从llama2到Qwen3.5-MoE,再到DeepSeek-V4-Flash——架构变迁笔记

题图

无声子夜翩跹指间
谁拾获着散落的碎片
你说忘了吧又回头
不舍得远走
如果你迷失在无明中
我会为你守候
等到春暖花开的时候
都会再度重逢

—— 焚蝶 · 铁痕电台-MSR/Aurora Sky

llama2的架构总算演进到了第三代

题图:《明日方舟:终末地》庄方仪潜能三插图

引子

时值Qwen3.6、DeepSeek-V4相继发布之际,大模型的竞争已从”把参数做大”转向”把结构做巧”——总参数与激活参数解耦,长序列的代价从平方压回线性,推理加速直接做进了权重本身。回望2023年的llama2,它留下的那张图纸依然是今天所有架构的默认值,沿着基线看两代演进,就能看清这三年的路径。看结构是很有必要的。

本文以llama2的结构为基线,逐次展示Qwen3.5-MoE和DeepSeek-V4-Flash相对上一代改了什么、保留了什么。作为读代码比读论文习惯的我,所有维度都直接来自真实的config和权重文件头,不下权重。本文不会介绍训练细节和采样策略,只谈结构。

基线:llama2的结构

以7B为例,我们先看整体——一条直线:

1
2
3
4
5
6
7
input_ids [B,S]
↓ Embedding (32000 → 4096)
hidden [B,S,4096]
↓ 32 × TransformerBlock
↓ RMSNorm
↓ lm_head (4096 → 32000)
logits [B,S,32000]

每个Block是标准的pre-norm残差结构:

1
2
3
4
5
6
7
8
x ─┬──────────────────┐
↓ RMSNorm │ 残差
↓ Attention │
⊕ ←────────────────┘
├──────────────────┐
↓ RMSNorm │ 残差
↓ SwiGLU FFN │
⊕ ←────────────────┘

三个组件,逐个看:

注意力(MHA,70B为GQA):Q/K/V各自线性投影,Q、K做RoPE,因果softmax注意力:

Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q,K,V)=\text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V

其中 Q,K,VRB×H×S×dhQ,K,V\in\mathbb{R}^{B\times H\times S\times d_h} 由层输入 xRB×S×dx\in\mathbb{R}^{B\times S\times d}WQ,WK,WVW^Q,W^K,W^V 投影而来(7B:H=32H=32dh=128d_h=128);dk=dhd_k=d_h 为缩放维度,SS 为序列长。

FFN(SwiGLU):

FFN(x)=Wdown(SiLU(Wgatex)Wupx)\text{FFN}(x) = W_{down}\big(\text{SiLU}(W_{gate}x) \odot W_{up}x\big)

其中 xRB×S×dx\in\mathbb{R}^{B\times S\times d} 为层输入;Wgate,WupRinter×dW_{gate},W_{up}\in\mathbb{R}^{inter\times d} 投出门与值,WdownRd×interW_{down}\in\mathbb{R}^{d\times inter} 降回(7B:d=4096d=4096inter=11008inter=11008)。

中间维1100883×409611008 \approx \frac{8}{3} \times 4096

归一化(RMSNorm,子层之前):

RMSNorm(x)=x1dixi2+ϵγ\text{RMSNorm}(x) = \frac{x}{\sqrt{\frac{1}{d}\sum_i x_i^2 + \epsilon}} \cdot \gamma

其中 xR×dx\in\mathbb{R}^{\dots\times d} 为待归一向量,dd 为 hidden;γRd\gamma\in\mathbb{R}^d 是可学习缩放,沿最后一维广播;ϵ\epsilon 防除零。

两个规格:

7B 70B
层数 32 80
hidden 4096 8192
Q头数 / KV头数 32 / 32 64 / 8(GQA)
head_dim 128 128
FFN中间维 11008 28672
上下文 4096 4096

对应总参(逐层累加):

  • 7B:32层 × (注意力 4×409624 \times 4096^2 + FFN 3×4096×110083 \times 4096 \times 11008) + embedding/lm_head 2×32000×40962 \times 32000 \times 4096 ≈ 6.7B
  • 70B:80层 × (注意力 2×81922+2×8192×10242 \times 8192^2 + 2 \times 8192 \times 1024(GQA) + FFN 3×8192×286723 \times 8192 \times 28672) + 2×32000×81922 \times 32000 \times 8192 ≈ 69B

