专栏Kimi K3 模型结构·总览1 / 8
8 min学习

Kimi K3 模型结构(0):一张图看懂 Kimi K3

连载开篇。用一张可点击的总架构图把 Kimi K3 的 93 层、三个维度上的三个新模块和视觉通路摆在一起,给出 K2 → K3 的结构对照表,并说明后面每一篇讲什么。

目录8 节

这个连载配合 Kimi K3 技术报告的 §2 "Model Architecture" 一起读。论文这一节只有八页,但每个模块背后都压着一篇独立论文,K3 又在每个模块上做了自己的改动。开篇先不进任何细节,只做三件事:把整个模型画成一张图,把层数和维度对上,告诉你后面每一篇在图上的哪个位置。

三句话版本

Kimi K3 是一个 2.78T 总参数、104.2B 激活参数的 MoE 模型,93 层,训练上下文 1M token,原生支持图像和视频输入。

论文把结构上的改动归成三个维度,每个维度一个新模块:

维度混合的是什么模块来自哪篇论文
序列token 之间Kimi Delta Attention(KDA)与 Gated MLA 按 3
混合
Kimi Linear(2510.26692)
深度层之间Attention Residuals(AttnRes)Attention Residuals(2603.15031)
宽度通道之间Stable LatentMoELatentMoE(2601.18089)+ K3 自己的三个稳定化改动

再加上输入端的视觉编码器 MoonViT-V2 和一个投影层,以及优化器 Per-Head Muon。论文的说法是,这些结构改动加上数据和训练配方的改进,让整体 scaling efficiency 相对 Kimi K2 提升了约 2.5 倍。

总图

下面这张图是论文 Figure 2 的中文可交互版。后面每一篇文章开头都会再放一次,只点亮当篇讲的模块。

文本 token图像 / 视频视觉 token 与文本 token 交错后进入同一条主干残差流(prefix sum)重复 23 次3 KDA : 1 Gated MLA第 2 – 92 层每 12 层是一个 AttnRes 块AttnRes 来源(最多 9 个)每个 α 前都有这一组来源α = softmax(wₗ · RMSNorm(来源))wₗ 是每个子层各一个的可学习向量logits输出前再聚合一次全部块最终隐藏状态 + 下一个 token 的 embeddingAttention Residuals 算子:用本子层的伪 query wₗ 对来源打分,softmax 加权求和αAttention Residuals 算子:用本子层的伪 query wₗ 对来源打分,softmax 加权求和αAttention Residuals 算子:用本子层的伪 query wₗ 对来源打分,softmax 加权求和αAttention Residuals 算子:用本子层的伪 query wₗ 对来源打分,softmax 加权求和αAttention Residuals 算子:用本子层的伪 query wₗ 对来源打分,softmax 加权求和αAttention Residuals 算子:用本子层的伪 query wₗ 对来源打分,softmax 加权求和αAttention Residuals 算子:用本子层的伪 query wₗ 对来源打分,softmax 加权求和αAttention Residuals 算子:用本子层的伪 query wₗ 对来源打分,softmax 加权求和αAttention Residuals 算子:用本子层的伪 query wₗ 对来源打分,softmax 加权求和α词表 163840,隐藏维 7168Token Embedding163840 × 7168从零训练的视觉编码器,hidden 1024,12 头MoonViT-V227 层 · 0.4B · patch 14merge_type = sd2_tpool2×2 Pixel-shuffle+ 时间池化 · token ÷4PatchMergerMLPV2,GELU,RMSNormProjector4096 → 4096 → 7168词嵌入永远是一个来源b₀ = Embedding每个块的输出是块内所有子层输出之和b₁ … bₙ₋₁已完成的块(每块 12 层之和)本块里已经算完的子层之和,相当于块内的普通残差流bₙ⁽ⁱ⁾ 当前块 partial sumKimi Delta Attention:96 头 × 128 维,状态 128×128/头KDA第 1 层第一层不用 MoE,用一个稠密 SiTU-GLU FFNDense FFN仅第 1 层 · 中间维 33792三层 KDA,每层后接一个 Stable LatentMoEKDA×37168 → 3584 latent → 16 个 routed expert → RMSNorm → 7168Stable LatentMoE896 选 16 + 2 sharedDeepSeek 式 MLA,无位置编码,满秩 sigmoid 输出门Gated MLA×1 · NoPE同上Stable LatentMoE896 选 16 + 2 shared主干末尾额外放一层全局注意力Gated MLA第 93 层 · 收尾同上Stable LatentMoE第 93 层最终归一化RMSNorm不与 embedding 共享权重LM Head→ 163840预训练时 1 层多 token 预测;post-training 微调成投机解码的 draftMTP 层 ×1镜像主干 block · 部署时做 EAGLE-3 draft
序列 · KDA序列 · Gated MLA深度 · AttnRes宽度 · Stable LatentMoE输入 · MoonViT-V2零件
Kimi K3 总架构。纵向是深度,每一行是一个子层:先经过一个 AttnRes 算子 α,再进子层,输出回到残差流。方块可点击跳到对应文章。

