
이번 주부터 드디어 기다리고 기다리던 프로젝트를 시작한다.
지금은 팀 구성이 완료되었고 팀 구성원들의 포지션을 배치 후 이제는 앞으로 어떻게 진행해야 될지에 대해 더 구체화시켜야 할 타이밍이라고 생각한다.
자 그럼 이제부터 앞으로의 진행 파이프라인을 간략하게 소개하는 시간을 가져보도록 하겠다.
1. EC2 환경 세팅 및 의존성 설치
2. DeepSeek Coder 6.7B 모델 다운로드 및 로드
3. 학습용 데이터 전처리
4. PEFT 기반 파인튜닝 (LoRA/QLoRA)
5. 체크포인트 저장 및 평가
6. 양자화 (int4, int8)
7. 추론 파이프라인 구축 및 테스트
from transformers import AutoTokenizer, AutoModelForCausalLM
model_name = "deepseek-ai/deepseek-coder-6.7b-instruct"
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
model_name,
trust_remote_code=True,
device_map="auto",
load_in_8bit=True, # 또는 4bit for QLoRA
)
from peft import prepare_model_for_kbit_training, LoraConfig, get_peft_model
from transformers import TrainingArguments, Trainer
model = prepare_model_for_kbit_training(model)
lora_config = LoraConfig(
r=8,
lora_alpha=16,
target_modules=["q_proj", "v_proj"], # DeepSeek에 맞게 수정 필요
lora_dropout=0.1,
bias="none",
task_type="CAUSAL_LM"
)
model = get_peft_model(model, lora_config)
training_args = TrainingArguments(
output_dir="./results",
per_device_train_batch_size=2,
gradient_accumulation_steps=8,
num_train_epochs=3,
fp16=True,
logging_steps=10,
save_steps=500,
save_total_limit=2,
evaluation_strategy="no"
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_dataset["train"]
)
trainer.train()
model.save_pretrained("./finetuned")
tokenizer.save_pretrained("./finetuned")
→ 추론 검증용 스크립트에서 예시 질문 넣고 결과 확인.
# 이미 QLoRA면 4bit 상태 → GPTQ 양자화로 변환 시 Huggingface Optimum 사용 가능
from transformers import AutoModelForCausalLM, AutoTokenizer
from optimum.gptq import quantize_model
model = AutoModelForCausalLM.from_pretrained("./finetuned")
quantized_model = quantize_model(model, quantization_config={"bits": 4})
quantized_model.save_pretrained("./quantized")
auto-gptq, ggml, gguf 등으로 변환 → 추론 성능 위주 최적화 가능
from transformers import pipeline
pipe = pipeline("text-generation", model="./quantized", tokenizer="./quantized", device=0)
output = pipe("function to reverse a string in python:", max_new_tokens=100)
print(output[0]["generated_text"])
llm_pipeline/
│
├── bootstrap.sh # EC2 초기 셋업
├── preprocess.py # 데이터 전처리
├── train.py # QLoRA 파인튜닝
├── quantize.py # 양자화
├── infer.py # 추론 테스트
├── data/
│ └── your_data.jsonl
└── output/
├── finetuned/
└── quantized/
QLoRA (Quantized Low-Rank Adaptation)는 다음과 같은 특징을 갖는다:
4-bit NF4 양자화: 모델 가중치를 4-bit로 양자화하여 메모리 사용을 최소화한다.
LoRA 어댑터: 모델의 핵심 가중치는 동결하고, 적은 수의 파라미터만 학습하여 효율적인 파인튜닝을 수행한다.
Double Quantization: 양자화된 가중치에 추가 양자화를 적용하여 메모리 사용을 더욱 줄인다.
Paged Optimizers: 메모리 사용량을 관리하여 학습 중 메모리 초과를 방지한다.
이러한 기법들은 T4 GPU와 같은 제한된 자원에서도 대규모 언어 모델의 파인튜닝과 양자화를 가능하게 한다.
from transformers import AutoTokenizer, AutoModelForCausalLM
model_id = "deepseek-ai/deepseek-coder-6.7b-instruct"
tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
model_id,
device_map="auto",
load_in_4bit=True,
trust_remote_code=True
)
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
model = prepare_model_for_kbit_training(model)
lora_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
model = get_peft_model(model, lora_config)
from transformers import TrainingArguments, Trainer
training_args = TrainingArguments(
output_dir="./output",
per_device_train_batch_size=1,
gradient_accumulation_steps=8,
num_train_epochs=3,
fp16=True,
save_total_limit=1,
logging_steps=10,
save_strategy="epoch",
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized["train"]
)
trainer.train()
model.save_pretrained("./finetuned")
tokenizer.save_pretrained("./finetuned")
from transformers import pipeline
pipe = pipeline("text-generation", model="./finetuned", tokenizer="./finetuned", device=0)
print(pipe("def reverse_string(s):", max_new_tokens=64)[0]['generated_text'])
자 이제 위의 예시 내용을 참고해서 본 내용을 진행하도록 하겠다.
| 항목 | 고려 이유 |
|---|---|
| LLM 모델 | DeepSeek Coder 6.7B (코드 전용, instruction-tuned) |
| 용도 | VSCode extension AI assistant |
| GPU 자원 | T4 (16GB) |
| CUDA | 12.1 |
| 요구사항 | 짧은 응답시간, 문맥 유지력, 높은 정확도 |
| 핵심 기술 | QLoRA + 코드 전용 학습 데이터 + 컨텍스트 창 고려 |
{
"prompt": "### Python function to calculate factorial:\ndef factorial(n):",
"completion": "\n if n == 0:\n return 1\n return n * factorial(n - 1)"
}
| 항목 | 설정값 |
|---|---|
| batch size | 1 (gradient accumulation 8~16) |
| fp16 | True |
| 4-bit 양자화 | NF4, double quantization |
| LoRA r | 16 |
| LoRA alpha | 32 |
| Target modules | q_proj, v_proj, k_proj, o_proj |
# Write a Python function to check if a number is prime.
하지만 추론 속도를 위한 GGUF or GPTQ 포맷 변환 고려 가능:
| 단계 | 기술/방법 |
|---|---|
| 모델 | deepseek-ai/deepseek-coder-6.7b-instruct |
| 파인튜닝 | QLoRA (4bit) + LoRA r=16 |
| 양자화 | 이미 4bit + double quantization 포함 (추가 X) |
| 데이터 | 코드 생성 특화, prompt-completion 형식 |
| 최적화 | gradient_accumulation_steps로 배치 증가 |
| API | FastAPI + VSCode 연결 or REST call |
이렇게 진행을 하니 궁금한 점이 하나 있어서 더 찾아본 내용이 있다.
이미 load_in_4bit=True로 로드한 DeepSeek Coder 6.7B 모델이라면,
추가적인 "양자화 작업"은 필요 없다.
즉, 추론을 위한 양자화는 이미 끝난 상태이다.
AutoModelForCausalLM.from_pretrained(
model_id,
load_in_4bit=True, # <= 이게 바로 "양자화된 상태로 로드"를 의미함
quantization_config=..., # NF4, double quantization 설정
)
| 구분 | 설명 | 당신의 경우 |
|---|---|---|
| 파인튜닝 시 양자화 (QLoRA) | 학습 시 모델을 4비트로 불러와 적은 메모리로 훈련 | ✅ 적용 중 |
| 추론 시 양자화 (GPTQ, GGUF) | 추론 속도/배포 목적, 더욱 경량화된 포맷 변환 | ❌ 선택 사항 (추가만 가능) |
| 항목 | 상태 | 필요 여부 |
|---|---|---|
load_in_4bit=True | ✔️ 설정됨 | 필수 |
QLoRA 방식 | ✔️ T4에 최적 | 필수 |
| 추가 GPTQ 양자화 | ❌ 안 해도 됨 | 선택 (속도 최적화 원할 경우) |
| 추론 속도 향상 목적의 GGUF | ❌ 안 해도 됨 | llama.cpp 환경에서만 필요 |
이번 주는 여기까지 앞으로의 프로젝트 화이팅...