对话:模型推理慢,怎么调


A:模型上线了,推理延迟 280ms,比预期高了一倍。

B:280ms 是什么模型?输入多大?

A:BERT-base,序列长度 512,batch=1。

B:单请求 280ms 明显偏高。BERT-base 在 910 上,序列 512,理论延迟是 80-100ms。差了 3 倍,先排查瓶颈在哪。

A:怎么排查?

B:看三个指标:AICore 利用率、HBM 带宽利用率、HCCL 通信时间(如果多卡)。用 npu-smi info -t usages 监控,推理的时候看实时数据。

A:AICore 利用率 45%,HBM 带宽利用率 60%,HCCL 不涉及(单卡)。

B:45% 太低了,正常应该 >70%。带宽利用率 60% 也偏低。说明瓶颈不在计算,在数据搬运。你的预处理在哪做的?

A:预处理在 CPU 上,用 transformers 库的 tokenizer。

B:tokenizer 本身不慢,但每次推理都要把 tokenized 结果从 CPU 搬到 NPU。PCIe 的带宽是 16GB/s,搬一个 (1, 512) 的 int64 tensor,大小是 4KB,理论耗时 0.25us。但实际搬运开销远大于这个------CPU 要准备数据、NPU 要接收、中间还有一次同步。batch=1 的时候,这个开销占比很大。

A:那预处理挪到 NPU 上?

B:对。昇腾有 ops-adv 仓库,里面有文本预处理的算子(分词、转 token ID)。但 tokenizer 的逻辑比较复杂,ops-adv 目前只支持基础操作(比如 lookup table)。如果模型用的是 BPE tokenizer,可能要自己写一个轻量版本。

A:写一个 tokenizer 算子工作量不小。有没有更快的方案?

B:有。把预处理和推理合成一个请求,减少 CPU-NPU 的交互次数。现在的流程是:CPU preprocess → 搬到 NPU → NPU inference → 搬回 CPU → CPU postprocess。改成:CPU preprocess → 搬到 NPU → NPU inference + postprocess(后处理也在 NPU 上做)→ 搬回 CPU。后处理就是取 argmax 和 softmax,很简单,用 Vector Unit 一行代码就能做。

A:改一下试试。


(半小时后)

A:改完了,延迟从 280ms 降到 180ms。还是比预期高。

B:180ms,进步了。AICore 利用率现在多少?

A:62%。带宽利用率 75%。

B:利用率上去了,但还是不够。再看计算图,BERT 的 Attention 算子有没有融合?

A:怎么看?

B:跑一遍推理,把 GE 的图导出来:export GENGINE_GRAPH_SAVE_PATH=./ge_graphs。然后用 Netron 打开,找 Attention 相关的节点。

A:看了一下,Attention 还是分开的:MatMul → Softmax → MatMul。没有合成 FlashAttention。

B:问题找到了。FlashAttention 没生效。ATC 编译的时候,模型要用 NPU 设备加载,GE 才能识别出 Attention 模式。你的模型是怎么加载的?

A:先在 CPU 上加载,然后 .npu()

B:这就是问题。CPU 加载之后,GE 看到的是一个普通的 PyTorch 模型,不认为是 Attention。改成:

python 复制代码
with torch.npu.device(0):
    model = BertModel.from_pretrained("bert-base")

这样 GE 在编译时能识别出 Attention 模式,自动合成 FlashAttention。

A:改一下,重新编译。


(编译后)

A:延迟从 180ms 降到 95ms。AICore 利用率 78%,带宽利用率 45%。

B:95ms 接近预期了。带宽利用率降到 45%,说明瓶颈转移到计算了,这是好事。还有优化空间吗?

A:跑 AOE 调优试试?

B:BERT 的调优收益通常在 10-20%。跑一下 GA,50 轮就够了。记得保存调优结果,下次编译直接加载。

A:调完之后延迟 82ms。满足预期了。


总结一下这次调优的关键:

  1. 预处理/后处理搬到 NPU,减少 CPU-NPU 数据搬运
  2. 模型用 NPU 设备加载,让 GE 识别出 Attention 模式,触发 FlashAttention 融合
  3. 跑 AOE 调优,进一步压榨 AICore 性能

从 280ms 到 82ms,提升 3.4 倍。单卡推理慢的问题基本解决了。

相关推荐
fanstuck5 小时前
1M 上下文能怎么用?我用 Seed Evolving 做了一个招标文件版本差异审查器
服务器·人工智能·数据分析·开源·aigc
墨舟的AI笔记7 小时前
React 组件库的 Tree Shaking:按需加载与副作用的工程化治理
人工智能
WoooChi8 小时前
DailyTech-20260724
人工智能·科技·业界资讯
zh路西法8 小时前
【CAM Grad-CAM Grad-CAM++】深度学习模型可解释性:从原理到YOLOv8部署实战
人工智能·深度学习·yolo·yolov8·grad-cam·cam
雨辰AI8 小时前
全集实战:企业级大模型服务化部署全栈指南|FastAPI 封装 + Nginx 负载均衡 + 高可用架构 从单机到生产一步到位
人工智能·ai·负载均衡·fastapi·ai编程
触底反弹8 小时前
Vibe Coding 不写 Git,等于悬崖边飙车
人工智能·git·面试
咖啡屋和酒吧9 小时前
健康管理:现代生活的科学守护
人工智能·生活·精选
星栈独行9 小时前
翻完 Pi 源码:它和 Codex、Claude Code 有何不同
开发语言·javascript·人工智能·程序人生
没有梦想的咸鱼185-1037-16639 小时前
AI-Python机器学习与深度学习技术:CNN/Transformer/扩散模型、SHAP可解释及Hermes智能体自动化
人工智能·python·深度学习·机器学习·chatgpt·cnn·transformer
船漏了就会沉9 小时前
Kimi K3 vs DeepSeek-V4:国产大模型的技术路线之争
人工智能