LLMLLM 파인튜닝강의 5개 중 4번째난이도 중급

LoRA/QLoRA — 오픈소스 모델 저비용 파인튜닝

발행 읽는 시간 약 1 분

  • LLM
  • LoRA
  • QLoRA
  • PEFT
  • HuggingFace
  • 오픈소스

강의 소개

LoRA와 QLoRA로 Llama, Mistral 같은 오픈소스 모델을 소비자급 GPU에서 파인튜닝하는 방법을 배웁니다. Hugging Face Transformers와 PEFT 라이브러리를 사용합니다.

LoRA vs QLoRA#

LoRAQLoRA
기본 모델FP16/BF164bit 양자화
VRAM 요구중간낮음
성능약간 높음약간 낮음
7B 모델~16GB~6GB
13B 모델~28GB~10GB

QLoRA = Quantized + Low-Rank Adaptation


환경 설정#

Bash
pip install transformers peft bitsandbytes datasets accelerate trl

QLoRA 파인튜닝 (Llama/Mistral)#

Python
import torch
from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    BitsAndBytesConfig,
    TrainingArguments,
)
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from trl import SFTTrainer
from datasets import load_dataset

# 1. 4bit 양자화 설정 (QLoRA)
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_use_double_quant=True,
)

# 2. 모델 로드
model_name = "mistralai/Mistral-7B-Instruct-v0.2"
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    quantization_config=bnb_config,
    device_map="auto",
)
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token

# 3. LoRA 설정
lora_config = LoraConfig(
    r=16,                # Rank (낮을수록 파라미터 적음, 보통 4~64)
    lora_alpha=32,       # 스케일링 (보통 r의 2배)
    target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
)

model = prepare_model_for_kbit_training(model)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# trainable params: 6,815,744 || all params: 3,758,489,600 || trainable%: 0.18

학습 설정#

Python
# 4. 학습 파라미터
training_args = TrainingArguments(
    output_dir="./results",
    num_train_epochs=3,
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,   # 유효 배치: 4×4=16
    learning_rate=2e-4,
    fp16=True,
    logging_steps=10,
    save_steps=100,
    eval_steps=100,
    warmup_ratio=0.05,
    lr_scheduler_type="cosine",
    report_to="none",  # "wandb"로 설정 시 실험 추적
)

# 5. 데이터셋 준비
dataset = load_dataset("json", data_files="training.jsonl")

def format_chat(sample):
    """ChatML 형식으로 텍스트 변환"""
    messages = sample["messages"]
    text = ""
    for msg in messages:
        if msg["role"] == "system":
            text += f"<|system|>\n{msg['content']}\n"
        elif msg["role"] == "user":
            text += f"<|user|>\n{msg['content']}\n"
        elif msg["role"] == "assistant":
            text += f"<|assistant|>\n{msg['content']}\n"
    return {"text": text}

formatted = dataset["train"].map(format_chat)

# 6. SFT 학습
trainer = SFTTrainer(
    model=model,
    train_dataset=formatted,
    args=training_args,
    tokenizer=tokenizer,
    max_seq_length=2048,
    dataset_text_field="text",
)

trainer.train()

모델 저장과 병합#

Python
# LoRA 어댑터만 저장 (작은 파일)
model.save_pretrained("./my-lora-adapter")
tokenizer.save_pretrained("./my-lora-adapter")

# 원본 모델에 LoRA 병합 (추론 최적화)
from peft import PeftModel

base_model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=torch.float16,
    device_map="auto",
)

merged_model = PeftModel.from_pretrained(base_model, "./my-lora-adapter")
merged_model = merged_model.merge_and_unload()  # 가중치 병합

merged_model.save_pretrained("./my-merged-model")

추론#

Python
from peft import PeftModel

# 방법 1: 어댑터 로드
base_model = AutoModelForCausalLM.from_pretrained(model_name, ...)
model = PeftModel.from_pretrained(base_model, "./my-lora-adapter")

# 방법 2: 병합된 모델 직접 로드
model = AutoModelForCausalLM.from_pretrained("./my-merged-model", ...)

def generate(prompt: str, max_new_tokens: int = 512) -> str:
    inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
    with torch.no_grad():
        outputs = model.generate(
            **inputs,
            max_new_tokens=max_new_tokens,
            temperature=0.7,
            do_sample=True,
            pad_token_id=tokenizer.eos_token_id,
        )
    return tokenizer.decode(outputs[0], skip_special_tokens=True)

정리#

하이퍼파라미터영향
r (rank)낮을수록 파라미터 적음, 성능 trade-off
lora_alpha보통 r의 2배
learning_rate1e-4 ~ 3e-4 (LoRA는 더 높게 설정 가능)
n_epochs3~5 (과적합 주의)
4bit 양자화VRAM 70% 절약, 성능 약간 저하

다음 편에서는 평가와 배포 — 파인튜닝 모델의 성능을 측정하고 서비스에 배포하는 방법을 배웁니다.

Follow · Ask · Work

이 글이 도움이 됐다면

짧은 작업 기록과 데모는 인스타그램에 올립니다. 만들고 싶은 것이 있다면 프로젝트 의뢰나 협업 제안도 편하게 보내 주세요.

글쓴이

파란여우

직접 만든 AI 앱·제품의 개발·배포를 공개하는 실전형 테크 크리에이터

파란여우 소개 Instagram @bluefox._.hi

이어서 보기

만들고 싶은 것이 있다면 프로젝트 의뢰로 알려 주세요.