Kiến trúc LLM¶
Hiểu bên trong một Large Language Model: từ cơ chế Attention đến quy trình huấn luyện Pre-train và Post-train.
1. Attention Mechanism¶
Vấn đề Attention giải quyết¶
Trước Attention, RNN/LSTM xử lý token tuần tự - thông tin từ đầu câu dần "mờ nhạt" khi câu dài. Attention cho phép model nhìn trực tiếp đến bất kỳ vị trí nào trong sequence, bất kể khoảng cách.
Scaled Dot-Product Attention¶
Mỗi token được biểu diễn bằng 3 vector:
| Vector | Ký hiệu | Ý nghĩa |
|---|---|---|
| Query | Q | "Tôi đang tìm kiếm thông tin gì?" |
| Key | K | "Tôi chứa thông tin gì?" |
| Value | V | "Nội dung thực tế tôi mang theo" |
Giải thích từng bước:
1. Q · Kᵀ → Ma trận điểm tương đồng (mỗi token "hỏi" mọi token)
2. / √dₖ → Scale để tránh gradient vanishing khi dₖ lớn
3. softmax(...) → Chuyển thành phân phối xác suất (tổng = 1)
4. × V → Tổng có trọng số của các Values
import torch
import torch.nn.functional as F
def scaled_dot_product_attention(Q, K, V, mask=None):
d_k = Q.shape[-1]
scores = torch.matmul(Q, K.transpose(-2, -1)) / (d_k ** 0.5)
if mask is not None:
scores = scores.masked_fill(mask == 0, float('-inf'))
weights = F.softmax(scores, dim=-1)
return torch.matmul(weights, V), weights
Multi-Head Attention¶
Thay vì 1 Attention, dùng H heads song song - mỗi head học một loại quan hệ khác nhau.
Input X
├─ Head 1: Q₁K₁V₁ → học quan hệ cú pháp (subject-verb)
├─ Head 2: Q₂K₂V₂ → học quan hệ ngữ nghĩa (co-reference)
├─ Head 3: Q₃K₃V₃ → học quan hệ vị trí (nearby tokens)
└─ ...
Concat → Linear → Output
MultiHead(Q, K, V) = Concat(head₁, ..., headₕ) · Wᴼ
headᵢ = Attention(Q·Wᵢ^Q, K·Wᵢ^K, V·Wᵢ^V)
Wᵢ^Q, Wᵢ^K, Wᵢ^V : projection riêng của từng head
Wᴼ : output projection chung (sau khi Concat)
Ví dụ với GPT-3
GPT-3 dùng 96 attention heads, mỗi head có dimension 128 (tổng d_model = 12,288).
Causal (Masked) Attention¶
Trong LLM, token chỉ được attend đến các token trước nó - không được "nhìn tương lai" khi generate.
Thực hiện bằng cách mask phần trên của attention matrix:
mask = torch.tril(torch.ones(seq_len, seq_len))
# [[1, 0, 0, 0, 0],
# [1, 1, 0, 0, 0],
# [1, 1, 1, 0, 0], ...]
Chi phí O(n²) của Attention
Ma trận Q·Kᵀ có kích thước n × n (n = số token) → compute và bộ nhớ tăng bình phương theo độ dài sequence. Đây là lý do trực tiếp dẫn tới các kỹ thuật tối ưu inference như KV-cache, FlashAttention và quantization (xem Serving Local LLMs).
2. Transformer Block¶
Kiến trúc tổng thể¶
Một Transformer decoder block (dùng trong GPT, Llama, v.v.) gồm các layer xếp chồng:
Input Embedding + Positional Encoding
│
┌────▼────┐
│ Block 1 │ ──┐
└────┬────┘ │
│ │ × N lần (32–96 blocks tùy model)
┌────▼────┐ │
│ Block 2 │ ──┘
└────┬────┘
│
┌────▼────────────┐
│ LM Head (Linear│
│ + Softmax) │
└─────────────────┘
│
Next token probabilities
Bên trong một Block¶
Input (x)
│
┌───────────┤
│ ▼
│ Layer Norm (Pre-LN)
│ │
│ Multi-Head Attention
│ │
└──────(+)──┘ ← Residual connection
│
┌───────┤
│ ▼
│ Layer Norm
│ │
│ Feed-Forward Network
│ (MLP: Linear → GELU → Linear)
│ │
└──(+)──┘ ← Residual connection
│
Output
Từng thành phần¶
Layer Normalization
Chuẩn hóa mỗi token embedding độc lập (không phụ thuộc batch size):
Hai vị trí phổ biến: - Post-LN (Transformer gốc): LayerNorm sau Attention/FFN - Pre-LN (GPT-2 trở đi): LayerNorm trước - ổn định training hơn
Feed-Forward Network (FFN)
Áp dụng trên từng token độc lập (không có cross-token interaction):
# Transformer gốc / GPT-2: 2 Linear với GELU
FFN(x) = W₂ · GELU(W₁ · x + b₁) + b₂ # d_ff ≈ 4 × d_model
# Model hiện đại (Llama, Mistral): SwiGLU - 3 Linear
FFN(x) = W₂ · (Swish(W₁ · x) ⊙ W₃ · x) # d_ff ≈ 2/3 × 4 × d_model
GELU vs SwiGLU
Transformer gốc dùng activation GELU với 2 ma trận. Các model hiện đại chuyển sang SwiGLU (gated, 3 ma trận) cho chất lượng tốt hơn - bù lại d_ff được giảm xuống ~2/3 để giữ tổng số param tương đương.
FFN là 'bộ nhớ' của model
Nghiên cứu cho thấy FFN lưu trữ factual knowledge (kiến thức sự kiện), trong khi Attention xử lý quan hệ ngữ cảnh.
Residual Connections
Cho phép gradient chảy thẳng qua nhiều layer - giải quyết vanishing gradient khi có 32–96 blocks.
Positional Encoding
Transformer không có khái niệm thứ tự tự nhiên - cần thêm vào:
| Loại | Ví dụ | Đặc điểm |
|---|---|---|
| Absolute (learned) | GPT-2, BERT | Học vị trí, bị giới hạn bởi max_position |
| Absolute (sinusoidal) | Transformer gốc | Công thức toán học, extrapolate được |
| RoPE (Rotary) | Llama, Mistral | Encode relative position → dùng phổ biến nhất hiện nay |
| ALiBi | MPT | Thêm bias vào attention scores |
Kích thước và Parameters¶
Ước lượng cho model d_model = 4096, 32 layers, vocab ~128k (~ Llama 3 8B):
| Component | Parameters |
|---|---|
| Token embedding | 128000 × 4096 ≈ 0.5B |
| Mỗi Attention (Q+K+V+O, MHA thuần) | 4 × 4096² ≈ 67M |
| Mỗi FFN (SwiGLU, 3 Linear) | 3 × 4096 × 14336 ≈ 176M |
| 1 Block tổng | ~240M |
| 32 Blocks | ~7.5B |
| Tổng model | ~8B params |
Grouped-Query Attention (GQA)
Công thức 4 × 4096² ở trên chỉ đúng cho Multi-Head Attention thuần. Các model hiện đại (Llama 3, Qwen 2.5, Mistral) dùng GQA - nhiều query head chia sẻ chung một nhóm K/V head. Ví dụ Llama 3 8B có 32 query head nhưng chỉ 8 K/V head → K và V chỉ chiếm 2 × 4096 × 1024 thay vì 2 × 4096². Điều này giảm đáng kể kích thước KV-cache lúc inference (xem Serving Local LLMs), nên con số param thực tế của khối Attention nhỏ hơn ước lượng MHA.
3. Pre-training¶
Mục tiêu¶
Pre-training xây dựng world knowledge và language understanding từ lượng văn bản khổng lồ - đây là bước tốn kém nhất (hàng triệu đô la GPU compute).
Objective: Next-Token Prediction¶
Model học dự đoán token tiếp theo, tối thiểu hóa cross-entropy loss:
Text: "Hà Nội là thủ đô của Việt"
↑
Model dự đoán: "Nam" (token tiếp theo)
Loss = -log P(Nam | Hà, Nội, là, thủ, đô, của, Việt)
Sau hàng tỷ ví dụ, model phải học: - Ngữ pháp và cú pháp - Kiến thức thực tế (địa lý, lịch sử, khoa học) - Code, toán học, logic - Nhiều ngôn ngữ đồng thời
Dữ liệu Pre-training¶
Common Crawl (web) ──────────────────── 67% (Llama 3)
Code (GitHub, v.v.) ──────── 8%
Books ────── 4.5%
Wikipedia ──── 4.5%
Other curated ────────────── 16%
Data quality > Data quantity
Llama 3 dùng 15 nghìn tỷ tokens với filtering nghiêm ngặt. Model yếu thường do data xấu, không phải do ít data.
Scaling Laws¶
Nghiên cứu Chinchilla (DeepMind, 2022) xác định tỷ lệ tối ưu:
Tokens tối ưu ≈ 20 × số parameters
Ví dụ:
- Model 7B → train trên ~140B tokens
- Model 70B → train trên ~1.4T tokens
Trong thực tế, các lab thường train nhiều hơn mức tối ưu để có model mạnh hơn ở inference.
Kỹ thuật quan trọng trong Pre-training¶
Mixed Precision Training (BF16/FP16)
Gradient Checkpointing
Không lưu tất cả activations - tính lại khi backward. Giảm VRAM ~√N lần, tăng thời gian ~30%.
Learning Rate Schedule
LR
│ ╱‾‾‾‾‾‾‾‾‾‾╲
│ ╱ ╲___________
│╱ (warmup) (cosine decay)
└──────────────────────────────▶ Steps
4. Post-training¶
Mục tiêu¶
Base model sau pre-training biết rất nhiều nhưng không biết cách trả lời câu hỏi - nó chỉ "tiếp tục văn bản". Post-training biến base model thành assistant hữu ích, an toàn, và đúng format.
Base Model (Llama 3 Base) → Assistant Model (Llama 3 Instruct)
"Hà Nội là thủ đô... [tiếp tục]" "Hà Nội là thủ đô của Việt Nam, là..."
Giai đoạn 1: Supervised Fine-tuning (SFT)¶
Fine-tune model trên các cặp (instruction, response) chất lượng cao:
# Dữ liệu SFT có format:
{
"messages": [
{"role": "system", "content": "Bạn là trợ lý hữu ích."},
{"role": "user", "content": "Giải thích attention mechanism."},
{"role": "assistant", "content": "Attention mechanism là..."}
]
}
# Loss chỉ tính trên phần assistant response (không tính user/system)
Nguồn dữ liệu SFT: - Human-written (chất lượng cao, đắt) - Teacher model generated (GPT-4, Claude tạo → distillation) - Tập hợp open-source: OpenAssistant, Dolly, ShareGPT
Giai đoạn 2: RLHF / Preference Learning¶
Mục tiêu: model không chỉ cần đúng mà còn cần phù hợp với preference của người dùng (helpful, honest, harmless).
Cách hoạt động của RLHF:
1. Thu thập preference data:
Prompt → [Response A] vs [Response B] → Human chọn cái tốt hơn
2. Train Reward Model (RM):
RM(prompt, response) → scalar score
3. RL fine-tuning (PPO):
Policy (LLM) cố maximize reward từ RM
+ KL penalty để không "cheat" RM quá xa base model
Thách thức của RLHF: - Tốn kém (cần human raters) - Reward hacking (model "gian lận" để có score cao mà không thực sự tốt) - PPO phức tạp, không ổn định
Giai đoạn 2 (alternative): DPO¶
Direct Preference Optimization - không cần Reward Model riêng biệt, fine-tune trực tiếp từ preference pairs:
# Dữ liệu DPO:
{
"prompt": "Giải thích tại sao bầu trời màu xanh?",
"chosen": "Bầu trời xanh do tán xạ Rayleigh...", # Response tốt hơn
"rejected": "Bầu trời màu xanh vì trời xanh." # Response kém hơn
}
# DPO loss tối ưu trực tiếp từ preference pairs
# Đơn giản hơn PPO, ổn định hơn, kết quả tương đương
Trend hiện nay
Hầu hết open-source models (Llama 3, Qwen 2.5, Mistral) dùng DPO hoặc biến thể (SimPO, IPO) thay vì RLHF truyền thống.
So sánh các bước Post-training¶
graph TD
BASE["Base Model (Pre-trained)"] --> SFT
SFT["SFT - Supervised Fine-tuning"] -->|"Dạy format & instruction-following"| ALIGN
ALIGN{"Alignment Method?"}
ALIGN -->|"Có human feedback"| RLHF
ALIGN -->|"Chỉ có preference pairs"| DPO
RLHF["RLHF - Reinforcement Learning from Human Feedback"] --> FINAL
DPO["DPO - Direct Preference Optimization"] --> FINAL
FINAL["Chat/Instruct Model - Helpful + Safe"]
Tóm tắt: Base vs Instruct Model¶
| Base Model | Instruct/Chat Model | |
|---|---|---|
| Hành vi | Tiếp tục văn bản | Trả lời câu hỏi |
| Ví dụ | Llama-3-8B | Llama-3-8B-Instruct |
| Dùng khi | Fine-tune thêm, research | Production, end-user |
| System prompt | Không hiểu | Hiểu và tuân theo |
5. Knowledge Distillation¶
Khái niệm¶
Distillation chuyển giao "kiến thức" từ model lớn (teacher) sang model nhỏ (student) - một cách train ra model nhỏ hơn thay vì nén model có sẵn.
Teacher (70B) → [Distillation Process] → Student (7B)
Chậm, đắt Nhanh, rẻ
(gần đạt chất lượng teacher)
Các phương pháp¶
Response Distillation (Data Distillation)
# Dùng teacher model tạo training data cho student
teacher_outputs = []
for prompt in dataset:
response = teacher_model.generate(prompt)
teacher_outputs.append({"input": prompt, "output": response})
# Fine-tune student model trên data này
student_model.finetune(teacher_outputs)
Logit Distillation (KL Divergence)
Thay vì học từ hard labels (đúng/sai),
student học từ soft probability distributions của teacher.
Teacher: {"con mèo": 0.7, "con chó": 0.2, "con vật": 0.1}
Student: Học để match distribution này → hiểu "relationships" giữa tokens
So sánh các kỹ thuật thu nhỏ model¶
| Phương pháp | Cơ chế | Kết quả |
|---|---|---|
| Distillation | Train lại model nhỏ hơn | Model nhỏ hơn, architecture khác |
| Quantization | Giảm precision của weights | Model nhỏ hơn, cùng architecture |
| Pruning | Xóa weights không quan trọng | Model thưa, cùng architecture |
Distillation (train) vs Quantization (deploy)
Distillation tạo ra model mới ở giai đoạn training - gần với Pre-train/Post-train. Quantization là kỹ thuật áp dụng lúc deploy model có sẵn, được trình bày chi tiết ở Serving Local LLMs.
Tóm tắt kiến trúc¶
graph TD
INPUT["Input Tokens"] --> EMB["Token Embedding + Positional Encoding (RoPE)"]
EMB --> B1
subgraph BLOCKS["x32 Transformer Blocks"]
B1["Layer Norm"] --> ATTN["Multi-Head Causal Attention"]
ATTN --> R1["Residual +"]
R1 --> B2["Layer Norm"]
B2 --> FFN["Feed-Forward Network: Linear - GELU - Linear"]
FFN --> R2["Residual +"]
end
R2 --> LMH["LM Head: Linear + Softmax"]
LMH --> OUT["Next Token Probabilities"]
| Giai đoạn | Mục tiêu | Chi phí | Kết quả |
|---|---|---|---|
| Pre-training | World knowledge | Hàng triệu USD | Base model |
| SFT | Instruction following | Hàng nghìn USD | Biết trả lời đúng format |
| RLHF / DPO | Alignment | Vài nghìn USD | Helpful + Harmless |