怎么读这张图:

  • 中间那条粗竖线是残差流。 在普通 Transformer 里它就是 hlh_l,一路往下加。在 K3 里它叫 prefix sum,只在一个 12 层的块内部起普通残差的作用,块与块之间靠 AttnRes 连接。
  • 每个子层前面有一个 α。 这是 Attention Residuals 算子:它拿本子层专属的一个可学习向量 wlw_l 当 query,对左边那一列「来源」做 softmax 加权求和,得到子层的输入。来源是词嵌入、之前每个块的输出之和、以及当前块已经算完的部分。一层里有两个 α,注意力前一个,FFN 前一个。
  • 子层只有四种。 KDA 和 Gated MLA 是两种注意力,Stable LatentMoE 是 FFN,第一层的 FFN 是唯一的例外,是一个稠密的 FFN。
  • 虚线框里的四行重复 23 次。 三层 KDA 接一层 Gated MLA,每层注意力后面都跟一个 LatentMoE。加上开头的第 1 层和收尾的第 93 层,正好 93 层。
  • 顶部是输入。 文本 token 走 embedding,图像和视频走 MoonViT-V2,经过 2×2 pixel-shuffle 把 token 数除以 4,再由一个两层 MLP 投影到 7168 维,和文本 token 交错后进同一条主干。
  • 底部是输出。 最后一次 AttnRes 把所有块的输出聚合起来,过 RMSNorm 和 LM head。预训练时还挂了一个 MTP 层,部署时被微调成投机解码的 draft。

93 层怎么排

