从零开始的大模型(Transformer)学习笔记
前言
本篇为大模型相关技术的初级学习文档,从transformer原理、GPU架构到软件与硬件基础,专业性不强,适合小学三年级儿童。
本文大部分总结自“基于chat对话,由文本类大模型整理生成”,如有谬误请帮忙甄别和指正!
Transformer部分,这里推荐3Blue1Brown的视频,非常易于理解:
以GPT-3(别看他是3)直观解释Transformer的第一步
从零开始的大模型(Transformer)技术学习笔记
本章节基于学习对话整理,聚焦AI运维与GPU服务器场景中,与基于Transformer的文本大模型运行时技术相关的核心知识、显存管理与GPU基础概念。适合作为快速索引和复习材料。
Transformer 是什么
Transformer 是一种专门处理序列数据(文本、语音等)的神经网络架构。今天几乎所有主流大语言模型——OpenAI GPT 系列、Meta Llama 系列、Google Gemma 系列、阿里巴巴 Qwen 系列——其核心都建立在 Transformer 之上。
理解 Transformer,可以从三个层次入手:模型的知识存放在哪里?模型如何理解上下文?模型如何高效生成内容?
模型的“知识库”——权重文件
模型的知识和能力就存储在权重文件里。这些文件包含了模型中所有神经元的连接强度,也就是大量的浮点数矩阵。目前主流的安全高效存储格式是Hugging Face推广的safetensors,它比传统的.bin文件加载更快且安全性更高。
一个 7B 模型拥有约 70 亿个参数,这些参数本质上是大量浮点数,最终组织成成千上万个矩阵,构成模型全部知识。
如果你部署过大模型,就会发现这玩意真巨大,下载部署非常耗时间
Embedding、向量与张量
在理解 Attention 机制之前,先建立几个基础的数学概念。标量就是一个数值,比如模型中某个权重值 0.5。向量是一组有序数值,词向量(Embedding)的本质就是向量,例如“[0.3, -0.7, 0.9]”,用来在高维空间中定位词的语义。矩阵是二维数据表,Transformer 的权重文件本质上就是由大量矩阵组成。张量是更高维度的数据容器,可以统一表示标量、向量、矩阵以及更高维的数组。
在深度学习中,[Batch, Sequence Length, Hidden Size] 就是一个典型的三维张量,Q、K、V 也都是张量。
Embedding 只是把 Token 转换成向量,比如“猪”变成了 [0.31, -0.12, 0.89 …],但模型仍然不知道“猪八戒”和“猪猪侠”中的“猪”含义是否相同,不过同一个 Token(比如“猪”)在同一个模型里的初始 Embedding 向量是固定且唯一的。
于是 Transformer 引入了 Self-Attention(自注意力机制) ,让模型能够理解上下文。
Attention 与 Q/K/V
为了让模型理解上下文(即区分 猪八戒 和 猪猪侠 是涉及了同词汇 猪 但语义不同),这个结构引入了注意力机制,并用到了三个核心向量:Q (Query,查询)、K (Key,键)、V (Value,值)。
| 向量 | 类比 | 作用 |
|---|---|---|
| Query(Q) | 我正在寻找什么 | 代表“我现在想找什么信息” |
| Key(K) | 我是谁 | 每个词的“身份标签”,用来被 Query 匹配 |
| Value(V) | 我的具体内容 | 词的“实际内容”,匹配后取出 |
整个过程分四步:
- 生成Q、K、V:模型把每个单词向量分别乘以三个不同的权重矩阵 $W_Q,W_K, W_V $,为它同时生成三个向量:Q、K、V。
- 计算相关性:用“提问者” Q 去和所有单词的“标签” K 做匹配。匹配方式通常是计算它们的点积,点积结果越大,表示相关性越高。
- 权重归一化:计算出的匹配分数通过 Softmax函数 转换为一个和为1的概率分布(归一化),这些概率就是注意力权重。 Temperature(温度) 参数,就是在这一步发挥作用,去控制权重的“平滑度”,从而影响生成文本的创造性和随机性。
- 加权求和出结果:最后,将注意力权重和对应单词的 V 值相乘并求和,得到最终的输出。这个输出也就相当于模型“阅读”了整句话后,对每个单词的关注度评估结果。
模型精度与显存占用
模型参数最终都要加载到显存中,模型大小(GB)≈ 参数量 × 精度字节数。例如一个 7B 模型若使用 FP32(4 字节),约占用 28 GB 显存。
常见精度格式:
| 精度 | 字节数 | 特点 |
|---|---|---|
| FP32 | 4 Byte | 训练标准,推理极少用 |
| FP16 | 2 Byte | 推理常用 |
| BF16 | 2 Byte | 保留与 FP32 相同的指数范围,训练更稳定、不易溢出 |
| INT8 | 1 Byte | 常见量化方案,通过 scale 因子将浮点范围映射到整数空间 |
| INT4 / FP4 | 0.5 Byte | 极限压缩 |
需要区分两个概念:权重量化减少模型加载后的基础显存占用,KV Cache 量化减少推理过程中动态增长的显存占用。两者可以独立进行——例如模型权重保持 FP16,KV Cache 单独压缩为 INT8(vLLM 中可通过 --quantization kv_cache_int8 实现)。权重量化解决“模型太大”的问题,KV Cache 量化解决“上下文太长”的问题。
运维要点:模型权重和KV Cache的精度可以不同,权重量化节省的是加载到显存的基础空间,而KV Cache量化直接影响运行时动态增长的显存占用。
KV Cache与GPU基础
在 GPU 上运行时,显存主要由三部分构成:模型权重(固定占用)、KV Cache(动态增长)、临时激活值(短暂占用)。在实际线上服务中,KV Cache 往往才是真正的显存消耗大户。
KV Cache:用空间换时间的核心策略
大语言模型(LLM)在生成文本时是一个字一个字(token)往外蹦的自回归过程。这意味着它是有状态的(stateful),每一步都严重依赖上一步乃至所有历史步骤的结果。
如果没有 KV Cache,生成第 100 个 Token 时要重新计算前 99 个 Token 的 K 和 V,生成第 101 个 Token 又要重新算前 100 个,重复计算会让推理速度急剧下降。
为了解决这个问题,引入了 KV Cache。
KV Cache 是一种典型的“空间换时间”策略。它将历史 token 的 Key 和 Value 向量缓存下来。当生成下一个新 token 时,模型只需要计算新 token 的 Query,然后直接复用缓存中的 K 和 V 来计算注意力,从而避免了大量重复计算。
需要注意的是,没有 Q Cache,因为每个新 token 的 Q 都不同,缓存它没有意义。
KV Cache:运维时的显存计算核心
KV Cache 的显存占用是整个系统的重中之重,可以直接通过公式精确估算。其计算公式如下:
1 | |
| 参数 | 含义 |
|---|---|
| L | Transformer 层数。如 Llama 3 8B 有 32 层,来自模型配置文件(config.json)的num_hidden_layers。 |
| H_kv | KV Head 数量,来自配置文件中的num_key_value_heads。在GQA(分组查询注意力)或MQA(多查询注意力)等优化技术中,H_kv通常远小于注意力头的总数,从而大幅减少 KV Cache 的显存占用。 |
| D_head | 每个注意力头的维度大小(通常由 hidden_size / num_attention_heads 计算) |
| Batch | 并发请求数 |
| SeqLen | 总上下文长度(输入长度 + 已生成输出长度) |
| dtype_bytes | 精度字节数。例如,FP32(单精度浮点)占4字节,FP16/BF16(半精度浮点)占2字节,INT8(8位整数)量化后仅占1字节。 |
| 系数2 | 代表 Key 和 Value 各缓存一份 |
其中最关键的是 Batch、SeqLen 和 H_kv,它们直接决定运行时的显存压力。
GPU基础与显存构成
理解了 KV Cache 的显存模型,就很容易理解大模型在 GPU 上运行时,显存主要被这几部分占据:模型权重(加载模型本身需要的空间)、KV Cache(如前所述,服务时的最大消耗大户)和临时激活值(计算过程中的中间变量,通常生命周期很短)。
这里需要特别说明的一个核心设计:为什么模型是“自回归”的?
自回归生成是当前主流大模型的运作方式。简单来说,就是模型通过反复预测“下一个最可能出现的词”来生成完整句子。模型每次只生成一个 token,然后将这个 token 与之前的输入拼接,形成新的输入序列,再重复上述过程,直到生成一个特殊的终止 token 或达到最大长度。
这样一来,模型的每一步输出都依赖于自己的上一步输出,如同滚雪球一般,这便是“自回归”的含义。
多头注意力MHA、MQA 与 GQA
每个注意力头可以理解成一位独立“专家”,在各自子空间中捕捉信息,然后并行拼接,让模型同时从多个角度理解语言。为了降低 KV Cache 的显存压力,业界发展出了几种关键变体:
- MHA(Multi-Head Attention,标准多头):每个Q头有独立的K和V。表达能力最强,但KV Cache随头数线性增长,显存占用最高。例如
num_attention_heads=32, num_key_value_heads=32 - MQA(Multi-Query Attention,多查询注意力):所有Q头共享一个K和V。显存占用极低,但有损模型质量
- GQA(Grouped-Query Attention,分组查询注意力):多头的折中方案。将Q头分组,每组共享一个K和V。在降低KV Cache和维持质量之间取得良好平衡。公式中
num_key_value_heads即组数。比如Q头数32,num_key_value_heads=8,则每组4个Q头共享一对KV。
不同架构对KV Cache显存的影响:num_key_value_heads直接决定了KV Cache公式中的H_kv。MHA模式下等于Q头数,显存占用大;MQA模式等于1,显存占用最小但质量有损;GQA模式等于组数,在两者之间取得平衡。当前主流大模型普遍采用GQA,例如Llama 3、Gemma等。
训练阶段的前向传播、反向传播与显存占用
前文已经讲了模型权重、精度和 KV Cache,这里补上训练阶段最容易缺失的一块:前向传播、反向传播、激活值、梯度、优化器状态,以及多卡训练中的 All-Reduce。
前面提到,推理时显存主要由三部分构成:模型权重(固定占用)、KV Cache(动态增长)、临时激活值(短暂占用)。
但训练和推理不一样。训练不只是“把模型跑一遍”,还要计算每个参数应该往哪个方向更新,所以显存里还需要额外保存更多中间结果。
训练时显存通常由以下几部分组成:
| 类型 | 是否训练特有 | 作用 | 显存特点 |
|---|---|---|---|
| 模型权重(Parameters) | 否 | 当前模型参数 | 固定占用,参数量越大占用越高 |
| 激活值(Activations) | 是 | 前向传播产生的中间结果,供反向传播使用 | 随 batch size、序列长度、层数增长,常常是显存大户 |
| 梯度(Gradients) | 是 | 每个参数的更新方向 | 通常和参数量同规模 |
| 优化器状态(Optimizer States) | 是 | Adam 等优化器保存的一阶/二阶动量 | Adam 通常额外保存 2 份状态,显存压力很大 |
| 通信缓冲区(Communication Buffer) | 多卡训练相关 | All-Reduce 等通信使用 | 多卡训练中额外占用 |
因此,同一个 7B 模型,能推理不代表能训练。推理只需要加载权重和运行时缓存,而训练还要保存激活、梯度和优化器状态。
前向传播:把输入一路算到输出
训练的第一步是 前向传播(Forward Pass)。
可以简单理解为:把一批 token 输入模型,从 Embedding 开始,依次经过每一层 Transformer Block,最后得到预测结果。
在每一层里,模型大致会做这些计算:
- 输入 token 先变成向量表示。
- 经过 Attention,计算 Q/K/V、注意力分数和加权结果。
- 经过 MLP/FFN,做非线性变换。
- 经过残差连接、LayerNorm 等结构。
- 输出传给下一层。
推理时,前向传播算完这一层的中间结果,大部分可以很快释放;但训练不行。
因为训练后面还要做反向传播,而反向传播需要用到前向阶段保存的中间结果,所以这些中间结果不能立刻丢掉。
这些被保存下来的中间结果,就是 激活值(Activations)。
激活值:训练显存里的隐藏大头
激活值可以理解为:模型每一层处理输入后留下的“中间状态”。
例如某一层 Transformer 处理完一批 token 后,会产生形状类似下面这样的张量:
1 | |
如果只是单层,这个张量看起来还不算夸张;但大模型有很多层,而且训练时每一层的关键中间结果都要保留,问题就变大了。
激活值显存大致和这些因素成正比:
1 | |
这里最容易被低估的是 seq_len。
当序列长度从 2048 提升到 4096 时,激活值不是简单“多一点”,而是会在多层 Transformer 中持续放大。Attention 相关中间张量还会进一步加剧长序列带来的显存压力。
显存杀手:在大模型训练中,所有层的激活值都需要保存在显存中,直到反向传播完成后才能释放。对于长序列(如 4096 个 token),激活值占用的显存甚至可能超过模型权重本身。
这也是为什么很多模型明明参数量不算特别大,但一训练就 OOM:显存不只是被权重吃掉,真正压垮显存的往往是 长序列 + 大 batch + 多层激活值。
反向传播:从损失反推每个参数怎么改
前向传播结束后,模型会得到预测结果。接着会用预测结果和真实答案计算一个 Loss(损失值)。
Loss 可以理解为:模型这次答得有多离谱。
然后进入 反向传播(Backward Pass)。
反向传播做的事情是:从最后的 Loss 开始,一层一层往回推,计算每个参数对 Loss 的影响,也就是梯度。
简单说:
1 | |
为什么反向传播必须依赖前向传播保存的激活值?
因为计算梯度时,不仅需要知道“当前层的参数是什么”,还需要知道“前向时这一层输入了什么、输出了什么”。这些信息就是前面保存的激活值。
所以训练时显存释放顺序大致是:
- 前向传播逐层保存激活值。
- 反向传播从最后一层往前计算梯度。
- 某一层的梯度算完后,该层对应的激活值才可以释放。
- 直到反向传播完成,大部分激活值才被释放。
这就是训练显存远高于推理显存的核心原因。
梯度:每个参数都要有一份“更新方向”
梯度(Gradient)表示每个参数应该如何调整,才能让 Loss 下降。
如果一个模型有 7B 参数,那么训练时不仅要保存这 7B 个参数本身,还要为这些参数保存对应的梯度。
通常可以粗略理解为:
1 | |
例如 7B 参数,如果梯度使用 FP16/BF16,每个参数 2 Byte,那么仅梯度就大约需要:
1 | |
这还没有算激活值、优化器状态和通信缓冲区。
优化器状态:Adam 为什么特别吃显存
训练中常用 Adam / AdamW 优化器。它不只是根据当前梯度更新参数,还会保存历史梯度的统计信息。
Adam 通常会为每个参数额外保存两类状态:
- 一阶动量(m):类似梯度的滑动平均。
- 二阶动量(v):类似梯度平方的滑动平均。
所以使用 Adam 训练时,显存里常见状态包括:
1 | |
如果为了数值稳定,还保留 FP32 master weights,那么显存会进一步增加。
一个很粗略的估算是:
| 项目 | 常见精度 | 7B 参数粗略占用 |
|---|---|---|
| 参数 | FP16/BF16 | 约 14 GB |
| 梯度 | FP16/BF16 | 约 14 GB |
| Adam 一阶动量 | FP32 | 约 28 GB |
| Adam 二阶动量 | FP32 | 约 28 GB |
| FP32 master weights(如保留) | FP32 | 约 28 GB |
可以看到,仅这些“参数相关状态”就可能远超单卡显存,更不用说激活值了。
这也是为什么大模型训练通常需要 ZeRO、FSDP、张量并行、流水线并行等技术来切分参数、梯度和优化器状态。
All-Reduce:多卡训练时梯度怎么同步
当模型放到多张 GPU 上训练时,每张卡通常会处理不同的数据 batch。每张卡都会独立完成一次前向传播和反向传播,并得到一份本卡上的梯度。
但这些 GPU 训练的是同一个模型,所以不能各改各的。每一步参数更新前,必须先把所有 GPU 上的梯度汇总起来,得到一致的全局梯度。
这个过程就是 All-Reduce。
可以简单理解为:
1 | |
All-Reduce 的特点是:
- 每张 GPU 都参与通信。
- 每张 GPU 最终都拿到相同的聚合结果。
- 通信量和梯度大小强相关。
- 模型越大,梯度越大,All-Reduce 通信压力越高。
在 NVIDIA 生态中,All-Reduce 通常由 NCCL 负责。NCCL 会根据硬件拓扑自动选择通信路径:
1 | |
如果拓扑不好,或者容器、驱动、RDMA、Peer Access 配置不对,All-Reduce 就可能从高速路径降级到低速路径,训练速度会明显下降。
排查时重点看:
1 | |
如果日志里看到 NCCL 没有走 NVLink / P2P / IB,而是退化到较慢路径,就要继续排查拓扑、驱动、容器挂载、Fabric Manager、RDMA 网卡和 NUMA 绑定。
训练显存为什么容易爆:一条完整链路
把上面的内容串起来,训练阶段的显存压力大致来自这条链路:
1 | |
所以训练显存不能只按“模型参数量 × 精度字节数”估算。这个公式只适合粗略估算模型权重,不适合估算训练总显存。
更接近真实训练的显存构成应理解为:
1 | |
其中最容易失控的是:
- 长序列导致激活值暴涨。
- Adam 优化器状态远大于参数本身。
- 多卡训练中的通信缓冲区和梯度同步开销。
- Attention 中间结果随序列长度快速放大。
降低训练显存的常见手段
下面这些技术,本质上都是在处理“参数、梯度、优化器状态、激活值”这几类显存压力。
| 手段 | 主要减少什么 | 代价 |
|---|---|---|
| Mixed Precision(FP16/BF16) | 参数、梯度、激活值 | 需要处理数值稳定性 |
| Gradient Checkpointing | 激活值 | 反向传播时重算部分前向,训练变慢 |
| ZeRO / FSDP | 参数、梯度、优化器状态 | 通信复杂度增加 |
| Tensor Parallelism | 单层矩阵计算和参数 | 依赖高速 GPU 互联 |
| Pipeline Parallelism | 不同层分布到不同 GPU | 需要处理流水线气泡 |
| Sequence Parallelism | 长序列相关激活 | 实现复杂,依赖框架支持 |
| 减小 batch size / seq_len | 激活值 | 可能影响吞吐或模型效果 |
其中最常见、最直接的组合是:
1 | |
如果是长序列训练,优先关注:
seq_len是否过大。- 是否开启 Gradient Checkpointing。
- Attention 实现是否使用 FlashAttention。
- 是否使用 ZeRO/FSDP 切分参数、梯度和优化器状态。
- 多卡拓扑是否支持高效 All-Reduce。
运维视角速查表
| 现象 | 常见原因 | 优先检查 |
|---|---|---|
| 推理能跑,训练 OOM | 训练多了激活、梯度、优化器状态 | batch size、seq_len、optimizer、checkpointing |
| seq_len 一加长就 OOM | 激活值随序列长度快速增长 | seq_len、FlashAttention、Gradient Checkpointing |
| 多卡训练速度很慢 | All-Reduce 走了低速路径 | nvidia-smi topo -m、NCCL_DEBUG=INFO |
| 显存占用远超模型权重 | Adam 状态和激活值占用大 | optimizer、ZeRO/FSDP、activation memory |
| GPU-Util 不高但训练慢 | CPU 数据加载或通信瓶颈 | dataloader、PCIe/NVLink、NCCL 日志 |
| 单卡能训,多卡异常 | 拓扑、NCCL、容器或 RDMA 配置问题 | topo、NCCL 日志、Fabric Manager、IB/RoCE |
小结
推理时重点关注 模型权重 + KV Cache;训练时则必须额外关注 激活值 + 梯度 + 优化器状态 + All-Reduce 通信。
其中最容易被忽视的就是激活值:在大模型训练中,所有层的激活值都需要保存在显存中,直到反向传播完成后才能释放。对于长序列(如 4096 个 token),激活值占用的显存甚至可能超过模型权重本身。
所以排查训练 OOM 时,不能只问“模型多大”,还要同时看:
1 | |
这几个因素共同决定了训练到底需要多少显存。
微观机制 - Softmax归一化与Temperature参数
现在我们从宏观的架构和显存优化,深入到模型决策的微观层面,从常见的大模型HTTP参数 Temperature 理解为什么它会影响模型的创造力,可以结合3Blue1Brown的视频理解!
Transformer 注意力机制通过计算 Query(查询)和 Key(键)的相似度来确定每个 token 的重要性,Softmax 函数在这里扮演了“翻译官”的角色,将原始的相似度分数转换成一个干净漂亮的概率分布。
Softmax:“提名”与“归一化”
数学形式与计算原理
对于一个输入的原始分数向量(logits) ( z = [z_1, z_2, …, z_n] ),Softmax 函数的数学定义如下:
$$
[
\text{Softmax}(z_i) = \frac{e^{z_i}}{\sum_{j} e^{z_j}}
]
$$
这个公式的逻辑分为两步,非常有意思:
- “指数放大”:通过 ( e^{z_i} ) 的指数运算,将向量中原本的差异给大大放大,让原本数值高的变得更高,低的变得更低。模型做这一切,都是为了确保那个最高分被凸显出来,方便我们选它。
- “归一化”:然后将这个指数结果除以所有指数结果的总和,将最终的输出值压缩到 (0, 1) 的区间内,并且确保这些值的总和为 1,完美地构成了一个概率分布。
Temperature参数:控制“随机性”与“创造力”
理解 Softmax 后,现在来看看 **Temperature (温度)**。它是大模型生成过程中一个至关重要的“控制旋钮”,直接影响输出的质量和多样性。它的作用对象,正是 Softmax 归一化生成的那个概率分布。
数学原理
带 Temperature 的 Softmax 公式如下:
$$
[
P_i = \frac{e^{z_i / T}}{\sum_{j} e^{z_j / T}}
]
$$
其中 T 就是我们所说的 Temperature 参数。它的作用是先“调制”原始分数(logits),再送入 Softmax 函数。
从呆板到发散:不同温度值对概率分布的影响
T = 1:标准状态
- 作用: 保持 Softmax 计算出的原始概率分布不变。
- 比喻: 就像一个专业的评委,客观地按照水平高低给选手分配得奖概率。
T < 1 (如 0.5):确定性、保守
- 数学作用: 除以一个小于1的数,相当于放大了原始分数(logits)。高分的 token 会获得指数级更高的概率,低分的概率则被进一步压低。
- 效果: 概率分布变得“尖锐”。模型基本只会选择最高概率的那个 token,输出变得极其确定和稳定,适合需要精确答案的代码生成或数学推理任务。
T > 1 (如 1.5):多样性、创造性
- 数学作用: 除以一个大于1的数,相当于缩小了原始分数(logits)之间的差距。高分的优势被稀释,低分 token 的涌现概率相对提升。
- 效果: 概率分布变得“平滑”。模型有更大的“勇气”去尝试那些原本概率较低的词汇,生成结果更加多样、有新意,适合故事创作或头脑风暴。
截至目前,运维视角的GPU基础认知
截至目前,我们还有很多知识点未学习(位置编码、残差连接、前馈神经网络FFN等),也暂未深入探讨GPU架构的底层细节,但了解了本文后,从运维角度,有几个 GPU 基础概念需要建立:
- 并行计算优势:GPU 擅长矩阵运算和向量运算,Transformer 本质上是海量矩阵乘法,因此天然适合 GPU 运行。
- 显存与内存的关系:GPU 显存(VRAM)与系统内存(RAM)物理隔离。高性能 HBM 直接与 GPU 核心封装在一起,NVIDIA H100 的 HBM3 带宽可达约 3.35 TB/s。
- PCIe 是瓶颈:GPU 与 CPU 之间通过 PCIe 通信,即使 PCIe 5.0 x16 带宽也只有约 128 GB/s,与 HBM 带宽相差超过一个数量级。因此模型权重与 KV Cache 必须尽量常驻显存,一旦发生换页,推理性能会急剧下降。
- 多 GPU 场景:当单卡放不下模型时,需要使用 NVLink、张量并行、流水线并行等技术,让多个 GPU 共同完成推理或训练任务。
对于大模型运维工作以及相关认证学习而言,真正需要重点掌握的是:Transformer 的 Q/K/V 与 Attention 原理、KV Cache 的生成机制与显存计算、FP16/BF16/INT8 等精度体系、MHA/MQA/GQA 对显存的影响,以及 GPU 显存、HBM、PCIe、NVLink 等基础架构。
理解这条链路后,后续学习 vLLM、TensorRT-LLM、SGLang、分布式推理与 GPU 调优时,就会顺畅很多。
GPU 与硬件架构
在了解了当前基于 Transformer 技术的基础原理后,我们来看下 GPU 硬件及其生态、单机多卡、GPU 排查 与 GPU 共享/虚拟化 相关的技术概念。
相关概念较多,建议按这条主线理解:
1 | |
GPU 单卡内部结构
这一部分先回答一个问题:GPU 内部到底由哪些计算单元组成?
CUDA 核心
GPU 里的通用“小工”,一个时刻只能算一个数。成百上千个 CUDA Core 可以一起并行处理大量简单的加减乘除,是 GPU 并行计算的基础。
张量核心(Tensor Core)
专门为 矩阵乘法 而生的“特种部队”,一个指令周期内能完成一个 4x4 矩阵的乘加运算。
Attention 机制中的 Q/K/V 计算本质上就是矩阵乘法,因此 Tensor Core 能大幅加速大模型训练和推理。
内存墙:指计算单元(如 Tensor Core)的处理速度远快于内存系统供给数据速度的现象。此时瓶颈通常不是“算不动”,而是“数据喂不够”,即 带宽压力 远大于 容量压力。
SM(Streaming Multiprocessor)
SM 包含若干 CUDA Core、若干 Tensor Core、调度器、寄存器文件和 L1 缓存。它负责调度和执行线程块(Thread Block)。
一个 SM 可以同时运行多个线程块,各 SM 之间并行工作,共同完成整个 Kernel 的计算。
GPU 总 CUDA 核心数通常可以这样理解:
1 | |

