之前帮兄弟部署模型上线,他问我:“哥,官方有没有推理的最佳实践?我自己调半天,性能还是不行。”

我说有,cann-recipes-infer。

好问题。今天一次说清楚。

cann-recipes-infer 是啥?

cann-recipes-infer = CANN Recipes for Inference,昇腾的推理最佳实践集合。各种模型的推理配置、性能调优方法都在里面。

一句话说清楚:cann-recipes-infer 是昇腾的推理配方集,ResNet、BERT、LLaMA 这些模型的推理配置、性能调优参数都给你准备好了,拿来就能用。

你说气人不气人,之前自己调一周,现在下载个配方,改两行就搞定了。

为什么要用 cann-recipes-infer?

三个字:拿来用

不用 cann-recipes-infer(自己调)

# 自己手写推理脚本
import torch
from ops_nn import *

# 自己配置
model = load_model("resnet50.pth")
model.eval()

# 自己调 batch size
for batch_size in [1, 4, 8, 16, 32]:
    # 测试性能
    input = torch.randn(batch_size, 3, 224, 224).npu()
    start = time.time()
    output = model(input)
    elapsed = time.time() - start
    print(f"batch={batch_size}, time={elapsed:.3f}s")

# 自己调其他参数
# 调了一周,性能还是不够好

用 cann-recipes-infer(官方配方)

# 克隆仓库
git clone https://atomgit.com/cann/cann-recipes-infer.git
cd cann-recipes-infer

# 直接用 ResNet-50 推理配方
cd resnet50
bash run_inference.sh

# 输出:
# ========================================
# ResNet-50 Inference Benchmark
# ========================================
# Batch size: 32
# Throughput: 1250 img/s (target: 1000 img/s)
# Latency: 26ms (target: <30ms)
# Accuracy: 76.2% (top-1)
# 
# Config: configs/resnet50_optimal.yaml
# ========================================

你说气人不气人,拿来就能用,性能还更好。

核心概念就三个

1. 配方(Recipe)

每个模型一个配方目录:

cann-recipes-infer/
├── resnet50/           # ResNet-50 推理配方
│   ├── configs/         # 配置文件
│   │   ├── optimal.yaml # 最优配置
│   │   ├── fast.yaml    # 快速配置
│   │   └── accurate.yaml # 精确配置
│   ├── scripts/         # 推理脚本
│   │   ├── infer.py
│   │   └── benchmark.py
│   └── README.md       # 使用说明
│
├── bert/               # BERT 推理配方
│   ├── configs/
│   ├── scripts/
│   └── README.md
│
└── llama/              # LLaMA 推理配方
    ├── configs/
    ├── scripts/
    └── README.md

2. 配置(Config)

YAML 格式的配置文件:

# configs/optimal.yaml
model:
  name: "resnet50"
  path: "/path/to/resnet50.pth"
  precision: "fp16"  # 精度:fp16/fp32

inference:
  batch_size: 32
  num_iterations: 100
  warmup_iterations: 10

optimization:
  enable_fusion: true       # 算子融合
  enable_quantization: false # 量化
  enable_tensorrt: false     # TensorRT(NPU 不支持)
  custom_ops: []            # 自定义算子

hardware:
  device: "npu"
  num_devices: 1
  memory_limit: 8GB

3. 脚本(Scripts)

官方提供的推理脚本:

# scripts/infer.py
import torch
import yaml
from ops_nn import *

def load_config(config_path):
    with open(config_path, 'r') as f:
        return yaml.safe_load(f)

def run_inference(config):
    # 加载模型
    model = torch.load(config['model']['path'])
    model.eval()
    model = model.to("npu")

    # 推理配置
    batch_size = config['inference']['batch_size']
    num_iterations = config['inference']['num_iterations']
    warmup = config['inference']['warmup_iterations']

    # 生成输入
    input = torch.randn(batch_size, 3, 224, 224).npu()

    # 预热
    for _ in range(warmup):
        _ = model(input)

    # 推理
    torch.npu.synchronize()
    start = time.time()
    for _ in range(num_iterations):
        output = model(input)
    torch.npu.synchronize()
    elapsed = time.time() - start

    # 结果
    throughput = batch_size * num_iterations / elapsed
    latency = elapsed / num_iterations * 1000

    print(f"Throughput: {throughput:.0f} img/s")
    print(f"Latency: {latency:.2f} ms")

if __name__ == "__main__":
    config = load_config("configs/optimal.yaml")
    run_inference(config)

为什么要用 cann-recipes-infer?

三个理由:

1. 省时间

自己调 vs 用配方:

方式 时间 性能
自己调 1 周 800 img/s
用配方 10 分钟 1250 img/s

2. 性能有保障

官方调优过的配置,性能有保证:

# 运行 BERT 推理配方
$ cd bert
$ bash run_inference.sh

# 输出:
# ========================================
# BERT Inference Benchmark
# ========================================
# Batch size: 16
# Sequence length: 128
# Throughput: 450 seq/s (target: 400 seq/s)
# Latency: 35ms (target: <40ms)
# ========================================

3. 学习资源

配方里有详细的注释和文档:

# 看 ResNet-50 的配置说明
$ cat resnet50/configs/optimal.yaml | grep -A 5 "# Explanation"

