一、 基于 Intel GPU 加速 PyTorch 模型训练
在本专栏的前面文章中,介绍了使用OpenVINO在Intel Ultra处理器的CPU、NPU、核显GPU上加速YOLO12模型的推理:
基于 Inter Ultra 处理器中的 NPU、核显GPU 加速 YOLO12 模型推理运算
但这篇文章解决的是推理问题。如果要基于自己的数据集重新训练或微调的话,就不是NPU的范畴了, 而CPU计算速度又比较缓慢,是否可以通过Intel的GPU做加速训练呢?所以本篇文章将YOLO的推理加速引到训练加速的解决方案上。而在Ultralytics框架中又默认采用PyTorch做为后端计算引擎,因此本文再聚焦到PyTorch生态上的训练加速优化。
PyTorch默认采用NVIDIA的GPU作为加速模块,但PyTorch 从 2.5版本起逐步将Intel GPU后端合入了主干,形成了torch-xpu版本,可以驱动Intel的GPU加速训练与推理,为加速设备的选择提供了一种备选方案。使用时device名称为xpu。它支持Intel的核显与独立显卡,底层走oneAPI Level Zero和SYCL,卷积、矩阵乘等算子会调度到Intel GPU的XMX矩阵引擎上。
注意:在PyTorch早期版本中,使用Intel GPU需要额外安装IPEX,但目前官方IPEX已经停止开发,它所提供的XMX加速、算子融合等能力已经合并进了上游PyTorch中,由PyTorch官方原生支持,在使用时需要鉴别。
下面基于Intel的核显GPU实验训练加速过程,模型本次采用较新的YOLO26n作为实验对象,主要介绍:
torch-xpu的环境准备与安装。- 数据集准备标注及
YOLO26n模型训练。 - 训练结果模型测试。
本次实验使用的硬件配置:
| 设备类型 | 型号 |
|---|---|
| CPU | Intel® Core™ Ultra X7 358H |
| 核显 GPU | Intel® Arc™ B390 GPU (iGPU) |
本次采用Python 3.14版本,相关依赖包的版本如下:
Python==3.14.7torch==2.14.1+xputorchvision==0.29.1+xpuultralytics==8.4.174二、环境准备与安装
2.1 Python 版本选择
torch-xpu和Python版本有着较强的关联,仅支持Python3.9以上版本:
| Python 版本 | 可用的最高版本 |
|---|---|
| 3.8及以下 | 不支持 |
| 3.9 | 2.8.0+xpu |
| 3.10 | 2.14.1+xpu |
| 3.11 / 3.12 | 2.14.1+xpu |
| 3.13 | 2.14.1+xpu |
| 3.14 | 2.14.1+xpu |
2.2 安装
建议使用uv安装,可以更好的管理依赖之间的版本:
uv pipinstalltorch torchvision torchaudio --index-url https://download.pytorch.org/whl/xpu注意:需要使用--index-url https://download.pytorch.org/whl/xpu指定安装的是xpu为后端的pytorch, 不能直接使用pip install torch,这样装到的是CUDA/CPU版本。
安装完成后用uv pip show torch确认版本号带+xpu后缀。
2.3 环境验证
importtorchprint("PyTorch 版本:",torch.__version__)print("XPU 版本:",torch.version.xpu)print("torch.xpu 是否可用:",torch.xpu.is_available())iftorch.xpu.is_available():print("XPU 设备数:",torch.xpu.device_count())foriinrange(torch.xpu.device_count()):props=torch.xpu.get_device_properties(i)print(f" xpu:{i}: name={props.name}, "f"driver={props.driver_version}, "f"EU={props.gpu_eu_count}, "f"mem={props.total_memory/1024**3:.1f}GiB")运行输出:
可以看到torch.xpu.is_available()返回True,识别出了Arc B390 GPU,96个EU。显存为16.5GiB的共享系统内存。
如果你的电脑确实有Intel GPU但是这里没有识别出来,那可能是驱动有问题,需要去Intel官网下载安装最新驱动。
2.4 安装 ultralytics 依赖
使用uv安装ultralytics,可以自动发现上面安装的torch并使用
uv pipinstallultralytics nncf openvino2.5 使用 GPU 做 YOLO26n 推理测试
测试图片:
测试过程,分别使用xpu和cpu做推理运算,观察推理耗时差距。
fromultralyticsimportYOLOimportcv2importtime# 要对比的设备DEVICES=['xpu','cpu']# 加载模型,不存在会自动下载model=YOLO('yolo26n.pt')# 图片只读一次,避免把读盘时间算进耗时img=cv2.imread('img.png')single={}print('===== 单图推理 =====')fordeviceinDEVICES:model.predict(img,device=device,verbose=False)# 预热一下total=0infer=0foriinrange(10):t=time.time()results=model.predict(img,device=device,verbose=False)total+=time.time()-t infer+=results[0].speed['inference']# 只取模型推理那一段single[device]=(total/10,infer/10)print(f"{device:>4}总耗时{total/10*1000:6.2f}ms 推理耗时{infer/10:6.2f}ms")batch={}print('\n===== 8 图批量推理 =====')imgs=[img]*8fordeviceinDEVICES:model.predict(imgs,device=device,verbose=False)# 预热一下t=time.time()infer=0foriinrange(5):results=model.predict(imgs,device=device,verbose=False)infer+=results[0].speed['inference']# 每张图的推理耗时dt=(time.time()-t)/5batch[device]=(dt,infer/5)print(f"{device:>4}总{dt*1000:6.2f}ms/批 ={dt/8*1000:5.2f}ms/图 "f"推理{infer/5:5.2f}ms/图{8/dt:6.1f}图/秒")print('\n===== 对比(倍数越大,xpu 优势越明显)=====')print(f"单图总耗时 cpu / xpu ={single['cpu'][0]/single['xpu'][0]:5.2f}倍")print(f"单图推理耗时 cpu / xpu ={single['cpu'][1]/single['xpu'][1]:5.2f}倍")print(f"批量总耗时 cpu / xpu ={batch['cpu'][0]/batch['xpu'][0]:5.2f}倍")print(f"批量推理耗时 cpu / xpu ={batch['cpu'][1]/batch['xpu'][1]:5.2f}倍")运行结果:
从数据上看,核显的优势主要体现在批量推理上:单图约2.3倍,一次送入 8 张后单张耗时压到2.77 ms,差距拉到4.5倍,说明单张图片的运算量填不满核显的执行单元。而按整条链路的总耗时算,提升只有1.2 ~ 1.5倍,原因是NMS后处理在xpu上反而比CPU慢(约2416 ms对693 ms),把前向省下的时间还了回去。所以评价算力要看推理耗时,评价实际响应速度则要看总耗时,并注意后处理在链路中的占比。
三、YOLO26n 模型训练
数据集使用本专栏前面实验YOLO-V10时标注的人脸数据集, 这里你可以收集一些自定义的图片,然后根据下面文章中介绍的方式进行标注:
基于 YOLO V10 Fine-Tuning 训练自定义的目标检测模型
创建train-config.yaml文件,写入下面内容:
path:D:/pyProject/xpu-demo/train_data# 数据集的根目录, 建议使用绝对路径train:images/train# 训练集图像目录val:images/val# 验证集图像目录test:# test images (optional)# 分类names:0:face微调训练,设备指定xpu:
frompathlibimportPathfromultralyticsimportYOLO# 加载模型, 不存在会自动下载model=YOLO("yolo26n.pt")# 训练model.train(data="train-config.yaml",# 数据集 yaml(绝对路径)epochs=200,# 训练的周期imgsz=640,# 图像的大小device="xpu",# 设备指定 xpu,如果是 cpu 则是 device='cpu'workers=0,# Windows 下保持 0,避免多进程 spawn 的问题batch=16# 批次大小)运行后可以看到打印的设备信息:
训练过程中可以也看到GPU显存的占用:
GPU的使用情况:
训练结束后可以在runs目录下面看到训练的结果:
weights下面的就是训练后保存的模型,这里可以先看下训练时loss的变化图:
四、模型测试
在runs\detect\train\weights下可以看到best.pt和last.pt两个模型,表示最佳和最终模型,下面使用best.pt模型进行测试
importosimporttorchfrommatplotlibimportpyplotaspltfromultralyticsimportYOLO plt.rcParams['font.sans-serif']=['SimHei']# 测试图片目录地址base_path="datasets/images/val"# 加载模型:直接指定训练输出的 best.ptweights="runs/detect/train/weights/best.pt"# 使用设备device="xpu"iftorch.xpu.is_available()else"cpu"# 加载模型model=YOLO(weights)forimg_nameinos.listdir(base_path):img_path=os.path.join(base_path,img_name)image=plt.imread(img_path)# 预测results=model.predict(image,device=device)boxes=results[0].boxes.xyxy.cpu().numpy()confs=results[0].boxes.conf.cpu().numpy()cls=results[0].boxes.cls.cpu().numpy()ax=plt.gca()forindex,boxeinenumerate(boxes):x1,y1,x2,y2=boxe[0],boxe[1],boxe[2],boxe[3]cl=int(cls[index].item())score=confs[index].item()ifcl==0:ax.add_patch(plt.Rectangle((x1,y1),(x2-x1),(y2-y1),linewidth=2,fill=False,color='green'))plt.text(x=x1,y=y1-10,s="{:.2f}".format(score),fontsize=15,color='white',bbox=dict(facecolor='black',alpha=0.5))else:ax.add_patch(plt.Rectangle((x1,y1),(x2-x1),(y2-y1),linewidth=2,fill=False,color='red'))plt.text(x=x1,y=y1-10,s="{:.2f}".format(score),fontsize=15,color='white',bbox=dict(facecolor='black',alpha=0.5))plt.imshow(image)plt.show()测试结果: