DeepSeek-V4 技术报告精读

动画讲解:Flash 架构 · Flash 逐卡推理 · Pro 架构 · Pro 逐卡推理。跟着一个 token,看压缩缓存、专家计算和跨卡通信怎样接起来。

在一百万 token 的上下文下,DeepSeek-V4-Pro 每生成一个 token 的推理 FLOPs 只有 V3.2 的 27%,KV cache 只有 10%;小一号的 V4-Flash 分别是 10% 和 7%。这是 DeepSeek 2026 年 4 月随 V4 预览版发布的 58 页技术报告《DeepSeek-V4: Towards Highly Efficient Million-Token Context Intelligence》(arXiv 2606.19348)开篇给的数字,报告的主线就是让一百万 token 的上下文变得便宜到可以日常使用。

为什么做得到?答案大部分在注意力里:V4 几乎把 V3 的注意力推倒重来,换成 CSA + HCA 混合注意力。此外它换了残差连接(mHC),换了优化器(Muon),又在训练、推理、后训练三套基础设施上做了一大堆配套工作。

1. 全景:V4 相对 V3 / V3.2 改了什么

V4 有两个型号,都是 MoE(Mixture-of-Experts,混合专家)模型,都原生支持 1M(\(2^{20}=1{,}048{,}576\))token 上下文:

每个模型又有三档「推理强度」:Non-think、Think High、Think Max。报告里最常出现的 V4-Pro-Max 就是 Pro 在 Think Max 档。

开头那几个效率数字都能从超参数直接算出来,第 4 节有一个计算器。

和 V3、V3.2 逐项对比:

部件V3(2024.12)V3.2(2025.12)V4(2026.04)
注意力MLA(稠密)MLA + DSA(lightning indexer 选 top-2048 个 token)CSA(4 倍压缩 + DSA 选 top-k)与 HCA(128 倍压缩、稠密)交替,外加 128 token 滑动窗口
KV 形式512 维潜向量 + 64 维 RoPE key同 V3,另加 128 维 indexer key单个 512 维向量同时当 K 和 V(shared-KV MQA),后 64 维带 RoPE
残差连接普通残差普通残差mHC:4 路残差流,混合矩阵约束为双随机矩阵
FFN前 3 层稠密,其余 DeepSeekMoE(256 路由 + 1 共享,激活 8)同 V3全部 MoE;前 3 层用 Hash 路由;激活 6 个;打分函数 Sigmoid → Sqrt(Softplus);取消节点数限制
MTP深度 1同 V3不变
优化器AdamWAdamWMuon(混合 Newton–Schulz),部分参数仍用 AdamW
上下文128K128K1M
后训练SFT + RL专家蒸馏 + 混合 RL(GRPO)专家 SFT+GRPO,再用多教师在线蒸馏(OPD)替换混合 RL
精度FP8 训练FP8FP8 训练;后训练对专家权重与 indexer QK 做 FP4 QAT
Embedding(d 维) 复制成 4 路残差流 Transformer Block ×L Pre-mix(A) CSA / HCA Post + Res mix(C, B) Pre-mix(A) DeepSeekMoE Post + Res mix(C, B) 合并 4 路 → 输出头 MTP 模块(深度 1) 注意力层的类型由层号决定: Flash(43 层):SWA, SWA, CSA, HCA, CSA, … Pro(61 层):HCA, HCA, CSA, HCA, CSA, … 每层 MoE:1 共享 + N 路由专家,激活 6 个 前 3 层按 token id 做 Hash 路由 残差流形状:n_hc × d = 4 × d 子层的输入输出仍是 d 维
图 1 V4 总体结构。橙色是 mHC 的三种映射,紫色是子层本体。

2. 先复习基线:MLA、DeepSeekMoE、MTP、DSA

V4 的每个新部件都是在这四样东西上改出来的。记号:\(d\) 是隐藏维度,\(\mathbf h_t\in\mathbb R^d\) 是第 \(t\) 个 token 进入某层时的隐藏状态,\(n_h\) 是注意力头数。

2.1 MLA:把 KV 压成一个潜向量

标准多头注意力(MHA)在每层为每个 token 缓存 \(n_h\) 个 key 和 \(n_h\) 个 value。以 V3 的尺寸(\(n_h=128\),每头 128 维)算,每 token 每层要存 \(2\times128\times128=32768\) 个数。解码时每生成一个 token 都要把整个 KV cache 从显存读一遍,所以 cache 越大越慢、能并发的请求越少。

MLA(Multi-head Latent Attention,V2 提出、V3 沿用)的做法是:只缓存一个低维潜向量,需要时再「解压」出各头的 K、V:

$$\mathbf c^{KV}_t = W^{DKV}\mathbf h_t\in\mathbb R^{512},\qquad \mathbf k^{C}_{t,i}=W^{UK}_i\mathbf c^{KV}_t,\qquad \mathbf v^{C}_{t,i}=W^{UV}_i\mathbf c^{KV}_t .$$

