写在前面

欢迎大家关注Rocky的知乎:Rocky Ding 《三年面试五年模拟》AIGC/LLM/AI Agent算法工程师/开发工程师求职面试秘籍独家资源:【三年面试五年模拟】WeThinkIn/AIGC-Interview-Book,欢迎大家Star~
Rocky最新撰写的10万字AI Agent(AI智能体)深入浅出全维度解析文章: 深入浅出完整解析AI Agent(AI智能体)的核心基础知识
AIGC/LLM/AI Agent算法岗/开发岗求职面试内推学习社群(涵盖AIGC、LLM大模型、AI Agent、传统深度学习、自动驾驶、机器学习、计算机视觉、自然语言处理、强化学习、大数据挖掘、具身智能、元宇宙、AGI等AI行业最新面试干货经验与核心知识)欢迎大家加入:https://t.zsxq.com/33pJ0
大家好,我是Rocky。
七年时间,参数规模扩大了 22580 倍。但这段历史真正值得记住的,不是一个更大的数字,而是模型如何一步步学会写入、遗忘、更新和检索记忆。

图 1:从 GPT-2 到 Kimi K3 的架构演进总览

图 2:注意力机制的演进时间线,原图保留
22580。
这是一个 Kimi K3(2026)能够容纳的 GPT-2(2019)参数量倍数。七年时间,我们把模型规模扩大了 22580 倍。
但问题来了:这真的只是规模的胜利吗?
这篇文章会沿着一条清晰的架构路线,回看我们究竟是怎样从 GPT-2 走到 Kimi K3 的,以及在看似翻天覆地的参数增长背后,哪些东西已经被彻底改写,哪些底层矛盾又从未消失。

图 3:从 GPT-2 到 Kimi K3 的完整架构对比
Rocky 认为,这段历史的中心线索不是“模型越来越大”,而是:当上下文越来越长、可用计算越来越昂贵时,模型如何用有限状态保存有用信息,又如何在信息必然损失的前提下做出更好的选择。
一、GPT-2:Decoder-only Transformer 的原点
GPT-2 采用的是纯解码器(decoder-only)架构。

图 4:输入首先经过 Token Embedding 与 Position Embedding
输入 Token 会被映射为词向量,再与位置向量相加。随后,表示依次经过 12 个 Transformer Block,最后通过层归一化和语言模型头得到词表 logits。
tok_emb = self.transformer.wte(idx) # shape: (b, t, n_embd)
pos_emb = self.transformer.wpe(pos) # shape: (t, n_embd)
x = self.transformer.drop(tok_emb + pos_emb)
for block in self.transformer.h:
x = block(x)
x = self.transformer.ln_f(x)
logits = self.lm_head(x)
return logits
把单个 Transformer Block 拉近来看,结构如下:

