cann-recipes-infer - 昇腾NPU推理优化从入门到精通
帮一个团队做 LLaMA-2-7B 的昇腾NPU部署,他们踩了一个坑:模型跑起来了,但是速度慢得没法用。8 张图片的 OCR 任务,跑了 5 分钟还没出结果。
查了一圈,发现问题出在没做量化。FP16 的 7B 模型,光权重就 14GB,昇腾 910 的 16GB 显存根本装不下,要频繁做显存换入换出,性能暴跌。
后来用了 cann-recipes-infer 的推理配方,换成 INT8 量化,14GB 降到 3.5GB,同样的任务 15 秒搞定。
cann-recipes-infer 是什么
cann-recipes-infer 是昇腾CANN生态的推理配方库,提供主流大模型的昇腾NPU推理优化方案,包括量化、算子融合、批处理优化等。
在 CANN 五层架构里,cann-recipes-infer 位于:
- 应用层:直接面向终端用户,提供端到端的推理解决方案
- 依赖 ATB:推理加速调用 ascend-transformer-boost
- 依赖 GE:图优化调用 Graph Engine
配方涵盖的模型
cann-recipes-infer 目前覆盖以下模型:
| 模型类型 | 支持模型 | 量化精度 | 加速比(vs FP16) |
|---|---|---|---|
| LLM | LLaMA-2/3、ChatGLM、QWen | FP16/INT8/INT4 | 2-4x |
| VLM | LLaVA、MiniGPT-4、CogVLM | FP16/INT8 | 1.5-2x |
| OCR | PaddleOCR 适配版 | FP16/INT8 | 2-3x |
| 检测 | YOLO 系列 | FP16/INT8 | 2-3x |
环境准备
第1步:安装 CANN + ATB
参考之前的 ATB 安装教程,先把环境搞定。
第2步:克隆 cann-recipes-infer
git clone https://atomgit.com/cann/cann-recipes-infer.git
cd cann-recipes-infer
第3步:安装依赖
pip install -r requirements.txt
requirements.txt 里的关键依赖:
torch-npu:PyTorch 的昇腾NPU后端atb:昇腾 Transformer 加速库transformers:HuggingFace 模型加载库optimum:推理优化工具
实战:LLaMA-2-7B 推理优化
配方1:FP16 基线(无优化)
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
# 加载 FP16 模型
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-7b-hf",
torch_dtype=torch.float16,
device_map="auto"
)
model = model.npu() # 转到昇腾NPU
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-hf")
# 推理
input_text = "昇腾NPU的大模型推理速度怎么样?"
input_ids = tokenizer(input_text, return_tensors="pt").input_ids.npu()
with torch.no_grad():
output = model.generate(input_ids, max_new_tokens=100)
print(tokenizer.decode(output[0]))
问题:FP16 的 7B 模型需要 14GB 显存,昇腾 910 的 16GB 显存刚刚够,推理时没有多余显存做优化,性能差。
配方2:INT8 量化(推荐)
from optimum.npu import NPUQuantizer
from transformers import AutoModelForCausalLM, AutoTokenizer
# 加载模型
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-7b-hf",
torch_dtype=torch.float16,
device_map="auto"
)
model = model.npu()
# INT8 动态量化(不重新训练)
quantizer = NPUQuantizer(
precision="int8",
calibration_data=calibration_dataset, # 校准数据集
download=True # 自动下载量化校准工具
)
# 执行量化
quantized_model = quantizer.quantize_model(
model,
tokenizer,
batch_size=1,
sequence_length=2048
)
# 保存量化模型
quantized_model.save_pretrained("llama2-7b-int8")
量化效果:
- 显存:14GB → 3.5GB(75% 减少)
- 速度:提升 2-3x(显存带宽压力减小)
- 精度损失:< 1%(大部分任务感知不到)
配方3:INT4 极致压缩
from optimum.npu import NPUQuantizer
# INT4 量化(更激进)
quantizer = NPUQuantizer(
precision="int4",
calibration_data=calibration_dataset,
quantile_alpha=0.95 # 量化阈值,平衡精度和压缩率
)
quantized_model = quantizer.quantize_model(model, tokenizer)
INT4 效果:
- 显存:14GB → 1.8GB(87% 减少)
- 速度:提升 3-4x
- 精度损失:2-5%(对精度敏感任务需要调优)
性能对比
| 配置 | 显存占用 | 首 token 延迟 | 吞吐 |
|---|---|---|---|
| FP16 基线 | 14 GB | 2,380 ms | 1,250 tokens/s |
| INT8 量化 | 3.5 GB | 980 ms | 3,200 tokens/s |
| INT4 量化 | 1.8 GB | 650 ms | 4,100 tokens/s |
常见踩坑点
坑1:量化后精度崩了
症状:INT8/INT4 量化后,模型输出乱码或准确率暴跌。
原因:校准数据集不够多样化,或者量化阈值没调好。
解决方案:
# 扩大校准数据集(至少 512 条样本)
calibration_dataset = load_dataset("your/domain-specific-data", split="train[:512]")
# 调高 quantile_alpha(更保守的量化)
quantizer = NPUQuantizer(quantile_alpha=0.98) # 默认 0.95
坑2:昇腾910显存不够
症状:模型加载时报 OOM(Out of Memory)。
原因:昇腾 910 的 16GB 显存对于 FP16 的 7B 模型刚好够,但推理时还有中间结果占用显存。
解决方案:
- 用 INT8 量化
- 降低 batch_size
- 开启 KV Cache 压缩
- 用昇腾 910B(32GB 显存)或 910Pro(64GB 显存)
坑3:ATB 加速没生效
症状:加了 ATB,但速度没变快。
原因:ATB 没有正确加载,或者模型结构不在 ATB 支持列表里。
解决方案:
# 确认 ATB 已安装
import atb
print(atb.__version__)
# 确认模型结构被 ATB 支持
from atb_speed import is_supported
print(is_supported("llama2-7b")) # 应该输出 True
下一步
想深入学推理优化?cann-recipes-infer 仓库有完整配方,覆盖 LLaMA、ChatGLM、QWen 等主流模型:
https://atomgit.com/cann/cann-recipes-infer
顺便说一句,如果你打算在昇腾NPU上部署大模型,量化是必做的。FP16 的时代已经过去了,INT8/INT4 才是主流。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)