第 1 层:KDA(后接 dense FFN)第 2 层:KDA(后接 Stable LatentMoE)第 3 层:KDA(后接 Stable LatentMoE)第 4 层:Gated MLA(后接 Stable LatentMoE)第 5 层:KDA(后接 Stable LatentMoE)第 6 层:KDA(后接 Stable LatentMoE)第 7 层:KDA(后接 Stable LatentMoE)第 8 层:Gated MLA(后接 Stable LatentMoE)第 9 层:KDA(后接 Stable LatentMoE)第 10 层:KDA(后接 Stable LatentMoE)第 11 层:KDA(后接 Stable LatentMoE)第 12 层:Gated MLA(后接 Stable LatentMoE)第 13 层:KDA(后接 Stable LatentMoE)第 14 层:KDA(后接 Stable LatentMoE)第 15 层:KDA(后接 Stable LatentMoE)第 16 层:Gated MLA(后接 Stable LatentMoE)第 17 层:KDA(后接 Stable LatentMoE)第 18 层:KDA(后接 Stable LatentMoE)第 19 层:KDA(后接 Stable LatentMoE)第 20 层:Gated MLA(后接 Stable LatentMoE)第 21 层:KDA(后接 Stable LatentMoE)第 22 层:KDA(后接 Stable LatentMoE)第 23 层:KDA(后接 Stable LatentMoE)第 24 层:Gated MLA(后接 Stable LatentMoE)第 25 层:KDA(后接 Stable LatentMoE)第 26 层:KDA(后接 Stable LatentMoE)第 27 层:KDA(后接 Stable LatentMoE)第 28 层:Gated MLA(后接 Stable LatentMoE)第 29 层:KDA(后接 Stable LatentMoE)第 30 层:KDA(后接 Stable LatentMoE)第 31 层:KDA(后接 Stable LatentMoE)第 32 层:Gated MLA(后接 Stable LatentMoE)第 33 层:KDA(后接 Stable LatentMoE)第 34 层:KDA(后接 Stable LatentMoE)第 35 层:KDA(后接 Stable LatentMoE)第 36 层:Gated MLA(后接 Stable LatentMoE)第 37 层:KDA(后接 Stable LatentMoE)第 38 层:KDA(后接 Stable LatentMoE)第 39 层:KDA(后接 Stable LatentMoE)第 40 层:Gated MLA(后接 Stable LatentMoE)第 41 层:KDA(后接 Stable LatentMoE)第 42 层:KDA(后接 Stable LatentMoE)第 43 层:KDA(后接 Stable LatentMoE)第 44 层:Gated MLA(后接 Stable LatentMoE)第 45 层:KDA(后接 Stable LatentMoE)第 46 层:KDA(后接 Stable LatentMoE)第 47 层:KDA(后接 Stable LatentMoE)第 48 层:Gated MLA(后接 Stable LatentMoE)第 49 层:KDA(后接 Stable LatentMoE)第 50 层:KDA(后接 Stable LatentMoE)第 51 层:KDA(后接 Stable LatentMoE)第 52 层:Gated MLA(后接 Stable LatentMoE)第 53 层:KDA(后接 Stable LatentMoE)第 54 层:KDA(后接 Stable LatentMoE)第 55 层:KDA(后接 Stable LatentMoE)第 56 层:Gated MLA(后接 Stable LatentMoE)第 57 层:KDA(后接 Stable LatentMoE)第 58 层:KDA(后接 Stable LatentMoE)第 59 层:KDA(后接 Stable LatentMoE)第 60 层:Gated MLA(后接 Stable LatentMoE)第 61 层:KDA(后接 Stable LatentMoE)第 62 层:KDA(后接 Stable LatentMoE)第 63 层:KDA(后接 Stable LatentMoE)第 64 层:Gated MLA(后接 Stable LatentMoE)第 65 层:KDA(后接 Stable LatentMoE)第 66 层:KDA(后接 Stable LatentMoE)第 67 层:KDA(后接 Stable LatentMoE)第 68 层:Gated MLA(后接 Stable LatentMoE)第 69 层:KDA(后接 Stable LatentMoE)第 70 层:KDA(后接 Stable LatentMoE)第 71 层:KDA(后接 Stable LatentMoE)第 72 层:Gated MLA(后接 Stable LatentMoE)第 73 层:KDA(后接 Stable LatentMoE)第 74 层:KDA(后接 Stable LatentMoE)第 75 层:KDA(后接 Stable LatentMoE)第 76 层:Gated MLA(后接 Stable LatentMoE)第 77 层:KDA(后接 Stable LatentMoE)第 78 层:KDA(后接 Stable LatentMoE)第 79 层:KDA(后接 Stable LatentMoE)第 80 层:Gated MLA(后接 Stable LatentMoE)第 81 层:KDA(后接 Stable LatentMoE)第 82 层:KDA(后接 Stable LatentMoE)第 83 层:KDA(后接 Stable LatentMoE)第 84 层:Gated MLA(后接 Stable LatentMoE)第 85 层:KDA(后接 Stable LatentMoE)第 86 层:KDA(后接 Stable LatentMoE)第 87 层:KDA(后接 Stable LatentMoE)第 88 层:Gated MLA(后接 Stable LatentMoE)第 89 层:KDA(后接 Stable LatentMoE)第 90 层:KDA(后接 Stable LatentMoE)第 91 层:KDA(后接 Stable LatentMoE)第 92 层:Gated MLA(后接 Stable LatentMoE)第 93 层:Gated MLA(后接 Stable LatentMoE)11224364860728493■ KDA ×69■ Gated MLA ×24(每第 4 层 + 第 93 层)虚线框 = 第 1 层,FFN 是 dense 而不是 MoEb₁b₂b₃b₄b₅b₆b₇尾块(9 层)AttnRes 分块:每 12 个 decoder layer 求和成一个 bₙ;embedding 记作 b₀;7 个满块 + 1 个 9 层尾块 + b₀ = 9 个来源
93 层的类型和 AttnRes 的分块边界。层号按论文和 config.json 的口径从 1 开始数。

