量化导出
这是 checkpoint-promotion 移交 PROMOTE 裁决后的最后一站:一个通过了四阶段关卡检查点的检查点仍然不会部署,除非它被导出为适合目标运行时的格式,并证明导出后仍然工作正常。REJECT 裁决永远不会到达这个技能——导出只从已提升的检查点开始。
输入: 一个已提升的检查点(或 LoRA 适配器)加上目标部署环境——GPU 类别、服务栈,以及长上下文/代码/数学工作负载是否在范围内。 输出格式: 一个选定格式的导出工件,加上一份冒烟测试差异报告,比较导出前和导出后 3-5 个黄金输出的差异。
格式映射
根据硬件和部署形态选择格式,而不是凭习惯——错误的选择要么浪费吞吐量余量,要么在特定工作负载上静默失败(见工作负载覆盖)。
- FP8 是 Hopper 级及更新 GPU 的默认选择。 它在内存使用几乎减半的情况下保留了接近 bf16 的质量,并且只要目标 GPU 支持且没有边缘设备约束,它就是安全的首选。
- AWQ INT4 针对不支持 FP8 硬件支持的较旧 GPU。 在新部署中 GPTQ 已被弃用——不要在全新的导出中使用它;AWQ 在相同位宽下具有更好的精度保持和更广泛的当前工具支持。
- GGUF 采用 Q4_K_M 量化,基于 imatrix 构建,是边缘/llama.cpp 格式。 用于本地或 CPU 相关的部署,而不是用于 GPU 服务吞吐量——它优化的是存储占用,而不是数据中心 GPU 上的 tokens/秒。
- NVFP4 仅限 Blackwell 大规模部署——且明确不适用于 GB10。 在 SM121(GB10)上,NVFP4 运行速度比 FP8 慢约 32%,因为除非内核编译为
sm_121a,否则硬件缺少原生的cvt.e2m1x2路径。在 GB10 目标上选择 NVFP4 是一种倒退,而不是升级——请在那里选择 FP8。 - 合并与仅 LoRA 是与量化格式分开的维度。 合并导出将适配器折叠到基础权重中:工件更大,但服务时无需基础模型依赖。仅 LoRA 保持适配器独立:工件小得多,但服务栈必须同时加载完全相同的基础模型——不匹配或错误版本的基础模型会静默改变输出。当工件可移植性比存储更重要时选择合并;当磁盘占用或多适配器服务更重要时选择仅 LoRA。
典型选择
核心格式选择权衡,以常见场景的查找表形式给出:
| 目标 | 工作负载 | 格式 |
|---|---|---|
| 数据中心 GPU | 通用聊天 | FP8 |
| 数据中心 GPU | 长上下文/代码/数学 | FP8 或 W8A8——绝不用 INT4 |
| 较旧 GPU 代 | 通用 | AWQ INT4 |
| 边缘设备/笔记本电脑 | llama.cpp 服务 | GGUF Q4_K_M + imatrix |
| GB10 | 任何工作负载 | 通过 vLLM 每日构建的 FP8,或通过 llama.cpp 本地的 GGUF——跳过 NVFP4 |
# 快速决策片段——完整映射见上表
hopper_or_newer: fp8
older_gpu: awq-int4
edge_llama_cpp: gguf-q4_k_m+imatrix
gb10_any_workload: fp8-vllm-nightly # 绝不在 GB10 上使用 nvfp4
工作负载覆盖
上述格式映射是默认值,但不是能适用于所有工作负载的规则。长上下文、代码和数学工作负载在 INT4 下会失败——量化误差在长序列和精确的令牌级推理中会累积,而这种累积在短而通用的提示中不会出现。对于这三类工作负载中的任何一种,即使目标硬件在成本上原本会证明 INT4 合理,也坚持使用 FP8 或 W8A8。
- 不要使用 MMLU 或类似广泛知识基准来验证此覆盖——它们不会暴露故障模式。使用实际任务评估来衡量——来自
eval-harness-first的黄金数据和评分器,通过导出工件运行——因为 INT4 在长上下文、代码或数学上的退化在知识基准变化之前就会表现为特定任务失败(上下文丢失、语法错误、算术错误)。 - 如果在这三类工作负载之一的 INT4 导出后任务评估退化,解决方法是切换格式,而不是重新调整量化配方——相同位宽的 AWQ 和 GPTQ 变体在这些工作负载上共享相同的累积误差故障模式。
冒烟测试
导出 bug 在文件级别是静默的——格式错误的导出仍然可能生成可加载的工件,因此文件存在检查毫无意义。冒烟测试对每个导出都是强制性的,任何格式都不能例外:
- 在实际目标运行时中加载导出的工件——FP8/AWQ 用 vLLM,GGUF 用 llama.cpp,而不是在不同于生产服务的框架中快速进行完整性检查。
- 通过它运行 3-5 个黄金提示——从
eval-harness-first维护的同一个eval/goldens.jsonl中提取,而不是一组临时新创建的提示。 - 将每个输出与导出前生成的相同提示、相同确定性采样设置进行比较——贪婪解码(temperature 0)和固定种子,在导出前和导出后的运行中持久化并重用,而不仅仅是名义上相同的配置。对于无损导出,字节匹配是关卡——任何差异都是 bug。 对于有损(量化)导出,字节匹配预计会失败;关卡改为任务评分器结果的一致性——参见
references/export-commands.md的冒烟测试脚本骨架。
作为一个关卡运行,而不是手动检查:
python smoke_test.py "$EXPORT_PATH" \
eval/goldens.jsonl pre-export-outputs.jsonl
# 任何前/后不匹配导致非零退出
故障特征
导出 bug 的实际表现,而不是一个简单的通过/失败标志:
- 模板不匹配表现为乱码或连篇的输出——导出中嵌入的聊天模板与检查点训练和评估时使用的模板不匹配,导致轮次边界或特殊令牌出现在错误的位置。
lm_head应用了错误的量化表现为偏离模板或语义无意义但看起来仍然流畅的输出——即使网络其余部分量化干净,输出头也丢失了它所需的精度。
切勿运送跳过此步骤的导出——检查点的 PROMOTE 裁决表示未导出的检查点是好的;它对导出管道没有任何说明。在量化方法或运行时版本升级后重新运行,而不仅仅是在第一次导出之后。每种格式的可运行命令序列以及冒烟测试脚本骨架:references/export-commands.md。
相关技能
checkpoint-promotion——此技能唯一有效的上游来源。没有PROMOTE裁决的检查点不会到达导出。eval-harness-first——拥有eval/goldens.jsonl,该技能冒烟测试从中提取 3-5 个提示,以及工作负载覆盖部分所需的用于长上下文/代码/数学验证的任务评估。finetuning-method-selection——其references/model-catalog.md是在根据上述格式映射选择格式之前检查硬件类假设(基础模型针对的 GPU 代)的地方。
Spark 用户: 在 GB10 上,通过 llama.cpp 的 GGUF 适用于本地服务,通过 vLLM 每日构建的 FP8 服务是另一个经过验证的路径——NVFP4 是要避免的一种格式(见上述格式映射异常)。安装 dgx-spark-ops 插件后,将 Spark 特定的服务和热管理问题委托给其技能,而不是在这里重新推导。