结构上三个特征,后面两代的全部改动都围绕它们:

  1. 稠密FFN:每个token激活全部参数
  2. 全注意力:每层都是O(S2)O(S^2),KV cache随序列线性增长
  3. 单条残差流xx+sublayer(x)x \leftarrow x + \text{sublayer}(x)

第一次演进:Qwen3.5-MoE vs llama2

整体形状和llama2一样,还是一条直线——变的只是管子里的维度,外加挂出一个MTP块:

1
2
3
4
5
6
7
8
input_ids [B,S]
↓ Embedding (248320 → 2048) ← 词表32000→248320;视觉特征替换image/video占位
hidden [B,S,2048] ← hidden 4096→2048
↓ 40 × Block ← 32→40层
↓ RMSNorm
↓ lm_head (2048 → 248320)
logits [B,S,248320]
└→ MTP块 (0.84B) ← 新增,投机解码用

Block内部,pre-norm残差的骨架原封不动,两个子层的算子都被换了

1
2
3
4
5
6
7
8
x ─┬────────────────────────┐
↓ RMSNorm │ 残差
↓ GDN / Full Attention │ ← 换:全注意力 → 混合注意力,3:1交替
⊕ ←──────────────────────┘
├────────────────────────┐
↓ RMSNorm │ 残差
↓ MoE (256选8 + 1共享) │ ← 换:稠密SwiGLU → MoE
⊕ ←──────────────────────┘

规格:40层,hidden 2048,上下文256K。总参数36B,其中专家权重 40层×256×3×2048×512 ≈ 32.2B,占90%;每token激活约3B ≈ 40层×9个专家×3.15M的FFN(≈1.1B) + 注意力投影(≈1.2B) + embedding/lm_head(2×248320×20482 \times 248320 \times 2048 ≈ 1.0B)。

变化一:稠密FFN → 256选8的MoE

llama2每层一个大FFN(4096→11008→4096,3×4096×11008136M3 \times 4096 \times 11008 \approx 136M参数);Qwen把它拆成256个小专家加1个共享专家,每token只过其中9个。我们看看MoE层内部:

1
2
3
x → router: softmax(W_r x) → top-8 专家编号+权重
├→ 8个routed专家: SwiGLU(中间维仅512),加权求和
└→ 共享专家: SwiGLU,必过,输出再乘sigmoid门
p=softmax(Wrx),I=topk8(p),wi=pijIpjp = \text{softmax}(W_r x), \quad I = \text{topk}_8(p), \quad w_i = \frac{p_i}{\sum_{j \in I} p_j}

其中 xRT×2048x\in\mathbb{R}^{T\times 2048} 为展平后的 token(T=B×ST=B\times S);WrR256×2048W_r\in\mathbb{R}^{256\times 2048} 为路由矩阵;pRT×256p\in\mathbb{R}^{T\times 256} 是逐专家概率;II 为选中的 8 个专家号;wiw_i 为组内归一化权重。

完整前向——8个routed专家加权求和,再加sigmoid门控的共享专家:

y=iIwiWdown(i)(SiLU(Wgate(i)x)Wup(i)x)+σ(gs(x))shared(x)y = \sum_{i \in I} w_i \cdot W_{down}^{(i)}\Big(\text{SiLU}\big(W_{gate}^{(i)}x\big) \odot W_{up}^{(i)}x\Big) + \sigma(g_s(x)) \cdot \text{shared}(x)

其中 Wgate(i),Wup(i)R512×2048W_{gate}^{(i)},W_{up}^{(i)}\in\mathbb{R}^{512\times 2048}Wdown(i)R2048×512W_{down}^{(i)}\in\mathbb{R}^{2048\times 512} 为第 ii 个专家的 SwiGLU 权重;gs(x)RT×1g_s(x)\in\mathbb{R}^{T\times 1} 为共享专家 sigmoid 门;shared(x)RT×2048\text{shared}(x)\in\mathbb{R}^{T\times 2048} 为共享专家输出。

权重布局上,256个专家融合成两个大张量,按专家号索引:

WguR256×1024×2048,WdownR256×2048×512W_{gu} \in \mathbb{R}^{256 \times 1024 \times 2048}, \quad W_{down} \in \mathbb{R}^{256 \times 2048 \times 512}

