YOLOV8 兼容适配昇腾NPU
前提:
# 已经安装好对应显卡兼容的torch_npu插件,且通过拉取源码安装torchvision_npu
# 在项目启动入口上引入这俩个包
from transformers import is_torch_npu_available
if is_torch_npu_available():
import torch_npu
import torchvision_npu
基本代码兼容:
import torch
from transformers import is_torch_npu_available
# 在全局调用获取torch设备的时候,进行如下兼容,0可以切换,若有多个显卡的话
def get_yolo_device(cls):
"""
获取有效的设备进行训练
"""
if torch.cuda.is_available():
device = torch.device('cuda:0')
elif is_torch_npu_available():
device = torch.device('npu:0')
else:
device = torch.device('cpu')
return device
# 在进行创建模型训练和推理的时候,使用上该device,不采用'cuda:0'或者'cpu'这种字符串来调用设备
model = YOLO(model_path)
model.to(device=device)
源码部分:
代码上基本已经兼容,主要涉及源码模块,在进行torch显卡设备识别的时候,源码无法对npu进行识别检测,原以为使用了torch.device后可以进行统一的过滤返回,但在进行模型训练(推理正常)的时候,最后的验证是将训练器的torch.device进行拷贝给验证器,导致torch.device从对象拷贝进去后成为了字符串如:“npu:0” ,对此需要在源码层面上做一层判断筛选,返回对应的torch.device。
在ultralytics包 → utils包 → torch_utils.py 文件
# 大概在124行,找到以下方法
def select_device(device="", batch=0, newline=False, verbose=True):
if isinstance(device, torch.device):
return devic
# 补充以下代码
if isinstance(device, str) and 'npu' in device:
return torch.device(device)
...
注意: yolo本身只支持cuda来调用GPU,所以使用以上方式进行兼容后,对于一些特定GPU上的兼容,在环境上是使用不了的,所以会发现在训练的时候会经常打印cuda相关的异常警告,但总体不影响模型的训练使用,可能在训练上对比GPU来说还是有些性能缺陷。