Attention Mechanism · Deep Dive

QKV 到底是什么

从「查询 / 键 / 值」的检索直觉出发,一路走到 DeepSeek 的 MLAFlash 系轻量产品 的注意力实现。 本页把公式、缓存瓶颈、低秩压缩和 kernel 层优化串成一条线,并配上可动手的可视化。

softmax(QKᵀ/√d)V
一切注意力的核心一行式
−93.3%
DeepSeek-V2 相对 MHA 的 KV Cache 降幅
5.76×
同配置下最大生成吞吐提升

先用检索理解,而不是公式

每个 token 在进注意力层之前,都会被三个不同的线性投影映射成三组向量。 它们角色完全不同——这是理解 QKV 的第一性。

Q Query 查询

「我正在找什么?」

当前 token 的提问向量。图书馆类比:你手里的检索需求单

K Key 键

「我有什么可以被匹配?」

每个 token 的索引标签。类比:书脊上的标题 / 关键词

V Value 值

「匹配上之后,真正要取走的内容」

被加权汇总进输出的载荷。类比:书正文

Q / K / V 投影数据流
悬停路径查看角色
h_t embedding W^Q W^K W^V q k v 提问 · 我要找什么 与所有 k 做点积 索引 · 可被匹配的标签 存入 KV Cache 载荷 · 匹配后取走的内容 按 α 加权求和
关键分离:K ≠ V。 适合被检索的表示,和适合被聚合的表示,往往不是同一件事。把索引与载荷拆开,检索精度和内容质量可以各自最优。

把直觉写成一行可计算的式子

qt = WQ ht    kt = WK ht    vt = WV ht

scorej = qtᵀ · kj / √dh
αj = softmaxj(score)
ot = Σj≤t αj · vj

六步走完一次自注意力

参考 Illustrated Transformer 的分解方式:点步骤按钮,逐步看矩阵如何变。

自注意力分步机
点 1–6 · 观察矩阵状态

亲手「查一次」注意力

点选某个位置作为当前 Query,观察它如何给历史 token 分配权重,并加权汇总出新的 Value。

因果自注意力检索台
点选 token · 观察 α 与加权 V

句子: The animal didn't cross the street because it was too tired

加权汇总后的输出向量 o

点到 it 时,权重应压在 animal 附近——这正是 Illustrated Transformer 里那张经典指代消解图。

注意力矩阵:整张 L×L 的「谁看谁」

每一行 i 是位置 i 的 Query,每一列 j 是位置 j 的 Key。颜色深浅 = αij。上三角是因果掩码。

交互注意力热力图
点单元格 · 看 score → α
点一个格子查看详情

为什么要多头?

单头只有一套 Q/K/V。多头把 d 维拆成 nh 个子空间,每个头独立检索,最后拼接再投影。

MultiHead = Concat(head₁, …, headnh) · WO
headi = Attention(Q WiQ, K WiK, V WiV)
四个头的典型分工
模拟 · 真实模型会更混沌

真实模型里头的模式更碎,有的几乎恒等。但「局部 / 语法 / 指代 / 位置」确实是被反复观察到的常见簇。

KV Cache:推理真正的内存墙

自回归生成时,第 t 步只需新 token 的 Q,但要和全部历史 K/V 做注意力。 不缓存就要整段重算。于是工程上把历史 K/V 存起来——这就是 KV Cache

缓存膨胀模拟器
拖动 L / batch · 切换架构
KV Cache 总量(估算)

从 MHA 到 MLA:压缓存的主线

MHAMulti-Head Attention
每头独立 Q/K/V。表达力最强,缓存最大。每 token 缓存 2 n_h d_h
MQAMulti-Query Attention
所有头共享 K/V。缓存砍到 1/nh,快但质量通常掉。
GQAGrouped-Query Attention
折中:nq 个 query 头分成 nkv 组,组内共享。Llama-3 / Qwen / GLM 主流。
MLAMulti-head Latent Attention
K 与 V 联合压缩到低秩潜向量 c^KV。头不减,用计算换显存。DeepSeek-V2 起。
哲学差异: MQA/GQA 在「头的数量」上做减法;MLA 在「表示的秩」上做减法——头一个不少。

