Bỏ qua

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.

Câu: "Con mèo ngồi trên chiếc ghế mà nó thích nhất."
                         "nó" cần attend đến "mèo" (cách xa 7 tokens)

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"
Attention(Q, K, V) = softmax(Q·Kᵀ / √dₖ) · V

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.

Token:   [The]  [cat]  [sat]  [on]  [the]
"sat"     ✓      ✓      ✓     ✗     ✗
"the"     ✓      ✓      ✓     ✓     ✓
(vị trí thứ 5)

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, FlashAttentionquantization (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):

# Với mỗi vector x ∈ ℝᵈ
x_norm = (x - mean(x)) / std(x) * γ + β

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

output = x + Sublayer(x)

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 knowledgelanguage 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)

# Weights lưu FP32, compute bằng BF16/FP16
# Giảm ~2× VRAM, tăng ~2× tốc độ

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