请添加图片描述

前言

昇腾 NPU 的编译优化依赖静态 shape——编译时确定了输入大小,GE 才能做内存规划、算子融合、内核选择。但实际业务里,输入 shape 经常变化:图片大小不固定、文本长度有长有短、batch_size 随负载调整。

怎么处理?


问题一:文本长度变化,每条请求都不一样

输入是文本,tokenized 之后长度在 32 到 512 之间。每条请求都要重新编译吗?

不用。有两种方案:

方案 A:Padding 到固定长度

把所有输入 padding 到最大长度(比如 512)。短的文本用 0 填充,attention_mask 标记哪些位置是填充。模型只编译一次,运行时不用重编译。

代价:padding 浪费计算。长度 64 的文本,padding 到 512,浪费 87% 的计算量。

方案 B:按档位编译

把长度分成几个档位:32、64、128、256、512。运行时根据输入长度,选择最近的档位,用对应的 .om 文件。ATC 编译时指定:

atc --model=model.onnx \
    --dynamic_batch_size="1,2,4,8" \
    --input_shape_range="input:[32,512]"

生成一个支持多档位的 .om 文件,内部是多个子图,每个子图对应一个档位。运行时自动选择。

代价:.om 文件变大(多个子图打包在一起),编译时间变长(要编译多份)。

推荐:短文本多的场景用方案 B,长文本为主的场景用方案 A。


问题二:图片尺寸不固定,有 224×224、384×384、512×512

目标检测模型,输入图片 resize 到不同尺寸,检测不同大小的目标。

方案:把 resize 也放进模型里

原始流程:CPU resize → 搬到 NPU → 模型推理。改成:原图直接搬到 NPU → NPU resize + 推理。

在模型前面加一个 ops-adv 的 resize 算子,输入是原始图片,输出是 resize 后的图片。这样模型输入固定是原始图片大小(比如 1080p),resize 在 NPU 内部完成,GE 能做优化。

ATC 编译时:

atc --model=model_with_resize.onnx \
    --input_shape="image:1,3,1080,1920"

输入固定 1080p,resize 算子在模型内部,shape 变化不影响编译。


问题三:batch_size 随负载变化,有时 1,有时 32

在线服务,白天高峰 batch=32,凌晨低谷 batch=1。

方案:动态 batch 编译

ATC 支持指定 batch_size 的范围:

atc --model=model.onnx \
    --dynamic_batch_size="1,2,4,8,16,32"

生成的 .om 文件支持这 6 个 batch_size,运行时根据输入自动选择对应的子图。不需要重启服务。

注意:batch_size 范围不要设太宽。1 到 32 可以,但 1 到 128 就不推荐了——子图太多,.om 文件膨胀,加载时间变长。


问题四:输入 shape 完全随机,没法预测

某些场景,输入 shape 完全随机(比如用户上传的图片,分辨率和宽高比都不确定),没法预先编译所有可能的 shape。

方案:fallback 到 CPU

NPU 不擅长处理完全动态的 shape。对于这种场景,可以:

  1. 在 CPU 上做 shape 相关的预处理(resize、padding)
  2. 把处理后的固定 shape 数据送到 NPU 推理

或者:用 Ascend CL 的动态 shape API(aclSetTensorShape),运行时动态设置 shape。但这种方式性能会下降(GE 的优化没法完全生效),只适合 shape 变化不那么频繁的场景。


问题五:编译太慢,shape 一变就要重新编译

大模型(比如 LLaMA),ATC 编译一次要 20 分钟。如果 shape 经常变化,编译时间不可接受。

方案:离线编译 + 热加载

把常用的 shape 组合提前编译好,存成多个 .om 文件。运行时根据输入 shape,选择对应的 .om 文件加载。加载时间 <1 秒,比重编译快得多。

如果遇到未编译的 shape,两种选择:

  1. 按最近的已编译 shape 运行(可能浪费计算)
  2. 异步触发编译,临时用 CPU 推理,编译完成后切换到 NPU

动态 shape 的处理没有银弹,核心思路是「把动态的部分隔离出去」——要么在模型外做 padding,要么在模型内加算子。编译时只处理固定部分,运行时动态选择对应的子图。不要试图让 NPU 处理完全随机的 shape,那是 CPU 的主场。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