RoPE(旋转位置编码)和这种低秩分解不兼容(旋转矩阵夹在中间,没法把 \(W^{UK}\) 吸收进别的矩阵),所以 MLA 另开一条 64 维的「解耦 RoPE」通道:\(\mathbf k^R_t=\mathrm{RoPE}(W^{KR}\mathbf h_t)\in\mathbb R^{64}\),所有头共享。query 也先压到 \(d_c'=1536\) 维再升回来。于是每 token 每层只需缓存 \(512+64=576\) 个数,是 MHA 的 1/57。

还有一个关键技巧叫矩阵吸收:注意力分数 \(\mathbf q_i^\top\mathbf k^C_{s,i}=\mathbf q_i^\top W^{UK}_i\mathbf c^{KV}_s=(W^{UK\top}_i\mathbf q_i)^\top\mathbf c^{KV}_s\)。把 \(W^{UK}_i\) 并进 query 一侧之后,每个头的 query 直接在 512 维潜空间里和缓存的 \(\mathbf c^{KV}\) 做内积;同理 \(W^{UV}_i\) 可以并进输出投影。解码时 MLA 因此等价于一个 MQA(Multi-Query Attention,所有头共享同一份 K/V):128 个 query 头,key 是 576 维 \([\mathbf c^{KV};\mathbf k^R]\),value 是 512 维 \(\mathbf c^{KV}\)。V3.2 报告把这叫 MLA 的「MQA 模式」。记住这一点,V4 的注意力就是把它变成了模型的「原生形式」。

2.2 DeepSeekMoE 与无辅助损失的负载均衡

MoE 层把一个大 FFN 拆成很多小专家,每个 token 只走其中几个。DeepSeekMoE 的两个特点是:专家切得细(V3 每个专家中间维度只有 2048),以及有始终激活的共享专家。V3 的一层 MoE 可以写成:

$$\mathbf h'_t=\mathbf u_t+\sum_{i=1}^{N_s}\mathrm{FFN}^{(s)}_i(\mathbf u_t)+\sum_{i=1}^{N_r}g_{i,t}\,\mathrm{FFN}^{(r)}_i(\mathbf u_t),\qquad s_{i,t}=\sigma(\mathbf u_t^\top\mathbf e_i),$$

其中 \(\mathbf e_i\) 是第 \(i\) 个专家的「质心」向量,\(s_{i,t}\) 是亲和度分数。选专家时用 \(s_{i,t}+b_i\) 排序取 top-\(K_r\),但门控权重 \(g_{i,t}\) 只用 \(s_{i,t}\),并在选中的 \(K_r\) 个里归一化。偏置 \(b_i\) 不参与梯度:每步之后,过载的专家 \(b_i\) 减 \(\gamma\),欠载的加 \(\gamma\),这就是无辅助损失的负载均衡(auxiliary-loss-free)。V3 另外加了一个权重很小的序列级均衡损失,防止单条序列内部极端不均。V3 还限制每个 token 最多发往 4 个节点,以控制跨节点通信。

2.3 MTP:多预测一个 token

MTP(Multi-Token Prediction)在主干之后串一个小模块:把主干第 \(i\) 个位置的最终表示和第 \(i+1\) 个 token 的嵌入拼起来,过一个 Transformer 块,再用共享的输出头预测第 \(i+2\) 个 token。训练时它是一个附加损失(加权 \(\lambda\)),让表示更「往前看」;推理时可以拿来做投机解码。V3 用深度 1,V4 的 MTP 配置与 V3 完全相同。具体实现上,MTP 块的输入是 \(\mathbf x=W_e\,\mathrm{RMSNorm}(\mathrm{Emb})+W_h\,\mathrm{RMSNorm}(\mathbf h)\),等价于先拼接再投影。

2.4 DSA:用一个便宜的打分器挑 token

V3.2 引入了 DSA(DeepSeek Sparse Attention)。它的出发点是:一个 query 真正需要关注的历史 token 往往很少。DSA 用一个轻量的 lightning indexer 给每个历史 token 打分:

$$I_{t,s}=\sum_{j=1}^{H^I}w^I_{t,j}\cdot\mathrm{ReLU}\!\left(\mathbf q^I_{t,j}\cdot\mathbf k^I_s\right),$$

其中 indexer 的头数 \(H^I=64\)、维度 128,可以全程用 FP8 算;然后只取分数最高的 top-\(k\)(V3.2 是 2048)个 token 的 KV 做真正的注意力。这样核心注意力从 \(O(L^2)\) 降到 \(O(Lk)\)。但 indexer 本身仍要扫过全部历史 token,是 \(O(L^2)\) 的,只是常数小。

V3.2 的 indexer 是这样训出来的:先冻结主模型、保持稠密注意力,用 KL 散度把 indexer 的分布 \(\mathrm{Softmax}(I_{t,:})\) 拉向主注意力在所有头上求和、L1 归一化后的分布(1000 步,共 2.1B token);再打开稀疏选择,所有参数一起训(943.7B token),indexer 只在选中的集合上继续对齐,且它的输入从计算图中 detach,只受自己的 KL 损失驱动。

V3.2 留下的两个问题。第一,KV cache 每 token 每层仍是 576 个数再加 128 维 indexer key,1M 上下文下 61 层要几十 GB;第二,indexer 每生成一个 token 要和全部历史做 64 头 × 128 维的内积,长度一到百万,这一项会压过其他所有计算(第 4 节的计算器里能看到)。V4 的混合注意力就是冲着这两点来的:先沿序列维度压缩,再做稀疏。

3. 混合注意力:CSA 与 HCA

V4 设计了两种注意力层,交替堆叠:

两者都额外带一个 128 token 的滑动窗口分支,用来看最近的、尚未凑满一个压缩块的 token。

3.1 Token 级压缩器

设一段输入隐藏状态 \(H\in\mathbb R^{n\times d}\),\(n\) 是序列长度,\(c\) 是注意力的头维度(V4 里 \(c=512\))。CSA 的压缩器先算两套「原始 KV」和两套「压缩权重」:

$$C^a=HW^{aKV},\quad C^b=HW^{bKV},\quad Z^a=HW^{aZ},\quad Z^b=HW^{bZ},\qquad W^{\ast}\in\mathbb R^{d\times c}.$$

于是 \(C^a,C^b,Z^a,Z^b\in\mathbb R^{n\times c}\)。第 \(i\) 个压缩条目由「本块」的 \(m\) 个 \(C^a\) 和「上一块」的 \(m\) 个 \(C^b\) 共 \(2m\) 个向量加权得到:

$$\big[S^a_{mi:m(i+1)-1};\,S^b_{m(i-1):mi-1}\big]=\mathrm{Softmax}_{\text{row}}\big(\big[Z^a_{mi:m(i+1)-1}+B^a;\;Z^b_{m(i-1):mi-1}+B^b\big]\big),$$ $$C^{\text{Comp}}_i=\sum_{j=mi}^{m(i+1)-1}S^a_j\odot C^a_j+\sum_{j=m(i-1)}^{mi-1}S^b_j\odot C^b_j\in\mathbb R^{c}.$$

有几个细节值得停下来看:

HCA 的压缩器更简单:只有一套 \(C=HW^{KV}\)、\(Z=HW^{Z}\),不重叠,每 \(m'=128\) 个 token 做一次逐通道 softmax 加权求和(位置偏置 \(B\in\mathbb R^{m'\times c}\)),条目数 \(n/m'\)。

图 2 CSA 压缩器的重叠窗口(\(m=4\))。条目 \(i\) 由块 \(i\) 的 \(C^a\)(橙)和块 \(i-1\) 的 \(C^b\)(紫)共 8 个 token 加权得到;条目 0 没有上一块,只用 4 个。

压缩之后,每个条目还要做一次 RMSNorm,在最后 64 维上施加 RoPE(位置取该块第一个 token 的位置 \(mi\)),再把非 RoPE 的 448 维量化成 FP8 存进 cache。注意:只有凑满 \(m\) 个 token 才会产生一个新条目;没凑满的尾巴 token 要先放在缓冲区里(8.5 节的「state cache」)。

3.2 CSA:在压缩条目上做 DSA

有了 \(n/m\) 个压缩条目,CSA 接下来用 lightning indexer 挑选。indexer 有自己的一套压缩器(同样的重叠压缩,但头维度是 \(c_I=128\)),得到压缩的 indexer key \(K^{\text{IComp}}\in\mathbb R^{\frac nm\times c_I}\)。query 一侧走低秩路径:

$$\mathbf c^Q_t=\mathbf h_tW^{DQ}\in\mathbb R^{d_c},\qquad \mathbf q^I_t=\mathbf c^Q_tW^{IUQ}\in\mathbb R^{c_In^I_h},\qquad \mathbf w^I_t=\mathbf h_tW^{w}\in\mathbb R^{n^I_h},$$ $$I_{t,s}=\sum_{h=1}^{n_h^I}w^I_{t,h}\cdot\mathrm{ReLU}\!\left(\mathbf q^I_{t,h}\cdot K^{\text{IComp}}_s\right),\qquad s\lt\lfloor t/m\rfloor .$$

形式和 V3.2 一模一样,区别只是打分对象从「每个 token」变成了「每个压缩块」,候选数少了 4 倍。然后取 top-\(k\):

$$\mathcal C^{\text{SprsComp}}_t=\big\{C^{\text{Comp}}_s\;\big|\;I_{t,s}\in\text{Top-}k(I_{t,:})\big\}.$$

V4-Flash 取 \(k=512\),V4-Pro 取 \(k=1024\),都比 V3.2 的 2048 小。每个压缩条目代表 4 个 token,所以 Pro 每层实际「覆盖」约 4096 个 token 的信息,而 V3.2 是 2048 个 token。

注意 query 的低秩潜向量 \(\mathbf c^Q_t\) 由主注意力和 indexer 共享。indexer 的 query 和 key 在量化到 FP4 之前还要做一次 Hadamard 旋转:正交变换不改变内积,却能把少数离群维度的能量摊到所有维度上,量化误差因此更小。

CSA 里 query \(t\) 的一次注意力(玩具尺寸:10 个已完成的压缩条目、top-\(k=3\)、滑窗 8;分数为示意)。indexer 给每个条目打分,只取分数最高的 \(k\) 个,再和最近的原始 token 放进同一个 softmax。

3.3 Shared-KV MQA 与分组输出投影

挑出来的压缩条目直接同时充当 key 和 value,所有 query 头共享(MQA):

$$\mathbf q_t=\mathbf c^Q_tW^{UQ}\in\mathbb R^{cn_h},\qquad \mathbf o_{t,i}=\mathrm{CoreAttn}\big(\mathbf q_{t,i},\;\mathcal C^{\text{SprsComp}}_t,\;\mathcal C^{\text{SprsComp}}_t\big)\in\mathbb R^{c}.$$

和 2.1 节对照:MLA 在 MQA 模式下,key 是 576 维 \([\mathbf c^{KV};\mathbf k^R]\),value 是其中 512 维的 \(\mathbf c^{KV}\);V4 直接把它统一成一个 512 维向量(最后 64 维带 RoPE),K 和 V 用同一个,也不再有 \(W^{UK},W^{UV}\) 这层「先压后解」的分解。换句话说,V4 把「吸收后的 MLA」直接当成了模型本来的样子。

代价是输出变宽了:每头输出 512 维,Pro 有 128 个头,拼起来 \(cn_h=65536\) 维,直接投影回 \(d=7168\) 要一个 \(65536\times7168\) 的矩阵(4.7 亿参数,每 token 每层 9.4 亿 FLOPs)。V4 因此用了分组输出投影:把 \(n_h\) 个头分成 \(g\) 组,每组 \(\frac{n_h}{g}\) 个头的输出(\(c\frac{n_h}{g}\) 维)先各自投影到 \(d_g\) 维,拼成 \(gd_g\) 维后再投影到 \(d\):

$$\mathbf o^G_{t,i}\in\mathbb R^{c\,n_h/g}\xrightarrow{\;W^{O1}_i\;}\mathbf o'^G_{t,i}\in\mathbb R^{d_g},\qquad[\mathbf o'^G_{t,1};\dots;\mathbf o'^G_{t,g}]\in\mathbb R^{gd_g}\xrightarrow{\;W^{O2}\;}\hat{\mathbf o}_t\in\mathbb R^{d}.$$

算一下 Pro(\(g=16,\ d_g=1024\)):第一级 16 个 \(4096\times1024\) 矩阵,共 67.1M 参数;第二级 \(16384\times7168\),117.4M;合计 184.5M,是直接投影的 39%。Flash(\(g=8\)):33.6M + 33.6M = 67.1M,是直接投影(\(32768\times4096\))的一半。这其实就是把一个大矩阵换成「块对角 + 稠密」的低秩结构。

历史 token 的 h_s(n×d) 当前 token 的 h_t KV 压缩器 c=512, m=4 indexer 压缩器 c_I=128 c^Q = h_t W^DQ(d_c 维) 主 query 与 indexer query 共享 Lightning indexer(FP4) I_ts = Σ_h w_h·ReLU(q_h·K_s) Top-k 选择 压缩 KV 条目 n/4 × 512 滑窗 KV:最近 128 token Shared-KV MQA(n_h 头)→ 分组输出投影
图 3 CSA 的数据流。HCA 去掉 indexer 和 top-k,压缩率换成 128,其余相同。

3.4 HCA:压得更狠,但不挑

HCA 和 CSA 共用 query 路径、shared-KV MQA、分组输出投影,区别只在压缩:128 个 token 压成 1 个条目、不重叠、没有 indexer,query 对所有已完成的压缩条目做稠密注意力。1M 上下文时也只有 8192 个条目,是 V3.2 每层 top-k(2048 个 token)的 4 倍,远小于 1M。

HCA(玩具尺寸:每 16 个 token 压成一个条目,真实模型是 128)。条目之间不重叠,也不经过 indexer 挑选,query 对全部已完成的条目做稠密注意力,再加上滑窗。

为什么要两种层交替?报告没有为此做消融,只说这种混合结构显著改善了长上下文效率。从结构上看,两者是分工:HCA 以极低成本给每一层提供「全局但模糊」的视图,CSA 提供「按需取回、分辨率 4 倍」的细节,滑窗分支补最近的精确信息。

3.5 其他细节

Query 与 KV 条目的 RMSNorm。在核心注意力之前,对每个 query 头和唯一的那个 KV 头各做一次 RMSNorm。这样 \(\mathbf q\cdot\mathbf k\) 的量级被锁住,注意力 logit 不会爆炸。正因为有这一步,V4 用 Muon 时不需要 Kimi K2 的 QK-Clip(第 7 节)。

部分 RoPE + 输出的反向旋转。每个 query 和 KV 条目只在最后 64 维施加 RoPE。问题来了:K 和 V 是同一个向量,于是 value 也带着绝对位置 \(s\) 的旋转。设 \(R(\theta_s)\) 是位置 \(s\) 的旋转矩阵,注意力输出的 RoPE 部分是

$$\mathbf o^{\text{rope}}_t=\sum_s p_{t,s}\,R(\theta_s)\,\mathbf x_s .$$

V4 的处理是在输出上再乘一次位置 \(-t\) 的旋转:\(R(-\theta_t)\mathbf o^{\text{rope}}_t=\sum_s p_{t,s}R(\theta_{s-t})\mathbf x_s\)。旋转矩阵满足 \(R(a)R(b)=R(a+b)\),所以每个条目对输出的贡献只依赖相对距离 \(s-t\)。实现上就是对输出的最后 64 维再调用一次 apply_rotary_emb(..., inverse=True)。

滑动窗口分支。压缩条目只有在整块凑满后才可见(严格因果),所以 query 看不到自己所在块里的其他 token;而最近的 token 往往最相关。因此 CSA 和 HCA 都额外接入最近 \(n_{\text{win}}=128\) 个未压缩的 KV(同样是 512 维 shared-KV),和压缩条目放在同一个 softmax 里。

Attention sink。每个头有一个可学习的 logit \(z'_h\),加到 softmax 的分母上:

$$s_{h,i,j}=\frac{\exp(z_{h,i,j})}{\sum_k\exp(z_{h,i,k})+\exp(z'_h)} .$$

这样一个头的注意力权重之和可以小于 1,甚至接近 0,头可以选择「这次什么都不看」。在稀疏和压缩注意力里这很有用:被选中的条目不一定真的相关,强行归一到 1 会引入噪声。

层的排布。Flash 共 43 层:前两层只用滑动窗口注意力(SWA),之后 CSA 与 HCA 交替;Pro 共 61 层:前两层用 HCA,之后交替。合起来,Pro 是 30 个 CSA 层 + 31 个 HCA 层,Flash 是 21 个 CSA + 20 个 HCA + 2 个 SWA;MTP 层的压缩率为 0,即只用滑窗。

位置编码的配置。RoPE 底数 10000,带压缩的层用 compress_rope_theta = 160000 并开 YaRN(factor 16,原始长度 65536);纯 SWA 层不开 YaRN。

交互演示 · 一个 query 在 CSA / HCA 里能看到什么

为了画得下,这里用缩小的玩具尺寸:64 个 token,CSA 压缩率 \(m=4\)、top-\(k=4\),HCA 压缩率 \(m'=16\),滑窗 8。索引分数由随机向量算出(示意),可见性规则(块凑满才可见、重叠覆盖、滑窗包含自身)和真实模型相同。

被 top-k 选中的压缩条目 / 它覆盖的 token 滑动窗口内的原始 token 可见但未选中的压缩条目 尚未凑满、不可见

4. 一百万 token 到底省了多少:KV cache 与 FLOPs

报告 2.3.4 节列了四个效率来源:

  1. 混合精度存储 KV:RoPE 的 64 维用 BF16,其余 448 维用 FP8,比纯 BF16 小将近一半;
  2. indexer 用 FP4 计算:indexer 的 QK 路径在 FP4 下缓存、读取和相乘(这是后训练 QAT 的结果,见 10.6 节);
  3. 更小的 top-k:512 / 1024 而不是 2048,对中短文本也更省;
  4. 最重要的:压缩 + 混合本身。

报告给出的对照是:以「BF16、GQA8、头维度 128」这种常见配置为基线,V4 在 1M 上下文时的 KV cache 约为基线的 2%。报告图 1 还画了 V3.2 / V4-Pro / V4-Flash 的累计 KV cache 和单 token FLOPs 随长度变化的曲线,在 1M 处标注 KV 小 9.5×(Pro)和 13.7×(Flash),FLOPs 低 3.7×(Pro)和 9.8×(Flash)。

这些曲线可以从超参数直接算出来。把每生成一个 token 的开销拆成四项(\(n\) 是当前上下文长度;「层」是主干层,不含 MTP):

V3.2(61 层)V4(CSA 层 / HCA 层)
KV cache / 层\(n\times\)(512 B FP8 潜向量 + 128 B BF16 RoPE + 128 B FP8 indexer key)CSA:\(\frac n4\times\)(448 B FP8 + 128 B BF16 + 64 B FP4 indexer key);HCA:\(\frac n{128}\times576\) B;每层另有 128 个滑窗条目
线性层\(2\times37\text{B}\),FP8\(2\times\)激活参数(49B / 13B),FP8
indexer\(64\times128\times2\times n\),FP8CSA 层:\(64\times128\times2\times\frac n4\),FP4
核心注意力\(128\)头\(\times\min(n,2048)\times2\times(576+512)\),BF16\(n_h\times(\text{条目数}+128)\times2\times(512+512)\),BF16;CSA 条目数 \(=\min(\frac n4,k)\),HCA \(=\frac n{128}\)

报告用「等效 FP8 FLOPs」计量,但没有给出折算方式。最自然的折算是按张量核心吞吐:同样一次乘加,BF16 的耗时是 FP8 的 2 倍,FP4 是一半,所以 FP8 计 1、BF16 计 2、FP4 计 0.5。按这套账,1M 处 KV 比值是 9.5×(Pro)和 13.6×(Flash),FLOPs 比值是 3.8× 和 10.1×;V4-Pro 的 FLOPs 是 V3.2 的 26.5%、KV 是 10.6%,Flash 是 9.9% 和 7.4%;以 61 层 GQA8 BF16 为基线,Pro 的 KV 是 1.98%。这些和报告给出的数字(9.5×、13.7×、3.7×、9.8×、27%、10%、2%)只差几个百分点,说明 V4 的长上下文开销基本就是由上表这几项决定的。

交互演示 · KV cache / 单 token FLOPs 计算器(V3.2 vs V4)
指标
FLOPs 折算
按上表的假设计算;忽略量化 scale、注意力 sink、mHC、MoE 门控等小项。V3.2 的激活参数取 37B,V4 取报告的 49B / 13B。KV 指整条序列在全部主干层上的累计量(单位 GB = 10⁹ 字节)。

拖一拖能看到几件事:

5. mHC:流形约束的超连接

5.1 从残差到超连接(HC)

普通残差连接是 \(\mathbf x_{l+1}=\mathbf x_l+F_l(\mathbf x_l)\):只有一条宽度为 \(d\) 的「残差流」。超连接(Hyper-Connections,HC)把残差流加宽成 \(n_{hc}\) 条:残差状态是一个矩阵 \(X_l\in\mathbb R^{n_{hc}\times d}\),用三个小映射连接子层:

$$X_{l+1}=B_lX_l+C_l\,F_l(A_lX_l),\qquad A_l\in\mathbb R^{1\times n_{hc}},\;B_l\in\mathbb R^{n_{hc}\times n_{hc}},\;C_l\in\mathbb R^{n_{hc}\times1}.$$

子层本身的输入输出仍是 \(d\) 维,所以内部结构不用改。HC 相当于提供了一条和隐藏维度解耦的扩展轴:\(n_{hc}=4\) 时残差流宽了 4 倍,但额外计算只是几个 \(4\times4\) 的混合。普通残差就是 \(n_{hc}=1,\ A=B=C=1\) 的特例。

超连接的一层(\(n_{hc}=4\)):\(A\) 把 4 条流加权合成子层 \(F\) 的输入,\(C\) 把 \(F\) 的输出按各自的权重写回每条流,\(B\) 让 4 条流互相混合(连线粗细 ∝ \(B_{ij}\))。图里的 \(B\) 是一个示意的双随机矩阵,每行每列的和都是 1。

问题是:深层堆叠时信号经过的是 \(\prod_l B_l\)。只要 \(B_l\) 的谱范数稍大于 1,乘上上百层就会爆炸;稍小于 1 就会消失。报告说 HC 在层数多时会频繁出现数值不稳定,难以扩展。

5.2 把 B 约束成双随机矩阵

mHC(DeepSeek 2025 年底的论文,arXiv 2512.24880)的核心是把 \(B_l\) 限制在双随机矩阵集合(Birkhoff 多面体)上:

$$B_l\in\mathcal M:=\{M\in\mathbb R^{n\times n}\mid M\mathbf 1_n=\mathbf 1_n,\;\mathbf 1_n^\top M=\mathbf 1_n^\top,\;M\ge0\}.$$

即非负、每行和每列都等于 1。它有两条好性质:

  1. 谱范数 \(\le1\)。Birkhoff–von Neumann 定理说双随机矩阵是置换矩阵的凸组合 \(M=\sum_k\lambda_kP_k\)(\(\lambda_k\ge0,\sum\lambda_k=1\)),而置换矩阵是正交的,\(\|P_k\|_2=1\),由三角不等式 \(\|M\|_2\le\sum_k\lambda_k=1\)。也就是说残差变换是「非扩张」的,前向和反向都不会放大。
  2. 对乘法封闭。两个双随机矩阵的乘积仍是双随机的(行和:\(M_1M_2\mathbf1=M_1\mathbf1=\mathbf1\)),所以堆多少层,\(\prod_lB_l\) 都还在 \(\mathcal M\) 里,范数仍 \(\le1\)。

同时 \(A_l\) 和 \(C_l\) 也被约束为非负且有界(用 sigmoid),避免不同流之间的信号互相抵消。

5.3 动态参数化与 Sinkhorn 投影

三个映射的参数是「动态 + 静态」两部分:先把 \(X_l\) 展平并归一化 \(\hat X_l=\mathrm{RMSNorm}(\mathrm{vec}(X_l))\in\mathbb R^{1\times n_{hc}d}\),再线性生成原始参数:

$$\tilde A_l=\alpha^{\text{pre}}_l\,(\hat X_lW^{\text{pre}}_l)+S^{\text{pre}}_l,\qquad \tilde B_l=\alpha^{\text{res}}_l\,\mathrm{Mat}(\hat X_lW^{\text{res}}_l)+S^{\text{res}}_l,\qquad \tilde C_l=\alpha^{\text{post}}_l\,(\hat X_lW^{\text{post}}_l)^\top+S^{\text{post}}_l,$$

其中 \(W^{\text{pre}},W^{\text{post}}\in\mathbb R^{n_{hc}d\times n_{hc}}\),\(W^{\text{res}}\in\mathbb R^{n_{hc}d\times n_{hc}^2}\),\(S\) 是静态偏置,\(\alpha\) 是初始化为小值的门控标量。然后施加约束:

$$A_l=\sigma(\tilde A_l),\qquad C_l=2\sigma(\tilde C_l),\qquad B_l=\mathrm{Sinkhorn}(\exp(\tilde B_l)).$$

Sinkhorn–Knopp 迭代:从 \(M^{(0)}=\exp(\tilde B_l)\)(保证正)出发,交替做列归一化和行归一化 \(M^{(t)}=\mathcal T_r(\mathcal T_c(M^{(t-1)}))\),迭代 \(t_{\max}=20\) 次。对正矩阵这个过程收敛到一个双随机矩阵。

Sinkhorn 迭代 4 轮(\(\tilde B\) 为示意值,格子颜色深浅 ∝ 元素大小)。列归一化让列和变成 1,但会打乱行和;行归一化再把行和拉回 1。来回几轮后行和、列和同时接近 1,谱范数也降到 1 附近。

形状账(Pro,\(d=7168,\ n_{hc}=4\)):三组 \(W\) 合在一起是 \(4d\times(4+4+16)=28672\times24\),每个子层一份(注意力前一份、MoE 前一份),每层 1.38M 参数,61 层约 84M,相对 1.6T 可以忽略。8.4 节会提到的「mHC 里输出维度只有 24 的矩阵乘」就是它。模型入口把嵌入复制成 4 份,出口用一个只有 sigmoid 权重的 \(A\) 把 4 路合成 1 路再接输出头。

交互演示 · Sinkhorn 把任意矩阵拉到双随机流形上

\(\tilde B\) 是随机生成的 4×4 矩阵,元素服从 N(0, σ²)。拖动迭代次数,看行和、列和与谱范数怎么变;矩阵右边一列是行和,下面一行是列和。

「堆叠」对比两种 122 层(61 层 × 每层两个子层)的残差变换连乘:一种是不加约束的 \(B=I+0.15\,\mathcal N(0,1)\)(模拟 HC 初始化附近的随机扰动),另一种是 20 步 Sinkhorn 投影后的 \(B\)(示意)。

工程上 mHC 并不免费:残差流宽了 4 倍,激活显存和流水线阶段之间的通信量都变大。报告用融合 kernel、选择性重计算、调整 DualPipe 的 1F1B 重叠三招把墙钟开销压到流水线阶段的 6.7%(见 8.3 节)。

6. MoE 的小改动与参数账

V4 的 MoE 仍是 DeepSeekMoE,报告列了这些改动:

按 config 把参数逐项数一遍:注意力(含 query 低秩、KV 投影、两级输出投影、压缩器、indexer)、mHC、门控、专家、嵌入和输出头。Flash 主干 284.3B、激活 13.3B(不含嵌入表),Pro 主干 1573B、激活 48.9B,正好是报告的 284B/13B 和 1.6T/49B(1573B 取整为 1.6T)。MTP 模块另有 6.6B(Flash)和 25.8B(Pro),与主干共享嵌入和输出头。

交互演示 · 参数量与专家并行(EP)通信计算器
起点

通信能否被计算藏住?每个 token-专家对,SwiGLU 的三个矩阵乘要 \(6hd\) FLOPs(\(h\) 隐藏维度,\(d\) 专家中间维度),而 dispatch(FP8)加 combine(BF16)只传 \(3h\) 字节,所以只要 \(C/B\le 2d\),通信就能完全藏在计算后面(\(C\) 峰值算力,\(B\) 互联带宽)。

参数按模型的各个模块逐项计数,其余超参取所选起点模型的 config。激活参数不含嵌入表(含输出头)。EP 部分的算力、带宽默认值为示意。

7. Muon 优化器

7.1 为什么要「正交化」更新

对一个权重矩阵 \(W\in\mathbb R^{n\times m}\),SGD/Adam 的更新方向通常是低秩、病态的:少数几个奇异方向占了绝大部分能量。Muon 的想法是:取动量矩阵 \(M=U\Sigma V^\top\),把它替换成 \(UV^\top\),即保留方向、把所有奇异值拉成 1。这样每个奇异方向都得到同样大小的更新,相当于在谱范数意义下做最速下降。直接算 SVD 太贵,于是用 Newton–Schulz 迭代近似。

先归一化 \(M_0=M/\|M\|_F\)(保证最大奇异值 \(\le1\)),再迭代

$$M_k=aM_{k-1}+b\,(M_{k-1}M_{k-1}^\top)M_{k-1}+c\,(M_{k-1}M_{k-1}^\top)^2M_{k-1}.$$

因为 \(M=U\Sigma V^\top\) 时 \((MM^\top)^jM=U\Sigma^{2j+1}V^\top\),这个迭代对每个奇异值独立地作用一个奇多项式 \(f(\sigma)=a\sigma+b\sigma^3+c\sigma^5\),奇异向量不变。我们要的就是让 \(f\) 迭代若干次后把 \((0,1]\) 里的所有值都推到 1 附近。

7.2 V4 的混合 Newton–Schulz

V4 共做 10 次迭代,分两个阶段:

交互演示 · Newton–Schulz 对奇异值做了什么
系数方案
横轴是归一化后的输入奇异值(对数刻度),纵轴是迭代后的输出。这是确定性的标量计算,没有随机成分。

7.3 完整算法与其他配置

报告的算法 1,对每个逻辑上独立的权重矩阵 \(W\in\mathbb R^{n\times m}\):

$$\begin{aligned} G_t&=\nabla_W\mathcal L_t(W_{t-1}),\qquad M_t=\mu M_{t-1}+G_t,\\ O'_t&=\mathrm{HybridNewtonSchulz}(\mu M_t+G_t),\\ O_t&=O'_t\cdot\sqrt{\max(n,m)}\cdot\gamma,\qquad W_t=W_{t-1}(1-\eta\lambda)-\eta O_t . \end{aligned}$$

8. 训练与推理基础设施

这部分来自报告第 3 节和第 5.2 节。具体的并行度(TP/PP/EP/DP 各多少)报告没有公开。

8.1 细粒度专家并行:把通信藏进计算

专家并行(EP)把不同专家放在不同 GPU 上,每层 MoE 要做两次 all-to-all:Dispatch(把 token 发给专家所在的卡)和 Combine(把结果收回来)。一层 MoE 因此分成四个阶段:Dispatch(通信)、Linear-1(gate/up 投影,计算)、Linear-2(down 投影,计算)、Combine(通信)。DeepSeek 的 profiling 发现单层里通信总时间小于计算总时间,所以只要排得好,通信可以完全藏住。

朴素 DispatchL1+ActL2Combine wave 化 橙=通信,紫=计算;以三个 wave 为例,计算串成一条,通信藏在缝里(时间比例为示意)。
图 4 EP 的时间线:朴素串行 vs. 按 wave 重叠。

实测:在 NVIDIA GPU 和华为昇腾 NPU 上都验证过,相对强的非融合基线,一般推理负载加速 1.50~1.73×,RL rollout、高速 agent 服务这类延迟敏感场景最高 1.96×。CUDA 版的「mega-kernel」以 MegaMoE 的名字开源在 DeepGEMM 里。

报告由此给硬件厂商提了几条建议,第一条就是上面计算器里的那个比值:通信能否完全藏住取决于「算力/带宽」比 \(C/B\) 而不是带宽本身。对 V4-Pro,每个 token-专家对需要 \(6hd\) FLOPs、传输 \(3h\) 字节,条件化简为 \(C/B\le2d=6144\) FLOPs/字节,即每 1 GB/s 带宽足以藏住 6.1 TFLOP/s 算力的通信;超过这个平衡点后继续堆带宽收益递减。另外三条:极端融合让算力、显存、网络同时满载,功耗墙会成为瓶颈,需要更多功耗余量;Dispatch 用的是「拉」(每张卡主动读远端激活)而不是「推」,因为细粒度推送的通知延迟太高,希望硬件提供更低延迟的跨卡信号;建议把 SwiGLU 换成不含指数和除法的逐元素激活函数,减少 GEMM 之后的处理开销。

8.2 用 TileLang 写算子

V4 的结构如果用 PyTorch 原生算子拼,会有几百个细碎的 ATen 算子。DeepSeek 用 TileLang(一种写 GPU kernel 的领域专用语言)写了一批融合 kernel 替换掉其中绝大部分,开源推理代码里的 FP4/FP8 GEMM、稀疏注意力、Sinkhorn 都是 TileLang 写的。报告提到三项对 TileLang 本身的改进:

8.3 训练框架

Muon 与 ZeRO 的冲突。ZeRO 把优化器状态按元素切分到多个数据并行 rank 上,这对 AdamW 这种逐元素优化器很自然;但 Muon 要对整个矩阵做 Newton–Schulz,需要完整的梯度矩阵。V4 的混合方案:

mHC 的开销控制。融合 kernel(训练与推理各一套);选择性重计算:层间的大多数隐藏状态和所有归一化后的层输入都重算,计算密集的操作不重算;调整 DualPipe 的 1F1B 重叠,容纳更大的流水线通信并让部分 mHC 操作并发。合起来 mHC 的墙钟开销只占重叠后 1F1B 流水线阶段的 6.7%。

压缩注意力下的上下文并行(CP)。CP 把序列切成连续的段,每个 rank 持有 \(s\) 个 token。压缩注意力带来两个麻烦:训练样本是多条序列拼起来的,每条序列独立压缩、尾部不足 \(m\) 个的 token 丢弃,所以各 rank 的压缩长度不一定是 \(s/m\);而且一个压缩块可能跨在两个 rank 的边界上。V4 用两阶段通信解决:

  1. rank \(i\) 把最后 \(m\) 个未压缩的 KV 发给 rank \(i+1\);rank \(i+1\) 把它们和本地 \(s\) 个 KV 一起压缩,产生固定长度 \(s/m+1\) 个条目(含若干填充)。
  2. all-gather 收集所有 rank 的压缩条目,再用一个融合的 select-and-pad 算子整理成总长 \(\text{cp\_size}\cdot s/m\) 的完整序列,填充放在末尾。

对 HCA 和 CSA 的 indexer,每个 query 可见的压缩条目范围按规则预先算好;对 CSA 的稀疏注意力,top-k 选择器直接给出可见条目的下标。

张量级激活 checkpoint。常规的激活 checkpoint 以模块为单位决定保存还是重算,粒度太粗;手写整层的前向和反向又失去了自动微分的便利。V4 的框架让开发者只写前向、给个别张量打「需要重算」的标注;框架用 TorchFX 追踪完整计算图,对每个标注张量反向遍历找出重算它所需的最小子图,插到对应梯度计算之前。重算时直接释放原张量显存、复用重算结果的存储指针,没有额外拷贝;由于追踪时能看到底层存储指针,共享存储的张量(如 reshape 前后)会自动去重。与手写实现相比没有额外开销。

8.4 批不变与确定性 kernel

V4 要求预训练、后训练和推理三条管线之间逐位对齐。两个概念:

难点和解法:

这件事在后训练里尤其值钱:10.7 节的 rollout 服务会说到,有了批不变和确定性,「中断后用同一个随机种子重新生成」在数学上就是正确的。

8.5 推理:异构 KV cache 的布局

V4 一个模型里有好几种 KV:CSA 的主 KV(每 4 token 一个,512 维)、CSA 的 indexer KV(每 4 token 一个,128 维)、HCA 的 KV(每 128 token 一个)、滑窗 KV(每层最近 128 个),还有「没凑满一个压缩块」的尾巴 token 及其隐藏状态。不同层的 cache 大小、更新规则、淘汰策略都不同,打破了 PagedAttention 的基本假设。报告把障碍归成两条:滑窗等不同的缓存策略;高性能注意力 kernel 的对齐要求。对应地:

8.6 磁盘 KV cache

为了让共享前缀的请求不再重复 prefill,V4 把 KV 存到磁盘。CSA/HCA 的压缩条目全部落盘,命中前缀时读取到最后一个完整压缩块为止,尾部不完整块里的 token 需要重算(未压缩的 KV 不落盘)。滑窗 KV 不压缩且每层都有,体积约是压缩条目的 8 倍,报告给了三种策略:

9. 预训练:数据、超参与稳定性

9.1 数据

9.2 超参数总表

V4 两个型号的完整超参数,V3.2 一列作为对照。

项目V4-FlashV4-ProV3.2(对照)
总参数 / 激活参数284B / 13B1.6T / 49B671B / 37B
层数 \(L\)436161
隐藏维度 \(d\)409671687168
前两层纯 SWAHCA—
CSA 压缩率 \(m\) / HCA 压缩率 \(m'\)4 / 1284 / 128—
CSA / HCA / SWA 层数21 / 20 / 230 / 31 / 0—
query 头数 \(n_h\)64128128
头维度 \(c\)(其中 RoPE 维)512(64)512(64)qk 192 / v 128;cache 512+64
KV 头数1(shared KV)1(shared KV)MQA 模式下 1
query 压缩维度 \(d_c\)102415361536
输出投影组数 \(g\) / 中间维度 \(d_g\)8 / 102416 / 1024—
indexer 头数 \(n^I_h\) / 头维度 \(c_I\)64 / 12864 / 12864 / 128
attention top-k51210242048(token)
滑窗 \(n_{\text{win}}\)128128—
MoE:共享 + 路由专家1 + 2561 + 3841 + 256
专家中间维度204830722048
激活路由专家668
Hash 路由层 / 稠密 FFN 层前 3 层 / 0前 3 层 / 00 / 前 3 层
路由打分 / route scale√softplus / 1.5√softplus / 2.5sigmoid / 2.5
MTP 深度111
mHC 扩展 \(n_{hc}\) / Sinkhorn 迭代4 / 204 / 20—
词表129280129280129280
RoPEθ=10⁴;压缩层 θ=1.6×10⁵ + YaRN(×16,原长 65536)YaRN ×40
训练 token32T33TV3.1 基座 + 约 0.94T 续训
最大 batch(token)75.5M94.4M
峰值 / 末尾学习率2.7e-4 / 2.7e-52.0e-4 / 2.0e-5
学习率调度线性 warmup 2000 步,长时间恒定,末尾余弦衰减
AdamW(部分参数)β₁=0.9, β₂=0.95, ε=1e-20, wd=0.1
Muon(其余参数)momentum 0.95, wd 0.1, 更新 RMS 0.18
负载均衡偏置更新速度 0.001;序列级均衡损失 0.0001
MTP 损失权重0.3;学习率开始衰减时改为 0.1
序列长度4K → 16K → 64K → 1M128K

顺带一提:75.5M 恰好是 \(18432\times4096\),94.4M 是 \(23040\times4096\),即以 4K 序列计的整数个样本;Flash 在 75.5M 的 batch 下 32T token 大约对应 42 万步量级(前期 batch 更小,实际步数更多)。

9.3 训练日程

9.4 训练不稳定与两个「土办法」

训练万亿参数的 MoE 时,V4 遇到了明显的不稳定,回滚只能暂时恢复、不能防止 loss spike 再次出现。他们的经验观察是:spike 总是和 MoE 层里的离群值(outlier)绑在一起,而路由机制本身似乎会加剧离群值的出现——离群值影响路由,路由又放大离群值。于是从两头下手:打断路由造成的恶性循环,以及直接压住异常值。

Anticipatory Routing(预见式路由)。第 \(t\) 步用当前参数 \(\theta_t\) 计算特征,但路由下标用历史参数 \(\theta_{t-\Delta t}\) 计算。实现上,在第 \(t-\Delta t\) 步就预取第 \(t\) 步的数据,「提前」算好路由下标缓存起来——这正是名字的由来,也避免了加载两份参数。预计算只需要一次前向,通过精心编排流水线和 EP 通信的重叠,额外墙钟开销约 20%。更进一步,它不是一直开着:系统自动检测 loss spike,检测到时短暂回滚并打开预见式路由,跑一段时间后切回正常训练,所以总开销可以忽略,也不损害模型性能。

SwiGLU Clamping。把 SwiGLU 的线性分支截断到 \([-10,10]\),门控分支上界截断到 10(即 up.clamp(-10, 10),gate.clamp(max=10),然后 \(\mathrm{SiLU}(\text{gate})\odot\text{up}\))。这个做法来自 gpt-oss。Flash 和 Pro 全程都开着,报告说它能有效消除离群值、帮助稳定,且不损害性能。

这两个技巧为什么有效,目前还没有完整的理论解释。

9.5 基座模型评测

报告表 1,三者在同一内部框架、同一设置下评测(差距不超过 0.3 视为持平):

类别基准(指标)shotsV3.2-BaseV4-Flash-BaseV4-Pro-Base
激活 / 总参数37B / 671B13B / 284B49B / 1.6T
世界知识AGIEval (EM)080.182.683.1
MMLU (EM)587.888.790.1
MMLU-Redux (EM)587.589.490.8
MMLU-Pro (EM)565.568.373.5
MMMLU (EM)587.988.890.3
C-Eval (EM)590.492.193.1
CMMLU (EM)588.990.490.8
MultiLoKo (EM)538.742.251.1
Simple-QA verified (EM)2528.330.155.2
SuperGPQA (EM)545.046.553.9
FACTS Parametric (EM)2527.133.962.6
TriviaQA (EM)583.382.885.6
语言与推理BBH (EM)387.686.987.5
DROP (F1)188.288.688.7
HellaSwag (EM)086.485.788.0
WinoGrande (EM)078.979.581.5
CLUEWSC (EM)583.582.285.2
代码与数学BigCodeBench (Pass@1)363.956.859.2
HumanEval (Pass@1)062.869.576.8
GSM8K (EM)891.190.892.6
MATH (EM)460.557.464.5
MGSM (EM)881.385.784.4
CMath (EM)392.693.690.9
长上下文LongBench-V2 (EM)140.244.751.5

最显眼的是知识类:Simple-QA verified 从 28.3 到 55.2,FACTS Parametric 从 27.1 到 62.6,几乎翻倍——总参数从 671B 涨到 1.6T,能记住的东西多了。Flash 用 13B 激活就在多数项上超过 37B 激活的 V3.2,但 BigCodeBench、MATH 这类推理密集项反而低于 V3.2,激活参数少的代价在这里。

10. 后训练:专家 RL + 多教师在线蒸馏

10.1 流程

V4 的后训练大体沿用 V3.2,但有一个关键替换:V3.2 最后的混合 RL 阶段(把推理、agent、人类对齐放进同一个 RL)被整个换成了在线策略蒸馏(On-Policy Distillation,OPD)。流程分两步:

  1. 培养专家:对每个目标领域(数学、代码、agent、指令遵循……),从基座出发先做该领域的 SFT,再用 GRPO 做 RL,奖励按该领域的成功标准设计。得到一组各自擅长一个领域的专家模型。
  2. 合并:训练一个统一的学生模型,在它自己生成的轨迹上,按 token 最小化它与各专家之间的反向 KL。报告说这一步用了十多个教师。

10.2 专家阶段的 GRPO

RL 用的是 GRPO,超参与 R1、V3.2 保持接近。它的目标函数如下(V3.2 的版本)。对问题 \(q\),从旧策略采样一组 \(G\) 个回答 \(\{o_i\}\),目标是

$$\mathcal J(\theta)=\mathbb E\Bigg[\frac1G\sum_{i=1}^G\frac1{|o_i|}\sum_{t=1}^{|o_i|}\Big(\min\big(r_{i,t}\hat A_{i,t},\ \mathrm{clip}(r_{i,t},1-\varepsilon,1+\varepsilon)\hat A_{i,t}\big)M_{i,t}-\beta\,\mathbb D_{\mathrm{KL}}\big(\pi_\theta\,\|\,\pi_{\mathrm{ref}}\big)\Big)\Bigg],$$

其中 \(r_{i,t}=\pi_\theta(o_{i,t}\mid q,o_{i,\lt t})/\pi_{\mathrm{old}}(o_{i,t}\mid q,o_{i,\lt t})\) 是重要性比;优势用组内相对奖励 \(\hat A_{i,t}=R_i-\mathrm{mean}(R_1,\dots,R_G)\),不需要价值网络。V3.2 在此之上加了四个稳定 RL 的做法:

10.3 推理强度、奖励模型与对话格式

三档推理强度。同一个模型支持 Non-think、Think High、Think Max。它们来自不同 RL 配置训出来的专家:每档用不同的长度惩罚和上下文窗口,输出的推理长度因此不同。格式上,Non-think 直接输出 </think> 加回答;High 输出 <think> 推理 </think> 加总结;Max 在此之外还在 system prompt 开头注入一段指令,大意是「推理强度拉满、不许走捷径:彻底分解问题、找根因,对所有路径、边界情况和对抗情形压力测试,把每个中间步骤、考虑过的备选方案和被否定的假设都写出来」。评测时三档的上下文窗口分别是 8K、128K、384K。

生成式奖励模型(GRM)。容易验证的任务用规则或测试用例;难以验证的任务,传统做法是 RLHF 训一个标量奖励模型。V4 不再用标量奖励模型,而是准备带评分细则(rubric)的 RL 数据,用生成式奖励模型给轨迹打分。关键是对 GRM 本身也做 RL,而且 actor 自己就充当 GRM,评判能力和生成能力一起优化。报告说这样只需要少量多样的人工标注就能获得稳健的打分。

工具调用格式。新格式用一个特殊 token |DSML| 加 XML 风格的标签:<|DSML|tool_calls> 包住若干 <|DSML|invoke name="…">,每个参数用 <|DSML|parameter name="…" string="true|false"> 标出——字符串参数原样写、string="true",其他类型写 JSON、string="false"。报告说 XML 格式比 JSON 嵌套更少出现转义错误,减少了工具调用失败。

交错思考(interleaved thinking)。V3.2 的策略是:工具调用轮次之间保留推理内容,但一来新的用户消息就清掉之前所有推理。V4 借着 1M 上下文改成:在有工具调用的场景,推理内容在整段对话里全部保留,跨用户消息也不清;在普通对话场景仍沿用旧策略,新用户消息到来时丢弃之前的推理。用用户消息模拟工具交互的 agent 框架(如 Terminus)触发不了前一条路径,报告仍建议它们用 non-think 模式。

Quick Instruction。聊天产品在生成回答前要做一堆辅助判断(要不要搜索、意图识别、生成搜索词……),通常交给另一个小模型,但小模型不能复用主模型已算好的 KV cache,要重新 prefill。V4 的做法是在输入序列末尾直接追加专用的特殊 token,每个对应一个辅助任务,复用已有 KV cache,而且像生成搜索词、判断权威性需求、判断领域这些任务可以并行。报告列了 <|action|>(是否需要搜索)、<|title|>(生成对话标题)、<|query|>(生成搜索词)、<|authority|>(对来源权威性的需求)、<|domain|>(领域)、<|extracted_url|> + <|read_url|>(某个 URL 是否要抓取阅读)。好处是降低首 token 延迟,也省掉维护一个额外小模型的工程成本。

10.4 多教师 OPD

给定 \(N\) 个专家 \(\{\pi_{E_1},\dots,\pi_{E_N}\}\),OPD 的目标是

$$\mathcal L_{\mathrm{OPD}}(\theta)=\sum_{i=1}^Nw_i\cdot\mathbb D_{\mathrm{KL}}\big(\pi_\theta\,\|\,\pi_{E_i}\big),$$

\(w_i\) 是各专家的权重,通常按重要性定。这里有两个要点。

一,反向 KL、在线采样。\(\mathbb D_{\mathrm{KL}}(\pi_\theta\|\pi_E)=\mathbb E_{y\sim\pi_\theta}[\log\pi_\theta(y)-\log\pi_E(y)]\) 的期望在学生分布下取,所以轨迹必须由学生自己生成(on-policy)。这和普通 SFT 式蒸馏(在教师生成的数据上做前向 KL / 交叉熵)不同:学生在自己会走到的状态上被纠正,不会出现训练时没见过的分布偏移。反向 KL 还有「寻模」的性质:学生倾向于集中在教师概率高的区域,而不是去覆盖教师的全部分布。在实际训练中,学生遇到数学题时,主要是数学专家的 KL 在起作用;遇到代码题时则是代码专家——不同专家的能力在 logits 层面汇总到一套参数里,绕开了权重合并或混合 RL 常见的性能退化。

二,全词表 KL 而不是单 token 估计。以前的工作通常把每个位置的 KL 简化为只看采样到的那个 token,再复用 RL 框架:把 \(\mathrm{sg}\big[\log\frac{\pi_E(y_t\mid x,y_{\lt t})}{\pi_\theta(y_t\mid x,y_{\lt t})}\big]\) 当作每个 token 的优势,代入策略梯度。这很省资源,但梯度方差大、训练不稳。V4 改为在每个位置对整个词表精确计算 KL。对学生 logits \(\mathbf z\) 求导很干净(记 \(p=\pi_\theta,\ q=\pi_E\),\(\ell_v=\log p_v-\log q_v\),\(\mathrm{KL}_t=\sum_vp_v\ell_v\)):

$$\frac{\partial\,\mathrm{KL}_t}{\partial z_v}=p_v\big(\ell_v-\mathrm{KL}_t\big).$$

推导:\(\partial p_u/\partial z_v=p_u(\delta_{uv}-p_v)\),所以 \(\partial\mathrm{KL}_t/\partial z_v=\sum_up_u(\delta_{uv}-p_v)(\ell_u+1)=p_v(\ell_v+1)-p_v(\mathrm{KL}_t+1)\)。每个位置的梯度都是一个确定的 129280 维向量,不再依赖采到哪个 token,方差自然小得多(前缀仍是学生采样来的,这部分随机性还在)。

10.5 让全词表 OPD 跑得动

十几个教师、每个可能上万亿参数、词表 12.9 万,直接把所有教师的 logits 存下来是不可能的。V4 的做法:

10.6 FP4 量化感知训练(QAT)

后训练阶段引入 QAT,让模型(包括教师和参考模型)适应量化带来的精度损失。量化格式是 MXFP4:每 32 个元素一组,共享一个 8 位的 2 的幂次缩放因子(E8M0),每个元素是 4 位 E2M1 浮点,能表示 \(\pm\{0,0.5,1,1.5,2,3,4,6\}\)。作用在两处:

  1. MoE 专家权重:显存的主要占用者。Pro 主干有约 1.55T 个路由专家参数(\(61\times384\times3\times7168\times3072\)),FP8 存要约 1.55 TB,MXFP4(每元素 4 bit,加上每 32 个元素一个 8 bit 的 scale,平均 4.25 bit)约 0.82 TB。
  2. CSA indexer 的 QK 路径:QK 激活在 FP4 下缓存、读取、相乘,加速长上下文下的打分。同时把索引分数 \(I_{:,:}\) 从 FP32 量化到 BF16,top-k 选择器提速 2 倍,KV 条目的召回率保持 99.7%。

专家权重的 QAT 流程:优化器维护 FP32 主权重,前向时先量化到 FP4,再反量化到 FP8 参与计算。这一步反量化是无损的:E4M3 比 E2M1 多 2 个指数位、动态范围大得多,只要每个 FP8 量化块(128×128)里各个 FP4 子块(1×32)的 scale 之比不超过某个阈值,细粒度的 scale 信息就能被 FP8 的指数范围完全吸收;他们验证了当前权重满足这个条件。于是整个 QAT 可以完全复用现有的 FP8 训练框架。反向时,梯度对前向用的那份 FP8 权重计算,直接传回 FP32 主权重——等价于对量化操作使用直通估计器(STE),也省掉了对转置权重重新量化。

在推理和 RL rollout 阶段(不需要反向),直接使用真正的 FP4 权重,而不是模拟量化。这保证采样时的模型行为与线上部署完全一致,同时真正减少了显存读取和占用。indexer 的 QK 路径同样处理。

10.7 Rollout 服务、百万 token RL 与沙箱

可抢占、容错的 rollout。集群有全局抢占式调度器,任何任务随时可能被抢占,硬件故障也很常见。V4 给每个生成请求维护一个 token 粒度的预写日志(WAL):每生成一个 token 就追加进去。被抢占时暂停推理引擎、保存未完成请求的 KV cache;恢复时用 WAL 和 KV cache 接着解码;即使遇到致命硬件错误,也能用 WAL 里的 token 重新 prefill 重建 KV cache。

报告特别指出:把未完成的请求从头重新生成在数学上是错的,会引入长度偏差。原因是短回答更可能在中断前就生成完,长回答更可能被打断;如果被打断的统统重来,最终收集到的样本会系统性地偏短。如果推理栈是批不变且确定的(8.4 节),用相同随机种子重新生成也是正确的,但要多花一遍解码,远不如 WAL 高效。

百万 token 的 RL/OPD。把 rollout 数据拆成轻量的元数据和重量的逐 token 字段。分发时先加载全部元数据做全局 shuffle 和打包布局计算;逐 token 字段通过共享内存数据加载器加载(节点内不重复),在 mini-batch 粒度用完即释放;设备上同时存放几个 mini-batch 由负载动态决定。

DSec 沙箱。为 agent 的训练和评测,DeepSeek 做了一个生产级沙箱平台 DeepSeek Elastic Compute(DSec):三个 Rust 组件(API 网关 Apiserver、每台机器上的代理 Edge、集群监控 Watcher),用自定义 RPC 互连,构建在 3FS 分布式文件系统上,单集群管理数十万个并发沙箱。设计要点:

11. 评测结果

11.1 设置

11.2 与闭源/开源模型对比(报告表 6)

基准(指标)Opus-4.6 MaxGPT-5.4 xHighGemini-3.1-Pro HighK2.6 ThinkingGLM-5.1 ThinkingDS-V4-Pro Max
MMLU-Pro (EM)89.187.591.087.186.087.5
SimpleQA-Verified (Pass@1)46.245.375.636.938.157.9
Chinese-SimpleQA (Pass@1)76.476.885.975.975.084.4
GPQA Diamond (Pass@1)91.393.094.390.586.290.1
HLE (Pass@1)40.039.844.436.434.737.7
LiveCodeBench (Pass@1)88.8-91.789.6-93.5
Codeforces (Rating)-31683052--3206
HMMT 2026 Feb (Pass@1)96.297.794.792.789.495.2
IMOAnswerBench (Pass@1)75.391.481.086.083.889.8
Apex (Pass@1)34.554.160.924.011.538.3
Apex Shortlist (Pass@1)85.978.189.175.572.490.2
MRCR 1M (MMR)92.9-76.3--83.5
CorpusQA 1M (ACC)71.7-53.8--62.0
Terminal Bench 2.0 (Acc)65.475.168.566.763.567.9
SWE Verified (Resolved)80.8-80.680.2-80.6
SWE Pro (Resolved)57.357.754.258.658.455.4
SWE Multilingual (Resolved)77.5--76.773.376.2
BrowseComp (Pass@1)83.782.785.983.279.383.4
HLE w/ tools (Pass@1)53.152.051.654.050.448.2
GDPval-AA (Elo)161916741314148215351554
MCPAtlas Public (Pass@1)73.867.269.266.671.873.6
Toolathlon (Pass@1)47.254.648.850.040.751.8

报告的总结是:知识上 SimpleQA-Verified 比其他开源模型高出约 20 个点,但仍落后 Gemini-3.1-Pro;推理上超过所有开源模型,略逊于 GPT-5.4 和 Gemini-3.1-Pro,自评落后前沿闭源模型约 3~6 个月;Codeforces 3206 分,报告说在人类选手中排第 23;agent 上与 K2.6、GLM-5.1 相当、落后闭源;MRCR 1M 超过 Gemini-3.1-Pro、不及 Opus 4.6。另外,在 Terminal-Bench 2.0 的 Verified 子集上 V4-Pro 约 72.0。

11.3 两个尺寸、三档强度(报告表 7)

基准(指标)Flash Non-ThinkFlash HighFlash MaxPro Non-ThinkPro HighPro Max
MMLU-Pro (EM)83.086.486.282.987.187.5
SimpleQA-Verified23.128.934.145.046.257.9
Chinese-SimpleQA71.573.278.975.877.784.4
GPQA Diamond71.287.488.172.989.190.1
HLE8.129.434.87.734.537.7
LiveCodeBench (Pass@1-COT)55.288.491.656.889.893.5
Codeforces (Rating)-28163052-29193206
HMMT 2026 Feb40.891.994.831.794.095.2
IMOAnswerBench41.985.188.435.388.089.8
Apex1.019.133.00.427.438.3
Apex Shortlist9.372.185.79.285.590.2
MRCR 1M (MMR)37.576.978.744.783.383.5
CorpusQA 1M (ACC)15.559.360.535.656.562.0
Terminal Bench 2.049.156.656.959.163.367.9
SWE Verified73.778.679.073.679.480.6
SWE Pro49.152.352.652.154.455.4
SWE Multilingual69.770.273.369.874.176.2
BrowseComp-53.573.2-80.483.4
HLE w/ tools-40.345.1-44.748.2
MCPAtlas Public64.067.469.069.474.273.6
GDPval-AA (Elo)--1395--1554
Toolathlon40.743.547.846.349.051.8

几个规律:Flash 和 Pro 的差距主要在知识(SimpleQA-Verified 34.1 vs 57.9)和难的 agent 任务(Terminal Bench 56.9 vs 67.9);给足思考预算后,推理题上 Flash-Max 和 Pro-Max 差距不大(HMMT 94.8 vs 95.2)。报告图 9 显示 MRCR 8-needle 在 128K 以内很稳,超过 128K 后开始下降。报告图 10 还显示,在 HLE 上 V4-Pro 达到同样分数所用的 token 比 V3.2 少。

形式化数学(报告图 8):在 Putnam-2025 的「重算力、形式与非形式混合」设置下,V4 拿到满分 120/120;在 Putnam-200 Pass@8 的轻量设置下也超过 Seed-Prover 等此前的系统。

11.4 真实任务

12. 小结与我的看法

从 V3/V3.2 出发,V4 改动的全部清单:

  1. 注意力:MLA 的潜向量 → 512 维 shared-KV(K=V)MQA;在序列维度上压缩(CSA 4 倍重叠压缩、HCA 128 倍);DSA 从选 token 变成选压缩块,top-k 变小;加滑窗分支、attention sink、Q/KV RMSNorm、部分 RoPE + 输出反旋转、分组输出投影。
  2. 残差:mHC,4 路残差流 + Sinkhorn 投影到双随机矩阵。
  3. MoE:√softplus 打分,前 3 层 Hash 路由,去掉节点限制,激活 6 个更大的专家,SwiGLU clamp。
  4. 优化:Muon(混合 Newton–Schulz、RMS 0.18、Nesterov),不需要 QK-Clip;预见式路由处理 loss spike。
  5. 系统:wave 化的 MegaMoE;TileLang;批不变 + 确定性 kernel;Muon 的混合 ZeRO;压缩注意力的两阶段 CP;张量级重计算;异构 KV cache 和磁盘缓存。
  6. 后训练:专家 SFT + GRPO → 多教师全词表 OPD;GRM 由 actor 自己担任并被 RL;三档推理强度;DSML 工具格式;跨轮保留推理;Quick Instruction;FP4 QAT;WAL rollout;DSec 沙箱。

几点看法:

报告提到的未来方向:进一步精简架构、研究训练稳定性的基础问题、在 MoE 和稀疏注意力之外探索新的稀疏维度(比如更稀疏的嵌入模块)、低延迟架构、长程多轮 agent 任务、多模态,以及更好的数据构造与合成。

13. 参考与延伸阅读