ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Windows 10 上从零搭建 YOLOX 目标检测环境实战指南

Windows 10 上从零搭建 YOLOX 目标检测环境实战指南

1. 为什么在 Windows 10 上跑 YOLOX 值得单独写一篇

如果你之前一直在 Linux 环境下做深度学习,第一次把训练或推理环境搬到 Windows 10 上,大概率会被各种编译错误、路径问题和依赖冲突折腾得够呛。YOLOX 作为一款在工业检测、安防监控、自动驾驶感知里被广泛使用的目标检测模型,它的官方代码默认是按 Linux 环境写的,很多脚本里直接用了sh命令、ln软链接,甚至依赖一些只在 Linux 下才有的编译工具链。这就导致很多人在 Windows 上装到一半就卡住,最后要么放弃,要么装个 WSL 绕过去。

但现实情况是,大量做算法落地的团队,开发和调试机器就是 Windows 10 台式机或者笔记本,尤其是做安防、工业质检这类场景,现场设备往往就是 Windows 系统。你不可能要求每个部署现场都装 Linux,所以把 YOLOX 在 Windows 10 上跑通,是一件非常实际、非常有必要的事情。这篇内容就是把我自己在 Windows 10 上从零搭建 YOLOX 环境的完整过程拆开来讲,包括 Python 环境怎么选、PyTorch 怎么装、依赖怎么编译、常见报错怎么定位,以及跑通推理和训练之后的一些实操心得。

整篇内容适合三类人看:第一类是刚接触目标检测、想在 Windows 上跑通 YOLOX 的新手;第二类是在 Linux 上用过 YOLOX、但需要在 Windows 上复现环境的开发者;第三类是负责项目部署、需要把模型落到 Windows 工控机上的工程人员。我会尽量把每一步的“为什么”讲清楚,而不是只丢一堆命令让你复制粘贴,因为环境搭建这件事,理解原理比记住命令重要得多。

2. 环境选型:Python、CUDA、PyTorch 三者怎么配才不打架

2.1 Python 版本不是越新越好

YOLOX 官方代码对 Python 版本是有隐性要求的。我实测下来,Python 3.8 和 3.9 是最稳的两个版本,3.10 也能跑,但部分依赖包在 3.10 上的预编译轮子(wheel)还不全,容易触发源码编译。3.7 及以下就太老了,很多新版本的 PyTorch 已经不支持。

为什么强调这个?因为 Windows 上装包和 Linux 最大的区别在于:Linux 下很多包可以直接从源码编译,系统自带 gcc、make 这些工具;而 Windows 默认没有完整的 C++ 编译环境,一旦某个包没有预编译好的 wheel,pip 就会尝试本地编译,然后大概率报错。所以选一个 wheel 覆盖最全的 Python 版本,能帮你省掉至少一半的麻烦。

我个人的建议是直接用Python 3.8.10,这是 3.8 系列最后一个带完整 Windows 安装包的版本,兼容性经过大量项目验证。安装的时候记得勾选“Add Python to PATH”,否则后面命令行里调python会找不到。

2.2 CUDA 和显卡驱动的关系要先理清

很多人一上来就问“我该装哪个版本的 CUDA”,其实这个问题应该反过来问:你的显卡驱动支持到哪个 CUDA 版本。CUDA 版本和显卡驱动之间是向下兼容的关系,驱动版本决定了你能用的最高 CUDA 版本。

查看方法很简单,在命令行里输入:

nvidia-smi

右上角会显示CUDA Version: xx.x,这个数字是你当前驱动支持的最高 CUDA 版本,不是你已经安装的版本。比如显示 11.7,那你可以装 CUDA 11.0 到 11.7 之间的任意版本。

对于 YOLOX,我推荐CUDA 11.3 配合 cuDNN 8.2,原因是这个组合对应的 PyTorch 版本(1.10 到 1.12)在 Windows 上的 wheel 最完整,而且 YOLOX 官方要求的 PyTorch 版本就在这个区间。如果你显卡比较新,驱动支持 CUDA 12,那也可以装 CUDA 11.8,对应 PyTorch 2.0 以上,但要注意 YOLOX 部分代码在 PyTorch 2.x 上需要小改。

2.3 PyTorch 安装:别用 pip 默认源

这是 Windows 上最容易踩的坑之一。如果你直接pip install torch,默认会从 PyPI 拉取 CPU 版本,装完发现torch.cuda.is_available()返回 False,白忙一场。

正确的做法是去 PyTorch 官网的 Previous Versions 页面,找到对应 CUDA 版本的安装命令。比如 CUDA 11.3 对应的命令是:

pip install torch==1.10.1+cu113 torchvision==0.11.2+cu113 torchaudio==0.10.1+cu113 -f https://download.pytorch.org/whl/cu113/torch_stable.html

注意后面的-f参数,它指定了额外的下载源,这样才能拉到带 CUDA 支持的版本。装完之后一定要验证:

import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))

三行输出分别确认版本号、CUDA 是否可用、显卡型号。如果第二行是 False,别急着往下走,先解决这个问题,否则后面训练会直接退化成 CPU 模式,速度慢到无法接受。

提示:如果你用的是笔记本双显卡(集显+独显),有时候cuda.is_available()会返回 False,这时候去 NVIDIA 控制面板里把 Python 解释器强制指定为独显运行,再重启命令行即可。

3. YOLOX 源码拉取与依赖安装的完整链路

3.1 源码下载与目录结构确认

YOLOX 的代码托管在公开仓库上,直接git clone或者下载 zip 包都行。我建议用 git clone,方便后续切换分支和查看提交记录:

git clone https://github.com/Megvii-BaseDetection/YOLOX.git cd YOLOX

下载完之后先别急着装依赖,花两分钟看一下目录结构。核心目录有这几个:yolox/放的是模型定义和核心逻辑,tools/放的是训练、推理、评估的入口脚本,exps/放的是各种实验配置文件。理解这个结构很重要,因为后面改配置、跑脚本都要跟这几个目录打交道。

3.2 依赖安装的顺序有讲究

YOLOX 的requirements.txt里列了一堆依赖,但如果你直接pip install -r requirements.txt,在 Windows 上大概率会在某个包上卡住。我踩过的坑是pycocotools这个包,它在 Windows 上没有官方预编译的 wheel,pip 会尝试本地编译,然后因为缺少 Visual C++ 编译环境而失败。

正确的安装顺序应该是这样的:

  1. 先装 PyTorch 和 torchvision(前面已经装好了)
  2. 再装cython和numpy,因为后面编译 pycocotools 需要它们
  3. 然后单独处理pycocotools-windows这个替代包
  4. 最后装剩下的依赖

具体命令:

pip install cython numpy pip install pycocotools-windows pip install -r requirements.txt

pycocotools-windows是社区维护的 Windows 适配版本,接口和原版一致,但提供了预编译的 wheel,省去了编译的麻烦。这一步是我认为 Windows 上装 YOLOX 最关键的一个替换操作,很多人卡在这里就是因为不知道有这个包。

3.3 安装 YOLOX 本体和验证

依赖装完之后,还需要把 YOLOX 本身以开发模式安装到环境里:

python setup.py develop

这个命令会把当前目录注册到 Python 的包路径中,这样你在任何地方import yolox都能找到。如果用install而不是develop,后续你改了源码里的东西,还得重新安装一遍,很麻烦。

验证是否装好,可以跑一个最简单的导入测试:

import yolox print(yolox.__version__)

如果没报错,说明基础环境已经通了。接下来可以跑一个官方提供的 demo 脚本,用一张示例图片做推理,确认整个链路没问题。

4. 跑通推理之后,训练环节还有哪些坑在等你

4.1 预训练权重下载与放置位置

YOLOX 官方提供了多个规格的预训练权重,从 nano 到 x 一共六个版本。做推理验证的话,建议先用yolox_s或者yolox_tiny,模型小、下载快、推理速度也快。

权重下载下来之后,要放到项目根目录下,然后在推理命令里通过-c参数指定。这里有个细节:Windows 的路径分隔符是反斜杠,但 YOLOX 的脚本里很多地方用的是正斜杠,混用的时候容易出问题。我的经验是统一用正斜杠,Python 在 Windows 上也能正确识别正斜杠路径,这样能避免很多莫名其妙的“文件找不到”错误。

推理命令示例:

python tools/demo.py image -f exps/default/yolox_s.py -c yolox_s.pth --path assets/dog.jpg --conf 0.25 --nms 0.45 --tsize 640 --save_result --device gpu

参数含义我拆一下:-f指定实验配置文件,-c指定权重,--path是输入图片,--conf是置信度阈值,--nms是 NMS 阈值,--tsize是推理尺寸,--save_result表示保存结果图,--device指定用 GPU 还是 CPU。

4.2 训练自己的数据集:COCO 格式转换是第一步

YOLOX 默认使用 COCO 格式的数据集,如果你手里的是 VOC 格式或者 YOLO 格式的标注,需要先转换。这一步看起来简单,但实际做的时候很容易在类别 ID 和图片路径上出错。

COCO 格式的核心是一个 JSON 文件,里面包含 images、annotations、categories 三个主要字段。images 里记录每张图的文件名和尺寸,annotations 里记录每个标注框的坐标和类别,categories 里记录类别名称和 ID。转换脚本网上有很多,但建议自己写一遍,因为你需要根据自己数据集的实际情况调整字段。

我踩过的一个坑是:图片路径里的中文和空格。Windows 下文件夹命名比较随意,但如果路径里有中文或者空格,YOLOX 在读取的时候可能会报错。解决办法是把数据集放到纯英文、无空格的路径下,比如D:/datasets/mydata/。

4.3 训练参数配置与显存控制

YOLOX 的训练配置在exps/目录下,每个模型规格对应一个文件。你需要改的主要是这几个地方:num_classes改成你的类别数,data_dir指向数据集路径,batch_size根据显存调整。

显存这块我要多说两句。Windows 下 PyTorch 的显存管理不如 Linux 下那么激进,同样的 batch_size,Windows 可能比 Linux 多占 10% 到 20% 的显存。所以如果你在 Linux 上能跑 batch_size=16,Windows 上可能只能跑 12 或者 8。建议从小 batch_size 开始试,跑通了再往上加。

另外,YOLOX 支持多尺度训练和混合精度训练,这两个都能有效降低显存占用。混合精度在 Windows 上需要确认 PyTorch 版本支持torch.cuda.amp,1.10 以上都没问题。

训练启动命令:

python tools/train.py -f exps/example/yolox_voc/yolox_voc_s.py -d 1 -b 8 --fp16 -o -c yolox_s.pth

-d是 GPU 数量,-b是 batch_size,--fp16开启混合精度,-o表示使用在线数据增强,-c是预训练权重。第一次训练建议加上-c,用预训练权重做微调,收敛快很多。

5. 那些让我折腾最久的报错与解决思路

5.1 “No module named ‘yolox’”

这个报错通常出现在你换了目录之后运行脚本。原因是setup.py develop注册的路径是绝对路径,如果你把项目文件夹移动了位置,注册就失效了。解决办法很简单,回到项目根目录重新跑一遍python setup.py develop。

还有一种情况是你用了虚拟环境,但安装的时候没激活环境,装到了全局 Python 里。这时候检查一下pip list里有没有 yolox,没有的话激活环境重装。

5.2 CUDA out of memory 的排查顺序

显存溢出是训练阶段最常见的报错。排查顺序我建议这样:

  1. 先确认是不是 batch_size 太大,直接减半试试
  2. 检查有没有其他程序占着显存,用nvidia-smi看
  3. 确认输入图片尺寸是不是太大,YOLOX 默认 640,如果你改成 1280,显存占用会翻好几倍
  4. 检查是不是开了多尺度训练,这个会动态改变输入尺寸,峰值显存不好预估

如果以上都排除了还是溢出,可以试试在训练脚本里加torch.cuda.empty_cache(),或者把--fp16打开。混合精度能把显存占用降低大约 30%,效果很明显。

5.3 Windows 下 DataLoader 的 num_workers 问题

YOLOX 的 DataLoader 默认会开多个 worker 进程来加速数据读取。在 Linux 下这没问题,但在 Windows 下,多进程的实现方式不同,如果num_workers设置不当,会出现程序卡死或者报BrokenPipeError。

我的经验是:Windows 下 num_workers 不要超过 4,而且最好在训练脚本里显式设置。如果遇到卡死,先把 num_workers 设成 0,用主进程读数据,虽然慢一点但稳定。确认能跑通之后,再逐步往上加。

还有一个相关的坑是:如果你在脚本里用了if __name__ == '__main__':保护,Windows 下多进程才能正常工作。YOLOX 的 train.py 里已经有这个保护了,但如果你自己写了数据预处理的脚本,记得也要加上。

5.4 路径分隔符引发的“玄学”错误

前面提过路径问题,这里再展开说一下。Windows 下路径可以用反斜杠,也可以用正斜杠,Python 的 os.path 模块两种都认。但问题出在配置文件里,如果你在 JSON 或者 YAML 里写了反斜杠,它会被当成转义字符,比如\n会被解析成换行,\t会被解析成制表符。这时候路径就乱了,程序报错说找不到文件,但你看着路径明明是对的。

解决办法就一个:配置文件里一律用正斜杠。不管是 JSON、YAML 还是 Python 字符串,正斜杠在 Windows 下都能正确解析,而且不会有转义问题。

6. 跑通之后的一些实操心得与性能调优

6.1 推理速度的优化空间

在 Windows 上跑 YOLOX 推理,如果直接用 PyTorch 原生接口,速度其实还有不少优化空间。我实测下来,几个有效的优化手段:

  • 开启 TensorRT:如果你显卡是 N 卡,把模型转成 TensorRT 引擎,推理速度能提升 2 到 3 倍。YOLOX 官方提供了转 TensorRT 的脚本,在tools/trt.py里。
  • 调整输入尺寸:640 是精度和速度的平衡点,如果对精度要求不高,降到 416 能快不少。
  • 关闭不必要的后处理:比如你只关心某一类目标,可以在后处理里过滤掉其他类别,减少计算量。

6.2 训练收敛慢怎么办

YOLOX 在自定义数据集上训练,如果收敛慢,先检查这几项:

  • 预训练权重有没有加载成功,看日志里有没有 “Loading model state dict”
  • 学习率是不是太大或太小,YOLOX 默认用的是 cosine 调度,初始学习率跟 batch_size 相关
  • 数据增强是不是太激进,Mosaic 和 MixUp 在小数据集上可能会让模型难以收敛,可以适当降低概率

我自己的经验是,小数据集(几千张图)上,把 Mosaic 概率从 1.0 降到 0.5,收敛会稳定很多。另外,如果类别不平衡严重,可以在损失函数里加类别权重,YOLOX 的配置里支持这个。

6.3 模型导出与部署的注意事项

训练完之后,通常需要把模型导出成 ONNX 格式,方便后续部署。YOLOX 提供了tools/export_onnx.py脚本,但 Windows 下导出 ONNX 有几个注意点:

  • 确认onnx和onnxruntime装好了,版本要匹配
  • 导出的时候指定--opset版本,建议用 11 或以上
  • 如果模型里有动态尺寸,导出的时候要加--dynamic参数

导出的 ONNX 模型可以用 Netron 可视化,检查一下输入输出节点对不对。这一步很重要,因为后面部署到其他框架(比如 OpenVINO、TensorRT)的时候,节点名字和维度必须匹配。

提示:Windows 下用 ONNX Runtime 做推理,记得装 GPU 版本,命令是pip install onnxruntime-gpu,装完确认onnxruntime.get_device()返回 GPU。

7. 关于环境复现的一点个人体会

环境搭建这件事,最怕的就是“在我机器上能跑”。Windows 上的深度学习环境尤其如此,因为显卡驱动、CUDA 版本、Python 版本、依赖包版本,任何一个环节变了,结果可能就不一样。我自己的做法是,每配好一个环境,就用pip freeze > requirements_lock.txt把当前所有包的精确版本导出来,下次换机器直接按这个文件装,能避免 90% 的版本冲突问题。

另外,如果你要在多台 Windows 机器上部署,建议把整个环境打包成 Docker 镜像。虽然 Windows 上的 Docker 对 GPU 的支持不如 Linux 那么成熟,但用 WSL2 后端的话,跑 YOLOX 是没问题的。这样环境一致性有保障,迁移也方便。

最后说一个我踩过的坑:Windows 系统更新有时候会自动更新显卡驱动,更新完之后 CUDA 版本可能就变了,导致 PyTorch 找不到 GPU。遇到这种情况,要么回滚驱动,要么重装对应版本的 CUDA。所以如果你环境跑通了,建议把显卡驱动更新关掉,或者至少别让它自动更新。这个坑我遇到过两次,每次都要花半天重新配环境,后来直接把自动更新禁了,世界就清净了。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进