GPC 与 TPC
在理解 SM 这个最小计算执行单元之后,还需要理解它上面的硬件组织层级。
GPU 动辄上百个 SM,如果每个 SM 都直接由上层统一调度,会产生很大的管理开销。就像管理一个国家不可能直接指挥每个村庄一样,GPU 的硬件架构也引入了中间管理层级。
- GPC(Graphics Processing Cluster,图形处理集群):NVIDIA GPU 中较高层级的硬件分区,可以理解为一个“省”。每个 GPC 内部包含完整的几何处理、光栅化、纹理映射以及计算流水线,可以独立处理一部分任务。
- TPC(Texture Processing Cluster,纹理处理集群):GPC 内部的中间层,可以理解为“市”。每个 TPC 通常包含若干 SM(常见为 2 个,少数架构为 3 个),以及共享的纹理缓存和调度逻辑。
- SM(Streaming Multiprocessor,流式多处理器):真正的执行单元。每个 SM 包含 CUDA Core、Tensor Core、寄存器文件、L1/共享内存、Warp 调度器等。
典型层级结构如下:
1 | |
这个层级结构对运维和性能调优很关键。例如,当 nvidia-smi 中看到某个 GPU 利用率不满时,问题可能不在单个 SM 层面,而是任务在 GPC/TPC 之间分配不均,或者上层并行策略导致部分硬件区域空闲。
实际排障中,虽然没有直接查看 GPC/TPC 利用率的通用命令,但可以通过 Nsight Systems、Nsight Compute 等性能分析工具观察 Kernel 执行时是否存在调度、同步或访存瓶颈。
可以粗略记成:GPC 管辖区划,TPC 协调小组,SM 冲锋陷阵。
从计算单元到存储层级
理解 SM、GPC、TPC 之后,还需要知道数据如何在 GPU 内部流动。
下面这张 NVIDIA 白皮书中的 GPU 硬件结构图,把关键部件一次性展示了出来:

