在深度学习训练过程中,GPU 是否被有效利用,往往比模型结构本身更早成为性能瓶颈。本文将从最基础的 nvidia-smi 使用方式开始,逐步演进到带时间戳、不清屏、可记录日志的工程级 GPU 监控方案,非常适合 PyTorch + Docker/容器训练场景。
一、为什么要“持续”监控 GPU?
很多初学者只在训练开始时敲一次:nvidia-smi,但在真实工程中,这远远不够:
-
GPU 利用率是否长期 < 50%?
-
显存是否在逐步泄漏?
-
训练过程中是否存在周期性空转(DataLoader 瓶颈)?
-
容器里看到的 GPU 是否和宿主机一致?
这些问题,只有持续监控才能发现。
二、最基础:定时刷新 nvidia-smi

2.1 使用 watch(清屏刷新)
watch -n 2 nvidia-smi
每 2 秒刷新一次,适合人眼盯着看。
- 缺点:无法保存历史记录
2.2 使用 nvidia-smi -l(不清屏)
nvidia-smi -l 1
每 1 秒输出一屏,不清屏,持续向下追加
- 没有时间戳
nvidia-smi -l更适合临时查看,但由于缺乏时间戳,不适合性能分析和问题回溯。
三、只看关键指标(工程中更常用)
完整的 nvidia-smi 输出信息太多,在训练过程中,指标越多,反而越难快速判断瓶颈。
训练时我们通常只关心:GPU 利用率和显存使用量。
nvidia-smi \
--query-gpu=index,name,utilization.gpu,memory.used,memory.total \
--format=csv
如果你只想看 第 0 块 GPU:
nvidia-smi -i 0 \
--query-gpu=index,name,utilization.gpu,memory.used,memory.total \
--format=csv
输出:
index, name, utilization.gpu [%], memory.used [MiB], memory.total [MiB] 0, NVIDIA A40, 43 %, 5525 MiB, 46068 MiB
四、工程级方案:不清屏 + 时间戳 + 字段名
- 参考脚本:
while true; do
ts=$(date '+%Y-%m-%d %H:%M:%S')
read util mem_used mem_total <<< $(
nvidia-smi -i 0 \
--query-gpu=utilization.gpu,memory.used,memory.total \
--format=csv,noheader,nounits
)
echo "[$ts] GPU0 util=${util}% mem=${mem_used}/${mem_total} MiB"
sleep 1
done
- 输出示例:
[2026-01-08 01:51:15] GPU0 util=66% mem=5607/46068 MiB
[2026-01-08 01:51:16] GPU0 util=68% mem=5607/46068 MiB
-
特点:
✅ 不清屏
✅ 可读性强
✅ 可直接重定向为日志文件
-
这类输出既适合人眼观察,也适合后期日志分析,是工程中最常用的 GPU 监控形式。
五、容器环境下的一个重要提醒
在 Docker / Kubernetes 中:
nvidia-smi -i 0
指的是:容器可见的第 0 块 GPU,不一定是宿主机的 GPU 0
例如:
docker run --gpus '"device=1"' ...
那么在容器内,对于nvidia-smi -i 0实际对应的是 宿主机 GPU 1,这一点在多卡服务器上极其容易误判。
六、如何用这些信息判断训练是否健康?
经验判断标准(非常实用):
| 现象 | 可能问题 |
|---|---|
| GPU 利用率长期 < 50% | DataLoader 太慢 |
| 利用率周期性掉 0 | I/O 或 CPU 预处理瓶颈 |
| 显存持续增长 | 内存泄漏 / tensor 未释放 |
| 显存远小于可用 | batch size 过小 |
七、小结
nvidia-smi本身只是工具- 真正有价值的是:时间 +上下文 + 可持续记录
- 一个简单的 shell 循环,就能把 GPU 监控提升到工程级
- 如果你无法解释 GPU 在“某一秒”在做什么, 那你也很难解释训练为什么慢。
565

被折叠的 条评论
为什么被折叠?



