LLM 工程化全流程手册数据 → 预训练 → 后训练 → 对齐 → 评测 → 推理部署
🔍 /

LLM 工程化全流程手册

把大语言模型从数据到线上推理服务的完整工程链路,按流程顺序系统梳理成一份可离线阅读、可搜索、可打勾的学习地图。每个技术点都回答四个问题:它是什么 → 为什么存在 → 代价与取舍是什么 → 什么时候会踩坑。

版本 v1.1 | 更新 2026-10-04(第 9 章补入四条已逐条核对编号与摘要的一手文献;新增附录 A 故障排查手册)| 单文件离线文档,无外部依赖 | 配套:LLM 知识速查表(llm-cheatsheet.html)

怎么用这份文档:左侧目录可以勾选(勾选=已学,进度存在浏览器本地),顶部 / 键直接全文搜索,每个章节标题右侧可点 复制锚点,顶部可一键折叠全部 / 打印或导出 PDF。

0. 导读与全流程地图

0.1 这份文档针对什么问题

如果你已经用了两三年 LLM,日常在做训练和推理加速,那么真正缺的通常不是某个单点技术,而是把单点放到整条链路上的位置感。这种缺失会在两种时刻暴露出来:

  • 遇到新概念时无法归类:比如看到某个新项目"工作在 logits 这一层",你要先知道 logits 在整个前向计算里处于哪一步、它的形状和数值特性是什么、谁在消费它,才能判断这个项目到底新在哪。
  • 做技术选型时缺少约束意识:知道 KV Cache 能省显存,但不知道它和并发数、上下文长度、batch size 之间是乘法关系,于是容量规划全靠线上试错。

所以这份文档的组织原则是沿流程走,而不是按技术名词罗列。每个环节都回答同样的问题:

四问框架

1. 是什么

给出精确定义与它在数据流中的位置。定义不清是后面所有误解的源头。

四问框架

2. 为什么存在

它替代了什么?如果不用它,系统会在哪一步崩掉(显存、带宽、延迟、精度、成本)?

四问框架

3. 取舍是什么

任何优化都是拿一项换另一项。写清代价,才能判断在你的负载下值不值。

四问框架

4. 什么时候踩坑

列出已知的典型故障模式。这一节最有实战价值,也最容易被教程省略。

标记块约定。全文用左下角带色条的块来区分信息类型:
  • 概念(蓝)= 定义与定位,需要记住的硬事实。
  • 为什么需要它(绿)= 这个技术解决的真实痛点。
  • 取舍(紫)= 代价、边界、选型判据。
  • 常见坑(红)= 会导致事故或白干几天的问题。
  • 实例·算一遍(黄)= 用具体数字算一遍,把抽象公式落到显存与延迟上。
  • 索引(青)= 代表论文与工具,方便你顺藤摸瓜。

0.2 全流程地图:一张图看完

数据采集·清洗·去重·配比→ Tokenizer词表·特殊 token→ 预训练基座能力·并行训练→ 后训练SFT·偏好对齐·RLVR→ 对齐与安全拒答·护栏·可解释性→ 评测离线基准·线上 A/B→ 推理与部署KV Cache·量化·调度→ 服务与运营路由·成本·可观测

注意这条链是回环而不是直线:线上评测结果会反向决定后训练的数据配比,推理约束(比如必须支持 128K 上下文)会在预训练阶段就改变位置编码与注意力实现的选择。

阶段核心目标关键产出物主要技术典型失败模式
数据工程决定能力上限去重后的语料 + 配比方案 + 数据 schema抽取、去重(MinHash/LSH)、质量过滤、去污染、课程配比评测集泄漏导致指标虚高;重复数据导致逐字记忆
Tokenizer文本 ↔ id 的可逆映射词表文件 + merge 规则BPE / Unigram / 字节回退换 tokenizer 必须从头训练;压缩率差导致同样的钱只买到更少的有效 token
预训练获得通用基座能力Base checkpointScaling law 定规模、DP/TP/PP/EP 并行、bf16/fp8、重计算loss spike 直接毁掉几天训练;并行切分不当导致通信成为瓶颈
后训练从"会续写"到"听话有用"Instruct / 推理模型 checkpointSFT、LoRA、RLHF/PPO、DPO 家族、GRPO/RLVR、蒸馏灾难性遗忘;奖励黑客;过度拒答
对齐与安全行为可控、边界清晰安全策略 + 护栏 + 红队报告红队、输入输出过滤、拒答训练、可解释性探针把安全当成事后过滤,结果既损体验又挡不住真正的攻击
评测可比较、可决策的证据评测报告 + 回归门禁基准测试、pass@k、LLM-as-judge、线上 A/B用被污染的公开榜单做决策;评委模型有位置/长度偏置
推理与部署把能力变成可交付的延迟与成本推理服务 + 容量模型 + SLOKV Cache、PagedAttention、量化、投机解码、连续批处理、PD 分离只优化吞吐忽略尾延迟;量化后精度静默下降
用一个判断准则把整条链串起来:数据决定上限,训练决定能力,推理决定可用性与单位成本,评测决定你能不能知道前三条做对了没有。任何一环缺失,最后一个环节都会以一种难以定位的方式表现出来——比如"模型答得不好"可能根本不是模型问题,而是评测集的污染或推理时的采样参数。

0.3 三种读法,对应三种真实场景

速查

5 分钟:遇到新名词

先查配套的 llm-cheatsheet.html(术语表 + 公式卡)。找不到定义时,用顶部搜索在本文件里定位,读该节的概念块和常见坑块即可。

精读

每章 30–45 分钟:建立结构

按第 1 → 8 章顺序读。第 1、2 章是地基(一次前向到底发生了什么、logits 到底是什么),值得反复读。

刷新

按需:知识保鲜

直接跳到第 10 章的更新日志与待核实清单,只看变化的部分和标注"快速演进"的技术。

另外,每一章末尾都有自查清单(第 10 章汇总)。如果你能不看文档答出来,说明这一章可以打勾了;答不出来,说明只是"眼熟"而不是"掌握"。

0.4 四周刷新计划

周目标读什么动手做什么
第 1 周重建地基层第 1 章(形状流)+ 第 2 章(Logits 专章)用 transformers 打印一次前向的逐层形状;对同一 prompt 打印 top-20 logits 与 softmax 概率,观察温度如何改变排序
第 2 周训练侧全景第 3–5 章(数据 / 预训练 / 后训练)估算一次 7B 全参训练的显存账单;跑一次 LoRA 微调并对比合并前后输出差异
第 3 周评估与对齐第 6–7 章(安全 / 评测)用 lm-evaluation-harness 跑一个小模型的两个基准;写一个带位置交换的成对 judge 脚本,观察偏差
第 4 周推理与前沿第 8–9 章(推理部署 / Jev 专题)算一遍 KV Cache 容量表(并发 × 上下文);对比开启/关闭投机解码的 TPOT

0.5 版本与更新日志

版本日期变更
v1.02026-10-04首版:第 0–10 章全部建立;Logits 独立成章;新增"Jev 与从 logits 读决策"专题(第 9 章),按证据等级分栏;配套速查表文件。
v1.12026-10-04第 9 章补入四条已逐条核对 arXiv 编号与摘要的一手文献(早期证据审计、AnyJev、LLM2Jev、Decision Hijacking),并据此改写 9.3 / 9.5 / 9.6 / 9.8;新增附录 A · 故障排查手册(症状 → 原因 → 处置,覆盖训练/后训练/推理服务/评测四类)。
关于时效性的诚实声明。本文档中标注为稳定共识的部分(如 Attention 形状、KV Cache 显存公式、DPO 的损失构造)可以放心当作长期知识;标注为快速演进的部分(推理框架特性、Agent 接口、决策模型类产品)在半年级别就可能过时。第 9 章的 Jev 专题尤其如此:它写于该产品发布后约三周,其中相当一部分数字是厂商自评,已在正文中逐条标注来源等级。

1. 地基:一次前向到底发生了什么

这一章的目标只有一个:让你能在脑子里把「一段文本」变成「下一个 token 的概率分布」的完整过程走一遍,并且知道每一步的张量形状。后面所有章节(Logits、量化、KV Cache、投机解码、Jev)都是在这条链上做文章——不知道链在哪,就不知道别人改的是哪一环。

本章结构
  1. 1.1 全景:五个阶段
  2. 1.2 Tokenizer:文本到 id
  3. 1.3 Embedding 与位置编码
  4. 1.4 Transformer block 内部
  5. 1.5 从 hidden state 到 logits
  6. 1.6 从 logits 到下一个 token
  7. 1.7 训练目标与 loss
  8. 1.8 形状与数字总表

1.1 全景:五个阶段

① 分词文本 → token id→ ② 嵌入id → 向量→ ③ 堆叠层向量 → 上下文向量→ ④ 输出投影向量 → logits→ ⑤ 采样logits → token

其中 ① 由 tokenizer 在 CPU 上完成,②③④ 是模型的张量计算(GPU),⑤ 是一段很小的确定性/随机性数学运算加控制逻辑。工程上绝大部分优化发生在 ③④ 与"如何重复 ①–⑤ 而不重复计算"。

自回归生成的关键事实:模型一次前向只产出最后一个位置的下一 token 分布,然后把这个 token 拼回输入,再跑一次前向。看起来是"逐 token 重复整个前向",实际工程上靠 KV Cache 把历史部分缓存起来,让第 t 步只计算最新的一个 token(第 8 章详述)。这是"看起来 O(n²) 实际可做到近似 O(n)"的根本原因。

1.2 Tokenizer:文本到 id

是什么。Tokenizer 把字符串映射为整数 id 序列,粒度介于"字符"与"词"之间,单位叫 token(子词 / subword)。主流算法是 BPE(字节级、从字符开始反复合并最高频相邻对)、Unigram(从大词表开始按概率剪枝)、以及 WordPiece(BERT 系)。现代 LLM 几乎都是字节级 BPE + 字节回退:任何 UTF-8 字节序列都能编码,不会出现 UNK。

关键认识:tokenizer 是模型的一部分,不是预处理工具。词表一旦确定,模型的输入输出空间就固定了,换 tokenizer 等于换模型,必须从头训练。

取舍

词表大小

大词表(128K–256K):同样文本的 token 数更少 → 上下文更"能装"、同样的钱买到更多内容;但 embedding 与 lm_head 参数量随 V 线性增长,softmax 也更贵。
小词表(32K):参数省、softmax 便宜,但序列变长、稀有词被切碎。
经验区间:英文为主 32K–64K,多语言/代码 100K–256K。

细节

特殊 token

BOS / EOS / PAD 之外,现代模型大量使用对话与工具标记(角色、轮次、工具调用边界、思考块边界)。这些是训练与推理的协议:推理时模板打错,模型表现会明显下降,这一点比换采样参数重要得多。

常见坑。
  • 把 token 数当字数。中文在多数词表下 1 个汉字 ≈ 1–2 个 token,英文 1 个词 ≈ 1.3 个 token,代码和 JSON 的压缩率差异更大。算成本、算上下文、算 KV Cache 都必须用 token 数。
  • 训练与推理用了不同版本的 tokenizer 或 chat template。表现为"模型不听话""不会停止""格式错乱",但模型本身没问题。这类 bug 极难从输出上定位,务必把 template 与 tokenizer 版本固化进部署配置。
  • 手动拼接 prompt 字符串。应该用官方 apply_chat_template 之类的接口,否则特殊 token 会被当普通文本编码,等于给模型喂了错误协议。
  • tokenizer 的并行/分片不一致导致同一条数据在数据加载的多个 worker 里编码结果不同(罕见但真实,尤其是自研 tokenizer 时的多线程 BPE)。

1.3 Embedding 与位置编码

token id 通过一个查表矩阵 E ∈ R^{V×d} 变成 d 维向量,得到 [B, S, d] 的初始表示。位置信息不能靠这个查表获得(查表与顺序无关),必须显式注入。

方案做法优点局限
绝对位置嵌入第 i 个位置查一个可学习向量,加到词嵌入上简单外推差,超过训练长度直接失效
正弦位置编码固定三角函数(原始 Transformer)无需训练被 RoPE 取代
RoPE(主流)对 Q、K 向量按成对维度旋转,旋转角与位置成正比内积天然只依赖相对位置;可通过改旋转基频/插值外推外推仍需专门处理;实现细节(cos/sin 缓存、交错方式)容易出错
ALiBi给注意力分数加与距离成线性的负偏置外推直观现代主流模型少用
RoPE 的工程含义。实现上是把 head_dim 维向量两两配对当作二维平面上的点做旋转,旋转角 θ_i = base^{-2i/d} 再乘以位置 m。两个词的内积因此只与它们的相对距离有关。长上下文扩展的本质就是改这个 base 或对位置做插值(位置插值 PI、NTK-aware、YaRN),具体见第 4.8 节。

1.4 Transformer block 内部

现代 LLM 基本都是 Pre-Norm 的 decoder-only 结构,一个 block 两步:

# Pre-Norm 残差结构(伪代码,L 层重复)
h = x + Attention(RMSNorm(x))     # 注意力:让 token 之间交换信息
y = h + FFN(RMSNorm(h))           # 前馈:逐 token 做非线性变换(承载大部分参数)
# 全部 L 层结束后:
h_final = RMSNorm(y)              # 最后的 norm 不能省
logits  = h_final @ E_out.T       # E_out ∈ R^{V×d},即 lm_head
组件

RMSNorm

只做缩放不做均值中心化,比 LayerNorm 便宜。放在子层之前(Pre-Norm)使深层残差通路干净、训练更稳;代价是最终必须补一个 norm。

组件

SwiGLU FFN

三个矩阵 W_gate, W_up, W_down,FFN(x)=W_down(SiLU(W_gate x) ⊙ W_up x)。为保持参数量与经典 4d² FFN 相当,取 d_ff ≈ 8d/3(常见再取 128 的倍数)。

组件

注意力与 KV 头数

MHA:Q/K/V 头数相同。MQA:所有 Q 头共享 1 组 KV。GQA:Q 头分组共享 KV 头(现代默认)。KV 头数直接决定 KV Cache 大小与解码时的显存带宽压力。

组件

因果掩码

上三角置 −∞,保证第 i 个位置只能看到 ≤ i 的内容。这是"decoder-only 能拿来做训练"的前提,也是推理时 KV Cache 能成立的前提。

为什么 GQA 几乎成了标配。解码阶段是显存带宽受限的:每生成一个 token,都要把整个 KV Cache 从显存读一遍。KV 头数从 n_heads 降到 n_kv_heads,KV Cache 与读取量就按同比例下降。以 32 个 Q 头、8 个 KV 头为例,KV Cache 直接变成原来的 1/4,而质量损失很小。MQA 是 n_kv_heads=1 的极端情形,省得更多但质量风险更大。

注意力的形状(以 Llama-3-8B 量级为例:d=4096, n_heads=32, n_kv_heads=8, head_dim=128):

输入     x        : [B, S, 4096]
Q 投影            : [B, S, 32, 128]     # n_heads    × head_dim
K, V 投影         : [B, S,  8, 128]     # n_kv_heads × head_dim  ← GQA
注意力分数        : [B, 32, S, S]       # 因果掩码后上三角为 -inf
注意力输出        : [B, S, 4096]        # concat 所有头后过 W_o

1.5 从 hidden state 到 logits

最后一层输出经过最终 RMSNorm,再乘输出投影矩阵(lm_head),得到整个词表上每个 token 的分数,这就是 logits:

hidden : [B, S, d]
lm_head: [V, d]
logits : [B, S, V]        # 例如 [1, 8192, 128256]
logits 的定义(这一句值得记住)。logits 是未经归一化的实数分数向量,是模型对"下一个 token 是谁"这件事的全部原始意见;只有经过 softmax 它才变成概率。它是连续量、可正可负、没有上下界(部分模型会显式加软上限,见下),因此不同模型、不同 prompt 之间的 logits 绝对值不可直接比较,可比较的是同一组 logits 内部的相对关系与 softmax 后的概率。第 2 章整章展开。
实现细节

权重共享(tied embedding)

让 lm_head = E(输入嵌入矩阵)可以省下 V×d 参数。以 V=128256, d=4096 计约 5.25 亿参数,对中小模型是不小的一块。Gemma 等模型默认共享,很多大模型不共享(表达能力更强)。

实现细节

只需要最后一个位置

