0
0

模型转换与推理部署实践:ATC、算子适配、精度调试与性能优化

模型转换与推理部署实践:ATC、算子适配、精度调试与性能优化

1. 从训练模型到线上推理服务的完整链路

深度学习模型从训练完成到真正部署到 GPU/NPU 上运行,通常需要经历多个阶段:

训练框架模型
(PyTorch / TensorFlow / MindSpore)
        ↓
模型导出
(ONNX / SavedModel / MindIR)
        ↓
模型转换
(TensorRT Engine / Ascend OM 等)
        ↓
精度调试
(保证转换前后一致性)
        ↓
性能优化
(降低延迟,提高吞吐)
        ↓
部署上线
(服务化、监控、扩缩容)

对于 LLM Inference 工程师来说,模型转换、精度调试和性能优化是连接算法模型与硬件执行之间的重要环节。


2. 模型转换:从通用模型到硬件执行模型

2.1 为什么需要模型转换?

训练阶段关注的是模型表达能力,通常使用:

  • PyTorch
  • TensorFlow
  • MindSpore

但是线上推理更关注:

  • 硬件利用率
  • 算子执行效率
  • 内存占用
  • 延迟和吞吐

因此需要将模型转换成推理引擎能够高效执行的格式。

例如:

PyTorch checkpoint
        ↓
ONNX
        ↓
TensorRT Engine
        ↓
GPU执行

或者:

PyTorch
        ↓
ONNX
        ↓
ATC
        ↓
OM模型
        ↓
Ascend NPU执行

3. ATC 转换是什么?

ATC(Ascend Tensor Compiler)是华为昇腾生态中的模型转换和编译工具。

它的作用不是简单修改模型格式,而是将通用计算图转换成适合昇腾 NPU 执行的离线模型。

典型流程:

ONNX模型
    ↓
ATC编译
    ↓
OM模型
    ↓
Ascend NPU运行

ATC通常会完成:

  • 解析计算图
  • 算子映射
  • 图优化
  • 算子融合
  • 数据布局调整
  • 精度类型转换
  • 针对硬件生成执行模型

因此 ATC 更接近一个针对 NPU 的模型编译器。


4. 模型转换中的算子缺失问题

不同框架和不同硬件支持的算子集合并不完全一致。

例如:

PyTorch Graph:

Conv
 ↓
LayerNorm
 ↓
FlashAttention

转换到目标推理平台时可能出现:

Unsupported operator: FlashAttention

原因:

训练框架支持该算子,但目标推理引擎没有对应实现。

常见解决方式:

方法1:算子替换

例如:

FlashAttention
        ↓
普通Attention

兼容性提高,但可能损失性能。

方法2:自定义算子

例如 TensorRT Plugin 或 NPU Custom Operator。

通过 C++/CUDA/NPU Kernel 实现缺失算子。

方法3:计算图改写

将高级算子展开为基础算子。

例如:

SiLU

转换为:

Sigmoid + Mul

5. 精度调试:为什么转换后结果不一样?

精度调试不是调模型参数,而是定位:

为什么同一个模型,在不同推理后端输出存在差异?

例如:

PyTorch:

cat: 0.998

转换后:

cat: 0.72

需要定位误差来源。


5.1 Layer级误差分析

比较转换前后的中间结果:

PyTorch:
Layer1 output
Layer2 output
Layer3 output

TensorRT/NPU:
Layer1 output
Layer2 output
Layer3 output

找到第一次出现明显偏差的位置。


5.2 FP32 / FP16 / INT8 精度问题

不同数据类型会影响数值精度:

FP32
 ↓
FP16
 ↓
INT8

例如:

  • Conv通常容易量化
  • Softmax、LayerNorm、Attention相关计算对精度更敏感

实际部署中经常采用混合精度:

Conv        INT8
MatMul      FP16
LayerNorm   FP32
Softmax     FP32

5.3 INT8量化调试

INT8需要校准数据集:

Calibration Dataset
        ↓
统计activation范围
        ↓
计算scale
        ↓
生成INT8模型

如果校准不合理,会造成模型精度下降。


6. 性能优化:让模型跑得更快

性能优化主要目标:

  • 降低延迟(Latency)
  • 提高吞吐(Throughput)
  • 降低显存/显存带宽压力

6.1 Kernel优化

GPU/NPU真正执行的是Kernel。

优化方向:

  • 使用高性能库
  • 使用Tensor Core
  • 优化访存
  • 编写自定义Kernel

例如:

普通CUDA Kernel
        ↓
Tensor Core优化Kernel

6.2 Kernel Fusion(算子融合)

原始计算:

MatMul
 ↓
Bias
 ↓
GELU
 ↓
LayerNorm

多个Kernel需要多次启动和读写显存。

融合后:

Fused Kernel

减少:

  • Kernel Launch开销
  • HBM访问次数

6.3 内存优化

GPU性能瓶颈很多来自数据搬运,而不是计算。

需要优化:

HBM
 ↓
Cache
 ↓
Shared Memory
 ↓
Register
 ↓
Tensor Core

减少高成本显存访问。


6.4 LLM推理特殊优化

大模型推理重点包括:

KV Cache

保存历史Attention计算结果,避免重复计算。

Continuous Batching

动态组合多个请求,提高GPU利用率。

Tensor Parallel

将大模型切分到多个GPU/NPU执行。

Quantization

例如:

FP16 70B模型
约140GB显存

INT4
约35GB显存

7. 激活函数与模型转换

模型转换中经常遇到激活函数算子不支持问题。

7.1 SiLU

SiLU定义:

SiLU(x)=x×sigmoid(x)SiLU(x)=x \times sigmoid(x)

因此:

SiLU(x)

数学上等价于:

x * sigmoid(x)

区别在工程实现:

SiLU

可能是一个融合算子,而:

Sigmoid + Mul

可能是两个基础算子。

模型转换时常通过算子展开提升兼容性。


7.2 GELU

GELU(Gaussian Error Linear Unit)是 Transformer 中常用激活函数。

作用:

  • 提供非线性能力
  • 平滑控制信息通过比例

常见形式:

GELU(x)=xΦ(x)GELU(x)=x\Phi(x)

工程实现可能展开为:

Erf + Add + Mul

或者:

Tanh近似实现

8. 对LLM Inference工程师的意义

完整能力链路:

模型格式理解
        ↓
ONNX / MindIR
        ↓
TensorRT / ATC / MindIE
        ↓
算子适配
        ↓
CUDA / NPU Kernel
        ↓
性能分析
        ↓
大规模推理部署

模型转换解决“能不能运行”。

精度调试解决“运行是否正确”。

性能优化解决“是否足够快”。

这三部分构成 AI Infra 工程师从模型到硬件之间的核心能力。