Supervised Fine-Tuning (SFT) — Instruction Tuning thực hành
Quy trình SFT đầy đủ với thư viện TRL: SFTTrainer, packing, masking loss trên phần assistant, theo dõi huấn luyện.
SFT là bước huấn luyện thực tế đầu tiên trong pipeline — nơi lý thuyết Module 2-5 được ghép lại thành một quy trình chạy được từ đầu đến cuối. Đây là kỹ năng thực hành cốt lõi của cả khoá học.
🎯 Mục tiêu học tập
- Sử dụng thư viện TRL (Transformer Reinforcement Learning) của Hugging Face để chạy SFT
- Hiểu và áp dụng kỹ thuật packing để tận dụng hiệu quả GPU khi mẫu dữ liệu ngắn
- Áp dụng đúng loss masking — chỉ tính loss trên phần phản hồi của assistant, không tính trên prompt
- Theo dõi quá trình huấn luyện và nhận biết dấu hiệu overfitting/underfitting
SFTTrainer — quy trình chuẩn với TRL
from trl import SFTTrainer, SFTConfig
from datasets import load_dataset
dataset = load_dataset("json", data_files="train.jsonl", split="train")
config = SFTConfig(
output_dir="./qwen-support-lora",
num_train_epochs=3,
per_device_train_batch_size=4,
gradient_accumulation_steps=4, # batch size hiệu dụng = 4 x 4 = 16
learning_rate=2e-4,
warmup_ratio=0.03,
logging_steps=10,
save_strategy="epoch",
packing=True, # gộp nhiều mẫu ngắn vào 1 sequence để dùng GPU hiệu quả hơn
max_seq_length=2048,
)
trainer = SFTTrainer(
model=model, # model đã bọc LoRA/QLoRA từ Module 4
args=config,
train_dataset=dataset,
eval_dataset=eval_dataset,
)
trainer.train()
Packing — dùng GPU hiệu quả hơn
Khi mẫu dữ liệu ngắn (vài trăm token) nhưng max_seq_length đặt cao (2048+), huấn luyện
từng mẫu riêng lẻ lãng phí rất nhiều compute vào phần padding (đệm chỗ trống). Packing
nối nhiều mẫu ngắn liên tiếp vào cùng 1 sequence (ngăn cách bằng token đặc biệt), lấp đầy gần hết
max_seq_length — tăng tốc huấn luyện đáng kể mà không đổi kết quả học được, gần như luôn nên
bật trừ khi dữ liệu của bạn vốn đã dài đều.
Loss Masking — chỉ học từ câu trả lời của Assistant
Mặc định, loss tính trên toàn bộ sequence bao gồm cả phần system/user prompt — điều này không sai về mặt kỹ thuật nhưng lãng phí: bạn không muốn model "học cách sinh ra câu hỏi của user", chỉ muốn nó học cách trả lời tốt hơn. Cấu hình completion-only loss (chỉ tính loss trên phần token thuộc vai trò assistant, che (mask) phần còn lại bằng giá trị đặc biệt -100 để PyTorch bỏ qua khi tính loss) là thực hành chuẩn cho SFT:
from trl import DataCollatorForCompletionOnlyLM
collator = DataCollatorForCompletionOnlyLM(
response_template="<|assistant|>", # token đánh dấu bắt đầu phần assistant, tuỳ theo chat template
tokenizer=tokenizer,
)
Theo dõi huấn luyện: nhận biết Overfitting/Underfitting
| Dấu hiệu | Ý nghĩa | Cách xử lý |
|---|---|---|
| Train loss giảm đều, eval loss cũng giảm | Đang học tốt | Tiếp tục, theo dõi thêm |
| Train loss giảm mạnh, eval loss bắt đầu tăng trở lại | Overfitting — model đang "học thuộc" dữ liệu train thay vì tổng quát hoá | Giảm số epoch, tăng lora_dropout, thêm dữ liệu đa dạng hơn |
| Cả train loss và eval loss giảm rất chậm hoặc không giảm | Underfitting — model chưa học được gì đáng kể | Tăng learning rate, tăng rank (r), kiểm tra lại format dữ liệu có đúng không |
| Loss đột ngột nhảy vọt (spike) rồi không hồi phục | Mất ổn định huấn luyện, thường do learning rate quá cao | Giảm learning rate, tăng warmup_ratio, kiểm tra gradient clipping |
Nên tích hợp MLflow hoặc Weights & Biases để log các chỉ số này theo thời gian thực và so sánh nhiều lần chạy — nếu đã học khoá Databricks, MLflow Tracking (Module 9 khoá đó) áp dụng trực tiếp cho việc log thực nghiệm fine-tuning này.
🏋️ Bài tập thực hành
Dùng tập dữ liệu đã chuẩn bị ở Module 5, chạy SFTTrainer với packing và completion-only loss masking bật sẵn. Log training/eval loss theo từng bước (dùng MLflow hoặc đơn giản là ghi ra file). Chạy 2 lần với 2 giá trị learning_rate khác nhau (ví dụ 1e-4 và 5e-4), so sánh biểu đồ loss và chọn cấu hình tốt hơn.
📚 Tài nguyên học tập
-
Hugging Face — TRL: SFTTrainerTài liệu chính thức SFTTrainerDocs
-
Hugging Face — TRL documentation (tổng)Tài liệu tổng quan thư viện TRLDocs
✅ Tự đánh giá hoàn thành
- Chạy thành công 1 lần SFT đầy đủ bằng SFTTrainer với dữ liệu tự chuẩn bị
- Bật đúng packing và completion-only loss masking
- Đọc hiểu biểu đồ train/eval loss và nhận biết được overfitting/underfitting
- So sánh được kết quả giữa ít nhất 2 cấu hình siêu tham số khác nhau