跳到主要内容
AIInfra前置基础

GPU 基础知识:从硬件架构到 AI 计算

系统理解 GPU 硬件架构、CUDA 编程模型、显存层次和计算单元,为深入学习 AI Infra打下坚实基础

GPU CUDA 硬件架构 AI计算 显存

GPU 是大模型时代的”发动机”——训练一个千亿参数的 LLM 可能需要数千块 GPU 运行数月,而推理服务的吞吐量和延迟也直接取决于 GPU 的利用效率。对于 AI Infra 工程师来说,理解 GPU 不是选修课,而是所有后续优化(算子、并行、调度)的硬件基础。

本文将从最基本的问题出发——GPU 为什么适合 AI 计算?它内部长什么样?程序是如何在上面运行的?——帮你建立一套完整的 GPU 认知框架。

📑 目录


1. CPU vs GPU:为什么深度学习选择了 GPU

要理解 GPU 的价值,最好的方式是把它和 CPU 放在一起对比。

想象你要批改 10000 份选择题试卷。CPU 的做法是请一位经验丰富的阅卷老师,他速度快、能处理各种复杂题型,但一次只能改一份;GPU 的做法是请 10000 个临时工,每人只会对答案这一件事,但所有人同时开工——1 秒就全部改完了。

这就是 延迟导向(Latency-oriented)与 吞吐导向(Throughput-oriented)的核心区别。

1.1 架构哲学的根本差异

📊 对比维度CPUGPU
设计目标低延迟处理复杂任务高吞吐处理大量简单任务
核心数量几个到几十个”大核”数千到上万个”小核”
单核能力强(复杂分支预测、乱序执行)弱(简单 ALU,按序执行)
缓存占比芯片面积的大部分芯片面积的小部分
控制逻辑复杂(乱序执行、分支预测器)简单(大量核心共享控制单元)
内存带宽较低(DDR5 ~100 GB/s)极高(HBM3 ~3 TB/s)
适合任务串行逻辑、操作系统、网络服务矩阵运算、数据并行、图形渲染

1.2 深度学习为什么天然适合 GPU

深度学习的计算核心是什么?拆到最底层,就是海量的矩阵乘法和逐元素运算:

  • 前向传播:每一层都是 Y=XW+bY = XW + b,本质是矩阵乘法
  • 反向传播:计算梯度依然是矩阵乘法(LW=XLY\frac{\partial L}{\partial W} = X^\top \cdot \frac{\partial L}{\partial Y}
  • Attention 计算Attention(Q,K,V)=softmax(QKdk)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right)V,核心还是矩阵乘

这些运算有两个关键特征:

  1. 数据并行度极高:矩阵中每个元素的计算相互独立,天然可以分配给不同的计算核心
  2. 计算模式规则:不需要复杂的分支判断,所有线程执行相同的指令

这恰好是 GPU 的长项——用成千上万个简单核心同时处理,吞吐量远超 CPU。

💡 提示:一块 H100 GPU 的 FP16 算力约为 989 TFLOPS,而高端服务器 CPU(如 Intel Xeon w9-3595X)的 FP16 算力通常在个位数 TFLOPS 级别。差距在两个数量级以上。


2. GPU 硬件架构剖析

了解了 GPU “为什么快”之后,我们来看看它”内部长什么样”。以 NVIDIA GPU 为例,从外到内可以分为三个层次:

2.1 GPC → TPC → SM 的层级结构

NVIDIA GPU 的计算核心按层级组织,就像一家大公司的组织架构:

GPU 芯片
├── GPC (Graphics Processing Cluster)  ← "事业部"
│   ├── TPC (Texture Processing Cluster)  ← "部门"
│   │   ├── SM (Streaming Multiprocessor)  ← "小组",GPU 的基本调度单元
│   │   │   ├── CUDA Core × N  ← "组员",执行 FP32/INT32 运算
│   │   │   ├── Tensor Core × M  ← "专家",执行矩阵运算
│   │   │   ├── SFU (Special Function Unit)  ← 执行 sin/cos/exp 等
│   │   │   ├── Register File  ← 寄存器堆(速度最快的存储)
│   │   │   ├── Shared Memory  ← 共享内存(SM 内所有线程共享)
│   │   │   └── L1 Cache
│   │   └── SM ...
│   └── TPC ...
├── GPC ...
├── L2 Cache(全局共享)
└── Memory Controller → HBM(显存)

