CUDA系统拆解-12-面试总复盘:怎么把 CUDA 能力连接到 AI 推理

本文是「CUDA系统拆解」系列第 12 篇。
系列导读:CUDA系统拆解-00-导读:从编程模型到 AI 推理系统的学习路线
上一篇:CUDA系统拆解-11-经典CUDA算子模式:elementwise、reduction、reorder 与 blocked compute
下一篇:CUDA系统拆解-13-面试强化专题:PTX、Tensor Core、CUTLASS 与 Triton 怎么讲

1. 这篇解决什么问题

  • 学到这里,你到底应该具备哪些能力。
  • 为什么 AI 推理岗位会反复问 CUDA。
  • 怎样把前面学过的内容整理成 算子层 / 执行层 / 系统层 三层框架。
  • 看到一个慢算子、一个 kernel、一个框架设计时,怎样把它还原成 CUDA 问题。
  • 面试里怎样把 occupancycoalescingfusiongraphbatching 讲成一套完整的系统理解。

2. 先记住的核心结论

  • AI 推理优化的本质,不只是“算得快”,而是“算和搬,以及调度和资源管理一起做好”。
  • CUDA 在推理岗位里重要,不是因为大家都要求你手写复杂 kernel,而是因为大量系统问题最后都能还原成 CUDA 的代价模型。
  • 一套成熟的理解框架可以分成三层:算子层执行层系统层
  • 看到慢算子时,要能还原成:线程怎么分工、数据怎么流动、同步和 launch 开销在哪里、GPU 为什么没吃满。
  • 面试真正想听的不是 API 名字,而是你能不能说清楚:为什么这样设计、快在哪里、代价在哪里、边界在哪里。
  • 高水平回答一定带 trade-off,而不是只有结论。

3. 正文讲解

3.1 学到这里应该具备哪些能力

如果前面 11 篇你真的吃进去了,现在应该不只是“知道一些 CUDA 名词”,而是至少具备下面几种能力。

第一,看到一个 kernel,能快速判断它在干什么。

也就是能回答:

  • 一个线程负责什么
  • 一个 block 为什么这样切
  • 它更像 elementwisereductionreorder 还是 blocked compute
  • 主要瓶颈更像带宽、同步、算力还是 launch

第二,看到一个慢算子,能大致猜到问题可能在哪。

例如:

  • reduction 慢,可能是同步和局部合并路径不好
  • transpose 慢,可能是访存模式和 bank conflict
  • GEMM 慢,可能是 tile、复用或资源平衡不好
  • decode 慢,可能是 kernel 太碎、launch 太重、memory latency 太明显

第三,看到一个推理框架设计,能把它拆成底层代价问题。

例如:

  • continuous batching 在解决 GPU 吃不满
  • fusion 在减少 global memory traffic 和 launch overhead
  • paged attention 在做 KV cache 的内存组织和复用管理
  • CUDA Graph 在减少 CPU 反复 launch 的开销

如果你已经能做到这三点,说明你学到的不是“概念列表”,而是分析框架。

3.2 为什么 AI 推理岗位会问 CUDA

很多人会误以为:

我做的是推理系统,不是专职内核工程,为什么还要学 CUDA?

原因很简单:推理系统的大量核心问题,最后都能落到 CUDA。

推理系统关心的通常是:

  • 更低延迟
  • 更高吞吐
  • 更高 GPU 利用率
  • 更低显存占用
  • 更稳定的多请求并发

而这些目标背后,本质上都对应一些 CUDA 问题:

  • 延迟为什么高:kernel 慢、launch 太碎、同步太多、调度有空泡
  • 吞吐为什么上不去:GPU 没吃满、batch 不规整、copy / compute 没 overlap
  • 显存为什么吃紧:activation、workspace、KV cache 和 allocator 策略
  • GPU 利用率为什么不高:occupancy、stream 编排、request 调度、kernel 粒度

所以面试官问 CUDA,不是在确认你会不会 cudaMalloc,而是在确认:

你能不能把推理系统问题还原成底层执行和资源问题。

3.3 一套成熟的三层框架

我建议把前面的 CUDA 知识收束成三层。

算子层

  • 关注单个算子怎么实现、为什么快、为什么慢
  • 关键词通常是:线程映射、访存模式、shared memory、reduction、tiling、fusion

