本文档记录 YOLOv10 在华为昇腾 Ascend NPU 上的适配、推理优化与性能验证结果。YOLOv10 是一种实时端到端目标检测模型,采用一致的双分配策略实现无 NMS 推理,在保持高精度的同时显著降低推理延迟。
从模型适配角度看,YOLOv10 基于 Ultralytics 框架,使用 v10Detect 检测头,支持 one2one(无 NMS)和 one2many(有 NMS)两种推理模式。通过 torch_npu 适配,模型可以在昇腾 NPU 上实现高效推理。
相关获取地址:
参考文档:
| 组件 | 版本 |
|---|---|
| Python | 3.11.14 |
| PyTorch | 2.9.0+cpu |
| torch_npu | 2.9.0.post1+gitee7ba04 |
| CANN | 8.5.1 |
| ultralytics | 8.1.34 |
# 克隆仓库
git clone https://gitcode.com/GitHub_Trending/yo/yolov10.git
cd yolov10
# 安装依赖
pip install -r requirements.txt
pip install -e .
pip install matplotlib thop# 基础环境变量
export ASCEND_RT_VISIBLE_DEVICES=0
# 优化环境变量(可选)
export TASK_QUEUE_ENABLE=2 # 一级流水优化
export CPU_AFFINITY_CONF=2 # 细粒度 CPU 绑核
export PYTORCH_NPU_ALLOC_CONF=max_split_size_mb:512 # 内存优化inference.py 提供了完整的 NPU 推理功能:
# 基础 NPU 推理
python inference.py --source ultralytics/assets/bus.jpg --device npu:0
# 带性能基准测试
python inference.py --source ultralytics/assets/bus.jpg --device npu:0 --benchmark --runs 100
# NPU vs CPU 精度对比
python inference.py --source ultralytics/assets/bus.jpg --device npu:0 --compare
# 保存结果到 JSON
python inference.py --source ultralytics/assets/bus.jpg --device npu:0 --benchmark --json results.jsoninference_optimized.py 包含 NPU 特定优化:
# 运行优化推理
python inference_optimized.py --source ultralytics/assets/bus.jpg --runs 100 --json results_optimized.json| 设备 | 均值延迟 (ms) | P50 (ms) | P90 (ms) | P95 (ms) | P99 (ms) |
|---|---|---|---|---|---|
| CPU | 292.15 | 291.63 | 294.20 | 295.56 | 297.75 |
| NPU(基线) | 11.29 | 11.27 | 11.35 | 11.47 | 11.77 |
| NPU(运行时优化) | 10.81 | 10.75 | 11.20 | 11.24 | 11.29 |
| NPU(FP16 + 深度优化) | 10.04 | 9.98 | 10.28 | 10.49 | 10.60 |
| 设备 | 吞吐量 (FPS) | 相对 CPU 加速比 |
|---|---|---|
| CPU | 3.42 | 1.0x |
| NPU(基线) | 88.57 | 25.9x |
| NPU(运行时优化) | 92.52 | 27.0x |
| NPU(FP16 + 深度优化) | 99.64 | 29.1x |
| 优化项 | 延迟降低 | 吞吐提升 | 说明 |
|---|---|---|---|
| TASK_QUEUE_ENABLE=2 | ~2.1% | ~2.1% | 一级流水优化 |
| CPU_AFFINITY_CONF=2 | ~1.5% | ~1.5% | 细粒度 CPU 绑核 |
| PYTORCH_NPU_ALLOC_CONF | ~0.9% | ~0.9% | 内存分配优化 |
| FP16 半精度 | ~7.1% | ~7.7% | 计算精度优化 |
| Channels-last 内存格式 | ~0.5% | ~0.5% | 内存布局优化 |
| 综合优化 | ~11.1% | ~12.5% | 相对 NPU 基线 |
| 指标 | 值 |
|---|---|
| 最终延迟 | 10.04 ms |
| 最终吞吐 | 99.64 FPS |
| 相对 CPU 加速比 | 29.1x |
| NPU 设备 | Ascend 910_9362 |
由于当前环境无法下载预训练权重(网络限制),使用随机权重进行推理验证。在实际部署中,应使用预训练权重进行精度对比。
# 运行 NPU vs CPU 精度对比
python inference.py --source ultralytics/assets/bus.jpg --device npu:0 --compare精度对比关注以下指标:
使用随机权重时,NPU 和 CPU 输出完全一致(误差 < 1e-6),证明模型适配正确。
export TASK_QUEUE_ENABLE=2export CPU_AFFINITY_CONF=2export PYTORCH_NPU_ALLOC_CONF=max_split_size_mb:512import torch
try:
import torch_npu
_HAS_TORCH_NPU = True
except ImportError:
torch_npu = None
_HAS_TORCH_NPU = False
def _is_npu_tensor(x: torch.Tensor) -> bool:
return (
_HAS_TORCH_NPU
and hasattr(torch, "npu")
and torch.npu.is_available()
and str(x.device).startswith("npu")
)# 启用 NPU 优化
if 'npu' in device:
torch.npu.config.allow_internal_ops = True
torch.npu.config.allow_tf32 = True将模型和输入转换为 FP16 可以显著提升计算性能:
# 模型转 FP16
model = model.half()
# 输入转 FP16
input_tensor = input_tensor.half()性能提升:延迟降低约 7.1%,吞吐提升约 7.7%
使用 channels-last 内存格式可以优化卷积运算的内存访问模式:
# 模型转 channels-last
model = model.to(memory_format=torch.channels_last)
# 输入转 channels-last
input_tensor = input_tensor.to(memory_format=torch.channels_last)性能提升:延迟降低约 0.5%,吞吐提升约 0.5%
YOLOv10 的 v10Detect 头包含 one2one 和 one2many 两个分支:
在 NPU 上推理时,使用 one2one 分支可以获得更好的性能。
def postprocess(preds, conf_thres=0.25, iou_thres=0.45, ...):
# 获取 one2one 预测(无 NMS)
if isinstance(preds, dict):
if 'one2one' in preds:
preds = preds['one2one']
# 转置并分割
preds = preds.t()
boxes = preds[:, :4] # xywh
scores = preds[:, 4:] # 类别分数
# 置信度过滤
max_scores, class_ids = scores.max(dim=1)
mask = max_scores > conf_thres
# ...NPU 不可用
ASCEND_RT_VISIBLE_DEVICES 环境变量内存不足
PYTORCH_NPU_ALLOC_CONF 参数性能不佳
TASK_QUEUE_ENABLE 和 CPU_AFFINITY_CONF--compare 参数对比 NPU 和 CPU 结果2026/05/17:深度优化版本
2026/05/17:初始版本,完成 NPU 适配和基础优化