其中第一维 256 为专家号,按号索引;1024=2×5121024=2\times 512 是 gate|up 拼接;2048 为 hidden;512 为专家中间维。

一层约840M参数里专家占 256×3×2048×512=805M256 \times 3 \times 2048 \times 512 = 805M(96%),但每token只算约28M = (8+1)×3×2048×512(8+1) \times 3 \times 2048 \times 512。防坍缩靠辅助损失:fif_i是专家实际分到的token比例,PiP_i是路由器给它的平均概率:

Laux=αNifiPiL_{aux} = \alpha \cdot N \cdot \sum_i f_i \cdot P_i

其中 α=0.001\alpha=0.001 为损失系数;N=256N=256 为专家数;fif_i 为专家 ii 实际分到的 token 比例(top-k 选出,不可导);PiP_i 为路由器给 ii 的平均 softmax 概率(可导,梯度由此进入)。

变化二:全注意力 → 混合注意力(3线性+1全)

llama2每层都是全注意力;Qwen把40层排成”3层线性注意力+1层全注意力”的循环,全注意力只在层3, 7, …, 39:

1
2
层0  层1  层2  层3   层4  层5  层6  层7
GDN GDN GDN Full GDN GDN GDN Full ...

线性注意力层是Gated DeltaNet:没有注意力矩阵,维护固定大小的记忆矩阵SR32×128×128S \in \mathbb{R}^{32 \times 128 \times 128}(约0.5M个状态单元,是状态不是权重),逐token递推:

St=egtSt1+βtkt(vtSt1kt)S_t = e^{g_t} \cdot S_{t-1} + \beta_t k_t (v_t - S_{t-1}^\top k_t)^\top

其中 StR32×128×128S_t\in\mathbb{R}^{32\times 128\times 128} 为记忆矩阵(32 个 V 头,各 128×128128\times 128);kt,vtR32×128k_t,v_t\in\mathbb{R}^{32\times 128}(16 个 K 头复制一倍对齐 V 头);gt,βtR32g_t,\beta_t\in\mathbb{R}^{32} 为逐头衰减与写入强度标量。

ot=Stqto_t = S_t^\top q_t

其中 qtR32×128q_t\in\mathbb{R}^{32\times 128} 为 query 头;otR32×128o_t\in\mathbb{R}^{32\times 128} 为逐 token 读出的注意力输出。

完整实现——QKV一次投出过kernel=4的因果卷积,衰减与写入强度来自标量投影,输出再过门:

[qt,kt,vt]=SiLU(Conv1d4(Wqkvxt)),zt=Wzxt[q_t, k_t, v_t] = \text{SiLU}\big(\text{Conv1d}_4(W_{qkv}x_t)\big), \quad z_t = W_z x_t

其中 WqkvR8192×2048W_{qkv}\in\mathbb{R}^{8192\times 2048} 一次投出 Q|K|V(2048|2048|4096),过 kernel=4 因果卷积;WzR4096×2048W_z\in\mathbb{R}^{4096\times 2048} 投出输出门 ztz_t

gt=exp(A)softplus(Waxt+Δ),βt=σ(Wbxt)g_t = -\exp(A) \cdot \text{softplus}(W_a x_t + \Delta), \quad \beta_t = \sigma(W_b x_t)

其中 A,ΔR32A,\Delta\in\mathbb{R}^{32} 为逐头可学习衰减参数;Wa,WbR32×2048W_a,W_b\in\mathbb{R}^{32\times 2048} 为标量投影。

outt=Wout(RMSNorm(ot)SiLU(zt))\text{out}_t = W_{out}\big(\text{RMSNorm}(o_t) \odot \text{SiLU}(z_t)\big)

其中 WoutR2048×4096W_{out}\in\mathbb{R}^{2048\times 4096} 把逐头输出拼回 hidden;门控 SiLU(zt)\text{SiLU}(z_t) 逐头相乘。

gtg_t是每头衰减系数,βt\beta_t是写入强度——带遗忘的纠错式记忆。序列多长状态都不变,decode成本恒定。这就是对llama2"KV cache线性增长"的回应:30层不再产生KV cache。

变化三:保留的10层全注意力也加强了

相对llama2的MHA/GQA:

  • 输出门控:q_proj输出双倍,一半是Q、一半是gate,注意力输出先乘sigmoid(gate)\text{sigmoid}(gate)再进o_proj
  • 部分RoPE:head_dim=256只旋转前64维,其余192维位置无关(llama2是全维旋转)
  • 强GQA:16个Q头共享2个KV头(8:1),比llama2-70B的64/8更激进

