ONNX模型在鲲鹏上推理慢一倍?先别急着换模型,查 NUMA 和算子后端

举报
yd_291746328 发表于 2026/11/07 18:21:23 2026/11/07
【摘要】 把一个在 x86 云服务器上跑得好好的 ONNX 推理服务迁到华为云鲲鹏 ARM 实例,预期是“架构换了但模型没变,性能应该差不多”。实际压测结果很尴尬:P99 延迟翻了一倍多,吞吐量掉了近四成,CPU 占用却上不去,像是在“等内存”。排查过程比预想的曲折,最终定位到两个 ARM 环境特有的隐形瓶颈。一、 第一个瓶颈:NUMA 跨节点内存访问的“隐性税”鲲鹏 920 采用多 NUMA 节点架...

把一个在 x86 云服务器上跑得好好的 ONNX 推理服务迁到华为云鲲鹏 ARM 实例,预期是“架构换了但模型没变,性能应该差不多”。实际压测结果很尴尬:P99 延迟翻了一倍多,吞吐量掉了近四成,CPU 占用却上不去,像是在“等内存”。排查过程比预想的曲折,最终定位到两个 ARM 环境特有的隐形瓶颈。

一、 第一个瓶颈:NUMA 跨节点内存访问的“隐性税”

鲲鹏 920 采用多 NUMA 节点架构,每个 CPU Socket 有自己的本地内存控制器。ONNX Runtime 的默认构建版本没有启用 NUMA 感知的内存分配,模型加载和推理时的内存页可能落在远端 NUMA 节点上。单次跨节点内存访问的延迟比本地访问高出数十纳秒,推理服务的高并发线程持续触发跨节点访问时,延迟抖动和带宽浪费会被显著放大。实测数据也印证了这一点:绑定 NUMA 本地节点后,ONNX 推理服务的 P99 延迟比未绑定时低约 40%,吞吐量提升 25%。

我们的修复很简单,但效果立竿见影:用 numactl 把推理进程绑定到单个 NUMA 节点,确保 CPU 和内存都在本地。

bash
numactl --cpunodebind=0 --membind=0 python serve_onnx.py
同时关掉内核的 numa_balancing,避免 CFS 调度器在运行中把线程迁移到远端节点、把缓存全部打掉。

bash
sysctl -w kernel.numa_balancing=0
二、 第二个瓶颈:ONNX Runtime 在 ARM 上回退到了低效后端

NUMA 绑定之后延迟有改善,但距离 x86 基线仍有差距。检查 ONNX Runtime 的构建信息才发现,使用的 pip 安装版本没有启用 ACL 或 DNNL 等 ARM 优化后端,可用 provider 列表中只有 CPUExecutionProvider。在 ARM64 上,这意味着部分算子回退到了标量或低效的 NEON 实现,尤其是 GatherND、DynamicQuantizeLinear 这类在 ARM 上缺乏高效内核的算子,会被迫走通用解释器路径。

解决路径有两条:一是换用华为云或 openEuler 生态提供的、启用了 ACL 后端的 ONNX Runtime 构建;二是对热点算子做定向替换或融合。我们优先换了启用 ACL 的版本,同时把 intra_op_num_threads 设成物理核数(而不是逻辑核数),避免超线程带来的缓存竞争。

python
sess_options = ort.SessionOptions()
sess_options.intra_op_num_threads = 8  # 物理核数,非逻辑核
三、 量化要谨慎:INT8 不是无脑加速

过程中也尝试了 INT8 动态量化来进一步压延迟,但在 ARM CPU 上,动态量化的收益不稳定——部分算子有高效 INT8 内核时提升明显,没有的反而引入额外的量化/反量化开销。相比之下,静态 QDQ 量化配合校准数据在 ARM 上的表现更可预期。我们最终对卷积为主的视觉子模型做了静态 INT8,对包含大量非规则算子的 NLP 子模型保持 FP32,整体延迟再降了约 15%,而精度损失控制在可接受范围内。

四、 总结

ONNX 推理在 ARM 云服务器上的性能退化,很少是“ARM 本身不行”。先做 NUMA 绑定、再检查 ONNX Runtime 的 ARM 后端是否启用、最后有针对性地选择量化策略,三步走完,大部分场景的性能可以回到甚至超过 x86 基线。反过来,如果在 NUMA 和算子后端都没对齐的情况下急着换模型或加机器,钱花了,问题还在。

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。