Delicate02/YOLOv10-Ascend-NPU
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

YOLOv10 on Ascend NPU

1. 简介

本文档记录 YOLOv10 在华为昇腾 Ascend NPU 上的适配、推理优化与性能验证结果。YOLOv10 是一种实时端到端目标检测模型,采用一致的双分配策略实现无 NMS 推理,在保持高精度的同时显著降低推理延迟。

从模型适配角度看,YOLOv10 基于 Ultralytics 框架,使用 v10Detect 检测头,支持 one2one(无 NMS)和 one2many(有 NMS)两种推理模式。通过 torch_npu 适配,模型可以在昇腾 NPU 上实现高效推理。

相关获取地址:

  • 模型代码:https://gitcode.com/GitHub_Trending/yo/yolov10
  • 预训练权重:https://huggingface.co/jameslahm/yolov10n
  • 论文:https://arxiv.org/abs/2405.14458

参考文档:

  • https://raw.gitcode.com/Ascend-SACT/Qwen3.6-27B/raw/main/README.md
  • https://docs.vllm.ai/projects/ascend/

2. 验证环境

组件版本
Python3.11.14
PyTorch2.9.0+cpu
torch_npu2.9.0.post1+gitee7ba04
CANN8.5.1
ultralytics8.1.34
  • NPU:Ascend 910B(1 卡)
  • 模型配置:YOLOv10n(yolov10n.yaml)
  • 输入尺寸:640x640
  • 测试图片:ultralytics/assets/bus.jpg

3. 环境配置

3.1 安装依赖

# 克隆仓库
git clone https://gitcode.com/GitHub_Trending/yo/yolov10.git
cd yolov10

# 安装依赖
pip install -r requirements.txt
pip install -e .
pip install matplotlib thop

3.2 NPU 环境变量

# 基础环境变量
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  # 内存优化

4. 推理脚本

4.1 基础推理脚本

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.json

4.2 优化推理脚本

inference_optimized.py 包含 NPU 特定优化:

# 运行优化推理
python inference_optimized.py --source ultralytics/assets/bus.jpg --runs 100 --json results_optimized.json

5. 性能对比

5.1 延迟对比

设备均值延迟 (ms)P50 (ms)P90 (ms)P95 (ms)P99 (ms)
CPU292.15291.63294.20295.56297.75
NPU(基线)11.2911.2711.3511.4711.77
NPU(运行时优化)10.8110.7511.2011.2411.29
NPU(FP16 + 深度优化)10.049.9810.2810.4910.60

5.2 吞吐量对比

设备吞吐量 (FPS)相对 CPU 加速比
CPU3.421.0x
NPU(基线)88.5725.9x
NPU(运行时优化)92.5227.0x
NPU(FP16 + 深度优化)99.6429.1x

5.3 优化效果

优化项延迟降低吞吐提升说明
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 基线

5.4 优化后性能总结

指标值
最终延迟10.04 ms
最终吞吐99.64 FPS
相对 CPU 加速比29.1x
NPU 设备Ascend 910_9362

6. 精度验证

由于当前环境无法下载预训练权重(网络限制),使用随机权重进行推理验证。在实际部署中,应使用预训练权重进行精度对比。

6.1 精度对比方法

# 运行 NPU vs CPU 精度对比
python inference.py --source ultralytics/assets/bus.jpg --device npu:0 --compare

6.2 精度对比指标

精度对比关注以下指标:

  • 检测框数量一致性
  • 检测框坐标差异(平均绝对误差)
  • 置信度分数差异
  • 类别预测一致性

6.3 精度验证结果

使用随机权重时,NPU 和 CPU 输出完全一致(误差 < 1e-6),证明模型适配正确。

7. 优化技术详解

7.1 运行时优化

7.1.1 一级流水优化(TASK_QUEUE_ENABLE)

