news 2026/10/18 8:35:29

YOLOv8从零复现:环境配置、自定义训练与推理脚本实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLOv8从零复现:环境配置、自定义训练与推理脚本实践

YOLOv8 这种开源视觉模型,网上复现教程多得快能按斤称了,但真正自己动手从零跑通的,数量其实没有想象中多。最近我刚好把环境搭建、权重推理、自定义数据集训练、测试脚本验证这条路完整走了一遍,全程没有用现成镜像容器,纯手动装包、调参、debug,最终把 yolov8n 和一个小批量自建数据集的模型都跑通了。这篇文章就把整个过程拆成模块来讲,重点不是背参数,而是说清楚每个环节“为什么这么弄”以及“实操时容易在哪里翻车”。不管你手头是 NVIDIA 显卡还是只能用 CPU 调试,照着下面的顺序走一遍,基本都能复现出来。

1. 复现前先弄清的三件事

1.1 复现不等于 pip install ultralytics

很多人一上来就pip install ultralytics,然后发现一个包能装,但模型跑不动、GPU 用不上、各种导入报错。原因很简单:YOLOv8 不是一个孤立的库,它背后挂着一整套与版本强相关的 Python 生态,至少包括 Python 解释器、PyTorch、CUDA、cuDNN、OpenCV、Pillow、NumPy。

其中最容易出问题的就是 PyTorch 的 CUDA 版本。PyTorch 安装包内部其实自带了一部分 CUDA 运行时库,但能否真正调用显卡,还取决于你机器的 NVIDIA 驱动是不是够新。很多时候torch.cuda.is_available()返回 False,不是因为你没装 CUDA,而是因为你装的 PyTorch 版本要求的 CUDA 运行时和你本机的驱动不兼容。

所以复现的第一步,不是急着下载模型,而是先把环境版本的对应关系理顺。这也是我觉得整个流程里最值得花时间的地方。环境一旦对了,后面基本是顺水推舟。

1.2 模型规格怎么选:n、s、m、l、x

YOLOv8 官方提供了一串不同尺寸的预训练模型,文件名后缀区分了模型大小。第一次复现时,强烈建议从yolov8n开始,因为它最小、最快、占显存最少,用来确认环境和流程是最合适的。我把几个常用规格的参数和定位整理了一下,方便你对照选型:

模型参数量(约)典型用途显存需求参考
yolov8n3.2M移动端、边缘设备、快速验证2GB 左右
yolov8s11.2M中等精度需求、边缘计算4GB 左右
yolov8m25.9M服务器端常规任务8GB 左右
yolov8l43.7M高精度检测任务12GB 左右
yolov8x68.2M对精度要求极高的场景16GB 以上

显存需求只是一个粗略参考,实际占用还跟训练图片尺寸、batch size、有没有开启 cache 等有直接关系。推理阶段占用会明显低于训练阶段,2GB 显存跑 yolov8n 推理完全没问题,甚至可以 CPU 跑,只是慢一点。复现阶段先用小模型把链路打通,后面再换大模型,这不会浪费你做的工作。

1.3 版本配套的大致规则

我这次用的环境组合是 Python 3.10 + PyTorch 2.1 + CUDA 12.1 对应的 torch 预编译包。如果你手头是 CUDA 11.8,也可以选 cu118 对应版本。关键规则是:换 CUDA 版本不如换 torch 对应的预编译版本,因为 torch 官方针对不同 CUDA 版本都发布了编译好的 wheel,直接装就能匹配,比自己装 CUDA 再编译简单得多。

Python 版本也是硬约束。老项目用 Python 3.6 或 3.7 可能会碰上某些新版本依赖装不上的问题,新版本库又可能因为 Python 太新而缺少预编译 wheel。实际体验下来,Python 3.9 或 3.10 兼容性最好,踩坑最少。如果你用的不巧是 Python 3.12 或更高,遇到编译报错时别硬刚,退回 3.10 通常能解决。

2. 环境搭建与依赖安装实战

2.1 创建独立的 Python 虚拟环境

复现这种项目,第一件事永远是建虚拟环境,别把依赖直接装进系统环境。身边有朋友图省事,直接在 base 环境里装 ultralytics,结果后来做另一个项目时一pip install就冲突到怀疑人生。用虚拟环境隔离,后面随意折腾都不怕污染其他项目。

我这里用的是 conda,你也可以用 Python 自带的 venv,但 conda 对依赖解析和 Python 版本切换更省心。

conda create -n yolov8 python=3.10 -y conda activate yolov8

