计算图与前向执行
计算图里,节点是运算(矩阵乘或其他变换),边是运算之间传的张量。节点的运算量决定计算需求,边上的张量决定数据量,边的方向决定谁必须先算完。图上的一条边只说明后一步要用这份数据,不代表一定要在 CPU 和 GPU 之间复制。
能不能并行,看依赖,不看“序列”这个名字。RNN 在同一层等前一个 token;因果 Transformer 只等上一层,同层已知 token 可以一起算。生成又加了一条跨调用的依赖:下一次的输入是这一次的输出。
图 2-1 / 2-2 · 4 个 token、3 层,谁等谁
节点里的数字是“最早第几步能算”(每层每 token 一个单位、并行资源充足)。RNN 的 ht = f(xt, ht−1),同层逐个推进;Transformer 第 l 层每个位置读上一层的因果前缀。加计算单元能让同一步的节点一起跑,但缩不短这条最长链。这也是练习 2-1 的答案。
一个计算节点:Y = XW
本次有 m 个 token,每个是 k 维向量,按行排成 X∈ℝm×k;权重 W∈ℝk×n。每个输出元素是长度 k 的点积,于是:
m 翻倍,运算翻倍、权重不变(同一模型处理更多输入);n 翻倍,权重和运算都翻倍(这一层变宽)。本章所有模型表都按这条规则逐行计算。
Qwen3-8B 配置
8,190,735,360 个参数| 配置项 | 取值 | 影响什么 |
|---|---|---|
| 层数 L | 36 | 重复次数、逐层状态、深度依赖 |
| 隐藏维度 d | 4096 | 子层输入输出与投影尺寸 |
| FFN 中间维度 f | 12288 | 三个 FFN 矩阵的权重与计算 |
| Q / KV 头数 | 32 / 8 | 查询与上下文表示的宽度 |
| 头维度 dh | 128 | 每头点积与状态宽度 |
| 词表 V | 151936 | 嵌入与输出头规模 |
前向从 token ID 开始:词嵌入查出 4096 维向量 → 36 层“注意力 + FFN” → 归一化 → 词表投影得到 logits。只生成下一个 token 时,只需最后一个 token 的 logits。
例 2-1 · 一层的参数与线性运算
Q、O 各 4096×4096,K、V 各 4096×1024,FFN 三个 4096×12288。这里还没用到上下文长度:投影对每个 token 做相同的变换。
注意力:Q 提问,K 匹配,V 被汇总
同一个 token 的隐藏向量乘三个权重矩阵得到 Q、K、V。Qwen3-8B 的 Q 宽 32×128 = 4096,K、V 各 8×128 = 1024;每 4 个 Q 头共用一个 KV 头。
除以 √dh 防止分数随头宽变大;ℳ 是因果掩码,屏蔽未来位置;Softmax 系数 aj = esj/Σesi 之和为 1。这里的“注意力权重”是本次输入算出的系数,不是模型参数。Qwen3 还在点积前做 QK Norm 和 RoPE(随位置旋转,让点积带上相对位置)。
图 2-4 · 查询—键配对 = 长方形 + 三角形
每格一次配对每对配对,一个 Q 头的 QKᵀ 约 2dh FLOPs,AV 再约 2dh。没有缓存的 prefill 里长度翻倍,投影行数翻倍,配对数约变 4 倍。保持 B·P 不变只能保持投影行数不变:把一条长输入拆成两条独立短输入,跨分界的配对就消失了。
FFN 与一层的骨架
SwiGLU:FFN(X) = [SiLU(XWgate) ⊙ (XWup)]Wdown,SiLU(x) = x/(1+e−x)。三矩阵共 3df 个参数,处理 m 个 token 需 6mdf FLOPs。Qwen3-8B 的 FFN 约 1.51 亿参数(BF16 288 MiB),注意力四个投影约 4194 万,FFN 占主要投影参数约 78%,所以短上下文时 FFN 算得最多。12288 维的宽激活只在计算期间临时存在。残差把子层输入留着,等变换完再逐元素相加。
表 2-1 合计 · Qwen3-8B 一次前向的矩阵运算量
F = 36(385,875,968·m + 16,384·Npair) + 2·mout·4096·151936下图:无缓存 prefill 时,注意力占总矩阵运算的比例随输入长度上升(横轴对数)。FFN 随 token 数线性增长,全注意力随 P(P+1)/2 增长。decode 只对新 token 做投影和 FFN,旧 token 的 K、V 从缓存读,当前查询与上下文的注意力仍要算。
自回归生成的资源消耗
prefill 一次处理已知输入,由最后一个 token 的 logits 选出首个输出;之后进入 decode,每次把上一个输出送回模型,每条请求只多一个 token。因果模型里旧 token 看不到新 token,所以旧 token 的 K、V 可以保留,下一步只用新的 Q 去读它们。
KV 缓存把“重算旧 token”换成“保存并反复读取旧 token 的状态”。同一份权重在一条请求里用上数百次,KV 却一边读一边涨:最终存了多少字节和累计读了多少字节,可以差上千倍。
每个上下文 token 占多少 KV
第一个 2 是 K 和 V。层数或 KV 头数减半,增长速度减半;batch 里每多一条独立请求,就多一份上下文。
权重
多次调用之间不变。Qwen3-8B 全部 BF16 权重约 16.38 GB(15.26 GiB)。[m,d]×[d,f] 的每一行都用同一个权重矩阵:读进片上一次,可供多行使用。
上下文状态
随请求保留,持续追加或更新。要算实际容量、每步读写量和更新所需的计算。
临时数据
算子或阶段内产生,用完释放。前一层的缓冲可给后一层复用;算子融合能让部分中间值只留在寄存器或片上。算读写量要数清每次访问,算峰值要找同一时刻还活着的张量。
例 2-2 · batch 加到多少,读 KV 比读权重还多
每批共享权重读一遍 RW = 15,136,811,008 BB* = RW / (cKV·H)。8K 时最小整数 batch 为 13,2K 时为 51:上下文缩到四分之一,交点约推后四倍。上下文越长,批内复用权重的收益越早被各请求独立的 KV 读取抵消。
图 2-7 · 每一步追加一个 token,重读全部旧上下文
例 2-3 · 一次完整回答:存下多少 vs 读了多少
B = 1,Qwen3-8B BF16最后返回的 token 没有再送进模型,所以不为它存 KV。早进入上下文的 token 参与更多后续查询。运算也一样:Fdecode,total = ndF0 + a[ndH + nd(nd−1)/2],固定部分随步数线性增长,上下文部分有一项按步数平方增长。把 G 改成 513 再看三项各涨多少(练习 2-3)。
上下文状态的表示与访问
两种记笔记的办法:逐页留记录,要哪页取哪页;或者只留一张定长摘要,每读到新内容就改写它。前者随历史增长,后者大小固定,但不保证找回每个 token 的细节。模型的办法可以拆成三个旋钮:每条记录多宽(GQA、MLA)、保存多少条(窗口、压缩、跨层共享)、每次读哪些条(稀疏索引),以及另一条路:固定大小的递推状态。
节省的存储与读取,要和新增的选择、压缩、更新工作一起算。索引打分本身要扫描索引条目,递推矩阵每步要读一遍写一遍。
2.3.1 · 减少 KV 份数:MHA、GQA、MQA
图 2-9 / 2-10 · 32 个查询头共用几组 KV
Qwen3-8B 实际为 GQA 8 组固定层数、头宽、8192 个 token 与 BF16,只改 KV 组数:32 / 8 / 1 组分别是 4608 / 1152 / 144 MiB。共享 KV 后每个 Q 头仍各自打分、各自输出,所以 KV 投影参数和状态按组数减少,QKᵀ 与 AV 的运算量仍按 32 个查询头算。MQA 原论文把增量推理的内存带宽开销作为动机,GQA 在 MHA 的质量与 MQA 的速度之间折中。
2.3.2 · 缩窄每条记录:MLA
图 2-11 / 2-12 · 上投影放在哪一侧
Kimi K3 · 24 层 Gated MLA由结合律 qKᵀ = q(cUk)ᵀ = (qUkᵀ)cᵀ:路径二只对当前查询做一次变换,再直接与潜变量 c 点积;值也可以先汇总低维向量再上投影。紧凑缓存每 token 存 512 维潜变量 + 64 维额外分支(K3 的 MLA 全部 NoPE,这 64 维不旋转,位置信息由 KDA 层提供)。紧凑路径仍为每个 token 存一条记录,存储和点积仍随上下文增长;上下文越短,查询变换本身的开销占比越高。
2.3.3 · 少存、少读:窗口、压缩、稀疏索引
DeepSeek V4-Flash 的 43 层 = 2 个纯窗口层 + 21 个 CSA 层 + 20 个 HCA 层,窗口 128。CSA 每 4 个 token 压成一条(相邻块重叠汇总共 8 个 token),另有 128 维索引;主注意力最多读窗口 + 512 个选中条目,但索引打分要扫描全部已存索引。HCA 每 128 个 token 一条,不做 top-k,读全部粗粒度条目。一条 512 维主 KV 记录同时当键和值,供多个查询头共享。
图 2-13 / 2-15 · 先攒满一块,再由查询挑选
压缩比 4:前三个 token 更新同一块缓冲,第四个到达后发布一条压缩条目。当前查询先扫描所有索引条目,再读取被选中条目的主注意力状态。图中只示意数量关系,省略 V4 的重叠投影与加权汇总;挑中哪几条是示意。
图 2-14 · V4-Flash 状态分解(BF16 参考格式)
另计 FP32 压缩器缓冲约 11.641 MiB8K 时一个 CSA 层:2048 条压缩记录(主状态约 2 MiB、索引约 0.5 MiB)、窗口约 0.125 MiB,选中的主状态最多 0.5 MiB;HCA 层 64 条(约 0.0625 MiB)。43 层合计 59.125 MiB + 缓冲 ≈ 70.8 MiB,最后一次查询主注意力(含窗口)+ 索引读 27.625 MiB。把 S 拖到 16384 看练习 2-4:保存条目和索引扫描翻倍,选中上限仍是 512。压缩缓冲容量这里固定按 8K 值计(示意)。
2.3.4 · 固定大小的递推状态
图 2-16 · 新键值外积加进旧状态,矩阵大小不变
左边是逐 token 记录(越存越长),右边是 4×4 的递推状态(数值为示意)。线性注意力不再显式算所有查询—键配对,特征维度固定时整段序列的运算随长度线性增长。实际的 KDA(Kimi Delta Attention)还加了门控和 delta 更新:用当前键检验已有状态的预测,按误差写修正,衰减门决定保留多少旧信息。
Kimi K3 的 KDA
每层 96 个头,每头 128×128,FP32:单层 6 MiB,69 层 414 MiB。一次 decode 读旧矩阵、写回新矩阵,理想读写 828 MiB,不随上下文增长。
短上下文 vs 长上下文
短上下文时这是一笔显著的固定开销;长上下文时避免了扫描量随 token 数一直涨。
prefill 另算
decode 用单步递推;已知输入用块式算法并行,块间传状态。块内中间量要临时空间,只看最终状态大小预测不了 prefill 峰值(第 5 章)。
2.3.5 · 混合结构:固定部分 + 随长度增长部分
图 2-18 / 2-19 · 五个模型的单请求状态随上下文增长
双对数轴曲线形状来自表示方式:Qwen3-8B 每 token 所有 GQA 层追加 K、V;Kimi K3 只有 MLA 追加,KDA 固定;V4-Flash 在压缩块完成时阶梯增长;Qwen3.6 是递推层 + 全注意力层。每步访问:逐 token 上下文计读取,递推矩阵计一读一写,不含权重。V4.1 Flash 的容量曲线按书中 8K(30.09 MiB)与 1M(3.138 GiB)两点线性插值,属示意;书中只给出它 8K 的每步读取(11.375 MiB,生产格式),其他长度不画。
练习 2-5 · 固定状态 vs 随长度增长的状态
低于交点 H*,缩短上下文只能省下一小部分;远高于交点,缩窄每个 token 的表示更有效。预算小于固定状态时,上下文缩到 0 也放不下。
2.3.6 · 每个 token 存多少,每次 decode 读多少
要同时给三个量:全局历史每加一个 token 的平均存储增量、长度 N 时实际存的状态、一次 decode 要读的历史。把三者都除以上下文长度,会掩盖它们不同的增长规律。下表 N = 8192(含查询自身)。
跨模型缓存对比
条形为对数长度Kimi K3 的参考实现把 K/V 展开,每 token 1,474,560 B,是紧凑路径的 53 倍多。两代 Flash 用生产混合格式:V4-Flash 主记录 FP8/BF16 每条 584 B、索引 MXFP4;BF16 参考格式下 V4-Flash 同一 8K 全局历史为 53.75 MiB(另有 5.375 MiB 窗口),读取 27.625 MiB。混合注意力另有固定状态:Qwen3.5 184.219 MiB、Qwen3.6 61.875 MiB、Kimi K3 433.406 MiB。
V4.1 Flash:CED 与跨层共享
V4.1 Flash 把 40 层文本主干分成前 20 层因果编码器和后 20 层解码器,同属一个自回归模型(受 YoCo 跨层复用 KV 启发)。编码器遵守因果约束,不是传统 seq2seq 那种双向编码器;生成新 token 时编码器也照样参与。
V4.1 没有再提高序列压缩比,而是靠跨层共享和更低精度缩小缓存。40 层里只有 4 层有独立全局 KV,全局 KV 平均每 token 890 B,比 V4-Flash 的 3514.25 B 小约 3.95 倍。
图 2-20 · CED:生成全局 KV 和构建局部状态分开做
大部分提示 token 只走编码器主体和全局 KV 投影;解码器每层的局部 SWA 依赖本层输入,所以把提示末尾最多 128 个 token 的编码器输出送进解码器重放(末尾窗口重放)。开始生成后,新 token 依次经过全部 40 层,所以 prefill 省下的比例不能直接套到 decode。
表 2-D · 8K 输入的 prefill 分到哪些阶段(TFLOPs)
参考全层前向让 8192 个 token 走完 40 层,并先算矩形索引分数再屏蔽;CED 路径只让解码器主体处理末尾 128 个 token,解码器全局 KV 与索引键仍为全部输入生成,后续索引限制在候选集内。差异同时来自执行位置数和索引算法。
图 2-21 · 40 层里谁存全局 KV,谁去读
层号从 0 开始第 2、8、14 层每 2 个 token 一条记录,第 20 层每 token 一条。主记录 512 个 FP4 值、每 16 个值一个字节 scale:512/2 + 512/16 = 288 B;索引 128/2 + 128/32 = 68 B。从偶数长度到奇数长度只加第 20 层的 356 B;再到下一个偶数长度,三个 2:1 压缩器各完成一条,本步加 4 × 356 = 1,424 B。复用层不生成自己的全局 K/V,但仍有独立的 Q 和局部 SWA(每层最多 128 条 FP8 记录,每条 528 B,40 层合计 2.578 MiB;填满后覆盖旧槽位,每步仍写 40 × 528 = 21,120 B)。
图 2-22 · CSA2 分层选择:Full → 候选池 → Reindex / Reuse
4 Full · 4 Reindex · 30 Reuse · 2 仅 SWA首个解码器 Full 层给所有条目评分,按每块 8 条分块、以块内最高分作块分,选 2048 块组成最多 16,384 个候选;该层仍按全局分数取 top-512。后续 Reindex 层在池内用自己的索引查询重选 512 条,Reuse 层沿用已有选择。后续搜索量有了上限,但首轮全局扫描仍随上下文增长;落在池外的条目,本次查询后续层再也选不到(训练要适应这一点,见第 10 章)。
条件计算与专家权重复用
稠密 FFN 对每个 token 用同一组矩阵。MoE 把参数分给多个专家:路由器算分,选 top-k 个专家,把 token 送过去,再按路由权重合并;有共享专家时,所有 token 还都走一条共享分支。每个专家本身仍是 gate、up、down 三个矩阵。
“模型存多少参数”和“一个 token 激活多少参数”可以分开调;batch 里的路由结果又决定实际读几份专家权重。增大 E 只扩大可选集合,只有选中数或专家尺寸变大,单 token 运算才会变。
例 2-4 · 运算相同,权重读取差 32 倍
Qwen3.6 一层:256 个路由专家、每 token 选 8 个,专家中间维度 512。一个专家 3 × 2048 × 512 = 3,145,728 个参数,BF16 为 6 MiB;全部路由专家 1.5 GiB/层,40 层 60 GiB。每个格子是一个专家,颜色越深收到的 token 越多。
一个 token 发给 8 个专家,就在 8 个专家的输入矩阵里各占一行,所以分派次数 = B × 8,运算量与路由方式无关。均匀分派时 64 个 token 覆盖全部 256 个专家、每个处理 2 行;集中分派时只读 8 份权重、每份处理 64 行,40 层合计 1.875 GiB。代价是一边要执行许多只有两行的小矩阵乘,一边是少数 64 行的矩阵乘,权重复用和计算效率都随之变化。“随机”模式用固定种子模拟每个 token 独立选 8 个专家,仅作示意。
Qwen3.6 整模型
全部文本参数约 346.6 亿(BF16 69.321 GB),已有 8K 上下文、B = 1 的一步 decode 约 7.33 GFLOPs,少于 Qwen3-8B 的 20.0:主干只有 2048 维,30 层用递推状态,MoE 只执行选中专家和共享分支。
V4-Flash:共享专家
每层 256 个路由专家选 6 个,另有 1 个共享专家,中间维度 2048;单专家 25,165,824 个参数。前三层哈希路由(按 token 定专家),之后评分路由。一层专家运算 = 2mNs + 2ΣteNe。
Kimi K3:潜空间专家
896 个路由专家选 16 个。输入先从 7168 维投影到 3584 维潜空间,再经中间维度 3072 的专家,合并后投影回主干;共享专家直接处理主干表示。降维缩小了专家矩阵,多了进出潜空间两次投影。
专家分布在不同卡上时,要把 token 发到专家所在的卡、算完再合并,通信量取决于专家和输入放在哪里(第 6、9 章)。
网络形状与计算组织
参数量相近的模型可以有不同的计算图;矩阵 FLOPs 相近的模型,缓冲区占用时间和串行步数也可能不同。
同样的参数预算,可以换成更深更窄、或专家更多更小:总量不变,但矩阵形状、依赖链长度和多卡分工的最小单位都变了。
深度 × 宽度:参数 ∝ L·d²
忽略词表和小向量参数、FFN 宽度与 d 保持固定比例时成立。宽度减半、层数 ×4:参数相近,每个矩阵更小,但逐层依赖链变 4 倍长,每层还要各存一份上下文状态。
专家粒度:参数 3Edf、单 token 运算 6ktopdf
Qwen3-235B-A22B 的对照:E 减半、f 加倍、k 减半,两个量都不变。16 个 token 的算例里,基线与 64 专家变体的专家矩阵运算都约 454 GFLOPs。但每专家收到的行数、分组矩阵乘的形状、路由器参数(随 E 变)都会变。128 个专家可分 8 组每组 16 个;4 个 KV 头按完整头分工只能分 4 份,8 卡执行就要复制部分 KV。第三个变体是按同一规则推出的示意。
残差连接决定哪些张量要同时活着
普通残差
xℓ+1 = xℓ + fℓ(xℓ):子层计算期间要留住 xℓ,变换完才能相加。后续多层还要引用的表示,必须存到最后一次使用。
mHC(V4-Flash,4 路)
残差通路扩成 4 条,每条是一份 4096 维表示;混合矩阵元素非负、行列和接近 1(Sinkhorn 迭代归一化)。主体矩阵仍是 4096 维输入。8192 个输入 token 时混合投影约 555 GFLOPs,非矩阵运算约 149 GFLOPs。V4.1 的 Single-Pass mHC 沿用上一层的输入混合系数,残差状态只读一遍。
AttnRes(Kimi K3)
沿网络深度做注意力:对较浅层的表示算权重再加权求和,作为当前层输入。块式实现只保留块表示。这些表示只活在本次前向里,KV 却要跨多次调用保留。
多 token 预测与推测解码
MTP 在主干末端加辅助预测模块:训练时让表示包含对更远内容有用的信息;推理时先提出多个候选 token,再由目标模型验证,通过的 token 一轮就能产出多个。V4-Flash 一次辅助预测(B = 1, P = 1)约 1.80 GFLOPs,其中共享词表头约 1.06:不增加独立权重,每次调用仍要做词表投影。
推测解码何时划算:ḡ > (Ts + Tv) / Td
书中例子:普通 decode 20 ms,草稿与验证合计 30 ms,平均每轮 2 个有效输出时每输出 15 ms;只得到 1 个时要 30 ms。多预测几个位置会增加单轮工作量(第 8 章细算)。
整个模型的资源需求与比较
前面三类结构变化:上下文表示决定状态大小和访问方式,专家选择决定每次用哪些权重,深度与连接决定计算顺序。整模型只需把每类层的参数、一次调用的运算、一条请求的状态,按层数加权求和:
g 是层的类别(同一类层采用相同的注意力、前馈与连接结构)。MoE 的 Ng 包含全部专家,Fg 用各专家实际收到的行数。
表 2-A · 五个模型的总体架构(文本部分)
T = 万亿V4.1 Flash 的 Engram 含约 196.61B 查表参数及其投影、门控:按 n-gram 对应的 24 个桶各取一个 256 维向量拼成 6144 维,查表地址只由 token 序列决定,可在该层执行前预取;查表参数增加了容量,但每个 token 不会遍历整张表。V4.1 只有第 2、8、14、20 层保存独立全局 KV,第 2、8、14、20、24、28、32、36 层运行索引器。Kimi K3 首层是中间维度 33792 的稠密 FFN,后 92 层用 3072 宽的路由专家。
图 2-25 ~ 2-31、2-36 · 换一把尺子比较
表 2-B · 参数由哪些部分构成
占各自总参数的百分比“其他”含路由器、潜空间进出投影、归一化、卷积和连接;注意力投影含 V4-Flash 的压缩与索引投影。Qwen3-8B 的参数主要在每个 token 都要执行的稠密 FFN;Qwen3.6 的路由专家约占 93%,V4-Flash 与 Kimi K3 约 97%—98%。所以三者的总容量由专家集合决定,单 token 专家运算取决于每层选中的专家。
表 2-C / 2-E · 相同输入条件下的数字
B = 1;prefill S=0, P=8192;decode S=8192, P=1;词表头只算末尾 token各模型按自己的执行路径累计:V4.1 为 CED + 末尾窗口重放及候选集内索引;Qwen3-8B 为有效因果注意力;Qwen3.6 为逐项执行的矩形注意力与块式线性分支;V4-Flash 为有效主注意力及参考索引;Kimi K3 为紧凑 MLA 与块式 KDA。“交互”只计当前查询的注意力评分与值汇总(两代 Flash 加索引点积)。Qwen3-8B、Qwen3.6 的发布配置分别支持 40,960 与 262,144 个位置,1M 行按同一结构外推。实际 checkpoint 用各自格式:V4-Flash 主干约 156.02 GB,Kimi K3 文本约 1559.97 GB。
Qwen3.6 vs Qwen3-8B
权重约 4 倍,单步运算更少:大量参数放进可选专家,每 token 只调 8 个。
V4-Flash
权重继续扩大,8K 状态反而因压缩与选择缩小。到 1M,交互 113.80 GFLOPs,整步 140.34。
V4.1 Flash vs V4-Flash
短上下文时 V4.1 更大的主干让投影和专家算得更多(8K:35.92 vs 29.54);200K 时 40.21 vs 50.48,1M 时 57.49 vs 140.34,较少的索引器与分层候选选择抵消了新增工作。
Kimi K3 的紧凑 MLA 减少了缓存,却没取消查询与历史 token 之间的计算:1M 时交互达 5257.04 GFLOPs。评估长上下文设计,要分别检查存了多少状态、访问哪些位置,以及索引和状态更新多出了多少工作。
2.6.2 · 一张卡能放几条请求
图 2-32 / 2-33 · 容量预算
递推与卷积状态同样计入每请求分母请求数整数跳变:剩余空间装不下一整份状态,就不能再加一条。4-bit 的 39.500 GB 含仍用高精度的嵌入、输出头、归一化,以及 scale 和打包填充,比所有参数一律按半字节折算更大。235B 的 BF16 权重约 470 GB,超过 8 张 RTX 4090 合计的 192 GB;一台 8 × H100 SXM 合计 640 GB,扣权重后约剩 170 GB,还要放状态、工作区和多卡切分后的重复数据(第 6 章)。
图 2-34 · 反过来:给定加速器,留给权重多少
Nmax = (C − M0 − B·K) / bWRTX 4090 的 24 GB,先给 B 条 8K 请求(每条 1.125 GiB)和 2 GiB 工作区留空间。书中 B = 4、BF16 时余量 17.02 GB,约 85.1 亿参数。加层数或 KV 头会增大每请求的 K,留给权重的空间随之变小。Llama 3 的 405B BF16 推理用了两台、共 16 张 H100。
2.6.3 · 同一请求,五个模型各算多少
图 2-35 / 2-36 · 输入 128 个 token、返回 4 个
一次 prefill + 三次 decode,最终保留 131 个位置。V4.1 Flash 的 128 个输入正好全落在解码器重放窗口内,短请求拿不到长提示跳过大量解码器位置的收益。增加 P 主要增加一次输入处理和后续 decode 开始时的上下文;增加 G 则反复执行投影、专家和输出头,并多次读取上下文。
同 token 数比较 vs 同文本比较
固定 S、P、G、B,回答“同样多的位置怎么算”;固定文本和任务,回答“同一个任务要怎么执行”。八道短语检索题里,Qwen3-8B 与 V4-Flash 都找对了目标短语,但短文在 Qwen 里是 523 或 524 个 token,在 V4-Flash 里是 501 个;长文分别是 2121 或 2122 个和 2036 个。先按同一标准判答案,再把各自的输入长度代入模型表。
从整模型合计追到具体矩阵
先选模型和执行分支,再用“单次矩阵 FLOPs × 层数”累计;路由专家要按实际收到的行数 te 求和。末端归一化执行一次,层内归一化、激活、位置处理和状态更新沿相应分支执行。DeepSeek-V3(表 2-3)作为 MLA 的历史参照。
四个容易下错的结论
总参数决定完整模型的容量;选中的专家、注意力类型和调用形状决定当前工作。Qwen3.6 权重约为 Qwen3-8B 的 4 倍,单步运算 7.33 vs 19.97 GFLOPs。
GQA 共享上下文表示,32 个查询头仍各自评分;MLA 改变上下文宽度,也改变上投影的执行位置。先找被改变的矩阵与状态,再算其余工作。
Kimi K3 的 414 MiB 递推矩阵每步一读一写,合计 828 MiB;prefill 还可能产生临时块状态。容量、累计访问与峰值工作区分别回答不同问题。
同 token 数适合比较资源结构;同文本任务还要固定评分、质量与执行条件,并允许不同分词器产生不同长度(523 vs 501 个 token)。
先找到被改变的对象,再代入公式
矩阵尺寸 → 权重与线性运算
NW = kn,F = 2mkn。投影和 FFN 随本次 token 数 m 增长;词表头按 mout 另算。
查询—键配对 → 注意力运算
Npair = B(PS + P(P+1)/2)。延长上下文、拆分请求、复用前缀,改变的都是这一项。
驻留时间 × 调用次数 → 状态读写
cKV = 2LnKVdhb。一条 8K 输入、1024 次 decode:存 1.27 GiB,读 1224 GiB。
表示方式 → 状态曲线
GQA 减组数,MLA 减宽度,窗口/压缩/共享减条目,索引减读取,递推固定大小但每步读写。
专家分派 → 每批读几份权重
F 按分派行数 B·ktop 累计,R 按访问到的不同专家数 U 累计。同样 512 次分派,U = 256 或 8。
容量预算 → 结构选择
先从加速器容量里扣除服务所需状态和工作区,再看剩下的空间能放多大的模型;MQA、GQA 与稀疏激活都说明,系统效率也是选结构的依据。
面对新条件,先指出它改变了哪个对象:加 batch、延长上下文、扩大专家集合、增加选中专家数,作用于不同的项。读完本章,应能对新的模型配置列出一次前向、一次 decode 和完整生成各自的资源需求。下一章加入请求长度分布、到达时间和工具调用依赖,让这些需求变成随时间变化的负载。
动手验证
练习 2-1〔延伸〕· RNN 与 Transformer 的依赖如何限制并行
4 个已知输入 token,分别画出三层 RNN 与三层因果 Transformer 的依赖图;再加一个待生成位置,指出计算它之前必须等哪个节点完成。设每层每 token 耗时一个单位、并行资源充足,求处理全部已知输入的最长依赖链;说明加计算单元能缩短哪些等待、不能缩短哪些。(2.1 的依赖图可直接切换。)
练习 2-2〔核心〕· 输入行数相同,注意力计算量为何不同
用表 2-1,取 B=4, S=4096, P=1024,分别算投影与 FFN、有效因果注意力、每条序列末尾 token 的词表投影 FLOPs。保持 BP=4096,改为 B=1, S=4096, P=4096,先预测哪些项相同。最后以一条 8K 输入为例,比较完整处理与复用前 6144 个 token 的 KV、只处理新增 2048 个 token,求节省的矩阵运算比例。(前向计算器里有这几组预设。)
练习 2-3〔延伸〕· 输出变长后,KV 容量与累计读取量如何增长
Qwen3-8B、B=1, S=0, P=8192,分别返回 G=513 与 G=1025。求 decode 次数、最终 KV 大小和累计旧上下文读取量;解释输出接近翻倍时,生成阶段新增 KV、最终 KV 总量与累计读取量为何按不同比例增长。再把 KV 位宽减半,哪些项随之减半?
练习 2-4〔延伸〕· KV 头共享与上下文压缩
把 Qwen3-8B 的 KV 头数从 8 改为 4(查询头仍 32),算 KV 容量、KV 投影参数量和查询—上下文交互运算的变化。再对 V4-Flash 的 CSA 层,把上下文从 8192 增到 16384,按压缩比 4、最多选 512 条,算保存条目数、索引扫描条目数和选中上限,解释三者为何不同比例增长。
练习 2-5〔核心〕· 上下文多长时,KV 容量超过固定状态
Qwen3.6:固定 61.875 MiB、每 token 20 KiB;Kimi K3 紧凑表示:递推 414 MiB、卷积 20,348,928 B、每 token 27 KiB。求两部分相等时的上下文长度,以及 32K、128K 的状态总量;若只有 256 MiB 预算,各能存多少 token?说明预算小于固定状态时为什么缩短上下文也放不下。
练习 2-6〔延伸〕· 专家数量与分派方式
Qwen3.6 一层,B=64、256 个专家、每 token 选 8 个。分别写出均匀与集中分派时各专家的 te,计算 FLOPs、访问的专家数与 BF16 权重读取量。再把专家数减半、中间维度加倍、选中数减半,判断总参数与实际专家运算是否变化。最后说明如何加入共享专家,以及潜空间专家进出潜空间的投影。
练习 2-7〔核心〕· 由显存容量决定可容纳请求数
RTX 4090 24 GB、工作区 2 GiB、Qwen3-8B BF16 精确权重,求 4K、8K、16K 下最多几条请求;8K 时工作区增到 3 GiB 再算。换成 70B 4-bit(39.500 GB)、RTX 6000 Ada 48 GB、预留 2 GiB,求 8K 与 32K 的请求数。
练习 2-8〔延伸〕· 前缀复用与输入改写
一轮输入共 1443 个 token,其中前 1392 个命中缓存,返回 128 个。求 S、P、G、nd、结束时的上下文长度和本轮新增 KV;相对完全重算,投影行数与有效因果配对数各减少多少?若第 501 个输入 token 被修改,重新求最长可复用前缀与新输入长度。
练习 2-9〔延伸〕· 根据容量、计算需求与任务质量选模型
用图 2-28 ~ 2-30 与表 2-C 列出每个模型的完整权重、8K 状态、单步 decode 与 8K prefill。部署在单张 80 GB H100 SXM、预留 2 GiB、BF16 权重,哪些能完整放进单卡?改为多卡部署时还需要后续章节的哪些时间与通信参数?把 G 改为 1,重算 prefill 与 decode 调用次数;为短语检索任务写出质量标准。