2.2 SM:GPU 的基本调度单元

SM(Streaming Multiprocessor)是理解 GPU 架构的关键,所有的线程调度和执行都发生在 SM 层面。

以 H100 的 SM 为例,每个 SM 内部包含:

🔧 组件数量功能
CUDA Core(FP32)128执行浮点和整数运算
Tensor Core(第四代)4执行矩阵乘累加(MMA)运算
Load/Store Unit32负责内存读写
SFU16执行超越函数(sin、cos、exp 等)
Warp Scheduler4每周期调度 4 个 Warp
Register File256 KB线程私有寄存器
Shared Memory / L1 Cache228 KB(可配置)SM 内共享的高速存储

📌 关键点:SM 是资源分配的最小粒度。当你编写 CUDA Kernel 时,一个 Thread Block 会被调度到一个 SM 上执行。SM 内的寄存器、共享内存等资源由这个 SM 上的所有 Thread Block 共同分配。

2.3 Warp:GPU 执行的最小单位

GPU 不是一个线程一个线程执行的,而是以 Warp(线程束)为单位,32 个线程锁步执行同一条指令。这就像军队齐步走——32 个士兵听同一声号令,迈出同一只脚。

Warp(32 个线程)
├── Thread 0:  执行 add r1, r2, r3
├── Thread 1:  执行 add r1, r2, r3  (同一条指令,不同数据)
├── Thread 2:  执行 add r1, r2, r3
├── ...
└── Thread 31: 执行 add r1, r2, r3

这种执行模式叫做 SIMT(Single Instruction, Multiple Threads),是 NVIDIA 对 SIMD 的扩展。

⚠️ 注意:如果 Warp 内的线程遇到分支(if-else),走不同分支的线程会被 掩码(mask),导致部分线程空转。这就是所谓的 Warp Divergence,是 GPU 编程中需要极力避免的性能杀手。


3. 显存层次与带宽

GPU 的计算再快,如果数据”喂”不上来也白搭。在 AI 工作负载中,显存带宽往往比算力更先成为瓶颈——这就是为什么 AI Infra 领域有句话叫 “Memory is the new compute”

3.1 GPU 存储层级金字塔

GPU 的存储层级和 CPU 类似,越靠近计算核心速度越快、容量越小:

📊 层级容量带宽/延迟作用域说明
Register(寄存器)每线程 ~255 个~0 cycle单线程私有最快,但容量极有限
Shared Memory每 SM ~228 KB~30 cycleSM 内所有线程程序员显式管理的”L1 级别”缓存
L1 Cache与 Shared Memory 共享~30 cycleSM 内硬件自动管理
L2 Cache整卡 ~50 MB~200 cycle全局所有 SM 共享
HBM(显存)80 GB~600 cycle全局主存储,带宽决定吞吐上限

3.2 HBM:高带宽显存

传统 GDDR 显存就像一条单车道公路——传输速率有限。HBM(High Bandwidth Memory)则是把几千条车道堆叠在一起,通过硅中介层(Silicon Interposer)直接和 GPU 芯片互联,实现数倍的带宽提升。

📊 显存类型代表 GPU带宽容量
GDDR6XRTX 40901,008 GB/s24 GB
HBM2eA1002,039 GB/s80 GB
HBM3H1003,350 GB/s80 GB
HBM3eB2008,000 GB/s192 GB

💡 提示:从 A100 到 B200,显存带宽增长了近 4 倍。这对 LLM 推理意义重大——推理阶段的 decode 是典型的 Memory-bound 任务,带宽每提升 1 倍,理论吞吐量就能接近翻倍。

3.3 Roofline 模型:算力 vs 带宽的平衡点