MLA 漏斗:压进去,再恢复出来

低秩 KV 联合压缩
点按钮推进阶段
// 下投影(真正进 cache)
ctKV = WDKV ht   // d_c ≪ n_h·d_h

// 上投影(可被吸收,推理可不显式算)
ktC = WUK ctKV
vtC = WUV ctKV

// 解耦 RoPE:位置信息单独一小段
ktR = RoPE(WKR ht)
kt,i = [kt,iC ; ktR]
# 标准 MHA 缓存
cache[token] = (K[heads, dh], V[heads, dh])
# → 2 * heads * dh 个元素
# MLA 缓存
cache[token] = (c_KV[dc], k_R[dR])
# → dc + dR ≪ 2*heads*dh
# W_UK 可吸收进 W_Q
# W_UV 可吸收进 W_O
数字: DeepSeek-V2 论文报告 KV Cache 相对 MHA 减少约 93.3%,最大生成吞吐约 5.76×。 MLA 有时甚至比 MHA 更强——低秩瓶颈强迫跨头共享检索特征,相当于一种隐式正则。

FlashAttention:不是新注意力,是新算子

FlashAttention(Dao et al.)

IO 感知的精确注意力 kernel。数学等价,只是分块 + 在线 softmax,避免 L×L 写回 HBM。

  • 显存 O(L²) → O(L)
  • 墙钟常 2–4×
  • 不是近似,是 exact

产品名里的 “Flash”

厂商把「Flash」用作轻量高速产品档:小激活、强蒸馏、低延迟。一般也用 FA 类 kernel,但名字指产品定位。

  • 更少激活参数
  • 更强蒸馏
  • 优先 TTFT 与吞吐
FlashAttention 分块动画
点播放 · 观察 SRAM 流水
Q 块(当前) K/V 块(流式读入) SRAM 内完成 HBM 写出(仅输出) 朴素实现会落盘的 L×L
架构层 vs Kernel 层,正交叠加。 MLA 减少每 token 要缓存/搬动的 KV 宽度;FlashAttention 减少每次注意力的 HBM 往返。生产部署通常两者都上。

对照:GLM Flash 系 vs DeepSeek Flash 系

说明:具体 Flash SKU 的完整权重配置往往不全公开。下表基于已开源技术报告与公开架构。 看到更新号(如 5.3 / V4.1)时,优先核对是否沿用下列机制。

维度 DeepSeek Flash / V 系 智谱 GLM Flash 系
注意力结构 MLA(低秩 KV 联合压缩 + 解耦 RoPE),V2 确立,V3 延续 开源主干以 GQA 类为主 + FlashAttention / FlashInfer kernel
FFN DeepSeekMoE:细粒度 + 共享专家;V3 加 aux-loss-free 均衡 MoE(4.5:355B/A32B;Air 106B/A12B)
加速栈 FP8、MTP 投机解码、MLA 吸收投影 MTP / EAGLE、FP8、共享专家融合、FlashInfer
“Flash” 含义 产品档:低激活、低延迟;算法核心仍是 MLA + MoE 产品档:高吞吐低成本;核心是 GQA + 强蒸馏 + 推理栈
长上下文 MLA 让 KV 几乎「定宽」,128K+ 更友好 依赖 GQA 压缩比 + 页式 KV / 量化缓存
注意力效率的四个正交旋钮
点击高亮
读型号的方法论: (1) 注意力是 MHA / GQA / MLA 哪一种? (2) 「快」来自架构省缓存,还是蒸馏变小,还是 kernel? (3) KV Cache 在 32K / 128K 下大概多少 GB?

收束

  1. Q 问,K 索引,V 载荷——把「检索」与「内容」解耦。
  2. softmax(QKᵀ/√d)V——点积相似度 + 概率化 + 内容加权提取。
  3. 多头提供多子空间并行检索;代价是 KV Cache 膨胀。
  4. GQA/MQA共享 K/V;MLA低秩潜向量,保留多头。
  5. FlashAttention是 IO-aware kernel,不改数学。
  6. DeepSeek Flash / GLM Flash是产品档;前者灵魂是 MLA,后者偏 GQA + 蒸馏。

延伸阅读