从这张图里,可以把 GPU 拆解成三大块:
- 计算单元:GPC -> TPC -> SM
- 存储层级:寄存器 -> L1/Shared Memory -> L2 -> HBM
- 对外接口:PCIe、NVLink / NVSwitch
寄存器 -> L1 -> L2 -> HBM
| 层级 | 位置 | 容量(H100 为例) | 延迟 | 控制方式 | 与大模型的关联 |
|---|---|---|---|---|---|
| 寄存器 | SM 内部,线程私有 | 每 SM 64K 个 32-bit 寄存器 | 约 1 周期 | 编译器分配 | Kernel 寄存器用量直接影响 SM 占用率 |
| L1 / Shared Memory | SM 内部,线程块共享 | 256 KB / SM(可配置) | 约 30 周期 | Shared Memory 手动控制,L1 自动 | FlashAttention 利用它做分块,减少 O(N^2) 显存访问 |
| L2 缓存 | 全芯片共享 | 约 50 MB | 约 200 周期 | 全自动 | 跨 SM 数据复用;对程序员不透明但性能敏感 |
| HBM | GPU 封装内,芯片外 | 80 GB(H100) | 约 500 周期 | 显式分配 | 主显存:存放模型权重、KV Cache、激活值 |
关键补充:
- L2 缓存与内存控制器直连,所有 HBM 读写请求通常都会先经过 L2 缓存。
- GigaThread with MIG Control 是硬件线程调度器,负责把线程块分配到空闲的 GPC/SM。
- MIG(Multi-Instance GPU) 会把一颗 GPU 物理切分为多个独立小 GPU,每个实例拥有专属的计算资源、L2 切片和 HBM 通道。
- HBM3 memory controller 负责管理 HBM 的读写时序和 ECC,它的数量通常与 HBM 堆栈/通道设计相关。
高带宽内存(HBM)
HBM 通过 堆叠 多个 DRAM die,并利用 硅通孔(TSV) 垂直连接,最后与 GPU 芯片整合在同一封装基板上。
它的核心优势在于 位宽极大(1024 到 2048 bit),而不是单通道频率极高。
| 内存类型 | 位宽(bit) | 核心策略 | 典型带宽(单卡) | 主要用途 |
|---|---|---|---|---|
| HBM | 1024-2048 | 建更多通道(路宽) | 1.2-2.0 TB/s | AI 训练/推理、超算 |
| GDDR6X | 32 | 提高车速(频率高) | 0.8-1.0 TB/s | 游戏显卡 |
| DDR5 | 64 | 平衡通用性 | 约 0.1 TB/s | PC/服务器主内存 |
HBM 成本高、封装复杂、产能紧张。AI 芯片需求增长后,也会间接影响普通 DDR5 内存市场价格。
PCIe 与 NVLink
- PCI Express:GPU 与 CPU 之间的主通道,负责加载模型、传输训练数据、host 端命令下发等。PCIe 5.0 x16 单向带宽约 64 GB/s,双向约 128 GB/s,远低于 HBM 带宽。
- NVLink / NVSwitch:多卡直连的高速互联技术。NVLink 可以绕过 PCIe,在 GPU 之间建立高带宽、低延迟的直连通道;NVSwitch 则负责把多条 NVLink 汇聚成多 GPU 全互联拓扑。
运维提示:
1 | |
通过该命令可以查看 GPU 之间的连接拓扑,判断 GPU-GPU 通信走的是 NVLink、PCIe,还是跨 CPU Socket 的路径。
单卡排查要点
这一部分先总结单卡内部结构带来的排查思路。
nvidia-smi的GPU-Util字段主要反映 SM 活跃度,不等于 GPU 整体负载。- 如果 SM 利用率低但显存带宽跑满,通常是“内存墙”问题,也就是计算单元在等数据。
- 如果显存占用高但 GPU-Util 为 0%,在大模型推理场景中可能只是模型已经加载、当前没有请求。
- 实时观察建议使用
nvidia-smi dmon,而不是只盯着一次性的nvidia-smi输出。
常用命令:
1 | |
HGX 与 SXM:多卡系统级硬件平台
以上讨论的是 GPU 芯片内部结构。实际部署时,GPU 还需要被封装、互联并安装到服务器中。
这里引入两个关键概念:SXM 和 HGX。
SXM(Server PCI Express Module)
SXM 是 GPU 的一种 高密度扣卡封装形态,专为数据中心设计。与常见 PCIe 插卡不同:
- SXM GPU 直接“平躺”安装在基板上,通过底部高密连接器与 NVSwitch、HBM 等通信。
- 支持更高功率,例如 H100 SXM 可达 700W,而同核心 PCIe 版本通常为 300-400W。
- NVLink 带宽更高,例如 H100 SXM 双向带宽可达 900 GB/s。
HGX(NVIDIA 多 GPU 基板平台)
HGX 是一种 集成多颗 SXM GPU 的基板平台,通常包含 4 或 8 颗 GPU,并板载 NVSwitch 芯片,实现 GPU 间全互联。
例如:
- HGX H100 8-GPU 基板:8 颗 H100 SXM GPU + 4 颗 NVSwitch 芯片,任意两颗 GPU 间可通过 NVLink/NVSwitch 通信。
- HGX B200 基板:8 颗 B200 SXM GPU + NVSwitch,带宽进一步提升。
NCCL 初始化时检测到的 NVLink 连接,正是建立在 SXM GPU 通过 HGX 基板上的 NVSwitch 物理拓扑之上。
如果使用 PCIe 版本 GPU(如 H100 PCIe),则无法享受 HGX/SXM 平台的全互联带宽,NCCL 只能走 PCIe P2P 或更慢路径。
SXM、HGX、PCIe 的关系
原文中 “SXM 架构” 和 “HGX 架构” 容易混在一起。更清晰的说法是:
- PCIe:一种 GPU 插卡形态和主机互联方式。
- SXM:一种高密度 GPU 模块封装形态。
- HGX:把多颗 SXM GPU、NVSwitch、基板、电源与散热设计组合起来的服务器 GPU 平台。
因此它们不是完全并列关系:SXM 是模块形态,HGX 是多 GPU 平台,PCIe 是另一种更通用但带宽较低的插卡形态。
多卡硬件排查要点
1 | |
排查注意:
- HGX 基板通常需要运行 NVIDIA Fabric Manager 服务来初始化 NVSwitch 拓扑。
- 如果 Fabric Manager 未正常运行,
nvidia-smi topo -m可能显示不全,NCCL 也可能降级。 - 新一代 SXM 规格随 GPU 代际演进:H100/H200 使用 SXM5,B200 使用 SXM6,不同规格不兼容。
nvidia-smi 排查主线
nvidia-smi(NVIDIA System Management Interface)是 NVIDIA 驱动自带的命令行工具,用于查询和配置 GPU 设备状态,能提供温度、利用率、显存使用、功耗等关键信息。
它底层通过 NVML(NVIDIA Management Library)API 与 GPU 驱动交互,上层提供命令行接口和结构化输出格式,既能独立运行,也可被 Prometheus、Grafana 等监控系统集成。
基础查询:先看整体状态
1 | |
常见字段含义:
| 字段 | 含义 | 运维关注点 |
|---|---|---|
| GPU | GPU 编号,从 0 开始 | 多卡场景下明确操作哪张卡 |
| Name | GPU 型号,如 L20、H100 SXM | 确认硬件规格是否符合预期 |
| Temp | GPU 温度 | 持续高温可能触发降频 |
| Perf | 性能状态,P0-P12,P0 最高 | 有负载但仍为 P12 需排查 |
| Pwr:Usage/Cap | 当前功耗 / 功耗上限 | 接近上限时可能触发 power throttling |
| Memory-Usage | 已用显存 / 总显存 | 接近总量是 OOM 前兆 |
| GPU-Util | SM 单元活跃周期占比 | 不等于整体负载 |
| Compute M. | 计算模式 | 多租户场景关注共享/独占设置 |
nvidia-smi -l 1 是内置采样机制,比 watch -n 1 nvidia-smi 更直接,也更适合观察短周期变化。
GPU-Util:最容易误读的指标
很多刚接触 GPU 运维的人看到 GPU-Util 显示 0%,第一反应是“GPU 没干活”。这是常见误区。
GPU-Util 统计的是采样周期内 SM 有 Kernel 执行的时间百分比。它只代表计算单元是否在干活,不代表整体负载。
以下几种场景中,SM 利用率可能很低甚至为 0,但 GPU 并不一定异常:
- 推理服务空闲:模型已加载到显存,但没有请求进来。
- 纯显存拷贝:数据在显存和系统内存之间搬运,SM 不参与,但 PCIe 带宽可能跑满。
- Tensor Core 密集型计算:部分场景下 Tensor Core 在干活,但 SM 利用率可能低估实际压力。
- CPU 成为瓶颈:数据加载、预处理过慢,GPU 一直在等数据。
结论:不要只看 GPU-Util,必须结合 Memory-Usage、Temp、功耗、进程列表和业务指标交叉判断。
实时监控:用 dmon 抓瞬时脉冲
推理负载经常是脉冲式的,单次 nvidia-smi 采样可能正好落在空闲区间。
nvidia-smi dmon 可以按时间序列周期性采样 GPU 状态,更适合记录负载曲线。
1 | |
-s 参数含义:
| 字母 | 含义 |
|---|---|
| p | 功耗(Power)和温度(Temp) |
| u | 利用率(SM、Mem、Enc、Dec、JPG、OFA) |
| c | 时钟频率(Mem / Proc clocks) |
| m | 显存、BAR1、受保护内存使用率 |
| e | ECC 错误、PCIe Replay 错误 |
| t | PCIe Rx/Tx 吞吐量 |
谁在用 GPU:排查进程占用
nvidia-smi 输出下半部分自带 Processes 列表,可以直接看到 PID、进程名和显存占用。
如果进程列表不全,例如崩溃后的残留上下文,可以从设备文件层面查找访问 GPU 的进程:
1 | |
拿到 PID 后进一步确认:
1 | |
结构化输出适合脚本和监控系统:
1 | |
多卡场景与拓扑排查
1 | |
在 HGX 多卡全互联架构下,NVLink / NVSwitch 是否生效会直接影响 NCCL 通信性能。
容器环境排查
容器环境下 GPU 排查比宿主机多一层抽象。容器内看不到 GPU,或者能看到但用不了,是高频问题。
第一步,确认宿主机 GPU 正常:
1 | |
第二步,确认容器内能看到 GPU:
1 | |
如果容器内报错 NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver,通常是容器启动时没有挂载 GPU 设备,或者 nvidia-container-toolkit 未正确配置。
第三步,验证框架是否真正使用 CUDA:
1 | |
如果输出 True 和 cuda:0,说明 GPU 确实可用。
推理场景排查速查表
| 现象 | 可能原因 | 排查命令 | 处理思路 |
|---|---|---|---|
| 显存占用高,GPU-Util 0% | 推理服务空闲,模型已加载无请求 | nvidia-smi,看进程列表 |
正常现象;若应有流量则检查请求是否到达 |
| 显存占用高,GPU-Util 偶尔跳高 | 正常推理的脉冲式负载 | nvidia-smi dmon -s u -d 1 |
验证请求触发时利用率是否瞬时上升 |
| GPU-Util 持续 > 90% | 计算密集型负载 | nvidia-smi dmon -s pucmt |
检查功耗和温度,确认未触发 throttling |
| Perf 显示 P12 但负载存在 | GPU 处于低功耗状态未唤醒 | nvidia-smi -l 1 |
观察是否随负载切换到 P0/P2 |
| 显存接近总量但 GPU-Util 低 | 大模型装载但无请求,或残留进程 | nvidia-smi + 进程列表 |
排查业务流量或清理残留进程 |
| 容器内看不到 GPU | 未挂载 GPU 设备或 toolkit 未配置 | 宿主机与容器内分别执行nvidia-smi |
检查--gpus 参数和 nvidia-container-toolkit |
精度格式确认
nvidia-smi 默认不显示当前运算精度。确认训练/推理是否使用了预期的 FP16、BF16、INT8 精度,通常需要:
- 查看框架日志中的精度设置信息。
- 通过显存占用规模估算:FP16 模型权重约为 FP32 的一半,INT8 约为四分之一。
- 使用
nvtop、框架 profiler 或nvidia-smi dmon观察带宽模式间接推测。
NCCL 到底让 GPU 数据走哪条路
大模型的多卡训练与推理,本质是让一群 GPU 协同工作。它们之间的“队内沟通”效率,直接决定算力集群的整体性能上限。
这一环节的核心技术链路,可以从硬件到软件逐层理解。
技术概念
- PCIe P2P(Peer-to-Peer):允许同一 PCIe 总线上的两个设备(如 GPU 与 GPU、GPU 与网卡)通过 DMA 直接交换数据,尽量绕过 CPU 和系统内存。
- NVLink / NVSwitch:为解决 PCIe 带宽瓶颈而生的 GPU 专用高速直连接口,提供远高于 PCIe 的点对点带宽与更低延迟。结合 NVSwitch,可在节点内构建 GPU 全互联网络。
- RDMA(Remote Direct Memory Access):跨节点通信技术。它允许一台服务器的数据绕过对方 CPU 和操作系统,直接传输到另一台服务器的目标内存区域。常见方案包括 InfiniBand 和 RoCE。
- NCCL(NVIDIA Collective Communications Library):位于应用层,是 NVIDIA 专为多 GPU 通信设计的集合通信库。它将底层 PCIe P2P、NVLink、RDMA 等能力统一抽象,为深度学习框架提供 AllReduce 等高性能集合通信原语。
通信机制对比
| 特征 | NVLink / NVSwitch | PCIe P2P | RDMA NIC / HCA |
|---|---|---|---|
| 路径类型 | GPU <-> GPU(通过 NVLink/NVSwitch) | GPU <-> GPU(通过 PCIe Switch) | GPU -> NIC/HCA -> 网络 -> 远端 GPU |
| 是否跨节点 | 否 | 否 | 是 |
| 是否需要 RDMA memory registration | 否 | 否 | 是 |
| 是否需要 peer access | 通常不需要显式关注 | 需要支持 peer access | 由 NIC/HCA 与驱动栈处理 |
| 是否可能 CPU staging | 通常否 | 可能,取决于拓扑与配置 | 可能,取决于实现与形态 |
| 典型场景 | 单机多 GPU,高带宽低延迟 | 单机多 GPU,通用连接方式 | 多机多 GPU,通过网络互联 |
NCCL 如何选择路径
NCCL 初始化时会根据 GPU 拓扑距离和可用硬件能力,为每对 GPU 选择通信路径。常见优先级可以理解为:
- 优先使用 NVLink / NVSwitch。
- 不可用则回退到同一 PCIe Switch 下的 P2P。
- 再退到跨 CPU Socket 的 PCIe 路径。
- 跨节点时走 RDMA 或 TCP。
同时,NCCL 提供 Ring 和 Tree 两种集合通信算法:
- Ring:更适合带宽敏感场景。
- Tree:更适合延迟敏感场景。
可通过环境变量手动指定:
1 | |
NCCL 排查要点
实际环境中,容器设备挂载、驱动能力、Peer access、HCA 绑定、IOMMU 设置等任何一环配置不当,都可能让理想路径退化为低速路径。
当怀疑 GPU 通信未走最优路径时,先看拓扑:
1 | |
再打开 NCCL 诊断日志:
1 | |
常用诊断环境变量:
| 环境变量 | 作用 |
|---|---|
NCCL_DEBUG=INFO |
打印 NCCL 初始化日志,观察通信路径选择 |
NCCL_DEBUG_FILE=/tmp/nccl_debug.log |
将日志输出到指定文件 |
NCCL_DEBUG_SUBSYS=INIT,GRAPH |
输出更详细的拓扑发现和路径决策过程 |
NCCL_P2P_DISABLE=1 |
强制禁用 P2P,用于对比是否因 P2P 导致异常 |
NCCL_IB_DISABLE=1 |
禁用 RDMA,回退到 TCP,用于定位 InfiniBand/RoCE 故障 |
NCCL_PROTO=Simple |
切换 NCCL 协议实现,可用于规避特定兼容性问题 |
NCCL_NET_GDR_LEVEL=5 |
控制 GPUDirect RDMA 启用级别 |
结合 nvidia-smi topo -m 与 NCCL 日志,可以快速判断实际通信路径是否符合预期。
GPU 共享技术 / 虚拟化
GPU 价值不菲,但很多时候根本用不满整卡。如果只能整卡直通或独占,算力利用率常常只有 30%-40%,剩下资源会闲置。
GPU 共享技术的核心目标是:把一张大卡切成多份,让多个任务同时运行,互不干扰。
目前主流方案可以分为三种:
| 方案 | 原理 | 隔离级别 | 适用场景 |
|---|---|---|---|
| MIG(硬件分区) | 物理切分,类似 GPU 的“硬盘分区” | 硬件级隔离 | 生产级多租户、关键推理 |
| vGPU / 时间切片 | 软件调度,类似 GPU 的“CPU 分时” | 软件级隔离 | 桌面云、开发测试、灵活超卖 |
| 整卡独占 | 一个任务占一整张卡 | 物理隔离 | 大模型训练、高性能要求 |
MIG(Multi-Instance GPU)
MIG 是 NVIDIA 从 Ampere 架构(A100)上推出的一项关键硬件能力。它允许将一块 AI GPU 从物理上切割成多个独立、隔离的小型 GPU 实例。
通过 nvidia-smi,一张 GPU 可划分为最多 7 个独立实例。每个实例拥有专属的 SM、显存、L2 缓存和硬件队列,彼此物理隔离。
核心优势:
- 性能可预测:邻居跑满也不会影响你。
- 故障隔离:一个实例崩溃不会拖垮整张卡。
限制:
- 切分规格固定,例如
1g.10gb、2g.20gb。 - 不能像软件虚拟化那样灵活超卖。
- 实例数量有上限,例如 H100 最多 7 个。
主流 GPU 的 MIG 支持情况:
| GPU 型号 | 微架构 | 最大 MIG 实例数 |
|---|---|---|
| GB200, B200, H100, H200, A100 | Blackwell / Hopper / Ampere | 7 个 |
| RTX PRO 6000 Blackwell(Server/Workstation) | Blackwell | 4 个 |
| RTX PRO 5000 Blackwell | Blackwell | 2 个 |
| RTX PRO 4500 Blackwell Server Ed. | Blackwell | 2 个 |
| A30 | Ampere | 4 个 |
常用命令:
1 | |
vGPU(虚拟 GPU)
传统虚拟化平台(如 VMware vSphere、KVM)通过软件模拟或分时调度,将一个物理 GPU 虚拟成多个 vGPU 分配给虚拟机。
特点:
- 灵活性高,支持一定程度的资源超卖。
- 实例数量多,通常可到 16-32 个。
- 性能受邻居影响。
- 可能引入约 10%-20% 性能开销。
MIG-backed vGPU(混合方案)
在 vSphere 等平台上,可以采用 先物理切分(MIG),再虚拟化分配 的方式:
- 用 MIG 将 A100/H100 切成多个 MIG 实例。
- 每个 MIG 实例通过直通(Passthrough)或 vGPU Profile 分配给独立虚拟机。
- 实现“硬件隔离 + 虚拟化调度”的组合。
该方案适合对隔离要求较高、但仍希望接入虚拟化平台统一管理的场景。
最终速查:按问题反推排查路径
| 问题 | 优先查看 | 下一步 |
|---|---|---|
| GPU 是否被识别 | nvidia-smi |
检查驱动、内核模块、容器 runtime |
| 显存是否被占满 | nvidia-smi 的 Memory-Usage |
查进程列表、模型大小、KV Cache |
| GPU-Util 为什么为 0 | nvidia-smi dmon -s u |
结合业务请求、显存占用、CPU 负载判断 |
| 多卡通信慢 | nvidia-smi topo -m |
开启NCCL_DEBUG=INFO 查实际路径 |
| NVLink 是否生效 | nvidia-smi nvlink -s、topo -m |
检查 Fabric Manager、驱动和硬件拓扑 |
| 容器看不到 GPU | 宿主机/容器内分别执行nvidia-smi |
检查--gpus、runtime、toolkit |
| 需要多租户隔离 | MIG / vGPU 支持情况 | 按性能隔离需求选择 MIG、vGPU 或整卡独占 |
GPU 设备与参数速查
外部资料: