第一阶段:PC端 —— 环境与模型准备
因为华为的转换工具 ATC 必须运行在 Linux 环境下,我们默认以 Windows + WSL2 (Ubuntu 22.04) 为例。
1. 开启电脑的 Linux 环境 (WSL2)(这里wsl的安装不再赘述)
-
打开终端:在 Windows 任务栏搜索
PowerShell,右键“以管理员身份运行”。 -
进入 Linux:输入
wsl进入Ubuntu环境。 - 提前创建好文件夹,例如310B(下述文件夹就以这个为例),后续PC端文件都在这个文件夹内进行。
2. 下载 YOLOv5 源码与模型 (在 Ubuntu 窗口内)
# 安装基础工具
sudo apt update && sudo apt install -y git python3-pip
# 克隆源码
git clone https://github.com/ultralytics/yolov5.git cd yolov5
# 下载权重文件 (yolov5s.pt)
wget https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5s.pt
或者前往GitHub自行下载
-
具体操作:下拉到页面底部的 Assets 栏,点击
yolov5s.pt下载到310B文件夹。
3. 将 .pt 转换为 .onnx
# 安装导出依赖
pip install -r requirements.txt onnx
# 执行导出
python3 export.py --weights yolov5s.pt --include onnx --simplify --img 640
完成后,文件夹里会出现 yolov5s.onnx。
第二阶段:PC端 —— ATC 工具安装与转换
1. 下载 CANN Toolkit 软件包
-
在 Windows 浏览器打开 昇腾社区下载页。
-
精准选择:版本
8.0.0.alpha001-> 架构x86_64-> 软件包Ascend-cann-toolkit_8.0.0.alpha001_linux-x86_64.run。 -
传输文件:将下载好的
.run文件放进310B文件夹里。
2. 安装与变量激活
# 赋予执行权限并安装
chmod +x Ascend-cann-toolkit_8.0.0.alpha001_linux-x86_64.run
./Ascend-cann-toolkit_8.0.0.alpha001_linux-x86_64.run --install

出现sucess就是安装成功了。
注意:这里安装软件包的时候需要使用
python3.11及以下的环境,3.12会报错。
寻找路径:激活ATC工具需要查看set_env.sh文件的位置。如果你不知道装哪了,输入 find ~ -name "set_env.sh"
# 使用你搜到的路径
source /home/你的用户名/Ascend/ascend-toolkit/set_env.sh
验证成功:直接输入 atc 回车。

出现ATC start working now.即激活成功。
3. 执行最终转换 (OM 模型生成)
atc --model=yolov5s.onnx \
--framework=5 \
--output=yolov5s \
--soc_version=Ascend310B1 \
--input_format=NCHW \
--input_shape="images:1,3,640,640" \
--log=error
此时,你就得到了 yolov5s.om。

🔍 深度解析:为什么要费劲在电脑端折腾?
-
硬件分层设计:华为昇腾将环境分为 开发环境 (Development) 和 运行环境 (Runtime)。
-
开发环境 (PC):安装 Toolkit 套件。它包含极其庞大的算子编译库和优化引擎,模型转换时会瞬间吃掉大量内存。如果在香橙派上跑,板子会直接因为内存耗尽而“死机”,除非增加 Swap 分区(虚拟内存),具体操作请查看 昇腾 310B 模型转换全指南:从 PT 到 ONNX 再到 OM。
-
运行环境 (香橙派):预装 NNRT (推理库)。它非常精简,只负责执行生成的
yolov5s.om指令集,不占空间,运行极快。
第三阶段:香橙派端 —— 部署与运行
1. 文件传输
将电脑上的 yolov5s.om 复制到香橙派的 /root/course/ 目录下(这里的文件夹也自行创建,这里举个例子)。
2. 板子端环境切换(python环境这里不再赘述,推荐使用conda环境)
# 进入香橙派终端
conda activate ascend_atc
3. 启动 Jupyter Lab 并远程登录
- 安装 Jupyter Lab:
# 安装 Jupyter Lab 及内核管理工具
pip install jupyterlab ipykernel
# 安装推理显示与矩阵运算依赖
pip install matplotlib opencv-python numpy==1.26.4
- 启动 Jupyter Lab:
jupyter lab --ip=0.0.0.0 --allow-root
- 手动注册内核 (Kernel)
这一步最为重要! 如果不执行,Jupyter 页面中将无法切换到包含昇腾驱动的环境。
# 将当前环境注册到 Jupyter 列表中
python -m ipykernel install --user --name ascend_atc --display-name "Python (ascend_atc)"
提示:注册成功后,网页端的 Launcher 界面会多出一个名为 “Python (ascend_atc)” 的图标,务必点击此图标新建 Notebook。
- 获取令牌:查看输出内容中的
http://127.0.0.1:8888/labtoken=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx。 - 浏览器登录:在 Windows 浏览器输入
http://开发板IP:8888/labtoken=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx。

