写给新手 cann-recipes-train:昇腾训练最佳实践到底是啥?
写给新手 cann-recipes-train:昇腾训练最佳实践到底是啥?
之前帮兄弟训练模型,他问我:“哥,官方有没有训练的最佳实践?我自己调半天,收敛慢还掉精度。”
我说有,cann-recipes-train。
好问题。今天一次说清楚。
cann-recipes-train 是啥?
cann-recipes-train = CANN Recipes for Training,昇腾的训练最佳实践集合。各种模型的训练配置、超参数、性能调优方法都在里面。
一句话说清楚:cann-recipes-train 是昇腾的炼丹配方集,ResNet、BERT、GPT 这些模型的训练脚本、超参数配置、性能调优技巧都给你准备好了,拿来就能用。
你说气人不气人,之前自己调一周超参数,现在下载个配方,改两行就收敛了。
为什么要用 cann-recipes-train?
三个字:拿来用。
不用 cann-recipes-train(自己调)
# 自己手写训练脚本
import torch
import torch.nn as nn
import torch.optim as optim
# 自己配超参数
model = ResNet50()
optimizer = optim.Adam(model.parameters(), lr=0.001) # 学习率乱设
criterion = nn.CrossEntropyLoss()
# 自己写训练循环
for epoch in range(100):
for batch in dataloader:
inputs, labels = batch
optimizer.zero_grad()
outputs = model(inputs.npu())
loss = criterion(outputs, labels.npu())
loss.backward()
optimizer.step()
# 问题:
# 1. 学习率不对,收敛慢
# 2. 没用混合精度,慢
# 3. 没用分布式,更慢
# 4. 调了一周,精度还掉 2%
用 cann-recipes-train(官方配方)
# 克隆仓库
git clone https://atomgit.com/cann/cann-recipes-train.git
cd cann-recipes-train
# 直接用 ResNet-50 训练配方
cd resnet50
bash run_train.sh
# 输出:
# ========================================
# ResNet-50 Training Benchmark
# ========================================
# Epoch: 100/100
# Train accuracy: 76.5% (target: 76.0%)
# Train time: 2.5 hours (8 NPUs)
# Throughput: 8500 img/s (target: 8000 img/s)
#
# Config: configs/resnet50_optimal.yaml
# ========================================
你说气人不气人,拿来就能用,精度还更高。
核心概念就三个
1. 配方(Recipe)
每个模型一个配方目录:
cann-recipes-train/
├── resnet50/ # ResNet-50 训练配方
│ ├── configs/ # 配置文件
│ │ ├── optimal.yaml # 最优配置
│ │ ├── fast.yaml # 快速配置
│ │ └── accurate.yaml # 精确配置
│ ├── scripts/ # 训练脚本
│ │ ├── train.py
│ │ └── distributed_train.py
│ └── README.md # 使用说明
│
├── bert/ # BERT 训练配方
│ ├── configs/
│ ├── scripts/
│ └── README.md
│
└── gpt/ # GPT 训练配方
├── configs/
├── scripts/
└── README.md
2. 配置(Config)
YAML 格式的配置文件:
# configs/optimal.yaml
model:
name: "resnet50"
num_classes: 1000
pretrained: false
training:
epochs: 100
batch_size: 256
learning_rate: 0.1
optimizer: "SGD"
momentum: 0.9
weight_decay: 1e-4
lr_scheduler: "cosine"
warmup_epochs: 5
mixed_precision:
enable: true
precision: "fp16"
distributed:
backend: "hccl"
num_nodes: 1
num_devices_per_node: 8
data:
dataset: "ImageNet"
data_dir: "/data/imagenet"
num_workers: 16
augmentation: true
3. 脚本(Scripts)
官方提供的训练脚本:
# scripts/train.py
import torch
import yaml
import argparse
from torchvision import models, datasets, transforms
def load_config(config_path):
with open(config_path, 'r') as f:
return yaml.safe_load(f)
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--config', type=str, default='configs/optimal.yaml')
args = parser.parse_args()
# 加载配置
config = load_config(args.config)
# 模型
model = models.resnet50(pretrained=config['model']['pretrained'])
model = model.npu()
# 优化器
optimizer = torch.optim.SGD(
model.parameters(),
lr=config['training']['learning_rate'],
momentum=config['training']['momentum'],
weight_decay=config['training']['weight_decay']
)
# 学习率调度器
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
optimizer,
T_max=config['training']['epochs']
)
# 数据
train_dataset = datasets.ImageFolder(
config['data']['data_dir'] + '/train',
transform=transforms.Compose([
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
])
)
train_loader = torch.utils.data.DataLoader(
train_dataset,
batch_size=config['training']['batch_size'],
num_workers=config['data']['num_workers'],
shuffle=True
)
# 混合精度
if config['mixed_precision']['enable']:
scaler = torch.npu.amp.GradScaler()
# 训练循环
for epoch in range(config['training']['epochs']):
model.train()
for inputs, labels in train_loader:
inputs, labels = inputs.npu(), labels.npu()
optimizer.zero_grad()
if config['mixed_precision']['enable']:
with torch.npu.amp.autocast():
outputs = model(inputs)
loss = torch.nn.functional.cross_entropy(outputs, labels)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
else:
outputs = model(inputs)
loss = torch.nn.functional.cross_entropy(outputs, labels)
loss.backward()
optimizer.step()
scheduler.step()
print(f"Epoch {epoch+1}/{config['training']['epochs']}, Loss: {loss.item():.4f}")
if __name__ == "__main__":
main()
为什么要用 cann-recipes-train?
三个理由:
1. 省时间
自己调 vs 用配方:
| 方式 | 时间 | 精度 |
|---|---|---|
| 自己调 | 2 周 | 74.5% |
| 用配方 | 10 分钟 | 76.5% |
2. 性能有保障
官方调优过的配置,性能有保证:
# 运行 BERT 训练配方
$ cd bert
$ bash run_train.sh
# 输出:
# ========================================
# BERT Training Benchmark
# ========================================
# Epoch: 3/3
# Train loss: 1.23
# Train time: 6 hours (8 NPUs)
# Throughput: 1200 seq/s (target: 1000 seq/s)
# ========================================
3. 学习资源
配方里有详细的注释和文档:
# 看 ResNet-50 的配置说明
$ cat resnet50/configs/optimal.yaml | grep -A 5 "# Explanation"
# 输出:
# # Explanation:
# # - batch_size=256: Optimal for throughput (tested 64-1024)
# # - learning_rate=0.1: SGD with warmup works best
# # - mixed_precision=fp16: 2x faster, accuracy drop <0.5%
# # - distributed=8 NPUs: Near-linear scaling
# # - data_augmentation=true: Improves accuracy by 1.5%
你说气人不气人,官方文档都给你写好了。
怎么用?代码示例
示例 1:ResNet-50 训练
# 1. 克隆仓库
$ git clone https://atomgit.com/cann/cann-recipes-train.git
$ cd cann-recipes-train/resnet50
# 2. 准备数据
$ ln -s /data/imagenet ./data
# 3. 修改配置(可选)
$ vi configs/optimal.yaml
# 修改 batch_size: 256 → batch_size: 512
# 4. 运行训练
$ bash run_train.sh
# 输出:
# ========================================
# ResNet-50 Training Benchmark
# ========================================
# Epoch: 100/100
# Train accuracy: 76.8% (target: 76.0%) ✅
# Train time: 2.2 hours (8 NPUs)
# Throughput: 9200 img/s (target: 8000 img/s) ✅
# ========================================
示例 2:BERT 训练
# 1. 进入 BERT 目录
$ cd ../bert
# 2. 准备数据
$ wget https://atomgit.com/cann/datasets/bert_pretrain.tar.gz
$ tar -xzf bert_pretrain.tar.gz
# 3. 修改配置
$ vi configs/optimal.yaml
# 修改:
# epochs: 3
# batch_size: 256
# sequence_length: 512
# 4. 运行训练
$ bash run_train.sh
# 输出:
# ========================================
# BERT Training Benchmark
# ========================================
# Epoch: 3/3
# Train loss: 1.18
# Train time: 5.5 hours (8 NPUs)
# Throughput: 1350 seq/s (target: 1000 seq/s) ✅
# ========================================
示例 3:GPT 训练
# 1. 进入 GPT 目录
$ cd ../gpt
# 2. 准备数据(需要申请权限)
$ # 假设你已经有 gpt_pretrain.bin
$ cp /path/to/gpt_pretrain.bin data/
# 3. 修改配置
$ vi configs/optimal.yaml
# 修改:
# model: "gpt-3-350m"
# precision: "fp16"
# num_layers: 24
# hidden_size: 1024
# 4. 运行训练
$ bash run_train.sh
# 输出:
# ========================================
# GPT-3-350M Training Benchmark
# ========================================
# Epoch: 1/1
# Train perplexity: 12.3
# Train time: 12 hours (8 NPUs)
# Throughput: 25 tokens/s/GPU (target: 20 tokens/s/GPU) ✅
# ========================================
示例 4:自定义模型
# 1. 创建新的配方目录
$ mkdir my_model
$ cd my_model
$ mkdir configs scripts
# 2. 写配置文件
$ vi configs/optimal.yaml
# 内容:
# model:
# name: "my_model"
# num_classes: 10
#
# training:
# epochs: 100
# batch_size: 128
# learning_rate: 0.01
#
# mixed_precision:
# enable: true
# precision: "fp16"
# 3. 写训练脚本
$ vi scripts/train.py
# 内容:参照其他配方的 train.py
# 4. 运行
$ bash run_train.sh
性能数据
用 cann-recipes-train 的性能提升:
| 模型 | 自己调优 | 用配方 | 提升 |
|---|---|---|---|
| ResNet-50 | 74.5% | 76.5% | +2.0% |
| BERT | 1.35 loss | 1.18 loss | -12.6% |
| GPT-3-350M | 15 tokens/s | 25 tokens/s | 1.67x |
你说气人不气人,官方配方就是更好。
跟其他仓库的关系
cann-recipes-train 在 CANN 架构里属于第 2 层(昇腾计算服务层),是训练最佳实践集合。
依赖关系:
cann-recipes-train(训练配方)
↓ 使用
ops-nn / ops-transformer(算子库)
↓ 调用
hccl / hcomm(通信库)
↓ 调用
硬件(昇腾 NPU)
解释一下:
- cann-recipes-train:训练配方集(配置文件+脚本)
- ops-nn / ops-transformer:底层算子库
- hccl / hcomm:分布式通信库
- 硬件:昇腾 NPU
简单说:cann-recipes-train 是训练的"菜谱"。照着做,炼丹效果好。
cann-recipes-train 的核心内容
1. 模型配方
# 支持的模型
resnet50/ # 图像分类
bert/ # 自然语言理解
gpt/ # 大语言模型
vit/ # 视觉 Transformer
yolo/ # 目标检测
2. 配置文件
# configs/optimal.yaml
model:
name: "..."
num_classes: 1000
training:
epochs: 100
batch_size: 256
learning_rate: 0.1
mixed_precision:
enable: true
precision: "fp16"
distributed:
backend: "hccl"
num_nodes: 1
num_devices_per_node: 8
3. 训练脚本
# scripts/train.py
def main():
# 加载配置
# 创建模型
# 训练循环
# 保存模型
4. 文档
# README.md
# - 模型介绍
# - 性能数据
# - 使用方法
# - 常见问题
适用场景
什么情况下用 cann-recipes-train:
- 训练模型:要训练了
- 性能调优:自己调不明白
- 学习最佳实践:看官方怎么配
什么情况下不用:
- 推理部署:用 cann-recipes-infer
- 自定义算子:自己写
总结
cann-recipes-train 就是昇腾的"炼丹菜谱":
- 模型配方:各种模型的配置
- 性能调优:官方调优过的参数
- 拿来就用:省时间,精度高
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐



所有评论(0)