生成时只需要 logits[:, -1, :],形状 [B, 1, V]。但朴素实现会把 [B, S, V] 全算出来——这在小 batch、长上下文时是纯浪费。第 2.6 节的"稀疏输出投影"正是针对这一点。

常见坑:logits 的数值范围与软上限。
  • logits 会很大。训练充分后,正确 token 的 logit 可以是几十甚至上百。用低精度存 logits(bf16 只有约 3 位十进制有效数字)时,接近的两个候选会被压成同一个值,导致 top-1/top-2 排序抖动。需要精确比较时,softmax 与比较都要在 fp32 里做。
  • 有的模型显式限制 logits。例如 Gemma 2 用 logit soft-capping(logits = cap * tanh(logits / cap),cap 常取 30)来抑制极端值、稳定训练。这意味着它的 logits 天然被压在 [−30, 30],直接和别的模型比数值大小没有意义。
  • 训练里还有 z-loss。PaLM 等用 z_loss = coef * logsumexp(logits)² 惩罚配分函数偏离 0,防止 logits 整体漂移导致数值不稳。看到 loss 里有 z-loss 项不要当它是笔误。

1.6 从 logits 到下一个 token

这一步在工程上被实现成一条固定的流水线,顺序很重要(HuggingFace 系框架的命名可以一一对应):

logits
  → ① LogitsProcessor 链   重复惩罚 / 频率惩罚 / 存在惩罚 / logit bias /
                           禁止词 / 最小长度 / 约束解码(语法、正则、JSON schema)
  → ② LogitsWarper 链      温度缩放 → top-k → top-p → min-p → typical
  → ③ Sampler             greedy(argmax) / multinomial(按概率采样) / beam search
  → 下一个 token id
参数对 logits 做什么典型值什么时候用 / 代价
temperaturelogits / T,T<1 拉大差距、T>1 压平0(贪心)~1.0事实性任务用低温;T 会改变概率数值,所以 logprob 不可跨温度比较
top_k只保留最大的 k 个,其余置 −∞20–100简单粗暴;k 固定,分布宽窄不同时表现不稳
top_p(核采样)按概率降序累加,累计超过 p 就截断0.9–0.95自适应候选集大小;与 top_k 可叠加
min_p保留概率 ≥ min_p × p_max 的候选0.02–0.1比 top_p 更不依赖分布形状,近年流行
repetition_penalty对已出现 token 的 logit 除以惩罚系数(正负号分别处理)1.0–1.15抑制复读;会破坏概率语义,不适合需要 logprob 的场景
logit_bias对指定 token 的 logit 加性干预按需强制或禁止某些 token;是"改写分布",与"事后重归一化"不同(见第 9 章对比表)
约束解码按语法/正则/Schema 把非法 token 置 −∞—保证输出可解析;有每步掩码开销,复杂语法会拖慢解码
取舍:为什么"复现别人的结果"经常失败。同一个 checkpoint,只要 temperature/top_p/惩罚项/框架默认值不同,输出分布就不同。要复现,必须固定完整的采样配置(包括 seed、框架版本、是否用 flash attention 这类会带来微小数值差异的算子)。反过来说,报告任何生成结果时都应该附带采样配置,否则不可比。

1.7 训练目标与 loss

预训练目标就是下一 token 预测:把输入右移一位当标签,对每个位置计算交叉熵。工程上有三个必须知道的细节:

  • shift by one。logits[:, :-1] 与 labels[:, 1:] 对齐。差一位的 off-by-one 是自研训练脚本最经典的 bug,表现为 loss 能降但模型很笨。
  • loss mask。SFT 时只在"助手该说的话"上计算 loss,用户输入与 padding 位置的标签置为忽略值(通常 −100)。掩码错了,模型会学会模仿用户口吻。
  • 与困惑度的关系。PPL = exp(平均交叉熵)。loss=2.0 对应 PPL≈7.4;loss=1.0 对应 PPL≈2.7。PPL 只在同一 tokenizer下可比——换词表后 PPL 数字直接失去意义。
算一遍:训练时的 logits 显存有多吓人。取 B=1, S=8192, V=128256,logits 用 fp32 存:
8192 × 128256 × 4 B ≈ 4.2 GB——仅仅是一个样本的 logits。加上反传需要的梯度与 softmax 中间量,轻松翻倍到 8 GB 以上。
这就是为什么大模型训练常用分块计算交叉熵(把 S 维切块)、词表并行(把 V 维切到多卡)或只对需要的位置计算 logits。也解释了为什么 SFT 的 packing 长度不能随便调到 32K 以上。

1.8 形状与数字总表

以下以 Llama-3-8B 量级的配置为参照(L=32, d=4096, n_heads=32, n_kv_heads=8, head_dim=128, d_ff=14336, V=128256):

对象形状 / 数值说明
嵌入矩阵 E[128256, 4096] ≈ 5.25 亿参数bf16 下约 1.0 GB
每层注意力参数W_q: d×d、W_k,W_v: d×(n_kv·head_dim)、W_o: d×dGQA 让 K/V 投影变成 1/4
每层 FFN 参数3 × d × d_ff = 3×4096×14336 ≈ 1.76 亿占总参数约 2/3
解码时每步的注意力分数[B, n_heads, 1, S_total]对 KV Cache 做一次读取
单 token 的 KV Cache2 × n_kv × head_dim × L × 2 B = 128 KiBbf16;全 MHA 则为 512 KiB(4 倍)
128K 上下文的 KV Cache131072 × 128 KiB ≈ 16 GiB单条序列!这就是长上下文服务贵的根本原因
前向 FLOPs 近似约 2 × 参数量 × token 数解码时几乎全是"读权重",所以是带宽受限
8B 模型 bf16 权重约 16 GB加 KV Cache 与激活,单卡 24 GB 已很紧张
索引。
  • 原始架构:Attention Is All You Need(2017)|RoFormer(RoPE)|GLU Variants Improve Transformer(SwiGLU)|Root Mean Square Layer Normalization
  • 分组注意力:GQA: Training Generalized Multi-Query Transformer Models(GQA)|Fast Transformer Decoding: One Write-Head is All You Need(MQA)
  • 训练稳定化:Gemma 2(logit soft-capping)|PaLM(z-loss)
  • 动手工具:transformers(output_hidden_states / output_logits)、torch.nn.functional、einops 用于核对形状
本章自查。不看文档回答:① 为什么 GQA 能把 KV Cache 降到 1/4?② bf16 存 logits 会带来什么问题,为什么要在 fp32 里做 softmax?③ 训练时 B=1,S=8192,V=128k 的 logits 占多少显存?④ 采样流水线中"重复惩罚"和"约束解码"都作用在 logits 上,为什么前者不该和 logprob 一起用?

2. Logits 专章:模型的原始意见与它的消费方

这一章回答一个具体问题:当有人说"我的工作发生在 logits 这一层"时,他到底站在流水线的哪个位置,改的是什么,为什么这件事有价值。同时把 logits 相关的一堆容易混淆的名词(logprobs、logit bias、约束解码、分类头、logit lens、softmax 校准)摆到同一张图里区分清楚。

本章结构
  1. 2.1 严格定义:logit 为什么叫 logit
  2. 2.2 形状、内存与"到底要算几个 logit"
  3. 2.3 消费方一:训练时的 logits
  4. 2.4 消费方二:推理时的 logits
  5. 2.5 消费方三:把 logits 当接口(六种用法)
  6. 2.6 数值工程:精度、稳定性、稀疏投影
  7. 2.7 语义陷阱:什么时候 logprob 不再等于概率
  8. 2.8 校准:为什么"置信度"不能当"正确率"
  9. 2.9 常见坑与索引

2.1 严格定义:logit 为什么叫 logit

定义。对一个 V 类分类器,最后一层线性输出的第 i 个分量 z_i ∈ R 就叫第 i 类的 logit。它未经归一化、可正可负、无上下界。通过 softmax 变成概率:
p_i = exp(z_i) / Σ_j exp(z_j)
名字来源于二分类的 log-odds:z = ln(p / (1−p)),即"概率的比值再取对数"。多分类里它退化成"相对分数的对数"。

三个必须内化的性质,它们解释了后面 90% 的工程细节:

性质 1

平移不变

所有 logit 同时加一个常数 c,softmax 结果完全不变。所以logit 的绝对值本身没有意义,只有两两之差有意义。跨模型、跨 prompt 比较 logit 大小是无效操作。

性质 2

尺度敏感

所有 logit 同时乘 k 会显著改变分布形状。temperature 做的就是这件事(z/T)。所以温度不是"风格旋钮",它改变了数值语义。

性质 3

差值即概率比

z_i − z_j = ln(p_i / p_j)。一个 2.3 的差值意味着 10 倍概率差,4.6 意味着 100 倍。判断"模型有多确定"时看差值比看绝对值有用得多。

算一遍:温度到底改变了什么。假设某个位置的 top-4 logits 是 好=18.2, 不错=15.7, 很=14.1, 糟=9.3:
候选logitT=1.0 概率T=0.5 概率
好18.291.0%99.3%
不错15.77.47%0.669%
很14.11.51%0.027%
糟9.30.0124%0.0000018%
把 91% 变成 99.3%,logits 一个都没变。所以任何"报告模型置信度"的接口都必须同时声明温度与是否做过归一化,否则数字不可比。

2.2 形状、内存与"到底要算几个 logit"

logits = hidden_final @ lm_head.T
hidden_final : [B, S, d]
lm_head      : [V, d]
logits       : [B, S, V]     ← 三维张量,V 通常在 32k ~ 256k

关键在于 V 很大而 B×S 也不小,两者相乘会爆掉。于是有了"到底需要哪些位置的 logit"这个问题,而回答它正是很多优化的切入点:

场景真正需要的 logit朴素实现的开销优化手段
训练(预训练/SFT)所有非掩码位置 × 全词表B×S×V×4B,例:1×8192×128256×4 ≈ 4.2 GB分块交叉熵、词表并行、只算非掩码位置
标准解码[B, 1, V](最后一个位置)把 [B, S, V] 全算出来是纯浪费只取最后位置;缓存复用
打分/排序(PPL、rerank)指定位置的、指定候选 token 的 logit同上稀疏投影:只算候选行
结构化槽位读取(Jev 类)若干固定槽位 × 若干候选标签扩散画布 4096×128256 fp32 ≈ 2.1 GB稀疏输出投影:只算 槽位数 × 候选数
可解释性(logit lens)各中间层 × 指定位置 × top-k每层都要投影一次只对目标位置、只取 top-k
算一遍:稀疏输出投影省了多少。某扩散模型画布宽度 4096、V=128256,若一次请求 64 个问题、每题最多 26 个候选:
  • 稠密:4096 × 128256 × 4 B ≈ 2.1 GB(仅 logits,还没算 softmax 中间量),加上投影 GEMM 的算力。
  • 稀疏:64 × 26 = 1664 行输出,约 1664 × 4096 × 2 ≈ 1.4e7 FLOPs 与 1664 × 4 B ≈ 6.6 KB。
  • 差距在 5–6 个数量级。
这就是"只读、不生成"这类接口在工程上真正吃得开的地方:它把一个 O(画布 × 词表) 的问题压成了 O(候选数)。

2.3 消费方一:训练时的 logits

训练时 logits 只有一个消费方:交叉熵损失。但围绕它有一串工程细节。

梯度形式很漂亮。对 softmax + 交叉熵的组合,logit 的梯度就是 ∂L/∂z_i = p_i − y_i(y 是 one-hot 标签)。含义直观:模型把概率分给谁,就把谁的 logit 往反方向推多少。正确 token 的 logit 会被推高,错误 token 按它当前拿到的概率被推低。这也是"logits 蒸馏"能工作的原因:教师模型的完整分布 p_teacher 可以直接作为软标签,梯度就是 p_student − p_teacher。
技术对 logits 做什么解决什么问题出现位置
logit soft-cappingz ← cap · tanh(z / cap),cap≈30抑制极端 logit,稳定训练Gemma 2 等
z-loss惩罚 logsumexp(z)²防止 logits 整体漂移导致数值不稳PaLM 等
标签平滑目标分布从 one-hot 变成 (1−ε)·one-hot + ε/V减少过度自信(直接影响校准)较早期工作
logits 蒸馏用 KL(p_teacher^T ‖ p_student^T),配温度 T让学生学到"类间相似性",比只学硬标签信息量大得多蒸馏、小模型训练
词表并行 CE把 V 切到多卡,各算部分 logits 后 all-reduce解决 4.2 GB 级 logits 显存Megatron 等
训练侧的常见坑。
  • 忽略值写错。框架用 ignore_index=−100(不是 0)。填 0 会让模型去学预测 id 为 0 的 token,loss 看起来在降但模型学坏了。
  • shift 与 mask 顺序颠倒。正确顺序是:先算 loss(框架内部 shift),mask 必须构造在标签那一侧。
  • softmax 用 bf16。大 logits 在 bf16 下 exp 会溢出或精度坍缩。标准做法是先减去该位置的最大 logit,再在 fp32 里算。
  • 把 soft-cap 或 z-loss 当成可选项随意删。这些项是跟特定模型训练配方绑定的,去掉后重训会不稳定;加了它再去对比不同模型的 logits 数值也不可比。

2.4 消费方二:推理时的 logits

推理时 logits 的消费方比训练多得多,而且每一个都对应一个你可能用过的开关:

消费方

① 采样器

argmax(贪心)或按概率采样。temperature / top-k / top-p / min-p 全部在这一步之前改写 logits。

消费方

② logprobs 接口

OpenAI 系 API 的 logprobs / top_logprobs 就是把这一层的数值暴露给调用方,用于分类、打分、置信度估计、构造确定性规则。

消费方

③ 约束解码

按 JSON Schema、正则、语法把非法 token 的 logit 置 −∞,保证输出一定可解析。

消费方

④ 干预类处理器

重复惩罚、频率/存在惩罚、logit bias、禁止词表。注意它们改写了分布,之后算出的"概率"已不是模型原始意见。

消费方

⑤ 投机解码的验证

用目标模型的 logits 对草稿 token 做接受/拒绝判定,需要精确比较两个分布(第 8.6 节)。

消费方

⑥ 结构性读取

不做生成,只在固定槽位读候选标签的概率——即第 9 章的 Jev 类接口。这是本文档把 logits 单独成章的直接原因。

取舍:暴露 logprobs 的代价。把完整 logprob 分布返回给调用方,意味着(1) 每步都要在 fp32 里做 softmax 并排序,有额外开销;(2) 返回体变大,网络与序列化成本上升;(3) 安全含义——logprobs 可以被用来做蒸馏(拿到教师分布)、也可以被用来做更精细的越狱探测。因此很多厂商只返回 top-k 的 logprob(如 top-5),或对某些模型干脆不开放。

2.5 消费方三:把 logits 当接口(六种用法)

把"生成一段文本"变成"读一个分布",是近年来很活跃的一条工程路线。下面六种用法常被混为一谈,请注意区分改的是什么、需不需要训练、有没有重新归一化。

用法怎么读要不要训练典型用途
A. 单 token 槽位读取
(最简约束解码)
把答案位置留成一个 token 的槽,取该位置 next-token 分布,重归一化到候选标签集合不需要,但校准需要分类、是/否判定、多选、打分(第 9 章 Jev 类)
B. 候选序列打分把每个候选拼成完整文本,取目标 token 的 logprob 求和,按长度归一化(或取平均)不需要rerank、PPL 打分、可验证答案的排序
C. 分类头读出在 hidden state 上接一个专门训练的线性头(或 MLP)需要固定标签集的判别任务;对照实验显示在匹配主干/数据/预算时并不优于直接用 lm_head 读出
D. logit lens / 中间层探针把中间层的 hidden state 直接过最终 lm_head,看"模型在第 k 层想说什么"不需要(探针本身可能要)可解释性,不是产品接口。与 A 用法无关,别混写
E. 嵌入相似度在嵌入空间做最近邻,不经过 lm_head不需要检索、聚类、部分零样本分类
F. logit 级蒸馏把教师模型的完整 logits/概率当监督信号需要(训练学生)小模型压缩、领域适配
三个最常被写错的区分。
  • logit bias ≠ 受限 softmax。前者是加性干预(z_i ← z_i + b_i),改变候选之间的相对关系;后者是事后重归一化(不改相对关系,但会放大数值、让"概率"更极端)。两者经常被同一篇文章混着说。
  • constrained decoding ≠ 只读不生成。约束解码保证格式合法,但仍然逐 token 生成,仍有完整的解码循环、语法状态机开销与失败重试路径。只读接口是一次前向、零生成。
  • logit lens 与投机解码和"读决策"都无关。前者是可视化工具,后者是加速技术。