激活之后,看到命令提示符前面出现(yolov8)就说明环境切换成功了。这一步是最简单的,但也最容易忽略,尤其是 Windows 上如果在 PowerShell 里没运行 conda 初始化脚本,可能直接卡在找不到 conda 命令。

2.2 安装 PyTorch 和 ultralytics

如果你确定要使用 GPU,建议不要直接pip install torch,因为默认可能装到 CPU 版本,等你训练时才发现用的是 CPU,白白浪费时间。先到 PyTorch 官方安装页面选一个和你的 CUDA 版本匹配的命令,然后手动指定 index-url 安装。

以 CUDA 12.1 为例:

pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121

如果只是 CPU 调试,直接:

pip install torch torchvision

然后安装 ultralytics:

pip install ultralytics

它会自动把 opencv-python、numpy、pillow、matplotlib、pandas 这些常见依赖拉下来。我实际测试时发现,只要网络正常,这套安装非常稳定,基本不会出现缺依赖的问题。

2.3 安装完别急着跑模型,先验证

装完之后,打开 Python 交互式环境,或者写一个临时脚本,确认显卡和包都能正常工作:

import torch print(torch.__version__) print(torch.cuda.is_available()) if torch.cuda.is_available(): print(torch.cuda.get_device_name(0)) else: print("current device: cpu")

如果你前面装的是带 CUDA 的 PyTorch,且驱动也正常,这里torch.cuda.is_available()应该输出 True。如果输出 False,先别往下走,回到第 2.2 节确认一下你是否装对了版本。这一步多花两分钟,能省掉后面大半天的排查时间。

再验证一下 YOLO 能正常初始化:

from ultralytics import YOLO model = YOLO("yolov8n.pt") print(model)

首次运行如果本地没有权重文件,会自动联网下载,下载完会打印模型结构信息。如果你看到一堆网络层结构输出来,那说明 ultralytics 本身已经没问题了。这里有个小细节:权重下载是到当前工作目录,如果你后面换目录运行,它又会再下一次。提前知道这一点,免得以为模型每次都自动下了一遍。

3. 用官方预训练权重把推理跑通

3.1 权重下载卡住怎么办

官方权重默认是从 GitHub Release 下载的。国内网络环境不稳定时,最常见的问题就是权重下载卡在几分钟都不动。解决办法很简单:手动下载对应权重文件放到当前目录,或者放到项目根目录,让程序检测到本地文件后跳过下载。

文件名要严格对照官网的命名,比如yolov8n.pt、yolov8s.pt、yolov8m.pt。注意权重文件不能改名,因为模型加载时会根据文件内容识别架构,而不是只认文件名。如果你下载了某个版本的权重,放到程序能找到的路径下,再运行YOLO("yolov8n.pt")就不会去网络请求了。

还有个细节,别把权重下载放到项目根目录后又在另一台机器上换个路径运行,程序会去和当前路径对比,找不到就需要重新下载。所以项目目录结构最好固定下来。

3.2 一条命令快速验证推理

环境没问题之后,先随便找一张测试图片,比如一张包含猫狗的图,放在工作目录下。然后运行:

yolo predict model=yolov8n.pt source="demo.jpg" conf=0.25 imgsz=640 save=True

conf=0.25表示只保留置信度大于等于 0.25 的检测框,imgsz=640是输入图片缩放尺寸,save=True表示把画好检测框的图片保存下来。运行完后会在runs/detect/predict目录下生成一张标注过的图,包含类名、置信度和边界框。

如果你用的是官方预训练权重,识别的是 COCO 数据集里的 80 类目标,比如人、车、猫、狗、杯子、椅子等。看到图上出现带类别名称的方框,就说明官方推理链路已经跑通了。

3.3 CLI 和 Python 接口怎么对应

命令行模式用起来方便,但实际项目里更多是嵌入到 Python 脚本中,这里把最常用的几个场景对照列出来,方便你切换:

功能CLI 方式Python 方式
检测yolo detect predict ...model.predict(...)
分割yolo segment predict ...YOLO("yolov8n-seg.pt").predict(...)
分类yolo classify predict ...YOLO("yolov8n-cls.pt").predict(...)
训练yolo detect train ...model.train(...)
验证yolo detect val ...model.val()

核心参数在两边的名字是一样的,比如conf、imgsz、device、save。CLI 只是把这些参数变成命令行字符串,底层调用的还是同一套 Python 接口。你自己写脚本时,直接以 Python 接口为准就行。

4. 送出的测试脚本:拿来直接跑

4.1 脚本的设计思路

说好的送测试脚本,这里直接给你一份我在复现过程中整理的版本。它比单纯敲命令行更接近真实使用场景:支持指定图片、文件夹、摄像头,支持把检测结果保存成图片和标签文本,还能打印出每个目标的类别和置信度。脚本里所有参数都用 argparse 接收,方便你不改代码就能换参数。

