모델별 실행 레시피
최종 업데이트
한국어 LoRA SFT 예제: 데이터·실행·평가
입력은 한국어 prompt/completion JSONL이고 출력은 저장된 adapter예요. 학습에서 제외한 같은 질문으로 base 모델과 비교해요.
Qwen 모델 카드는 Qwen2.5-0.5B-Instruct를 0.49B 파라미터, 한국어를 포함한 29개 이상 언어 지원, Apache-2.0으로 표시하고 Transformers 사용 예를 제공해요. 예제는 TRL SFTTrainer와 PEFT LoraConfig로 q_proj, k_proj, v_proj, o_proj를 학습해요. 예시 데이터는 형식 확인용이므로 실제 업무 예제로 교체하고 문서 단위로 train/held-out을 나눠요.
문의가 들어올 때마다 '환불·반품' 같은 분류명을 같은 형식으로 받고 싶을 수 있어요. LoRA1 파인튜닝은 입력 예제와 원하는 답을 보여주며 이런 작업 방식을 학습시키는 방법이에요. 아래에서는 한국어 예제를 파일로 만들고 작은 모델을 학습한 뒤, 결과 어댑터를 저장하고 같은 질문의 학습 전후 답을 비교해요.
학습보다 검색이 맞는 문제인지 먼저 정해요
질문에 답하려면 매번 바뀌는 문서나 사실을 찾아야 한다면 RAG2가 적합해요. 같은 형식의 답변을 반복하거나 특정 한국어 작업을 일관되게 분류해야 한다면 파인튜닝이 후보가 돼요. 결정이 애매하면 같은 질문에 대해 검색 결과를 제공한 baseline과 학습 후보의 답변을 함께 평가해요.

Qwen 모델과 학습 데이터를 준비해요
실제 업무의 다양한 한국어 표현을 모으되, 개인정보와 기밀 문서는 비식별화하거나 제거해요. 중복·상투적인 문장을 지우고 각 예에 입력, 기대 출력, 실패 기준을 함께 적어요. 같은 원문이나 템플릿이 학습과 평가 양쪽에 섞이지 않도록 사용자·문서 단위로 분리해요.
{"prompt":"<|im_start|>user\n문의 유형을 분류해 주세요: 주문한 상품을 반품하고 싶어요.<|im_end|>\n<|im_start|>assistant\n","completion":"환불·반품<|im_end|>"}
{"prompt":"<|im_start|>user\n다음 문장에서 날짜와 할 일을 JSON으로 정리해 주세요: 10월 20일까지 견적서를 보내 주세요.<|im_end|>\n<|im_start|>assistant\n","completion":"{\"date\":\"10월 20일\",\"task\":\"견적서 보내기\"}<|im_end|>"}연습에는 작은 Qwen2.5-0.5B-Instruct를 사용해요. 0.49B, 한국어를 포함한 29개 이상 언어, Apache-2.0, Transformers 지원이라는 조건을 갖춰 학습 파일과 어댑터 저장 과정을 준비하는 데 쓰기 좋아요. 실제 작업용 모델을 선택할 때는 최신 모델 카드의 언어·라이선스·PEFT target module을 확인하세요. Qwen3.5-0.8B는 다국어 하이브리드 비전·언어 모델이므로 이 예제의 텍스트 LoRA 설정을 옮기기 전에 해당 구조의 학습 경로를 확인해야 해요.
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -U 'trl[peft]' datasets accelerate
TRL 설정을 작게 시작하고 결과를 평가해요
train_lora.py는 먼저 학습 파일에 없는 held-out 질문의 base 응답을 출력하고, 같은 tokenizer chat template로 TRL 학습을 시작해요. SFTConfig는 출력 경로, 최대 길이 512, batch 1, gradient accumulation 8, epoch 2, LoRA 학습률 2e-4를 지정해요.
학습이 끝나면 output/adapter에 adapter와 tokenizer를 저장하고 held-out 질문에 다시 답해 결과를 비교해요. 학습 로그의 loss와 실제 메모리 사용량도 기록하고, held-out 답변의 품질을 확인해요.
from datasets import load_dataset
from peft import LoraConfig
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl import SFTConfig, SFTTrainer
MODEL = "Qwen/Qwen2.5-0.5B-Instruct"
QUESTION = "문의 유형을 분류해 주세요: 결제한 물건을 돌려보내고 결제 취소를 요청하고 싶습니다." # held-out wording; expected label: 환불·반품
tokenizer = AutoTokenizer.from_pretrained(MODEL)
def answer(model, question):
messages = [{"role": "user", "content": question}]
inputs = tokenizer.apply_chat_template(
messages, add_generation_prompt=True, tokenize=True,
return_dict=True, return_tensors="pt"
).to(model.device)
output = model.generate(**inputs, max_new_tokens=80, do_sample=False)
return tokenizer.decode(output[0][inputs["input_ids"].shape[-1]:], skip_special_tokens=True)
base = AutoModelForCausalLM.from_pretrained(MODEL, device_map="auto", torch_dtype="auto")
print("base:", answer(base, QUESTION))
del base
dataset = load_dataset("json", data_files="train.jsonl", split="train")
trainer = SFTTrainer(
model=MODEL,
args=SFTConfig(
output_dir="output/checkpoints",
max_length=512,
num_train_epochs=2,
per_device_train_batch_size=1,
gradient_accumulation_steps=8,
learning_rate=2e-4,
logging_steps=1,
save_strategy="epoch",
report_to="none",
eos_token=tokenizer.eos_token,
),
train_dataset=dataset,
processing_class=tokenizer,
peft_config=LoraConfig(
r=8, lora_alpha=16, lora_dropout=0.05, bias="none",
task_type="CAUSAL_LM",
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
),
)
trainer.train()
trainer.save_model("output/adapter")
tokenizer.save_pretrained("output/adapter")
print("adapter:", answer(trainer.model, QUESTION))python train_lora.py콘솔에는 base:와 adapter: 뒤에 생성된 두 응답이 표시돼요. 정상 완료 시 output/adapter/adapter_config.json과 adapter 가중치 파일이 생겨요.
CUDA3 메모리가 부족하면 max_length를 줄이고 batch 1을 유지하거나 더 큰 GPU4를 사용해요. 모델을 불러오지 못할 때는 Transformers가 최신인지 확인해요. Qwen2.5는 Transformers 4.37.0 미만에서 KeyError: 'qwen2'가 발생한다고 모델 카드가 안내해요.
결과는 held-out 질문의 정확성, 형식, 한국어 자연스러움을 표로 검토하고, 새 지식이 필요한 문제는 RAG baseline과 비교해요.

용어 각주
LoRA — 기본 모델의 동작을 조정하는 작은 추가 가중치를 학습·적용하는 방식입니다. 기본 모델에 어댑터를 함께 적용하며, 스타일 조정이나 적은 단계의 생성 등에 쓰입니다.
본문으로 돌아가기검색 증강 생성 — 질문과 관련된 자료를 검색해 모델 입력에 추가한 뒤, 그 문맥을 바탕으로 답변을 생성하는 방식입니다.
본문으로 돌아가기CUDA — NVIDIA GPU에서 범용 계산을 실행하기 위한 소프트웨어 플랫폼입니다.
본문으로 돌아가기GPU — 많은 계산을 병렬로 처리하는 프로세서입니다. AI 모델 실행에서는 모델 계산을 맡습니다.
본문으로 돌아가기
자주 묻는 질문
- 이 글에서 가장 먼저 확인할 것은 무엇인가요?
- Qwen 모델 카드는 Qwen2.5-0.5B-Instruct를 0.49B 파라미터, 한국어를 포함한 29개 이상 언어 지원, Apache-2.0으로 표시하고 Transformers 사용 예를 제공해요. 예제는 TRL `SFTTrainer`와 PEFT `LoraConfig`로 `q_proj`, `k_proj`, `v_proj`, `o_proj`를 학습해요. 예시 데이터는 형식 확인용이므로 실제 업무 예제로 교체하고 문서 단위로 train/held-out을 나눠요.
- 필요한 메모리는 어느 정도인가요?
- 학습이 끝나면 `output/adapter`에 adapter와 tokenizer를 저장하고 held-out 질문에 다시 답해 결과를 비교해요. 학습 로그의 loss와 실제 메모리 사용량도 기록하고, held-out 답변의 품질을 확인해요.
- 조건과 출처는 어디서 확인하나요?
- 연습에는 작은 Qwen2.5-0.5B-Instruct를 사용해요. 0.49B, 한국어를 포함한 29개 이상 언어, Apache-2.0, Transformers 지원이라는 조건을 갖춰 학습 파일과 어댑터 저장 과정을 준비하는 데 쓰기 좋아요. 실제 작업용 모델을 선택할 때는 최신 모델 카드의 언어·라이선스·PEFT target module을 확인하세요. Qwen3.5-0.8B는 다국어 하이브리드 비전·언어 모델이므로 이 예제의 텍스트 LoRA 설정을 옮기기 전에 해당 구조의 학습 경로를 확인해야 해요.