排布规则很机械:

[KDA, KDA, KDA, MLA]×2392 层 + MLA第 93 层\underbrace{[\text{KDA},\ \text{KDA},\ \text{KDA},\ \text{MLA}]\times 23}_{92\ \text{层}}\ +\ \underbrace{\text{MLA}}_{\text{第 93 层}}

所以 KDA 有 69 层,Gated MLA 有 24 层。config 里的 full_attn_layers 就是 4, 8, …, 92 再加一个 93。末尾多放一层全局注意力是刻意的,论文说是为了保证最后一层一定是全局注意力。

每一层注意力后面都跟一个 FFN,93 层就是 186 个子层。第 1 层的 FFN 是稠密的(first_k_dense_replace = 1),中间维 33792,这和 DeepSeek-V3、Kimi K2 的习惯一样。其余 92 层都是 Stable LatentMoE。

AttnRes 的分块是另一套刻度,每 12 个 decoder layer 一块,边界在第 1、13、25、…、85 层。这样切出来 7 个满块和一个 9 层的尾块,加上词嵌入本身,任何一个子层最多能看到 9 个来源。两套刻度是对齐的:12 是 4 的 3 倍,每个满块正好是三组 [KDA, KDA, KDA, MLA],块的第一层总是 KDA,最后一层总是 MLA。

K2 → K3 对照表

论文 Table 1 的翻译,加上几行 config.json 里有、论文表格没列的维度。

Kimi K2Kimi K3变化
层数6193+52%
总参数1.04T2.78T+167%
激活参数32.6B104.2B+220%
隐藏维71687168不变
MoE latent 维3584(0.5×)新增
每个 expert 中间维20483072+50%
routed expert 数384896+133%
每 token 激活 expert 数816×2
shared expert 数12×2
注意力头数6496+50%
稠密层数11不变
词表160K160K不变
训练上下文128K1M×8
注意力机制MLAKDA + MLA 混合
注意力层组成61 MLA69 KDA + 24 MLA
激活函数SwiGLUSiTU-GLU
MTP 层数11不变
视觉编码器MoonViT-V2,401M,27 层,patch 14,12 头新增

config.json 里值得先记住的几个数,后面每一篇都会用到:

字段意思
hidden_size7168主干宽度 dd
num_attention_heads / head_dim96 / 128KDA 和 MLA 共用的头数与头维
q_lora_rank / kv_lora_rank1536 / 512MLA 的 query 低秩和 KV latent 维
qk_nope_head_dim / qk_rope_head_dim / v_head_dim128 / 64 / 128MLA 每头的维度。64 维的 rope 位保留了,但不加旋转
mla_use_nopetrueMLA 层不用任何位置编码
gate_lower_bound−5.0KDA 衰减的下界,K3 的改动之一
use_full_rank_gate / mla_use_output_gatetrue / true两种注意力的输出门都是满秩的
attn_res_block_size12AttnRes 的块大小
num_experts / num_experts_per_token / num_shared_experts896 / 16 / 2MoE 配置
routed_expert_hidden_size / moe_intermediate_size3584 / 3072LatentMoE 的 latent 维和 expert 中间维
latent_moe_use_normtruelatent 求和后加 RMSNorm,K3 的改动
activation_situ_beta / activation_situ_linear_beta4.0 / 25.0SiTU-GLU 的两个软截断参数
topk_methodnoaux_tc无辅助损失的路由,偏置向量就是冻结的 Quantile Balancing 偏置
vocab_size163840词表
max_position_embeddings10485761M 上下文