完整实现——q_proj投出双倍维度拆成Q和gate,RoPE只旋转前64维(RoPE64\text{RoPE}_{64}),KV的2个头复制8份对齐Q头:

Q,g=split(Wqx),Q~=RoPE64(Q),K~=RoPE64(Wkx)Q, g = \text{split}(W_q x), \quad \tilde Q = \text{RoPE}_{64}(Q), \quad \tilde K = \text{RoPE}_{64}(W_k x)

其中 WqR8192×2048W_q\in\mathbb{R}^{8192\times 2048} 输出双倍,拆成 QR16×256Q\in\mathbb{R}^{16\times 256}(每 token)与门 ggWkR512×2048W_k\in\mathbb{R}^{512\times 2048}(2 KV 头×256);RoPE64\text{RoPE}_{64} 只旋转前 64 维。

Attn(x)=Wo(softmax(Q~K~256)V~σ(g))\text{Attn}(x) = W_o\Big( \text{softmax}\big(\tfrac{\tilde Q \tilde K^\top}{\sqrt{256}}\big)\tilde V \odot \sigma(g) \Big)

其中 V~\tilde V 由 2 个 KV 头复制 8 份对齐 16 个 Q 头;σ(g)RB×S×4096\sigma(g)\in\mathbb{R}^{B\times S\times 4096} 为输出门;WoR2048×4096W_o\in\mathbb{R}^{2048\times 4096}

这10层每层的投影参数约27M:q_proj 2048×81922048 \times 8192(含输出门) + k/v_proj 2×2048×5122 \times 2048 \times 512 + o_proj 4096×20484096 \times 2048

变化四:新增MTP与多模态

checkpoint里多了一个MTP块(0.84B ≈ 一层全注意力约27M + 一层MoE约809M):主干最终hidden与下一token的embedding拼接后,再过一层注意力+MoE,预测更后面的token,用于投机解码。另外加了ViT视觉编码器(约0.45B:27层×(4×11522+2×1152×46084 \times 1152^2 + 2 \times 1152 \times 4608) ≈ 0.43B,加patch嵌入与merger),embedding层的image/video占位位置由视觉特征替换。

MTP前向——hth_t是主干最后一层输出,et+1e_{t+1}是下一token的embedding(与主干共享):

htmtp=Block(Wfc[ht;et+1]),x^t+2=Wlmhtmtph^{mtp}_t = \text{Block}\big( W_{fc}[\,h_t \,;\, e_{t+1}\,] \big), \quad \hat x_{t+2} = W_{lm}\, h^{mtp}_t

其中 htRB×S×2048h_t\in\mathbb{R}^{B\times S\times 2048} 为主干末层输出;et+1RB×S×2048e_{t+1}\in\mathbb{R}^{B\times S\times 2048} 为下一 token 的 embedding(与主干共享);WfcR2048×4096W_{fc}\in\mathbb{R}^{2048\times 4096} 把拼接 [;][\,;\,] 降回 hidden;WlmR248320×2048W_{lm}\in\mathbb{R}^{248320\times 2048} 出 logits。

第二次演进:DeepSeek-V4-Flash vs Qwen3.5-MoE

这次连”一条直线”的形状都变了——单条残差流被拆成4条并行流(mHC),首尾各多一个折叠/展开算子:

1
2
3
4
5
6
7
8
9
input_ids [B,S]
↓ Embedding (129280 → 4096) ← 词表248320→129280;hidden 2048→4096
streams [B,S,4,4096] ← 新增:单流 → 4流mHC
↓ 43 × Block
↓ HyperHead (4流 → 1流) ← 新增
↓ RMSNorm
↓ lm_head (4096 → 129280)
logits [B,S,129280]
└→ MTP + DSpark ← 新增

Block内部,pre-norm残差还在,但每个子层被mHC包了一层”4流折叠→计算→写回”:

1
2
3
4
5
6
7
8
9
10
streams[4流] ─┬──────────────────────────┐
↓ attn_hc 折叠 (4流→1流) │ mHC写回
↓ RMSNorm │
↓ 滑窗 / CSA / HCA 压缩注意力 │ ← 换:递归GDN → 压缩+检索
⊕ ←──────────────────────────────────┘
├──────────────────────────┐
↓ ffn_hc 折叠 (4流→1流) │ mHC写回
↓ RMSNorm │
↓ MoE (256选6 + 1共享) │ ← 换:选8→选6,辅助损失→无损失,前3层hash
⊕ ←──────────────────────────────────┘

规格:43层,hidden 4096,上下文1M,以FP8+专家FP4发布。总参数304B,其中专家权重 43层×256×3×4096×2048 ≈ 277B,占91%。

变化一:token mixer从递推换成压缩+检索

Qwen的30层递归状态在DeepSeek这里完全消失,43层全是”滑动窗口+压缩KV”的注意力:

1
2
层0  层1   层2   层3    层4   层5    ...   层42
滑窗 滑窗 CSA HCA CSA HCA ... CSA
  • 滑窗层(2层):只看局部128个token
  • CSA层(21层):每4个token门控加权压成1条KV——1M上下文会产生26万条,所以配一个Lightning Indexer支路(每层约11M参数:2×4096×2562 \times 4096 \times 256 压缩投影 + 1024×81921024 \times 8192 query投影 + 4096×644096 \times 64 头权重),给每个query打分挑top-512:
sw=hwhReLU(qhKw)s_w = \sum_h w_h \cdot \text{ReLU}(q_h^\top K_w)

其中 qhR128q_h\in\mathbb{R}^{128} 为第 hh 个 index 头的 query(共 64 头,由 Q 低秩中间量 uu 投出);KwR128K_w\in\mathbb{R}^{128} 为第 ww 条压缩 key;whw_h 为头重要性(由 xx 投出,R64\in\mathbb{R}^{64})。

  • HCA层(20层):每128个token压成1条,1M上下文只有约8192条,全量可见

压缩本身是窗内softmax门控凸组合,CSA用交叠窗(上一窗CaC_a ⊕ 本窗CbC_b共8槽)避免硬切边界。对比Qwen的路线:一个把历史递推成固定状态,一个把历史压成可检索的条目。

压缩的完整实现——窗内成员按门控权重做凸组合,ptmodRp_{t \bmod R}是窗内位置偏置:

cw=RMSNorm(twinwαtkvt),αt=softmaxt(gatet+ptmodR)c_w = \text{RMSNorm}\Big(\sum_{t \in win_w} \alpha_t \odot kv_t\Big), \quad \alpha_t = \text{softmax}_t\big(gate_t + p_{t \bmod R}\big)

其中 kvt,gatetR512kv_t,gate_t\in\mathbb{R}^{512} 为窗内每 token 的内容与门(各由一个 512×4096512\times 4096 投影投出);ptmodRR512p_{t\bmod R}\in\mathbb{R}^{512} 为窗内位置偏置;αt\alpha_t 为窗内 softmax 权重(和为 1);cwR512c_w\in\mathbb{R}^{512} 为压缩条目;R=4R=4(CSA)或 128128(HCA)。

压缩条目在窗位置wRwR上做RoPE后,与滑窗KV拼接参与注意力;CSA层再把可见集限制到indexer选出的top-512:I(q)=topk512(s(q))\mathcal{I}^{(q)} = \text{topk}_{512}(s^{(q)})

变化二:注意力本体——K==V、低秩、门控sink

Qwen的全注意力层还是经典形状(Q/K/V分开,16头),DeepSeek的注意力本体激进得多:

  • K==V:只有1个KV头,同一张量既当K又当V,KV cache压到极致;代价是输出要做一次共轭旋转抵消V上的RoPE
  • Q两段低秩4096102464×5124096 \to 1024 \to 64 \times 512;输出分组低秩投回:64头拆8组各409610244096 \to 1024,拼成8192再混合回4096
  • 可学习sink:softmax里每头加一列”垃圾桶”logit,概率算完即丢,稳定长上下文注意力

完整实现——Q两段低秩,K/V共享一个投影,sink列ss进softmax分母后丢弃,RoPE\text{RoPE}_{-}表示在query位置用sin-\sin的共轭旋转:

u=RMSNorm(Wqax),Q=WqbuR64×512,K=V=RMSNorm(Wkvx)R512u = \text{RMSNorm}(W_{qa}x), \quad Q = W_{qb}u \in \mathbb{R}^{64 \times 512}, \quad K = V = \text{RMSNorm}(W_{kv}x) \in \mathbb{R}^{512}

