【一、无 GPU 环境踩过的血泪坑】
盲目追大尺寸坑:以为 imgsz 越大精度越高,直接设 1280。结果 CPU 扛不住 —— 单张图预处理时间从 0.1 秒涨到 0.8 秒,每个 epoch 要 4 小时(GPU 才 10 分钟!),跑了 3 个 epoch 还因为系统内存炸了(服务器就 16G 内存),训练记录全丢。
过度压缩尺寸坑:为了快,把 imgsz 降到 256。结果原始包裹图是 1024×768,缩到 256 后小包裹(30×30 像素)直接糊成色块,验证集小目标 AP 从 0.5 掉到 0.1,业务完全没法用。
忽略内存占用坑:设 imgsz=640、batch=8,以为 CPU 能扛。训练时用
htop一看,内存占满 16G 还超了,系统直接杀进程。后来才知道,CPU 训练没有 GPU 显存缓冲,数据全堆系统内存,imgsz 和 batch 一涨内存就崩。没开矩形训练坑:图是长方形(1024×768),强行用正方形 imgsz=640,拉伸后包裹变形,检测框全偏到角落。CPU 本来就慢,还因为拉伸多做了无效计算,雪上加霜。
【二、无 GPU 下 imgsz 选择的核心逻辑】
算力限制:imgsz 不能超 416(除非能接受慢)
CPU 算力比 GPU 弱 10-20 倍,而 imgsz 和计算量是平方关系:imgsz 从 320→416,计算量涨 1.7 倍;416→640,计算量涨 2.2 倍。亲测:
imgsz=320:CPU(i7-12700)单 epoch 约 1 小时
imgsz=416:单 epoch 约 1.5 小时
imgsz=640:单 epoch 约 3.5 小时(除非业务必须,否则不推荐)
内存限制:按 “内存 = (imgsz/320)² × 4G × batch” 估算
CPU 训练时,图像数据、特征图全放系统内存,没有 GPU 显存分担。比如服务器 16G 内存,按这个公式算:
batch=2 + imgsz=320:约 4G×2=8G(安全)
batch=2 + imgsz=416:约 (416/320)²×4G×2≈7.2G(安全)
batch=4 + imgsz=416:约 14.4G(接近 16G 上限,容易崩)
所以无 GPU 下 batch 建议设 1-2,imgsz 优先 320/416。
目标尺寸:必须满足 “imgsz ≥ 小目标尺寸 ×10”
CPU 没法像 GPU 那样靠大尺寸补精度,只能靠 “不压缩过头” 保特征。比如我这边小包裹最小 30×30 像素:
若 imgsz=256:30×(256/1024)=7.5 像素(糊了)
若 imgsz=320:30×(320/1024)=9.375 像素(勉强能识别)
若 imgsz=416:30×(416/1024)=12.1875 像素(精度够)
所以小目标最小尺寸 ×10,是 imgsz 的底线。
【三、无 GPU 下 imgsz 选择实操步骤(亲测有效)】
步骤 1:先摸透数据集和服务器底子
- 数据集分析:
用 LabelImg 看目标尺寸:记小目标最小尺寸(我这是 30×30)、原始图尺寸(1024×768)。
算 imgsz 底线:30×10=300,所以 imgsz 至少 320(得是 32 的倍数)。
- 服务器评估:
看内存:
free -h查可用内存(我这 16G,可用 12G)。看 CPU 核心:
lscpu查核心数(16 核,能开多线程加速)。
步骤 2:选初始 imgsz(别纠结,先试 320 或 416)
若小目标多 + 内存≥16G:初始 imgsz=416,batch=2
若内存≤8G + 目标偏大:初始 imgsz=320,batch=1
长方形图必开
--rect:比如我这 1024×768,开 rect 后 imgsz 会自动调成 416×312(接近原比例),省算力还不拉伸。
步骤 3:试训 10 个 epoch,盯三个关键指标
训练速度:单 epoch 超 2 小时就降 imgsz(比如 416→320),业务等不起。
内存占用:用
htop看峰值内存,超可用内存 80% 就降 batch(2→1)或 imgsz。小目标 AP:验证集小目标 AP<0.3,就试着把 imgsz 涨一档(320→416),前提是速度能接受。
我这边试训结果:416+batch=2,单 epoch1.5 小时,内存占 8G,小目标 AP0.52,刚好达标。
步骤 4:确定最终值(别追求完美,够用就好)
别想着 “再涨点 imgsz 提升精度”,CPU 环境下精度提升 1% 可能要多花 1 小时 /epoch,不值。
我最终定的:imgsz=416,batch=2,开 rect,小目标 AP0.52,单 epoch1.5 小时,3 天能训完 100epoch。
【四、无 GPU 下常见问题 Fix(附命令)】
- 内存溢出(OOM)
原因:imgsz 太大或 batch 太高。
解法:先降 batch 到 1,还不行就降 imgsz(416→320)。
命令示例:
yolo train data=package.yaml model=``yolov8n.pt`` imgsz=416 batch=1 --rect
- 训练太慢(单 epoch 超 2 小时)
原因:CPU 算力不够,还开了没必要的功能。
解法:
① 用最轻量模型:YOLOv8n(比 v8s 快 50%);
② 关冗余数据增强:
--augment False(别开马赛克、随机缩放,CPU 扛不住);③ 开 OpenMP 加速:
export OMP_NUM_THREADS=16(用满 CPU 核心)。命令示例:
export OMP_NUM_THREADS=16 && yolo train data=package.yaml model=``yolov8n.pt`` imgsz=416 batch=2 --rect --augment False
- 小目标漏检严重
原因:imgsz 太小,目标特征丢了。
解法:在速度能接受的前提下,把 imgsz 从 320→416,再不行就做数据裁剪(把原始图裁成 416×416,只保留包裹区域,小目标占比变大)。
裁剪工具:用 OpenCV 写个脚本,按标注框位置裁图,5 分钟搞定 1000 张图。
【五、无 GPU 专属小技巧】
预处理提前做:把所有图按最终 imgsz(比如 416×312)提前 resize 好,训练时直接读,省得 CPU 实时预处理(能快 10%)。
别用 float16:CPU 对 float16 支持差,反而比 float32 慢,老老实实设
--half False。断点续训必开:CPU 训练慢,万一崩了能续训(
--resume True),我之前没开,崩了白跑 3 小时。
【总结】
无 GPU 下选 imgsz,核心就是 “低头认怂”—— 别跟 GPU 比精度,先保证能跑起来、跑得完,再谈精度。我这物流场景,416×416+YOLOv8n 就够用,没必要死磕 640。下次再遇到纯 CPU 训练,直接按这个流程来,能省两天踩坑时间。