一个 token 的一次前向

把维度串起来走一遍,你会发现整个模型只有四种子层在重复。下面是一个普通 decoder layer 的结构,按 Hugging Face 建模代码的顺序画:

四种子层各自的维度账:

KDA。 输入 7168 维。q、k、v 各自经过一个线性层到 96×128 = 12288 维,再过一个核大小为 4 的因果短卷积和 Swish,q 和 k 再做 L2 归一化。每个头一个标量 βt\beta_t(7168 → 96,sigmoid),每个头一个 128 维的衰减向量 αt\alpha_t,由低秩投影 7168 → 128 → 12288 加每头偏置产生。每个头维护一个 128×128 的状态矩阵。输出先做逐头 RMSNorm,乘一个满秩 sigmoid 门(7168 → 12288),再经 WoW_o 回到 7168 维。

Gated MLA。 query 走 1536 维低秩,展开成 96 个头、每头 128 + 64 维。key/value 压成一个 512 维 latent 加 64 维所有头共享的分量,KV cache 每 token 每层只存这 576 个数。每头 value 128 维。没有位置编码。输出乘满秩 sigmoid 门再经 WoW_o 回到 7168 维。

Stable LatentMoE。 router 在 7168 维上打 896 个 sigmoid 分数,加偏置选 top-16 后归一化。token 先被一个共享的下投影压到 3584 维,16 个 expert 在 3584 维空间里各算一个 3584 → 3072 → 3584 的 SiTU-GLU,加权求和,过 RMSNorm,再由一个共享的上投影回到 7168 维。旁边并联两个全宽的 shared expert,代码里合成了一个 7168 → 6144 → 7168 的 MLP。

AttnRes α。 每个子层前一个。参数只有一个 7168 维的向量 wlw_l 和一个 RMSNorm 的 7168 维增益,来源最多 9 个。

最后一层出来以后,输出端再做一次 AttnRes 聚合所有块,过 RMSNorm,LM head 把 7168 维映到 163840 个 logit。LM head 不和 embedding 共享权重。

阅读地图

每一篇对应论文的一个小节,标题后面括号里是它在总图上点亮的部分。

讲什么对应论文
0本篇。总图、层排布、维度账§2 开头,Table 1
1序列(上):从线性注意力到 KDA。delta rule、逐通道衰减、K3 的满秩输出门§2.1.1 前半,Kimi Linear
2序列(下):KDA 的 chunkwise 并行形式,K3 的下界衰减为什么让所有 tile 都能上 Tensor Core§2.1.1 后半,Fig. 3
3序列:Gated MLA,NoPE,3
的混合比,以及 1M 上下文时的 KV 账
§2.1.2
4深度:Attention Residuals。残差流为什么是深度上的 RNN,Full 与 Block 两种形式,K3 的 9 个来源§2.2
5宽度:Stable LatentMoE。在 latent 空间里跑 expert,RMSNorm、SiTU-GLU、Quantile Balancing 三个稳定化改动§2.3,附录 B/C/D
6输入端与零件:MoonViT-V2、投影、MTP 层、Per-Head Muon§2.4,§2.5,§4.1.4
7结构决定系统:FlashKDA、KDA 的上下文并行、KDA 感知的前缀缓存§5.1,§5.4

这个连载不讲什么

数据、预训练配方、post-training 的 SFT / RL / 蒸馏、评测数字,一律不讲。§5 的系统部分只挑和结构直接相关的部分放在最后一篇。读完这个连载,你应该能在不看代码的情况下写出 K3 每一层每个矩阵的形状,也能说清楚每个改动是为了解决什么问题。

资料