阶段二 · 补齐系统基础

Chapter 03 · GPU / CUDA / 显存 / 并行基础

到这一章,你开始真正接触“为什么系统会慢”的底层来源。目标不是把你训练成 CUDA 内核工程师,而是建立足够可靠的硬件直觉:什么时候是算力问题,什么时候是显存容量问题,什么时候是带宽或通信问题,什么时候只是调度方式没有把设备利用起来。

时长 3-4 天
难度 L2 基础
先修
GPU 执行模型 显存与带宽 并行取舍

章节导读

大模型推理问题很容易被一句“GPU 不够强”糊弄过去。但工程上你必须继续追问:是权重装不下?是 KV Cache 占满显存?是带宽在搬数据时耗光了?还是算子和并行组织让设备闲着?这一章就是建立这种追问能力。

这一章真正要解决什么

建立足够实用的硬件执行模型,而不是追求底层实现细节本身。

学完应该会什么

至少能把算力、显存容量、显存带宽、卡间通信这四类资源分开理解。

阅读方式建议

不要试图一次记住所有 GPU 术语,重点是抓住“资源类型”和“系统症状”的对应关系。

本章目标

  • 建立 GPU 执行模型的最小认知:kernel、线程块、stream 是怎么帮助你理解推理执行的。
  • 理解显存容量与显存带宽为什么是两类不同且都重要的约束。
  • 知道并行不是“越多越快”,而是和切分、同步、通信、内存布局一起权衡。
  • 能把系统症状映射到更可能的硬件资源瓶颈上。

前置知识

必须知道

  • 推理最终要把模型计算落到具体硬件上。
  • 矩阵乘、注意力和缓存读写是常见的计算热点。
  • “性能问题”不等于“单一指标不够高”。

建议知道

  • 知道 GPU 和 CPU 在并行方式上有明显差异。
  • 知道多卡运行意味着会发生数据传输和同步。
  • 知道模型越大,对显存和带宽的要求通常越高。

这一章不要被什么吓到

  • 你不需要记住每个硬件参数。
  • 你不需要现在就去写内核。
  • 重点是建立推理系统的资源观,而不是做芯片课程。

正文主线

1. 从推理视角理解 GPU 执行模型

对推理系统来说,GPU 不是一个抽象的大黑盒,而是一组擅长大规模并行计算的执行单元。模型里的矩阵乘、注意力和归一化不会“自动快起来”,它们通常会被拆成很多 kernel 送到 GPU 上执行。你不需要马上理解每个硬件细节,但需要知道:系统最终是在安排大量小计算块怎样被并行组织起来。

因此,推理系统里的很多问题其实都能翻译成一个更底层的问题:这段工作是怎么被提交到设备上的?设备有没有足够多的并行工作可做?数据读写是不是成了瓶颈?这就是为什么 kernel、线程块、stream 这些词虽然底层,但对理解推理执行很有帮助。

2. CUDA 之于推理引擎,更像“执行接口和调度方式”

很多工程师听到 CUDA 会下意识想到“写底层代码”。但从推理系统学习角度,你更应该把它理解成 GPU 程序的执行接口和组织方式。推理框架、编译器、运行时最终都要借助这类接口把工作交给 GPU 执行。

这意味着即使你不自己写 CUDA,也最好知道它存在于系统哪一层:它连接的是“引擎想执行什么”和“GPU 实际如何执行”。后面当你看到算子优化、图编译或者高性能内核时,都会发现它们本质上是在改进这层连接。

3. 显存容量与显存带宽,是两类完全不同的约束

容量问题指的是:权重、激活、中间状态和 KV Cache 到底能不能放得下。带宽问题指的是:这些数据能不能足够快地被读写和搬运。你可能有一张显存足够大的卡,但如果带宽跟不上,推理依然会慢;也可能算力足够强,但权重和缓存装不下,系统根本起不来。

在 LLM 推理里,二者都极其重要。权重规模和高并发请求会持续吃显存容量;长上下文和缓存访问模式又会持续消耗带宽。所以你不能只盯着“多少 GB 显存”,也不能只盯着理论 FLOPS。

工程直觉

“装不下”先想容量;“装得下但不够快”先想带宽、访问模式和执行组织。

4. 并行是一种权衡,不是默认收益

模型大到单卡放不下时,你就会开始看到 tensor parallel、pipeline parallel 等概念。直觉上,“多卡一起干”似乎一定更快,但现实是:切分模型会引入更多通信、同步和调度成本。如果工作负载组织得不好,多卡未必比单卡更优。

所以并行设计本身就是一个系统问题:你为了缓解哪种压力切分?切分后带来的通信和同步成本能否接受?这个问题会在后面的部署与框架比较里反复出现。

5. 把硬件问题翻译成推理系统症状

当你看到“模型启动失败”“并发一高就 OOM”“吞吐很低但 GPU 利用率也不高”“多卡扩展不线性”这些症状时,本质上是在看硬件资源与执行组织的映射。学完本章后,你不一定能立刻修复问题,但应该已经能把症状归因到更合理的方向。

6. 单卡、多卡、跨机,其实是三个复杂度台阶

单卡问题主要集中在显存、带宽和内核效率;到了多卡,你还要考虑切分方式和卡间通信;跨机之后,网络拓扑、容错和更高层的服务编排也会一起进入问题域。所以“能不能扩更多卡”从来不是一道单一算力题,而是复杂度不断上升的系统题。

对入门学习来说,最重要的是先建立这三个台阶的意识。你可以暂时不深入每种并行策略的细节,但要知道每跨一个台阶,新增的成本类型是什么。

工程判断

先区分是“放不下”还是“跑不快”

显存容量和显存带宽是两种完全不同的限制,解决思路也不同。

  • 放不下先看权重、缓存和并发占用。
  • 放得下但慢,先看访问模式与带宽。
  • 不要用同一种优化去解决两类问题。

看到 GPU 利用率低,不代表算力过剩

很多时候设备不忙,是因为内存搬运、调度空洞或请求组织不足,而不是模型太轻。

  • 结合带宽、队列和 batch 一起看。
  • 看是不是没有足够并行工作填满设备。
  • 单看一个利用率指标很容易误判。

多卡不是默认答案

当问题还停留在单卡的缓存管理、内核效率或负载组织阶段时,盲目加卡往往只会把问题搬到通信层。

  • 先确认单卡瓶颈真的触顶。
  • 再评估并行带来的同步成本。
  • 最后再决定是否值得进入更复杂部署形态。

场景拆解

症状 容量 动作

模型能加载,但并发一高就 OOM

这通常不是“模型本身太大”这么简单,而是活跃请求叠加后,KV Cache 和中间状态把剩余显存迅速吃完了。

  • 先区分是权重常驻占用还是请求缓存占用。
  • 再看并发模式和上下文长度。
  • 这类问题后面往往会落到缓存管理和量化策略。
症状 通信 动作

从单卡切到多卡后,吞吐提升不明显

如果切分带来的通信和同步成本接近新增算力收益,就会出现“卡更多了,但收益没线性增长”的现象。

  • 先确认并行策略本身是否匹配模型和负载。
  • 再看卡间通信与拓扑限制。
  • 不要把扩卡视为天然的性能放大器。

图解实验室

这章最需要的是“资源约束能翻译成什么症状”的直觉。图里左列和右列按行一一对应。

硬件约束与系统症状映射图

先分清是哪类资源在限制系统,再决定后面该往容量、带宽、算子还是通信方向想。

硬件资源

左列是资源类型。

算力 单位时间能完成多少计算,决定热点算子有没有足够执行能力。
显存容量 决定权重、KV Cache 和并发请求到底能不能一起放下。
显存带宽 决定数据能不能足够快地被读取、搬运和写回。
卡间通信 决定多卡切分后的同步和交换成本高不高。

系统表现

右列是更容易看到的现象。

热点算子执行慢 GPU 型号不差,但热点 kernel 还是成为瓶颈。
加载失败或并发受限 模型能跑,但一提并发或上下文就直接顶到 OOM。
装得下但跑不快 利用率和时延表现异常,问题更像数据搬运和访问模式。
扩卡收益不线性 卡变多了,但同步和通信把新增收益吃掉了。
先区分两类大问题 “放不下”先想容量,“跑不快”先想带宽、算力和执行组织。
多卡会新增一层成本 一旦进入并行切分,通信就会成为单卡里没有的独立瓶颈来源。

关键表格与结论

资源 / 维度 它限制什么 推理系统常见症状 后续常见优化方向
算力 单位时间能完成多少计算 内核效率低、热点算子执行慢 算子优化、编译、融合内核
显存容量 模型、缓存、并发请求能否放下 加载失败、OOM、并发受限 量化、切分、缓存管理
显存带宽 数据能否足够快地被读取和写回 算力不低但推理仍慢 内存布局优化、减少搬运、IO-aware 内核
卡间通信 多卡之间同步和交换数据的代价 扩卡后收益变差、时延抖动 并行策略调整、通信压缩、拓扑优化

结论 1

推理快慢很少只是“GPU 型号”问题,更常见的是资源类型和工作负载组织不匹配。

结论 2

只知道模型参数量,不知道上下文长度、并发度和缓存策略,几乎无法判断真实硬件压力。

动手任务

任务 1:做一张“资源类型 → 系统症状”映射表

至少覆盖算力、显存容量、显存带宽、卡间通信四类。最低完成标准是:任意给你一个症状,你能先猜最可能是哪类资源在作祟。

任务 2:挑一张常见 GPU,整理它的关键参数

例如显存大小、带宽、是否适合多卡扩展。最低完成标准是:你能结合推理负载解释这些参数为什么重要,而不是只抄表格。

任务 3:写一段“为什么多卡不天然更快”的说明

至少提到切分、同步、通信这三个关键词。最低完成标准是:你不再把并行当作零成本扩展。

任务 4:为一个假想服务判断它更可能受哪种资源约束

场景示例:长上下文聊天、高并发短问答、单机本地推理。最低完成标准是:你的判断里要同时出现负载特征和资源特征。

阶段产出

产出 1

一张资源类型与系统症状映射表。

产出 2

一张你自己整理的 GPU 参数解释卡。

产出 3

一段关于并行成本的简要说明。

自测问题

  1. 1. 显存容量不足和显存带宽不足,各自更像什么样的系统症状?

    如果你能举出不同症状,说明资源观已经建立。

  2. 2. 为什么单纯看 FLOPS 不足以判断 LLM 推理表现?

    你的答案里至少应该出现缓存、带宽或数据搬运。

  3. 3. 多卡切分为什么会引入新的问题?

    如果你只说“更复杂”而没提通信和同步,说明还不够具体。

  4. 4. 你能否把“装不下”和“跑不快”区分成两类不同的问题?

    如果可以,后面学习优化时就更不容易误判。

推荐资料

官方文档

论文 / 技术文章

  • Paper FlashAttention

    适合用来感受“IO-aware”思路如何把注意力问题转成更贴近带宽和内存访问的优化问题。

源码入口

  • Source NVIDIA/TensorRT-LLM

    适合后面沿着硬件优化路线继续读高性能推理框架的实现方式。

  • ggml-org/llama.cpp

    适合观察跨 CPU / GPU / 本地推理路线的工程权衡。

实践建议

  • Practice TensorRT-LLM Overview

    适合提前感受“硬件平台特性和推理框架能力是如何耦合在一起”的。

常见误区

误区 1:把所有性能问题都归结成“GPU 不够好”

这会让你忽略带宽、缓存访问模式、算子实现和调度策略带来的巨大差异。

误区 2:把多卡当作零成本扩展

只要发生切分,就会伴随同步和通信,收益从来不是免费的。

误区 3:觉得不写 CUDA 就不需要懂硬件

你不必写内核,但必须知道问题大概率落在哪类资源上,否则优化阶段会一直漂在表面。

下一章衔接

有了这层硬件直觉后,下一章会重新回到请求链路本身,解释 prefill、decode、sampling 和 KV Cache 在引擎里如何组成一个真实的状态机。这样你才能理解为什么缓存会成为后续调度与优化的核心。