判断一个计算任务是 Compute-bound(受算力限制)还是 Memory-bound(受带宽限制),可以用 算术强度(Arithmetic Intensity)这个指标:

算术强度=浮点运算量 (FLOPs)内存访问量 (Bytes)\text{算术强度} = \frac{\text{浮点运算量 (FLOPs)}}{\text{内存访问量 (Bytes)}}

当算术强度低于 GPU 的 ops:byte 比(即算力 / 带宽)时,任务是 Memory-bound;反之是 Compute-bound。

以 H100 SXM 为例:

  • FP16 算力:989 TFLOPS
  • HBM3 带宽:3,350 GB/s
  • ops:byte 比 = 989×10123,350×109295\frac{989 \times 10^{12}}{3,350 \times 10^9} \approx 295 FLOPs/Byte

这意味着:如果你的 Kernel 每从显存读取 1 Byte 数据,需要执行至少 295 次 FP16 浮点运算才能让算力充分跑满。否则 GPU 会”闲着等数据”。

📌 关键点:大多数深度学习算子(尤其是 Attention、LayerNorm、激活函数等)的算术强度远低于 295,这就是为什么 FlashAttention、Kernel Fusion 等优化技术如此重要——它们的核心思路就是减少显存访问、提升算术强度。


4. Tensor Core:AI 加速的核心引擎

CUDA Core 是通用计算核心,一个时钟周期执行一次 FMA(fused multiply-add)运算。而 Tensor Core 是专门为矩阵运算设计的加速单元——一个时钟周期可以完成一个小矩阵的乘累加运算。

4.1 工作原理

Tensor Core 执行的基本操作是 矩阵乘累加(MMA, Matrix Multiply-Accumulate):

D=A×B+CD = A \times B + C

其中 AABBCCDD 是小尺寸矩阵(具体尺寸取决于精度和架构代次)。

以 Hopper 架构为例,单个 Tensor Core 一个时钟周期可以完成 16×8×1616 \times 8 \times 16 的 FP16 矩阵乘累加——相当于一个 CUDA Core 要执行数千个时钟周期的工作量。

4.2 精度格式演进

不同精度格式在算力、精度、显存占用之间做了不同的取舍:

📊 精度位宽动态范围首次 Tensor Core 支持典型应用
FP3232 bit基准精度、loss 累加
TF3219 bit同 FP32Ampere(A100)训练(Ampere 上的默认 FP32 路径)
FP1616 bit较窄Volta(V100)混合精度训练(需 loss scaling)
BF1616 bit同 FP32Ampere(A100)混合精度训练(推荐,无需 loss scaling)
FP8(E4M3/E5M2)8 bit可选Hopper(H100)训练 + 推理
INT88 bit整数Turing(T4)推理量化
FP44 bit极窄Blackwell(B200)推理量化

💡 提示:BF16 和 FP16 都是 16 位,但 BF16 保留了和 FP32 相同的 8 位指数位,因此动态范围更大,训练时更不容易溢出。现代大模型训练几乎都用 BF16 而非 FP16。

4.3 Tensor Core 的算力倍增

Tensor Core 对比 CUDA Core 的性能提升非常显著(以 H100 SXM 为例):

📊 精度CUDA Core 算力Tensor Core 算力加速比
FP3267 TFLOPS495 TFLOPS(TF32)~7.4×
FP16134 TFLOPS989 TFLOPS~7.4×
FP81,979 TFLOPS

📌 关键点:要触发 Tensor Core 加速,矩阵的维度必须满足对齐要求(通常是 8 或 16 的倍数)。在实际工程中,如果模型的 hidden_size 不是 8 的倍数,Tensor Core 可能无法被充分利用。


5. CUDA 编程模型

CUDA 是 NVIDIA 提供的并行计算编程框架,是连接”软件算法”和”硬件执行”的桥梁。即使你日常用 PyTorch 而不直接写 CUDA,理解它的编程模型也有助于理解底层发生了什么。

5.1 线程层级:Grid → Block → Thread

