AI Infra 学习路线 · 阶段二(打通 GPU 这一层)· 模块一
目标:把"GPU 黑盒"打开 ------ 理解 GPU 为什么适合深度学习、核心怎么组织、显存怎么分层
性质:纯理论,是后面写 CUDA(模块二)和算显存账(模块三)的地基
环境验证已通过:WSL 本地 torch 2.12.0+cu130,CUDA 可用,5060Ti 能真实计算
1. 为什么 GPU 适合深度学习:CPU vs GPU 的本质区别
| CPU | GPU | |
|---|---|---|
| 比喻 | 少数几个全能博士 | 成千上万个只会简单算术的工人 |
| 核心 | 几个~几十个,每个很强 | 几千个(5060Ti 约 4600 CUDA 核心),每个较简单 |
| 擅长 | 复杂逻辑、分支判断 | 大量简单、可同时进行的运算 |
| 设计目标 | 低延迟(尽快做完一个任务) | 高吞吐(同时处理海量任务) |
为什么深度学习适合 GPU :神经网络核心计算是矩阵乘法 ,而矩阵乘法 = 大量互相独立的"乘加运算"。一个 1000×1000 矩阵乘法 = 几百万个独立乘加。这种"大量、简单、可同时进行"正是 GPU 的主场:几千个核心每人分一小块,同时开干。
torch.matmul(x,y) 在 GPU 上一瞬完成,背后就是几千个 CUDA 核心同时把矩阵乘法拆块并行算完 ------ 这就是"并行"在硬件上的真实含义。
2. 判断"适不适合 GPU"的核心标准 ★
任务能不能拆成大量互相独立、可同时进行的小块?
- 能拆(互不依赖)= 数据并行 → 适合 GPU(如矩阵乘法:结果每个位置可独立算出)
- 有强串行依赖(每步依赖上一步结果)→ 适合 CPU(如斐波那契:第 n 个数必须等 n-1、n-2 算完)
串行依赖的活给 GPU,几千核心只有一个在干、其余干等,优势全废。
这个标准会一直用:大模型训练为什么想方设法"并行化"、有些计算为什么是 GPU 瓶颈,根子都在于尽量减少串行依赖、别让核心闲着。
3. SIMT(Single Instruction, Multiple Threads)
GPU 的工作模式:一条指令,同时驱动很多线程在不同数据上执行 。
比喻:老师喊一声"把手上两个数相乘",几千学生同时执行这同一条指令,但每人算不同的数。"一声令下、齐刷刷干同样的活"是 GPU 高效的根源。
推论 :GPU 不擅长复杂分支。若线程各做各的(大量 if-else 分叉),没法"齐步走",效率暴跌。
影响:写 CUDA 要让线程步调一致;推理优化时 batch 越规整越快 ------ 都源于 SIMT。
4. SM(Streaming Multiprocessor,流多处理器)
GPU 核心不是一盘散沙,而是分组管理:
- SM = 基本组织单位,理解为"车间"。整个 GPU(工厂)由几十个 SM 组成。
- 每个 SM 内含一批 CUDA 核心(工人)+ 共享资源。
- GPU 以 SM 为单位调度:把大批线程分组,每组扔给一个 SM 执行。
为什么要知道:写 CUDA 时线程怎么分块,直接对应"任务怎么分给 SM",分得好不好直接影响 GPU 利用率(nvidia-smi 的 GPU-Util)。利用率上不去的一种原因就是线程分块没分好、SM 没喂饱。
5. 显存层级 ★★(后面算显存账的基础)
GPU 存储分多层,越快的越小越贵,越大的越慢。从大/慢到小/快:
| 层级 | 容量 | 速度 | 范围 | 比喻 | 存什么 |
|---|---|---|---|---|---|
| 全局显存 Global | 最大(如 8G) | 相对最慢 | 所有 SM 可访问 | 仓库(大、远、慢) | 模型参数、训练数据、中间结果 |
| 共享显存 Shared | 每 SM 几十~上百 KB | 极快(比全局快上百倍) | 仅本 SM 线程 | 工位旁小架子(小、近、快) | 反复用的数据(手动搬入做优化) |
| 寄存器 Registers | 极小 | 最快 | 每线程私有 | 手里正拿的工具 | 线程临时变量 |
高性能计算的艺术 = 尽量减少跑"仓库"(全局显存)的次数,多用手边的东西 。
写优化 CUDA kernel 的核心技巧之一:把反复用的数据先搬到共享显存,避免反复去慢的全局显存取(模块二重点)。
6. 为什么 nvidia-smi 的显存占用 ≈ 全局显存
nvidia-smi 报告的显存数(如 967MiB / 8151MiB)统计的就是全局显存占用,共享显存和寄存器不在内:
- 量级差太远:全局是 GB 级,共享每 SM 几十上百 KB、寄存器按字节算,几十个 SM 加起来才几~十几 MB,相比 8G 可忽略。
- 性质不同:全局显存是"长期持有"(模型参数加载后整个训练都占着,稳定可测);共享显存/寄存器是线程执行时临时借用、用完即还,生命周期以微秒计,不是"占住不放"的占用,无法也无需报稳定数字。
结论 :nvidia-smi 显存数 ≈ 全局显存占用。模型参数、梯度、优化器状态、激活值这些"训练期间一直占着"的大头全在全局显存里。
→ 模块三"算显存账"算的就是"全局显存被这几样分别吃掉多少",且能用 nvidia-smi / PyTorch 显存接口实测验证。
7. 模块一知识地基(一条线串起来)
GPU vs CPU(吞吐 vs 低延迟)
→ 判断标准(能否拆成大量独立小任务)
→ SIMT(一声令下齐步走,不擅分支)
→ SM(核心的组织单位,关系到利用率)
→ 显存三层级(全局/共享/寄存器,越快越小;nvidia-smi 反映全局)
扎实后:模块二写 CUDA 知道"为什么这么写",模块三算显存账知道"账记在哪一层"。