Prefix Caching — System prompt giống nhau? Tính 1 lần, dùng ngàn lần
Kỹ thuật Prefix Caching giúp giảm 90% chi phí inference bằng cách tái sử dụng KV cache cho phần prompt chung, biến GPU từ máy tính lại thành máy tra cứu.
Khi bạn triển khai hệ thống AI cho hàng nghìn người dùng — dù là chatbot RAG hay agentic workflow — 80-90% nội dung prompt lặp lại giống hệt nhau: system instructions, tool definitions, hay ngữ cảnh tài liệu. Nếu không có Prefix Caching, bạn đang trả tiền GPU để tính toán đi tính lại cùng một phép nhân ma trận hàng nghìn lần. Anthropic báo cáo giảm 90% chi phí và 85% độ trễ chỉ bằng cách đừng làm việc thừa.
Vấn đề
Trong inference LLM, giai đoạn prefill (xử lý prompt đầu vào) là kẻ giết chết Time-To-First-Token (TTFT). Với một agent thực thi multi-step reasoning, mỗi lượt gọi API đều mang theo cùng một khối system prompt 2K tokens và context RAG 8K tokens. Không có caching, GPU phải chạy forward pass qua 10K tokens đó cho mỗi request — dù nội dung chưa từng thay đổi.
Vấn đề trở nên nghiêm trọng với KV cache. Mỗi lần tính attention cho token thứ i, model cần Key (K) và Value (V) của tất cả token trước đó. Nếu bạn có 1000 request song song, mỗi request 10K tokens, bạn đang tính 10 triệu lần projection K/V cho cùng một đoạn text. Đây là sự lãng phí FLOPs khổng lồ và là lý do tại sao các hệ thống production trước đây phải "đốt" GPU để xử lý prompt dài, trong khi phần sinh token (decode) lại nhanh.
Ý tưởng cốt lõi
KV cache chính là "trạng thái tinh thần" của model sau khi đọc prompt. Khi hai người đọc cùng một chương sách, "hiểu biết" của họ về chương đó là giống hệt nhau. Tương tự, với transformer, nếu hai prompt chia sẻ prefix chung 1000 tokens đầu tiên, tensor K/V cho 1000 tokens đó là bit-for-bit identical — hoàn toàn giống nhau ở mức bit.
Tại sao? Vì causal masking. Token ở vị trí i chỉ có thể nhìn thấy các token từ 0 đến i. Nó không biết tương lai tồn tại. Do đó, K/V của token i chỉ phụ thuộc vào quá khứ, và nếu quá khứ giống nhau, K/V sinh ra cũng giống nhau. Đây là tính chất bất biến nhân quả (causal immutability).
Cơ chế thực hiện: Thay vì tính lại, ta lưu K/V của prefix vào bộ nhớ và "tái sử dụng" cho mọi request có chung prefix. Khi request mới đến, model bắt đầu tính từ token đầu tiên khác biệt, coi cached K/V như "lịch sử đã được xử lý".
Nhưng làm sao để chia sẻ bộ nhớ hiệu quả giữa nhiều request? Đây là lúc PagedAttention (vLLM) xuất hiện. Nó chia KV cache thành các block 16-token, quản lý qua "block table" — tương tự virtual memory trong hệ điều hành. 1000 request có thể trỏ đến cùng một vật lý block cho phần prefix chung, chỉ copy-on-write khi phần suffix khác nhau.
Cái bẫy byte-for-byte: Nhiều người tưởng "cùng nghĩa là cache hit". Sai. [{"a":1,"b":2}] và [{"b":2,"a":1}] khác nhau về token ID. Prefix Caching yêu cầu exact match từng byte — thứ tự key JSON, khoảng trắng, dấu xuống dòng đều phải giống hệt. Một ký tự khác là cache miss ngay lập tức.
That's it. Bạn không cần thay đổi kiến trúc model. Chỉ cần đừng tính lại những gì đã biết chắc.
Tại sao nó hoạt động
Toán học của Causal Additivity:
Trong attention mechanism, output tại vị trí i là tổng có trọng số của Value vectors:
\text{Attention}(Q_i, K_{\leq i}, V_{\leq i}) = \sum_{j=0}^{i} \text{softmax}\left(\frac{Q_i K_j^T}{\sqrt[d_k]}\right) V_j
Lưu ý rằng và chỉ phụ thuộc vào tokens 0..j, không phụ thuộc vào tokens sau j. Do đó, với hai prompt chia sẻ prefix đến vị trí , ta có:
- và với mọi
Cài đặt PagedAttention:
# Pseudocode minh họa block table
block_table = {
"request_001": [block_0, block_1, block_5], # block_0 shared
"request_002": [block_0, block_1, block_9], # share block_0,1 với request_001
}
# block_0 chứa KV của system prompt + tool definitionsKhi request mới đến, hệ thống hash prefix, tìm trong cache:
- Cache hit: Load block IDs vào block table của request mới (zero-copy, chỉ copy pointer)
- Cache miss: Chạy prefill thông thường, lưu K/V vào block mới
Chiến lược Eviction: GPU memory có hạn (H100 80GB chứa được khoảng 40K-50K tokens ở FP16). Khi đầy, LRU (Least Recently Used) hoặc LFU (Least Frequently Used) quyết định xóa block nào. Marconi (2024) đề xuất admission policies thông minh hơn cho hybrid LLMs.
Ý nghĩa thực tế
Hiệu năng thực tế:
- Throughput: vLLM cộng đồng báo cáo 2-10× throughput improvement trên workload agent có prefix chung
- Latency: DigitalOcean ghi nhận giảm 80% TTFT cho prompt dài; Anthropic giảm 85% độ trễ và 90% chi phí với prompt caching rõ ràng
- Memory: Giảm áp lực bộ nhớ nhờ chia sẻ vật lý giữa request, cho phép batch size lớn hơn
So sánh với KV Cache cơ bản:
| KV Cache thường | Prefix Caching | |
|---|---|---|
| Phạm vi | Nội bộ 1 request | Chia sẻ cross-request |
| Memory | Mỗi request cấp phát riêng | Copy-on-write, shared blocks |
| TTFT | Tuyến tính với độ dài prompt | Gần như instant nếu cache hit |
| Ràng buộc | Không có | Byte-for-byte exact match |
Giới hạn cần biết:
- Chỉ prefill, không decode: Tăng tốc xử lý đầu vào, không giúp sinh token nhanh hơn
- Cold start: Request đầu tiên vẫn phải trả giá đầy đủ; lợi ích tích lũy theo thời gian
- Memory pressure: Prefix dài (4K+) × nhiều concurrent request nhanh chóng đầy H100
- Exact match tyranny: Timestamp, JSON key order, hay một dấu cách thừa cũng phá vỡ cache
Đào sâu hơn
Paper gốc:
- Marconi: Prefix Caching for the Era of Hybrid LLMs (2024) — Admission policies cho hybrid models
- ChunkAttention: Efficient Self-Attention with Prefix-Aware KV Cache Management (2024) — Prefix-aware management
- KVFlow: Efficient Prefix Caching for Accelerating LLM-Based Multi-Agent Workflows (2025) — Tối ưu cho multi-agent
Cùng cụm (KV Cache & Inference):
- KV Cache — Nền tảng causal immutability và cơ chế caching cơ bản
- PagedAttention (vLLM) — Virtual memory cho AI, nền tảng kỹ thuật của prefix caching
- Continuous Batching — Kết hợp với prefix caching để tận dụng GPU triệt để
- Speculative Decoding — Song song với prefix caching để tăng tốc decode phase
- Constrained Decoding — Giữ chất lượng output khi throughput tăng cao
Đọc tiếp:
- Flash Attention — Tối ưu attention computation, bổ sung cho prefix caching ở layer thấp
- EAGLE Speculative Decoding — Frontier method tăng tốc inference ở Level 2
- GGUF & llama.cpp — Quantization giảm memory footprint cho KV cache, kết hợp với prefix caching trên consumer hardware
Continuous Batching — Swap request vào/ra liên tục, GPU không bao giờ rảnh
Iteration-level scheduling giúp tăng 23x throughput bằng cách xóa bỏ khái niệm batch cố định, cho phép GPU xử lý prefill và decode đồng thời.
Speculative Decoding — Model nhỏ draft, model lớn verify song song
Dùng model nhỏ dự đoán trước 5-10 token, rồi để model lớn verify cả chuỗi trong một forward pass — giảm latency 2-3x mà không làm giảm chất lượng output.