CUDA 程序以 Kernel 为单位在 GPU 上执行。Kernel 的线程按三级层次组织:

Grid(网格)
├── Block (0,0)          Block (1,0)          Block (2,0)
│   ├── Thread (0,0)     ├── Thread (0,0)     ├── ...
│   ├── Thread (0,1)     ├── Thread (0,1)
│   ├── Thread (1,0)     ├── Thread (1,0)
│   └── ...              └── ...
├── Block (0,1)          Block (1,1)          Block (2,1)
│   └── ...              └── ...              └── ...
📊 层级说明硬件对应
Grid一次 Kernel 启动的所有线程整个 GPU
Block(线程块)一组协作的线程(最多 1024 个)调度到一个 SM
Thread(线程)最小执行单元CUDA Core
Warp(线程束)32 个连续线程(隐式分组)SM 中的 Warp Scheduler

5.2 一个简单的 CUDA Kernel 示例

下面是一个向量加法的 CUDA Kernel,展示 CUDA 的基本编程范式:

// 向量加法 Kernel:C[i] = A[i] + B[i]
__global__ void vecAdd(float *A, float *B, float *C, int N) {
    // 计算当前线程负责的全局索引
    int idx = blockIdx.x * blockDim.x + threadIdx.x;

    // 边界检查
    if (idx < N) {
        C[idx] = A[idx] + B[idx];
    }
}

// 主机端启动 Kernel
int main() {
    int N = 1000000;
    int threadsPerBlock = 256;
    int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;

    // <<<Grid 维度, Block 维度>>>
    vecAdd<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_C, N);
    return 0;
}

执行流程:📥 Host 分配显存并拷贝数据 → ⚙️ 启动 Kernel,GPU 将 Block 分配到各 SM → 📤 Kernel 执行完毕,结果拷回 Host。

5.3 内存模型与存储对应

CUDA 编程中不同的变量声明对应不同的硬件存储:

📊 CUDA 内存类型声明方式硬件位置作用域生命周期
Register局部变量SM 寄存器堆单线程Kernel
Local Memory溢出的局部变量HBM(显存)单线程Kernel
Shared Memory__shared__SM 片上存储Block 内Kernel
Global Memory__device__ / cudaMallocHBM(显存)所有线程应用
Constant Memory__constant__HBM + 缓存所有线程应用

⚠️ 注意:Local Memory 虽然名字里有”Local”,但实际存储在 HBM 上,访问速度和 Global Memory 一样慢。当寄存器不够用时,编译器会自动将变量溢出到 Local Memory,这叫做 Register Spilling,是需要警惕的性能问题。

5.4 用 PyTorch 感受 GPU 计算

大多数 AI Infra 工程师日常并不直接写 CUDA C,而是通过 PyTorch 等框架间接调用。理解底层 CUDA 有助于写出更高效的 PyTorch 代码:

import torch
import time

# 检查 GPU 信息
if torch.cuda.is_available():
    gpu = torch.cuda.get_device_properties(0)
    print(f"GPU: {gpu.name}")
    print(f"SM 数量: {gpu.multi_processor_count}")
    print(f"显存: {gpu.total_memory / 1024**3:.1f} GB")

# CPU vs GPU 矩阵乘法性能对比
N = 4096
A_cpu = torch.randn(N, N)
B_cpu = torch.randn(N, N)
A_gpu = A_cpu.cuda()
B_gpu = B_cpu.cuda()

# 预热
torch.mm(A_gpu, B_gpu)
torch.cuda.synchronize()

# 计时
start = time.perf_counter()
C_cpu = torch.mm(A_cpu, B_cpu)
cpu_time = time.perf_counter() - start

torch.cuda.synchronize()
start = time.perf_counter()
C_gpu = torch.mm(A_gpu, B_gpu)
torch.cuda.synchronize()
gpu_time = time.perf_counter() - start

print(f"CPU: {cpu_time*1000:.2f} ms | GPU: {gpu_time*1000:.2f} ms | 加速比: {cpu_time/gpu_time:.1f}x")