典型问题:

  • GEMM 为什么适合 tile 化
  • softmax 为什么是 reduction + elementwise
  • LayerNorm 为什么常常 memory-bound
  • attention 为什么经常受 KV cache 访问和中间数据流影响

执行层

  • 关注多个 kernel 和数据传输怎样组织
  • 关键词通常是:stream、异步拷贝、pinned memory、overlap、launch overhead、CUDA Graph

典型问题:

  • 为什么默认 stream 会把流水拉直
  • 为什么 decode 场景更容易暴露 launch 开销
  • 为什么 graph capture 对稳定重复路径有价值

系统层

  • 关注请求调度、显存管理、并发策略、多 GPU 协作
  • 关键词通常是:continuous batching、KV cache、paged attention、memory pool、通信重叠

典型问题:

  • 为什么 continuous batching 能提高吞吐
  • 为什么 KV cache 是推理系统里的核心状态
  • 为什么 paged attention 的关键是管理灵活性和访问代价之间的平衡

这三层最大的价值在于:

你可以把系统层问题一路拆到执行层,再拆到算子层。

3.4 算子层:看到慢算子时如何还原成 CUDA 问题

算子层的核心不是公式,而是代价模型。

以后看到一个算子,先问:

  • 它是 elementwisereductionreorder 还是 blocked compute
  • 它更像 memory-bound 还是 compute-bound
  • 中间结果主要留在寄存器、shared memory 还是频繁回写 global memory

几个最典型的推理映射:

Linear / MLP

  • 核心是 GEMM
  • 真正关键的是 tile、复用、shared memory、寄存器和 tensor core 路径

softmax / LayerNorm / RMSNorm

  • 本质是 reduction + elementwise
  • 常见问题是中间结果回写多、同步多、launch 太碎

attention

  • 本质是 GEMM-like 计算、reduction、reorder 和内存管理的组合
  • 真正难点常在数据流和 KV cache 访问,而不只是公式

所以当面试官问你一个算子为什么慢时,不要只说“复杂度高”,而要说:

  • 它在哪一层受限
  • 是算得慢还是搬得慢
  • 是复用不够还是 launch 太碎

3.5 执行层:为什么很多问题不是 kernel 本身慢

到了执行层,你要建立一个很重要的意识:

很多推理性能问题,不是单个 kernel 本身差,而是整条执行流水组织得差。

几个最典型的执行层因素:

stream

  • 本质是设备端的有序任务队列
  • 它决定哪些工作必须排队,哪些工作有潜在并发机会

异步拷贝和 pinned memory

  • 不是为了 API 好看
  • 而是为了让 H2D / D2H 与计算更容易 overlap

launch overhead

  • 在 prefill 这种大算子场景里往往不明显
  • 在 decode、小 batch、小 kernel 场景里会被迅速放大

CUDA Graph

  • 本质是在减少 CPU 反复提交稳定路径的成本
  • 适合稳定重复的执行图,不适合无限动态的一切场景

所以执行层最核心的提问方式是:

  • GPU 是慢在算,还是慢在等
  • 时间花在 compute、copy、sync,还是 host 调度
  • overlap 到底成立了没有

3.6 系统层:为什么推理系统设计本质上是资源管理

到了系统层,很多话题表面看已经不像 CUDA,但底层逻辑还是一样。

最典型的是 KV cache。

KV cache 的本质是:

  • 用显存换计算
  • 让 decode 不必重复算历史 token

但这立刻会引出系统级问题:

  • 显存怎么管
  • 请求进进出出时怎么避免碎片
  • 长上下文下怎么让访问仍可接受

paged attention 的重要性也在这里。
它真正解决的不是“分页”这个词,而是:

在动态请求和长上下文场景下,让 KV cache 更可管理、更可复用、更可扩展。

再比如 continuous batching。

它表面上是调度策略,底层本质却是:

  • 让 batch 不至于过稀
  • 让 GPU 一直有比较规整的活可做
  • 缓解 decode 阶段小步长、小并行度带来的资源浪费

所以系统层真正关心的是:

  • 工作怎么持续喂给 GPU
  • 显存和缓存怎么被长期管理
  • 通信、计算、copy、调度如何重叠

3.7 怎样把 occupancycoalescingfusiongraphbatching 连到推理系统

这一段是面试里最容易形成完整表达的地方。

occupancy

  • 不是性能分数
  • 在推理里它更像“延迟隐藏能力”的一个窗口
  • decode、小 batch、小 kernel 时更容易显得不够