其中 xRB×S×4096x\in\mathbb{R}^{B\times S\times 4096} 为层输入;WqaR1024×4096W_{qa}\in\mathbb{R}^{1024\times 4096}WqbR32768×1024W_{qb}\in\mathbb{R}^{32768\times 1024} 为 Q 的两段低秩(32768=64×51232768=64\times 512);WkvR512×4096W_{kv}\in\mathbb{R}^{512\times 4096} 为单 KV 头投影,K 与 V 共用。

pj=exp(zj)jexp(zj)+exp(s),o=RoPE(jpjvj)p_j = \frac{\exp(z_j)}{\sum_{j'} \exp(z_{j'}) + \exp(s)}, \quad o = \text{RoPE}_{-}\Big(\sum_j p_j v_j\Big)

其中 zjz_j 为第 jj 个 key 的注意力 logit;ss 为可学习 sink 标量(每头一个),进分母后该列被丢弃;vjv_jKjK_j(K==V);RoPE\text{RoPE}_{-} 为共轭旋转。

分组低秩输出投影(8组各409610244096 \to 1024,拼接后混合):

out=Wob[G1o1;G2o2;;G8o8]\text{out} = W_{ob}\big[\,G_1 o_1 \,;\, G_2 o_2 \,;\, \dots \,;\, G_8 o_8\,\big]

其中 oiR4096o_i\in\mathbb{R}^{4096} 为第 ii 组(64 头拆 8 组,每组 8 头×512)的注意力输出;GiR1024×4096G_i\in\mathbb{R}^{1024\times 4096} 为组内降秩;WobR4096×8192W_{ob}\in\mathbb{R}^{4096\times 8192} 把拼接结果混合回 hidden。

输出投影的参数量对比:直接投 32768×4096134M32768 \times 4096 \approx 134M;分组低秩 8×4096×1024+8192×409667M8 \times 4096 \times 1024 + 8192 \times 4096 \approx 67M,省一半。

变化三:残差从单流变4流(mHC)

llama2和Qwen都是单条残差xx+sublayer(x)x \leftarrow x + \text{sublayer}(x);DeepSeek把它扩成4条并行流,每个子层动态决定读哪些流、输出写回哪些流。折叠与三组系数都由当前流内容经一个线性层动态算出:

x=ipreiSi,prei=σ()+ϵ,posti=2σ()[0,2]x = \sum_i pre_i S_i, \quad pre_i = \sigma(\cdot) + \epsilon, \quad post_i = 2\sigma(\cdot) \in [0,2]

其中 SiRB×S×4096S_i\in\mathbb{R}^{B\times S\times 4096} 为第 ii 条残差流(共 4 条);prei,postipre_i,post_i 为逐 token 标量系数,由 4 流拼平(1638416384 维)经一个 24×1638424\times 16384 线性层动态算出。

C=Sinkhorn(softmax()),o=Sublayer(RMSNorm(x))C = \text{Sinkhorn}\big(\text{softmax}(\cdot)\big), \quad o = \text{Sublayer}\big(\text{RMSNorm}(x)\big)

其中 CR4×4C\in\mathbb{R}^{4\times 4} 为流间混合矩阵(同一线性层的 16 个输出经 softmax+Sinkhorn);oo 为折叠单流 xx 过子层(注意力或 MoE)的输出。

回写规则:

Sknew=postko+jCj,kSjS^{new}_k = post_k \cdot o + \sum_j C_{j,k} S_j

其中 postkopost_k\cdot o 把子层输出按强度写回第 kk 条流;jCj,kSj\sum_j C_{j,k} S_j 为旧流的双随机混合。

混合矩阵CC经20次Sinkhorn迭代投影成双随机矩阵,于是C2C1C=1|C|_2 \le \sqrt{|C|_1 |C|_\infty} = 1——86个子层复合下来残差路径非膨胀,这是深堆叠训练的骨架级保险。代价很小:每个HC位 24×163840.4M24 \times 16384 \approx 0.4M 参数,全模型2位×43层 ≈ 34M;换来的是残差激活内存×4。

变化四:路由从辅助损失换成无损失纠偏

Qwen靠LauxL_{aux}均衡专家;DeepSeek的noaux_tc不用辅助损失:打分用softplus\sqrt{\text{softplus}},选择时加专家纠偏偏置bb,加权时用原始分:

