DeepSeek-V4 series incorporate several key upgrades: (1) hybrid attention architecture that combines Compressed Sparse Attention (CSA) and Heavily Compressed Attention (HCA); (2) Manifold-Constrained Hyper-Connections (mHC); (3) Muon optimizer.
DeepSeek-V4 彻底改变了 KV Cache 的设计,从 V3 的 MLA(Multi-head Latent Attention)转向 CSA + HCA 混合注意力架构,通过序列维度压缩而非仅靠隐维度压缩来大幅降低 KV Cache 开销。
附录:Python 计算器代码
以下代码可直接运行,计算任意序列长度下的 KV Cache 大小:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
NUM_LAYERS = 61 HEAD_DIM = 512 ROPE_DIM = 64 NOPE_DIM = HEAD_DIM - ROPE_DIM WINDOW = 128 INDEX_DIM = 128 CSA_RATIO = 4 HCA_RATIO = 128 N_CSA = 30 N_HCA = 31
def bf16_bytes(): """BF16 基准:所有元素 2 bytes。""" s_kv = HEAD_DIM * 2 s_idx = INDEX_DIM * 2 return s_kv, s_idx
def mixed_bytes(): """混合精度部署:nope FP8 (1B) + rope BF16 (2B) + indexer FP4 (0.5B)。""" s_kv = NOPE_DIM * 1 + ROPE_DIM * 2 s_idx = INDEX_DIM * 0.5 return s_kv, s_idx
def calc_kvcache(seq_len: int, precision="bf16"): """ 计算 DeepSeek-V4-Pro 的 KV Cache 大小。
Args: seq_len: 序列长度(token 数) precision: "bf16" 或 "mixed"(FP8+BF16+FP4)
Returns: 包含各组件和总大小的字典(字节) """ s_kv, s_idx = bf16_bytes() if precision == "bf16" else mixed_bytes()
csa_compressed = (seq_len // CSA_RATIO + WINDOW) * s_kv csa_indexer = (seq_len // CSA_RATIO) * s_idx csa_swa = WINDOW * s_kv csa_per_layer = csa_compressed + csa_indexer + csa_swa
hca_compressed = (seq_len // HCA_RATIO + WINDOW) * s_kv hca_swa = WINDOW * s_kv hca_per_layer = hca_compressed + hca_swa
total = N_CSA * csa_per_layer + N_HCA * hca_per_layer
return { "csa_per_layer": csa_per_layer, "hca_per_layer": hca_per_layer, "csa_total": N_CSA * csa_per_layer, "hca_total": N_HCA * hca_per_layer, "total_bytes": total, "total_gib": total / (1024**3), "csa_shared_kv": N_CSA * (seq_len // CSA_RATIO) * s_kv, "csa_indexer": N_CSA * (seq_len // CSA_RATIO) * s_idx, "hca_shared_kv": N_HCA * (seq_len // HCA_RATIO) * s_kv, "all_windows": (N_CSA + N_HCA) * WINDOW * s_kv, }
def fmt(b): """格式化字节数为可读字符串。""" if b >= 1024**3: return f"{b / (1024**3):.2f} GiB" return f"{b / (1024**2):.2f} MiB"
def report(seq_len: int): print("=" * 60) print(f" DeepSeek-V4-Pro KV Cache | seq_len = {seq_len:,}") print("=" * 60) print(f" {N_CSA} CSA 层 (ratio={CSA_RATIO}) + {N_HCA} HCA 层 (ratio={HCA_RATIO})") print(f" head_dim={HEAD_DIM} (nope={NOPE_DIM} + rope={ROPE_DIM})") print(f" index_dim={INDEX_DIM}, window={WINDOW}") print()
for prec in ["bf16", "mixed"]: r = calc_kvcache(seq_len, prec) s_kv, s_idx = bf16_bytes() if prec == "bf16" else mixed_bytes() label = "BF16 基准" if prec == "bf16" else "FP8 kv + BF16 rope + FP4 indexer" print(f" ── {label} (S_kv={s_kv}, S_idx={s_idx}) ──") print(f" CSA 单层: {fmt(r['csa_per_layer']):>10s} HCA 单层: {fmt(r['hca_per_layer']):>10s}") print(f" 组件分解:") for name, val in [ ("CSA Shared-KV 压缩", r["csa_shared_kv"]), ("CSA Indexer", r["csa_indexer"]), ("HCA Shared-KV 压缩", r["hca_shared_kv"]), ("滑动窗口 (61 层)", r["all_windows"]), ]: print(f" {name:30s} {fmt(val):>10s} ({val/r['total_bytes']*100:.1f}%)") print(f" {'─' * 56}") print(f" {'Total':30s} {fmt(r['total_bytes']):>10s}") print()
if __name__ == "__main__": report(1_048_576)
|
运行结果(Python 3.x):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| ============================================================ DeepSeek-V4-Pro KV Cache | seq_len = 1,048,576 ============================================================ 30 CSA 层 (ratio=4) + 31 HCA 层 (ratio=128) head_dim=512 (nope=448 + rope=64) index_dim=128, window=128
── BF16 基准 (S_kv=1024, S_idx=256) ── CSA 单层: 320.12 MiB HCA 单层: 8.12 MiB 组件分解: CSA Shared-KV 压缩 7,500.00 MiB (77.9%) CSA Indexer 1,920.00 MiB (19.5%) HCA Shared-KV 压缩 248.00 MiB (2.5%) 滑动窗口 (61 层) 7.50 MiB (0.1%) ───────────────────────────────────────────────────────────── Total 9,675.50 MiB (9.62 GiB)
── FP8 kv + BF16 rope + FP4 indexer (S_kv=576, S_idx=64.0) ── CSA 单层: 160.07 MiB HCA 单层: 4.57 MiB 组件分解: CSA Shared-KV 压缩 4,218.75 MiB (87.4%) CSA Indexer 480.00 MiB (9.7%) HCA Shared-KV 压缩 139.50 MiB (2.8%) 滑动窗口 (61 层) 4.25 MiB (0.1%) ───────────────────────────────────────────────────────────── Total 4,822.50 MiB (4.83 GiB)
|
对比 V3.2(61 层,每 token 1152 bytes):
- V3.2 BF16: 61 × 1,048,576 × 1152 / 1024³ ≈ 83.9 GiB
- V4-Pro BF16: 9.62 GiB (8.7× 压缩)
- V4-Pro 混合精度: 4.83 GiB (17.4× 压缩) ✅!
一、核心架构参数!
| 参数 |
符号 |
V4-Pro |
V4-Flash |
| 总参数量 |
|
1600B |
285B |
| 总层数 |
Llayers |
61 |
43 |
| CSA 层数 |
|
30 |
— |
| HCA 层数 |
|
31 |
— |
| 压缩后 latent 维度 (c_KV) |
c |
512 |
— |
| index_head_dim |
cI |
128 |
— |
| index_topk |
k |
1024 |
— |
| sliding_window |
w |
128 |
— |
数据来源:config.json
compress_ratios 数组 → 层类型
compress_ratios 有 62 个元素(61 层 + 1 层 MTP):
1 2 3
| 索引: 0 1 2 3 4 5 ... 59 60 61 值: 128 128 4 128 4 128 ... 128 4 0 类型: HCA HCA CSA HCA CSA HCA ... HCA CSA MTP
|
| 类型 |
数量 |
层索引 |
| HCA (ratio=128) |
31 |
0,1,3,5,7,…,59 |
| CSA (ratio=4) |
30 |
2,4,6,8,…,60 |
| 总计 |
61 |
|
二、KV Cache 结构革命!
V3 MLA vs V4 CSA/HCA!
| 对比项 |
V3 MLA |
V4 CSA/HCA |
| KV 投影 |
Linear(dim, 576) = 512+64 |
Linear(dim, 512) |
| RoPE 位置 |
独立存储 64 维,拼接在 512 后 |
包含在 512 维内(后 64 维) |
| KV cache 每 entry |
640 bytes (FP8+BF16) |
576 bytes (FP8+BF16 混合) |
| 压缩方式 |
隐维度压缩 (7168→512) |
序列维度压缩 (4:1 或 128:1) |
V4 KV entry 构成(512 维)
1 2 3 4 5 6 7
| KV entry (512 dims) ┌────────────────────────────┬──────────────┐ │ nope 维度 (448 个元素) │ rope 维度 (64)│ │ FP8: 448 × 1 byte │ BF16: 64 × 2 │ │ = 448 bytes │ = 128 bytes │ └────────────────────────────┴──────────────┘ 合计 = 576 bytes/entry (混合精度)
|
论文原文(Section 2.3.4):
“我们采用混合存储格式:RoPE 维度使用 BF16 精度,其余维度使用 FP8 精度。”
代码证据!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| self.head_dim = args.head_dim self.rope_head_dim = args.rope_head_dim self.nope_head_dim = self.head_dim - self.rope_head_dim
self.register_buffer("kv_cache", torch.zeros(args.max_batch_size, kv_cache_size, self.head_dim), persistent=False)
kv = self.wkv(x) kv = self.kv_norm(kv) apply_rotary_emb(kv[..., -64:], freqs_cis) act_quant(kv[..., :-64], 64, scale_fmt, scale_dtype, True)
|
结论:V4 的 512 维包含 RoPE(后 64 维),所以存储是 576 bytes/entry(混合精度),相比 V3 的 640 bytes/token 还小。
三、压缩机制详解!
1. HCA(Heavily Compressed Attention)— 重度压缩!
- 压缩比:128:1(每 128 个 token → 1 个压缩 KV entry)
- 无 overlap(论文明确:“does not perform overlapped compression”)
- 无稀疏选择:对所有压缩条目做全量密集注意力(提供全局"低分辨率概览")
- 滑动窗口:同样保留最近 128 个 token!
单层 KV Cache 计算(1M tokens):
| 组件 |
entries |
bytes/entry |
小计 |
| 压缩 KV |
1M/128 |
576 |
4.5 MB |
| SWA |
128 |
1088 |
135 KB |
| 总计 |
|
|
~4.6 MB/层 (无 Indexer) |
2. CSA(Compressed Sparse Attention)— 轻度压缩!
- 压缩比:4:1(每 4 个 token → 1 个压缩 KV entry)
- 窗口大小:8 个 token(含 50% overlap,步长=4)
- 稀疏选择:Lightning Indexer(FP4 精度)选取 top-1024 最相关的压缩块
- 滑动窗口:保留最近 128 个 token 的原始未压缩 KV!
单层 KV Cache 计算(1M tokens):
| 组件 |
entries |
bytes/entry |
小计 |
| 压缩 KV |
1M/4 |
576 |
144 MB |
| Indexer |
1M/4 |
64 (FP4) |
16 MB |
| SWA |
128 |
1088 |
135 KB |
| 总计 |
|
|
~160 MB/层 |
四、索引器(Indexer)机制(CSA 独有)!
索引器是 CSA 的"导航系统",用来决定哪些压缩块最值得关注。
结构
- 独立 Compressor:自己的 wkv 和 wgate 权重(head_dim=128,不是 512)
- FP4 量化:Hadamard 旋转 + fp4_act_quant(全 128 维)
- 计算流程:
1 2
| Query token t → indexer query (128 维) → 和所有压缩块的索引器 key 算分 → Top-k (1024) → 选出最相关的 1024 个压缩块
|
Indexer Cache 大小(1M tokens)
1
| (1M/4) × 128 dims × 0.5 byte (FP4) = 16 MB/层
|
论文 Section 5.2.1:
“索引器中的 QK 激活被缓存、加载,并完全以 FP4 精度计算。”
五、RoPE 的特殊处理!
三处应用 RoPE(Section 2.3.3)
- Query 向量 (q_t,i) → last 64 dims
- KV entry 向量 (C_Comp) → last 64 dims
- Core attention 输出 (o_t,i) → last 64 dims(位置 = -i)
为什么输出也要加 RoPE?!
因为 KV entry 同时作为 K 和 V,压缩后的 entry 带绝对位置信息。如果直接输出:
1
| o_t,i = Σ attn_weight_j × C_Comp_j(R(j)) ← 携带绝对位置 R(j)
|
对输出施加 RoPE(position=-i):
1
| R(-i) × o_t,i = Σ attn_weight_j × C_Comp_j(R(j-i)) ← 转为相对位置
|
论文原文:
“注意力输出的贡献将与 query 和 KV entry 之间的距离相关。”
六、精度配置!
两种精度模式!
| 符号 |
含义 |
BF16 基准 |
混合精度部署 |
| Skv |
Shared-KV 每元素字节 |
512×2=1024 |
448×1+64×2=576 |
| Sidx |
Indexer 每元素字节 |
128×2=256 |
128×0.5=64 (FP4) |
论文依据!
Section 2.3.4:
“RoPE 维度使用 BF16 精度,其余维度使用 FP8 精度。”
Section 5.2.1:
“索引器中的 QK 激活完全以 FP4 精度计算。”
七、总 KV Cache 计算公式!
通用公式!
设序列长度 N,CSA 层数 NCSA=30,HCA 层数 NHCA=31:
Total KV=NCSA×PerCSA+NHCA×PerHCA
其中:
PerCSA=Shared-KV(4N+w)×Skv+Indexer4N×Sidx
PerHCA=Shared-KV only(128N+w)×Skv
八、数值结果(N = 1,048,576 = 1M tokens)!
BF16 基准(vLLM 博客算法)
CSA 30 层:
| 组件 |
计算 |
结果 |
| Shared-KV 压缩 |
262,144 × 1024 |
256.00 MiB |
| Shared-KV 窗口 |
128 × 1024 |
0.125 MiB |
| Indexer 压缩 |
262,144 × 256 |
64.00 MiB |
| CSA 单层 |
|
320.13 MiB |
| 30 层 CSA |
320.13 × 30 |
9,603.75 MiB |
HCA 31 层:
| 组件 |
计算 |
结果 |
| Shared-KV 压缩 |
8,192 × 1024 |
8.00 MiB |
| Shared-KV 窗口 |
128 × 1024 |
0.125 MiB |
| HCA 单层 |
|
8.13 MiB |
| 31 层 HCA |
8.13 × 31 |
251.88 MiB |
总计(BF16):9,603.75 + 251.88 = 9,855.63 MiB ≈ 9.62 GiB ✅(和 vLLM 博客完全一致)
混合精度实际部署(FP8 + BF16 + FP4)
| 组件 |
bytes/entry |
30 层 CSA |
31 层 HCA |
| CSA 压缩 KV |
576 |
4.23 GiB |
— |
| CSA Indexer |
64 (FP4) |
0.47 GiB |
— |
| CSA SWA |
576 |
2.11 MiB |
— |
| HCA 压缩 KV |
576 |
— |
0.14 GiB |
| HCA SWA |
576 |
— |
2.18 MiB |
| 总计 |
|
~4.84 GiB |
|
压缩比:
- V3.2 KV Cache (61 层) = 83.9 GiB
- V4-Pro 混合精度 = 4.84 GiB
- 压缩比:83.9 / 4.84 ≈ 17.3× ✅!
九、各组件占比(BF16 基准)!
| 组件 |
MiB |
百分比 |
| CSA Shared-KV 压缩 |
7,680.00 |
77.9% ← 绝对主体 |
| CSA Indexer |
1,920.00 |
19.5% ← 不可忽略 |
| HCA Shared-KV 压缩 |
248.00 |
2.5% ← 128× 压缩极高效 |
| 滑动窗口 (全部 61 层) |
7.63 |
0.1% ← 可忽略 |
| 总计 |
9,855.63 |
100% |
CSA 的 Indexer 占了近 20%,是不能漏算的部分。
十、为什么能这么小?关键洞察!
-
序列维度压缩(V3 只压缩隐维度,V4 同时压缩序列长度)
- CSA: L → L/4
- HCA: L → L/128
-
稀疏注意力(CSA 只访问 top-1024 个压缩块,而非全部 L/4 个)
-
分层设计:CSA 负责精准的中程依赖,HCA 负责全局概览,互为补充
-
混合精度:
- RoPE 维度:BF16(2 bytes,保证位置精度)
- 其余维度:FP8(1 byte,节省空间)
- Indexer:FP4(0.5 byte,最激进)
-
磁盘 KV Cache:压缩后的 KV 块可以落盘存储,共享前缀的请求复用缓存*
十一、Forward 计算流程图(V4-Pro)!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| Hidden State [batch, seq_len, 7168] │ ┌───────────────┴───────────────┐ ▼ ▼ Q Down-proj KV 通路 [7168 → 1536] [7168 → 512] (wkv) │ │ ▼ ▼ Q Up-proj (1536→128×512) ┌──→ 压缩 (CSA: ratio=4 / HCA: ratio=128) │ │ ├─→ RoPE (后 64 维, BF16) Q [batch, seq_len, 128, 512] │ ├─→ FP8 量化 (前 448 维) │ │ └─→ 写入 KV cache ┌─→ RoPE (后 64 维) │ │ │ │ │ Q [batch, seq_len, 128, 512] KV cache [batch, N/ratio, 512] │ │ │ │ └──→ Indexer (仅 CSA) ──→ Top-k → 1024 个选中 │ │ └──→ Attention(Q, K=selected_1024, V=selected_1024) │ └──→ + SWA (最近 128 个 token) │ ▼ Output [batch, seq_len, 7168]
|
十二、和 vLLM 部署对齐!
vLLM 博客明确验证了 V4 的计算:
“using fp4 indexer cache and fp8 attention cache, which further reduces the KV cache size by roughly 2× compared to the bf16 estimate!”
| 来源 |
KV Cache (1M tokens) |
说明 |
| 论文 Figure 1 |
9.62 GiB (10% of V3.2) |
BF16 估计 |
| vLLM 博客 |
~4.8 GiB |
FP4+FP8 混合精度 |
| 本文计算 |
4.84 GiB |
精确对齐 ✅ |
十三、总结!
DeepSeek-V4 通过序列维度压缩 + 混合精度存储 + 稀疏选择,将 1M tokens 的 KV Cache 从 V3.2 的 83.9 GiB 压缩到 4.84 GiB(17.3× 压缩)。
核心创新:
- CSA:4:1 压缩 + overlap + Indexer 稀疏选择
- HCA:128:1 重度压缩,提供全局概览
- 混合精度:RoPE (BF16) + 内容 (FP8) + Indexer (FP4)
这套架构让百万 token 上下文从"不可能"变成"日常可用" 🐾!
参考!
- DeepSeek-V4 论文 (2026) Section 2.3
- vLLM 博客:DeepSeek V4 in vLLM (2026-04-24)
- config.json
- 代码追踪: model.py, compressor.py, c4.cuh
- 论文 Section 2.3.3: Partial Rotary Positional Embedding
- 论文 Section 5.2.1: FP4 Quantization-Aware Training