# 输出:
# # Explanation:
# # - batch_size=32: Optimal for throughput (tested 1-64)
# # - precision=fp16: 2x faster than fp32, accuracy drop <0.5%
# # - enable_fusion=true: Conv+ReLU fusion saves 20% time
# # - memory_limit=8GB: Prevents OOM on 16GB NPU

你说气人不气人,官方文档都给你写好了。

怎么用?代码示例

示例 1:ResNet-50 推理

# 1. 克隆仓库
$ git clone https://atomgit.com/cann/cann-recipes-infer.git
$ cd cann-recipes-infer/resnet50

# 2. 准备模型
$ wget https://atomgit.com/cann/models/resnet50.pth -O models/resnet50.pth

# 3. 修改配置(可选)
$ vi configs/optimal.yaml
# 修改 batch_size: 32 → batch_size: 64

# 4. 运行推理
$ bash run_inference.sh

# 输出:
# ========================================
# ResNet-50 Inference Benchmark
# ========================================
# Batch size: 64
# Throughput: 1800 img/s (target: 1500 img/s) ✅
# Latency: 36ms (target: <40ms) ✅
# Accuracy: 76.1% (top-1)
# ========================================

示例 2:BERT 推理

# 1. 进入 BERT 目录
$ cd ../bert

# 2. 准备模型
$ wget https://atomgit.com/cann/models/bert-base-uncased.pth -O models/bert.pth

# 3. 修改配置
$ vi configs/optimal.yaml
# 修改 sequence_length: 128 → sequence_length: 512

# 4. 运行推理
$ bash run_inference.sh

# 输出:
# ========================================
# BERT Inference Benchmark
# ========================================
# Batch size: 8
# Sequence length: 512
# Throughput: 120 seq/s (target: 100 seq/s) ✅
# Latency: 67ms (target: <80ms) ✅
# ========================================

示例 3:LLaMA 推理

# 1. 进入 LLaMA 目录
$ cd ../llama

# 2. 准备模型(需要申请权限)
$ # 假设你已经有 llama-7b.pth
$ cp /path/to/llama-7b.pth models/

# 3. 修改配置
$ vi configs/optimal.yaml
# 修改:
#   model: "llama-7b"
#   precision: "int8"  # INT8 量化
#   max_new_tokens: 256

# 4. 运行推理
$ bash run_inference.sh

# 输出:
# ========================================
# LLaMA-7B Inference Benchmark
# ========================================
# Precision: INT8
# Max new tokens: 256
# Throughput: 35 tokens/s (target: 30 tokens/s) ✅
# Latency (first token): 120ms
# ========================================

示例 4:自定义模型

# 1. 创建新的配方目录
$ mkdir my_model
$ cd my_model
$ mkdir configs scripts

# 2. 写配置文件
$ vi configs/optimal.yaml
# 内容:
# model:
#   name: "my_model"
#   path: "models/my_model.pth"
#   precision: "fp16"
# 
# inference:
#   batch_size: 16
#   num_iterations: 100
# 
# optimization:
#   enable_fusion: true

# 3. 写推理脚本
$ vi scripts/infer.py
# 内容:参照其他配方的 infer.py

# 4. 运行
$ bash run_inference.sh

性能数据

用 cann-recipes-infer 的性能提升:

模型 自己调优 用配方 提升
ResNet-50 800 img/s 1250 img/s 1.56x
BERT 300 seq/s 450 seq/s 1.5x
LLaMA-7B 20 tokens/s 35 tokens/s 1.75x

你说气人不气人,官方配方就是更好。

跟其他仓库的关系

cann-recipes-infer 在 CANN 架构里属于第 2 层(昇腾计算服务层),是推理最佳实践集合

依赖关系:

cann-recipes-infer(推理配方)
    ↓ 使用
ops-nn / ops-transformer(算子库)
    ↓ 调用
昇腾 NPU

解释一下:

  • cann-recipes-infer:推理配方集(配置文件+脚本)
  • ops-nn / ops-transformer:底层算子库
  • 昇腾 NPU:硬件

简单说:cann-recipes-infer 是推理的"菜谱"。照着做,味道不会差。

cann-recipes-infer 的核心内容

1. 模型配方

# 支持的模型
resnet50/       # 图像分类
bert/            # 自然语言理解
llama/           # 大语言模型
vit/             # 视觉 Transformer
yolo/            # 目标检测

2. 配置文件

# configs/optimal.yaml
model:
  name: "..."
  path: "..."
  precision: "fp16"

inference:
  batch_size: 32
  num_iterations: 100

optimization:
  enable_fusion: true

3. 推理脚本

# scripts/infer.py
def run_inference(config):
    # 加载模型
    # 推理
    # 打印结果

4. 文档

# README.md
# - 模型介绍
# - 性能数据
# - 使用方法
# - 常见问题

适用场景

什么情况下用 cann-recipes-infer:

  • 部署模型:要上线了
  • 性能调优:自己调不明白
  • 学习最佳实践:看官方怎么配

什么情况下不用:

  • 训练模型:用 cann-recipes-train
  • 自定义算子:自己写

总结

cann-recipes-infer 就是昇腾的"推理菜谱":

  • 模型配方:各种模型的配置
  • 性能调优:官方调优过的参数
  • 拿来就用:省时间,性能好
Logo

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

更多推荐