σ=softplus(Wrx),I=topk6(σ+b),wσI\sigma = \sqrt{\text{softplus}(W_r x)}, \quad I = \text{topk}_6(\sigma + b), \quad w \propto \sigma_I

其中 WrR256×4096W_r\in\mathbb{R}^{256\times 4096} 为路由矩阵;σRT×256\sigma\in\mathbb{R}^{T\times 256} 为 sqrtsoftplus 打分;bR256b\in\mathbb{R}^{256} 为专家纠偏偏置(只影响选择);II 为 top-6 专家号;加权 ww 用不含 bb 的原始分 σI\sigma_I

另外前3层用hash路由:选哪些专家由冻结表tid2eid[input_id]\text{tid2eid}[\text{input\_id}]直接查,权重仍是学习的——浅层词面特征按token静态分工,换可预测的访存和天然负载均衡:

I=tid2eid[input_id],wjσIjI = \text{tid2eid}[\text{input\_id}], \quad w_j \propto \sigma_{I_j}

其中 tid2eidZ129280×6\text{tid2eid}\in\mathbb{Z}^{129280\times 6} 为冻结查找表,由 token id 直接查出 6 个专家号(不依赖 xx);σIj\sigma_{I_j} 为路由在这些专家上的原始分,仍由 WrxW_r x 学习。

两种路由的矩阵都只有 256×40961M256 \times 4096 \approx 1M/层;tid2eid\text{tid2eid}129280×6129280 \times 6 的冻结查找表,不计入可学习参数。

变化五:推理与精度做进权重

Qwen的MTP之外,DeepSeek加了DSpark:用主干最后3层特征+低秩Markov结构按块草拟,草稿与目标同checkpoint。目标模型验证草稿token按拒绝采样接受——生成必须串行,但验证可以并行,一次forward给全部候选打分:

以概率min(1,ptarget(di)pdraft(di))接受草稿di\text{以概率} \min\Big(1, \frac{p_{target}(d_i)}{p_{draft}(d_i)}\Big) \text{接受草稿} d_i

其中 did_i 为草稿模型第 ii 个候选 token;pdraft(di)p_{draft}(d_i) 为草稿给它的概率;ptarget(di)p_{target}(d_i) 为目标模型一次 forward 在对应位置并行算出的概率;第一个被拒位置之后的草稿全部丢弃。

发布精度也从bf16变成FP8(e4m3,128×128块)+专家FP4,SwiGLU里的±10\pm 10 clamp就是低精度的数值护栏。

总结

三代结构摆在一起:

llama2-70B Qwen3.5-MoE DeepSeek-V4-Flash
总参数 / 激活 70B稠密 36B / 约3B 304B / 远小于总参
上下文 4096 256K 1M
token mixer 全注意力×全部层 30层GDN递归+10层门控全注意力 滑窗+CSA/HCA压缩+indexer
KV cache 全层线性增长 仅10层有 低秩+逐层压缩
FFN 稠密SwiGLU 256选8,辅助损失 256选6,noaux_tc,前3层hash
残差 单流 单流 4流mHC
投机解码 MTP MTP+DSpark
发布精度 bf16 bf16 FP8+FP4

三条趋势:

  1. 从全激活到按需激活:MoE把容量和成本拆开
  2. 从全注意力到两条稀疏路线:递推压缩(Qwen)或条目检索(DeepSeek),都在回答”长序列里大部分token不值得O(S2)O(S^2)的注视”
  3. 推理优化架构化:MTP、DSpark、量化从部署技巧变成训练时的一等公民

Don’t you get there? It calls, it calls,
我盼你凯旋 念念不忘,
仰いだ空が色を変えるから,
曾日复仰望的天空新彩焕然,
My naked heart can hear echoes, echoes,
这露骨心声 终闻回响,
識らず求めた Avidity,
却仍不知不觉地切盼,
Whisper your name again,
不甘低喃你名字,
Then restart it right away,
念完一次又一次,
Oh my bitter color ardor wander,
我的痛苦 欢愉 热情 犹疑,
Gotta feel it undercover,
只有暗暗藏于心底,
行方も知らない あの日の群青,
那天奔赴战场的你 至今下落仍是不明。

—— SawanoHiroyuki[nZk] / 瑞葵(mizuki)《Avid》

Reference