Qwen4 架构全解:把参数从显存里搬出去
Qwen4 的权重还没发,但架构已经公开:8 月 27 日开源的 Qwen3.8-Flash-Next,官方定位是 an early preview of the architecture used in Qwen4。下面所有数字都来自它的 config.json 和官方技术博客,可以逐项复算。
规格
| 项 | Qwen3.8-Flash-Next |
|---|---|
| 主模型参数 | 125B |
| N-gram 查表参数 | 51B(不入矩阵乘) |
| 每 token 激活 | 6B |
| 层数 | 48 |
| 注意力布局 | 36 层 GDN + 12 层 QSA(3:1) |
| Hidden / Head dim | 2560 / 256 |
| Q 头 / KV 头 | 24 / 2(GQA 12:1) |
| RoPE | 部分旋转 25%(64 维),$\theta=10^7$,mRoPE 交错 |
| MoE | 512 专家,top-10,专家中间维 640,共享专家 1 个 |
| 残差 | Gated Residual,4 分支(HC4) |
| 原生上下文 | 262,144,YaRN 可扩到 1,000,000 |
| MTP | 1 层,混合模式 |
| 视觉塔 | 27 层,hidden 1152,patch 16,2×2 合并 |
| 词表 | 248,320 |
注意 125B 和 51B 是两个账本:算力只算前者,显存要看两者之和(176B),但后者不占 HBM。
48 层的排布是这样的:
1 | from transformers import AutoConfig |
QSA:索引粒度也一起压
DSA 是 token 级稀疏:用小号 indexer 给每个历史 token 打分,取 top-k 再算注意力。注意力成本从 $O(n^2)$ 降到 $O(nk)$,但 indexer 仍要把 $n$ 个位置全打一遍分。上下文到 1M,这笔索引开销不可忽略。
QSA 把索引的粒度也压掉:
对应四个超参:
| 超参 | 值 | 含义 |
|---|---|---|
indexer_compress_ratio |
4 | 4 个 token 合成一个 micro-block |
indexer_budget |
2048 | 每次检索的 token 预算(= 512 块) |
indexer_n_heads / indexer_kv_heads |
4 / 1 | indexer 自身极窄 |
indexer_head_dim |
128 | 打分用的头维度 |
于是 1M 上下文下每个 QSA 层实际只 attend 2048 个 token,覆盖 0.2% 的序列长度。
Qwen 没有采用跨层索引复用(IndexCache 的思路),而是每层独立做序列压缩。原因是混合架构里 GDN 层会改变表示,相邻层「选出同一批位置」的假设不成立。代价是每层多跑一次 indexer,换来的是不依赖跨层相似性。
官方数据:1M 上下文下 QSA kernel 在 prefill 上最高 7.6×、decode 上 4.9× 加速;90% 前缀缓存命中的线上设定下,prefill 吞吐是 Qwen3.7-Plus 的 8.6 倍。
GDN + QSA:3:1 的分工
48 层里每 4 层一个循环:3 层 GDN + 1 层 QSA,由 layer_types 写死。GDN 用 delta rule 把历史压进固定大小的矩阵状态,状态与上下文长度无关:
$$48 \times 128 \times 128 \times 36\ \text{层} \approx 2.8\times10^{7}\ \text{个 fp32} \approx 113\ \text{MB}$$
113MB 是常数,1K 和 1M 上下文一样大。QSA 层保留真正的 KV cache,每 token 每层 2 头 × 256 维 × 2(K,V) × 2 字节 = 2KB,12 层合计 24KB/token:
| 上下文 | QSA 层 KV cache |
|---|---|
| 32K | 0.8 GB |
| 262K | 6.3 GB |
| 1M | 24.6 GB |
48 层全注意力的话这三个数要乘 4。所以 3:1 的含义是:大部分层用常数内存记历史,少数层用线性内存做精确定位。
Gated Residual
原版 Hyper-Connections 把残差流扩成多分支,层间用矩阵 $B$ 混合。Gated Residual 保留分支、去掉混合,改为在读写时加逐元素的、依赖当前内容的门:
$$\mathbf{x}_{b}^{\ell+1} = g_{b}^{\text{read}}(\mathbf{h}_{\ell})\odot \mathbf{x}_{b}^{\ell} + g_{b}^{\text{write}}(\mathbf{h}_{\ell})\odot \mathrm{Layer}_{\ell}(\mathbf{h}_{\ell})$$
四个分支(hc_count=4),低秩门(hc_lowrank=320)。官方给的理由是:读写门足够表达时,分支混合的收益不显著,反而多一次访存、多一个不稳定源。这和 DeepSeek-V4 的 mHC 正好相反——那边保留混合矩阵,但把它约束到双随机矩阵流形上换数值稳定。
另外两点:门本身抑制激活离群值;残差状态可存 FP8,访存减半。官方还观察到四条分支里有一条会自发成为远程通路,从第一个注意力层连到中后段多数层。
N-gram Embedding:51B 参数放主机内存
标准 embedding 一个 token 查一行。N-gram embedding 用当前 token 加前两个 token 组成的三元组去查表(ngram_size=3),补上短语和局部模式的表示。
表不是一张,而是 16 张子表(bigram 8 张、trigram 8 张,heads_per_ngram=8)。地址用混合哈希:
$$h = \Big(\bigoplus_{i=0}^{n-1}\big(x_{t-i}\cdot m_i\big)\Big) \bmod 2^{64} \qquad \text{row} = h \bmod p_h$$
$m_i$ 是层内乘子,$p_h$ 是子表局部词表大小;序列开头或遇 EOS 时缺失前驱补 EOS id。地址只依赖上下文,可以在生成开始前批量算好,这是预取的前提。
参数量:ngram_vocab_size_base=20000000 × ple_embed_dim=2560:
$$2.0\times10^{7} \times 2560 \approx 5.12\times10^{10}$$
按精度折算的体积:
| 存储 | 体积 | 部署门槛 |
|---|---|---|
| bf16 | ~102 GB | 多通道服务器内存 |
| INT8 | ~51 GB | 工作站 |
| IQ4_NL(GGUF 实际格式) | ~26 GB | 单机 64G 内存 |
这些参数各自待在哪里:
放置位置是 ple_layer_ids=[2]:只有第 3 层挂这张表,紧跟在两层 GDN 之后。官方把它称为「大规模局部模式记忆」,挂在靠前的位置最划算。
访存特性值得单独算:
- 带宽不是瓶颈。 每 token 取 16 行 × 2560 维,bf16 下 80KB、int4 下 20KB;batch 64、100 tok/s 也就百来 MB/s。
- 延迟是瓶颈。 每个 token 一次跨总线的随机访存,预取晚了就是 stall。查表对延迟敏感,矩阵乘对带宽敏感。
- 容量是硬门槛。 26GB 的表决定了这条路的入场券是内存容量,不是算力。
MoE
| 项 | 数值 | 对比 |
|---|---|---|
| 专家数 | 512 | DeepSeek-V4 是 256 / 384 |
| 每 token 激活 | 10 | 6 |
| 专家中间维 | 640 | 常见 1408–2048 |
| 共享专家 | 1(同样 640 宽) | 1 |
参数量验算,每层:
$$512 \times 3 \times 2560 \times 640 \approx 2.52\ \text{B / 层}$$
48 层约 121B,加共享专家 0.24B、注意力 0.4B、GDN 约 1.7B、词表 0.64B,合计 124B 出头,对上 125B。
激活侧:10 个专家 49M/层 × 48 ≈ 2.4B,加共享专家 0.24B、注意力 0.4B、GDN 1.7B、词表 0.64B,合计 5.4B,对上 6B。
专家又小又多的收益是路由分辨率更高、分工更细;代价是每 token 要 gather 10 份专家权重,通信和访存放大,需要 EP 加高带宽互联才划算。
训练
优化器换成 Muon,三个实现细节是重点:
- 正交化精度:Newton-Schulz 的步数和系数要重调。
- 参数分配:注意力、GDN、MoE 专家的主权重走 Muon;embedding、路由器、GR 低秩参数继续走 AdamW。
- 融合矩阵先拆:QKV、SwiGLU、GDN 投影在实现里是拼在一起的,Muon 要求按独立线性变换分别正交化。
一个反直觉结论:Batch Size Warmup 可以去掉。从小 batch 爬到目标 batch 不提升最终效果,反而多花 18.8% 的优化步数。新配方直接上目标 batch,配合更大学习率;scaling law 也按新架构重拟合,结论是能稳定吃更大的 LR 和 batch。
稳定性沿用 Qwen3.5 以来的做法:零中心 RMSNorm 且 norm 权重吃 weight decay、注意力输出门控(sigmoid)、MoE 路由器归一化初始化。
27B 的推断配置
四档里 27B 是明确开源的,配置从 llama.cpp 的补丁里被反推出来:
| 维度 | 推断值 |
|---|---|
| 类型 | 稠密(PR 写明 strict dense) |
| Hidden | 5120 |
| 骨架 | 3:1 的 GDN + 注意力,第 4 层换 QSA |
| 残差 | HC4 |
| MTP | 有,draft=4 |
| 原生上下文 | 未公布 |
补丁只验证配置和算子契约,真正的 QSA 权重没给,所以这是「能跑通」的证据而非规格书。但 GDN 头配置(QK 16 头、V 48 头、head_dim 128)和 Flash-Next 完全一致,说明骨架在往下传。
小结
四条改动可以归成两类:QSA 减少「看多少」、GDN 减少「记多少」、GR 改善「怎么传」,这三条都在省;N-gram 查表用确定性寻址扩容,几乎不增加每 token 的 FLOPs,是唯一在加的一条。它的代价从算力转成了内存容量和访存延迟——把「模型容量」和「HBM 容量」解耦,是这一代最实质的改动。
参考链接
- Qwen3.8-Flash-Next 官方博客:https://www.alibabacloud.com/blog/qwen3-8-flash-next-a-new-architecture-towardsultimate-cost-efficiency_603501
- 模型权重(含 config.json):https://huggingface.co/Qwen/Qwen3.8-Flash-Next
- 技术报告:https://github.com/QwenLM/Qwen3.8-Flash-Next/blob/main/tech_report.pdf
- Transformers 文档中的
qwen4_exp:https://huggingface.co/docs/transformers/en/model_doc/qwen4_exp - Gated DeltaNet:https://arxiv.org/abs/2412.06464
- DeepSeek-V3.2(DSA 来源):https://arxiv.org/abs/2512.02556
- Conditional Memory via Scalable Lookup(Engram):https://arxiv.org/abs/2601.07372