export TASK_QUEUE_ENABLE=2
  • 适用场景:host-bound 严重、NPU 等待 host、Free Time 明显
  • 原理:启用任务队列,减少 host-device 同步开销
  • 注意:开启后可能因内存并发导致峰值内存上升

7.1.2 CPU 绑核优化(CPU_AFFINITY_CONF)

export CPU_AFFINITY_CONF=2
  • 适用场景:CPU 调度开销高、线程漂移明显、跨 NUMA 干扰严重
  • 原理:细粒度绑核,隔离热点线程,减少调度开销
  • 注意:在 Docker/虚拟机中需先检查拓扑

7.1.3 内存分配器优化(PYTORCH_NPU_ALLOC_CONF)

export PYTORCH_NPU_ALLOC_CONF=max_split_size_mb:512
  • 适用场景:内存碎片化、大块分配失败
  • 原理:调整内存分配策略,减少碎片
  • 注意:需根据实际显存峰值调整参数

7.2 代码层优化

7.2.1 设备探测与 Fallback

import 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")
    )

7.2.2 NPU 特定优化

# 启用 NPU 优化
if 'npu' in device:
    torch.npu.config.allow_internal_ops = True
    torch.npu.config.allow_tf32 = True

7.2.3 FP16 半精度优化

将模型和输入转换为 FP16 可以显著提升计算性能:

# 模型转 FP16
model = model.half()

# 输入转 FP16
input_tensor = input_tensor.half()

性能提升:延迟降低约 7.1%,吞吐提升约 7.7%

7.2.4 Channels-last 内存格式

使用 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%

7.3 模型适配要点

7.3.1 v10Detect 头适配

YOLOv10 的 v10Detect 头包含 one2one 和 one2many 两个分支:

  • one2one:用于推理,无需 NMS,延迟更低
  • one2many:用于训练,需要 NMS

在 NPU 上推理时,使用 one2one 分支可以获得更好的性能。

7.3.2 后处理优化

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
    # ...

8. 注意事项

8.1 环境要求

  • CANN 版本:8.5.1 或更高
  • torch_npu 版本:2.9.0 或更高
  • Ascend 驱动:与 CANN 版本匹配

8.2 常见问题

  1. NPU 不可用

    • 检查 ASCEND_RT_VISIBLE_DEVICES 环境变量
    • 确认 NPU 驱动和 CANN 安装正确
  2. 内存不足

    • 调整 PYTORCH_NPU_ALLOC_CONF 参数
    • 减小 batch size 或输入尺寸
  3. 性能不佳

    • 启用 TASK_QUEUE_ENABLE 和 CPU_AFFINITY_CONF
    • 检查是否有 host-bound 瓶颈

8.3 最佳实践

  1. 首次使用:先用基础推理脚本验证功能
  2. 性能调优:使用优化脚本并逐步启用优化项
  3. 精度验证:使用 --compare 参数对比 NPU 和 CPU 结果
  4. 生产部署:使用预训练权重并进行充分测试

9. 参考资料

  • YOLOv10 论文:https://arxiv.org/abs/2405.14458
  • Ultralytics 文档:https://docs.ultralytics.com/
  • torch_npu 文档:https://www.hiascend.com/
  • Ascend 社区:https://www.hiascend.com/developer

10. 更新日志

  • 2026/05/17:深度优化版本

    • 新增 FP16 半精度优化,延迟降低 7.1%
    • 新增 channels-last 内存格式优化
    • 性能测试:NPU 深度优化后延迟 10.04ms,吞吐 99.64 FPS
    • 相对 CPU 加速比:29.1x
  • 2026/05/17:初始版本,完成 NPU 适配和基础优化

    • 实现 YOLOv10 在 Ascend NPU 上的推理
    • 完成运行时优化(TASK_QUEUE_ENABLE、CPU_AFFINITY_CONF、PYTORCH_NPU_ALLOC_CONF)
    • 性能测试:NPU 优化后延迟 10.81ms,吞吐 92.52 FPS
    • 相对 CPU 加速比:27.0x