快速开始
本章以一个 YOLO 模型为示例,讲解 TVM-MUSA 的编译与推理流程。示例拆成两个独立阶段:
build.py:使用 Ultralytics、Torch-MUSA 和 TorchVision 环境加载、融合并导出 YOLOv8s,再通过 TVM-MUSA 编译和优化,最终保存.so共享库及描述文件。inference.py:只加载.so和描述文件,在 MUSA 上执行推理、图片后处理、画框和性能测试,不依赖 PyTorch 或 Ultralytics。
这种拆分把构建依赖和部署依赖隔离开。构建阶段可以在具备 Torch-MUSA、TorchVision、Ultralytics 和 TVM-MUSA 的环境中完成;部署阶段需要 TVM-MUSA、NumPy 和 Pillow。
| 阶段 | 脚本 | 主要依赖 | 产物 |
|---|---|---|---|
| 编译优化 | build.py | TVM-MUSA、Torch-MUSA、TorchVision、Ultralytics、NumPy | yolov8s_musa.so、yolov8s_musa.json |
| 运行时推理 | inference.py | TVM-MUSA、NumPy、Pillow | 标注图片、检测结果、性能数据 |
开始前请先完成安装与验证。TVM MUSA Wheel 包以及示例脚本可从从产品下载页面下载
准备示例环境
构建示例需要使用 Moore Threads 发布的 PyTorch 软件栈。请从 M1000 软件发布包中获取与本地 MUSA SDK 匹配的 aarch64 wheel,并将 torch、torch_musa 和 torchvision 一起安装到安装与验证创建的 venv:
python -m pip install \
/path/to/torch-<version>-cp310-cp310-linux_aarch64.whl \
/path/to/torch_musa-<version>-cp310-cp310-linux_aarch64.whl \
/path/to/torchvision-<version>-cp310-cp310-linux_aarch64.whl
本文验证组合为 Torch 2.9.1.post1、Torch-MUSA 2.9.1.post1 和
TorchVision 0.22.1
验证 Torch-MUSA 环境:
python -c "import torch, torch_musa; print(torch.musa.is_available())"
输出为 True 表示环境可用。安装示例的其他依赖:
python -m pip install numpy pillow==12.3.0 ultralytics==8.4.192
Step1 编译并生成 .so 文件
进入发布包的 examples/ 目录,执行构建脚本:
cd tvm-musa-m1000/examples
python build.py
脚本的位置参数是 Ultralytics 模型名,默认 yolov8s.pt,并生成:
artifacts/<model>_musa.so:TVM-MUSA 编译产物,默认模型对应artifacts/yolov8s_musa.so;artifacts/<model>_musa.json:输入 dtype、图像尺寸和类别名等运行时元数据。
模型文件不存在时,Ultralytics 会自动下载到当前工作目录。也可以直接指定其他 Yolo 模型名:
python build.py yolov8n.pt
离线设备需要提前准备对应模型文件。构建阶段固定 batch=1、640x640 静态输入,模型和输入均为 FP16,输出也是 FP16。默认模型实测输出示例:
PASS: /path/to/tvm-musa-m1000/examples/artifacts/yolov8s_musa.so
构建过程直接使用内存中的 PyTorch ExportedProgram 作为 TVM 前端输入,不会生成 ONNX 或其他中间模型文件。
.so 是面向 M1000、MUSA SDK 和当前 TVM-MUSA 版本生成的平台产物。更换设备、MUSA SDK 或 TVM wheel 后,应重新执行 build.py,不要直接复用其他环境的 .so。
Step2 加载 .so 执行推理
保持在同一目录,直接运行运行时脚本:
python inference.py
inference.py 默认加载以下文件:
artifacts/yolov8s_musa.so:由build.py生成;artifacts/yolov8s_musa.json:与.so同名的描述文件;assets/bus.jpg:用于实际推理和计时的图片。
如果构建时使用了其他模型名,请通过 --model artifacts/<model>_musa.so 指定对应产物。
标注结果自动保存到输入图片所在目录,文件名为 <原文件名>_marked<后缀>,例如 assets/bus_marked.jpg。不需要额外传入输出路径。
在 M1000、MUSA SDK 5.2.0 上使用默认参数时,实测输出示例:
PASS: 5 detections, 10.38 ms, 96.4 images/s
result: /path/to/tvm-musa-m1000/examples/assets/bus_marked.jpg
延迟和吞吐会随设备负载和模型版本波动。上述数值用于说 明输出格式和计时口径,不作为固定性能承诺。
以下条件同时满足,表示两阶段链路已经跑通:
- 构建阶段生成了
.so和同名.json; - 标注图片保存在输入图片旁边,检测结果合理;
- 两个脚本均以状态码
0退出,并分别打印构建或推理的PASS。
Step3 脚本做了什么
1. 加载、融合并导出 YOLOv8s
build.py 把命令行传入的模型名直接交给 Ultralytics;模型不存在时会自动下载。然后执行常见的 Conv-BatchNorm 融合:
from ultralytics import YOLO
yolo = YOLO(model_name)
fused = yolo.model.fuse(verbose=False)
model = (fused if fused is not None else yolo.model).eval().half()
随后把 YOLOv8 Detect 头切换到静态导出模式,并使用固定 shape 的输入执行一次前向:
import torch
from ultralytics.nn.modules import Detect
for module in model.modules():
if isinstance(module, Detect):
module.dynamic = False
module.export = True
module.shape = None
example_input = torch.zeros(1, 3, 640, 640, dtype=torch.float16)
with torch.no_grad():
model(example_input)
exported_program = torch.export.export(
model, args=(example_input,), strict=True
)
这里固定 batch=1、640x640 和静态 shape。Detect 头默认会根据输入重新生成 anchor;提前设置静态导出模式并执行一次固定输入前向,可以把 anchor 和 stride 固定下来,避免 torch.export 在 make_anchors 中遇到未绑定的动态符号。