硬件基础:GPU架构简介
做AI训练和推理,说白了就是在跟GPU打交道。显存溢出这个问题,十有八九都跟GPU的硬件特性有关。我见过太多人,代码写得飞起,结果一跑就OOM,然后一脸懵地来问我:「我显卡不是有24G吗?怎么才跑一个batch就爆了?」
嗯,这里有个误区——你看到的24G,不一定都能用。今天我们就从硬件层面,把GPU的底裤扒干净。
GPU的核心三要素
我个人习惯把GPU拆成三个关键指标:显存带宽、显存容量、计算单元。这三者缺一不可,任何一个短板都会成为你的瓶颈。
1. 显存带宽
带宽是什么?说白了就是「数据搬运的速度」。GPU计算再快,如果数据搬不过来,那也是白搭。我遇到过一位同学,用A100跑大模型,结果发现训练速度还不如V100——后来一查,是他的数据加载方式导致带宽利用率极低。
显存带宽的计算公式很简单:
带宽 = 显存频率 × 位宽 ÷ 8
举个例子:
| GPU型号 | 显存类型 | 位宽 | 频率(GHz) | 带宽(GB/s) |
|---|---|---|---|---|
| RTX 3090 | GDDR6X | 384-bit | 19.5 | 936 |
| A100 | HBM2e | 5120-bit | 2.4 | 1555 |
| H100 | HBM3 | 5120-bit | 3.5 | 2039 |
你想想看,A100的位宽是5120-bit,比RTX 3090的384-bit大了十几倍。这就是为什么A100能轻松处理大batch,而3090容易卡在数据搬运上。
关键点:显存溢出不仅仅是容量问题,很多时候是带宽不够导致数据堆积,最终触发OOM。
2. 显存容量
容量这个好理解,就是GPU能装多少数据。但这里有个坑——显存不是给你一个人用的。
我调试过一个项目,明明用的是24G的RTX 4090,结果一跑就报显存不足。排查了半天,发现是系统自带的桌面环境占用了2G,浏览器又占了1G,再加上PyTorch的CUDA context初始化又吃掉几百兆……真正可用的,其实只有20G出头。
避坑指南:我曾经在服务器上同时跑了两个训练任务,结果两个都OOM了。后来才发现,显存是共享资源,不是你一个人独占的。用nvidia-smi看清楚当前占用,再分配任务。
3. 计算单元
计算单元就是GPU的「工人数量」。NVIDIA的GPU核心叫CUDA Core,每个核心可以执行一个线程。A100有6912个CUDA Core,H100有18432个。
但这里有个容易误解的地方——计算单元多,不代表一定快。如果你的模型很小,数据量也不大,那计算单元再多也是闲置。我见过有人用A100跑一个只有几万参数的小模型,结果GPU利用率不到5%,纯属浪费。
我的建议:小模型用小GPU,大模型用大GPU。别拿大炮打蚊子,也别拿手枪打坦克。
如何查看GPU状态:nvidia-smi详解
nvidia-smi是NVIDIA官方提供的GPU监控工具。我每天至少要看它几十次,几乎成了肌肉记忆。下面我把最常用的几个命令和参数拆开讲。
基础命令
nvidia-smi
这个命令会输出当前所有GPU的状态,包括:
- 温度:GPU核心温度,超过85°C就要注意了
- 利用率:GPU计算核心的占用百分比
- 显存使用:已用/总显存
- 进程列表:哪些进程在用GPU
我习惯用这个命令快速扫一眼,看看有没有「偷跑」的任务。
实时监控
watch -n 1 nvidia-smi
这个命令每秒刷新一次,适合在训练过程中盯着看。我曾经用这个命令抓到一个bug——某个数据加载线程卡住了,导致GPU利用率从90%掉到10%,显存却一直没释放。
查看详细参数
nvidia-smi -q
这个命令会输出GPU的所有详细信息,包括:
- 显存带宽利用率
- PCIe链路状态
- 电源功耗
- 时钟频率
我个人最常用的是 nvidia-smi -q -d MEMORY,只看显存相关的信息,省得被一堆参数淹没。
显存溢出时的排查步骤
当你遇到OOM时,别慌。按这个顺序查:
- 先看总显存:
nvidia-smi看看总容量和已用量 - 再看进程:有没有其他人在用?有没有残留进程?
- 最后看带宽:
nvidia-smi -q -d UTILIZATION看看显存带宽利用率
经验之谈:我遇到过最坑的一次,是PyTorch的DataLoader开了太多worker,每个worker都预加载了一批数据到显存里。明明batch size不大,显存却爆了。后来把num_workers从8降到2,问题解决。
GPU架构知识图谱
下面这张图是我自己整理的,把GPU的核心概念串起来了。你看完应该能对「显存溢出」有个全局认识。
这张图把GPU架构和显存溢出的关系理清楚了。你从中心往外看,先理解三要素,再掌握排查工具,遇到OOM就不会手忙脚乱了。
最后说一句:别把nvidia-smi当成摆设。我每次训练前都会跑一遍,看看当前显存状态。养成这个习惯,能帮你省下大量排查时间。