6. GPU 关键性能指标

评估一块 GPU 的 AI 计算能力,需要关注以下核心指标:

6.1 四大核心指标

📊 指标含义为什么重要
算力(TFLOPS)每秒浮点运算次数决定 Compute-bound 任务的上限
显存带宽(GB/s)每秒显存读写数据量决定 Memory-bound 任务的上限
显存容量(GB)可存储的数据总量决定能跑多大的模型
互联带宽(GB/s)GPU 间通信速度决定多卡并行的扩展效率

6.2 算力计算公式

GPU 的理论峰值算力可以通过硬件参数推算:

FP16 算力=SM 数量×每 SM 的 FP16 Core 数×2×时钟频率\text{FP16 算力} = \text{SM 数量} \times \text{每 SM 的 FP16 Core 数} \times 2 \times \text{时钟频率}

其中 ×2\times 2 是因为每个 FP Core 每周期执行一次 FMA(Fused Multiply-Add),包含一次乘法和一次加法。

Tensor Core 的算力计算方式不同,需要考虑每个 Tensor Core 每周期完成的 MMA 运算规模。

💡 提示:厂商标称的 TFLOPS 通常是带 Tensor Core 的稀疏(Sparsity)模式峰值,实际应用中的有效算力通常只有峰值的 30%~60%。当你做性能分析时,应该用实测值而非标称值。


7. 主流 AI GPU 横向对比

下面是截至 2025 年主流 NVIDIA AI GPU 的核心参数对比:

📊 型号架构SM 数显存带宽FP16 算力FP8 算力TDP典型用途
V100Volta8032 GB HBM2900 GB/s125 TFLOPS300W经典训练卡
A100 SXMAmpere10880 GB HBM2e2,039 GB/s312 TFLOPS400W训练 + 推理
H100 SXMHopper13280 GB HBM33,350 GB/s989 TFLOPS1,979 TFLOPS700W大规模训练
H200Hopper132141 GB HBM3e4,800 GB/s989 TFLOPS1,979 TFLOPS700W长序列推理
B200Blackwell160192 GB HBM3e8,000 GB/s2,250 TFLOPS4,500 TFLOPS1000W下一代旗舰
L40SAda14248 GB GDDR6864 GB/s366 TFLOPS350W推理 / 多媒体

⚠️ 注意:同一架构可能有 SXM 和 PCIe 两种封装。SXM 版本通常功耗更高、频率更高、且支持 NVLink 互联,性能显著强于 PCIe 版本。选型时务必确认封装类型。


8. 显存管理:AI Infra 的核心挑战

训练大模型时,显存往往是最先遇到的瓶颈。一个 7B 参数的模型(FP16),仅模型参数就需要约 14 GB 显存;加上优化器状态、梯度、激活值,实际显存占用可达 4~8 倍参数量。

8.1 训练时显存都用在哪里

以 Adam 优化器 + FP16 混合精度训练为例,每个参数需要的显存:

📊 组成部分每参数字节说明
FP16 参数2 B前向 / 反向计算使用
FP32 参数副本4 BAdam 需要维护 FP32 master weights
FP32 梯度4 B反向传播产生
Adam 一阶动量(m)4 B梯度的指数移动平均
Adam 二阶动量(v)4 B梯度平方的指数移动平均
合计18 B

一个 7B 模型的固定显存 = 7×109×18=1267 \times 10^9 \times 18 = 126 GB,这还不算激活值(Activation)。

8.2 常用显存优化策略

面对显存不够用的困境,AI Infra 领域发展出了一系列经典策略:

📊 策略原理显存节省代价
混合精度训练用 FP16/BF16 做前向反向,FP32 做参数更新~50% 参数显存需要 loss scaling(FP16)
梯度累积用多个 micro-batch 累积梯度,等效大 batch减少激活值峰值增加训练步数
梯度检查点前向时只保留部分激活,反向时重新计算激活显存降至 O(N)O(\sqrt{N})增加约 33% 计算量
ZeRO 优化将优化器状态 / 梯度 / 参数分片到多卡线性降低每卡显存增加通信量
Offloading将部分数据卸载到 CPU 内存或 NVMe突破单卡显存上限PCIe 带宽成为瓶颈

