3. 硬件与软件栈概览

混合精度部署不是“把模型转成INT8就完事”,它首先是一个硬件能力匹配问题。同一份ONNX模型,在GPU、NPU、CPU上能否跑INT8、能否跑FP16、算子是否被加速器原生支持,决定了你最终选择哪条工具链、哪套量化策略。本节从硬件支持矩阵出发,再落到CUDA、TensorRT、OpenVINO三条主流软件栈的分工与协作方式。

一、核心原理:三种硬件的精度支持差异

GPU、NPU、CPU对低精度的支持逻辑完全不同。GPU以SIMT并行见长,FP16和INT8通常通过Tensor Core或DP4A指令加速;NPU是专用数据流架构,INT8往往是其“主粮”,FP16次之,FP32反而可能被拆解执行;CPU则依赖SIMD指令集,如AVX-512 VNNI、AMX,INT8吞吐提升明显,但延迟和功耗模型与加速器不同。

关键要区分三个层次:存储精度(权重以什么格式保存)、计算精度(乘加在什么位宽下执行)、累加精度(部分和用什么位宽累加)。很多“INT8模型变慢”的根因,是硬件只支持INT8存储,却把计算回退到FP32,或者累加溢出导致精度崩塌。

GPU / NPU / CPU 精度支持与工具链映射 GPU(NVIDIA) FP16:Tensor Core 原生加速 INT8:Tensor Core / DP4A FP32:CUDA Core 基准 累加:FP16→FP32,INT8→INT32 工具链:CUDA + TensorRT NPU(昇腾/瑞芯微等) INT8:主计算精度,吞吐最高 FP16:多数支持,次优路径 FP32:常被拆解或回退CPU 算子:需查算子支持列表 工具链:CANN / RKNN / 厂商SDK CPU(x86 / ARM) INT8:VNNI / AMX / NEON FP16:AVX-512 FP16 / ARMv8.2 FP32:通用基准,延迟稳定 优势:无需搬运,适合边缘 工具链:OpenVINO / ONNX Runtime 统一中间表示与转换路径 PyTorch / ONNX → 量化校准(PTQ/QAT) → 引擎编译(TensorRT/OpenVINO) → 部署推理 选型判断:先看算子支持,再看精度收益,最后看端到端延迟 INT8 不是万能:小 batch、动态 shape、非卷积算子可能回退 FP16/FP32

二、方法流程:从模型到硬件的落地路径

一条可复用的混合精度部署流程如下:

  1. 导出与规范化:将训练框架模型导出为ONNX,固定输入shape或标注动态维度。
  2. 硬件能力探测:确认目标设备是否支持INT8、FP16,以及关键算子(Conv、MatMul、Attention)是否在加速列表内。
  3. 量化校准:用代表性校准集统计激活分布,生成scale/zero-point;对精度敏感层保留FP16。
  4. 引擎编译:TensorRT生成plan,OpenVINO生成IR+blob,NPU生成离线模型。
  5. 精度与性能回归:对比FP32基线,检查余弦相似度、Top-1/Top-5、mAP,并测量P50/P99延迟。
建议先做“全FP16”基线,再逐步把卷积、矩阵乘替换为INT8。这样能快速定位是哪个算子导致精度下降,而不是一次性混在一起排查。

三、工具链分工:CUDA、TensorRT、OpenVINO

三者不是替代关系,而是不同层次的协作。CUDA是GPU的底层并行计算平台,提供kernel、流、显存管理;TensorRT构建在CUDA之上,负责图优化、层融合、精度校准和kernel自动调优;OpenVINO则面向Intel CPU、集成GPU和NPU,通过nGraph/IR做跨设备推理。

工具链 主要目标硬件 INT8支持方式 FP16支持方式 典型入口
CUDA NVIDIA GPU DP4A / Tensor Core 指令 __half / cublasH 自定义kernel
TensorRT NVIDIA GPU PTQ校准 + Q/DQ层 builderFlag FP16 trtexec / Python API
OpenVINO Intel CPU/GPU/NPU NNCF量化 + POT IR FP16转换 mo / benchmark_app
ONNX Runtime 跨平台 QDQ + Execution Provider FP16图优化 ort session

四、案例场景:同一模型的三种部署选择

假设你有一个ResNet-50分类模型,需要部署到三种环境:

  • 云端T4 GPU:用TensorRT,开启FP16 + INT8校准,batch=32时吞吐可提升2~3倍。
  • 边缘NPU盒子:用厂商SDK转INT8离线模型,注意检查ResNet的残差Add是否被支持,否则会回退CPU。
  • 工控机CPU:用OpenVINO,INT8在AVX-512 VNNI上通常有1.5~2倍加速,但小batch延迟优势不明显。
# TensorRT INT8 校准示例(trtexec)
trtexec --onnx=resnet50.onnx \
        --int8 --fp16 \
        --calib=calibration.cache \
        --workspace=4096 \
        --saveEngine=resnet50_int8.plan

# OpenVINO 量化与基准测试
pot -c resnet50.yml -m resnet50.xml
benchmark_app -m resnet50_int8.xml -d CPU -api async

五、误区与复盘

误区一:INT8一定比FP16快。在GPU上,如果batch很小或算子以element-wise为主,INT8的量化/反量化开销可能抵消收益,FP16反而更稳。

误区二:NPU支持INT8就等于所有算子都支持。很多NPU对动态shape、非4维张量、自定义算子支持有限,会静默回退到CPU,导致“看起来在NPU跑,实际在CPU跑”。

误区三:只看模型大小,不看端到端延迟。量化后模型变小,但前处理、后处理、数据搬运可能成为新瓶颈。

复盘时建议固定三张表:算子支持表(哪些层跑在什么精度)、精度对比表(FP32/FP16/INT8的指标)、延迟分解表(预处理、推理、后处理各占多少)。只有把硬件能力、工具链行为和业务指标对齐,混合精度部署才可复现、可维护。