1. 为什么是这套组合:Ubuntu + PyTorch + Ultralytics
先说结论:YOLO环境搭建之所以劝退那么多人,90%的报错都出在环境本身,而不是模型代码。网上教程东拼西凑,A帖让你装CUDA 11.8,B帖让你装CUDA 12.1,你照着敲完命令行,第一行import torch就红了。这篇文章我直接按自己实操验证过的流程来写,从系统到推理跑通,一步到位。
先说选型思路。YOLO现在主流的训练和推理框架就是Ultralytics,它把YOLOv8、YOLO11、YOLOv5的数据加载、模型结构、训练流程、导出部署全部封装成了一套Python接口。我不需要再去GitHub上翻源码自己拼训练脚本,也不用自己写数据增强、学习率调度这些通用逻辑,一条命令就能开始训练。
而Ultralytics的底层是PyTorch,所以PyTorch装得好不好,直接决定了后续会不会炸。PyTorch嘛,做深度学习的估计没人不知道,它用动态计算图,调试起来比TensorFlow的静态图舒服太多,社区生态也是最活跃的。YOLO的模型定义、损失函数、训练的每一步都跑在PyTorch上,装错一个CUDA版本,后面全是连锁反应。
至于为什么用Ubuntu而不是Windows,我自己的感受是:Windows上装PyTorch GPU版本身不难,难的是后续装一些依赖库时总有莫名其妙的问题,比如编译报错、DLL缺失、路径带空格之类。而Ubuntu的包管理一套apt下去干净利落,绝大多数深度学习开源项目的第一支持系统都是Linux,遇到坑能搜到的解决方案也最多。如果你用的是WSL2,那体验和原生Ubuntu基本没差,显卡驱动走Windows那边的就行,下面我会单独讲。
这套组合适合谁?适合刚开始接触目标检测、想用自己的数据集训练YOLO模型、或者正在复现论文项目的朋友。只要你跟着这篇文章把环境理顺,后面的训练、验证、导出部署就会顺很多。
2. 动手前的准备:Ubuntu系统和显卡驱动
2.1 第一次装系统,选WSL还是原生Ubuntu
我的建议是:如果你已经有Windows在用,优先考虑WSL2,省去双系统和驱动折腾的麻烦。WSL2是在Windows里跑一个轻量虚拟化Linux环境,装好后直接在终端操作,文件系统互通,我实测训练速度能达到原生Linux的95%左右,完全够用。
如果决定用原生Ubuntu,注意几个核心步骤。下载Ubuntu 22.04 LTS或24.04 LTS镜像,用Rufus或balenaEtcher做成启动U盘。安装时分区建议单独划一个/home分区,方便以后系统出问题重装时数据还在。别的选项基本默认即可。
装完系统后第一步不是装Python环境,而是先把显卡驱动搞定。如果你在虚拟机里安装Ubuntu(VMware这类),那就不存在独立显卡直通的问题,后面直接装CPU版PyTorch就行,训练慢一点但能跑。
2.2 安装NVIDIA驱动,踩过的三个坑
Ubuntu桌面版的"软件和更新"里有一个额外的驱动程序选项卡,可以直接在里面选NVIDIA驱动,这是最推荐的方式,简单粗暴。但实际用下来有几个坑:
第一个坑是装了驱动后黑屏。这通常是因为Nouveau开源驱动没禁用干净,和NVIDIA驱动冲突。解决方法是进恢复模式先把NVIDIA驱动卸载,然后在启动参数里加上rd.driver.blacklist=nouveau modprobe.blacklist=nouveau,重启后再装NVIDIA驱动。
第二个坑是驱动版本和CUDA版本不匹配。新手最容易在这里绕晕。其实CUDA Toolkit自带某个版本的驱动要求,高版本驱动向下兼容低版本CUDA。我建议装最新的稳定版驱动,这样后面换CUDA版本时不用频繁改驱动。
第三个坑是明明装了显卡驱动,但nvidia-smi命令提示找不到。十有八九是装驱动时用的runfile方式和系统内核版本产生了冲突。我的经验是用Ubuntu官方的apt源装驱动最稳:
# 查看推荐版本 ubuntu-drivers devices # 自动安装推荐驱动 sudo ubuntu-drivers install装完重启,终端输入nvidia-smi,能看到类似下面的输出就说明驱动OK:
+-----------------------------------------------------------------------------+ | NVIDIA-SMI 525.147.05 Driver Version: 525.147.05 CUDA Version: 12.0 | +-----------------------------------------------------------------------------+注意这里的CUDA Version: 12.0表示当前驱动支持的最高CUDA版本,不是你实际安装的CUDA Toolkit版本,这两个概念千万别搞混。后面装PyTorch时看的就是它。
2.3 Anaconda:环境管理的第一个护身符
我强烈建议通过Anaconda来管理Python环境,不要直接用系统自带的Python。原因很朴素:你的项目A可能需要Python 3.8 + PyTorch 1.13,项目B需要Python 3.11 + PyTorch 2.3,如果全装在系统里,早晚要打架。用conda给每个项目建独立环境,互不干扰。
# 下载Anaconda安装包,建议用清华源 wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2024.06-1-Linux-x86_64.sh # 执行安装,一路按Enter,最后输入yes确认 bash Anaconda3-2024.06-1-Linux-x86_64.sh # 让conda初始化生效 source ~/.bashrc安装完成后,顺手配置一下国内镜像源,否则后面创建虚拟环境、装包的时候那个速度会让人崩溃:
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --set show_channel_urls yes然后创建一个YOLO实战的专用环境:
conda create -n yolo python=3.10 -y conda activate yoloPython版本我为什么选3.10?因为Ultralytics对Python 3.8到3.12都兼容,而3.10是目前PyTorch、CUDA、各种依赖库兼容性最稳妥的版本。3.12虽然新,但有些老库还没跟上;3.8又偏老,部分新版本PyTorch已经停止支持了。3.10是那个编译报错最少的选择。
3. PyTorch安装:CUDA版本怎么选才不翻车
3.1 先搞清楚CUDA、cuDNN、PyTorch三者的关系
很多新手拿到教程就跟着敲pip install torch,结果装了CPU版,等训练的时候发现模型跑到天荒地老才意识到不对劲。这三个东西的关系我打个比方:CUDA是NVIDIA给GPU写的底层驱动协议和计算库,cuDNN是针对深度学习的卷积等操作进一步加速的库,而PyTorch是更上层的深度学习框架。PyTorch会内置它自己编译好的CUDA运行时代码,所以你不一定需要单独安装完整的CUDA Toolkit。
关键是绕开那个常见的坑:不要先去NVIDIA官网下载CUDA Toolkit。直接按PyTorch官网给的命令安装,PyTorch会自己带上匹配的CUDA工具包,这样版本一致性问题就少了一大半。
3.2 用官方命令安装GPU版PyTorch
打开PyTorch官网(pytorch.org),选择你对应的系统、安装方式、CUDA版本,它会自动生成一条安装命令。2025年写这篇文章时,我是这样装的:
conda activate yolo pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121这个命令里的cu121就是CUDA 12.1版本。为什么选12.1?因为它是目前兼容面最广的版本,Ultralytics官方测试最充分的也是这个版本。如果你机器较新、驱动版本很高,也可以选cu124或更新版本。判断标准就一条:你之前nvidia-smi输出里的CUDA Version不能低于你选的版本。比如驱动显示最高支持12.0,那你只能装cu118或更低的。
装完验证是否真的能调用GPU:
python -c "import torch; print(torch.__version__); print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0))"如果输出:
2.8.0+cu121 True NVIDIA GeForce RTX 4060 Laptop GPU就说明PyTorch确实在用CUDA了。如果torch.cuda.is_available()返回False,直接跳到第5章的排查部分。
3.3 CPU版与GPU版的取舍
如果你的机器没有NVIDIA显卡,或者是在虚拟机里跑,那就装CPU版:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpuCPU版不是不能用,我实测在CPU上跑YOLO11s模型推理一张640x640的图大约需要0.8秒,训练的话一张COCO子集图片大概要3到5秒,做个实验验证流程还是可以的,真要训练大模型就有点折磨人了。如果你短期内没有升级硬件的打算,建议优先用Google Colab这类云端GPU平台做训练,本地环境先用CPU版熟悉流程。
3.4 关于cuDNN,要不要单独装
单独装cuDNN还是有必要的,尤其是训练大型模型时性能差距明显。用conda安装最省事:
conda install -c conda-forge cudnn不过注意,PyTorch内部也带了卷积运算的加速实现,不装cuDNN它也能跑,只是速度会差一些。我的建议是:先用不装cuDNN的方式跑通流程,等确认一切正常后再装上,避免一步错步步错的排查难度。
4. Ultralytics安装与首次实战验证
4.1 安装Ultralytics包
环境已经就绪,现在进入正题。Ultralytics的安装简单得很:
pip install ultralytics这条命令会把YOLO训练推理的所有依赖一起装上,包括opencv-python、matplotlib、pandas、pyyaml这些。装完后验证一下版本:
python -c "import ultralytics; print(ultralytics.__version__)"看到输出版本号就说明装好了。如果这一步报错,大概率是依赖冲突,常见的是opencv-python版本问题。我用3.10环境实测下来,Ultralytics最新版配Python 3.10是兼容的,如果报cv2相关的错,可以单独重装一下:
pip uninstall opencv-python opencv-python-headless -y pip install opencv-python4.2 首次推理验证:用自己的图片跑一次YOLO
环境通不通,拉出来遛遛就知道。我找了一张包含人和车辆的街景图,跑一次YOLO11n模型推理:
yolo predict model=yolo11n.pt source='https://ultralytics.com/images/bus.jpg'第一次运行会自动下载yolo11n.pt权重文件(大概6MB),然后开始推理。整个过程如果没报错,你会在输出里看到类似这样的信息:
image 1/1 /path/to/bus.jpg: 640x640 4 persons, 1 bus, 4s Speed: 12.3ms preprocess, 45.6ms inference, 2.1ms postprocess同时会在当前目录下生成runs/detect/predict/文件夹,里面是画好检测框的结果图。看到这个输出,你的环境就算是100%跑通了。
如果你习惯写Python脚本的方式,可以这样:
from ultralytics import YOLO model = YOLO("yolo11n.pt") results = model("https://ultralytics.com/images/bus.jpg", save=True) # results[0].boxes 里有检测框坐标、置信度、类别ID print(results[0].boxes.xyxy) # 4个角的坐标 print(results[0].boxes.conf) # 置信度 print(results[0].boxes.cls) # 类别ID4.3 用自建数据集训练YOLO模型的标准流程
环境搭好只是开始,大多数人来搭这个环境是为了训练自己的检测模型。Ultralytics的训练流程我已经跑过很多次了,这里把关键流程梳理一遍。
第一步是标注数据。官方推荐用LabelImg或Roboflow做标注,输出格式支持YOLO的txt格式和COCO的json格式。我平时用的最多的是LabelImg,它操作简单:画框、选类别、保存,一个小时内能标几百张图。标注完成后,数据目录按下面的方式组织:
datasets/ ├── images/ │ ├── train/ # 训练图片 │ └── val/ # 验证图片 ├── labels/ │ ├── train/ # 每张图片对应的标注txt │ └── val/ └── data.yaml # 数据集配置文件data.yaml的内容是:
train: datasets/images/train val: datasets/images/val nc: 2 names: ['person', 'car']第二步是转换格式。如果你标注的时候用的是COCO格式,需要转成YOLO格式。格式转换的核心逻辑很简单:COCO的标注是像素坐标的多边形或矩形框,YOLO需要的是归一化后的中心点坐标和宽高。转换公式是:
x_center = (x_min + x_max) / 2 / image_width y_center = (y_min + y_max) / 2 / image_height width = (x_max - x_min) / image_width height = (y_max - y_min) / image_height每个标注框存一行txt,格式是class_id x_center y_center width height,所有值都在0到1之间。
第三步是开训。Ultralytics封装好了训练的逻辑,只需要了解几个关键参数:
yolo train model=yolo11s.pt data=datasets/data.yaml epochs=100 imgsz=640 batch=8 device=0model:选择的预训练权重,yolo11n是最轻量的版本,yolo11x是精度最高的版本。一般建议从s或m开始试,训练时间适中,效果也不错。epochs:训练轮数。数据量小的话50到100轮绰绰有余。batch:显存小就调低点,一般8或16是稳妥值。显存不够就调成4,甚至用梯度累积。imgsz:训练分辨率。640是默认值,效果和速度比较均衡。device=0:代表使用第一块GPU。CPU训练就改成device=cpu。
训练过程中输出的loss值怎么看?我直接说结论:box_loss是边界框回归的损失,cls_loss是分类损失,dfl_loss是分布焦点损失。三者都在下降就说明模型在正常学习。如果loss从训练一开始就不下降或者变成nan,优先检查学习率和数据标注是否正确。
4.4 模型导出:训练完要部署怎么办
训练完成后,模型权重保存在runs/train/exp/weights/best.pt。如果要把模型部署到手机、嵌入式设备或者推理服务上,需要导出成不同格式。Ultralytics一键搞定:
yolo export model=runs/train/exp/weights/best.pt format=onnx # 或者导出TensorRT格式,NVIDIA GPU上推理速度最快 yolo export model=runs/train/exp/weights/best.pt format=engine device=0导出的ONNX文件就可以用ONNXRuntime部署了,TensorRT格式则用于NVIDIA GPU上的高性能服务。这个流程我自己踩坑无数:ONNX导出时最容易遇到的问题就是opset version不兼容,如果部署端对opset有要求,可以在导出时指定:
yolo export model=best.pt format=onnx opset=125. 高频环境报错的定位与处理
这一章我把自己实际遇到过的报错整理成速查表。不敢说覆盖100%,但至少能覆盖平时最常见的70%以上,另外那30%都能通过对报错信息的正确解读找到方向。
5.1 torch.cuda.is_available() 返回 False
这是新手遇到最多的一个问题,也是最让人崩溃的一个。原因无非以下几种:
| 可能原因 | 排查方法 | 解决办法 |
|---|---|---|
| 装了CPU版PyTorch | pip list | grep torch看版本有没有+cu后缀 | 卸载后按GPU版重装 |
| 驱动没装好 | 终端敲nvidia-smi看是否有输出 | 重装NVIDIA驱动 |
| 驱动太旧,不支持当前CUDA版本 | nvidia-smi看最上面的CUDA Version | 升级驱动或降低CUDA版本 |
| 在虚拟机上用GPU直通 | 虚拟机默认不提供GPU | 装CPU版或改用WSL2 |
排查思路是:先确认硬件的驱动正常(nvidia-smi),再确认PyTorch版本带CUDA,最后确认版本匹配。这三步走完,90%的问题能解决。
有个小细节我补充一下:如果你装了多个Python环境,用anaconda建了虚拟环境,检查torch版本时一定要先确认当前激活的是哪个env。我有一次检查了半天找不到原因,结果是检查的时候base环境里有一个旧版torch,而在yolo环境里却用的另一个版本。
5.2 导入Ultralytics时出现 pkg_resources 相关报错
这个报错的大意是AttributeError: module 'pkg_resources' has no attribute 'get_distribution'。这通常是因为setuptools版本太新或太旧导致的不兼容。Ultralytics某些版本依赖了setuptools的旧接口。
解决办法:
pip install setuptools==68.0.0如果还不行,就把setuptools升到最新:
pip install -U setuptools这类问题本质上是Python生态的依赖地狱,体验很糟糕,但解决方案通常就这么简单。
5.3 opencv-python 导入时报 libGL.so.1 错误
报错信息通常长这样:
ImportError: libGL.so.1: cannot open shared object file: No such file or directory原因很直接:OpenCV需要libGL库,但你的系统没装。在Ubuntu上执行:
sudo apt update sudo apt install -y libgl1 libglib2.0-0这个典型案例告诉我们一个道理:深度学习的报错不全是Python包的问题,很多是系统层面的动态链接库缺失。看到cannot open shared object file时,第一反应应该是去查这个动态库属于哪个系统包,用apt file搜索一下再装。
5.4 CUDA Out of Memory 显存不足
报错类似:
RuntimeError: CUDA out of memory. Tried to allocate 512.00 MiB (GPU 0; 8.00 GiB total capacity; 7.25 GiB already allocated)这个不算严格意义的环境报错,但训练时非常常见。我给的实用方案是:
- 调小
batch,这个立竿见影。比如batch从16改到8,显存占用直接减半。 - 把训练图片尺寸
imgsz从640改成512或416。 - 设置
cache=False,避免预加载整个数据集到内存。 - 用混合精度训练:Ultralytics里加参数
amp=True,这在Ampere架构及以上的显卡上效果很好,显存占用和训练速度都会改善。 - 如果连续报显存不够,检查一下是不是有上次运行残留的显存占用。可以用
nvidia-smi里的PID找到进程,然后kill掉,或者干脆重启一下。
5.5 下载权重超时或卡住不动
Ultralytics第一次运行时会自动从GitHub下载预训练权重,国内网络经常卡住。我的解决方案是手动下载,然后再加载。
到GitHub的Ultralytics仓库的release页面找到对应的.pt文件下载,放到当前目录,然后代码里这样用:
model = YOLO("/path/to/yolo11n.pt")或者给Ultralytics配置镜像源。在Python里设置环境变量:
import os os.environ["YOLO_CONFIG_DIR"] = "/path/to/config"实际上,权重下载用的是GitHub的release地址,这个域名在部分地区连接不稳定。我的经验是:提前手动下好权重、放在项目目录里,是最省心的方式,没有之一。另外把下面这行加进代码,会提示Ultralytics不要联网检查更新,省掉等待超时的时间:
from ultralytics import settings settings.update({"sync": False})5.6 训练时NCCL报错或分布式训练初始化失败
如果你在多卡训练时遇到:
RuntimeError: NCCL error in: ... unhandled system error, NCCL version 2.x.x大概率是进程通信出了问题。单卡训练的踩坑记录中遇到过类似的问题,可以给几个尝试方向:
- 检查多张显卡之间是否在同一个PCIe拓扑中,有时主板插槽分配不合理会导致通信异常。
- 降级NCCL相关环境变量,例如设置
NCCL_P2P_DISABLE=1,如果问题消失说明是GPU间点对点通信的兼容性问题。
NCCL_P2P_DISABLE=1 yolo train ...5.7 pip安装依赖时超时或网络失败
国内网络环境下pip install经常卡住,这不是环境问题但非常烦人。我通常直接换国内镜像源:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple ultralytics或者永久配置默认源:
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple5.8 常见报错速查表
| 报错信息 | 根因 | 解决方式 |
|---|---|---|
no module named 'torch' | Python环境选错或未安装 | conda activate yolo再pip install torch |
ImportError: libGL.so.1 | 缺少系统库 | sudo apt install libgl1 libglib2.0-0 |
AssertionError: CUDA unavailable | PyTorch和CUDA不匹配 | 重新安装匹配GPU的PyTorch版本 |
FileNotFoundError: yolov8n.pt | 权重下载失败 | 手动下载权重放到目录 |
OutOfMemoryError: CUDA out of memory | 显存不足 | 调小batch或imgsz |
AttributeError: 'NoneType' object has no attribute 'shape' | 图片路径错误/图片损坏 | 检查图片目录格式和文件完整性 |
subprocess.CalledProcessError | 编译相关依赖问题 | 安装编译工具链sudo apt install build-essential |
TypeError: __init__() got an unexpected keyword argument 'device' | ultralytics和torch版本不兼容 | 同时升级pip install -U ultralytics torch |
6. 实操心得:那些踩过坑之后才知道的事
环境搭建本身不难,难的是遇到问题后能不能准确判断问题的方向。这几条是我反复踩坑后总结出的习惯,能帮你少走很多弯路。
养成先看报错第一行而非最后一行的习惯。终端输出一长串红色信息,大多数人下意识看最后一行,但很多时候真正的错误原因在开头的几行里。比如ImportError,它会先告诉你哪个模块、哪个动态库找不到,那是源头;后面的一大堆 traceback 只是调用链。我先用编辑器把完整报错信息复制下来,从第一行往下扫,定位到第一个Error,这一点对任何环境问题都适用。
版本锁定是环境稳定的基石。记录环境配置时,不要只写 "torch 2.x",而是具体到torch==2.8.0+cu121、ultralytics==8.3.x、python==3.10.11。很多问题就是"昨天还好好的,今天就不行了"——大概率不是你代码改了,而是某个依赖自动升级了。把关键依赖版本写在项目的requirements.txt里,并用pip freeze > requirements.txt锁定环境快照,这是专业团队的普遍做法。
给显存留点冗余。训练时显存占用顶满不一定报错,但速度会明显下降,严重时系统整个卡死。我通常把batch设置成显存能容纳的70%左右,训练稳定性好很多。怎么算?先设一个较大的batch跑一个batch试试,观察nvidia-smi里显存占用,再按比例下调。
Ubuntu上写代码,字体也很重要。当时从Mac切到Ubuntu最不习惯的就是终端字体,默认的Ubuntu Mono怎么看怎么别扭。后来换了JetBrains Mono和Cascadia Code之后,体验确实提升了不止一个档次——等宽、清晰、对0、O、1、l这些容易混淆的字符有很好的区分度。终端风格也是,用起来舒服了,排查报错的心情都好一点。
不要忽视系统的数据和环境备份。有一次我手滑把conda环境搞坏了,重装了好几个小时。后来养成了两个习惯:一是创建虚拟环境时给环境和项目目录留好清晰的文档记录;二是重要数据和权重定期备份。环境坏了就重建,数据丢了才真的头疼。
遇到不确定的报错,先搜索再动手。不夸张地说,90%的环境报错都能在网上找到答案。搜索的技巧是直接把报错信息里带Error的那一行原封不动地复制到搜索引擎,加上"解决方案"或者"site:github.com"限定范围。拿别人验证过的方案当参考,比自己瞎试效率高的多。
一切跑通之后,记得保存一个环境备份。conda导出当前环境的依赖列表:
conda env export > yolo_environment.yaml这样即使以后系统坏了,也能用一条命令复现同样的环境:
conda env create -f yolo_environment.yaml实践下来,这套流程我从裸机到跑通YOLO推理,花费的时间从一开始的两天缩短到现在的半小时。环境搭建这东西,第一次总是痛苦的,但每踩过一个坑,你对整个体系的理解就深一层。环境稳定之后,就可以把精力放在真正的目标检测任务上了——数据标注、模型调优、性能优化,那些才是出成果的地方。