pip install -U transformers datasets peft accelerate bitsandbytes
# GPU가 없다면 bitsandbytes는 생략 가능(QLoRA 미사용)
Python 3.10+ 권장. GPU가 없으면
QLoRA대신LoRA만 시도하세요(속도 이슈 고려).
train.jsonl 사용)train.jsonl(한 줄에 {"text": "..."} 형태)을 그대로 사용한다.from datasets import load_dataset
dataset = load_dataset("json", data_files="train.jsonl")
# 작은 샘플로 먼저 확인하고 싶다면:
# dataset["train"] = dataset["train"].select(range(200))
labels = input_ids + 패딩 토큰 위치는 -100으로 마스킹from transformers import AutoTokenizer, AutoModelForCausalLM, DataCollatorForLanguageModeling
# SLM 계열: 크기가 너무 큰 모델은 내 머신에서 과부하가 날 수 있습니다.
# 예시 1) OPT 1.3B
model_name = "facebook/opt-1.3b"
tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=True)
# pad 토큰 지정(없으면 eos를 pad로 사용)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
def tokenize_and_label(batch):
enc = tokenizer(
batch["text"],
truncation=True,
padding="max_length",
max_length=512,
)
# labels = input_ids (언어모델용 next-token 예측)
labels = []
for ids in enc["input_ids"]:
# pad 토큰 위치는 -100으로 마스킹 → loss에서 제외
labels.append([tok if tok != tokenizer.pad_token_id else -100 for tok in ids])
enc["labels"] = labels
return enc
tokenized = dataset.map(tokenize_and_label, batched=True, remove_columns=["text"])
# causal LM용 collator (MLM=False 중요)
collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False)
# 모델 로드(LoRA 적용 전 base 모델)
base_model = AutoModelForCausalLM.from_pretrained(model_name)
# 토큰 개수 변경 시(위에서 pad_token 추가) 안전하게 resize
base_model.resize_token_embeddings(len(tokenizer))
from peft import LoraConfig, get_peft_model
lora_cfg = LoraConfig(
r=8,
lora_alpha=16,
target_modules=["q_proj", "v_proj"], # OPT/LLaMA 계열에서 널리 쓰는 패턴
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
lora_model = get_peft_model(base_model, lora_cfg)
모델 유형에 따라
target_modules가 다를 수 있다. 만약 architecture가 달라 에러가 나면
['q_proj','k_proj','v_proj','o_proj']중 존재하는 레이어로 조정하라.
from transformers import Trainer, TrainingArguments
import torch
# bfloat16/float16 자동 선택
use_bf16 = torch.cuda.is_available() and torch.cuda.get_device_capability(0)[0] >= 8
use_fp16 = torch.cuda.is_available() and not use_bf16
args = TrainingArguments(
output_dir="./lora-out",
num_train_epochs=2,
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
learning_rate=2e-4,
logging_steps=20,
save_strategy="epoch",
save_total_limit=2,
report_to="none",
bf16=use_bf16,
fp16=use_fp16,
optim="paged_adamw_8bit" if torch.cuda.is_available() else "adamw_torch",
)
trainer = Trainer(
model=lora_model,
args=args,
train_dataset=tokenized["train"],
data_collator=collator,
)
trainer.train()
select(range(200))로 200개 정도만 학습해 파이프라인 정상 작동 먼저 확인하는 것을 권장.import torch
from peft import prepare_model_for_kbit_training
from transformers import BitsAndBytesConfig
bnb_cfg = BitsAndBytesConfig(
load_in_4bit=True, # 4비트 양자화
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.float16,
)
qlora_base = AutoModelForCausalLM.from_pretrained(
model_name,
quantization_config=bnb_cfg,
device_map="auto",
)
qlora_base.resize_token_embeddings(len(tokenizer))
qlora_base = prepare_model_for_kbit_training(qlora_base)
qlora_model = get_peft_model(qlora_base, lora_cfg)
trainer = Trainer(
model=qlora_model,
args=args,
train_dataset=tokenized["train"],
data_collator=collator,
)
trainer.train()
GPU가 없다면 QLoRA는 불가(또는 무의미). 이 경우 LoRA만 사용.
lora_model.save_pretrained("./lora-out/adapter") # 또는 qlora_model
tokenizer.save_pretrained("./lora-out/tokenizer")
학습 전/후 비교는 간단한 프롬프트로도 감이 온다. (정교 평가는 다음 장)
from transformers import pipeline
gen = pipeline("text-generation", model=lora_model, tokenizer=tokenizer, device_map="auto")
print(gen("### Instruction:\nExplain the difference between regression and classification.\n### Response:\n",
max_new_tokens=80)[0]["generated_text"])
labels가 없어서 loss가 없던 문제를 해결 → 학습(loss) 정상 출력-100 마스킹, collator 설정(mlm=False)다음 5장에서는 성능 평가와 실험 추적(Perplexity/ROUGE 등) 을 다루고,
6장에서는 LoRA 병합 → GGUF 변환 → Ollama용 모형 생성(Modelfile) → 로컬 실행을 마무리한다.
labels 필요성, DataCollatorForLanguageModeling(mlm=False) 사용위 참고 문서는 변동될 수 있으니, 최신 버전 기준의 Transformers / PEFT 공식 문서를 확인해 주세요.