第四阶段:Jupyter 内核推理
新建 Notebook,粘贴代码运行:
import acl
import numpy as np
import cv2
import os
import matplotlib.pyplot as plt
def final_detector_hunt():
# 1. 设置路径 (请确保这两个文件都在这个目录下)
work_dir = "/root/course/"
os.chdir(work_dir)
model_path = "yolov5s.om"
img_path = "data/images/bus.jpg"
# 2. 初始化硬件 (ACL)
try: acl.init()
except: pass
acl.rt.set_device(0)
context, _ = acl.rt.create_context(0)
# 3. 加载模型
model_id, _ = acl.mdl.load_from_file(model_path)
model_desc = acl.mdl.create_desc()
acl.mdl.get_desc(model_desc, model_id)
# 4. 预处理图片
raw_img = cv2.imread(img_path)
img_resized = cv2.resize(raw_img, (640, 640))
# 尝试标准的预处理:BGR->RGB, 归一化
img_rgb = img_resized[:, :, ::-1].transpose(2, 0, 1).astype(np.float32) / 255.0
img_data = np.ascontiguousarray(img_rgb)
# 5. NPU 推理过程 (简化封装)
input_size = img_data.nbytes
dev_ptr, _ = acl.rt.malloc(input_size, 1)
acl.rt.memcpy(dev_ptr, input_size, acl.util.numpy_to_ptr(img_data), input_size, 1)
input_dataset = acl.mdl.create_dataset()
acl.mdl.add_dataset_buffer(input_dataset, acl.create_data_buffer(dev_ptr, input_size))
output_size = 1 * 25200 * 85 * 4
out_dev_ptr, _ = acl.rt.malloc(output_size, 1)
output_dataset = acl.mdl.create_dataset()
acl.mdl.add_dataset_buffer(output_dataset, acl.create_data_buffer(out_dev_ptr, output_size))
print(" NPU 推理中...")
acl.mdl.execute(model_id, input_dataset, output_dataset)
# 6. 获取结果
host_out, _ = acl.rt.malloc_host(output_size)
acl.rt.memcpy(host_out, output_size, out_dev_ptr, output_size, 2)
result = acl.util.ptr_to_numpy(host_out, (1, 25200, 85), 11).copy()
print(" 开始后处理...")
preds = result[0]
# 自动探测:看看最大置信度是多少,如果太低,自动降阈值
actual_max_conf = np.max(preds[:, 4])
print(f" 探测到最高置信度: {actual_max_conf:.4f}")
# 动态阈值:取最高置信度的一半,或者 0.25,谁大取谁
conf_thresh = max(0.2, actual_max_conf * 0.5)
print(f" 当前使用的过滤阈值: {conf_thresh:.2f}")
boxes, confs, ids = [], [], []
for p in preds[preds[:, 4] > conf_thresh]:
# 自动识别坐标系 (0~1 还是 0~640)
x, y, w, h = p[:4]
if np.max(p[:4]) <= 1.05:
x, y, w, h = x * 640, y * 640, w * 640, h * 640
cls_id = np.argmax(p[5:])
score = p[4] * p[5 + cls_id]
if score > conf_thresh:
boxes.append([int(x - w/2), int(y - h/2), int(x + w/2), int(y + h/2)])
confs.append(float(score))
ids.append(cls_id)
# NMS 画框
canvas = img_resized.copy()
if len(boxes) > 0:
indices = cv2.dnn.NMSBoxes(boxes, confs, conf_thresh, 0.4)
for i in indices:
idx = i[0] if isinstance(i, (list, np.ndarray)) else i
b = boxes[idx]
cv2.rectangle(canvas, (b[0], b[1]), (b[2], b[3]), (0, 255, 0), 2)
cv2.putText(canvas, f"ID:{ids[idx]} {confs[idx]:.2f}", (b[0], b[1]-5),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
print(f" 成功画出 {len(indices)} 个检测框!")
else:
print(" 没有检测到框,可能预处理(BGR/RGB)与模型不匹配。")
# 8. 最终显示
plt.figure(figsize=(8, 8))
plt.imshow(cv2.cvtColor(canvas, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.show()
# 资源释放
acl.rt.free(dev_ptr)
acl.rt.free(out_dev_ptr)
acl.rt.free_host(host_out)
acl.mdl.unload(model_id)
acl.rt.destroy_context(context)
final_detector_hunt()
注意:这里注意模型和要检测图片的路径正确。


💡 避坑终极总结
-
ATC 命令必须在
source ../set_env.sh之后运行,否则会报command not found。 -
模型输入尺寸:转换时指定了
640x640,那么 Python 代码里的cv2.resize也必须是640, 640。 -
NumPy 版本:板子端如果报错
_ARRAY_API not found,可能是NumPy 版本过高,请立刻运行pip install numpy==1.23.5并重启 Jupyter 内核。


没有回复内容