1. 项目概述与核心价值
最近在项目里又用到了YOLOv5,虽然现在YOLOv8、YOLOv9甚至YOLOv10都出来了,但不得不说,YOLOv5依然是很多团队和个人开发者的首选。它就像一个“六边形战士”,在速度、精度、易用性和社区生态上取得了非常好的平衡。很多刚接触目标检测的朋友,或者需要在工业场景快速落地的工程师,第一个想到的往往还是它。今天这篇内容,我就从一个老手的视角,带大家走一遍YOLOv5从零开始的下载与部署流程。这不仅仅是“照着文档敲命令”,我会把每一步背后的逻辑、可能遇到的坑,以及如何根据你的实际需求做选择,都掰开揉碎了讲清楚。无论你是想跑通一个Demo验证想法,还是要为后续的模型训练和工程化集成打基础,这套流程都是你必须掌握的“第一课”。
2. 环境准备:打造稳固的基石
部署模型的第一步,永远是把环境搭建好。一个干净、版本匹配的环境能避免90%后续的玄学问题。YOLOv5对环境的兼容性已经做得相当不错了,但为了追求最佳的稳定性和性能,我依然推荐大家遵循官方的推荐配置。
2.1 核心依赖解析与安装
YOLOv5的核心是PyTorch深度学习框架。你首先需要安装PyTorch。这里有个关键点:不要直接pip install torch。PyTorch的安装需要根据你的操作系统、是否使用GPU(CUDA版本)来选择合适的命令。去PyTorch官网(https://pytorch.org/get-started/locally/)看看,那里有一个非常直观的命令生成器。
假设你用的是Linux系统,有一张NVIDIA显卡,并且安装了CUDA 11.8,那么安装命令大概是这样的:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118如果你没有GPU,或者只是想先快速体验一下,可以安装CPU版本:
pip install torch torchvision torchaudio安装完PyTorch后,再安装YOLOv5所需的其他依赖就简单了。最规范的做法是克隆YOLOv5的官方仓库,然后用它的requirements.txt文件来安装。这能确保所有库的版本都是经过验证、彼此兼容的。
git clone https://github.com/ultralytics/yolov5 # 克隆仓库 cd yolov5 pip install -r requirements.txt # 安装所有依赖这个requirements.txt里包含了opencv-python(用于图像处理)、matplotlib(画图)、pandas(数据处理)等几十个库。用这种方式安装,比你一个个手动pip install要省心得多,也安全得多。
注意:我强烈建议使用Python虚拟环境(如
venv或conda)来做这件事。这能把你这个项目的依赖和系统其他Python环境完全隔离开。想象一下,你系统里原来有个老项目用的是TensorFlow 1.x,而YOLOv5需要一些新版本的库,两者冲突会导致各种难以排查的错误。用虚拟环境就一劳永逸地解决了这个问题。创建和激活虚拟环境的命令很简单:python -m venv yolov5_env # 创建名为yolov5_env的虚拟环境 source yolov5_env/bin/activate # Linux/Mac激活 # 或者 yolov5_env\Scripts\activate # Windows激活激活后,你的命令行提示符前面通常会显示环境名,之后所有
pip install操作都只影响这个环境。
2.2 验证环境与常见问题
安装完成后,怎么知道环境没问题呢?一个简单的验证方法是进入Python交互界面,尝试导入关键库:
import torch import cv2 print(torch.__version__) print(torch.cuda.is_available()) # 如果返回True,说明GPU可用如果这些导入都没报错,并且torch.cuda.is_available()返回了True(对于GPU用户),那么基础环境就算搭建好了。
在这个过程中,你可能会遇到几个典型问题:
- 网络超时或下载慢:这是因为
pip默认的源在国外。解决方法是指定国内的镜像源加速,例如使用清华源:pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple - 版本冲突:某个库的版本与PyTorch或其他库不兼容。如果使用
requirements.txt安装后仍报错,可以尝试单独升级或降级出问题的包。查看错误信息,通常它会提示你哪个包需要什么版本。 - CUDA与PyTorch版本不匹配:这是GPU用户最常踩的坑。表现为
torch.cuda.is_available()返回False。请务必核对你的显卡驱动支持的CUDA最高版本,然后安装对应版本的PyTorch。你可以通过nvidia-smi命令查看驱动版本,然后去NVIDIA官网查该驱动支持的CUDA版本。
3. 模型获取:选择合适的“武器”
环境好了,接下来就是获取模型。YOLOv5提供了多种预训练模型,我们称之为“模型家族”,从轻量到重型,满足不同场景。
3.1 官方模型家族详解
YOLOv5的官方模型通常按照模型大小和复杂度命名,主要有以下几种(以v6.1版本为例):
- YOLOv5n(nano): 最轻量级,速度极快,精度最低。适合移动端或边缘设备(如Jetson Nano),或者对实时性要求极高的场景。
- YOLOv5s(small): 小型模型,在速度和精度间取得了很好的平衡。这是我最推荐初学者和大多数应用场景首先尝试的模型,它足够快,精度也还不错。
- YOLOv5m(medium): 中型模型,精度比
s有明显提升,速度稍慢。适合对精度有一定要求,且算力不是首要瓶颈的场景。 - YOLOv5l(large): 大型模型,精度更高。
- YOLOv5x(extra large): 超大型模型,精度最高,速度最慢。通常用于学术研究刷榜,或者在不计成本追求极致精度的场合。
如何选择?记住一个核心原则:没有最好的模型,只有最适合的模型。如果你的应用是视频监控,需要处理30帧的视频流,那n或s可能是唯一选择。如果你是在处理医学图像,每一个漏检的代价都很大,那么即使慢一点,也要优先考虑l或x。对于大多数验证性任务和入门学习,从YOLOv5s开始绝对没错。
3.2 模型下载的两种方式与原理
获取这些模型有两种主要方式,它们背后的逻辑不同:
方式一:通过代码自动下载(推荐)这是最常用、最方便的方式。当你第一次运行YOLOv5的检测脚本时,它会自动检查并下载你指定的模型。例如,运行检测命令时,--weights yolov5s.pt参数中的yolov5s.pt如果不存在于本地,程序会自动从Ultralytics的官方发布页面(通常是GitHub Release)下载。这种方式的好处是省心,版本肯定是对的。它的原理是代码里写好了模型的URL,通过torch.hub.load或类似的机制去获取。
方式二:手动下载在某些无法直接访问外网的环境(如某些企业内网、离线服务器),你需要手动下载模型文件。你需要访问YOLOv5的GitHub仓库,找到Releases页面,在对应的版本(比如v6.1)的Assets中,找到yolov5s.pt、yolov5m.pt等文件,手动下载到本地。然后,在运行命令时,将--weights参数指向你本地文件的路径即可,例如--weights ./downloads/yolov5s.pt。
实操心得:对于国内用户,自动下载有时会因为网络问题失败或极慢。我的习惯是,在能顺畅访问外网的环境(比如自己的开发机)上,先让程序自动下载一次,把
.pt模型文件缓存下来。然后把这个文件拷贝到内网或生产环境中使用。模型文件的位置通常在~/.cache/torch/hub/目录下(Linux/Mac)或C:\Users\<用户名>\.cache\torch\hub\(Windows)的对应子目录中。找到它,备份它,这是一个好习惯。
4. 快速部署与首次推理
模型到手,环境就绪,是时候让它“动起来”了。我们将进行第一次图片推理,这是验证整个流程是否畅通的关键一步。
4.1 使用官方脚本进行图片检测
YOLOv5仓库根目录下的detect.py脚本是进行推理的入口。它的设计非常简洁,只需要指定模型权重、输入源和输出目录即可。一个最基础的命令如下:
python detect.py --weights yolov5s.pt --source data/images/bus.jpg --project runs/detect --name exp让我们拆解这个命令:
--weights yolov5s.pt: 指定使用的模型权重。这里会触发我们上面说的自动下载(如果本地没有)。--source data/images/bus.jpg: 指定输入源。它可以是单张图片(如.jpg, .png)、一个包含多张图片的文件夹、一个视频文件(.mp4, .avi)、甚至是一个RTSP流地址(如rtsp://...)或摄像头索引(如0表示第一个摄像头)。YOLOv5仓库自带了几张示例图片在data/images/目录下,bus.jpg就是其中之一。--project runs/detect: 指定所有推理实验结果的父目录。--name exp: 指定本次实验的子目录名。输出结果会保存在runs/detect/exp/这个路径下。
执行这个命令后,你会看到终端开始打印信息。首先会加载模型,然后显示模型的结构(一层层的卷积、SPPF、Detect头等),接着开始处理图片。处理完成后,它会告诉你结果保存的路径,例如:
Results saved to runs/detect/exp 1 image processed, 0.023s pre-process, 0.004s inference, 0.001s NMS per image at shape (1, 3, 640, 640)打开runs/detect/exp文件夹,你就能看到处理后的图片bus.jpg,图片上应该已经画出了检测到的行人、汽车等物体的边界框、类别标签和置信度。
4.2 关键参数解析与调优
第一次跑通固然令人兴奋,但detect.py的强大之处在于它丰富的参数,可以让你精细控制推理过程。了解这些参数,你才能用活这个工具。
--img-size或--imgsz: 输入图片的尺寸。默认是640。模型会将输入图片缩放到这个尺寸进行处理。这是一个非常重要的参数。增大尺寸(如1280)通常会提升检测小物体的精度,但会显著增加计算量和内存占用,降低速度。减小尺寸则相反。你需要根据你的硬件条件和任务需求(是更看重速度还是精度)来权衡。通常,保持640是一个不错的起点。--conf-thres: 置信度阈值。默认0.25。模型会输出很多预测框,每个框有一个置信度分数,表示模型有多确信这个框里有所说的物体。低于这个阈值的预测框会被直接过滤掉。调高这个值(如0.5)可以让结果更“干净”,只留下把握很大的检测框,但可能会漏掉一些模糊的物体。调低则可能看到更多结果,但杂讯(假阳性)也会变多。--iou-thres: 非极大值抑制(NMS)的IoU阈值。默认0.45。当多个预测框指向同一个物体时,NMS会保留置信度最高的那个,并抑制掉与其重叠度(IoU)过高的其他框。这个阈值决定了“多高算过高”。调低它(如0.3)会让NMS更严格,同一个物体最终只留下一个框,但若物体密集可能会误杀;调高它则可能让一个物体留下多个框。--max-det: 每张图片最大检测数量。默认300。防止一张图片里出现成百上千个无意义的检测框。--device: 指定运行设备。默认是空,程序会自动选择。你可以指定--device 0使用第一块GPU,--device cpu强制使用CPU。在服务器上有多卡时,这个参数很有用。--view-img: 一个布尔标志。加上这个参数,会在推理时弹出一个窗口实时显示检测结果。在调试和演示时非常直观。--save-txt: 保存检测结果为YOLO格式的txt文件。每个txt文件对应一张图片,里面记录了每个检测框的类别、中心点坐标、宽高(都是归一化后的值)。这个功能对于后续生成数据集标签、或者与其他系统集成至关重要。
一个更复杂的、调优后的命令可能长这样:
python detect.py --weights yolov5m.pt --source ./my_video.mp4 --img-size 1280 --conf-thres 0.4 --iou-thres 0.5 --device 0 --view-img --save-txt这个命令意味着:使用精度更高的yolov5m模型,处理我自己的视频my_video.mp4,以更高的分辨率1280进行推理,只相信置信度高于0.4的预测,使用更宽松的NMS(0.5)来处理可能重叠的物体,指定使用第一块GPU,实时显示画面,并保存检测框的坐标数据。
5. 深入部署:超越基础脚本
当你熟练使用detect.py后,可能会遇到一些更复杂的需求,比如将YOLOv5集成到自己的Python项目中,或者需要更高的推理性能。这时就需要更深入的部署方式。
5.1 使用PyTorch Hub极简调用
PyTorch Hub是PyTorch提供的一个模型仓库和加载工具。YOLOv5也支持这种方式,它能让你的代码变得异常简洁。在你的Python脚本中,只需要几行:
import torch # 从PyTorch Hub加载模型 model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True) # 设置模型为评估模式(这对推理是必须的) model.eval() # 进行推理 img = 'https://ultralytics.com/images/zidane.jpg' # 可以是图片路径、URL、PIL图像、OpenCV图像等 results = model(img) # 查看结果 results.print() # 打印检测到的物体信息 results.show() # 显示带标注的图片 results.save() # 保存图片到当前目录这种方式本质上和运行detect.py脚本是一样的,但它给了你更大的灵活性。results对象包含了丰富的属性,比如results.pandas().xyxy[0]可以返回一个Pandas DataFrame,里面是检测框的坐标、置信度和类别,方便你进行后续的数据处理和分析。
5.2 模型导出与优化推理
在生产环境中,我们很少直接使用原始的PyTorch模型(.pt文件)。为了追求极致的推理速度和跨平台部署能力,我们需要将模型“导出”成更高效的格式。
1. 导出为TorchScriptTorchScript是PyTorch模型的一种中间表示,它可以被脱离Python环境运行,例如在C++中调用。使用YOLOv5自带的export.py脚本可以轻松导出:
python export.py --weights yolov5s.pt --include torchscript执行后,你会得到一个yolov5s.torchscript.pt文件。这个文件可以在C++中使用LibTorch库进行加载和推理,这对于嵌入式设备或对Python依赖有洁癖的服务端部署非常有用。
2. 导出为ONNXONNX是一种开放的模型交换格式,得到了众多推理引擎的支持,如TensorRT, OpenVINO, ONNX Runtime等。导出ONNX同样简单:
python export.py --weights yolov5s.pt --include onnx得到yolov5s.onnx文件后,你就可以使用ONNX Runtime进行推理了。下面是一个简单的ONNX Runtime推理示例:
import onnxruntime import cv2 import numpy as np # 加载ONNX模型和创建会话 ort_session = onnxruntime.InferenceSession('yolov5s.onnx') # 准备输入数据(需要预处理:BGR->RGB, HWC->CHW, 归一化,增加批次维度) img = cv2.imread('bus.jpg') img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_resized = cv2.resize(img_rgb, (640, 640)) input_data = img_resized.transpose(2, 0, 1).astype(np.float32) / 255.0 input_data = np.expand_dims(input_data, axis=0) # 变成 [1, 3, 640, 640] # 运行推理 ort_inputs = {ort_session.get_inputs()[0].name: input_data} ort_outs = ort_session.run(None, ort_inputs) # ort_outs 包含了输出,后续需要做后处理(如NMS)来解析出检测框3. 导出为TensorRT或OpenVINO(性能飞跃)如果你有NVIDIA显卡,强烈建议导出为TensorRT引擎。TensorRT会对模型进行层融合、精度校准(FP16/INT8)、内核自动调优等深度优化,通常能带来数倍甚至十数倍的推理速度提升。YOLOv5的export.py也支持直接导出为TensorRT:
python export.py --weights yolov5s.pt --include engine --device 0类似地,对于Intel的CPU或集成显卡,可以导出为OpenVINO的IR格式,也能获得显著的加速效果。
注意事项:导出模型不是一劳永逸的。导出的模型只包含了前向推理的计算图,预处理(缩放、归一化)和后处理(NMS)通常需要你自己实现。YOLOv5的导出脚本会尝试将一些简单的预处理(如
/255)打包进模型,但复杂的后处理一般不包括。所以,当你使用导出的模型时,需要参考原始仓库中的代码,确保你的前处理和后处理与训练时保持一致,否则结果会完全不对。
6. 实战问题排查与性能调优指南
在实际部署中,你几乎一定会遇到各种问题。下面我整理了一份从新手到进阶常遇到的“坑”及其解决方案。
6.1 常见错误与解决方案速查表
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
ImportError: No module named ‘xxx‘ | 依赖库未安装或版本不对。 | 1. 检查是否在正确的虚拟环境中。 2. 运行 pip install -r requirements.txt重新安装。3. 根据错误信息单独安装缺失的包。 |
torch.cuda.is_available()返回False | 1. PyTorch版本与CUDA版本不匹配。 2. 显卡驱动太旧。 3. 系统未安装CUDA工具包。 | 1. 使用nvidia-smi查看驱动支持的CUDA最高版本,安装对应PyTorch。2. 更新显卡驱动。 3. 从NVIDIA官网下载并安装CUDA Toolkit。 |
| 推理速度非常慢 | 1. 模型在CPU上运行。 2. 使用了过大的模型(如YOLOv5x)。 3. 输入图片尺寸 ( --img-size) 设置过大。 | 1. 确保--device 0或检查CUDA是否可用。2. 换用更小的模型(如YOLOv5s)。 3. 尝试减小 --img-size(如从1280降到640)。 |
| 检测结果框太多/太杂乱 | 置信度阈值 (--conf-thres) 设置过低。 | 逐步调高--conf-thres,如从0.25调到0.5或更高,直到结果满意。 |
| 同一个物体被重复检测多个框 | NMS的IoU阈值 (--iou-thres) 设置过高。 | 逐步调低--iou-thres,如从0.45调到0.3或更低。 |
| 检测不到小物体 | 1. 模型本身能力有限。 2. 输入图片尺寸太小,小物体特征丢失。 | 1. 换用更大的模型(如YOLOv5l)。 2. 增大 --img-size(如从640增到1280)。3. 考虑使用专门针对小物体改进的模型或方法。 |
| 自动下载模型失败/极慢 | 网络连接问题。 | 1. 手动下载模型文件,用--weights指定本地路径。2. 配置网络代理。 |
| 内存不足 (OOM) | 1. 图片尺寸太大或批次太大。 2. 模型太大。 3. GPU显存太小。 | 1. 减小--img-size。2. 换用小模型。 3. 尝试在CPU上运行 ( --device cpu)。 |
6.2 性能调优实战心得
除了解决错误,让模型跑得更快、更稳才是部署的终极目标。这里分享几个压箱底的调优经验:
1. 图片尺寸是性能杠杆--img-size是影响速度和精度最直接的参数。它的值必须是32的倍数,因为YOLOv5网络中有5次下采样(2^5=32)。一个黄金法则是:在满足精度的前提下,使用尽可能小的尺寸。你可以做一个简单的实验:用同一段视频,分别用--img-size 320和--img-size 640去检测,对比FPS和检测效果。你会发现,尺寸减半,速度可能提升3-4倍,但小物体的检测能力会下降。这个权衡需要你自己根据业务指标来定。
2. 批处理 (Batch Inference) 加速detect.py脚本默认是一次处理一张图片。但在处理大量图片或视频流时,批处理可以极大提升GPU利用率。虽然detect.py没有直接提供批处理图片文件夹的显式参数,但它的--source参数支持传入一个图片目录,程序内部会以批次的形式进行处理。你可以通过修改源码中的detect.py,找到创建DataLoader的部分,调整batch_size参数来改变批次大小。增大batch_size能提升吞吐量,但也会增加延迟和内存消耗,对于实时视频流,batch_size=1通常是延迟最低的选择。
3. 使用TensorRT进行终极加速如果你部署在NVIDIA GPU上,并且对性能有极致要求,那么TensorRT是必经之路。过程大致是:PyTorch -> ONNX -> TensorRT。YOLOv5的export.py提供了--include engine选项,可以一键完成转换(内部先转ONNX,再转TensorRT)。转换时,你可以指定精度为FP16甚至INT8。FP16精度几乎无损,速度提升明显;INT8量化需要校准数据集,精度可能有轻微损失,但速度最快,内存占用最小。转换后的.engine文件,推理速度相比原始PyTorch模型常有数倍提升。
4. 预处理与后处理优化推理过程不仅仅是模型前向传播。图片解码、缩放、归一化(预处理),以及解析输出、做NMS(后处理)也占了相当一部分时间。对于高并发场景,可以考虑:
- 使用GPU加速的图片解码和预处理,如NVIDIA的DALI库。
- 将后处理(尤其是NMS)也放到GPU上执行。YOLOv5的PyTorch模型输出后,其NMS是在CPU上进行的。可以寻找或自己实现CUDA版本的NMS内核,与模型推理在同一个GPU流中完成,减少数据在CPU和GPU间的传输。
部署YOLOv5模型,从下载到跑通Demo可能只需要10分钟,但要想把它打磨成一个在生产环境中稳定、高效运行的组件,需要对这些细节有深入的理解和不断的调试。希望这篇超过5000字的详细拆解,能帮你打下扎实的基础,避开我当年踩过的那些坑。记住,动手试一遍,远比看十遍文章要有效。