刘孟玄 Blog

「离开世界之前 一切都是过程」

FFN 中的 CUDA Kernel 融合

减少中间张量的显存往返,让逐元素操作留在片上

SwiGLU 的数学表达式很短: $Y=\left[\operatorname{SiLU}(XW_{gate})\odot(XW_{up})\right]W_{down}$ 但如果每个步骤都启动一个独立 CUDA kernel,中间结果就需要反复写回和读出 GPU 显存。Kernel fusion(内核融合)要做的是:把适合连续执行的操作放进同一个 kernel,让中间值留在寄存器或共享...

MoE:从多个 FFN 专家到稀疏激活

Router 如何选择专家,以及为什么参数量增加后计算量仍可控

普通 Transformer 的 FFN 只有一套参数,所有 token 都经过同一个变换。MoE(Mixture of Experts,混合专家)把这一个 FFN 换成多个专家,并让 Router 为每个 token 选择少数几个专家。 它想解决的是一个容量问题:模型可以拥有更多 FFN 参数,但单个 token 不必激活全部参数。 1. 从一个 FFN 到多个专家 普通结构是: ...

FFN 张量并行:从列切分到行切分

为什么两张 GPU 分工后,结果仍然和完整矩阵乘法相同

当 FFN 的权重无法放进一张 GPU 时,可以沿中间维度把它切到多张 GPU 上。关键不是把矩阵随意切开,而是让升维矩阵生成的那部分中间特征,与降维矩阵对应的那部分行保持一致。 这篇文章用两张 GPU 和行向量记法说明:W_up 按列切,W_down 按行切,最后对部分输出做 AllReduce 求和。 1. 先看完整的 FFN 忽略偏置,标准 FFN 是: $h=\phi(xW_...

Transformer 前馈网络:从 FFN 到 SwiGLU

从逐 token 加工、激活函数到 4 倍与 8/3 倍中间维度

Transformer Block 中,Attention 先汇聚上下文信息,FFN 再对每个位置的表示进行非线性加工。理解 FFN,可以从最基本的“展开—激活—压缩”结构出发,再看激活函数如何演进为 SwiGLU 的门控结构,最后用参数量解释中间维度的选择。 1. FFN 在 Transformer 中的作用 Attention 让 token 之间交换信息,FFN 则对汇聚后的特征进...

FlashAttention:从 Safe Softmax 到分块计算

用在线归一化把 Attention 的中间结果留在片上

FlashAttention 的名字很容易让人以为它提出了一个新的 Attention 公式。实际上,它并没有改变 Attention 的数学结果:给定相同的 Q、K、V,输出仍然是普通的精确 Attention。 它真正改变的是计算过程:不把完整的 N×N 注意力分数矩阵和概率矩阵写回 HBM,而是把 Q、K、V 切成 tile,在 GPU 片上的 SRAM 和 registers 中完...

KV Cache 优化(四):Speculative Decoding 投机解码

不改变大模型答案分布,怎样一次推进多个 token?

前面三篇都在缩小或筛选 KV Cache。这一篇优化的是 Decode 的串行性这一瓶颈。 普通自回归生成一次只产生一个 token: 1 xₜ → xₜ₊₁ → xₜ₊₂ → xₜ₊₃ 每一步都要调用一次大模型,而大模型单 token Decode 的计算规模很小,却要读取大量权重和 KV Cache。Speculative Decoding(投机解码)采用“先猜、后验”的办法: ...

KV Cache 优化(三):局部注意力、StreamingLLM 与 KV Pruning

当上下文太长,哪些历史 token 值得继续保留?

前两篇分别减少了 KV head 的数量,或把每个 token 的 K/V 压缩成 latent。它们解决的是“每个 token 存得太宽”。这一篇换一个问题: 如果上下文已经长到几十万 token,是否真的需要保留每一个历史 token? Sliding Window Attention、StreamingLLM 和 Pruning KV Cache 都在减少历史状态,但方式不...

KV Cache 优化(二):深入理解 Multi-head Latent Attention

DeepSeek 如何用低秩潜在表示压缩每个 token 的 K/V

MQA 和 GQA 通过共享 K/V heads 减少 KV Cache。DeepSeek-V2 提出的 Multi-head Latent Attention(MLA)换了一个角度: 不直接缓存展开后的多头 K/V,而是先把它们压缩成一个低维潜在向量,只缓存这个更短的表示。 当后续 Query 需要读取历史信息时,再通过上投影恢复所需的 K/V;在经过代数变换的高效实现中,部分...

KV Cache 优化(一):从 MHA 到 MQA 与 GQA

少存几组 K/V,为什么就能明显改善 Decode?

标准 KV Cache 避免了自回归生成时对历史 token 的重复计算,但它也带来了新的问题:上下文越长、并发请求越多,缓存就越大。 对于每一层、每一个 token,模型都需要保存一组历史 Key 和 Value: $M_{KV}=2LBTN_{KV}D_h\times\text{bytes}$ 这里的 2 表示 K 和 V,L 是层数,B 是并发序列数,T 是上下文长度,N_KV ...

KV Cache:Transformer 推理中的增量计算

从 Prefill、Decode 到 K/V 的追加与显存带宽

大语言模型生成文本时,并不是每次都把已经处理过的整段文本重新计算一遍。它会把历史 token 在每一层产生的 Key 和 Value 保存下来,下一次生成时直接复用。这块保存下来的状态就是 KV Cache。 KV Cache 的核心可以先浓缩成一句话: Prefill 一次处理完整 Prompt 并建立缓存;Decode 每次只处理一个新 token,用它的 Query 查询历史...