图 5:GPT-2 Transformer Block 与多头自注意力
class Block(nn.Module):
def __init__(self, config):
super().__init__()
self.ln_1 = LayerNorm(config.n_embd, bias=config.bias)
self.attn = CausalSelfAttention(config)
self.ln_2 = LayerNorm(config.n_embd, bias=config.bias)
self.mlp = MLP(config)
def forward(self, x):
x = x + self.attn(self.ln_1(x))
x = x + self.mlp(self.ln_2(x))
return x
其中,注意力计算的核心过程是:由同一份隐状态投影得到
Q
Q
Q、
K
K
K 和
V
V
V,计算缩放点积、因果 Mask 与 Softmax,再对
V
V
V 加权求和。
B, T, C = x.size()
q, k, v = self.c_attn(x).split(self.n_embd, dim=2)
k = k.view(B, T, self.n_head, C // self.n_head).transpose(1, 2)
q = q.view(B, T, self.n_head, C // self.n_head).transpose(1, 2)
v = v.view(B, T, self.n_head, C // self.n_head).transpose(1, 2)
att = (q @ k.transpose(–2, –1)) * (1.0 / math.sqrt(k.size(–1)))
att = att.masked_fill(self.bias[:, :, :T, :T] == 0, float('-inf'))
att = F.softmax(att, dim=–1)
att = self.attn_dropout(att)
y = att @ v
y = y.transpose(1, 2).contiguous().view(B, T, C)
y = self.resid_dropout(self.c_proj(y))
return y
当最终隐状态矩阵产生后,语言模型头会把它映射到整个词表的 logits。自回归解码时,每一步实际只需要最后一个位置的 logits,用来选择下一个 Token。
这也暴露了 decoder-only 生成的一个明显低效点:模型为所有输入位置都计算了表示,但每个解码步只消费最后一个位置的 logits。如果没有缓存,下一个 Token 到来时,前面的大部分计算都要重复一遍。

图 6:KV Cache 用空间换取自回归解码时的重复计算
KV Cache 来自一个非常直接的观察:当新生成的 Token 被追加到序列后,旧 Token 的 Key 和 Value 投影其实没有变。把它们保存下来,就能避免对所有历史 Token 重复投影。
代价是,KV Cache 需要保留前
N
−
1
N-1
N−1 个 Token 在每层、每个注意力头中的 Key 和 Value。它会随序列长度线性增长,并在长上下文与大批量服务中逐步变成显存容量和带宽瓶颈。
vocab_size: int = 50304
n_layer: int = 12
n_head: int = 12
n_embd: int = 768
对于这个基线模型,词表约 5 万,共 12 个 Block、12 个注意力头,Embedding 维度为 768,总参数约 1.24 亿。
按原文给出的 2.8 万亿参数计算,一个 Kimi K3 的总参数,大致相当于 22580 个 GPT-2。
但如果只停在这里,我们就会错过真正的架构演进。参数增长解决的是容量问题,而接下来的每一步,都在回答另一个问题:记忆该如何以更低成本被保存、更新和取回?
二、线性注意力:把无限增长的 KV Cache 压进固定状态
Softmax Attention 会先计算
q
⋅
k
q \\cdot k
q⋅k,再对结果施加非线性变换。这使得每一个 Query 都与所有 Key 发生耦合,计算顺序不能被随意交换。
线性注意力的关键改动,是把如
ELU
(
x
)
+
1
\\operatorname{ELU}(x)+1
ELU(x)+1 这样的特征映射
ϕ
(
⋅
)
\\phi(\\cdot)
ϕ(⋅) 分别作用在
q
q
q 和
k
k
k 上。这样一来,原本的计算可以重新结合:
ϕ
(
Q
)
(
ϕ
(
K
)
⊤
V
)
\\phi(Q)\\bigl(\\phi(K)^\\top V\\bigr)
ϕ(Q)(ϕ(K)⊤V)
于是,不断增长的
K
K
K 和
V
V
V 集合,就可以被折叠到一个固定尺寸的
D
×
D
D \\times D
D×D 状态矩阵
S
S
S 中。
原文作者最初被论文中的
O
(
N
2
)
O(N^2)
O(N2) 表述困扰:严格来说,“Transformer 每个时间步的成本随当前序列长度的平方增长”并不是今天解码阶段的准确说法。有了 KV Cache 后,单步解码的注意力计算和读取量随历史长度
N
N
N 线性增长,生成完整
N
N
N 个 Token 的累计成本才呈二次增长。FlashAttention 主要解决的,则是精确 Softmax Attention 的 IO 与中间矩阵物化问题,并不是把其数学计算量从二次变成线性。
这个时间背景很重要:线性注意力的代表性工作发布于 2020 年。当时训练往往会显式物化完整的
N
×
N
N \\times N
N×N 注意力矩阵,FlashAttention 尚未出现,许多参考级自回归实现甚至还会在没有 KV Cache 的情况下重算历史 Token。
def forward(self, x, mask=None, past_kv=None):
b, t, d = x.shape
d_head = d // self.num_heads
h = self.num_heads
qkv = self.qkv_proj(x)
q = qkv[:, :, :d].view(b, t, h, d_head).transpose(1, 2)
k = qkv[:, :, d:2*d].view(b, t, h, d_head).transpose(1, 2)
v = qkv[:, :, 2*d:].view(b, t, h, d_head).transpose(1, 2)
if past_kv is not None:
k = torch.cat((past_kv[0], k), dim=2)
v = torch.cat((past_kv[1], v), dim=2)
scores = (q @ k.transpose(–1, –2)) / math.sqrt(d_head)
if past_kv is None:
causal_mask = torch.triu(
torch.ones(t, t, dtype=bool, device=q.device), diagonal=1
)
scores = scores.masked_fill(causal_mask, float('-inf'))
if mask is not None:
scores = scores.masked_fill(~mask, float('-inf'))
attn = scores.softmax(–1)
o = attn @ v
o = o.transpose(1, 2).contiguous().view(b, t, d)
return self.o_proj(o), (k, v)
从显存访问的角度看,问题更直观:每个解码步都需要从 HBM 读取随上下文增长的 Key 和 Value,KV Cache 本身也会以
O
(
N
)
O(N)
O(N) 速度增长。

图 7:标准注意力在自回归解码中的 HBM 读写与 KV Cache 增长
线性注意力用固定状态
S
S
S 和归一化累积量
z
z
z 取代了不断拼接的 KV Cache:
def forward(self, x, mask=None, cache=None):
b, t, d = x.shape
d_head = d // self.num_heads
h = self.num_heads
qkv = self.qkv_proj(x)
q = qkv[:, :, :d].view(b, t, h, d_head).transpose(1, 2)
k = qkv[:, :, d:2*d].view(b, t, h, d_head).transpose(1, 2)
v = qkv[:, :, 2*d:].view(b, t, h, d_head).transpose(1, 2)
k = (F.elu(k) + 1).transpose(–1, –2)
q = F.elu(q) + 1
S, z = cache if cache is not None else (0.0, 0.0)
S = S + k @ v
z = z + k
o = q @ S
denom = q @ z
o = o / denom
o = o.transpose(1, 2).contiguous().view(b, t, d)
return self.o_proj(o), (S, z)
但这不是一顿免费的午餐。
在 Softmax Attention 中,指数函数作用于
q
k
⊤
qk^\\top
qk⊤ 之后;在线性注意力中,我们改用
ELU
+
1
\\operatorname{ELU}+1
ELU+1 分别处理
q
q
q 和
k
k
k,再让它们发生交互。两者都会对分数进行归一化,但线性注意力的特征映射只是对 Softmax Kernel 的一种表达力较弱的近似。它可能损失精度,实际损失大小则取决于架构和任务。
图中为了简洁,省略了对
q
k
qk
qk 之和的除法。从更高层看,注意力始终在做三件事:
q
k
qk
qk 分数变为非负数。线性注意力用
ELU
+
1
\\operatorname{ELU}+1
ELU+1,Softmax 注意力用指数函数。
所以,线性注意力保留了注意力的基本契约,却通过牺牲一部分表达力,换取了可重新结合的计算顺序和固定尺寸状态。
Rocky 的补充判断是:这里发生的不是“更快的注意力”这么简单,而是一次记忆模型的更换。标准注意力像保留每份原始档案,线性注意力则像把历史不断写入一块固定大小的白板。它解决了存储增长,也因此引入了更难的问题:白板写满以后,该擦掉什么?
三、DeltaNet:从“只会累加”到“先擦除、再写入”
固定容量的 Cache 无法为每个历史 Token 保留独立槽位。在普通线性注意力中,第
i
i
i 个 Token 的状态会被直接叠加到同一个
D
×
D
D \\times D
D×D 矩阵上。这意味着,新 Query 已经无法像标准注意力那样,精确取回某一个历史 Token 的完整、隔离表示。
而这种“直接相加”,恰恰又是效率收益的来源。Cache 通过加法而不是拼接来更新,尺寸就不再按
O
(
N
)
O(N)
O(N) 增长;但所有信息共享同一块存储,也会互相干扰。DeltaNet 要解决的,正是这种可恢复性的丧失。

图 8:序列越长,越多键值关联被叠加进同一个固定容量状态
Schlag 等人在 Fast Weight Programmers 中把问题说得很清楚:
当序列长度超过存储容量时,模型可能进入过容量区间。要在这种情况下正常工作,模型应学会动态地与记忆内容交互,有选择地决定哪些键值关联应当保留,哪些应当删除。纯加性的更新指令可能并不适合这一目标……像式 17 那样,向有限容量的记忆中无休止地添加新关联,必然会到达极限。
这是一个很典型的架构悖论:当
N
N
N 远大于
D
D
D 时,线性注意力的效率优势最明显;但也正是在这个区间,固定状态最容易超出有效容量。由于更新只会叠加,没有任何内容主动离开 Cache,键值关联最终必然相互干扰。
def forward(self, x, mask=None, cache=None):
b, t, d = x.shape
d_head = d // self.num_heads
h = self.num_heads
qkv = self.qkv_proj(x)
q = qkv[:, :, :d].view(b, t, h, d_head).transpose(1, 2)
k = qkv[:, :, d:2*d].view(b, t, h, d_head).transpose(1, 2)
v = qkv[:, :, 2*d:].view(b, t, h, d_head).transpose(1, 2)
q = F.normalize(F.silu(q), dim=–1)
k = F.normalize(F.silu(k), dim=–1)
beta = torch.sigmoid(self.w_beta(x)).view(b, 1, t, 1)
S = cache if cache is not None else 0.0
v_old = k @ S
u = beta * (v – v_old)
S = S + k.transpose(–1, –2) @ u
o = q @ S
o = o.transpose(1, 2).contiguous().view(b, t, d)
return self.o_proj(o), S
用一个可视化例子,会更容易理解。

图 9:Delta Rule 先读出已有内容,再写入新旧之差
假设只写入一组关联:
S
=
k
⊤
v
S = k^\\top v
S=k⊤v
如果使用同一个 Key 读取,就会得到:
k
(
k
⊤
v
)
=
(
k
k
⊤
)
v
=
∥
k
∥
2
v
k(k^\\top v) = (kk^\\top)v = \\lVert k \\rVert^2 v
k(k⊤v)=(kk⊤)v=∥k∥2v
换句话说,读取结果只是被 Key 的模长平方缩放了。如果把
k
k
k 归一化为单位长度,或者在结果中除以该缩放量,就可以精确找回
v
v
v。
Query 也是一个学习出来的指针。
W
q
W_q
Wq 和
W
k
W_k
Wk 从同一份残差流中读取信息,当模型需要某个事实时,Query 会指向写入这个事实时所使用的 Key 方向。
Delta Rule 的更新先询问:“用当前 Key 从 Cache 中已经能读到什么?”然后,它用想写入的 Value 减去旧内容,把差值与 Key 相乘,再加回状态中。这就完成了一次有针对性的“擦除旧信息,写入新信息”。
线性注意力只会做累加,DeltaNet 开始学会做编辑。
四、并行化 DeltaNet:好的数学规则,必须能在 GPU 上高效跑起来
这是原文中最难的一节。作者花了大约七个小时,才建立起一套可以工作的理解,因此这里也从实现出发。
简单概括,DeltaNet 实现了一阶线性递归,其状态转移可表达为广义 Householder 转移矩阵。这种形式允许序列按大小为
C
C
C 的 Chunk 分块,每个 Chunk 基于前一个 Chunk 的最终状态,再结合当前块的
Q
Q
Q、
K
K
K 和
V
V
V 并行计算输出。目标是在保留线性时间复杂度的同时,让训练真正变得硬件友好。
实际的工程问题出现在 Prefill 阶段。如果直接在
T
T
T 个 Token 上实现 Delta Rule,代码会像下面这样:
S = torch.zeros(b, h, dh, dh) if cache is None else cache
outs = []
for i in range(t):
k_i = k[:, :, i:i+1]
v_i = v[:, :, i:i+1]
b_i = beta[:, :, i:i+1]
v_old = k_i @ S
u_i = b_i * (v_i – v_old)
S = S + k_i.transpose(–1, –2) @ u_i
outs.append(q[:, :, i:i+1] @ S)
o = torch.cat(outs, dim=2)
与标准注意力不同,Delta Rule 需要在每一个 Key 上计算一次校正,所以它无法立刻改写为一次大矩阵乘法。即使去掉 Delta Rule,一个最直接的递归线性注意力 Prefill 仍然是串行的:
S = torch.zeros(b, h, dh, dh) if cache is None else cache
outs = []
for i in range(t):
q_i = q[:, :, i:i+1]
k_i = k[:, :, i:i+1]
v_i = v[:, :, i:i+1]
S = S + k_i.transpose(–1, –2) @ v_i
o_i = q_i @ S
outs.append(o_i)
o = torch.cat(outs, dim=2)
更高效的方案,是分块计算。

图 10:Chunk 内使用并行注意力,Chunk 间通过递归状态传递历史
当
C
=
N
C=N
C=N 时,该形式退化为标准的
O
(
N
2
)
O(N^2)
O(N2) 注意力;当
C
=
1
C=1
C=1 时,它就是常规的递归线性注意力。中间的
C
C
C 值,则用更多块内计算换取更高的硬件利用率。
实践中,
C
C
C 经常取 64 或 128,因为 Tensor Core 上的矩阵乘指令能在这类粒度上高效工作,UMMA 就是一个例子。
块内产生的中间 Tile,会在状态更新中折叠进
S
S
S:

图 11:对角块保留局部精确注意力,历史块被折叠进递归状态
S = torch.zeros(b, h, dh, dh) if cache is None else cache
outs = []
for i in range(t // C):
q_c = q[:, :, i*C:(i+1)*C]
k_c = k[:, :, i*C:(i+1)*C]
v_c = v[:, :, i*C:(i+1)*C]
o_prev = q_c @ S
attn = (q_c @ k_c.transpose(–1, –2)).tril()
o_curr = attn @ v_c
o = o_prev + o_curr
S_new = k_c.transpose(–1, –2) @ v_c
S = S + S_new
outs.append(o)
o = torch.cat(outs, dim=2)
在块内,我们计算
q
(
k
⊤
v
)
q(k^\\top v)
q(k⊤v) 的“分数优先”形式,也就是带 Mask 的常规注意力顺序;在块间,我们采用
(
k
⊤
v
)
q
(k^\\top v)q
(k⊤v)q 的“状态优先”形式,也就是递归顺序。
因此,成本可以被拆成两部分:
2
L
d
2
+
2
L
C
d
2Ld^2 + 2LCd
2Ld2+2LCd
第一项
2
L
d
2
2Ld^2
2Ld2 是状态读写工作,与 Chunk 大小
C
C
C 无关;第二项
2
L
C
d
2LCd
2LCd 是位于对角线上的块内分数矩阵成本。完整注意力只是
C
=
L
C=L
C=L 的特例,此时第二项就变成
2
L
2
d
2L^2d
2L2d。从纯 FLOPs 的角度看,
C
C
C 越小,计算量越低。
但
C
=
1
C=1
C=1 虽然 FLOPs 最低,却未必拥有最短的真实运行时间。GPU 可以在更多算术运算能够高效映射到矩阵乘单元时,用更短的墙上时间完成更多 FLOPs。
这里的工程启示很关键:算法复杂度不等于端到端性能。真正的模型架构必须同时通过数学、内存访问和硬件执行三重检验。
下一步,是把同样的 Chunkwise 思路扩展到 DeltaNet。

图 12:《Parallelizing Linear Transformers with the Delta Rule》中的分块并行思路
根本难点很简单:适用于纯加性线性注意力的分块方法,不能直接用在 Delta 更新上。
v_old = k_i @ S
u_i = b_i * (v_i – v_old)
要计算“应该减掉的旧信息”,就需要按顺序知道每一步的中间状态。如果不做数学重参数化,就无法像纯加性更新那样直接并行。
原始更新可以写为:
u = v_new – v_old
S_t = S_(t–1) + K.T @ u
o = q @ S_t
重参数化后,可以写为:
S_t = S_(t-1)(I – β_t k_t k_tᵀ) + β_t v_t k_tᵀ
o_t = S_t q_t
这个形式使得分块代码可以一次性计算同一个 Chunk 中的
C
C
C 个 Delta:
def chunk_delta_rule_forward(Q, K, V, beta, C):
L, d = Q.shape
Q, K, V = map(lambda x: x.reshape(–1, C, d), [Q, K, V])
beta = beta.reshape(–1, C)
K_beta = K * beta.unsqueeze(–1)
V_beta = V * beta.unsqueeze(–1)
T = –(K_beta @ K.transpose(–1, –2)).tril(–1)
for i in range(1, C):
T[i, :i] = T[i, :i] + (T[i, :, None] * T[:, :i]).sum(–2)
T += torch.eye(C)
W = T @ K_beta
U = T @ V_beta
S = torch.zeros(d, d)
O = torch.empty_like(V)
for i in range(L // C):
q_i, k_i, w_i = Q[i], K[i], W[i]
u_i = U[i] – w_i @ S
o_inter = q_i @ S
A_i = (q_i @ k_i.t()).tril()
o_intra = A_i @ u_i
S += k_i.t() @ u_i
O[i] = o_intra + o_inter
return O.reshape(L, d)
这就带来了第一个关键架构对比:标准多头注意力 Transformer 与 DeltaNet Transformer。

图 13:MHA Transformer 与 DeltaNet Transformer 的架构对比
到这里,DeltaNet 已经同时解决了两个问题:它让固定状态不再只会盲目叠加,也让这个顺序更新规则能够通过分块与重参数化在 GPU 上高效运行。
但它仍然只会“定点替换”,还没有一个面向全局的遗忘机制。
五、Gated DeltaNet:精确更新还不够,记忆还要学会遗忘
现在,我们已经拥有一种能够精确修改 Cache 的方法。对于每个新事实,也就是每个新 Key,模型可以查看该位置已经存了什么,再用新内容取代旧内容。
但这种机制只能忘记那些“恰好有一个新关联要来替换”的旧关联。当上下文发生切换时,它无法一次高效清理多个关联,也不能让旧记忆普遍衰减,为未来信息释放容量。
如果我们使用的只是纯加性线性注意力,增加遗忘能力其实很简单:只需要加入一个控制旧状态保留比例的参数
α
\\alpha
α。
S_old = cache
S_new = k @ v
cache = alpha * S_old + S_new

图 14:Mamba 式门控更新:衰减旧状态,再写入新状态
这是 Mamba-2 所引入的关键思路:先让上一时刻的 Cache 衰减,再以完整强度写入新 Cache,防止状态无限累积。
在每个时间步,根据动态比例统一衰减所有键值关联,是一种可以工作的方法,也是 Mamba 所采用的思路。但它没有区分不同关联的重要程度。
也就是说,如果模型只需要忘掉一组特定关联,Mamba 式衰减却会让所有关联一起变淡。相反,Delta Rule 可以精确更新某个事实,却没有让其余事实普遍衰减的能力。
因此,Gated Delta Rule 把 Mamba 的门控更新与 Delta Rule 结合起来。它引入参数
α
\\alpha
α:当
α
=
1
\\alpha=1
α=1 时,系统退化为纯 Delta Rule;当
α
=
0
\\alpha=0
α=0 时,旧记忆被清空。真正的挑战,是如何让这一新规则继续兼容上一节的并行 Chunk 实现。
其实现继续使用前文所述的 DeltaNet 重参数化,数学形式几乎相同,只多了一个由数据决定、介于 0 和 1 之间的标量,用于控制旧状态的衰减。它把有效的键值关联学习,与自适应记忆管理合并在了同一套更新规则里。

图 15:Delta Rule 与 Gated Delta Rule 的代码变化
代码中的
γ
r
/
γ
i
\\gamma^r/\\gamma^i
γr/γi 项负责表示累积衰减。一个在时刻
x
x
x 写入、在
x
+
t
x+t
x+t 时刻读取的 Token,会被乘上:
α
x
α
x
+
1
α
x
+
2
⋯
α
x
+
t
\\alpha_x\\alpha_{x+1}\\alpha_{x+2}\\cdots\\alpha_{x+t}
αxαx+1αx+2⋯αx+t
它可以被看作前缀和的乘法版本。
最终得到的架构如下:

图 16:Gated DeltaNet Transformer 同时具备定点更新与全局衰减能力
从产品角度看,这里解决的是长上下文中的“记忆污染”问题:模型不仅要记住新事实,还要在任务切换、话题转移和信息过期时,主动降低旧信息的权重。没有遗忘的记忆不是强记忆,只是快要写满的缓存。
六、KDA / Kimi Linear:从标量衰减走向通道级精细管理
走到这一步,研究者开始在同一架构中混合多种注意力或状态更新形式,例如结合 Gated DeltaNet 与 Mamba。
Kimi Linear 之所以引发广泛关注,核心在于一个强有力的论文结论:在受控对比中,它的效果超过了全注意力架构。作者把它定位为一种可直接替换的架构方案,声称在提升质量的同时,解码吞吐量最高可达原来的 6 倍。
需要注意,“最高 6 倍”是原文转述的论文结果,它依赖具体模型、序列长度、批量、硬件和 Kernel 实现,不应被直接理解为所有部署场景的通用加速比。
Kimi Linear 对 Gated DeltaNet 的关键改进,是引入了细粒度门控。它不再为整个状态只学习一个标量衰减率,而是为每个通道学习独立的衰减值。

图 17:从 Delta Rule、Gated Delta Rule 到 Kimi Delta Attention(KDA)
KDA 的状态更新规则仍然与 Gated DeltaNet 相似,但实现中最关键的变化,是把
α
\\alpha
α 重塑为按通道展开的形式:

图 18:从单点更新、标量衰减到通道级精细衰减
alpha.reshape(num_blocks, C, d)
这一行变化承载了论文最重要的贡献:模型不再用一个门粗暴地决定整块记忆应该保留多少,而是能够针对不同表示通道,分别决定哪些信息应继续保留,哪些可以更快衰减。
与 DeltaNet Transformer 并排来看,Kimi Linear 引入了三项重要变化:
α
\\alpha
α 投影,为 DeltaNet 的记忆管理增加容量和精细度。

图 19:Kimi Linear 将 KDA、MLA 与 MoE 组合成混合架构
后文会继续展开 MLA 与 MoE。此刻最重要的是理解:这不是盲目扩张规模。
新增容量具有非常明确的数学目的。通道级缩放让模型能以更细粒度控制记忆衰减;MLA 弥补固定状态无法完整保留 Token 级信息的缺口;MoE 则让总参数容量与单 Token 的激活计算量解耦。
缩放定律仍然重要,但容量必须被放到正确的位置,并以系统真正能够利用的形式存在。这条演进路径中的每一代架构,都在为上一代的某个具体缺陷增加有功能的容量,而不只是把网络做得更大。
七、Kimi K3:2.8 万亿参数背后,是一套混合记忆与稀疏计算系统
最终,Kimi K3 的语言骨干与前文的 Kimi Linear 十分相似。它包含 23 个由四层组成的宏周期(macrocycle)。在每个宏周期中,前三层使用 Kimi Delta Attention,第四层使用 Multi-head Latent Attention。
第一层使用稠密前馈网络,之后的其余层均采用潜在空间 MoE。
乍看之下,它相对 Kimi Linear 的改动似乎并不夸张:
- 显著提升整体规模;
- 每 12 层引入一次块级 Attention Residuals(AttnRes);
- 为 MLA 增加 Query LoRA 与输出门控;
- 使用潜在空间 MoE;
- 使用 SiTU 激活;
- 使用 Gated MLA。
KDA 提供了固定尺寸的递归记忆,周期性出现的 MLA 层则保留了对完整 Token 上下文进行 Softmax 检索的能力。下图给出了一个简化后的架构参照:

图 20:Kimi K3 将 KDA、周期性 MLA、潜在 MoE 与 AttnRes 组合在同一骨干中
先看三个相对直接的改动:Gated MLA、潜在空间 MoE 和 SiTU 激活。
Gated MLA 用一个由输入投影得到的门,与 MLA 检索结果做逐元素相乘,决定每个被取回的特征有多少可以进入残差流。它不是只回答“取回了什么”,还要回答“这些信息应该通过多少”。
在常规 MoE 中,一个学习得到的 Router 通过点积相似度,把每个 Token 发送到少数专家网络。按原文给出的架构数据,Kimi K3 共有 898 个专家:其中 2 个是每个 Token 都会通过的共享专家;在其余 896 个专家中,Router 为每个 Token 选择 16 个。
Kimi K3 还改变了专家激活方式。传统路径是对 up projection 施加 SiLU,再与 gate 做逐元素乘法,最后经过 down projection;Kimi K3 则改用 SiTU:
d = x.shape[–1] // 2
gate = x[..., :d].to(torch.float32)
up = x[..., d:].to(torch.float32)
situ_a = self.beta * torch.tanh(gate / self.beta) * torch.sigmoid(gate)
if self.linear_beta is not None:
up = self.linear_beta * torch.tanh(up / self.linear_beta)
return (situ_a * up).to(x.dtype)
模型还会先把输入下投影到共享专家的潜在空间,再把所有共享专家的输出求和并上投影回模型维度:

图 21:潜在 MoE 压缩专家计算空间,SiTU 则改变专家内部激活路径
这里体现了模型推理中一个反复出现的挑战:一个在数学上更好的激活函数,如果没有对应的融合 Kernel,在真实硬件上可能反而慢很多。
按原文实现观察,如果缺少融合 Kernel,新激活路径的速度接近原始实现的三分之一。对冲这一成本的优化,是让专家在被压缩的潜在空间中工作,从而显著加速专家前向计算,并使 FLOPs 接近减半。
其余改动包括 MLA Query LoRA、输出门控,以及每 12 层一次的块级 Attention Residuals。按原文数据,AttnRes 会增加约 2% 的推理延迟,但带来两项关键收益:
- 可选择地取回早期表示,缓解残差稀释和隐状态幅值增长问题;
- 按原文口径带来 1.25 倍计算优势。
AttnRes 与 MLA 其实在从两个方向解决同一个底层问题:KDA 层使用固定大小状态,因此必然丢失一部分信息。MLA 从 Token 上下文维度取回被压缩的信息,AttnRes 则从网络深度维度取回早期表示。
八、AttnRes:残差连接不再一视同仁,每层都可以选择自己需要的过去
原文作者在本节特别感谢 @chloey3k 对理解与写作的帮助。
在一次前向传播中,输入会通过一系列网络层。这里的每一层,都由一个注意力块(KDA 或 MLA)与一个 MLP 或 MoE 块组成。
在常规残差结构中,第
l
l
l 层的输入可以理解为原始 Embedding 与所有前序层输出的等权累加:
h
l
=
h
1
+
∑
i
=
1
l
−
1
f
i
(
h
i
)
h_l = h_1 + \\sum_{i=1}^{l-1} f_i(h_i)
hl=h1+i=1∑l−1fi(hi)
其中,
h
i
h_i
hi 是第
i
i
i 层的输入,
h
1
h_1
h1 是当前 Token,也就是当前序列最后一个 Token 的 Embedding,
f
i
(
h
i
)
f_i(h_i)
fi(hi) 则是第
i
i
i 层某个注意力或 MLP 块的输出。
问题在于,这种加法没有选择性。不同类型的层会收到同一份聚合状态,即使它们实际上可能需要完全不同的历史权重。同时,由于这个递归是纯加性的,越靠后的层必须学会输出幅值越来越大的信号,才能显著改变已经累积起来的残差流,这可能让训练变得不稳定。
AttnRes 不再一视同仁地相加,而是为求和中的每一项乘上专门权重:
h
l
=
α
0
⋅
h
1
+
∑
i
=
1
l
−
1
α
i
⋅
f
i
(
h
i
)
h_l = \\alpha_0 \\cdot h_1 + \\sum_{i=1}^{l-1} \\alpha_i \\cdot f_i(h_i)
hl=α0⋅h1+i=1∑l−1αi⋅fi(hi)
每个
α
i
\\alpha_i
αi 都由 Query-Key 点积计算得到。Query 是每层独立学习的,Key 和 Value 则来自更早的残差流状态。分数经归一化后总和为 1,再用来对历史状态做加权组合。

图 22:常规残差只会累加历史,AttnRes 让当前层按需检索早期表示
因此,模型不再只能依赖直接前驱层的聚合结果。AttnRes 让每一层都能选择性访问更早的层输出,通过自己学习到的 Query,取回当前计算最需要的表示。
下面的伪代码在 Block 粒度上实现了同一思路。一个 Block 保存 12 个 Decoder Layer 中注意力与 MLP 输出的逐元素累积,作为一份可供后续 AttnRes 混合的深度表示:
V = torch.stack(blocks + [partial_block]) # [N+1, B, T, D]
K = norm(V)
logits = torch.einsum('d, n b t d -> n b t', proj.weight.squeeze(), K)
h = torch.einsum('n b t, n b t d -> b t d', logits.softmax(0), V)
return h
如果在每一层都执行残差注意力,训练与推理成本都会过高。只在固定 Block 边界上执行,可以用更低成本保留大部分收益。
在 Kimi K3 中,边界每 12 个 Decoder Layer 出现一次。23 个四层宏周期合计形成八个 AttnRes Block。这种 Blockwise 设计,实质上是在表示质量与系统吞吐之间做结构化折中。
九、从 GPT-2 到 Kimi K3:真正的主线不是规模,而是“选择”
到这里,我们完成了从 GPT-2 到 Kimi K3 的整个路径。
最核心的变化并不只是规模。每一次架构演进,都在改变模型存储什么、如何更新状态,以及如何取回那些固定容量状态无法完整保留的信息。
Kimi K3 把固定状态的递归记忆、周期性 Softmax 检索、稀疏专家容量,以及深度维度的选择性残差访问组合在同一个系统中。额外容量不是被平均撒向所有位置,而是被放到了每个具体功能真正需要的地方。
从本质上说,一个维度固定的联想记忆,必须拥有某种淘汰策略。因为当它达到容量上限后,纯加性线性操作必然会引入干扰。门控、路由、衰减本质上都是学习得到的选择机制;而 Attention,仍然是目前最有效的选择性读取机制。
Rocky 的核心判断
22580 倍参数并不是这七年最重要的结论。更重要的是,模型开始把“选择”编译进每一层系统里:选择记什么,选择忘什么,选择激活哪些专家,选择从哪个 Token 和哪一层取回信息。
这也是为什么 Kimi K3 不能被简化为一个更大的 Transformer:
对不同读者的启发
**对 AI 算法工程师:**不要只会背论文模块名称。真正值得掌握的是状态如何写入、读取和淘汰,复杂度如何分解,以及数学形式为什么能或不能映射到 GPU。架构名会过时,这些机制不会。
**对推理与系统工程师:**不要把 FLOPs 当成唯一指标。内存带宽、Cache 容量、Kernel 融合、矩阵形状和并行粒度,都可能把纸面优势改写成真实瓶颈。产品买单的是端到端 Goodput,而不是一个单独的复杂度符号。
**对 AI 产品与 Agent 团队:**更长的上下文窗口不等于更好的长期记忆。要关心模型是如何忘记、何时会发生信息干扰,以及产品层的外部记忆、检索与上下文管理如何与模型内部记忆配合。
**对创业者与投资人:**技术先进性不等于商业确定性。一个混合架构能否形成长期价值,不仅要看 Benchmark,还要看它能否被稳定训练、高效服务、广泛适配硬件,并最终转化为用户愿意持续付费的工作流价值。
结语
从 GPT-2 到 Kimi K3,表面上是 1.24 亿参数走向 2.8 万亿参数,背后却是一部记忆系统的演进史。
先是用 KV Cache 避免重复计算,再是用线性状态压缩无限增长的历史;接着用 Delta Rule 精确替换、用 Gate 学会遗忘、用 KDA 精细到每个通道;最后,用 MLA 取回 Token 历史,用 MoE 选择计算容量,再用 AttnRes 取回深度历史。
当计算与记忆都不可能无限时,智能系统真正需要学会的,就是选择。
工具会更换,架构会迭代,参数纪录也还会被打破。真正具有跨周期价值的,是看懂每一代系统在哪里遭遇了物理与数学边界,又是如何用新的选择机制,把有限资源用在最值得的地方。
推荐阅读
1. 深入浅出完整解析AI Agent(AI智能体)的核心基础知识
2025年可以说是AI Agent全面落地应用的元年,因此Rocky在持续撰写对AI Agent的全维度解析文章:
深入浅出完整解析AI Agent(AI智能体)的核心基础知识
2. 深入浅出完整解析扩散模型DDPM、DDIM、Score-Based、SDE、LDM、Classifier/Classifier-Free Guidance、Rectified Flow核心基础知识
Rocky对扩散模型的本质原理与和核心基础知识进行了全面系统的深入浅出分析讲解,同时不断跟进补充扩散模型的最新技术发展,希望能给大家带来帮助:
深入浅出完整解析扩散模型DDPM、DDIM、Score-Based、SDE、LDM、Classifier/Classifier-Free Guidance、Rectified Flow核心基础知识
3. 入浅出完整解析FLUX.2、Seedream(即梦)、Z-image、GLM-Image核心基础知识
Rocky对AIGC时代“中场时刻”之后的主流AIGC创作大模型的核心基础知识进行了全面系统的深入浅出分析讲解,力求让大家通俗易懂理解AIGC时代的技术浪潮的本质价值:
入浅出完整解析FLUX.2、Seedream(即梦)、Z-image、GLM-Image核心基础知识
4. 深入浅出完整解析FLUX.1 Kontext和FLUX.1 Krea核心基础知识
Rocky对FLUX.1 Kontext和FLUX.1 Krea的核心基础知识作了全面系统的梳理与解析:
深入浅出完整解析FLUX.1 Kontext和FLUX.1 Krea核心基础知识
5. 深入浅出完整解析DeepSeek系列核心基础知识
Rocky对DeepSeek系列模型的核心基础知识作了全面系统的梳理与解析:
深入浅出完整解析DeepSeek系列核心基础知识
6. 深入浅出完整解析Stable Diffusion 3(SD 3)和FLUX.1系列核心基础知识
Rocky对Stable Diffusion 3和FLUX.1的核心基础知识作了全面系统的梳理与解析:
深入浅出完整解析Stable Diffusion 3(SD 3)和FLUX.1系列核心基础知识
7. 深入浅出完整解析Stable Diffusion XL(SDXL)核心基础知识
Rocky对Stable Diffusion XL的核心基础知识作了全面系统的梳理与解析:
深入浅出完整解析Stable Diffusion XL(SDXL)核心基础知识
8. 深入浅出完整解析Stable Diffusion(SD)核心基础知识
Rocky对Stable Diffusion 1.x-2.x系列模型的核心基础知识做了全面系统的梳理与解析:
深入浅出完整解析Stable Diffusion(SD)核心基础知识
9. 深入浅出完整解析Stable Diffusion中U-Net的前世今生与核心知识
Rocky对Stable Diffusion中最为关键的U-Net结构进行了深入浅出的全面解析,包括其在传统深度学习中的价值和在AIGC中的价值:
深入浅出完整解析Stable Diffusion中U-Net的前世今生与核心知识
10. 深入浅出完整解析LoRA(Low-Rank Adaptation)模型核心基础知识
对于AIGC时代中的“ResNet”——LoRA模型,Rocky进行了深入浅出的全面讲解:
深入浅出完整解析LoRA(Low-Rank Adaptation)模型核心基础知识
11. 深入浅出完整解析ControlNet核心基础知识
AIGC图像创作开源社区已经形成以Stable Difffusion/FLUX为核心,ConrtolNet和LoRA作为首要AI辅助工具的变化万千的AIGC图像创作工作流。
ControlNet正是让AI图像创作社区无比繁荣的关键一环,它让AIGC图像创作过程更加的可控,更有助于广泛地将AIGC算法解决方案应用到各行各业中:
深入浅出完整解析ControlNet核心基础知识
12. 深入浅出完整解析Sora、Seedance、keling等AI视频大模型核心基础知识
AI绘画和AI视频是两个互相促进、相互交融的领域,2024年无疑是AI视频领域的爆发之年,Rocky对AI视频领域核心的Sora、Seedance、Keling等大模型进行了全面系统的梳理与解析:
深入浅出完整解析Sora、Seedance、keling等AI视频大模型核心基础知识
13. 深入浅出完整解析AIGC时代Transformer核心基础知识
在AIGC时代中,Transformer为AI行业带来了深刻的变革。Transformer架构正在一步一步重构所有的AI技术方向,成为AI技术架构大一统与多模态整合的关键核心基座,大有一统“AI江湖”之势。Rocky也对Transformer模型进行持续的深入浅出梳理与解析:
深入浅出完整解析AIGC时代Transformer核心基础知识
14. 深入浅出完整解析ComfyUI、Diffusers、Stable Diffusion WebUI等主流AIGC创作框架核心基础知识
AIGC创作框架正是AIGC算法工作流的运行载体,目前主流的AIGC创作框架有ComfyUI、Diffusers、Stable Diffusion WebUI等。在传统深度学习时代,PyTorch、TensorFlow以及Caffe是传统深度学习模型的基础运行框架,到了AIGC时代,Rocky相信ComfyUI就是AIGC时代的“PyTorch”、Stable Diffusion WebUI就是AIGC时代的“TensorFlow”、Diffusers就是AIGC时代的“Caffe”:
深入浅出完整解析ComfyUI、Diffusers、Stable Diffusion WebUI等主流AIGC创作框架核心基础知识
15. 深入浅出完整解析ComfyUI、Diffusers、Stable Diffusion WebUI等主流AIGC创作框架核心基础知识
在AIGC时代中,如何快速转身,入局AIGC产业?如何成为AIGC/LLM/AI Agent算法/开发工程师?如何在学校中系统性学习AIGC/LLM/AI Agent知识,斩获心仪的AIGC/LLM/AI Agent算法/开发offer?
Don‘t worry,Rocky为大家总结整理了全面的AIGC/LLM/AI Agent算法/开发工程师成长秘籍,为大家答疑解惑,希望能给大家带来帮助:
手把手教你成为AIGC/LLM/AI Agent算法/开发工程师,斩获AIGC/LLM/AI Agent算法/开发offer!
16. AIGC产业的深度思考与分析
2023年3月21日,微软创始人比尔·盖茨在其博客文章《The Age of AI has begun》中表示,自从1980年首次看到图形用户界面(graphical user interface)以来,以OpenAI为代表的科技公司发布的AIGC模型是他所见过的最具革命性的技术进步。
Rocky也认为,AIGC及其生态,会成为AI行业重大变革的主导力量。AIGC会带来一个全新的红利期,未来随着AIGC的全面落地和深度商用,会深刻改变我们的工作、生活、学习以及交流方式,各行各业都将被重新定义,过程会非常有趣。
那么,在此基础上,我们该如何更好的审视AIGC的未来?我们该如何更好地拥抱AIGC引领的革新?Rocky准备从技术、产品、商业模式、长期主义等维度持续分享一些个人的核心思考与观点,希望能帮助各位读者对AIGC有一个全面的了解:
深入浅出全面解析AIGC时代核心价值与发展趋势(2025年版)
17. AI算法工程师的独孤九剑秘籍
为了方便大家实习、校招以及社招的面试准备,同时帮助大家提升扩展技术基本面,Rocky将符合大厂和AI独角兽价值的算法高频面试知识点撰写总结成《三年面试五年模拟》之独孤九剑秘籍:
【三年面试五年模拟】AIGC时代的算法工程师的求职面试秘籍(持续更新中)
18. 深入浅出完整解析AIGC时代中GAN(Generative Adversarial Network)系列模型核心基础知识
GAN系列模型作为传统深度学习时代的最热门生成式Al模型,在AIGC时代继续繁荣,作为Stable Diffusion/FLUX系列大模型的“得力助手”,广泛活跃于AlGC图像创作的产品与工作流中:
深入浅出完整解析AIGC时代中GAN(Generative Adversarial Network)系列模型核心基础知识

![[特殊字符]DeepSeek‑Harness(DSH)小白保姆教程-171主机测评](https://www.171host.com/wp-content/uploads/2026/08/20260816085112-6a817a009aabf-220x150.png)
