← Chương trước: Phần 4: Knowledge Distillation: Chắt Lọc Tri Thức DeepSeek-R1 | Mục lục Series | Chương tiếp theo: Phần 6: Tối Ưu Hóa Triển Khai vLLM & Đánh Giá Tự Động →
Answer-first: Căn chỉnh hành vi hiện đại thay thế PPO bằng DPO và GRPO nhằm triệt tiêu ảo giác và ép tuân thủ 99.8% JSON Schema. Tính toán lợi thế tương đối theo nhóm không cần mô hình Critic cho phép căn chỉnh mô hình 7B–14B trên một GPU 24GB duy nhất mà không lo bất ổn định hội tụ.
📖 Bản tiếng Anh (English Edition): Part 5: Preference Alignment with DPO & GRPO
1. Sự Sụp Đổ Của PPO Trong Môi Trường Giới Hạn Tài Nguyên
BLUF (Bottom Line Up Front): PPO đòi hỏi nạp cùng lúc 4 mô hình lớn vào bộ nhớ GPU (Actor, Critic, Reference, Reward), gây nổ VRAM (>80GB) và thường xuyên trôi dạt hàm giá trị (Critic drift); DPO thay thế toàn bộ hệ thống phức tạp này bằng một hàm mất mát phân loại nhị phân đơn giản chỉ với 150 dòng mã nguồn PyTorch.
Trong kỷ nguyên ban đầu của RLHF (Reinforcement Learning from Human Feedback, 2022–2023), thuật toán PPO (Proximal Policy Optimization) được xem là tiêu chuẩn vàng. Tuy nhiên, khi áp dụng vào môi trường doanh nghiệp thực tế, PPO bộc lộ những rào cản chí mạng:
flowchart TD
subgraph PPOArchitecture ["Sự Cồng Kềnh Của PPO Cổ Điển (Cần 4 Mô Hình Đồng Thời)"]
direction TB
Prompt["Prompt x"] --> Actor["1. Policy / Actor Model (Trainable)<br/>Sinh văn bản"]
Prompt --> Ref["2. Reference Model (Frozen)<br/>Tính KL Divergence"]
Actor --> Reward["3. Reward Model (Frozen)<br/>Chấm điểm phần thưởng r(x, y)"]
Actor --> Critic["4. Critic / Value Model (Trainable)<br/>Dự đoán giá trị kỳ vọng V(x)"]
Critic & Reward & Ref --> GAE["Generalized Advantage Estimation (GAE)"]
GAE --> PPOUpdate["Cập nhật Gradient PPO (Cực kỳ nhạy cảm & Dễ vỡ)"]
end
Ba tử huyệt hạ tầng của PPO:
- Nổ VRAM (4-Model Memory Explosion): Để huấn luyện một mô hình 7B bằng PPO, máy chủ phải duy trì ít nhất 4 phiên bản trọng số: Actor (trainable), Critic (trainable), Reference (frozen) và Reward Model (frozen). Tổng VRAM yêu cầu vượt quá 80GB–120GB, buộc doanh nghiệp phải thuê cụm đa GPU đắt đỏ.
- Hiện Tượng Trôi Dạt Hàm Giá Trị (Critic Drift): Mạng nơ-ron Critic cố gắng xấp xỉ giá trị hàm tương lai nhưng thường xuyên bị mất ổn định do phương sai gradient quá lớn, kéo sụp toàn bộ chính sách sinh văn bản của Actor chỉ sau vài trăm bước tối ưu.
- Khai Thác Lỗ Hổng Phần Thưởng (Reward Hacking): Mô hình nhanh chóng học được các mánh khóe để đánh lừa Reward Model—chẳng hạn như sinh câu trả lời cực dài, lặp lại các từ ngữ tâng bốc hoặc dùng cấu trúc ngữ pháp hoa mỹ rỗng tuếch để giành điểm thưởng cao mà không giải quyết vấn đề thực tế.
2. Bản Chất Toán Học Của DPO: Dẫn Xuất Nghiệm Đóng Bradley-Terry
BLUF (Bottom Line Up Front): Rafailov et al. (Stanford, 2023) chứng minh rằng phần thưởng tối ưu trong mô hình xác suất Bradley-Terry có thể biểu diễn tường minh qua tỷ lệ log-xác suất giữa mô hình huấn luyện và mô hình tham chiếu gốc, biến bài toán RL phức tạp thành bài toán hồi quy logistic thông thường.
Nhận định đột phá của DPO (Direct Preference Optimization) là: chúng ta không cần huấn luyện một mô hình phần thưởng riêng biệt. Hàm phần thưởng $r(x, y)$ có thể được định nghĩa ngầm định (implicitly) thông qua chính sách tối ưu $\pi_\theta$ và chính sách tham chiếu $\pi_{\text{ref}}$:
$$r(x, y) = \beta \log \frac{\pi_\theta(y|x)}{\pi_{\text{ref}}(y|x)}$$
flowchart LR
subgraph DPOFlow ["Cơ Chế Tính Mất Mát Của DPO (Không Cần Reward Model)"]
direction TB
Pair["Cặp Dữ Liệu: Prompt x<br/>(y_w: Được chọn, y_l: Bị từ chối)"]
Pair --> PolicyEval["Đánh Giá Trên Chính Sách Đang Học pi_theta<br/>log pi_theta(y_w|x) & log pi_theta(y_l|x)"]
Pair --> RefEval["Đánh Giá Trên Tham Chiếu Đóng Băng pi_ref<br/>log pi_ref(y_w|x) & log pi_ref(y_l|x)"]
PolicyEval & RefEval --> ImplicitMargin["Tính Tỉ Số Lợi Thế Ngầm Định:<br/>Delta = beta * [log(pi_theta/pi_ref)_w - log(pi_theta/pi_ref)_l]"]
ImplicitMargin --> SigmoidLoss["Mất Mát Nhị Phân: -log sigma(Delta)"]
end
Công thức hàm mất mát DPO
Thay thế biểu thức phần thưởng ngầm định vào mô hình sở thích Bradley-Terry $P(y_w \succ y_l | x) = \sigma(r(x, y_w) - r(x, y_l))$, ta thu được mục tiêu tối ưu hóa DPO trực tiếp:
$$\mathcal{L}{\text{DPO}}(\pi\theta; \pi_{\text{ref}}) = -\mathbb{E}{(x, y_w, y_l) \sim \mathcal{D}} \left[ \log \sigma \left( \beta \log \frac{\pi\theta(y_w|x)}{\pi_{\text{ref}}(y_w|x)} - \beta \log \frac{\pi_\theta(y_l|x)}{\pi_{\text{ref}}(y_l|x)} \right) \right]$$
Trong đó:
- $y_w$ (winning/chosen): Câu trả lời được con người hoặc hệ thống ưa thích.
- $y_l$ (losing/rejected): Câu trả lời bị từ chối (chứa lỗi logic, vi phạm an toàn hoặc sai định dạng).
- $\beta \in [0.05, 0.2]$: Hệ số phạt kiểm soát khoảng cách KL giữa chính sách mới và chính sách tham chiếu gốc.
- $\sigma$: Hàm sigmoid chuẩn $\sigma(z) = \frac{1}{1 + e^{-z}}$.
Khi triển khai với LoRA, ta chỉ cần tắt adapter trong quá trình tính toán để mô hình đóng vai trò $\pi_{\text{ref}}$, giúp giảm 50% chi phí VRAM và huấn luyện ổn định trên 1 GPU duy nhất!
3. GRPO (Group Relative Policy Optimization): Động Cơ Đằng Sau DeepSeek-R1
BLUF (Bottom Line Up Front): DeepSeek phát minh ra GRPO bằng cách lấy mẫu một nhóm $G$ câu trả lời cho mỗi prompt và tính toán điểm lợi thế tương đối so với trung bình của nhóm; kỹ thuật này loại bỏ hoàn toàn mô hình Critic mà vẫn thực hiện được thuật toán khám phá RL mạnh mẽ.
Trong khi DPO dựa trên dữ liệu sở thích tĩnh (offline dataset), các tác vụ tư duy toán học và lập trình đòi hỏi mô hình phải chủ động khám phá các con đường suy luận mới thông qua Reinforcement Learning trực tuyến. Để khắc phục sự cồng kềnh của PPO, DeepSeek giới thiệu GRPO (Group Relative Policy Optimization):
flowchart TD
subgraph GRPOLogic ["Quy Trình Tính Toán Lợi Thế Nhóm Trong GRPO"]
direction TB
PromptQ["Truy Vấn q"] --> Sampler["Chính Sách pi_theta Lấy Mẫu G Câu Trả Lời<br/>{o_1, o_2, ..., o_G} (ví dụ G=8)"]
Sampler --> Evaluator["Hệ Thống Chấm Điểm Oracle Tự Động (Quy Tắc)<br/>Math Check: Đúng = 1.0, Sai = 0.0<br/>JSON Format: Đúng Schema = 1.0, Sai = 0.0"]
Evaluator --> GroupStats["Tính Giá Trị Trung Bình & Độ Lệch Chuẩn Của Nhóm:<br/>mean({r}) và std({r})"]
GroupStats --> RelativeAdvantage["Lợi Thế Tương Đối Từng Mẫu:<br/>A_i = (r_i - mean) / (std + eps)"]
RelativeAdvantage --> PolicyUpdate["Cập Nhật Trọng Số Policy Với Surrogate Loss"]
end
Công thức tính lợi thế tương đối (Relative Advantage Formulation)
Với mỗi câu hỏi $q$, GRPO sinh ra $G$ phương án giải quyết ${o_1, o_2, \dots, o_G}$. Điểm số lợi thế của phương án $o_i$ được chuẩn hóa trực tiếp theo phân phối của nhóm:
$$A_i = \frac{r_i - \text{mean}({r_1, \dots, r_G})}{\text{std}({r_1, \dots, r_G}) + \epsilon}$$
Ưu điểm mang tính cách mạng của công thức này:
- Không cần mô hình Critic: Giá trị kỳ vọng $V(q)$ được ước lượng tức thì bằng trung bình điểm số của nhóm $\text{mean}({r})$. Mô hình Critic bị khai tử hoàn toàn.
- Khuyến khích tự sửa sai: Nếu trong 8 câu trả lời, có 2 câu trả lời tự phát hiện lỗi và quay lui thành công để ra kết quả đúng ($r=1.0$), chúng sẽ nhận điểm lợi thế $A_i > 0$ rất cao, thúc đẩy mô hình củng cố hành vi suy ngẫm nội tâm.
4. KTO (Kahneman-Tversky Optimization): Học Từ Tín Hiệu Nhị Phân Đơn Lẻ
BLUF (Bottom Line Up Front): Trong môi trường thực tế, việc ghép cặp câu trả lời được chọn và bị từ chối là rất tốn kém; KTO áp dụng lý thuyết triển vọng (Prospect Theory) của Kahneman & Tversky để huấn luyện trực tiếp trên các tín hiệu đơn lẻ (Thumbs Up / Thumbs Down).
Phần lớn dữ liệu tương tác trong các ứng dụng doanh nghiệp xuất hiện dưới dạng tín hiệu rời rạc: người dùng nhấn Like (Hài lòng) hoặc Dislike (Không hài lòng) cho một câu trả lời duy nhất, chứ không bao giờ ngồi viết 2 phương án để so sánh.
KTO (Kahneman-Tversky Optimization) định nghĩa hàm hữu dụng phi tuyến tính dựa trên tâm lý học hành vi: con người cảm thấy nỗi đau mất mát (loss) sâu sắc hơn niềm vui nhận được phần thưởng (gain) có cùng giá trị.
flowchart LR
subgraph KTOMethodology ["Mô Thức Căn Chỉnh Đơn Tín Hiệu Của KTO"]
SingleCompletion["Một Phản Hồi Duy Nhất (x, y)"] --> SignalCheck{"Nhãn Người Dùng"}
SignalCheck -->|Thumbs Up: label=True| PositiveBranch["Tối Ưu Hóa Hàm Hữu Dụng Dương:<br/>U(x, y) = 1 - sigma(beta * (r - z_ref))"]
SignalCheck -->|Thumbs Down: label=False| NegativeBranch["Phạt Nặng Theo Lý Thuyết Triển Vọng:<br/>U(x, y) = 1 - sigma(beta * (z_ref - r)) * lambda_loss"]
end
KTO cho phép doanh nghiệp tận dụng ngay lập tức 100,000 lượt tương tác người dùng thực tế từ hệ thống chăm sóc khách hàng mà không cần tốn hàng tuần lễ để tạo cặp dữ liệu giả định.
5. Triệt Tiêu Thiên Kiến Độ Dài (Verbosity Bias) & Phương Pháp SimPO
BLUF (Bottom Line Up Front): Các thuật toán căn chỉnh thông thường vô tình khuyến khích mô hình “nói dài để lấy lòng”; SimPO (Simple Preference Optimization) chuẩn hóa hàm mất mát theo độ dài chuỗi ký tự, ngăn chặn hoàn toàn tình trạng văn phong lê thê tốn token.
Một hiện tượng suy thoái phổ biến trong căn chỉnh DPO là Verbosity Bias: mô hình nhận ra rằng các câu trả lời dài thường có điểm phần thưởng ngầm định cao hơn các câu trả lời ngắn gọn. Hậu quả là mô hình bắt đầu chèn thêm hàng loạt đoạn văn mở đầu và kết luận xã giao rườm rà, làm tăng 40% độ trễ sinh từ và lãng phí tài nguyên máy chủ.
SimPO (Simple Preference Optimization, 2024) giải quyết triệt để vấn đề này bằng cách:
- Chuẩn hóa xác suất theo độ dài chuỗi: $\frac{1}{|y|} \log \pi_\theta(y|x)$.
- Đặt một ngưỡng biên độ mục tiêu (target margin $\gamma > 0$):
$$\mathcal{L}{\text{SimPO}} = -\mathbb{E} \left[ \log \sigma \left( \frac{\beta}{|y_w|} \log \pi\theta(y_w|x) - \frac{\beta}{|y_l|} \log \pi_\theta(y_l|x) - \gamma \right) \right]$$
Nhờ đó, một câu trả lời ngắn gọn, đi thẳng vào trọng tâm sẽ giành chiến thắng áp đảo trước một câu trả lời dài dòng nhưng nội dung nghèo nàn.
6. Mã Nguồn Thực Thi: Tinh Chỉnh DPO Bằng Hugging Face TRL
Dưới đây là kịch bản hoàn chỉnh cấu hình DPOTrainer với thư viện TRL để căn chỉnh mô hình Qwen 2.5 7B trên một card đồ họa NVIDIA RTX 4090 24GB:
# train_dpo_alignment.py - Enterprise DPO Alignment Engine (Python 3.11+, TRL 0.12+)
import torch
from datasets import load_dataset
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments
from trl import DPOTrainer, DPOConfig
from peft import LoraConfig, get_peft_model
# 1. Định nghĩa mô hình và siêu tham số
MODEL_ID = "Qwen/Qwen2.5-7B"
OUTPUT_DIR = "/opt/models/qwen7b_dpo_aligned"
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, use_fast=True)
tokenizer.pad_token = tokenizer.eos_token
# 2. Khởi tạo mô hình ở định dạng Bfloat16 với FlashAttention-2
model = AutoModelForCausalLM.from_pretrained(
MODEL_ID,
torch_dtype=torch.bfloat16,
device_map="auto",
attn_implementation="flash_attention_2"
)
# 3. Cấu hình LoRA Adapter (Tận dụng cơ chế PEFT để không cần nạp ref_model riêng)
peft_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
# 4. Thiết lập DPOConfig tối ưu hóa bộ nhớ
dpo_config = DPOConfig(
output_dir=OUTPUT_DIR,
beta=0.1, # Hệ số điều tiết KL (0.1 là giá trị vàng cho 7B)
learning_rate=5e-6, # Tốc độ học nhỏ để tránh vỡ chính sách
per_device_train_batch_size=2,
gradient_accumulation_steps=16, # Tương đương effective batch size = 32
max_length=2048,
max_prompt_length=1024,
num_train_epochs=2,
logging_steps=10,
save_steps=100,
evaluation_strategy="steps",
eval_steps=50,
warmup_ratio=0.1,
bf16=True,
loss_type="sigmoid", # Sử dụng loss Sigmoid chuẩn Bradley-Terry
gradient_checkpointing=True,
report_to="none"
)
# 5. Khởi tạo DPOTrainer
trainer = DPOTrainer(
model=model,
ref_model=None, # Khi dùng LoRA, TRL tự động vô hiệu hóa adapter làm ref_model
args=dpo_config,
peft_config=peft_config,
train_dataset=dataset["train"],
eval_dataset=dataset["test"],
tokenizer=tokenizer,
)
# 6. Bắt đầu huấn luyện căn chỉnh
trainer.train()
trainer.save_model(OUTPUT_DIR)
print("Căn chỉnh DPO hoàn tất thành công. Checkpoint an toàn đã được lưu trữ.")
7. Nghiên Cứu Sự Cố Thực Tế: Sụp Đổ Chính Sách (Policy Collapse) & Lặp Từ Vô Hạn
BLUF (Bottom Line Up Front): Đặt hệ số $\beta$ quá nhỏ ($\beta = 0.01$) kết hợp với việc thiếu mặt nạ phân cách Prompt khiến mô hình học sinh bị vỡ chính sách (Policy Collapse), liên tục sinh ra chuỗi ký tự rỗng hoặc lặp lại dấu chấm than vô hạn trên toàn bộ hệ thống sản xuất.
Dòng thời gian sự cố (Incident Timeline)
┌────────────────────────────────────────────────────────────────────────┐
│ POST-MORTEM: ALIGNMENT POLICY COLLAPSE │
├────────────────────────────────────────────────────────────────────────┤
│ 15:30 UTC: Triển khai mô hình sau căn chỉnh DPO v1.0 lên cụm Gateway. │
│ 15:48 UTC: Hệ thống giám sát phát hiện 100% yêu cầu sinh văn bản chạm │
│ ngưỡng timeout (60 giây). │
│ 16:05 UTC: Phân tích nội dung phản hồi: Mô hình liên tục sinh: │
│ "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" cho đến khi cạn token.│
│ 16:15 UTC: Rollback khẩn cấp về checkpoint SFT trước căn chỉnh. │
│ 17:30 UTC: Tái lập môi trường kiểm thử: Phát hiện giá trị beta = 0.01. │
│ 19:00 UTC: Nâng beta lên 0.1, thêm bộ lọc Margin và huấn luyện lại. │
└────────────────────────────────────────────────────────────────────────┘
Phân tích nguyên nhân kỹ thuật (Technical Root Cause)
- Hệ Số Phạt $\beta$ Quá Nhỏ: Khi kỹ sư đặt $\beta = 0.01$ với hy vọng mô hình “học nhanh và quyết liệt”, khoảng cách KL giữa $\pi_\theta$ và $\pi_{\text{ref}}$ bị nới lỏng quá mức. Mô hình nhanh chóng tìm thấy một điểm cực tiểu cục bộ (local minimum) kỳ dị: sinh ra một token duy nhất có xác suất cực cao để tối đa hóa hàm sigmoid nhân tạo.
- Cặp Dữ Liệu Chênh Lệch Chiều Dài Cực Đoan: Tập dữ liệu có các mẫu trong đó câu trả lời được chọn dài 500 từ trong khi câu bị từ chối chỉ có 10 từ. Gradient của DPO đã trừng phạt tất cả các từ ngắn và đẩy xác suất các token kết thúc câu (
<|im_end|>) xuống 0.
Biện pháp chuẩn hóa phòng ngừa (Remediation Standard)
- Thiết Lập Vùng An Toàn Cho Beta: Khóa cứng tham số $\beta \in [0.08, 0.15]$ trong quy chuẩn CI/CD; từ chối tự động mọi pipeline có cấu hình $\beta < 0.05$.
- Theo Dõi Chỉ Số Implicit Margin Trong Quá Trình Huấn Luyện: Nếu khoảng cách phần thưởng ngầm $\Delta r = r(x, y_w) - r(x, y_l)$ vượt quá ngưỡng 10.0, bộ ngắt mạch (Circuit Breaker) sẽ tự động dừng quá trình huấn luyện để tránh làm cháy trọng số.
- Áp Dụng SimPO Hoặc Length-Penalty: Luôn chuẩn hóa độ dài chuỗi trước khi tính toán gradient để vô hiệu hóa hiện tượng lợi dụng độ dài.
8. Ma Trận Đánh Đổi Công Nghệ: DPO vs GRPO vs KTO vs PPO
Bảng tổng hợp đặc tính kỹ thuật và chi phí vận hành giữa các phương pháp căn chỉnh:
| Phương Pháp Căn Chỉnh | Yêu Cầu Mô Hình Phụ | Bản Chất Dữ Liệu | Độ Tiêu Tốn VRAM | Độ Ổn Định Huấn Luyện | Tác Vụ Phù Hợp Nhất |
|---|---|---|---|---|---|
| DPO | 🟢 Không (Dùng LoRA) | Cặp so sánh $(y_w, y_l)$ | 🟢 Thấp (1x 24GB GPU) | 🟢 Rất cao (Hồi quy tĩnh) | Văn phong, an toàn, đối thoại |
| GRPO | 🟢 Không (Bỏ Critic) | Tín hiệu điểm thưởng quy tắc | 🟡 Vừa (1-2x GPU 24GB) | 🟡 Cao (Cần Oracle chuẩn) | Toán, Code, JSON Schema |
| KTO | 🟢 Không (Dùng LoRA) | Tín hiệu nhị phân đơn lẻ | 🟢 Thấp (1x 24GB GPU) | 🟢 Rất cao | Phản hồi Like/Dislike thực tế |
| PPO Cổ Điển | 🔴 3 mô hình phụ | Trực tuyến + Reward Model | 🔴 Cực lớn (>80GB) | 🔴 Kém (Dễ trôi Critic) | Đã lỗi thời trong môi trường SLM |
9. Căn Chỉnh Ép Tuân Thủ Định Dạng JSON Schema & Tool Calling
BLUF (Bottom Line Up Front): Đối với các tác vụ Agentic AI, thất bại lớn nhất của SLM là sinh sai cú pháp JSON hoặc thừa các ký tự giải thích; căn chỉnh DPO trên các cặp dữ liệu cú pháp sẽ rèn cho mô hình phản xạ xuất ra dữ liệu có cấu trúc nguyên khối 100% hợp lệ.
Để huấn luyện một mô hình ngôn ngữ nhỏ phục vụ cho các quy trình tự động hóa:
- Tạo Cặp Dữ Liệu Âm Có Chủ Đích (Synthetic Schema Violations):
- Chosen ($y_w$): Chuỗi JSON chuẩn xác tuyệt đối, tuân thủ Pydantic Model, không có lời mở đầu hay kết thúc.
- Rejected ($y_l$): Chuỗi JSON bị thiếu dấu ngoặc nhọn, có chứa lời thoại “Dưới đây là kết quả JSON của bạn: …”, hoặc sử dụng dấu nháy đơn thay vì dấu nháy kép.
- Kích Hoạt Trọng Số Phạt Cao: Cấu hình hàm mất mát DPO tập trung phạt nặng các lỗi vi phạm dấu ngoặc đóng mở, giúp tỷ lệ phân tích cú pháp thành công phía backend tăng từ 74% lên 99.8%.
❓ Câu Hỏi Thường Gặp (FAQ)
Tôi nên chọn DPO, GRPO hay KTO cho dự án doanh nghiệp của mình?
Tại sao khi huấn luyện DPO với LoRA tôi không cần cung cấp reference model riêng biệt?
Làm thế nào để nhận biết mô hình đang bị rơi vào hiện tượng Policy Collapse khi căn chỉnh?
loss giảm đột ngột về 0 trong khi độ lệch chuẩn phần thưởng ngầm định rewards/margins tăng vọt lên mức hàng trăm. Lúc này, hãy kiểm tra ngay đầu ra văn bản: nếu mô hình bắt đầu lặp từ, sinh văn bản rỗng hoặc không chịu tạo thẻ kết thúc chuỗi, bạn cần tăng ngay hệ số $\beta$ và kiểm tra lại chất lượng tập dữ liệu.🔗 Chương Tiếp Theo Trong Series
Sau khi mô hình đã được căn chỉnh hành vi hoàn hảo và tuân thủ tuyệt đối các ràng buộc an toàn, bước cuối cùng là tối ưu hóa hạ tầng để phục vụ hàng nghìn người dùng đồng thời:
👉 Phần 6: Tối Ưu Hóa Triển Khai vLLM & Đánh Giá Tự Động.
