Inference Optimization
Tối ưu suy luận — Làm AI nhanh hơn
Model Llama-3 70B trên GPU A100 (80GB) mất 500 ms/request. Bạn cần phục vụ 10.000 người dùng đồng thời với ngân sách cố định — đâu là cách hiệu quả nhất?
Một request LLM đi qua bốn giai đoạn. Pie chart bên dưới hiển thị tỉ lệ thời gian mỗi stage chiếm trong tổng latency — con số trên mỗi lát là mili-giây thực tế với cấu hình hiện tại.
Hình minh họa
Bật các toggle ở mục tiếp theo để xem từng lát thay đổi trực quan.
Bật từng kỹ thuật để xem cumulative speedup — hiệu ứng nhân lên khi kết hợp. Không tối ưu nào là miễn phí: mỗi kỹ thuật có đánh đổi về chất lượng, bộ nhớ, hoặc độ phức tạp triển khai.
Hình minh họa
Batching không giảm latency/request — nó tăng throughput (req/s). Chọn batch size để so sánh throughput ở batch 1, 4, 16, 64.
Hình minh họa
Pareto frontier là tập điểm không thể cải thiện một trục (latency hoặc throughput) mà không hy sinh trục còn lại. Các điểm KHÔNG trên frontier là tối ưu kém — có cấu hình tốt hơn ở cả hai trục.
Hình minh họa
Bốn kỹ thuật không cộng — chúng nhân. KV cache ×2.5, speculative ×2.2, quantization ×1.8 — kết hợp cho ~10× chỉ trên decoding. Thêm batching nâng throughput ×50 mà không cần GPU mới. Đây là lý do model 70B có thể serve tại $0.0003/1K token trên hạ tầng cloud thương mại — điều tưởng chừng không thể nếu chỉ nhìn vào "baseline FP32".
Chatbot của bạn có SLA: p95 latency < 250 ms. Hiện tại baseline FP16 batch=1 cho 500 ms. Kế hoạch nào giúp đạt SLA mà vẫn giữ throughput cao nhất?
Model 70B FP16 = 140 GB. GPU A100 có 80 GB. Dùng quantization nào để fit trên 1 GPU duy nhất?
Giải thích
Tối ưu suy luận (Inference Optimization) là nghệ thuật serving model AI với latency thấp, throughput cao, và chi phí nhỏ — mà KHÔNG đổi kiến trúc model hay huấn luyện lại.
1. Tại sao decoding chậm?
Mỗi token mới phải đi qua toàn bộ model — forward pass của model N tầng có độ phức tạp O(N · d²) với d là hidden size. Với Llama-70B, mỗi token mất ~2–5 ms trên A100. Sinh 512 token → 1–2.5 giây trần. Và không thể song song hoá vì token t+1 cần token t đã sinh (autoregressive).
2. KV Cache — giảm O(N²) xuống O(N)
Self-attention ở mỗi layer:
Khi sinh token thứ t, chỉ Qt mới — còn K1..t-1 và V1..t-1 đã tính ở bước trước. Lưu chúng trong "KV cache" trên GPU memory, mỗi bước chỉ append Kt, Vt. Tiết kiệm ~2.5× trên decoding stage. Xem chi tiết tại KV Cache.
3. Speculative Decoding — dự đoán trước
Ý tưởng (Leviathan et al., 2023): dùng một draft model nhỏ (ví dụ 1B params) sinh k token liên tiếp. Sau đó target model lớn (70B) verify k token trong MỘT forward pass — đây là khâu song song hoá được. Nếu accept m ≤ k token, speedup ≈ m.
với αj là xác suất draft token thứ j được accept. Thực nghiệm cho thấy α ≈ 0.7–0.85, dẫn tới speedup 2–3×.
4. Continuous Batching
Static batching: đợi N request, xử lý cùng lúc, đợi request dài nhất xong. Lãng phí GPU vì các request ngắn kết thúc sớm nhưng slot vẫn chiếm.
Continuous batching (Orca, vLLM): ngay khi một request xong, thay bằng request mới trong cùng batch. GPU utilization tăng từ ~30% lên 90%+. Xem Model Serving và GPU Optimization.
5. Quantization
Giảm số bit/tham số. FP16 → INT8 → INT4:
Techniques: GPTQ, AWQ, SmoothQuant. Chất lượng thường giảm < 1% với INT8, 1–3% với INT4. Chi tiết tại Quantization.
6. Pareto frontier — chọn config phù hợp
Không có "config tốt nhất" — chỉ có config tốt nhất cho một use case:
- Interactive chat: p95 latency < 300 ms → batch nhỏ (1–4), KV cache, speculative.
- Batch job (tóm tắt tài liệu): ưu tiên throughput → batch 64–128, INT4.
- Edge device (điện thoại): ưu tiên bộ nhớ → INT4, model nhỏ (3B–7B).
- RAG pipeline: prefill là bottleneck (prompt dài) → FlashAttention + prefix caching.
from vllm import LLM, SamplingParams
# Model đã quantize AWQ 4-bit: 70B params chỉ 35GB
# vLLM tự động xử lý continuous batching + PagedAttention
llm = LLM(
model="TheBloke/Llama-3-70B-AWQ",
quantization="awq", # 4-bit AWQ
tensor_parallel_size=2, # 2 GPU A100
max_model_len=8192,
gpu_memory_utilization=0.95,
enable_prefix_caching=True, # Cache common system prompts
speculative_model="facebook/opt-1.3b", # Draft model nhỏ
num_speculative_tokens=5, # Propose 5 token mỗi lần
enable_chunked_prefill=True, # Chia prefill thành chunk nhỏ
)
params = SamplingParams(
temperature=0.7,
top_p=0.9,
max_tokens=512,
)
# Gửi nhiều request cùng lúc — vLLM sẽ batch tự động
prompts = [
"Giải thích AI cho học sinh lớp 5",
"Viết đoạn code Python đọc CSV",
"Tóm tắt cuốn sách Sapiens",
# ... hàng trăm request
]
outputs = llm.generate(prompts, params)
# Metrics thực tế trên 2×A100 80GB:
# - Baseline naive FP16: ~200 tokens/s total
# - Với vLLM + AWQ + spec: ~2000–3000 tokens/s total
# - Chi phí giảm ~15× so với HuggingFace pipeline ngây thơ# Khởi động vLLM OpenAI-compatible server
python -m vllm.entrypoints.openai.api_server \
--model TheBloke/Llama-3-70B-AWQ \
--quantization awq \
--tensor-parallel-size 2 \
--max-model-len 8192 \
--gpu-memory-utilization 0.95 \
--enable-prefix-caching \
--enable-chunked-prefill \
--host 0.0.0.0 \
--port 8000
# Client gọi như OpenAI API
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "llama-3-70b",
"messages": [{"role": "user", "content": "Chào bạn"}],
"temperature": 0.7,
"max_tokens": 256
}'
# Benchmark throughput với vllm benchmark tool
python benchmarks/benchmark_serving.py \
--backend vllm \
--model TheBloke/Llama-3-70B-AWQ \
--num-prompts 1000 \
--request-rate 50
# Kết quả điển hình trên 2×A100:
# Successful requests: 1000
# Total tokens: 256000
# Throughput: 2800 tokens/s
# Mean TTFT: 180 ms
# Mean TPOT: 28 ms
# P95 latency: 240 msKhi kết hợp tối ưu suy luận với chiến lược chi phí (spot instance, multi-region, autoscaling) và model serving (canary deploy, A/B test), bạn có được một hệ thống AI production-grade phục vụ hàng triệu người dùng với chi phí kiểm soát được.
- Latency của 1 request LLM = tokenization + prefill + KV lookup + decoding. Decoding chiếm ~68% vì autoregressive.
- KV cache lưu attention đã tính → giảm decoding từ O(N²) xuống O(N), tăng tốc ~2.5×.
- Speculative decoding dùng draft model nhỏ đề xuất, target model verify song song → ×2–3 khi acceptance rate cao.
- Continuous batching tăng throughput ×5–10 mà KHÔNG giảm latency; PagedAttention (vLLM) giảm waste KV cache từ 60% xuống 4%.
- Quantization INT8/INT4 giảm bộ nhớ 4–8× và tăng tốc 1.5–2× — sweet spot INT8 cho chất lượng, INT4 cho tiết kiệm.
- Pareto frontier latency ↔ throughput: không có config tốt nhất — chọn theo SLA. Kết hợp 4 kỹ thuật có thể giảm chi phí 10–50×.
Kiểm tra hiểu biết
Trong một request LLM điển hình (prompt 512 token, sinh 128 token), giai đoạn nào chiếm nhiều latency nhất?