为什么"读分布"比"生成文本"更省。生成路径上每一步都要付出:前向计算 → softmax → 采样 → 拼回输入 → 下一轮;外加格式化风险(模型写出非法 JSON)、解析失败、重试。读分布路径把这些全砍掉了,只剩下一次前向 + 取若干行 logits。
但代价是表达力被严格限制:候选必须是预先枚举好的、通常必须是单 token 的、问题之间一般不能有依赖。这是一次非常清晰的"用表达力换延迟与确定性"的交易。

2.6 数值工程:精度、稳定性、稀疏投影

数值

softmax 必须减最大值

softmax(z) = softmax(z − max(z)),且要在 fp32 里算。bf16 下 exp(88) 就溢出,而训练充分的模型 logits 上百很常见。

数值

用 logsumexp 代替 exp

需要 log 概率时用 log_softmax(内部 logsumexp),比"softmax 再取 log"稳定得多。

性能

只算需要的行

稀疏输出投影:输出头只对请求的候选 label 行做 GEMM。省显存(少分配 [B,S,V])也省算力。

性能

只算最后位置

标准解码只需 logits[:, -1, :]。很多朴素实现把整个序列都投影,白白多算 S 倍。

算一遍:lm_head 到底占多少。8B 模型解码一个 token 的总前向约 2 × 8e9 = 16 GFLOPs;lm_head 是 2 × V × d = 2 × 128256 × 4096 ≈ 1.05 GFLOPs,约占 6%。
结论有两面:(1) 在标准解码里稀疏投影省下的算力有限,省的主要是显存分配与带宽;(2) 但在"画布/序列很宽、只需少数位置"的场景(扩散模型、长上下文打分),稠密投影会从 6% 变成主要瓶颈,稀疏化收益就是数量级的。

2.7 语义陷阱:什么时候 logprob 不再等于概率

下面这些操作都会让"logprob"失去"模型原始概率"的含义。把它们记成一张清单,比记住任何公式都有用。

操作怎么破坏语义后果
temperature ≠ 1z/T 改变分布形状概率数值被系统性放大/压平;跨温度不可比
top-k / top-p / min-p截断后剩余项通常被重新归一化返回的 top-1 概率被人为抬高;"模型 99% 确定"可能是截断造出来的
重复/频率/存在惩罚直接改写 logits已出现 token 的概率被压低,与模型真实意见不符
logit bias / 禁止词加性干预同上,且是人为指定的
约束解码掩码非法 token 置 −∞ 后重归一化概率质量被强行搬到合法集合里
bf16 logits有效精度约 3 位十进制接近的候选可能被压成同值,排序抖动
logit soft-capping非线性压缩极值高置信区间的数值被严重压缩,不可与外模型比较
实践规则:要"概率语义",就把干预全部关掉。如果你要用 logprob 做分类、阈值判定或校准,配置应当是:temperature=1、top_k=0(不截断)、top_p=1、无惩罚、无 bias、无约束掩码,并只在 fp32 下比较。
反之,如果你只是想要"输出好看",那把干预全开也没关系——但此时不要再用这些数字去做任何阈值决策。最常见的生产事故就是这样来的:用一个被 top-p 截断+重复惩罚改过的"概率 0.97"去当 97% 准确的置信度。

2.8 校准:为什么"置信度"不能当"正确率"

校准(calibration)的定义。一个模型是校准的,指的是:在它给出"置信度 0.8"的所有样本里,实际正确率大约就是 80%。用可靠性图(reliability diagram)与 ECE(Expected Calibration Error,把置信度分桶后算 |准确率 − 平均置信度| 的加权和)来度量。

现代 LLM 的原始概率通常不是校准的:经过 RLHF/偏好对齐后往往过度自信(RLHF 会系统性推高被选答案的 logprob),而经过蒸馏或强标签平滑的模型可能偏保守。因此:

  • 置信度 ≠ 正确率,除非你在自己的留出集上验证过。
  • 阈值必须在自己的数据上定。不要用别人博客里的 0.9。
  • 温度缩放是成本最低的校准手段:在验证集上拟合一个标量 T(不重训模型),再用于概率输出。它不改变 top-1 排序,只让数值更接近真实正确率。
  • 若要做"拒绝/升级"(reject option、模型级联),校准质量直接决定系统收益——这是第 9 章 Jev 类接口最关键的工程前提。

2.9 常见坑与索引

logits 相关的高频事故清单。
  1. 用截断后的概率当校准概率(见 2.7)。
  2. 把 batch 里不同样本的 logits 混着归一化:必须每个位置独立 softmax。写错维度(对 [B,S,V] 在错误的轴上 softmax)会产生"看不出来但完全错"的结果。
  3. padding 位置的 logits 参与了任何统计:打分、平均 logprob、置信度都必须先按 attention mask / loss mask 过滤。
  4. 长度归一化算错:比较不同长度候选时,用"平均 logprob"而不是"求和"。求和会让短候选系统性占优。
  5. 在多轮对话里对整段算 logprob:模型对"用户说的话"也有概率,这部分与"助手答得好不好"无关,必须只取助手段。
  6. 把 logit lens 的中间层结果当模型最终判断:中间层表示没经过最终 norm 与后续层变换,早期层基本是噪声。
  7. 假设同一 prompt 的 logits 可复现:不同 kernel(FlashAttention 变体)、不同精度、不同 batch 组成都会带来微小差异,进而改变接近候选的排序。
索引。
  • logit lens 与可解释性:Interpreting GPT: the Logit Lens(2020)|Eliciting Latent Predictions from Transformers with the Tuned Lens
  • 知识探针与事实性:Language Models (Mostly) Know What They Know(自评置信度)|Calibration of Neural Networks 综述(温度缩放、ECE)
  • 约束解码:Grammar-Constrained Decoding|outlines、guidance、lm-format-enforcer、xgrammar(vLLM 内)
  • 打分/rerank:monoT5|Qwen3-Reranker(yes/no logit 读出)
  • 蒸馏:Distilling the Knowledge in a Neural Network(软标签与温度)|MiniLLM(反向 KL)
  • 动手:transformers 的 output_logits、return_dict_in_generate、scores;torch.log_softmax;OpenAI/本地推理的 top_logprobs
本章自查。① 为什么 logit 的绝对值不可跨模型比较,但差值可以?② 温度 0.5 把 91% 变成 99.3%,logits 变了吗?这对"报告置信度"意味着什么?③ 稀疏输出投影在什么场景下收益是数量级的,在什么场景下只是一点点?④ 列出至少四种会让 logprob 失去概率语义的配置。⑤ logit lens 和"把 logits 当接口"的区别是什么?

3. 数据工程:决定上限的那一环

在预训练里,数据配方是比架构更重要的变量。同一个架构、同样的算力,数据质量与配比不同,最终能力可以差出一个代际。这一章按"从原始网页到可训练样本"的处理链路走。

采集抓取·授权→ 抽取正文·代码·公式→ 清洗规则·模板去除→ 去重精确·近似·语义→ 质量过滤启发式·分类器→ 去污染对齐评测集→ 配比领域权重·课程→ 打包tokenize·shuffle

3.1 数据来源与它们的特性

来源规模量级独特价值主要问题
网页抓取(Common Crawl 等)PB 级、数十万亿 token覆盖面最广,是通识与语言能力的底座噪声极高,需激进过滤;质量分布长尾
代码(GitHub 等)万亿 token 级显著提升推理与结构化能力,远不止"会写代码"许可证与合规;重复率高;测试文件噪声
书籍与论文千亿 token 级长程连贯性、深度论述版权最敏感;需要长文档处理
百科与结构化知识百亿 token 级事实密度高、格式规范风格单一,重复喂会导致语气僵化
数学与形式化(含合成)百亿~千亿推理能力的关键来源合成数据的分布偏差与自洽性风险
多语言语料按语种差异极大跨语言迁移低资源语种容易被"遗忘",需主动加权
合成数据(强模型生成)可控补齐稀缺能力(长链推理、特定格式、指令遵循)模型崩塌风险:递归自训练导致分布退化
"数据配比"是一个需要被显式管理的超参数。领域权重(网页 : 代码 : 数学 : 多语言 …)通常写成一张配方表随训练阶段变化。经验规律:训练后期做"退火"(annealing)时提高高质量数据与指令型数据的权重,收益远高于同等算力下调整架构。

3.2 抽取与清洗

  • 正文抽取:从 HTML 里剥掉导航、广告、页脚。工具如 trafilatura、Readability 系算法。抽取质量差会直接引入"模板噪声",让模型学会输出网页残渣。
  • 规则清洗:去 control 字符、统一 Unicode(NFKC)、修 HTML 实体、剔除超短/超长/符号占比异常的行。
  • 模板与样板去除:同一模板在大量页面重复出现(如"点击这里订阅"),会污染语言模型分布。按行/按段落跨文档计数是常用的做法。
  • PII 与合规:邮箱、电话、身份证等敏感串的识别与脱敏;robots 与许可证合规记录。

3.3 去重:三档强度

精确

哈希去重

文档级 SHA-256。只能去除逐字节相同的副本,成本最低。

近似

MinHash + LSH

按 n-gram 集合算 MinHash 签名(常 128–256 个哈希、5-gram),用 LSH 分桶找近似重复对,再按 Jaccard 阈值(如 0.8)判重。工业界主力。

语义

SemDedup 类

用嵌入做聚类去重,能抓到改写/翻译级重复,但成本高、阈值更难定,且可能误删有价值的长尾表达。

为什么去重是"性价比最高的数据操作"。
  • 省算力:重复数据等于白烧 GPU。
  • 防记忆:高频重复片段会被逐字记住,既是隐私/版权风险,也直接损害泛化。
  • 抑制退化:重复会放大分布尖峰,让模型更容易复读、更容易在采样时陷入循环。
  • 保护评测:很多"能力提升"其实是训练集里混进了评测题的原题。

3.4 质量过滤:从启发式到分类器

手段判据优点 / 风险
启发式规则平均词长、符号/数字占比、重复行比例、停用词比例、是否含 "lorem ipsum"极便宜、可解释;但会系统性删掉代码、表格、非拉丁语种
分类器打分fastText / 小 Transformer 判"是否像 Wikipedia 或教科书"效果强;会引入风格偏置,把整个语料往百科腔推
教育价值打分用强模型给样本打"对学习有用程度"分质量最高;成本高、依赖教师模型、可能引入教师偏见
困惑度过滤用参考模型算 PPL,剔除极端高/低能滤掉乱码;但会删掉稀有但正确的专业内容
过滤器的典型副作用(很值得记住)。过滤器按"像 Wikipedia"打分,就会把方言、口语、非拉丁语种、代码注释系统性判为低质。结果是模型在这些群体上表现更差,而且这个偏差在训练日志里完全看不见。所以过滤器必须按语种/领域分别校准阈值,并保留抽样人工复核。

3.5 去污染:这一步没做,后面所有评测都不可信

污染(contamination)指评测集的内容(或其近义改写)出现在训练数据里。检测手段:
  • n-gram 重叠:对评测样本取 8–13-gram,在训练语料上匹配。命中率高即疑似。
  • 嵌入近邻:抓改写/翻译形式的泄漏。
  • 行为探针:看模型能否补全评测题的下文、是否对"题目前缀"异常敏感。
处理方式:直接删除命中样本(比"按基准整体剔除"更精细),并保留审计日志。
污染的破坏力被普遍低估。一旦泄漏,你看到的是"榜单涨了 15 个点",而实际能力没变。更糟的是,你会基于这个假信号做出错误的模型选型。反过来,很多看起来"某模型在某个榜上异常强"的现象,第一嫌疑对象就是污染或格式过拟合,而不是能力。

3.6 Tokenizer 训练:数据阶段的最后一个决定

  • 训练语料的采样:词表要用与预训练配比一致的样本训练,否则会偏向某个领域(例如用纯英文训词表,中文就被切得很碎)。
  • 压缩率指标:常用"字节/token"或"token/词"衡量。压缩率高 → 同样的上下文窗口装更多信息 → 推理成本更低。这是中文/多语言模型必须重点优化的一项。
  • 词表大小与 embedding 成本:V×d 参数(可能双份,如果输出不共享)。
  • 稳定性:词表一旦上线,改动成本极高(要重训或做 embedding 对齐手术),所以宁可在早期多试几版。

3.7 三种数据 schema(后面章节都会用到)

# ① 预训练:纯文本流
{"text": "……"}

# ② SFT:对话 + 只在助手回答上算 loss
{"messages": [
  {"role": "user",      "content": "……"},
  {"role": "assistant", "content": "……"}          # ← 只有这里参与 loss
]}

# ③ 偏好数据:同一 prompt 的两个回答 + 人类/模型偏好
{"prompt": "……", "chosen": "……", "rejected": "……"}
# 可验证奖励(RLVR)则不需要 rejected,只要有标准答案/可执行校验:
{"prompt": "……", "answer": "42", "verifier": "math_exact_match"}
数据侧的常见坑。
  1. 只统计 token 数,不统计"有效 token 数":模板、padding、被 mask 的部分都不该算。
  2. 把去重做在 tokenize 之后:那时已经晚了,且会在序列边界引入人为截断。
  3. 训练数据与评测数据的时间重叠:即使是同一个网站的不同时间抓取,也可能包含同一份内容。
  4. SFT 数据格式不统一:多个来源的对话模板混用,会让模型学到矛盾的格式协议,表现为"偶尔不听话"。
  5. 合成数据递归放大:用模型 A 生成数据训模型 B,再用 B 生成数据训 C,几轮后分布坍缩、多样性断崖式下降。必须混入真实数据并监控多样性指标。
  6. 忽略数据顺序:shuffle 不充分会让同一来源的样本聚集,等效于给某个领域临时加了很高的学习率,容易触发 loss spike。
索引。
  • 数据集:The Pile|C4|RedPajama|Dolma(含完整清洗管线的开源复现)|FineWeb / FineWeb-Edu(过滤配方与消融)|The Stack(代码)
  • 方法:Deduplicating Training Data Makes Language Models Better|Textbooks Are All You Need(phi 系的数据哲学)|Scaling Data-Constrained Language Models(重复数据的收益递减)
  • 工具:datasets、trafilatura、datasketch(MinHash LSH)、fastText、text-dedup
本章自查。① 为什么去重同时改善泛化、隐私和成本?② 用"像 Wikipedia"的分类器做过滤会带来什么系统性偏差?③ 去污染如果只按基准整体剔除会有什么问题?④ 为什么 tokenizer 的训练语料配比要跟预训练一致?

4. 预训练:把算力换成能力

预训练是整条链上最贵、最难调试、也最"工程"的一环。它的核心问题只有三个:做多大(Scaling law)、怎么切到几千张卡上跑(并行)、怎么让它别崩(稳定性)。

4.1 规模直觉:算力、参数、数据三者的关系

训练算力估算(值得背下来的公式)。
训练总 FLOPs ≈ 6 × N × D
    N = 参数量(不含 embedding 时可近似)
    D = 训练 token 数
系数 6 = 前向 2(乘加)+ 反向 4
以 8B 模型、15T token 为例:6 × 8e9 × 15e12 ≈ 7.2e23 FLOPs。若单卡有效算力 400 TFLOPS(H100 bf16 峰值 989,实际 MFU 常 35%–50%),约需 7.2e23 / 4e14 ≈ 1.8e9 卡秒,即 1000 卡跑约 21 天。

MFU(Model FLOPs Utilization,实际算力/峰值算力)是预训练最重要的效率指标。大模型训练里 MFU 40%+ 已经很好,50%+ 属于调优很到位。它受通信、气泡、重计算、算子实现共同影响——这也解释了为什么并行策略的选择直接等于钱。

4.2 Scaling law:定规模的依据

