Fine-tuning vs Prompting
Fine-tuning hay Prompting?
Công ty bạn muốn AI viết email khách hàng theo đúng giọng văn thương hiệu. Bạn có 20 email mẫu. Bước đầu tiên nên làm gì?
Hãy tưởng tượng bạn là chủ một chuỗi quán phở mới và cần một đầu bếp. Bạn có vài lựa chọn:
- Few-shot prompting = thuê đầu bếp giỏi sẵn rồi đưa công thức phở của bạn trước mỗi ca làm — rẻ, linh hoạt, nhưng công thức phải đủ ngắn và rõ.
- RAG = đầu bếp có cuốn sổ công thức, khi khách gọi món lạ thì giở sổ tra — cập nhật sổ dễ, nhưng cần thời gian tra cứu.
- LoRA = cho đầu bếp đi học thêm khóa ngắn về phở Hà Nội — học đủ sâu mà không cần đào tạo lại từ đầu.
- Full fine-tuning = tuyển một đầu bếp mới, dạy phở từ con số 0 trong 3 năm — tốn kém, nhưng giỏi phở nhất.
Trong AI, 4 cấp độ này khác nhau về chi phí, thời gian, dữ liệu cần, và độ chính xác. Chọn sai cấp độ sẽ làm lãng phí hàng chục triệu đồng và vài tháng của team — không khác gì tuyển nhầm đầu bếp.
Nguyên tắc: luôn thử cấp thấp trước. Thử prompting, đánh giá, nếu chưa đạt thì leo thang RAG, rồi LoRA, cuối cùng mới full fine-tune. Đừng bao giờ nhảy thẳng vào fine-tuning mà chưa thử prompting.
- Zero-shot prompting (không có ví dụ) — đủ chưa?
- Few-shot prompting (2–10 ví dụ) — đủ chưa?
- RAG (nếu có tài liệu tham khảo) — đủ chưa?
- LoRA / PEFT fine-tuning — đủ chưa?
- Full fine-tuning (bước cuối cùng)
Hình minh họa
Decision Tree: Chọn chiến lược phù hợp
Trả lời 5 câu hỏi để tìm chiến lược tối ưu cho dự án của bạn. Hệ thống tính điểm dựa trên dataset, domain, budget, latency, và yêu cầu format.
Bạn có bao nhiêu ví dụ (input, output) chất lượng?
Đây là tín hiệu quan trọng nhất — ít dữ liệu thì không thể fine-tune hiệu quả.
Bảng so sánh 4 chiến lược
| Tiêu chí | Few-shot | RAG | LoRA | Full FT |
|---|---|---|---|---|
| Chi phí setup | $0 – $10 | $50 – $500/tháng | $50 – $2.000 | $1.000 – $100.000+ |
| Thời gian | Vài phút | Vài ngày | Vài giờ – 1 ngày | Vài ngày – vài tuần |
| Dữ liệu cần | 2–10 ví dụ | Kho tài liệu | 500–10.000 ví dụ | 10.000+ ví dụ |
| Thay đổi model? | Không | Không | Có (adapter nhỏ) | Có (toàn bộ) |
| Đổi model mới? | Copy prompt | Copy pipeline | Train lại LoRA | Train lại toàn bộ |
| Độ trễ inference | +10–30% (prompt dài) | +100–500ms | Như base | Như base |
| Chất lượng domain hẹp | Trung bình | Tốt nếu có tài liệu | Rất tốt | Tốt nhất |
Prompting= "dạy AI bằng hướng dẫn" (nhanh, rẻ, linh hoạt). Fine-tuning= "đào tạo AI chuyên gia" (tốn kém, mạnh cho domain specific). Luôn leo thang từ rẻ đến đắt — đừng bao giờ nhảy thẳng vào fine-tuning mà chưa thử prompting.
Insight quan trọng: chi phí ẩn lớn nhất của fine-tuning là khi model mới ra (GPT-5, Claude 5). Prompting thì đổi model trong 1 dòng code; fine-tuning thì phải train lại từ đầu — có thể tốn hàng chục triệu và vài tuần.
Prompting có 3 ưu điểm lớn: (1) cực rẻ, (2) debug dễ — chỉ chỉnh prompt, không train lại, (3) tự động hưởng lợi khi model base mạnh lên. 70% dự án thực tế dừng lại ở prompting, không cần leo thang.
- Dataset quá nhỏ hoặc kém chất lượng → model overfit, mất khả năng generalization.
- Không có eval set → không biết fine-tune có cải thiện hay không.
- Catastrophic forgetting → model quên kỹ năng cơ bản (toán, code, đa ngôn ngữ) sau khi fine-tune domain hẹp.
- Quên so sánh với baseline prompting — nhiều team fine-tune xong mới phát hiện prompting cũng đạt 95% chất lượng.
GPT-5 vừa ra mắt, mạnh hơn GPT-4 rõ rệt. Bạn đã fine-tune GPT-4 cho task phân loại hồ sơ khách hàng. Muốn hưởng lợi từ GPT-5, bạn cần làm gì?
Giải thích
Prompting và fine-tuninglà hai triết lý khác nhau khi tùy chỉnh LLM cho task cụ thể. Trong thực tế, chúng ta không chọn "một hay hai" — chúng ta leo thang qua 4 cấp độ: zero-shot → few-shot → RAG → LoRA → full fine-tune, dừng lại ngay khi đạt chất lượng yêu cầu.
1. Prompting — điều khiển model qua input
Zero-shot prompting: chỉ đưa hướng dẫn, không có ví dụ. Ví dụ: "Phân loại sentiment của câu sau: ...". LLM hiện đại (Claude, GPT-4) thường xử lý tốt task phổ biến mà không cần ví dụ.
Few-shot prompting: đưa 2–10 cặp (input, output) làm mẫu. Model nhìn vào pattern để suy ra cách trả lời câu mới. Đây gọi là in-context learning. Ưu: rất mạnh cho task có pattern rõ. Nhược: prompt dài tốn token; giới hạn context window.
2. RAG — prompting tăng cường bằng retrieval
RAG tách kiến thức khỏi model: lưu tài liệu trong vector database, khi có câu hỏi thì tìm tài liệu liên quan, nhét vào prompt, rồi gọi LLM. Ưu: cập nhật kiến thức không cần train lại, dễ trích dẫn nguồn, giảm hallucination. Nhược: cần xây pipeline (chunking, embedding, re-ranking).
RAG đặc biệt hiệu quả cho: chatbot nội bộ, customer support, technical documentation, hệ thống yêu cầu trích dẫn (legal, medical, research).
3. LoRA / PEFT — fine-tuning hiệu quả
LoRA (Low-Rank Adaptation) chỉ huấn luyện hai ma trận nhỏ A và B sao cho:
trong đó A có shape , B có shape , và (thường r = 4, 8, 16). Số tham số train giảm ~100–1000×, bộ nhớ GPU giảm tương ứng.
Hầu như luôn luôn — trừ khi bạn có tài nguyên gần không giới hạn. LoRA đạt 90–98% chất lượng của full FT với 1–5% chi phí. Ngoài ra, bạn có thể duy trì nhiều adapter cho cùng một base model (mỗi khách hàng enterprise một adapter), tiết kiệm đáng kể chi phí deploy.
4. Full fine-tuning — cập nhật toàn bộ trọng số
Huấn luyện lại toàn bộ model trên dataset riêng. Chi phí cao (GPU, thời gian, kỹ sư ML), nhưng có thể thay đổi hành vi cốt lõi. Chỉ dùng khi: dataset rất lớn và chất lượng (10.000+ ví dụ), domain cực chuyên biệt, có team MLOps để maintain.
Chi phí tổng thể: tính toán thực tế
Một câu hỏi hay bị bỏ qua: đâu là chiến lược rẻ nhất về tổng thể (TCO)? Câu trả lời phụ thuộc khối lượng request.
- Prompting: chi phí mỗi request cao hơn (prompt dài), nhưng setup gần bằng 0. Rẻ nếu volume thấp.
- Fine-tuning: setup đắt (hàng ngàn đến hàng chục ngàn USD), nhưng chi phí mỗi request thấp. Rẻ hơn khi volume cao (hàng triệu request).
Điểm hòa vốn thường rơi vào khoảng 100.000 – 10 triệu request. Dưới mức này, prompting luôn rẻ hơn dù tính cả token cost.
# Pipeline đề xuất: leo thang từ rẻ đến đắt
# Mỗi bước đều đo trên cùng 1 eval set để so sánh công bằng
from anthropic import Anthropic
from my_eval import evaluate_on_eval_set
client = Anthropic()
# ─── Bước 1: Zero-shot ───
def zero_shot(sample):
return client.messages.create(
model="claude-sonnet-4-6",
max_tokens=500,
messages=[{
"role": "user",
"content": f"Phân loại sentiment: {sample['input']}"
}]
)
score_zero = evaluate_on_eval_set(zero_shot)
print(f"Zero-shot: {score_zero:.1%}")
# ─── Bước 2: Few-shot (nếu zero-shot chưa đủ) ───
FEW_SHOT_EXAMPLES = [
{"input": "Giao hàng chậm quá!", "label": "negative"},
{"input": "Phở ngon tuyệt!", "label": "positive"},
{"input": "Giá tầm trung, chất lượng ổn.", "label": "neutral"},
]
def few_shot(sample):
examples = "\n".join(
f"Input: {e['input']}\nOutput: {e['label']}"
for e in FEW_SHOT_EXAMPLES
)
prompt = f"{examples}\n\nInput: {sample['input']}\nOutput:"
return client.messages.create(
model="claude-sonnet-4-6",
max_tokens=50,
messages=[{"role": "user", "content": prompt}]
)
score_few = evaluate_on_eval_set(few_shot)
print(f"Few-shot: {score_few:.1%}")
# ─── Bước 3: RAG (nếu cần kiến thức external) ───
# ... (pipeline chunking + embedding + retrieval)
# ─── Bước 4: LoRA (nếu vẫn chưa đủ) ───
from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM, Trainer
base_model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.1-8B")
peft_config = LoraConfig(
r=16, # rank thấp
lora_alpha=32, # scaling
target_modules=["q_proj", "v_proj"],
lora_dropout=0.05,
)
model = get_peft_model(base_model, peft_config)
# Chỉ ~0.3% tham số được train!
# trainer.train() với dataset 500-2000 ví dụ
# Sau đó lưu adapter (chỉ vài MB)
# ─── Bước 5: Full fine-tune (cuối cùng) ───
# Chỉ khi các bước trên KHÔNG đạt yêu cầu VÀ có 10k+ ví dụ chất lượng# Tính toán TCO (Total Cost of Ownership) để chọn chiến lược
# Input: volume dự kiến, chi phí setup, chi phí mỗi request
def total_cost(strategy, monthly_requests, months=12):
if strategy == "prompting":
setup = 0
per_request = 0.01 # USD, prompt dài
elif strategy == "rag":
setup = 500 # vector DB setup
per_request = 0.012 # embedding + LLM
elif strategy == "lora":
setup = 500 # train LoRA
per_request = 0.006 # prompt ngắn hơn
elif strategy == "full-ft":
setup = 10000 # full training
per_request = 0.006
else:
raise ValueError(f"Unknown: {strategy}")
return setup + per_request * monthly_requests * months
# Ví dụ:
for volume in [1_000, 100_000, 10_000_000]:
print(f"\nVolume: {volume:,}/month")
for s in ["prompting", "rag", "lora", "full-ft"]:
cost = total_cost(s, volume)
print(f" {s:12} = ${cost:>12,.0f}")
# Output tiêu biểu:
# Volume: 1,000/month — prompting rẻ nhất ($120)
# Volume: 100,000/month — LoRA bắt đầu cạnh tranh
# Volume: 10,000,000/month — Full FT rẻ nhất về tổng thểChỉ khi cả 4 điều kiện đều đúng: (1) dataset 10.000+ ví dụ chất lượng cao, (2) domain cực chuyên biệt, (3) volume request rất lớn (10M+/tháng) — đủ để hòa vốn chi phí setup, (4) có team MLOps để maintain. Thiếu 1 trong 4 điều kiện → nên dùng LoRA thay.
Kết hợp nhiều chiến lược
Trong thực tế, các chiến lược thường được kết hợp, không loại trừ lẫn nhau:
- RAG + few-shot: nhét tài liệu retrieval VÀ vài ví dụ mẫu vào prompt.
- LoRA + RAG: LoRA cho style công ty, RAG cho kiến thức cập nhật.
- Full FT + prompting: full FT làm nền, thêm prompting để điều chỉnh giọng văn mỗi request.
Dự án: chatbot hỏi đáp về 10.000 trang tài liệu nội bộ công ty, được cập nhật hàng tuần. Chiến lược?
Sai lầm tai hại nhất: fine-tune (hoặc chỉnh prompt) mà không có eval set chuẩn. Bạn không có cách nào biết thay đổi có tốt hơn hay không — tất cả chỉ là cảm giác. Trước mọi quyết định tùy chỉnh model, hãy xây 50–500 ví dụ eval gold-standard, được con người kiểm tra, và đo chất lượng trên eval set này cho mọi chiến lược.
Prompt engineering có những kỹ thuật đo lường được: chain-of-thought ("suy luận từng bước"), role assignment ("Bạn là chuyên gia..."), structured output (JSON schema), constraint injection ("tối đa 50 từ"), few-shot ordering (ví dụ khó trước). Một prompt tốt có thể hơn một LoRA tệ — đừng xem nhẹ prompt engineering.
Code minh họa 4 chiến lược
# Few-shot prompting — không train gì
# Chỉ cần prompt tốt + vài ví dụ mẫu
prompt = """Phân loại sentiment của bình luận tiếng Việt.
Chỉ trả lời: positive, negative, hoặc neutral.
Ví dụ:
- "Phở ngon lắm!" → positive
- "Giao hàng chậm quá" → negative
- "Giá tầm trung" → neutral
Bình luận: "Shop bán hàng chất lượng!"
Kết quả:"""
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=50,
messages=[{"role": "user", "content": prompt}]
)
print(response.content[0].text) # "positive"- 4 chiến lược: few-shot prompting → RAG → LoRA → full fine-tuning. Leo thang từ rẻ đến đắt.
- Prompting: nhanh, rẻ, dễ đổi model mới. Fine-tuning: chất lượng cao hơn cho domain chuyên sâu, nhưng gắn chặt với model cụ thể.
- RAG phù hợp khi có kho tài liệu cần cập nhật — không cần train lại khi tài liệu thay đổi.
- LoRA đạt 90–98% chất lượng full fine-tune với 1–5% chi phí — lựa chọn mặc định khi cần fine-tune.
- Luôn xây eval set gold-standard TRƯỚC. Không có eval thì mọi quyết định tùy chỉnh chỉ là đoán mò.
- Chi phí ẩn lớn nhất của fine-tuning: khi model mới ra (GPT-5, Claude 5) phải train lại từ đầu. Prompting không có chi phí này.
Kiểm tra hiểu biết
Bạn có 100 ví dụ (input, output) cho một task phổ biến. Bước đầu tiên nên làm gì?