用 CANN 做推理时,图像预处理通常在 CPU 上完成——读图、Resize、Normalize、格式转换,然后把处理好的 Tensor 拷到 NPU。AIPP(AI Preprocessing)改变了这个模式——它让预处理成为推理管线的一部分,跟模型推理在同一硬件链路上执行。

AIPP 在昇腾 NPU 上是一组可配置的预处理参数。模型加载时,AIPP 配置随 OM 模型一起加载到硬件中。推理时输入数据直接喂给 AIPP 硬件模块,预处理后的结果直接流入模型推理——中间不需要软件层面的干预。


AIPP 为什么存在

推理的预处理通常分三步:从存储读文件(CPU 负责)、做图像处理(CPU 或 DVPP)、把结果拷到 NPU。第三步的 CPU→NPU 搬运是隐藏的性能损耗——数据类型和内存布局在搬运过程中可能需要二次转换。

AIPP 的定位是融合这三步中的可配置部分:

传统流程:
CPU 读图 → CPU Normalize → CPU HWC→CHW → CPU→NPU 拷贝 → NPU 推理

AIPP 流程:
CPU 读图 → NPU AIPP 硬件做 Normalize+格式转换 → NPU 推理

CPU 只做最基本的图像读取(从磁盘到内存)。归一化参数、颜色空间转换、布局变换全部由 AIPP 在 NPU 上完成。


AIPP 配置项

AIPP 通过静态配置文件定义预处理流程。配置项在 ATC 模型转换时嵌入 OM 模型:

{
  "aipp_config": {
    "input_format": "YUV420SP_U8",     // 输入格式
    "src_image_size_w": 640,
    "src_image_size_h": 640,
    
    "csc_params": {                     // 颜色空间转换
      "matrix_r0c0": 256,
      "matrix_r0c1": 0,
      "matrix_r0c2": 359,
      // ... YUV→RGB 矩阵参数
    },
    
    "mean_chn_0": 128,                  // 各通道均值
    "mean_chn_1": 128,
    "mean_chn_2": 128,
    
    "min_chn_0": 0.0,                   // 归一化范围
    "max_chn_0": 255.0
  }
}

可配置的操作:

  • 颜色空间转换(CSC):YUV→RGB/BGR,使用配置的 3×3 矩阵
  • 归一化(pixel - mean) * var,各通道独立配置
  • 裁剪:从原图裁剪区域后再 Resize
  • Padding:Resize 后的图像如果尺寸不对齐,填充到对齐尺寸

推理链路中的 AIPP

AIPP 在推理链路中的位置:

原始图像(YUV/NV12)→ NPU 输入 Buffer
  ↓
AIPP 硬件模块:
  ┌─────────────────────────────┐
  │ CSC: YUV → RGB              │
  │ Crop: 裁剪兴趣区域           │
  │ Resize: 缩放到模型输入尺寸   │
  │ Normalize: (pixel-mean)*var  │
  │ Layout: HWC → CHW           │
  └─────────────────────────────┘
  ↓
模型推理(AI Core)

AIPP 的输出直接是模型输入的 float32 Tensor——布局、数值范围、通道顺序全部已对齐。AIPP 执行的整个过程不受 CPU 干预,它是模型加载时被编译进 OM 的一个硬件配置。


AIPP 与 DVPP 的对比

AIPP 和 DVPP 都做预处理,但定位不同:

特性 AIPP DVPP
处理内容 Normalize、CSC、Crop JPEG 解码、Resize、CSC
配置方式 静态配置(编译时确定) 运行时 API 调用
位置 推理管线内部(紧耦合) 推理管线外部(松耦合)
数据源 直接从输入 Buffer 读取 从 CPU 内存或文件读取
灵活性 低(参数编译时固定) 高(运行时可选)

AIPP 适合生产环境——预处理参数固定,不折腾配置。DVPP 适合开发阶段——想换预处理参数时不用重新编译模型。

两者也可以串联使用:DVPP 做解码和 Resize,输出喂给 AIPP 做 Normalize 和 CSC。DVPP 输出的是 YUV 数据,AIPP 的 CSC 正好处理 YUV→RGB 的转换。


图像推理中的典型场景

ResNet-50 图像分类部署时使用 AIPP:

atc --model=resnet50.onnx \
    --framework=5 \
    --output=resnet50 \
    --soc_version=Ascend910 \
    --insert_op_conf=aipp_resnet50.cfg

插入 AIPP 配置后,推理时输入只需是原始的 YUV 或 JPEG 数据(由 DVPP 解码后的格式)。Normalize 参数和均值由 AIPP 在 NPU 上处理。

如果多个模型需要不同的预处理参数——模型 A 用 mean=[0.485,0.456,0.406],模型 B 用 mean=[0.5,0.5,0.5]——每个 OM 模型携带独立的 AIPP 配置。推理时根据 modelId 自动选择对应的预处理参数。

AIPP 与 DVPP 的配合使用

AIPP 和 DVPP 可以协作完成预处理管线。一个典型场景:

  1. DVPP 解码:JPEG → YUV(硬件解码)
  2. DVPP Resize:YUV 缩放到模型输入尺寸
  3. AIPP:YUV→RGB Normalize → 输出 float32 Tensor

DVPP 处理完的 YUV 数据直接通过片上 DMA 传给 AIPP——不需要经过 DDR。AIPP 的 Normalize 参数在模型加载时已配置好,不需要每次推理传参。

协作流程完全在 NPU 内部完成,CPU 只负责提供原始图像数据。

AIPP 的局限性

AIPP 的主要局限在于参数必须在编译时确定。如果需要为不同输入使用不同的 Normalize 参数(比如多模型服务中各模型的预处理参数不同),需要多个 OM 模型各带独立的 AIPP 配置。

AIPP 也无法处理动态形状的预处理——如果你的模型输入形状在推理时变化,AIPP 的 Resize 目标尺寸无法在模型加载后修改。动态 Shape 场景建议用 DVPP + ops-cv 的运行时 API。

参考仓库

ops-cv 图像处理算子库

DVPP 视觉预处理文档

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