结论内容工程含义
Kaplan 等(2020)loss 随参数量、数据量、算力呈幂律下降;给定算力时优先增大参数量催生了"大参数、相对少数据"的一代模型
Chinchilla(2022)算力最优时,参数量与 token 数应同比例增长,约 20 token / 参数7B → 约 140B token。推翻了上一行的结论:数据被严重欠训
推理感知最优把推理成本也纳入总成本后,最优解是"更小的模型 + 更多的数据"这是 Llama-3-8B 用 15T token(远超 Chinchilla)以及大量小模型长时间训练的理论依据
数据受限高质量数据有限时,重复数据的收益快速衰减,多次重复几乎不再有增益解释了为什么"数据枯竭"成为真实约束,以及为什么要做合成数据
取舍:Scaling law 是规划工具,不是定律。它给的是"给定算力下的粗略最优点",但现实决策还要考虑:推理成本是否主导(大多数商用场景是)、数据是否够、部署硬件约束、迭代速度(小模型迭代快)。实践中更常见的做法是先用小规模跑一批消融(ablation),把配比/架构定下来,再放大,并用 μP 之类的参数化方法让超参在小模型上调好后可直接迁移到大模型。

4.3 架构选择:dense 还是 MoE

DenseMoE(稀疏专家)
参数量 vs 计算量绑定:参数多则每 token 计算多解耦:总参数可以很大,每 token 只激活少数专家
训练算力效率基线同算力下通常更强(更多容量)
显存占用≈ 参数量所有专家都要常驻,显存按总参数算,不按激活算
通信TP/PP/DP 为主额外需要 all-to-all(token 发到专家所在卡),突发性强、对网络敏感
训练稳定性较稳路由不均衡、专家塌缩、loss spike 风险更高
推理特性规则、易批处理batch 内专家负载不均 → 利用率波动大;需要 EP 与专门调度
微调与量化生态成熟工具链支持较晚,量化时专家分布不均增加难度
MoE 的本质是一笔交易:用显存和通信复杂度,换同等算力下更强的能力。所以它特别适合"显存够、算力是瓶颈"的场景,而不适合"显存紧张、要极致单卡部署"的场景。看到"26B 总参数 / 3.8B 激活"这类标注时,要意识到它的显存与带宽需求接近 26B,而不是 3.8B。

4.4 并行策略:切什么、通信多少

这是预训练工程的核心表格。判断一个并行方案是否可行,只要看通信量与可用带宽是否匹配。

策略切分维度通信原语 / 频率带宽要求解决的问题
DP 数据并行batch 维(每卡一份完整模型)梯度 all-reduce,每步 1 次,量 ≈ 2×参数量中低(可跨节点,梯度累积/重叠缓解)吞吐;但每卡都要放全量优化器状态
ZeRO-1/2/3(FSDP)DP 的显存优化版:分片优化器状态 / +梯度 / +参数stage 越高通信越多;ZeRO-3 每层需 all-gather 参数中高单卡放不下优化器状态——最常见的第一步
TP 张量并行层内矩阵(列/行切分)每层 2 次 all-reduce,频率极高极高,基本要求 NVLink 同机单层参数放不下;层内并行度提升
PP 流水并行按层切到不同卡相邻 stage 点对点传激活,量小但需调度低,可跨节点超深模型;代价是流水气泡
SP 序列并行norm/dropout 区域的序列维与 TP 配合,减少激活同 TP长序列下的激活显存
CP / Ring 上下文并行序列维切分做注意力环形传递 KV中高超长上下文的注意力显存与算力
EP 专家并行MoE 专家分布到不同卡all-to-all,突发高且对拓扑敏感MoE 的专家容量
3D 并行的典型摆放(记住这个直觉)。
节点内(NVLink,带宽最高)→ TP + EP + SP/CP
节点间(IB/RoCE)        → PP(通信量小)
最外层                   → DP / ZeRO(可与计算重叠)
原则:通信最频繁的放到带宽最高的连接上。反过来放(把 TP 跨节点)会立刻把 MFU 打到个位数。

4.5 显存账单:全参训练到底要多少

算一遍:7B 模型混合精度 + AdamW 全参训练。
项目精度公式7B 占用
权重bf162N14 GB
梯度bf162N14 GB
主权重副本fp324N28 GB
Adam 一阶动量 mfp324N28 GB
Adam 二阶动量 vfp324N28 GB
小计(不含激活)16N≈ 112 GB
结论:单卡 80 GB 装不下;用 ZeRO-2 把优化器状态与梯度分片到 8 卡后,每卡约 (28+28+28+14)/8 + 14 ≈ 26 GB,再加激活与临时缓冲就比较舒服了。
对比 LoRA:基座 14 GB 冻结 + 极小的 adapter 与优化器状态,单张 24 GB 卡即可微调 7B。这就是 PEFT 在工程上不可替代的原因。

激活显存与 B × S × L × d 成正比,长序列下会成为主要项。控制手段:梯度检查点(重计算,用算力换显存,通常多花约 30% 时间)、序列并行、分块注意力、以及把中间量以低精度存储。

4.6 混合精度与低精度训练

bf16

现代默认

8 位指数(与 fp32 同量级范围)、7 位尾数。因范围足够大,通常不需要 loss scaling。缺点是精度低,小梯度可能被吞掉,所以优化器状态仍用 fp32。

fp16

需 loss scaling

范围窄,梯度下溢需要放大再缩回。今天主要用于老硬件兼容。

fp8

Hopper/Blackwell 起

E4M3/E5M2,需逐张量缩放与延迟缩放策略。能显著提升吞吐,但对稳定性与实现成熟度要求高。

4.7 训练稳定性:loss spike 的因果与处置

典型症状。梯度范数先出现尖峰,紧接着 loss 抬升;有时能自行回落("spike and recover"),有时直接发散。几百步后才发现,等于几小时到几天的算力白烧。
可能原因机理缓解手段
坏数据批次某批样本异常(重复、乱码、超长)造成巨大梯度数据清洗与长度控制;跳过该 batch
学习率/warmup 不当早期参数远离初始化点,更新过猛更长 warmup、更低峰值 LR、cosine 衰减
注意力 logits 爆炸QK 内积过大 → softmax 饱和 → 梯度异常("massive activations")QK-Norm、softmax 前缩放、logit soft-capping
输出层 logits 漂移配分函数持续增大z-loss
低精度溢出fp16 下溢/上溢改用 bf16;动态 loss scaling
初始化/参数化不当深层残差累积过大按 1/√(2L) 之类缩放初始化;μP
标准处置流程(值得做成 runbook)。
  1. 监控梯度范数,不要只看 loss。
  2. 发现尖峰:回滚到尖峰前若干步的 checkpoint,跳过导致尖峰的数据分片,并略微降低学习率后重启。
  3. 不要"继续跑看它能不能自己好"——发散的训练很少能靠等待恢复,而等待的成本是按天算的。
  4. 把每次尖峰的数据分片、LR、step 记进训练日志,几次之后就能定位到配方问题。

4.8 长上下文扩展

方法做法特点
位置插值(PI)把超出训练长度的位置压缩回训练范围内简单有效,短上下文性能损失小,实现即插即用
NTK-aware按频率高低非线性调整 RoPE 基频比 PI 更好地保留高频(局部)信息
YaRNNTK 思路 + 注意力温度修正少步数即可扩展到很长,工业界常用
继续预训练在长文档上继续训练效果最好,但需要长文档语料与可观算力
注意力结构改造滑窗注意力、attention sink、稀疏注意力降低 O(n²) 成本,但与既有权重兼容性需验证
长上下文的三个陷阱。
  • "宣称长度" ≠ "有效长度"。支持 128K 不代表在 128K 上还能找到中间位置的针。必须用 NIAH(needle-in-a-haystack)、RULER、LongBench 之类做位置 × 长度的二维评估,常见失效模式是中间位置塌陷(lost in the middle)。
  • prefill 成本是平方级的。128K 的 prefill 算力与显存远超线性直觉,这也是 PD 分离(第 8.7 节)存在的理由。
  • KV Cache 是线性增长的。128K 单序列在 8B 模型上就是约 16 GiB——容量规划必须按这个算,而不是按权重算。

4.9 MoE 训练细节

  • 路由:每 token 选 top-k 专家(k 常为 1–8)。细粒度专家 + 共享专家是当前主流设计:把专家切得更小更多,并留若干"永远激活"的共享专家承载通用能力。
  • 负载均衡:若无约束,路由会塌缩到少数专家。用辅助损失(aux loss,鼓励各专家被均匀使用)或专家选择路由(expert-choice)来均衡;过强的 aux loss 会损害质量,权重需要调。
  • 容量因子与丢 token:每个专家有容量上限,超出部分的 token 会被丢弃(或走残差)。丢弃比例是重要监控指标。
  • 通信:all-to-all 是主要瓶颈,需与计算重叠;专家放置要考虑拓扑。

4.10 基础设施与容错

框架

常见组合

Megatron-LM(TP/PP/EP 最成熟)|DeepSpeed(ZeRO 系)|FSDP/FSDP2(PyTorch 原生)|NeMo(封装)|torchtitan / MaxText(现代参考实现)|veRL / OpenRLHF(后训练)

容错

必须提前设计的事

异步 checkpoint(不阻塞训练)|分片状态的一致性|断点续训的数据序恢复(否则等于重复喂数据)|节点故障自动重启|慢节点(straggler)检测

分布式训练里最贵的坑。
  1. 续训后数据顺序错乱:看起来 loss 曲线正常,实际模型见了重复数据,评测指标莫名下降。
  2. 只有一张卡上出了问题:多卡训练是"最慢的卡决定速度",也是"任何一张卡出错整体出错"。日志必须能定位到 rank。
  3. checkpoint 格式与并行度绑定:改变 TP/PP 度数后无法直接加载。要预留 checkpoint 转换脚本。
  4. 用训练 loss 判断模型好坏:loss 更低不代表下游更好,尤其在多语言与代码混合配比下。
索引。
  • Scaling:Scaling Laws for Neural Language Models(Kaplan)|Training Compute-Optimal LLMs(Chinchilla)|Scaling Data-Constrained Language Models
  • 并行与系统:Megatron-LM|ZeRO|Efficient Large-Scale Language Model Training on GPU Clusters Using Megatron-LM(3D 并行)|Ring Attention|Sequence Parallelism
  • 稳定性:Gemma 2|PaLM|Numerical instability 相关分析与 QK-Norm|μP / Tensor Programs V
  • 长上下文:RoFormer|YaRN|Lost in the Middle|RULER|StreamingLLM(attention sink)
  • MoE:Switch Transformer|GShard|DeepSeekMoE|Mixtral
本章自查。① 用 6ND 估算你手上一次训练的总 FLOPs 和卡天。② 为什么 TP 必须放在 NVLink 域内,而 PP 可以跨节点?③ 7B 全参训练的优化器状态占多少显存,ZeRO-2 分片到 8 卡后是多少?④ 出现 loss spike 的标准处置流程是什么?⑤ 为什么 MoE"3.8B 激活"不等于"3.8B 的显存需求"?

5. 后训练:从"会续写"到"听话有用"

预训练让模型学会语言与世界知识,后训练决定它怎么用这些能力。这一层的技术演化非常快,但骨架是清晰的:SFT 教格式与任务 → 偏好对齐教取舍 → 可验证奖励教推理。

Base只会续写→ SFT格式·指令遵循→ 偏好对齐RLHF / DPO / GRPO→ 可验证强化RLVR·推理模型→ 蒸馏与合并压缩·整合

5.1 SFT:最有效、也最容易被做坏的一步

是什么。监督微调:拿"指令 → 理想回答"的样本继续做下一 token 预测,但 loss 只算在助手回复上。它不教新知识,主要作用是把能力对齐到你要的格式、语气和任务分布上。
  • 数据质量 > 数量。少量高质量、多样化的样本(几千条量级)往往胜过几十万条噪声样本。混合来源时,格式一致性比单条样本的精美程度更重要。
  • 轮次与长度:多轮对话要正确构造 mask(只算助手段);样本长度分布直接决定 padding/packing 效率。
  • 超参经验:全参微调 LR 常在 1e-5 ~ 2e-5,LoRA 常在 1e-4 ~ 2e-4;epochs 通常 1–3,再多就出现过拟合与"只会一种腔调"。
  • 灾难性遗忘:SFT 太猛会削弱基座能力(多语言、长文、代码)。缓解:混入一定比例的预训练数据(replay)、降低 LR、用 LoRA、控制步数。
SFT 侧的四个高频坑。
  1. packing 引入样本间串扰。把多条样本拼成一条长序列能提升吞吐,但如果不做块对角注意力掩码,后面的样本会"看到"前面的样本,学出奇怪的关联。要么用注意力隔离,要么放弃 packing。
  2. mask 构造错位。多轮对话里把用户轮也算进 loss,模型会学会以用户口吻自我回复。
  3. 训练与推理模板不一致。训练用 A 模板、部署用 B 模板,模型表现会明显下降,而且表现为"随机不听话"。
  4. 用 SFT 修知识错误。SFT 擅长改行为,不擅长注入大量新事实;需要知识注入时应回到继续预训练或 RAG。

5.2 参数高效微调:LoRA 家族

LoRA 的核心思想。冻结基座权重 W,只训练一个低秩增量 ΔW = B·A(A ∈ R^{r×d_in}、B ∈ R^{d_out×r},r ≪ d),前向为 x(W + α/r · BA)。
省显存的机理很直接:不需要为基座存梯度与优化器状态——按第 4.5 节,那部分正好是 16N 里的大头。
变体关键改动解决的问题
LoRA低秩增量 + α/r 缩放显存与存储;一个基座挂多个适配器
QLoRA基座 4-bit 量化(NF4)+ 反量化计算 + LoRA进一步压低基座显存,单卡微调大模型
DoRA把权重分解为幅度 + 方向,只对方向做低秩更新低秩下更接近全参微调的效果
AdaLoRA / 变秩按重要性动态分配秩预算同样参数预算下效果更好
Prefix / P-Tuning只训练软提示向量参数更少,但占据上下文位置、效果上限较低
取舍:合并还是在线挂载?
  • 合并进基座:推理零额外开销,但每个任务一份权重(存储与部署成本 ×N)。
  • 在线挂载(多 LoRA):一份基座服务多个适配器,显存只多了一点;代价是每步多一次小矩阵乘,且批量内不同适配器需要分组处理,调度更复杂。
  • 经验:适配器数量多、流量分散 → 多 LoRA 服务;单个适配器吃满流量 → 合并。
PEFT 的坑。
  • target_modules 选错:只挂 q_proj, v_proj 是最老的做法,挂全线性层(含 FFN)通常明显更好,代价是参数变多。
  • α 与 r 的配比:α/r 实质是缩放,改了 r 却不调 α,等效学习率就变了。
  • QLoRA 的反量化开销:训练尚可,不要用 4-bit 基座做生产推理,除非已验证精度;推理应单独量化(第 8.5 节)。
  • 适配器与基座版本错配:部署时基座 revision 变了却继续用老适配器,效果会静默下降。

5.3 偏好对齐总览

方法需要的信号要不要奖励模型要不要参考模型主要特点
RLHF / PPO成对偏好 → 训 RM → 用 RM 打分要要(KL 约束)在线采样,效果强;四模型并存,工程最重、最容易不稳定
DPO成对偏好(离线)不要要把 RL 目标解析地转成分类损失;稳定、便宜,是当前主流
IPO / KTO / ORPO / SimPO成对偏好,或二元好/坏标签不要视方法而定各自修补 DPO 的特定缺陷(过拟合、需要成对、长度偏置、是否需参考模型)
GRPO / RLOO对同一 prompt 多次采样并打分可选(多为规则/验证器)要(KL)免价值网络,用组内相对优势;是推理模型训练的主力
RLVR可验证奖励(答案对错、单测通过、格式合规)不要要奖励不可被"讨好",能显著提升推理;但仅适用于可验证任务
DPO 的损失(值得能写出来)。
L_DPO = − log σ( β·[log(π_θ(y_w|x)/π_ref(y_w|x))
                    − log(π_θ(y_l|x)/π_ref(y_l|x))] )
