KV Cache, Flash Attention & Inference Optimization
Type: Build
Languages: Python
Prerequisites: Phase 7 · 02 (Self-Attention), Phase 7 · 05 (Full Transformer), Phase 7 · 07 (GPT)
Time: ~75 minutes
Vấn đề
Một máy giải mã tự động thâm nhập ngu ngốc có thể làm được O(N²)làm việc để tạo ra Ntoken: ở mỗi bước nó tính lại sự chú ý trên tiền đề đầy đủ. Đối với một phản ứng 4K-token là 16M các hoạt động chú ý, hầu hết chúng là dư thừa. Mỗi trạng thái ẩn của một tiền đề token là xác định khi được tính toán.
Ngoài ra, sự chú ý tự động di chuyển rất nhiều dữ liệu. Sự chú ý tiêu chuẩn hiện thực hóa một matrix điểm số N×N, đầu ra mềm dẻo N×d, đầu ra cuối cùng N×d đọc và viết quá nhiều cho HBM. Đối với N≥2K, sự chú ý bị ràng buộc trong bộ nhớ trước khi nó trở thành FLOP. Các hạt nhân chú ý cổ điển sử dụng GPU hiện đại ít hơn 410×.
Hai cách tối ưu hóa, cả hai từ Dao et al., đã đẩy suy luận biên giới từ "nước từ" sang "nhanh":
- KV cache.lưu trữ các vector K và V của mỗi token tiền tố. sự chú ý của mỗi token mới là một truy vấn so với các khóa được lưu trữ trong cache.
O(N²)đếnO(N)mỗi bước thế hệ. - Flash Attention.Đặt máy tính chú ý để các n×N matrix đầy đủ không bao giờ chạm vào HBM. Tất cả các softmax + matmul xảy ra trong SRAM. 24× tốc độ đồng hồ tường trên A100; 510× trên H100 với FP8.
Đến năm 2026, cả hai đều phổ biến. Mỗi đống suy luận sản xuất (vLLM, TensorRT-LLM, SGLang, llama.cpp) giả định chúng.
Khái niệm
!KV cache growth and Flash Attention tiling
KV cache toán học
Mỗi lớp giải mã, mỗi token, mỗi đầu:
bytes_per_token_per_layer = 2 * d_head * dtype_size
^
K and VĐối với mô hình 7B với 32 lớp, 32 đầu, d_head=128, fp16:
per token per layer = 2 * 128 * 2 = 512 bytes
per token (32 layers) = 16 KB
per 32K context = 512 MBĐối với Llama 3 70B (80 lớp, d_head=128, GQA với 8 đầu KV):
per token per layer = 2 * 8 * 128 * 2 = 4096 bytes (4 KB)
per 32K context = 10.4 GBĐó là lý do tại sao Llama 3 70B ở 128K cần hầu hết 40 GB A100 chỉ cho bộ nhớ cache KV ở kích thước batch 1.
GQA is the KV-cache win.MHA với 64 đầu sẽ là 32 GB. MLA nén hơn nữa.
Nhổ kích thước và xem kích thước cache di chuyển. Nhấn chiều dài chuỗi hoặc hàng lên và xem nó thổi nhanh như thế nào qua một GPU duy nhất:
Flash Attention thủ thuật làm gạch
Sự chú ý tiêu chuẩn:
S = Q @ K^T (HBM read, N×N, HBM write)
P = softmax(S) (HBM read, HBM write)
O = P @ V (HBM read, HBM write)Ba chuyến đi về và về của HBM. trên H100, băng thông HBM là 3 TB / s; SRAM là 30 TB / s. Mỗi chuyến đi của HBM là một sự chậm lại nhân tố 10 so với giữ mọi thứ trên chip.
Lưu ý:
for each block of Q (tile size ~128 × 128):
load Q_tile into SRAM
for each block of K, V:
load K_tile, V_tile into SRAM
compute S_tile = Q_tile @ K_tile^T (SRAM)
running softmax aggregation (SRAM)
accumulate into O_tile (SRAM)
write O_tile to HBMMột chuyến HBM mỗi tấm.O(N²)đếnO(N). Pass ngược tính lại một số giá trị từ pass phía trước thay vì lưu trữ chúng một bộ nhớ khác giành chiến thắng.
Numerical trick.Tăng tốc độ hoạt động của softmax(max, sum)Phân tích không phải là một cách gần gũi Flash Attention tính toán đầu ra bit giống hệt với sự chú ý tiêu chuẩn (modulo fp16 không liên quan).
Version evolution:
| Version | Year | Key change | Speedup on reference hardware |
|---|---|---|---|
| Flash 1 | 2022 | Tiled SRAM kernel | 2× on A100 |
| Flash 2 | 2023 | Better parallelism, causal-first ordering | 3× on A100 |
| Flash 3 | 2024 | Hopper asynchrony, FP8 | 1.5–2× on H100 (~740 TFLOPs FP16) |
| Flash 4 | 2026 | Blackwell 5-stage pipeline, software exp2 | Inference-first (forward only initially) |
Flash 4 chỉ được tiến hành khi ra mắt. Đào tạo vẫn sử dụng Flash 3. GQA và varlen hỗ trợ cho Flash 4 đang chờ đợi (trung năm 2026).
Việc giải mã giả định chiến thắng độ trễ khác
Mô hình rẻ tiền đề xuất N token. Mô hình lớn xác minh tất cả N song song. Nếu xác minh chấp nhận k token, bạn đã trả 1 thẻ chuyển tiếp mô hình lớn cho k thế hệ.
2026 không phát hành:
- EAGLE 2 / Medusa.Bộ trưởng dự thảo tích hợp chia sẻ trạng thái ẩn của người xác minh. 23x tăng tốc mà không mất chất lượng.
- Speculative decoding with draft model.2×4 tăng tốc trên phần cứng tiêu dùng.
- Lookahead decoding.- Không cần mô hình dự thảo, nhưng miễn phí.
Lượng hàng liên tục
Kết luận đợt cổ điển: chờ đợi chuỗi chậm nhất kết thúc, sau đó bắt đầu một đợt mới.
Lưu lượng liên tục (lưu lượng đầu tiên tại Orca, bây giờ tại vLLM, TensorRT-LLM, SGLang): trao đổi các yêu cầu mới vào lô ngay khi các yêu cầu cũ kết thúc.
PagedAttention KV cache như bộ nhớ ảo
Tính năng tiêu đề của vLLM. KV cache được phân bổ trong 16 khối mã thông báo; một bảng trang lập bản đồ vị trí logic cho các khối vật lý. Cho phép bạn chia sẻ KV trên các mẫu song song (hướng tìm kiếm, lấy mẫu song song), tiền đề hot-swap cho lưu trữ nhanh chóng, và bộ nhớ phân mảnh.
Hãy xây dựng nó
Nhìn xemcode/main.pyChúng tôi thực hiện:
- Một kẻ ngây thơ .
O(N²)decoder tăng trưởng. - A
O(N)KV-cache decoder. - Một Softmax được làm bằng gạch mô phỏng thuật toán chạy tối đa của Flash Attention.
Bước 1: KV cache
pythonclass KVCache:
def __init__(self, n_layers, n_heads, d_head):
self.K = [[[] for _ in range(n_heads)] for _ in range(n_layers)]
self.V = [[[] for _ in range(n_heads)] for _ in range(n_layers)]
def append(self, layer, head, k, v):
self.K[layer][head].append(k)
self.V[layer][head].append(v)
def read(self, layer, head):
return self.K[layer][head], self.V[layer][head]Rất đơn giản: tiếp tục tăng trưởng các vector per token K, V trong các danh sách per layer, per head.
Bước 2: Softmax được làm phay
pythondef tiled_softmax_dot(q, K, V, tile=4):
"""Flash-attention-style softmax(qK^T)V with running max/sum."""
m = float("-inf")
s = 0.0
out = [0.0] * len(V[0])
for start in range(0, len(K), tile):
k_block = K[start:start + tile]
v_block = V[start:start + tile]
scores = [sum(qi * ki for qi, ki in zip(q, k)) for k in k_block]
new_m = max(m, *scores)
exp_old = math.exp(m - new_m) if m != float("-inf") else 0.0
exp_new = [math.exp(sc - new_m) for sc in scores]
s = s * exp_old + sum(exp_new)
for j in range(len(out)):
out[j] = out[j] * exp_old + sum(e * v[j] for e, v in zip(exp_new, v_block))
m = new_m
return [o / s for o in out]Khả năng phát ra bit giống nhau với softmax(qK) Vtrong một lần chụp, nhưng bất cứ lúc nào bộ làm việc là một tile × d_headkhối, không phải toàn bộ N × d_head- Tôi không biết.
Bước 3: So sánh mã hóa ngây thơ so với mã hóa được lưu trữ trong caching trên thế hệ 100 token
- Lưu ý các hoạt động chú ý.
O(N²)= 5050.O(N)Mã in cả hai.
Sử dụng nó
python# HuggingFace transformers auto-enables KV cache on decoder-only generate().
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.2-3B",
attn_implementation="flash_attention_2", # use FA3 if Hopper
torch_dtype="bfloat16",
)
# generate() uses KV cache automaticallysản xuất vLLM:
bashpip install vllm
vllm serve meta-llama/Llama-3.1-70B-Instruct \
--tensor-parallel-size 4 \
--max-model-len 32768 \
--enable-prefix-caching \
--kv-cache-dtype fp8Caching tiền đề trên các yêu cầu là một chiến thắng lớn 2026 cùng một hệ thống nhắc, vài lần chụp ví dụ, hoặc tài liệu ngữ cảnh dài sử dụng lại KV trên các cuộc gọi. Đối với tải trọng công việc của đại lý với nhắc lại các yêu cầu công cụ, Caching tiền đề thường là tăng thông qua 5x.
Chuyển nó
Nhìn xemoutputs/skill-inference-optimizer.md. Khả năng chọn sự thực hiện chú ý, chiến lược cache KV, định lượng và giải mã suy đoán cho việc triển khai suy luận mới.
Các bài tập
- Easy.Đi chạy
code/main.py- Đảm bảo các máy giải mã ngây thơ và được lưu trữ trong cache tạo ra cùng một đầu ra; lưu ý sự khác biệt trong số op. - Medium.Thực hiện bộ nhớ cache tiền tố: với một prompt P và một số hoàn thành, chạy một lần đi trước trên P để lấp đầy bộ nhớ cache KV, sau đó nhánh cho mỗi hoàn thành.
- Hard.Thực hiện một đồ chơi PagedAttention: KV cache trong các khối 16 token cố định với một danh sách miễn phí. Khi một chuỗi kết thúc, trả lại các khối của nó cho hồ bơi. Mô phỏng 1.000 kết thúc trò chuyện với chiều dài khác nhau. So sánh phân mảnh bộ nhớ so với phân bổ liền kề.
Các điều khoản chính
| Term | What people say | What it actually means |
|---|---|---|
| KV cache | "The trick that makes decoding fast" | Stored K and V from every prefix token; new queries attend to them instead of recomputing. |
| HBM | "GPU main memory" | High Bandwidth Memory; 80 GB on H100, 192 GB on B200. ~3 TB/s bandwidth. |
| SRAM | "On-chip memory" | Per-SM fast memory, ~256 KB per SM on H100. ~30 TB/s bandwidth. |
| Flash Attention | "Tiled attention kernel" | Computes attention without materializing N×N in HBM. |
| Continuous batching | "No-wait batching" | Swap finished sequences out, new ones in, without draining the batch. |
| PagedAttention | "vLLM's headline" | KV cache allocated in fixed blocks with a page table; eliminates fragmentation. |
| Prefix caching | "Reuse long prompts" | Cache KV for a shared prefix across requests; major cost cut for agents. |
| Speculative decoding | "Draft + verify" | Cheap draft model proposes tokens; big model verifies k in one pass. |
Đọc thêm
- Dao et al. (2022). FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness Flash 1.
- Dao (2023). FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning Flash 2.
- Shah et al. (2024). FlashAttention-3: Fast and Accurate Attention with Asynchrony and Low-precision Flash 3.
- FlashAttention-4 release notes (Dao-AILab, 2026) Blackwell 5 giai đoạn đường ống và trò chơi phần mềm-exp2; đọc repo README cho các cảnh báo phóng chỉ đi trước bài học này đề cập.
- Kwon et al. (2023). Efficient Memory Management for Large Language Model Serving with PagedAttention giấy vLLM.
- Leviathan et al. (2023). Fast Inference from Transformers via Speculative Decoding Tự giải mã thông số.
- Li et al. (2024). EAGLE: Speculative Sampling Requires Rethinking Feature Uncertainty Bài báo EAGLE-1/2 cho phương pháp tiếp cận dự thảo tích hợp bài học đề cập.
- Cai et al. (2024). Medusa: Simple LLM Inference Acceleration Framework with Multiple Decoding Heads phương pháp Medusa được tham khảo cùng với Eagle.
- vLLM docs — PagedAttention canonical deep dive trên 16 token block và trang-table thiết kế.
This free lesson is part of the AI Engineering from Scratch curriculum. Read the full explanation, run the lesson code, and verify the result in the interactive reader or from the repository source.
Browse the complete course catalog or open this lesson on GitHub.