请添加图片描述

前言

拿到昇腾开发板或服务器,第一件事是什么?

官方推荐的路径:先跑通 cann-samples 里的示例。这个仓库收集了覆盖 CV、NLP、推荐系统、多模态等场景的完整示例代码,从环境搭建到模型部署全流程都有。


为什么要从示例入手

读文档能了解 API,但文档往往只讲单个接口,不告诉你怎么串起来。示例代码的优势是完整性——一个能跑的程序,比十页文档更有用。

cann-samples 里的示例有几个特点:

  1. 可复现:环境依赖、数据准备、运行命令都写清楚了
  2. 覆盖主流场景:CV、NLP、推荐、多模态都有
  3. 版本对应:示例代码跟 CANN 版本绑定,不会因为版本不匹配踩坑

必看示例一:ResNet50 图像分类

路径:cann-samples/vision/classification/ResNet50/

这个示例覆盖从数据预处理到推理部署的全流程:

# 1. 准备环境
git clone https://atomgit.com/cann/cann-samples.git
cd cann-samples/vision/classification/ResNet50/

# 2. 下载预训练模型(ONNX 格式)
wget https://github.com/onnx/models/raw/main/vision/classification/resnet/model/resnet50-v1-7.onnx

# 3. 编译成 .om
atc --model=resnet50-v1-7.onnx \
    --framework=5 \
    --output=resnet50 \
    --soc_version=Ascend910

# 4. 运行推理
python infer.py --model=resnet50.om --image=cat.jpg

输出示例:

Top-1: 银鲑鱼 (golden retriever), 置信度: 0.873
Top-2: 拉布拉多犬 (Labrador retriever), 置信度: 0.041
Top-5: ...

这个示例的价值在于:它展示了标准的推理流程——模型编译、数据预处理、推理执行、结果后处理,每一步都有对应代码。


必看示例二:BERT 文本分类

路径:cann-samples/nlp/text_classification/bert/

NLP 模型跟 CV 模型的区别:输入是变长的 token 序列,需要处理 padding 和 attention mask。

# 数据预处理
from transformers import BertTokenizer

tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
inputs = tokenizer(
    "这部电影真的很棒!",
    padding=True,
    truncation=True,
    max_length=512,
    return_tensors="pt"
)

# 转 NPU
input_ids = inputs["input_ids"].to("npu:0")
attention_mask = inputs["attention_mask"].to("npu:0")

# 推理
output = model(input_ids, attention_mask=attention_mask)

这个示例的重点是 attention_mask 的处理——把 padding 位置标记出来,避免模型关注无效 token。


必看示例三:YOLOv5 目标检测

路径:cann-samples/vision/object_detection/yolov5/

目标检测比分类复杂:输出不是单个类别,而是多个边界框 + 类别 + 置信度。

后处理是关键:

# YOLOv5 后处理:NMS(非极大值抑制)
import torch

def nms(boxes, scores, iou_threshold=0.5):
    # 1. 按置信度排序
    sorted_indices = torch.argsort(scores, descending=True)
    
    keep = []
    while len(sorted_indices) > 0:
        # 2. 取置信度最高的框
        best = sorted_indices[0]
        keep.append(best)
        
        # 3. 计算跟其他框的 IoU
        ious = compute_iou(boxes[best], boxes[sorted_indices[1:]])
        
        # 4. 保留 IoU < threshold 的框
        keep_indices = (ious < iou_threshold).nonzero().squeeze(1)
        sorted_indices = sorted_indices[keep_indices + 1]
    
    return keep

这个示例展示了端到端部署的完整流程:模型编译、预处理、推理、后处理、可视化。


必看示例四:DeepFM 推荐系统

路径:cann-samples/recommendation/deepfm/

推荐系统模型的输入是稀疏特征(用户 ID、物品 ID、类别标签等),需要先做 embedding 查表,再送进 DNN。

# embedding 查表
user_embedding = nn.Embedding(num_users, embedding_dim)
item_embedding = nn.Embedding(num_items, embedding_dim)

user_vec = user_embedding(user_ids)  # [batch, embed_dim]
item_vec = item_embedding(item_ids)   # [batch, embed_dim]

# FM 部分:特征交叉
fm_output = torch.sum(user_vec * item_vec, dim=1)

# DNN 部分:深层特征提取
dnn_input = torch.cat([user_vec, item_vec], dim=1)
dnn_output = dnn(dnn_input)

# 输出:点击率预测
output = torch.sigmoid(fm_output + dnn_output)

这个示例覆盖稀疏特征处理多塔结构(FM + DNN),是推荐系统的经典范式。


必看示例五:CLIP 多模态检索

路径:cann-samples/multimodal/clip/

CLIP 的训练方式是:图像和文本分别编码,然后算余弦相似度,让配对的图像-文本相似度最高。

推理时可以反过来用:用文本检索图像,或者用图像检索文本。

# 图像编码
image_features = image_encoder(images)  # [batch, embed_dim]
image_features = image_features / image_features.norm(dim=-1, keepdim=True)

# 文本编码
text_features = text_encoder(texts)     # [batch, embed_dim]
text_features = text_features / text_features.norm(dim=-1, keepdim=True)

# 计算相似度矩阵
similarity = image_features @ text_features.T  # [batch, batch]

# 对角线上的元素是正样本(配对的图-文)
# 非对角线是负样本
loss = cross_entropy(similarity, labels)

这个示例展示了多模态模型的推理方式,以及怎么用昇腾 NPU 加速 CLIP。


怎么把示例改成自己的项目

直接抄示例代码是最快的入门方式,但要把它改成自己的项目,需要改几个地方:

  1. 数据预处理:示例用的是公开数据集,你要换成自己的数据格式
  2. 模型结构:示例用的是标准模型,你可能需要加自定义层
  3. 后处理:示例的后处理是通用逻辑,你的业务可能有特殊需求

建议的做法:先原样跑通示例,确保环境和流程没问题;再逐步替换数据、模型、后处理,每次只改一个部分,方便定位问题。


总结

cann-samples 的价值不在于代码本身,而在于它展示了完整的、可复现的流程。从 ResNet50 的图像分类到 CLIP 的多模态检索,这五个示例覆盖了昇腾 NPU 上最常见的 AI 场景。把示例跑通、理解、改造,比从头写代码效率高得多。

Logo

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

更多推荐