y_w = 被偏好的回答, y_l = 被拒绝的回答, β 控制偏离参考模型的程度
直觉:提高好回答相对参考模型的概率,压低坏回答相对参考模型的概率。它绕过了"先训 RM 再 RL"的两段式,因此工程上便宜得多。
GRPO 的损失(推理模型的关键)。对同一 prompt 采样 G 个回答,得到奖励 r_1..r_G,用组内归一化当优势:
A_i = (r_i − mean(r)) / std(r)
L = − E[ min( ρ_i·A_i , clip(ρ_i, 1−ε, 1+ε)·A_i ) − β·KL(π_θ‖π_ref) ]
ρ_i = π_θ(o_i|x) / π_θ_old(o_i|x)
省掉了 PPO 的价值网络(critic),显存与调参负担都下降;组内相对比较使得奖励的绝对尺度不重要——这正是它能与"答案对错"这类 0/1 奖励配合的原因。
对齐阶段的经典失败模式。
  1. 奖励黑客(reward hacking):模型学会迎合奖励模型的表面特征——更长、更多列表、更多"让我来帮你"、更自信,而不是更正确。必须持续用人类/独立评测复核,并监控长度与格式指标。
  2. 长度偏置:RM 与 judge 都偏好长回答。DPO 家族尤其容易把"变长"当成提升偏好的捷径。SimPO、长度正则、长度平衡的偏好数据都是应对手段。
  3. 过度拒答 / 谄媚:安全对齐过头会拒答正常请求;偏好数据偏向"顺从"会让模型放弃指出用户错误。
  4. KL 崩塌:β 或 KL 系数太小 → 模型跑偏、多样性丧失;太大 → 几乎不学习。
  5. 离线偏好数据分布漂移:DPO 用固定偏好集,策略一变数据就"过期",效果低于在线方法。
  6. 用 RL 修知识:同 SFT,RL 也改不了缺失的知识,只会改变表达与策略。

5.4 蒸馏:把大模型的能力搬到小模型

序列级

输出蒸馏

用教师生成回答做 SFT 数据。on-policy(用学生自己采样的轨迹请教师纠正)通常优于纯 off-policy,能缓解曝光偏差。最易落地。

logit 级

分布蒸馏

最小化 KL(p_teacher^T ‖ p_student^T)(见第 2.3 节)。信息量最大,但要求同词表,实践上多用于同族模型压缩。

推理级

思维链蒸馏

连推理过程一起学。风险是学到的可能是"看起来像推理"的模板,而没有真正的可迁移推理能力。

5.5 模型合并与领域适配

  • 模型汤 / SLERP / 任务向量:把多个同源微调模型的权重直接平均或做插值。成本极低(不需要重训),在"多个窄任务各训一个模型"时非常划算。
  • TIES / DARE:先修剪小幅度参数、再解决符号冲突,最后合并。比朴素平均更稳,能减少互相干扰。
  • 继续预训练(CPT):注入领域知识(法律、医疗、内部文档)。注意:CPT 容易造成通用能力退化,应混入通用数据并做回归评测。
  • 合并的评测纪律:合并出来的模型必须在所有子任务上回归,避免"平均分涨了但某个任务崩了"。
索引。
  • SFT 与数据:InstructGPT|LIMA: Less Is More for Alignment|Self-Instruct|Magpie
  • PEFT:LoRA|QLoRA|DoRA|peft、unsloth、LLaMA-Factory、axolotl
  • 偏好对齐:Training language models to follow instructions with human feedback(RLHF)|DPO|IPO|KTO|ORPO|SimPO
  • 推理强化:DeepSeek-R1(GRPO + RLVR)|GRPO|RLOO|Let's Verify Step by Step(PRM)|Math-Shepherd
  • 蒸馏:Distilling the Knowledge in a Neural Network|MiniLLM|On-Policy Distillation(GKD)
  • 合并:Model Soups|TIES-Merging|DARE|mergekit
本章自查。① 为什么 LoRA 能省显存(对照第 4.5 节的 16N)?② DPO 相比 RLHF 省掉了哪两个组件?③ GRPO 省掉了什么网络,为什么组内归一化让奖励尺度不再重要?④ "奖励黑客"最常见的三种表现形式是什么,怎么监控?⑤ on-policy 蒸馏为什么优于纯 off-policy?

6. 对齐与安全:让能力落在可控边界内

安全不是"最后一层过滤器",而是横跨数据、训练、推理、产品四层的约束体系。把它当过滤器做,结果通常是:体验被削掉了,真正的攻击仍然能过。

6.1 有用性与无害性的张力

这对张力是结构性的,不是调参问题。要"尽量回答"就要降低拒答阈值;要"尽量不伤害"就要提高它。任何单一阈值都无法同时最优化两端,所以成熟做法是分层:模型层学会区分"该拒的"与"该答的",系统层做二次判定与升级,产品层给用户明确的边界与申诉路径。

6.2 攻击面

攻击机理为什么难防
越狱(jailbreak)通过角色扮演、编码、多语言、分步诱导绕过安全训练攻击空间是开放的,防御方要覆盖所有表述
提示注入(prompt injection)把指令藏进模型会读到的数据里(网页、文档、工具返回、检索结果)模型无法从结构上区分"指令"与"数据"——二者都在同一个 token 流里。这是当前最本质的未解问题之一
数据外泄诱导模型复现训练数据或系统提示、把上下文里的敏感信息发到外部记忆与泛化的边界模糊;工具调用把外泄变成一次正常 API 调用
间接注入 + 工具滥用在检索文档里放指令,让 Agent 执行危险操作(转账、删库、发邮件)Agent 有真实副作用,且攻击者可污染长链条中的任意一环
关于注入的一个关键结论(也适用于第 9 章的决策模型类接口)。约束输出的格式只能限制模型"能说什么",不能阻止模型"被说服相信什么"。有研究显示:即使接口只允许返回预先声明的选项(无法返回未声明的标签),注入仍能可靠地把概率质量推向攻击者想要的那个选项。
工程含义:任何基于模型概率的下游判断,都必须假设输入可能被污染,因此要有阈值 + 升级 + 人工复核 + 最小权限,而不能因为"输出是结构化的、类型安全的"就认为它可信。

6.3 防御的分层

训练侧

让模型学会边界

安全 SFT(含拒答样本)、偏好数据里包含"该拒就拒"与"不该拒就别拒"两侧、红队数据回流。目标是校准边界的形状,而不是一味提高拒答率。

系统侧

护栏与隔离

输入分类器(检测注入/越狱)、输出过滤器(PII、有害内容)、权限隔离(Agent 只能调用白名单工具、写操作要二次确认)、外部内容的来源标记与信任级别。

运行时

监控与响应

记录完整轨迹(含检索到的原文)、异常检测(突然的工具调用序列)、速率与配额限制、可回滚的副作用(软删除、事务、幂等)。

安全工程常见错误。
  1. 把安全当成后置过滤器:过滤器只能处理已生成的文本,无法阻止 Agent 已经调用了危险工具。
  2. 只看平均拒答率:安全评估必须看分类型的漏放率与误拦率,平均值会掩盖严重的单类问题。
  3. 拿安全提示词当防御:"不要被注入"这类系统提示可以被绕过,只能作为纵深防御的一层。
  4. 不做红队回归:每次模型/提示词更新后,之前修好的攻击会重新出现。红队用例必须进 CI。
  5. 低估多语言风险:安全训练通常以英文为主,低资源语种的越狱成功率显著更高。

6.4 幻觉与事实性

  • 来源分类:训练数据缺口(不知道)、冲突知识(记混)、解码采样(随机性导致编造)、上下文误用(RAG 召回了错误内容)。不同来源要用完全不同的手段。
  • 可行手段:检索增强(把知识外部化)、要求给出处并校验出处、自一致性/多次采样投票、工具化(计算、检索、执行代码)、拒答与不确定性表达。
  • 不可靠手段:只靠"请勿幻觉"的提示词;把 logprob 当正确率(见第 2.8 节)。

6.5 可解释性工具箱(与 logits 直接相关的部分)

工具读的是哪一层能回答什么不能回答什么
logit lens / tuned lens中间层 hidden state 过输出头信息在哪一层开始成形;模型"中途想说什么"不是模型的最终判断;早期层结果接近噪声
线性探针 probing指定层的 hidden state某概念/属性是否线性可解码(如"这句话是否真实")相关性非因果;探针自身需要训练与验证
稀疏自编码器 SAE激活空间把叠加的激活分解成可解释特征("特征即方向")覆盖不全;特征解释带主观性
注意力可视化注意力权重token 之间的信息流动注意力权重 ≠ 因果重要性
归因/消融输入或组件哪些输入片段真正影响输出(因果)成本高;结果随基线选择变化
为什么这一节放在"安全"章。可解释性的工程价值主要在三个场景:调试(模型为什么答错)、审计(能否证明模型没用某个特征)、防御(检测被注入后的内部状态偏移)。它不是产品接口——把它和"从 logits 读决策"混为一谈是常见误解(见第 2.5 节与第 9 章)。
索引。
  • 对齐总论:InstructGPT|Constitutional AI|Scalable Oversight 相关综述
  • 攻击与防御:Universal and Transferable Adversarial Attacks on Aligned LMs|Not what you've signed up for: Compromising Real-World LLM-Integrated Applications with Indirect Prompt Injection|OWASP LLM Top 10|GCG|Many-shot Jailbreaking
  • 幻觉:Survey on Hallucination in NLG|SelfCheckGPT|Semantic Entropy(不确定性估计)
  • 可解释性:Toy Models of Superposition|Scaling Monosemanticity(SAE)|Towards Monosemanticity|Tuned Lens
  • 工具:TransformerLens、nnsight、baukit、SAELens
本章自查。① 为什么提示注入在结构上难以根治?② "输出格式受约束"为什么不能防注入(结合第 9 章)?③ logit lens 与"读 logits 做决策"的区别是什么?④ 幻觉的四种来源分别对应什么手段?

7. 评测:你怎么知道前面几步做对了

评测是整条链的反馈信号。信号不可信,前面所有优化都是在盲调。这一章的重点不是列举榜单,而是识别评测什么时候在骗你。

7.1 评测的三个层次

层次 1

能力(capability)

知识、推理、代码、数学、多语言。通常用公开基准 + 内部私有集。私有集是对抗污染的唯一可靠手段。

层次 2

行为(alignment)

指令遵循、拒答边界、格式合规、谄媚程度、安全漏放/误拦率。多数需要人工或强模型评委。

层次 3

系统(system)

端到端任务成功率、延迟与成本、工具调用正确率、失败可恢复性。只有这一层能回答"能不能上线"。

7.2 基准地图与它们的失效模式

