避免 GPU 资源浪费的核心思路是:让 GPU 始终“有事可做、做对事、不空转”。下面从使用习惯、任务调度、代码优化、资源管理四个层面,给出可落地的建议。
一、使用习惯层面(最容易浪费的地方)
1. 不要“占着 GPU 不干活”
- 常见浪费:
- 启动训练后长时间等待数据
- 调试时一直占用 GPU
- 推理服务长期空闲但 GPU 未释放
- 对策:
- 调试阶段用 CPU 或小 batch
- 使用
CUDA_VISIBLE_DEVICES 精确指定 GPU - 推理服务空闲时自动释放或缩容
2. 避免“GPU 等 CPU”
- 现象:
- GPU 利用率低
- 训练速度慢但 GPU 温度不高
- 原因:
- 数据加载慢
- 预处理在 CPU 串行
- 对策:
- 使用
DataLoader(num_workers > 0) - 预处理尽量 GPU 化(如
torchvision.transforms 的部分操作) - 使用 异步数据加载
二、任务与调度层面
3. 合理分配 GPU 资源
- 避免:
- 一个任务只用 10% GPU 却独占整张卡
- 对策:
- 多进程 / 多任务共享 GPU
- 使用 MPS(Mac / 部分 A 卡)或 MIG(A100)
- 容器化(Docker + CUDA)
✅ 示例:
CUDA_VISIBLE_DEVICES=0,1 python train.py
4. 使用任务队列 / 调度系统
如果是团队或服务器环境:
- 使用:
- Slurm
- Kubernetes + GPU operator
- 内部 GPU 管理平台
- 好处:
- 自动排队
- 防止“抢卡”
- 空闲自动回收
三、代码与模型层面(技术核心)
5. 提高 GPU 利用率
- 检查指标:
nvidia-smi- GPU utilization < 30% → 有问题
- 常见优化:
- 增大 batch size(在显存允许范围内)
- 减少不必要的
.cpu()、.item() - 减少 Python 循环,多用向量化
6. 避免显存浪费
- 常见错误:
- 不必要地保存中间变量
- 推理时仍计算梯度
- 对策:
with torch.no_grad():
output = model(x)
optimizer.zero_grad()
loss.backward()
optimizer.step()
7. 混合精度训练(FP16 / BF16)
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
with autocast():
output = model(x)
loss = criterion(output, y)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
四、推理与服务部署
8. 推理优化
- 使用:
- TensorRT
- ONNX Runtime
- TorchScript
- 批量推理(batching)
- 避免频繁启动 / 销毁模型
9. 推理服务自动缩容
- GPU 空闲 → 自动释放
- 请求到来 → 自动拉起
- 使用:
- Triton Inference Server
- KServe
- Ray Serve
五、监控与治理(防止“看不见的浪费”)
10. 建立 GPU 使用监控
- 工具:
nvidia-sminvtop- Prometheus + Grafana
- 关键指标:
- GPU 利用率
- 显存占用
- 任务运行时间
✅ 建议:
任何 GPU 占用超过 1 小时,都要能解释“它在干什么”
六、一句话总结
避免 GPU 浪费 = 不空跑 + 不独占 + 不低效 + 不失控
如果你愿意,我可以:
- ✅ 帮你诊断当前 GPU 利用率低的原因
- ✅ 给你一份 GPU 使用规范(团队版)
- ✅ 针对 训练 / 推理 / 大模型 给出具体优化方案