💡 提示:这些策略并非互斥,实践中通常组合使用。例如 DeepSpeed ZeRO Stage 2 + 混合精度 + 梯度检查点是训练中大模型(7B~70B)的常见配置。


9. 多卡互联:从单机到集群

当单卡显存和算力无法满足需求时,就需要多卡并行。GPU 之间的互联带宽和拓扑直接决定了并行训练的效率。

9.1 互联技术对比

📊 互联技术带宽场景说明
PCIe 5.0128 GB/s(双向)跨卡(通用)普遍但带宽较低
NVLink 4.0(Hopper)900 GB/s(全双工)机内 GPU 互联专用高速互联,H100 使用
NVLink 5.0(Blackwell)1,800 GB/s(全双工)机内 GPU 互联B200 使用
NVSwitch连接所有 NVLink机内全互联实现 All-to-All 全带宽通信
InfiniBand NDR400 Gb/s(50 GB/s)跨机互联大规模集群标配

9.2 典型多卡拓扑

以 DGX H100(8 卡)为例:

  • 8 块 H100 通过 NVSwitch 实现全互联,任意两卡之间 900 GB/s
  • 每台机器通过 8 张 ConnectX-7 InfiniBand 网卡与集群相连
  • 机内通信 >> 机间通信,这个带宽差异直接影响并行策略的选择

📌 关键点:在设计分布式训练策略时,应该让通信量大的并行维度(如张量并行)放在高带宽的机内 NVLink 上,通信量相对较小的并行维度(如数据并行、流水线并行)放在机间 InfiniBand 上。

# 查看 GPU 拓扑信息
nvidia-smi topo -m

# 查看 NVLink 状态
nvidia-smi nvlink -s

📝 总结

本文从 CPU 与 GPU 的架构差异出发,逐步深入到 GPU 的内部结构,涵盖了以下核心知识点:

  • 为什么选择 GPU:深度学习的矩阵运算天然适合 GPU 的大规模并行架构
  • 硬件架构:GPC → TPC → SM → CUDA Core / Tensor Core 的层级组织,Warp 是执行的最小调度单位
  • 显存层次:Register → Shared Memory → L1/L2 Cache → HBM 的金字塔结构,带宽往往比算力更先成为瓶颈
  • Tensor Core:专为矩阵乘累加设计的加速单元,BF16/FP8 等低精度格式持续推动算力增长
  • CUDA 编程模型:Grid → Block → Thread 的线程组织,以及存储类型与硬件的对应关系
  • 性能评估:算力、带宽、显存容量、互联带宽四大核心指标
  • 显存管理:混合精度、梯度累积、梯度检查点、ZeRO 等经典优化策略
  • 多卡互联:NVLink、NVSwitch、InfiniBand 构成从机内到集群的通信基础

掌握这些基础知识后,你将具备阅读后续 CUDA 编程、分布式训练、推理优化等进阶文章的硬件认知基础。


🎯 自我检验清单

  • 能说出 CPU 和 GPU 在架构设计哲学上的核心区别
  • 能画出 GPU 的层级结构(GPC → SM → CUDA Core / Tensor Core)
  • 能解释 Warp 的概念以及 Warp Divergence 为什么影响性能
  • 能说出 GPU 存储层级(Register → Shared Memory → L2 → HBM)各自的容量和速度量级
  • 能用 Roofline 模型判断一个算子是 Compute-bound 还是 Memory-bound
  • 能解释 BF16 和 FP16 的区别,以及为什么大模型训练更推荐 BF16
  • 能列举 3 种以上显存优化策略及其原理
  • 能用 nvidia-smi 查看 GPU 状态、拓扑信息
  • 能说出 NVLink 和 PCIe 在带宽上的数量级差异
  • 能估算一个 7B 参数模型使用 Adam + FP16 混合精度训练时的显存占用

📚 参考资料