Trong software engineering, có một câu hỏi cổ điển: “tôi nên thuê thêm dev, mua thêm server, hay đầu tư tooling?”. Đây là bài toán phân bổ nguồn lực. Câu trả lời phụ thuộc vào constraint hiện tại (CPU bound, memory bound, hay developer bound).
Trong LLM, có câu hỏi tương tự: “tôi có $1M budget GPU, nên train model 1B với 100B tokens, hay model 10B với 30B tokens, hay model 70B với 5B tokens?”. Cả ba option đều dùng cùng compute, nhưng kết quả khác nhau hàng chục lần về quality.
Đây không phải đoán. Có công thức rõ ràng, gọi là scaling laws. Bài này đi từ Kaplan 2020 (paper khởi đầu) đến Chinchilla 2022 (paper sửa lỗi Kaplan) đến cách Llama-3 và GPT-4 dùng scaling laws hôm nay.
Sau bài này bạn biết: với budget cụ thể, model bao nhiêu params và bao nhiêu data là tối ưu. Đây là kiến thức “economist của ML engineer”.
Mental model: tam giác Compute, Params, Data
Có 3 đại lượng quan trọng trong pretraining:
Compute (C)
[FLOPs total]
/\
/ \
/ \
Params / \ Data
(N) / \ (D)
/ \
/________________\
Quan hệ: C ≈ 6 * N * D (rule of thumb).
Một forward pass tốn ~2*N*D FLOPs. Backward tốn ~4*N*D. Tổng ~6*N*D cho một full training run trên D tokens với model N params.
Ví dụ:
- Llama-3-8B: N = 8e9, D = 15e12 tokens, C ≈ 6 * 8e9 * 15e12 ≈ 7.2e23 FLOPs
- GPT-3-175B: N = 175e9, D = 300e9 tokens, C ≈ 6 * 175e9 * 300e9 ≈ 3.15e23 FLOPs
Llama-3-8B dùng compute hơn 2x GPT-3-175B, mặc dù model nhỏ hơn 22 lần. Tại sao? Vì data nhiều hơn 50 lần. Đây là phát hiện chính của Chinchilla.
Phần 1: Kaplan 2020, paper đầu tiên
Năm 2020, OpenAI publish paper “Scaling Laws for Neural Language Models” (Kaplan và team). Đây là lần đầu tiên có công thức rõ ràng cho LLM:
Loss(N, D) = (N_c / N)^α + (D_c / D)^β
Trong đó:
N= số params,D= số tokens trainingN_c,D_clà hằng số (depend on architecture)α ≈ 0.076,β ≈ 0.103
Hệ quả Kaplan kết luận: với compute budget cố định, nên dùng model lớn và data ít hơn. Cụ thể: nhân đôi compute thì nhân params với 5.5x và nhân data với 1.8x.
Đây là lý do GPT-3 (2020) có 175B params nhưng chỉ 300B tokens. Theo Kaplan, đó là tối ưu cho compute budget đó.
Spoiler: Kaplan đã sai. Hai năm sau, DeepMind sẽ chỉ ra lý do.
Phần 2: Chinchilla 2022, paper sửa lỗi
Năm 2022, DeepMind publish “Training Compute-Optimal Large Language Models” (Hoffmann và team). Họ train 400+ models với nhiều combination params/data khác nhau, rồi fit lại scaling laws.
Kết luận sốc: Kaplan undersize data. Công thức tối ưu thật sự là:
N_opt(C) ≈ 0.6 * C^0.5
D_opt(C) ≈ 0.3 * C^0.5
(với compute đo bằng FLOPs)
Tức là khi nhân đôi compute, nên nhân params x sqrt(2) và data x sqrt(2), không phải 5.5x params và 1.8x data như Kaplan nói.
Ratio tối ưu: 20 tokens / parameter. Một model N params nên train với ~20N tokens.
| Model size | Tokens tối ưu (Chinchilla) | Tokens thực tế |
|---|---|---|
| 1B | 20B | varies |
| 7B | 140B | LLaMA-1: 1T; Llama-3: 15T (oversized) |
| 70B | 1.4T | LLaMA-2: 2T; Llama-3: 15T |
| 175B | 3.5T | GPT-3: 300B (undersize 12x) |
| 400B | 8T | Llama-3-405B: 15T |
GPT-3 undersize data 12 lần so với Chinchilla optimal. Có nghĩa là cùng 175B params đó, nếu train 3.5T tokens thay vì 300B, model sẽ tốt hơn rất nhiều.
DeepMind validate phát hiện này bằng cách train Chinchilla 70B với 1.4T tokens, ngang compute Gopher 280B với 300B tokens. Chinchilla 70B đánh bại Gopher 280B trên gần như mọi benchmark, mặc dù chỉ 1/4 params. Quote chính thức của paper: “Gopher is substantially over-sized for its compute budget”.
Phần 3: Tại sao Kaplan sai
Hai lý do chính:
1. Learning rate schedule. Kaplan train tất cả model với cùng số step. Model lớn cần lr cao hơn, model nhỏ cần lr thấp hơn. Nếu không tune lr theo size, model nhỏ bị undertrain.
2. Bộ data nhỏ. Kaplan chỉ thử data lên đến ~25B tokens. Khi data nhỏ, không thể phân biệt được “thêm data” và “thêm params” cái nào quan trọng hơn. Chinchilla scale lên 100B+ tokens nên thấy rõ data quan trọng hơn nhiều so với Kaplan ước tính.
Bài học cho dev: đừng tin scaling law nào nếu nó được fit trên data nhỏ. Khi data scale lên 1000x, các pattern lúc nhỏ có thể đảo ngược hoàn toàn.
Phần 4: Hệ quả thời 2024-2026
Sau Chinchilla, có hai trường phái:
Trường phái A: train tới Chinchilla optimal. Model size cân với data theo công thức. Ví dụ: muốn model 10B params, train với 200B tokens.
Trường phái B: undertrain params, overtrain data. Train model nhỏ hơn với data nhiều hơn Chinchilla optimal rất nhiều. Llama-3-8B với 15T tokens là ví dụ. 15T tokens là 94x Chinchilla optimal cho 8B.
Tại sao Meta chọn B? Vì inference cost matters more than training cost.
Reasoning:
- Train model 8B với 15T tokens tốn
7.2e23FLOPs, 1 lần. - Sau khi train, inference 1 lần tốn
~16B FLOPs(2*N với N=8B). - Model 8B sẽ được dùng tỷ lần sau khi train.
- Model 70B inference tốn 8.75x hơn 8B.
Nếu inference billions of times, oversizing data trong training để có model nhỏ hơn nhưng good enough là kinh tế nhất. Đây là logic “train hard, deploy cheap” của Meta/Apple/Anthropic.
GPT-4 và Claude theo trường phái B nhiều. Model size không tăng nhanh như compute, nhưng data tăng nhanh.
Phần 5: Tính compute cho dự án của bạn
Giả sử bạn muốn fine-tune một model 7B với một corpus tiếng Việt 10B tokens, trên 8x A100 (80GB). Hỏi: bao lâu?
Bước 1: tính FLOPs cần.
C = 6 * N * D
= 6 * 7e9 * 10e9
= 4.2e20 FLOPs
Bước 2: tính throughput GPU.
A100 BF16 peak: 312 TFLOPS = 3.12e14 FLOPS/s/GPU.
8 GPU: 2.5e15 FLOPS/s.
Hiệu suất thực tế (MFU, Model FLOPs Utilization): khoảng 40-50% cho transformer training. Lấy 0.45.
Effective throughput: 2.5e15 * 0.45 = 1.12e15 FLOPS/s.
Bước 3: thời gian.
T = C / throughput
= 4.2e20 / 1.12e15
= 3.75e5 giây
≈ 104 giờ
≈ 4.3 ngày
Vậy fine-tune 7B với 10B tokens trên 8x A100 mất khoảng 4-5 ngày. Nếu thuê GPU rental khoảng $1.5/hr/GPU, tổng cost: 8 * 104 * 1.5 = $1,250.
Đây là estimate, thực tế thường thêm 20-30% cho data loading, eval, checkpoint, etc. Cứ nhân 1.3 cho an toàn: ~$1,600.
Pattern này áp dụng được mọi setup. Có 3 con số: N, D, throughput của hardware. Là estimate được cost training trong 5 phút.
Phần 6: Khi nào scaling laws KHÔNG đúng
Scaling laws được fit cho pretraining loss. Có 3 trường hợp công thức không apply:
1. Fine-tuning trên data nhỏ. Chinchilla ratio 20 tokens/param chỉ áp dụng cho pretraining. Fine-tune trên 10K samples không cần model 0.5B params.
2. Domain-specific data. Code data, math data, medical data có scaling khác. Một paper 2024 (DeepSeek) chỉ ra code data scaling tốt hơn natural text khi train code model.
3. Emergent abilities. Một số ability (chain-of-thought, in-context learning) chỉ xuất hiện khi model vượt ngưỡng (vài tỷ params trở lên). Loss giảm smooth nhưng ability xuất hiện bất ngờ. Scaling laws predict loss, không predict ability.
Pitfall: ước tính compute nhầm
Có một lần tôi setup một experiment train một transformer 100M params trên 5B tokens. Estimate trên giấy: 3e18 FLOPs, throughput 1 GPU A100 hiệu suất 40%, ra ~2 giờ. Thực tế chạy 12 tiếng.
Nguyên nhân:
- Data loading bottleneck. Tokenize on-the-fly từ raw text, CPU không theo kịp GPU. GPU idle 60% thời gian.
- Batch size quá nhỏ. Set batch_size = 32 vì không tune. A100 cần batch lớn để bão hòa. Tăng lên 128 thì throughput tăng 2.5x.
- Logging quá nhiều. In loss mỗi step, sync với tensorboard. Bottleneck CPU.
Fix:
- Pre-tokenize data, save vào numpy memmap.
- Tăng batch size tới giới hạn OOM.
- Log mỗi 50 step thôi.
Bài học: scaling law ước tính FLOPs, không ước tính wall-clock. Wall-clock phụ thuộc rất nhiều vào data pipeline, batch size, MFU. Luôn benchmark thực tế trên một sub-run nhỏ trước khi commit budget lớn.
Cheatsheet
| Quantity | Symbol | Đơn vị |
|---|---|---|
| Params | N | số (8e9 cho 8B) |
| Training tokens | D | số (15e12 cho 15T) |
| Compute | C | FLOPs (6ND) |
| Loss | L | nat / token |
| Wall-clock | T | giây |
| Chinchilla ratio | 20 tokens / parameter |
|---|---|
| Kaplan ratio (sai) | ~1.7 tokens / parameter |
| Llama-3 ratio (oversize data) | 1875 tokens / parameter cho 8B |
| Hardware | Peak BF16 FLOPS | MFU thực tế |
|---|---|---|
| A100 80GB | 312 TFLOPS | 35-50% |
| H100 80GB | 989 TFLOPS | 40-55% |
| H200 141GB | 989 TFLOPS | 45-60% |
| TPU v5p | 459 TFLOPS | 50-60% |
| Use case | Tokens cần |
|---|---|
| Pretrain Chinchilla-optimal 1B model | 20B tokens |
| Pretrain Llama-style 7B (oversized) | 1T+ tokens |
| Continue pretrain trên domain mới | 1-50B tokens |
| Fine-tune SFT instruction | 10K-1M samples |
| LoRA adapter | 1K-100K samples |
Lời kết
Scaling laws là khung kinh tế của LLM. Chúng không phải định luật vật lý cứng, nhưng đủ chính xác để estimate cost trước khi spend GPU. Một junior research engineer học scaling laws đầu tiên là vì lý do đó: trước khi đề xuất experiment $50K, phải biết kết quả gần đúng là gì.
Hands-on song song:
- Đọc paper Chinchilla nguyên gốc (“Training Compute-Optimal Large Language Models”, Hoffmann 2022 trên arXiv). Pretty đọc được, không cần background ML sâu. Tập trung Figure 1 và 3.
- Mở một spreadsheet, làm bảng
(N, D, C, time)cho 5 model: 100M, 1B, 7B, 70B, 175B. Hyperparam: 1x A100, MFU 0.4. Xem chênh lệch wall-clock. - Đọc Llama-3 paper Section “Pre-training”. Nhận diện chỗ Meta giải thích tại sao chọn 15T tokens cho 8B (cost-effective inference). Đây là ví dụ kinh điển của trường phái “overtrain data”.
- Tool gợi ý: Karpathy có một calculator nhỏ trong nanoGPT repo (
tools/cost.pymock), nhưng đơn giản hơn là tự viết một function Python. Input: N, D, GPU type, num GPU. Output: time và estimated USD.
Bài 16 sẽ vào mixed precision FP16/BF16 và gradient checkpointing. Hai kỹ thuật cơ bản để giảm memory mà mọi LLM trainer phải biết. Khi train 7B model trên 1 GPU 24GB VRAM, mixed precision là khác biệt giữa “chạy được” và “OOM ngay step đầu”.