1. 课程导入
当你把一个训练好的深度学习模型交给推理服务时,最先遇到的现实问题往往不是模型结构,而是“用什么数值精度跑”。全 FP32 精度高但显存占用大、吞吐低;全 INT8 速度快、显存省,却可能让精度掉到不可接受。混合精度部署(Mixed-Precision Deployment)正是为解决这一矛盾而生的工程方法:它不追求“全模型统一精度”,而是根据每一层、每一算子对数值误差的敏感程度,分别选择 INT8、FP16 甚至保留 FP32,从而在精度、延迟、显存、功耗之间取得可量化的平衡。
一、核心定义:混合精度不是“折中”,而是“分层决策”
混合精度部署指在同一个推理图中,允许不同张量、不同算子以不同数值格式执行,并在必要时插入量化/反量化(Quant/Dequant)节点完成格式转换。它的关键不是简单地把 FP32 换成 FP16,而是建立一套“敏感度—收益”判断:哪些层可以安全地降到 INT8,哪些层必须留在 FP16,哪些层(如 LayerNorm、Softmax、残差累加)需要 FP32 保护。
一句话理解:混合精度部署 = 量化策略(选精度) + 图改写(插转换) + 校准(定 scale) + 运行时调度(选 kernel)。
从工程视角看,它涉及四个层面的协同:算法层(敏感度分析、校准集选择)、图编译层(算子融合、格式传播)、运行时层(kernel 选择、内存复用)、服务层(批大小、并发、SLA)。任何一层缺失,都会导致“精度达标但性能不达标”或“性能达标但精度崩坏”。
二、整体知识框架:从模型到上线的五段链路
本课程后续 29 章将围绕一条完整链路展开。下图给出混合精度部署的整体知识框架,它把“精度选择”放在数据流与图结构之中,而不是孤立地讨论某个量化公式。
三、方法流程:一次可复现的混合精度落地
下面给出一个可复现的最小流程,适用于 PyTorch → ONNX → TensorRT 或 ONNX Runtime 的典型链路。注意每一步都要保留可回滚的检查点。
# 1. 导出 FP32 基线模型
python export_onnx.py --model resnet50 --opset 17 --output fp32.onnx
# 2. 准备校准集(500~1000 张有代表性样本)
python build_calib.py --data ./calib --num 800 --output calib.npy
# 3. 敏感度分析:逐层尝试 INT8,记录精度损失
python sensitivity.py --onnx fp32.onnx --calib calib.npy --report sens.json
# 4. 生成混合精度策略:敏感层保留 FP16/FP32
python build_policy.py --sens sens.json --threshold 0.5 --output policy.json
# 5. 量化并编译
trtexec --onnx=fp32.onnx --int8 --fp16 \
--calib=calib.npy --precisionPolicy=policy.json \
--saveEngine=mixed.plan
# 6. 精度回归 + 性能压测
python eval_accuracy.py --engine mixed.plan --dataset val
trtexec --loadEngine=mixed.plan --batch=8 --iterations=500
其中第 3 步的敏感度分析是混合精度与“全 INT8”最大的区别。常见做法是逐层替换为 INT8,观察 Top-1/Top-5 或 mAP 的下降幅度,再结合阈值决定该层精度。阈值不是固定值,而是由业务可接受的精度损失反推。
四、案例场景:ResNet50 与 BERT 的不同选择
不同模型结构的敏感层分布差异很大。下表给出两个典型场景的对比,帮助建立“按结构选精度”的直觉。
| 模型 / 场景 | 推荐精度分配 | 关键敏感层 | 预期收益 |
|---|---|---|---|
| ResNet50 图像分类 | 卷积 INT8,首尾层 FP16,残差累加 FP32 | 第一层卷积、最后一层全连接、BN 折叠后累加 | 显存约降 3 倍,吞吐约升 2 倍,Top-1 掉点 < 0.3% |
| BERT-base 文本推理 | MatMul INT8,LayerNorm/Softmax FP16,Attention 累加 FP32 | LayerNorm、Softmax、残差连接、位置编码 | 延迟约降 40%,显存约降 2 倍,F1 掉点 < 0.5% |
| 检测模型 YOLO 系列 | 主干 INT8,检测头 FP16,NMS 后处理 FP32 | 检测头回归分支、NMS、坐标解码 | mAP 掉点 < 1%,帧率提升 1.5 倍以上 |
经验法则:归一化、指数、累加、坐标回归、小通道卷积通常对量化更敏感;大通道卷积、矩阵乘、逐元素乘加通常更耐受 INT8。
五、常见误区与复盘
- 误区一:混合精度就是 FP16 + INT8 随便混。实际上必须有敏感度依据和校准数据,否则精度不可控。
- 误区二:只看精度不看延迟。插入过多 Q/DQ 节点会引入额外转换开销,可能抵消 INT8 收益。
- 误区三:校准集随便取几张图。校准集分布必须贴近真实业务输入,否则 scale 偏移会导致系统性掉点。
- 误区四:忽略算子融合。Conv+BN+ReLU 融合后再量化,与未融合分别量化,结果差异很大。
- 误区五:没有精度回归基线。没有 FP32 基线,就无法判断掉点是否由量化引起。
复盘要点:每次调整精度策略后,必须同时记录三项指标——精度(Top-1/mAP/F1)、延迟(P50/P99)、显存峰值。只优化其中一项,往往会在另两项上付出代价。
六、学习目标与工程价值
完成本课程后,你应当能够:独立完成一次从 FP32 到混合精度的端到端部署;读懂敏感度报告并制定精度策略;定位量化掉点的具体层;在 TensorRT / ONNX Runtime / PyTorch 等不同后端上复现同一策略;并用数据说明混合精度带来的显存、吞吐与成本收益。
混合精度部署的工程价值,最终体现在三个可量化的维度:精度可控(误差可测量、可回归)、性能提升(显存下降 2~4 倍、吞吐提升 1.5~3 倍)、成本优化(单卡承载更多实例,降低 TCO 与功耗)。它不是一次性的“量化技巧”,而是一套贯穿模型分析、图编译、运行时调度与服务验证的系统工程方法。