这个脚本的核心逻辑就是调用model.predict(),让 ultralytics 内部去处理图片预处理、推理、后处理和可视化。你只需要关心传入什么路径、存到哪里、过滤阈值是多少。

4.2 完整的 Python 测试脚本

import argparse from pathlib import Path from ultralytics import YOLO def parse_args(): parser = argparse.ArgumentParser(description="YOLOv8 test runner") parser.add_argument("--weights", type=str, default="yolov8n.pt") parser.add_argument("--source", type=str, default="demo.jpg") parser.add_argument("--conf", type=float, default=0.25) parser.add_argument("--imgsz", type=int, default=640) parser.add_argument("--project", type=str, default="runs/detect") parser.add_argument("--name", type=str, default="test") parser.add_argument("--device", type=str, default="0") parser.add_argument("--save-txt", action="store_true", help="同时保存检测结果的 txt 文件") return parser.parse_args() def main(): args = parse_args() model = YOLO(args.weights) results = model.predict( source=args.source, conf=args.conf, imgsz=args.imgsz, project=args.project, name=args.name, save=True, save_txt=args.save_txt, device=args.device, exist_ok=True, verbose=True, ) for idx, r in enumerate(results): print(f"result {idx}: {r.path}") if r.boxes is not None: for box in r.boxes: cls_id = int(box.cls[0]) conf = float(box.conf[0]) xyxy = [round(float(x), 2) for x in box.xyxy[0]] print(f" category={r.names[cls_id]} conf={conf:.3f} box={xyxy}") if __name__ == "__main__": main()

保存成test_yolov8.py,然后运行:

python test_yolov8.py --source ./images --conf 0.3 --save-txt

如果--source给的是一个文件夹路径,程序会把文件夹下所有图片依次推理完,保存的结果会放在runs/detect/test下。--device默认写的是0,表示使用第一张显卡;如果你只有 CPU,改成--device cpu就行。

4.3 怎么读结果对象

脚本里results是一个列表,数量对应输入源的数量,比如输入一个文件夹里有 10 张图,那结果就有 10 个元素。每个元素都包含检测框、类别、置信度、原始图像路径等信息。

  • r.boxes:检测框对象,包含坐标和置信度
  • box.cls:类别索引,例如 0 代表 data.yaml 里第一个类别
  • box.conf:置信度,0 到 1 之间
  • box.xyxy:检测框左上角和右下角坐标,格式是[x1, y1, x2, y2]
  • r.names:类别索引到类别名的映射字典

如果你处理的是视频或摄像头实时画面,predict方法内部仍会逐帧处理。但对实时视频流更推荐model(source=stream_path, stream=True)这种生成器写法,避免一次性把所有帧结果全部载入内存,细节先不展开,等有需求时再单独说。

5. 训练自己的数据集

5.1 数据集目录怎么摆

推理通了,接下来通常就是训练自己的数据集。这里我不讲从零构造大规模数据的完整工程,只讲最基础、最常用的目录结构。YOLOv8 的训练接口对数据目录的要求很直接,建议用以下方式组织:

dataset/ ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/

images和labels必须在同一个父目录下。图片和标签的文件名保持一致,比如001.jpg对应001.txt,一张图对应一个同名 txt 文件。val 目录不是必须的,但强烈建议准备,因为训练过程要靠它做验证和早期停止。

5.2 标注文件的 YOLO 格式

YOLO 的标签文本格式非常简洁,每行代表一个目标:

class_id x_center y_center width height

注意,坐标是归一化到 0 到 1 之间的值,不是像素值。x_center和y_center是目标框中心点相对图片宽度和高度的比例,width和height是目标框宽高占图片宽高的比例。类别索引从 0 开始,比如你只有猫和狗两类,那猫是 0,狗是 1。

很多新手踩的坑是把坐标写成像素值,或者类别索引从 1 开始,这样训练出来的模型要么完全学不到东西,要么所有检测框都偏掉。格式这个东西没有技巧,就是字段顺序和归一化两个点,写完后自己写个小脚本确认一下数值范围是否都在 0 到 1 之间,能省很多事。

如果你想自己标注数据,可以用开源标注工具,导出 YOLO 格式时会自动生成同名 txt 文件。拿到 txt 后不要急着训练,先随机抽几张图,打印对应的标注内容,人工对照一下,确保标签和图像内容真的匹配。

5.3 编写 data.yaml 配置

YOLOv8 训练时通过一个 YAML 文件告诉模型数据集在哪、有哪些类别。我这里给一个最典型的写法:

path: ./dataset train: images/train val: images/val nc: 2 names: 0: cat 1: dog

path是数据集根目录,最好用绝对路径或相对于当前工作目录的清晰相对路径。train和val是相对这个根目录的图片目录路径。nc是类别数量,names是类别索引到名称的映射。注意names的顺序必须和标注文件里的类别索引一致,否则训练出来的模型类别会错乱,检测结果的含义也会完全对不上。

5.4 训练命令与关键参数

训练的核心命令很简单:

yolo detect train data=dataset/data.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=16 device=0

这里model=yolov8n.pt很关键,它表示在官方预训练权重基础上继续微调,也就是迁移学习。对于自制小数据集来说,用预训练权重比随机初始化收敛更快,精度也更高。如果你想从零训练,也可以只给模型架构文件yolov8n.yaml,但实际应用里大多数人不会这么做。

几个参数的选取逻辑说一下:

  • epochs:训练轮数。小数据集 100 轮起步,如果验证集 loss 还在持续下降,可以加大到 200。
  • batch:批大小。这个值受限于显存,显存不够就减小。比如 8GB 显存跑 yolov8n 训练,batch 16 通常没问题,但如果同时开cache=True把图片全部预加载进显存,就可能显存爆掉。
  • imgsz:输入图片尺寸。官方默认 640,显存小可以降到 416 甚至 320,但精度会有所下降。
  • device:指定训练设备,0是首张 GPU,cpu是 CPU。

训练过程中会看到 mAP50、mAP50-95、loss 等指标随轮次变化。不用太在意每个 epoch 的震荡,重点看整体趋势。训练结束后,最优权重保存在runs/detect/train/weights/best.pt,最后一个 epoch 的权重在last.pt,一般直接使用best.pt。

5.5 训练完怎么验证模型效果

训练结束后,不要直接用best.pt去猜效果,先用验证集跑一遍指标:

yolo detect val model=runs/detect/train/weights/best.pt data=dataset/data.yaml

它会输出 mAP50、mAP50-95 等数值。mAP50 是 IoU 阈值大于等于 0.5 时的平均精度,mAP50-95 是在多个 IoU 阈值下的平均值,后者更严格也更接近真实难度。对一个类别很少的小数据集来说,mAP50 能到 0.9 以上通常已经相当好了。

如果你更习惯用脚本评估:

from ultralytics import YOLO model = YOLO("runs/detect/train/weights/best.pt") metrics = model.val(data="dataset/data.yaml") print(metrics.box.map50, metrics.box.map)

最后再用第 4 节那个测试脚本,把--weights换成best.pt路径,跑几张没参与过训练的图片看看,确认实际检测框位置和类别标签是否符合预期。这一步能直观反映模型在真实环境里的表现。

6. 复现过程中最常见的问题与排查

6.1 环境层面的高发问题

复现过程中,环境相关的报错是出现频率最高的。我把几类常见信息整理成一个速查表,遇到可以直接对照:

报错关键信息常见原因解决思路
torch.cuda.is_available()返回 FalsePyTorch 与驱动不匹配重装对应 CUDA 版本的 PyTorch,或升级驱动
AttributeError: module 'PIL.Image' has no attribute 'Resampling'Pillow 版本过旧pip install -U pillow升级 Pillow
ImportError: libGL.so.1OpenCV 缺少系统图形库安装 opencv-python-headless,或在系统层补齐图形库
OMP: Error #15OpenMP 重复加载检查有没有在多个环境里混用库,必要时设置相关线程环境变量
CUDA out of memorybatch 或 imgsz 太大减小 batch、imgsz,关闭 cache
No labels found in ...标签目录路径或格式错误检查 data.yaml 路径,确认存在同名 txt 文件

环境类问题最忌讳的就是反复重装,越急越容易把环境搞得乱七八糟。我的建议是报错先看前三行,如果是依赖缺失,直接补对应依赖;如果是 CUDA 相关问题,先单独写个脚本测试torch.cuda.is_available(),再决定要不要重装。

6.2 数据准备阶段的典型错误

数据阶段最常见的错误有几种。第一种是标签文件和图片文件名不一致。YOLOv8 是按文件名前缀匹配图片和标签的,比如001.jpg必须对应001.txt。如果你从别的数据集转换过来,文件名规则对不上,就会疯狂报“No labels found”。

第二种是类别索引错位。训练数据里标注的是0 cat、1 dog,但 data.yaml 里names写反了,模型训练时会把猫和狗的标签互相混淆,导致最终检测结果完全错误。这种错误在指标上往往不明显,因为整体 mAP 可能看起来不低,但实际语义完全乱了。