coalescing

  • 不只是访存概念
  • 它会直接影响 KV cache 访问、layout transform、attention 读取效率

fusion

  • 不只是减少 kernel 数量
  • 更重要的是减少中间结果写回 global memory 的次数
  • 在 LayerNorm、softmax、bias、activation 一类链式算子里尤其关键

graph

  • 不只是“优化 launch”
  • 它在推理里真正有价值的场景是重复、稳定、可 capture 的路径

batching

  • 不只是把请求凑一起
  • 本质是在系统层维持更好的 GPU 利用率和执行规整性

如果把它们串起来,你就会发现:

推理优化本质上是在同时管理并行度、访存效率、执行流水和系统动态性。

这就是面试里最值得讲出来的“整体观”。

3.8 面试回答为什么不能停留在 API 层

很多人的回答最大的问题是:

  • 会报术语
  • 会背定义
  • 但没有代价模型

例如别人问:

  • 为什么 fusion 能快
  • 为什么 decode 难优化
  • 为什么 paged attention 重要

如果你只回答:

  • “因为减少 kernel 数量”
  • “因为 decode 更复杂”
  • “因为 paged attention 更适合长序列”

这种回答信息密度太低。

更好的回答必须包含三件事:

第一,它在解决什么问题。

第二,底层为什么会快或更稳。

第三,它的代价和边界是什么。

这就是为什么我一直强调:

面试回答重点应是代价模型和系统理解,而不是背 API。

3.9 一个通用的回答模板

以后你遇到任何 CUDA × 推理问题,都可以用下面这个模板组织:

第一步:先说它在解决什么问题。

例如:

  • fusion 在解决中间结果频繁回写和 kernel 过碎
  • continuous batching 在解决动态请求下 GPU 吃不满
  • paged attention 在解决 KV cache 管理和碎片

第二步:再说底层为什么有效。

例如:

  • 减少 global memory traffic
  • 提高数据复用
  • 减少 launch overhead
  • 让 overlap 更容易成立

第三步:说收益。

  • 更高吞吐
  • 更低延迟
  • 更稳的 GPU 利用率
  • 更低显存压力

第四步:说代价或边界。

  • 寄存器压力上升
  • 动态 shape 更难做
  • 实现复杂度更高
  • 管理更复杂

这套模板非常适合面试,因为它天然带工程感。

4. 和 AI 推理的关系

这一篇本身就是在把 CUDA 和 AI 推理直接连起来。

如果只用一句话概括:

AI 推理中的很多高性能设计,表面上是在做系统、算子和调度,底层本质上都可以还原为 CUDA 的三个核心问题:线程如何组织、数据如何流动、延迟如何隐藏。

更具体一点:

  • prefill 更像大算子吞吐问题
  • decode 更像小步长、强动态、memory latency 和调度问题
  • attention 是最好的桥梁,因为它同时包含 GEMM、reduction、重排、KV cache 和系统调度代价
  • 高水平推理优化,本质上是跨越算子层、执行层、系统层一起做 trade-off

5. 常见误区

  • 推理岗位不需要学 CUDA。不是,很多系统问题最后都能还原成 CUDA 代价模型。
  • 学 CUDA 就是为了手写复杂 kernel。不是,更重要的是能读懂底层代价和系统边界。
  • 面试只要会讲几个 API。不是,真正想听的是“为什么这样设计”。
  • fusion、graph、batching 是系统技巧,和 CUDA 没关系。不是,它们本质上都在管理执行和数据流。
  • occupancy 高、GPU 利用率高,就说明系统没问题。不是,QPS、首 token 延迟和 steady-state token latency 还取决于很多执行层和系统层因素。
  • paged attention 只是一个框架名词。不是,它背后是典型的显存管理与访问代价权衡。

6. 复习自测

  • 学到这里,你应该具备哪些能力?
  • 为什么 AI 推理岗位会反复问 CUDA?
  • 怎样用 算子层 / 执行层 / 系统层 三层框架去理解推理系统?
  • 看到一个慢算子时,怎样把它还原成 CUDA 问题?
  • 怎样把 occupancycoalescingfusiongraphbatching 连成一套系统理解?
  • 为什么面试回答重点应该是代价模型和 trade-off,而不是背定义?
  • prefill 和 decode 的瓶颈差异应该怎样讲?
  • 为什么说很多推理创新,本质上都是更懂 GPU 代价模型?

系列导航