类别代表主要失效模式
通识知识MMLU 系、GPQA污染最严重;题目短、答案可猜;已接近饱和
数学与推理AIME、MATH、GSM8K答案抽取规则敏感;"答案对但过程错";可用工具/代码绕过
代码HumanEval、SWE-bench 系测试用例泄漏;环境依赖;数据划分与真实仓库分布不一致
指令遵循IFEval 系可被格式过拟合;与真实用户请求分布差距大
长上下文NIAH、RULER、LongBench"针"的构造太容易;只测召回不测推理;长度与位置覆盖不全
安全红队集、越狱集攻击更新快于基准更新;单一语言/单一攻击类型
偏好/主观Chatbot Arena 类风格偏置(长、排版好、自信者占优);投票人群偏差
三种会让榜单失真的机制,务必能识别。
  • 污染:训练数据里含评测题(见第 3.5 节)。表现是"某个基准上异常高,同族其他基准正常"。
  • 饱和:分数挤在 90+ 的窄区间,差异落在噪声内。此时该换更难的自建集,而不是继续排名。
  • 格式过拟合:模型学会了基准的标准答案格式(如固定输出 #### 后跟数字),在真实任务上并不具备同样能力。

7.3 指标与其含义

指标定义什么时候用 / 注意
accuracy / exact match完全正确的比例客观题。注意归一化规则(大小写、单位、等价形式)会显著改变结果
pass@k采样 k 次至少有一次通过代码与数学。k 越大越"宽容",要明确报告 k 与采样温度
PPL / loss指数化的平均交叉熵仅在同一 tokenizer 下可比;与下游能力不是单调关系
win rate成对比较的胜率主观任务;必须控制位置与长度偏置
Elo / Bradley-Terry由成对结果拟合出的排名分跨批次可比,但依赖对手池;新模型加入会改变全体分
系统指标任务成功率、TTFT/TPOT、$/千次调用上线决策只用这组

7.4 LLM-as-judge:好用,但必须防偏

是什么。用强模型当评委给回答打分或做成对比较。它是目前唯一能规模化评估开放式任务的实用手段。
偏差表现缓解
位置偏置偏爱第一个(或第二个)出现的答案交换顺序各评一次,只保留结论一致的样本
长度/格式偏置偏爱更长、更多分点、更"自信"的回答长度配对控制;在评委提示里显式要求忽略长度;监控胜者长度差
自我偏好偏爱与自己同族的模型输出用多个不同族评委投票;避免用被评模型自己当评委
评分不稳定同一输入重复评分结果不同固定温度(多为 0)、多次采样取多数;报告一致性指标
与人类不一致在专业/安全维度上系统性偏离保留人工标注子集做校准;报告评委与人类的相关系数

7.5 线上评测

  • 离线 → 在线之间必须有门禁:把关键评测做成 CI,指标退化超过阈值就阻止发布。
  • A/B 的注意点:分流要按用户而非按请求(避免同一用户体验抖动);要提前定义主指标与最小可检测效应;看尾延迟与失败率,平均值会掩盖问题。
  • 影子流量:新模型只推理不影响用户,用来提前暴露崩溃与格式错误。
  • 生产监控:输出长度分布、拒答率、工具调用失败率、解析失败率、用户追问率——这些比离线榜单更早发现退化。
评测侧的坑。
  1. 用被污染的公开榜单做选型决策(最常见的重大误判)。
  2. 不固定解码参数:temperature 从 0 改成 0.7,分数变了,却归因于模型。
  3. 样本量太小:几百条样本上的 2 个点差异基本是噪声,却据此选型。
  4. 只报平均分:掩盖了某一类任务的严重退化。
  5. 把 judge 的分数当绝对真值:它是相对信号,必须配人工校准。
  6. 不做"同一模型重复评测"的方差估计:不知道噪声水平,就无法判断差异是否显著。
索引。
  • 框架:lm-evaluation-harness|lighteval|OpenCompass|HELM|EvalPlus|SWE-bench|RULER|Inspect
  • 方法:Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena|Length-Controlled AlpacaEval|Lost in the Middle|Your Benchmark is Broken 类批评文献
本章自查。① 为什么私有评测集是对抗污染的唯一可靠手段?② 成对 judge 为什么必须交换顺序各评一次?③ pass@k 报告时至少要附哪些信息?④ 为什么"平均分涨了"不足以支持上线?

8. 推理与部署:把能力变成延迟与成本

这一章是整条链路里工程收益最直接的一环。核心认识只有一句:prefill 是算力受限,decode 是显存带宽受限。几乎所有推理优化技术,都能被归类为"针对这两者之一做了什么"。

本章结构
  1. 8.1 两阶段模型与 roofline
  2. 8.2 该看哪些指标
  3. 8.3 KV Cache:容量、分页、复用
  4. 8.4 注意力算子
  5. 8.5 量化
  6. 8.6 投机解码与约束解码
  7. 8.7 批处理与调度(含 PD 分离)
  8. 8.8 分布式推理
  9. 8.9 框架选型
  10. 8.10 服务化与成本模型

8.1 两阶段模型与 roofline

阶段 1

Prefill(预填充)

把整段输入一次性算完,并行处理所有输入 token。计算量大、矩阵乘密集,属于 compute-bound。它的耗时直接决定 TTFT。

阶段 2

Decode(解码)

每步只算 1 个新 token,但要读取全部权重和整个 KV Cache。算力几乎闲置,属于 memory-bandwidth-bound。它决定 TPOT。

算一遍:为什么 decode 是带宽瓶颈。以 8B 模型、bf16 为例:
  • 每生成 1 个 token,需要读的权重约 16 GB(bf16 下 2N)。
  • 产生的计算约 2N = 16 GFLOPs。
  • 算术强度 ≈ 16e9 / 16e9 = 1 FLOP/Byte。
  • H100 的 bf16 峰值约 989 TFLOPS、显存带宽约 3.35 TB/s,其拐点在约 989e12 / 3.35e12 ≈ 295 FLOP/Byte。
  • 1 远小于 295 → decode 严重落在带宽侧。理论上限约 3.35e12 / 16e9 ≈ 209 token/s(不管 batch 多大,单个请求只能这么快)。
结论:提升 decode 吞吐的唯一根本手段是增大 batch——让同一份权重读取服务更多序列。这就是连续批处理(8.7)存在的全部理由,也是量化(减少要读的字节数)在 decode 上收益明显的原因。

8.2 该看哪些指标

指标含义被什么影响
TTFT首 token 时间(排队 + prefill)输入长度、队列深度、prefill 是否被 decode 抢占(chunked prefill 相关)
TPOT / ITL每个输出 token 的平均耗时(不含首 token)batch 大小、KV Cache 长度、带宽、是否启用量化/投机解码
端到端延迟排队 + TTFT + (n_out−1)×TPOT输出长度影响巨大:长回答的尾延迟主要由 TPOT 决定
吞吐总 token/s(输入+输出)batch、并行策略、算子效率
goodput满足 SLO 的 token/s唯一能指导容量规划的指标:吞吐再高但违反 TTFT SLO 的请求是无效产出
取舍:batch 越大吞吐越高,但 TPOT 会变差。批处理让权重读取被更多请求分摊(吞吐上升),同时每个请求要等更久(TPOT 上升)。所以"最大吞吐"和"最低延迟"是两个不同的系统配置,必须按业务定 SLO 后再调。常见错误是把离线批处理的配置直接搬到在线服务上。

8.3 KV Cache:容量、分页与复用

它是什么。自回归生成时,历史 token 的 Key/Value 不会改变,可以缓存下来,避免每步重算。缓存的就是 KV Cache。
KV Cache 字节数 = 2 × L × n_kv_heads × head_dim × S × B × bytes_per_elem
                  ↑K和V  ↑层数              ↑缓存长度 ↑批次
算一遍:8B GQA 模型(L=32, n_kv=8, head_dim=128, bf16)每 token 的 KV。 2 × 32 × 8 × 128 × 2 B = 131072 B = 128 KiB/token(若为全 MHA 的 32 个 KV 头,则是 512 KiB/token,4 倍)。
上下文长度单序列 KV8 并发32 并发128 并发
4K512 MiB4 GiB16 GiB64 GiB
32K4 GiB32 GiB128 GiB512 GiB
128K16 GiB128 GiB512 GiB2 TiB
结论:在 80 GB 的卡上,8B 模型权重只占 16 GB,剩下 60 GB 左右才是"并发容量预算"。32K 上下文下单卡只能容纳约 15 条并发。这就是长上下文服务如此昂贵的根本原因——不是权重,是 KV Cache。
技术做法收益代价
PagedAttention把 KV 切成固定大小的块(常 16 token)非连续存储,逻辑上连续基本消除显存碎片,利用率可到 90%+;支持块级共享(前缀缓存、copy-on-write)需要专门 kernel;块大小是调参项
前缀缓存相同前缀(系统提示、few-shot 示例、长文档)复用已算好的 KV 块Agent 场景收益极大,TTFT 可降一个数量级需要前缀匹配/哈希与淘汰策略;命中率取决于请求分布
KV 量化KV 存成 FP8/INT8(有时只量化 K 或 V)KV 显存减半 → 并发翻倍或上下文翻倍长上下文下的精度损失需要实测;对注意力数值敏感
GQA / MQA减少 KV 头数(架构层解决)直接降到 1/4 或更低需要在训练时就定好,无法事后改
滑窗 / 注意力池只保留最近 N 个 token 的 KV,或用注意力池保留"汇点"把线性增长变成常数丢失远期信息;需要按任务验证
驱逐 / 压缩按重要性丢弃或合并历史 KV(H2O、SnapKV 类)长对话下显著省显存策略复杂,质量风险随任务而变
KV Cache 的坑。
  1. 按权重估容量:这是最常见的容量规划错误。必须按 权重 + KV×并发 + 激活与临时缓冲 一起算。
  2. 忽略显存碎片:没有分页管理时,长短请求混合会让可用显存迅速碎片化,表现为"明明还有显存却 OOM 或无法接纳新请求"。
  3. 前缀缓存命中率不监控:开了前缀缓存但请求前缀每次都不同(比如把时间戳放进系统提示),命中率为 0,白付复杂度。
  4. 把 KV 量化当免费午餐:短上下文影响小,长上下文与需要精确检索的任务上可能明显退化。
  5. 抢占与重算策略未设计:显存不足时框架会抢占请求(丢弃 KV,稍后重算 prefill)。若不理解这一点,会看到"负载高时 TTFT 突然翻倍"的怪现象。

8.4 注意力算子

算子解决什么关键点
FlashAttention 1/2/3注意力中间矩阵 [S,S] 太大,读写显存成为瓶颈分块 + 在线 softmax,把中间量留在片上(SRAM),不落显存,是 IO 优化而非近似算法
FlashDecoding / 拆分 KVdecode 时 batch 小、KV 长,并行度不足沿 KV 维切分并行归约,提升长上下文 decode 的 GPU 利用率
融合 kernel大量小算子的启动开销与中间读写RMSNorm+量化、RoPE、QKV 投影融合等;低 batch 下收益显著
分块 prefill(chunked prefill)超长输入的 prefill 会阻塞所有 decode把 prefill 切成块与 decode 混跑,改善 TPOT 抖动(见 8.7)
一个重要的心智模型:FlashAttention 不改变数学结果。它是精确注意力的IO 优化实现(除了浮点累加顺序带来的微小差异),因此不需要"精度换速度"的评估。真正做近似的是稀疏注意力、滑窗、KV 驱逐那一类。

8.5 量化

方案量化对象主要收益注意
GPTQ / AWQ仅权重(INT4)权重显存降到 1/4;decode 是带宽受限,所以直接加速必须有融合反量化 kernel(Marlin 等),否则可能更慢;精度要按任务测
SmoothQuant 类权重 + 激活(W8A8)同时加速 prefill 与 decode需要处理激活离群通道,校准集影响结果
FP8权重 / 激活 / KVHopper 及以后有原生支持,精度损失小逐张量缩放策略与 kernel 支持依赖硬件与框架版本
GGUF(k-quants / Q4_K_M 等)权重CPU / Apple Silicon / 消费级显卡可用,格式灵活面向本地单机,吞吐与并发不是强项
QAT训练时插入伪量化低比特下精度最好需要训练资源,流程重
KV Cache 量化KV(FP8/INT8)并发翻倍长上下文精度需实测(见 8.3)
量化选型的判断顺序(实用)。
  1. 先看瓶颈在哪:小 batch / 低并发、decode 主导 → 权重量化收益大;大 batch、强 prefill → 需要激活量化。
  2. 再看有没有融合 kernel:没有的话,反量化开销可能吃掉全部收益。
  3. 最后按你的任务测精度,不要只看 PPL。PPL 对量化不敏感,但对长链推理、代码正确率、结构化输出的影响可能很大。
  4. 保留一份 bf16 基线用于回归对比;量化版本必须过同一套评测门禁。
量化的坑。
  • 只测 PPL:PPL 变化 <1% 不代表任务指标不掉。
  • AWQ/GPTQ 用了不同校准集:校准集应尽量贴近真实流量分布。
  • 忽略尾部:量化对"需要精确复制长串 ID/JSON"的任务伤害最大。
  • 把 4-bit 训练(QLoRA)的模型直接拿去推理:训练时的反量化是临时的,部署应使用专门的推理量化版本。

8.6 投机解码与约束解码

投机解码(speculative decoding)的基本机制。
  1. 用一个便宜的方式(小 draft 模型、额外预测头、或 n-gram 查表)一次猜出 k 个后续 token。
  2. 目标模型一次前向并行验证这 k 个位置(代价接近生成 1 个 token,因为 decode 是带宽受限的,多算几个位置几乎不增加时间)。
  3. 按概率比值做接受/拒绝采样;被拒绝的位置从修正后的分布重新采样。
关键保证:正确实现的投机解码与目标模型单独采样得到相同的分布——它是无损加速,不是近似。
变体草稿来源特点
独立 draft 模型同族小模型实现简单;需要额外显存;两模型词表需一致
Medusa在目标模型上多加若干预测头不增加独立模型;需要训练头部;树状验证
EAGLE 系用目标模型的隐藏状态做自回归草稿接受率高,是当前主流方案之一
n-gram / 查表从上下文或语料里找重复片段零训练成本,对代码编辑、摘要、重复性文本极有效
投机解码什么时候有效、什么时候白花。
  • 有效:低 batch(decode 带宽受限、算力闲置)、输出可预测(代码、格式化文本、翻译)、有高接受率的草稿源。
  • 无效甚至有害:高 batch 已经接近算力饱和时,验证成本无法被隐藏,反而降低吞吐;草稿接受率低时(创造性写作、高温度)收益接近零;额外显存挤占了 KV Cache 空间。
  • 监控指标:接受率(acceptance rate)与平均接受长度。低于阈值就该关掉。

约束解码(结构化解码)是另一类:按 JSON Schema / 正则 / 语法在每一步把非法 token 的 logit 置 −∞。它保证可解析,不保证内容正确。实现上有编译有限状态机的,也有用推理解码器(如 xgrammar)的;复杂 schema 的每步掩码开销需要评估。第 9 章的"单 token 槽位读取"是它的最简特例:只约束一个位置且候选极少,于是可以连解码循环都省掉。

8.7 批处理与调度

机制做法解决的问题
静态批处理一批请求一起跑完才接下一批实现简单;长短请求混合时 GPU 大量空转
连续批处理以"一次前向"为调度单位,完成的序列立刻退出、新请求立刻补位吞吐提升数倍;是现代推理引擎的标配
chunked prefill把长 prefill 切成多个块,与 decode 交错执行避免长输入把 TPOT 打出尖峰(改善尾延迟)
PD 分离prefill 与 decode 部署在不同的实例池,KV 通过网络传递两种工作负载特性完全不同(算力受限 vs 带宽受限),分开可各自扩缩容与调优
前缀缓存跨请求复用相同前缀的 KVAgent / RAG 场景的 TTFT 大幅下降
抢占与重算显存不足时丢弃某请求的 KV,稍后重算保证公平性与不 OOM;代价是延迟抖动
PD 分离为什么值得做。prefill 吃算力、对带宽不敏感,decode 吃带宽、算力闲置。混部时两者互相拖累:长 prefill 会阻塞 decode(TPOT 尖峰),而 decode 的持续占用又让 prefill 排队(TTFT 变差)。分离后可以:prefill 池用高算力配置、decode 池堆显存换并发;各自独立扩缩容;KV 通过高速网络(NVLink/RDMA)传输。代价是 KV 传输开销、额外的调度复杂度、以及需要两套实例(小流量时利用率下降)。

8.8 分布式推理

策略什么时候用代价
TP(张量并行)模型单卡放不下;低延迟小 batch 场景每层 all-reduce,增加延迟;要求高速互联(同机 NVLink)
PP(流水并行)跨节点部署超大模型流水气泡;延迟增加,吞吐优先场景更合适
EP(专家并行)MoE 模型all-to-all 通信;专家负载不均
副本(replica)吞吐优先、模型能单卡装下无通信开销,最理想;受单卡显存限制
一个反直觉但重要的结论。TP 在小 batch 低延迟时收益最大(把单步算力需求分散,降低每步时间);但在大 batch 高吞吐时,单卡已有足够算力填满,TP 带来的通信开销可能让它不如直接用副本。所以"能单卡放下就尽量用副本"往往是吞吐场景的最优解。

8.9 框架选型

框架核心优势适合注意
vLLMPagedAttention 起源地、连续批处理、生态最广(量化/LoRA/投机/结构化输出/多模态)、社区迭代快通用在线服务、自研二次开发特性多 → 组合配置需要验证;不同版本的性能差异明显
SGLangRadixAttention 前缀缓存、结构化输出(xgrammar)性能强、DSL 友好Agent / 多轮 / 大量共享前缀生态相对小一些
TensorRT-LLMNVIDIA 官方极致性能、FP8/INT4 kernel 成熟、in-flight batching追求确定性的极致性能、固定模型编译流程重,模型更新要走构建管线;可移植性差
llama.cppGGUF 生态、CPU/Metal/消费级硬件、单机部署极简本地/边缘/桌面高并发服务不是强项
LMDeploy / TGI / MLC前两者服务化封装成熟,MLC 跨平台编译按团队栈选择检查所需特性(量化类型、投机、工具调用)是否支持
框架选型的三个实际坑。
  1. 用官方 benchmark 数字做决策:那些数字通常是最优配置、最优硬件、单一负载。必须用自己的长度分布与并发模型压测。
  2. 忽略版本:推理框架的吞吐可以因为一个 kernel 或调度改动而在版本间差 20%+。压测必须锁定版本。
  3. 只看吞吐不看 goodput:在 SLO 约束下的有效吞吐才是业务指标。

8.10 服务化与成本模型

路由

分级与缓存

小模型先试、低置信度升级到大模型(模型级联);精确缓存 + 语义缓存;按任务路由到不同规格的实例池。

扩缩容

按队列深度而非 GPU 利用率

GPU 利用率在 decode 阶段天然偏低(带宽受限),用它做扩缩容信号会永远不扩容。应该看排队时长、TTFT p95、队列长度。

成本

单位 token 成本

每百万 token 成本 = GPU 每小时成本 / (每 GPU 每小时产出 token 数)。注意输入与输出成本不同(输出受 decode 带宽限制,单价通常高数倍)。Prompt 缓存命中率是最大的成本杠杆之一。

可观测

必须采集的

TTFT/TPOT 的 p50/p95/p99、队列等待、缓存命中率、KV 占用率、抢占次数、输出长度分布、解析失败率、每请求 token 计费。

算一遍:成本量级。假设单卡每小时成本 2 美元,在 8B 模型 + 连续批处理下实测吞吐 3000 token/s(输入+输出混合): 2 / (3000 × 3600) × 1e6 ≈ 0.19 美元/百万 token。
若把并发从 8 提到 64(batch 更大),吞吐可能到 8000 token/s,单位成本降到约 0.07 美元/百万 token——但 TPOT 会变差。成本、延迟、SLO 三者必须一起谈。
索引。
  • 系统与调度:Efficient Memory Management for Large Language Model Serving with PagedAttention(vLLM)|Orca: A Distributed Serving System for Transformer-Based Generative Models(连续批处理)|SGLang / RadixAttention|DistServe、Splitwise(PD 分离)
  • 注意力与算子:FlashAttention 1/2/3|FlashDecoding|PagedAttention
  • 量化:GPTQ|AWQ|SmoothQuant|LLM.int8()|Marlin|FP8 Formats for Deep Learning
  • 解码加速:Fast Inference from Transformers via Speculative Decoding|Medusa|EAGLE|Lookahead Decoding
  • KV 优化:H2O|SnapKV|StreamingLLM
  • 工具:vllm、sglang、TensorRT-LLM、llama.cpp、genai-perf、locust、vllm bench serve
本章自查。① 为什么 decode 是带宽受限,这直接推出哪两个最重要的优化方向?② 8B GQA 模型 32K 上下文、32 并发需要多少 KV 显存?③ 什么情况下投机解码会让吞吐下降?④ 为什么 PD 分离能同时改善 TTFT 与 TPOT?⑤ 为什么自动扩缩容不该用 GPU 利用率做信号?⑥ goodput 和吞吐差在哪,为什么前者才对?

9. 专题:Jev 与"从 logits 读决策"

这一章回应一个具体的新概念:一个项目声称"工作在 logits 等中间过程上"。我们会把它拆成(1) 它到底指什么、(2) 机制的哪一部分是真的新、(3) 与已有技术的血缘、(4) 哪些数字不能信。本章所有关键论断都标注了证据等级。

本章的证据等级标注。 已核实多来源一致,或本文件作者直接读过原文; 厂商宣称只有厂商/作者自测来源,不可当作客观事实; 独立实测第三方测量,附样本量; 无法验证没有任何公开可靠来源。
本章写于 2026-10-04(该产品公开发布约三周后),属于第 0.5 节定义的快速演进内容,半年内即可能过时。

9.1 先钉死指称:这里的 "Jev" 指什么

已核实本文所说的 "Jev",指 TypeSafe AI 于 2026 年 9 月中旬发布的托管型"类型化决策模型"(typed decision model)服务。它是闭源的商业 API 产品,不是论文、不是开源架构、也不是某个 GitHub 仓库。
  • 调用形态:调用方提交 state(一段描述现状的文本)加一组带类型的问题,服务返回每个答案的概率与置信度,不产出任何自由文本。
  • 三种问题原语:Choice(多选)、Noul(布尔;命名来自内部术语)、Score(有界评分,取概率加权期望)。
  • 按请求声明候选:候选集合在请求时给出(而非训练时固定标签集),这是它相对传统分类器的主要接口差异。
  • 命名取自杰文斯悖论;厂商自称首个 "System One Model"(借用卡尼曼的双系统隐喻),训练方法自称 RLCD。
最容易出错的地方:区分"Jev"与一堆同名复刻。已核实生态里已经出现大量第三方实现与衍生项目,它们的名字里都带 jev,但都不是 TypeSafe 的 Jev:LocalJev(GitHub Next 官方,开源参考实现)、AnyJev、OpenSourceJev、jev-serve、Laya、SemIf、JevLite、PixelJev、Visual Jev 等。
读任何一篇关于 Jev 的文章时,第一件事是确认它指的是哪个 artifact:托管 API、LocalJev、还是某个复刻。三者的机制、可复现性、性能数字完全不同,混着引用会得出矛盾结论。
不要把它和这些东西混为一谈。
  • "Jev = 扩散语言模型的一次去噪"——错。一次去噪只是把 Jev 风格接口套用到文本扩散模型上的一种实现路径(见 9.4),不是 Jev 的定义或核心机制。
  • Jev = logit lens——错。logit lens 是读中间层表示的可解释性探针(第 6.5 节),与产品接口无关。
  • Jev = 投机解码——错。投机解码是纯加速技术,不改变接口语义。

9.2 它解决的问题:把开放式生成变成有界决策

传统做法要"让模型输出一个类别/概率",标准套路是让它把答案写成文本或 JSON,然后解析。这条路径上有四个成本项:

成本 1

逐 token 自回归

为得到几个概率数字,要跑完整条解码循环——每一步都受带宽限制(第 8.1 节),而其中绝大部分计算与"这几个数字"无关。

成本 2

格式风险

模型可能写出非法 JSON、多写解释、把数字写成中文、或在概率上加引号。要把这条路径做稳,需要约束解码甚至重试。

成本 3

解析与重试

格式错误就要重试,重试又会重新付出上面两项成本,且尾部延迟不可控。

成本 4

概率语义被破坏

模型"写出的 0.82"是被采样出来的一个 token,不是模型对该类别的真实后验概率(对照第 2.7 节的清单)。

核心洞察(这一条是本专题最有价值的部分):如果一个问题本来就只需在有限个候选中选一个,那么它根本不需要"生成"——它的答案已经存在于某一次前向的 logits 里。要做的只是:把候选映射到 token、在正确的位置读出这些 token 的 logit、softmax 并归一化到候选集合上。
这不是新数学,而是把已有的可能性产品化:从"让模型写 JSON"变成"从 logits 里读答案"。

9.3 机制:受限 softmax,以及它和近邻技术的精确区别

已核实核心机制(多来源描述一致,且与第 2.5 节的"用法 A:单 token 槽位读取"完全对应):
1. 把 state + 问题渲染成 prompt,让答案落在某个固定位置
2. 保证每个候选标签映射到【单个 token】(多 token 候选由编译器变换成单 token 字母等)
3. 取该位置 next-token 分布的 logits
4. 只保留候选标签对应的那些 logit,做 softmax 并【重新归一化】
5. 返回归一化后的概率(+ 置信度/熵诊断),不生成任何 token
务必区分:这是"事后重归一化",不是"加性干预"。
技术对 logits 做什么是否改变候选间相对关系是否生成 token
受限 softmax 读出(Jev 类)取出候选子集,事后重新归一化否(但概率数值被放大)否
logit bias对指定 token 加/减一个偏置是(改写分布)是
约束/结构化解码把非法 token 置 −∞,然后继续逐 token 生成是(限制候选集)是
logprobs API直接暴露 next-token logprob否是(调用方自己取数)
分类头 / 线性探针在 hidden state 上接一个额外训练的头—否
一句话记法:受限 softmax 是"只在已有的分布里挑出我要的那几项并重新归一",约束解码是"限制它接下来能写什么但仍在写",logit bias 是"改写分布"。
已核实三个层次的实现,成本和可控性差异很大:
实现做法优点缺点
① 生成 JSON 再解析
LocalJev(开源参考实现)
让普通 chat 模型把概率值当 JSON 文本"写"出来,再校验解析,格式错就重试任何模型都能用、零改造扛下整条生成管线的开销;解析失败与重试;概率语义被采样破坏
② 从 logits 直接读
多数第三方复刻
改推理引擎,在答案位置取 logits、重归一化到候选标签无解码循环、无解析、无重试;数值上等价于从完整分布里取出相同标签再归一化需要引擎层改造(或支持 logprobs 的接口);候选必须是单 token
③ 扩散模型单步去噪读取
DiffusionGemma + vLLM 的结构化读取模式
文本扩散模型的输出是一个可预先固定大部分 token 的画布:把答案位留成单 token 槽位,只做一步去噪,从收敛步的 logits 读出各候选标签概率多个问题可与同一份 prompt 的 K/V 复用、共享一次前向;画布宽度大时配合稀疏输出投影收益是数量级的依赖扩散类模型;属于特定实现的路径,不是通用方案
关于"一次去噪"的正确表述。已核实vLLM 曾合并一个 PR,为文本扩散模型 DiffusionGemma(MoE 架构)加入"Jev 风格的结构化读取":答案位置留成单 token 槽位、单步去噪、从收敛步的 logits 读候选概率;随后有第三方推理引擎(含 .NET 生态的 TensorSharp)复现了该路径。
正确写法:"Jev 风格接口在文本扩散模型上的一种实现路径"。 错误写法:"Jev 就是扩散语言模型的一次去噪"。后者把一个实现特例当成了定义。
为什么"稀疏输出投影"在这里是关键优化。看第 2.2 节的算法:若画布宽度为 4096、词表 128k,稠密 logits 张量约 2.1 GB;而实际需要的只是"答案槽位 × 少量候选标签"那一小撮行(例如 64 题 × 26 候选 = 1664 行,约 6.6 KB)。
这不是"省一点",而是把 O(画布 × 词表) 压成 O(候选数),差 5–6 个数量级。它也是这类接口能在延迟上占优的主要结构性原因之一。
已核实 · 第三方复现机制已经被完整复现,并且发现两个必须修正的系统性偏差(AnyJev 技术报告,arXiv:2610.00831,2026-09-30,代码开源):
  • 做法是一次 prefill 完成:从预训练指令模型的答案位置读出,把 next-token 分布限制到候选 token 上。不需要生成,也不需要打补丁式的引擎改造。
  • 偏差一 · 标签先验(label prior):某些标签无论输入是什么都会拿到更高概率。
  • 偏差二 · 顺序偏差(position bias):候选在选项列表中的位置会影响概率。
  • 修正不需要任何梯度步或参数改动:除以从未标注输入上估计出的标签先验;对选项列表的 K 个循环轮换取对数概率平均。
  • 实测效果:在两个 20 选项任务上,循环轮换把「顺序翻转率」从 0.33 降到 0.14 与 0.18,并在 11/11 个模型上提升准确率。
  • 代价与优化:读全部轮换需要 K 次 prefill。用一个在未标注状态上选出的停止规则,读取次数可从 18 降到约 10.6(服务实测 7.3),于是在 vLLM 上每秒多服务 2.2 倍的决策。
工程含义:如果你要自己实现这类接口,先验校正与顺序轮换不是可选项。不做这两件事,返回的概率同时取决于「标签是谁」和「排在第几位」;而如果你的评测集不随机打乱选项顺序,你根本发现不了这个偏差。

9.4 收益:厂商宣称 vs 独立实测

口径数字说明
厂商宣称加速 20–200×,成本降至 1/40–1/400,延迟 70–500 ms;首页曾出现 193.6× / 444.6× 一类的对比数字不是实证结果。其对比的分母是"前沿大模型做开放式生成",属于任务不对称的比较(一个在做有界选择,一个在生成长文本)。"输出免费"是定价政策,不是物理事实
独立实测社区汇总中位数约为 加速 7×、成本降至约 1/30、延迟约 76 ms(样本量分别在数百量级);独立开发者用真实邮件分类基准测得 4.1–8.5×比厂商数字小一个数量级,但仍然是显著的。这才是可用于规划的量级
独立实测特定实现对比同硬件下的 LocalJev 报 "快 4–5 倍"作者自己注明是特定硬件 + 特定量化(16 GB 级 GPU、Q4_K_M)+ 特定负载,并明确提醒不同来源的公布数据不能横向比较
独立实测学术审计(arXiv:2609.32160,审阅 2026-09-19 至 09-24 间的 28 篇论文):类型化读出尚未显示出独立于同类"标签概率读出"的准确率优势;最清晰的收益在延迟与成本这是本章最该记住的一条独立结论:它是接口与效率的进步,不是准确率的突破
取舍:4–8× 与 193× 之间的差距从哪来。不是有人撒谎,而是基线不同:
  • 与"大模型生成长文本"比 → 数量级差异(任务不对称)。
  • 与"小模型 + 约束解码 + 只取标签位置 logprob"比 → 折扣到个位数倍数(同任务比较)。
  • 与"专用分类器(如微调的 BERT 类)"比 → 在固定标签集场景下,专用小模型可能更快更准;Jev 的价值在候选集在请求时可变、零训练接入。
所以判断它值不值得用,要问的是:"我的候选集是不是频繁变化、是否零样本、我是否愿意为省下训练与维护成本而付出一些准确率。"

9.5 边界与风险

限制内容等级
表达能力受具体实现约束,差别很大:某条扩散模型路径明确拒绝多 token 候选、图像输入、问题依赖链、多步去噪与长思考模式;而第三方方案用括号数字标识符(如 [1])把选项映射到单 token,可支持任意选项数,并声称原生支持图像上的多模态决策已核实
规模上限单请求问题数有上限(如 64),每题候选数有区间(如 2–26 或 2–255,视实现)已核实
置信度不是校准正确率返回的是条件概率与熵诊断。实现方文档明确建议"在自己的留出样本上评估后再定阈值"——这正是第 2.8 节讲的问题已核实
对提示注入脆弱独立研究(数万次调用量级)显示:类型化输出确实守住了"不返回未声明的选项"(攻击目标被选中比例很低),但注入能可靠地推动概率质量。安全界的总结很到位:输出格式约束的是模型能说什么,不是它能被说服信什么独立实测
非确定性重复调用同一请求,返回的概率会变(有报告称在两位小数网格上波动,幅度约 1% 量级)。这与"确定性结构化决策"的营销话术存在张力独立实测
闭源与不可复现架构、参数量、训练数据、奖励函数均未公开;厂商不发布公开基准;据称其评测的参考答案取其他前沿模型输出的平均,属于自证闭环无法验证
跨版本稳定性现有研究基本只测了单一版本快照,跨版本行为无公开数据无法验证
注入的量化数据基于 510 个重构 InjecAgent 案例的研究(arXiv:2609.28613):恶意内容会移动动作概率,但很少真的让模型选中攻击者目标(新验证集上约 1.8%);使用分数反馈的自适应攻击可把优化中观测到的最高攻击目标概率翻倍,并把成功率推到约 3.5%;成功案例与初始决策边界很小或攻击者对观测的控制更强相关。结论是 schema 约束的输出改变但未消除注入风险独立实测

9.6 血缘关系:它的祖先都是成熟技术

独立实测学术审计把它逐条对齐到已有技术,结论是实质新意主要在"打包":
祖先技术相同之处
Verbalizer / cloze 式分类(PET、LM-BFF 等)把标签填进模板空位,用语言模型对标签 token 的概率做分类
GPT-3 时代的 likelihood scoring用候选文本的 logprob 打分并比较
语法约束解码保证输出落在合法集合内
Yes/No 式 reranker(monoT5、Qwen3-Reranker 等)用"是/否"标签 token 的 logit 做相关性判定
零样本 NLI 分类器把分类转成蕴含判定,读标签概率
Reject option / learning to defer / 模型级联低置信度时拒绝或升级到更强模型
温度缩放与"proper scoring rules"下的强化学习让输出的概率本身成为可优化、可评估的对象
打包层面的三点差异(这才是它值得关注的地方):① 候选集在请求时声明,不需要为每个标签集训练;② 一次前向可回答同一 state 的多个相互独立的问题;③ 把概率本身当作产品(配合校准训练与置信度诊断)。
关于"新架构"的说法。无法验证厂商声称使用"新架构 + 并行采样 + RLCD 训练法",并称其"既不小也不是 LLM"。但架构从未公开,也没有独立验证。社区里流传的"encoder-only + 分类头""并行采样器"等说法均属推测。
写作与选型建议:把它当作一个行为已知、实现未知的黑盒 API 来评估——只信你能自己测出来的部分(延迟、成本、在你数据上的准确率与校准)。
已核实 · 独立实测更直接的独立结论是:通用 LLM 本来就具备这种能力。有工作(arXiv:2610.02076,2026-10-01)在不改架构的前提下,从括号数字标识符(如 [1])的 next-token 概率里直接提取决策,并给出免训练配方与一套微调目标(tree-factorized listwise 损失,并用 KL 把辅助预测锚定到基座模型):
  • 无需训练时,4B 模型即可追平同主干的社区 Jev 类实现,优于「字母 logit」读法,支持任意选项数,并原生支持图像上的多模态决策。
  • 微调的收益是有针对性而非普遍的:明显改善弱模型与特定任务(如多选项意图路由),对强主干收益递减。
  • KL 锚定可以避免对话生成能力退化;在强模型上 LoRA 表现最好。
把三条独立结论放在一起,就是本章最重要的判断:这类接口代表的是「把已有能力标准化、产品化」的进步,而不是一项超出通用 LLM 的新能力。这也正好解释了为什么它的收益集中体现在延迟与成本,而非准确率——第 9.4 节的独立审计给出了同一个结论。

9.7 工程落地建议

可以用

适合的场景

高容量、低风险的初筛层:工单分类、意图识别、内容打标、路由决策、需要概率而非文本的评分。特点是:候选集频繁变化、零样本接入、对延迟敏感、错了可以被下游兜住。

别用

不适合的场景

高后果决策的唯一依据(放款、医疗、权限授予);需要多 token 或自由文本答案;问题之间存在依赖;输入不可信且没有隔离措施(注入风险)。

无论用哪个实现,五条工程纪律:
  1. 自己测校准:在留出集上画可靠性图,定阈值。不要相信任何"置信度"直接等于正确率。
  2. 设升级路径:低置信度 → 更强模型或人工。这正是 reject option 的经典用法。
  3. 把输入当不可信:外部内容进 state 前做来源标注与清洗;对概率质量的异常偏移做监控。
  4. 离线对比要同任务:与"小模型 + 约束解码 + 标签 logprob"这种同任务基线比,而不是与大模型生成长文本比。
  5. 锁定指称与版本:文档里写清用的是托管 API 还是某个开源复刻、哪个版本;否则半年后无法解释数据差异。

9.8 待核实清单(下次刷新时优先查这些)

  • 架构、参数量、训练数据与 RLCD 奖励函数是否公开,或是否出现独立复现。
  • (已部分解答)机制层面已有第三方复现与实测(见 9.3:标签先验与顺序偏差、11/11 模型提升、vLLM 上 2.2× 决策吞吐);但托管服务本身仍没有独立的公开基准对比。
  • 厂商对比数字的原始测量协议与方差是否公布。
  • 跨版本的行为稳定性数据。
  • 注入防御是否有实质改进。当前证据是:自适应攻击可把成功率从约 1.8% 推到约 3.5%(见 9.5),需对照第 6.2 节的结构性结论一起看。
  • 主流推理框架是否把"单 token 槽位读取"做成通用能力(若成为标准,这类接口会变成默认选项,而非独立产品)。
来源。读者应自行核验
  • TensorSharp 支持 Jev 模式了:一次去噪,直接读出决策(张善友,腾讯云开发者社区,2026-09-24)——本文件中"实现路径 ③""稀疏输出投影""能力上限与拒绝项"的直接来源,作者本人已注明数字的硬件与量化条件。
  • githubnext/localjev——"实现路径 ①"的开源参考实现(生成 JSON 再解析)。
  • rreinold/jev-serve、ShaileshRawat1403/AnyJev、sabeel111/OpenSourceJev——第三方复刻,用于观察机制差异,不代表托管 Jev 的实现。
  • (本节条目已由下方四条 arXiv 引用取代,保留以说明早期核验状态)学术侧:对早期证据的审计、机制最透明的开源实现(含 hidden state 上拟合线性头的变体)、以及"LLM 本来就是 Jev-style"一类论述。
  • arXiv:2609.32160 — Typed Decision Models: An Early Evidence Audit and Evaluation Checklist(2026-09-26):审阅 2026-09-19 至 09-24 间的 28 篇论文,结论为「类型化读出本身尚未显示出独立于同类标签概率读出的准确率优势;Jev 最清晰的收益在延迟与成本,难题上仍有准确率差距」,并给出 14 项评估清单。9.2 与 9.4 核心判断的依据。其自我限定:只覆盖单一托管模型发布后的前九天,应视为早期证据地图。
  • arXiv:2610.00831 — AnyJev Technical Report(2026-09-30):一次 prefill 读出、标签先验与顺序偏差及其免训练修正、循环轮换的停止规则与 vLLM 吞吐实测。代码:nokia-applied-research/AnyJev。9.3 的依据。
  • arXiv:2610.02076 — LLM2Jev: LLMs Are Already Jev-Style Decision Models — When and How to Fine-Tune Them(2026-10-01):括号数字标识符读出、免训练配方、tree-factorized listwise 损失与 KL 锚定。9.6 的依据。
  • arXiv:2609.28613 — Decision Hijacking: Prompt Injection Attacks on Jev's Typed Probabilistic Decisions(2026-09-23):510 个重构案例的注入实验与自适应攻击数据。9.5 的依据。

说明:本章中标注"厂商宣称"的数字来自厂商公开材料与媒体报道;标注"独立实测"的来自第三方测量,其中部分为小样本或单一作者自测,已在表中注明样本量或条件。凡本文件作者未直接读到原文的条目,均标为"无法验证"或写入 9.8 待核实清单。

本章自查。① 用一句话说清 Jev 的机制(不许出现"魔法架构"这类词)。② 受限 softmax 与 logit bias、约束解码的区别分别是什么?③ "一次去噪"正确的限定语是什么,写错会犯什么性质的错误?④ 为什么厂商的 193× 和独立实测的 7× 可以同时为真?⑤ 为什么"输出是结构化、类型安全的"不能推出"输出可信"?⑥ 如果你要在生产里用它做初筛,必须补哪三件事?

10. 速查卡与自查清单

这一章是可以单独打印的部分:公式、形状、超参经验值、选型决策树,以及全文的自查清单。术语表在配套文件 llm-cheatsheet.html 中。

10.1 核心公式卡

要算什么公式示例
训练总算力FLOPs ≈ 6 × N × D8B × 15T token ≈ 7.2e23
推理单 token 算力≈ 2 × N(激活参数量)8B → 16 GFLOPs/token
显存:全参训练16N 字节(混精 + AdamW,不含激活)7B → 约 112 GB
显存:仅推理权重2N(bf16)/ N(INT8)/ 0.5N(INT4)8B bf16 → 16 GB
KV Cache2 × L × n_kv × head_dim × S × B × bytes8B GQA bf16 → 128 KiB/token
解码吞吐上限(带宽)带宽 / 权重字节数3.35 TB/s ÷ 16 GB ≈ 209 token/s(单序列)
算术强度FLOPs / Bytes,与硬件拐点比较decode ≈ 1,H100 拐点 ≈ 295 → 带宽受限
端到端延迟排队 + TTFT + (n_out − 1) × TPOT—
单位成本GPU 每小时成本 ÷ 每小时产出 token × 1e62 美元/时、3000 tok/s → 0.19 美元/M
困惑度PPL = exp(平均交叉熵)loss 2.0 → PPL 7.4
Chinchilla 参考D ≈ 20 × N(算力最优)7B → 140B token

10.2 形状速查(一次前向)

token ids        [B, S]
embedding        [B, S, d]
每层 Q           [B, S, n_heads,    head_dim]
每层 K / V       [B, S, n_kv_heads, head_dim]      # GQA: n_kv_heads < n_heads
注意力分数       [B, n_heads, S, S]                # prefill;decode 时 S→S_total
注意力输出       [B, S, d]
final norm       [B, S, d]
logits           [B, S, V]                         # 解码只需 [:, -1, :]
概率             [B, S, V]                         # softmax 在最后一维,fp32

10.3 超参经验值

阶段参数常见取值备注
预训练LR / warmup / 裁剪峰值 LR 随规模下降;warmup 数千步;grad clip 1.0用 μP 让超参可跨规模迁移
预训练batch(token 数)数百万 token 级用梯度累积凑;注意与 LR 的缩放关系
SFT 全参LR / epochs1e-5 ~ 2e-5 / 1–3超过 3 轮容易过拟合与风格僵化
LoRALR / r / α / target1e-4 ~ 2e-4 / 8–64 / 常用 2r / 全部线性层只挂 q,v 是老做法,效果通常更差
DPOβ0.1 左右太小 → 跑偏;太大 → 学不动
PPO / GRPOKL 系数、clip、采样数 GKL 0.01–0.1;clip 0.2;G 常 4–16奖励尺度与 KL 需联合调
推理temperature / top_p / min_p事实任务 0;创意 0.7–1.0 / 0.9–0.95 / 0.02–0.1报告结果必须附采样配置
服务max_num_seqs / max_model_len / gpu_memory_utilization按 KV 预算反推先算 KV 容量表再定并发

10.4 选型决策树

「延迟/吞吐该怎么优化」
  1. TTFT 太高?→ 查输入长度与队列(chunked prefill / PD 分离);查前缀缓存命中率;查是否被 decode 抢占。
  2. TPOT 太高?→ 显存带宽受限:上权重量化(INT4/FP8)→ 增大 batch → 低 batch 场景加投机解码 → 长上下文考虑 KV 量化。
  3. 吞吐不够?→ 连续批处理 → 增大并发(受 KV 限制)→ 前缀缓存复用 → 引入副本而非 TP。
  4. 成本太高?→ goodput 而不是峰值吞吐定容量 → 分级路由(小模型初筛)→ 缓存 → 按 SLO 选硬件规格。
  5. 长上下文贵?→ KV 量化 → 滑窗/驱逐 → PD 分离 → 重新审视是否真的需要那么长的上下文。
「要不要上某项技术」
  • 投机解码:只在低 batch、可预测输出、接受率高时开;高 batch 已算力饱和时关掉。
  • PD 分离:长输入 + 高并发 + 对尾延迟敏感时值得;小流量下利用率下降。
  • MoE:显存充裕、算力是瓶颈、能承受 all-to-all 复杂度时值得。
  • 量化:decode 主导选权重量化;prefill 主导需要激活量化;都必须按任务测精度。
  • RLHF/DPO/GRPO:有偏好数据选 DPO 起步;任务可验证(数学/代码)优先 RLVR + GRPO;需要在线探索与最强效果才上 PPO。

10.5 全文自查清单

逐条用"能不能不看文档答出来"判断。答不出来的章节回去打勾前先重读。

第 1–2 章 · 地基层

  • 说清一次前向的五个阶段与各自形状
  • 解释 GQA 为什么能把 KV 降到 1/4
  • 解释为什么 softmax 必须在 fp32、且要减最大值
  • 说清 logits 的三条性质与工程后果
  • 列出会让 logprob 失去概率语义的配置
  • 区分受限 softmax / logit bias / 约束解码 / 分类头 / logit lens

第 3–5 章 · 训练侧

  • 说明为什么去重同时改善泛化、隐私与成本
  • 写出 6ND 与 16N 并会算
  • 解释 TP 与 PP 对带宽要求的差异及摆放原则
  • 说出 loss spike 的标准处置流程
  • 解释 LoRA 省显存的机理(回到 16N)
  • 区分 DPO / GRPO / RLVR 各需要什么信号

第 6–7 章 · 对齐与评测

  • 解释提示注入为什么在结构上难根治
  • 说明为什么"格式受约束"不等于"输出可信"
  • 说出 judge 的至少三种偏差与缓解手段
  • 说明私有评测集为什么不可替代

第 8–9 章 · 推理与前沿

  • 解释 prefill 与 decode 的瓶颈差异及由此推出的优化方向
  • 会算 KV Cache 容量表并做容量规划
  • 说出投机解码何时有害
  • 解释 PD 分离为什么同时改善 TTFT 与 TPOT
  • 说明 goodput 为什么比吞吐重要
  • 用一句话讲清 Jev 的机制,并说出三条局限

10.6 更新日志

版本日期变更
v1.02026-10-04首版:第 0–10 章;Logits 独立成章(第 2 章);Jev 专题(第 9 章,按证据等级分栏);配套速查表文件。
v1.12026-10-04第 9 章补入四条已核验的一手文献并据此改写多节;新增附录 A · 故障排查手册。
下次刷新建议优先更新的部分:第 8.9 节框架对比(版本迭代快)、第 9 章 Jev 专题(快速演进 + 大量待核实项)、第 7.2 节基准地图(新基准与饱和情况)、第 5.3 节对齐方法表(新方法出现频率高)。

附录 A · 故障排查手册(症状 → 原因 → 处置)

正文各章的「常见坑」讲的是原理上会怎么错;这份附录讲的是线上真的出问题时先查什么。按四张表组织:训练 / 后训练 / 推理服务 / 评测与质量。

三步定位法(比任何一张表都重要)。
  1. 先定侧:问题出在训练侧(模型能力)、推理侧(延迟/吞吐/显存)、还是评测侧(结论不可信)?三者症状经常相似,但排查路径完全不同。经验判据:同一模型换一套推理配置就能复现 → 推理侧;换评测方法结论就翻转 → 评测侧。
  2. 做一个最小可复现样本:把 batch 降到 1、上下文截短、关掉所有优化开关(量化/投机/前缀缓存)。如果最小配置正常,就二分法逐个打开开关。
  3. 核对"数字口径":硬件、量化位数、batch、输入输出长度分布、采样配置、样本量——两项不一致,比较就无意义(贯穿全文的纪律)。

A.1 训练阶段

症状优先怀疑处置
loss 变 NaN / inffp16 溢出、学习率过大、坏数据批次改 bf16;降峰值 LR 并延长 warmup;开梯度裁剪;从最近 checkpoint 回滚并跳过该数据分片
梯度范数尖峰后 loss 抬升见第 4.7 节的六类原因按 4.7 的 runbook:回滚 + 跳批 + 降 LR;不要"等它自己恢复"
loss 正常下降但模型很笨shift by one 错位、loss mask 错、ignore_index 填错、数据未充分 shuffle做小样本过拟合测试:能否把 8 条样本背下来。背不下来一定是实现 bug,不是数据问题
多卡比单卡更慢TP 跨了节点、通信未与计算重叠、micro-batch 过小、PP 气泡过大重排拓扑(TP 进 NVLink 域,PP 跨节点);增大 micro-batch;用梯度累积补全局 batch;改用 interleaved PP
吞吐忽高忽低慢节点(straggler)、数据加载成为瓶颈、异步 checkpoint 未生效采集逐 rank 逐步耗时,不要只看总吞吐;把 dataloader worker 数与预取调大到 GPU 不再空等;checkpoint 改异步
续训后指标莫名下降数据序未恢复(等于重复喂数据)、LR schedule 被重置检查 dataloader 状态的恢复逻辑;这是最隐蔽也最贵的一类坑
显存够但 OOM长序列激活峰值、分块 CE 未开、碎片开梯度检查点;开分块交叉熵/词表并行;限制单样本最大长度
MFU 明显偏低算子未融合、重计算过多、通信未重叠对照第 4.4 节的带宽要求逐项核对;优先解决通信与气泡,再考虑算子

A.2 后训练阶段

症状优先怀疑处置
SFT 后通用能力退化灾难性遗忘混入一定比例预训练数据(replay);降 LR 与步数;改用 LoRA;对通用基准做回归门禁
SFT 后"随机不听话"、格式时好时坏训练与推理的 chat template 或 tokenizer 版本不一致把 template 固化成部署配置的一部分;用它重新渲染一批训练样本做单测;这是排查优先级最高的一项
模型开始模仿用户口吻自我回复loss mask 错位(用户轮也算了 loss)打印若干样本的 mask 可视化核对
LoRA 训练几乎没提升只挂了 q/v 投影、LR 过低、α/r 不匹配、数据量或多样性不足挂到全部线性层(含 FFN);LR 提到 1e-4 ~ 2e-4;保持 α≈2r;先做小样本过拟合验证通路
DPO 后回答明显变长、变啰嗦长度偏置(偏好数据里长回答天然占优)做长度配对的偏好数据;加长度正则;或改用对长度不敏感的偏好损失;监控胜者长度差
RL 后指标涨但人评变差奖励黑客独立人评/多族评委校准;监控长度、列表密度、自信措辞等表面特征;检查奖励模型是否被过度优化
安全对齐后大量误拒拒答样本占比过高、阈值过激在偏好数据里补"不该拒就别拒"的一侧;分类型统计误拦率而不是只看平均
推理模型的思考段复读或超长思考段模板/终止标记与训练不一致、max_tokens 过大、采样温度过高核对思考块边界标记;限制思考长度;降低温度

A.3 推理与服务

症状优先怀疑处置
TTFT 突然翻倍抢占重算(显存不足丢 KV 后重算 prefill)、长输入阻塞队列、前缀缓存失效查抢占计数与队列等待;开 chunked prefill;核对前缀是否每次都变(时间戳、随机 ID 会让命中率归零)
TPOT 抖动大(尾延迟差)长 prefill 混入同一批次、batch 组成随流量变化、CPU 侧采样/分词成瓶颈开 chunked prefill;限制单批 token 总量;把分词与后处理移出关键路径
OOM 但看起来显存还够KV 碎片、块大小不当、并发按权重估算了按第 8.3 节公式重算:权重 + KV×并发 + 缓冲;确认分页 KV 已启用
吞吐远低于预期未开连续批处理、并发太小(KV 限制)、无量化、TP 过度而副本不足按第 10.4 节决策树逐项排查;用 goodput 而不是峰值吞吐评判
开了量化反而更慢没有融合反量化 kernel,或实际没走低比特 GEMM换用带融合 kernel 的实现(如 Marlin 系);确认日志/算子层面确实是 INT4/FP8 路径
投机解码没有收益甚至更慢高 batch 下已算力饱和、草稿接受率低、额外显存挤占 KV监控接受率与平均接受长度;只在低 batch、可预测输出的负载上开
输出重复、陷入循环采样配置(top-p/惩罚缺位)、KV 量化精度、上下文过长导致退化调 min_p/重复惩罚;回退 KV 量化做对比;截短上下文试
结果无法复现采样参数、kernel 实现、batch 组成、框架版本不同固定并记录完整配置(含框架与 kernel 版本、seed);把"报告采样配置"变成规范
长上下文"中间的信息丢了"lost in the middle;位置外推不足做位置 × 长度的二维评估;把关键信息放在开头或结尾;必要时用检索而非超长上下文
MoE 服务 GPU 利用率低且波动batch 内专家负载不均、EP 布局不佳、容量因子设置不当增大并发让专家负载摊平;调整 EP 与专家放置;观察 token 丢弃比例
扩缩容不生效用了 GPU 利用率做信号(decode 天然偏低)改用队列长度、排队时长、TTFT p95 作为扩缩容信号

A.4 评测与质量结论

症状优先怀疑处置
公开榜单高但线上表现差数据污染、格式过拟合、任务分布不同建私有评测集;用真实流量分布采样评测;对照第 3.5 节做去污染审计
同一模型两次评测分数不同采样参数未固定、样本量太小固定温度与解析规则;先用同一配置重复评测估计方差,再判断差异是否显著
换评委模型结论就翻转自我偏好、位置/长度偏置交换顺序各评一次只保留一致结论;多族评委投票;保留人工校准子集
换 tokenizer 后 PPL 不可比PPL 只在同一词表下有意义改用任务级指标;或换算为每字节的比特数(bits-per-byte)做跨词表比较
新模型整体更好但某类任务崩了只看平均分按任务类别分组报告;把关键类别做成发布门禁
上线后缓慢退化流量分布漂移、上游数据变化、缓存污染监控输出长度/拒答率/工具失败率/追问率;定期用固定私集回归
把排查沉淀成资产。每次事故后补三条:① 症状与判据写进本附录对应表;② 若属于原理性问题,补进对应章节的「常见坑」;③ 能自动化的判据(如 mask 可视化单测、template 一致性校验、goodput 回归)进 CI。否则同类问题会以不同面貌重复出现。
附录自查。① 拿到一个"慢"的投诉,你的前三步是什么?② 为什么"loss 在降但模型很笨"要用小样本过拟合测试来判定?③ 哪三类症状最容易被误归因到模型能力,实际却是评测或推理配置问题?