第三种是标签数据没有归一化。YOLO 格式要求坐标都归一化到 0 到 1,如果写成像素坐标,训练会非常不稳定,甚至出现 loss 为 NaN。建议拿到任何数据集后,先写一段几行的脚本统计一下所有标签文本的数值范围,如果超出 0 到 1,就要先处理数据再训练。

6.3 几条避坑经验总结

这部分是我自己跑完几轮实验之后的体会。

第一个经验,不要一上来就用大模型和全量数据。先用 yolov8n 加几十张图,把整个训练流程跑通,确认数据格式和代码链路都没问题,再上大模型和大数据量。这样即便出错,每次迭代周期也只有几分钟,而不是几小时。

第二个经验,每次实验单独建目录。我习惯在runs/detect下给不同实验起不同 name,比如train_baseline、train_aug,这样权重和日志都隔离,不会因为覆盖而丢失历史结果。对比实验时也能快速找到哪一份权重是哪个配置训出来的。

第三个经验,善用exist_ok=True。如果是自己写脚本调用 train 或 predict,加这个参数可以让程序重复写同一目录时直接覆盖,而不是每次创建新的序号目录。我在自动化跑批量测试时经常因为忘加这个参数,结果生成一堆无意义的目录。

第四个经验,CPU 也能跑,但要接受速度差距。如果实在没有 GPU,训练时把imgsz降到 320、batch设为 4 或 8,还是能跑通的,只是时间慢很多。推理阶段 CPU 也不至于完全不可用,拿几张小图测一批效果完全没问题。

说真的,YOLOv8 复现的难点不在模型本身,而在环境版本匹配和数据格式对齐。跑通一个最小 demo 之后,再一句一句改自己的脚本,改一步跑一步,别一口气照着别人的完整工程全量粘贴。把我上面这个测试脚本和训练流程搭起来,你就能从“会跑官方权重”顺利过渡到“训练自己的数据集”。后面再想扩展模型量化、导出 ONNX、接入摄像头实时检测,都可以在这个基础上慢慢加。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 8:32:09

乐天API获取商品详情:从申请到批量同步的完整指南

之前做过一个跨境商品选品模块,需要把日本站点的商品名称、价格、评分、店铺信息同步到本地库做比价分析。一开始图快,直接抓详情页,结果动态加载、JS渲染、验证码轮番上阵,没跑两天IP就被限制,解析规则也跟着页面改版…

作者头像 李华
网站建设 2026/10/18 8:28:06

深入浅出BACnet模拟器:楼宇自控联调与设备仿真完全指南

简介:这是一份BACnet楼宇自动控制网络通信协议的模拟器及相关源码整合包,面向从事建筑自动化系统集成、设备调试与协议学习的工程师和技术人员。压缩包内共含1650个文件,以Python脚本为主(1072个py),并包含…

作者头像 李华
网站建设 2026/10/18 8:27:05

YOLO训练提速4倍:从GPU利用率到数据管线与混合精度调优

如果你盯着YOLO训练进度条,一小时只跳了十来个epoch,第一反应多半是“这张卡不行”。我之前也这么想过,甚至在购物车里躺着一块新显卡。直到某天我把GPU利用率调出来看了一眼,才发现整个训练流程的瓶颈根本不在算力:显…

作者头像 李华
网站建设 2026/10/18 8:26:10

Geany JSON格式化插件:轻量C实现的实时美化、压缩与校验

简介:这是一款专为Geany轻量级IDE开发的JSON处理插件,面向Linux平台下的C/C开发者、前端工程师及API调试人员,解决JSON数据在开发过程中格式混乱、验证困难、手动美化效率低等实际问题。资源包共176个文件,含59个JSON示例与测试用…

作者头像 李华
网站建设 2026/10/18 8:25:40

可重构智能表面辅助多用户MIMO:无源波束成形与信道估计实战解析

简介:面向计算机、电子信息工程与数学专业大学生的MATLAB项目资源,聚焦可重构智能表面(RIS)辅助多用户MIMO系统中的无源波束成形与信息传输设计。采用参数化编程,注释详尽、参数可灵活修改,且附带可直接运行…

作者头像 李华
网站建设 2026/10/18 8:25:08

拿了奥数满分的 AI,为什么偏偏是个“生活小白”?

洗车店就在 50 米外,我该走路去,还是开车去? 你一秒就能给出答案:车都没开去,洗个寂寞吗? 可就在今年 2 月,有人拿这道“送分题”测了 53 个 AI 模型,结果惊掉下巴——有 42 个 AI 一…

作者头像 李华