简介
简介(未完成)
程序员必须了解的AI系统设计与挑战知识 硬件演进 ==> 软件演进 ==> 训练挑战 ==> 推理挑战。
硬件演进
从CPU为中心到GPU为中心。传统基础设施以 CPU 为核心,通过多线程和微服务构建分布式系统,处理高并发请求(如 Web 服务)。这些都有成熟的方法论了(如”海量服务之道”)。主要工作是逻辑事务的处理,瓶颈在网络 I/O 和 CPU 核心数量。而 AI Infra 以 GPU 为核心,其设计目标从逻辑事务处理转向高吞吐浮点计算。此时CPU 多线程被 GPU 并行计算替代,内存被显存替代。为什么 GPU 会成为核心?是因为 LLM 大模型每次生成一个 token,都需要读取全量的模型参数。传统的 CPU + 内存的算力和带宽无法满足如此恐怖的计算密度,计算和通信都必须转移(offload)到 GPU 内完成。CPU 成为数据搬运工和“辅助处理器”。为了更直观地理解这个计算密度,我们做一个简单的计算。不考虑计算的延时,LLM 大模型生成一个 token 的耗时公式计算为:计算耗时 = 模型参数 * 数据精度 / 显存带宽。以 DeepSeek-R1-671B-A37B-FP8 模型为例,计算一个 token 耗时,H20 为 37B × 1byte ÷ 4000GB/s = 9ms,如果是 CPU 则为 37B × 1byte ÷ 64GB/s = 578ms。传统 Infra 的分布式理念貌似在 AI 时代失效了。传统 Infra 追求横向扩展,而 AI Infra 呈现 “AI 大型机”特性,是因为传统后台服务的可以容忍毫秒级延迟,但 AI 集群不行,GPU 的算力是 CPU 的数百倍,微秒级的延时等待也会造成很大的算力损耗,需要硬件的高度集成。
软件演进
相比传统后台应用的增删查改,AI 应用的新范式是模型训练和推理。模型训练是指通过海量数据拟合出一个复杂的神经网络模型,推理就是利用训练好的神经网络模型进行运算,输入的新数据来获得新的结论。
- 工欲善其事,必先利其器。传统后台应用依赖 tRPC 或 Spring 等微服务框架,帮助我们屏蔽负载均衡、网络通信等底层细节,我们可以把精力放在业务实现上。与之相似,AI 应用则依赖深度学习框架。如果没有深度学习框架(比如PyTorch),我们就可能陷入在茫茫的数学深渊中,挣扎于痛苦的 GPU 编程泥潭里。得益于动态计算图、自动微分和丰富的 Tensor 操作算子,PyTorch 能帮助我们快速实现模型设计。只需要描述模型结构+待学习的网络参数,不需要关心数学计算和 GPU 编程的细节。
- GPU 编程。绝大部分的 AI 应用,的确不需要我们手写数学计算的 GPU 代码。但为了满足模型创新的需求,有必要学习 GPU 编程。例如 Meta 发布的 HSTU 生成式推荐模型,核心的 hstu_attn 计算,如果直接用 PyTorch 框架算子组合实现,则时间复杂度为 O(M * N²) ,其中 M 和 N 是一个数量级,相当于O(N³) 。但是通过自定义内核,可以优化到 O(N²)。
模型训练的挑战
PS: 类似传统infra的大数据
我们一直追求更大的模型,DeepSeek-R1 有数千亿参数,使用了数十万亿 token 的训练数据,涉及算力、存储、通信等多维度的工程挑战。有了 PyTorch 深度学习框架,只是 AI 应用落地的万里长征第一步。接下来我们将讨论深度学习框架之上的模型训练的挑战,即建设分布式 GPU 集群的原因。
- 存得下。
- 显存刺客:中间激活。在前向传播结束后出现一个显存占用(中间激活)的尖峰,远大于模型参数本身。
- 传统后台服务使用分片(Sharding)策略解决单机存不下的问题。与之相似,AI Infra 提出“模型并行”,就是将单个大模型拆分为多个子模块,并分布到不同 GPU 上协同工作,通过通信来共享数据。
- 算得快。简单的机器堆叠,算力不一定有线性的增长。因为分布式训练并不是简单地把原来一个 GPU 做的事情分给多个 GPU 各自做。需要协调多个 GPU 机器计算任务分配,GPU 机器之间的数据传输会引入网络IO和通信开销,降低训练速度。
- 通信计算重叠。传统后台服务我们通过多线程或异步 IO 避免阻塞 CPU 主线程,与之相似,AI Infra 提出通信计算重叠的方法论。GPU 编程模型中有流(stream)的概念,一个流表示一个 GPU 操作队列,该队列中的操作将以添加到流中的先后顺序而依次执行。不同流之间可以并行执行。那么通过令计算和通信操作加入不同的流中,可以做到二者的执行在时间上重叠。PS: 一个wrap阻塞了就跑另一个wrap?
模型推理的挑战
PS: 类似传统infra的高并发业务系统 主要是2个挑战:高吞吐(降本),低延时(增效,用户体验)。
- 降低延时。传统后台服务我们使用链接复用、缓存、柔性等技术降低系统响应时间。AI Infra 也有相似的做法。
- 在 GPU 编程模型中,CPU 和 GPU 是异构的,CPU 通过 API(例如 CUDA API) 向 GPU 提交任务,然后异步等待 GPU 的计算结果返回。GPU 收到任务后,会执行内核启动、内存拷贝、计算等操作。这个过程中,涉及到 CPU 与 GPU 之间的通信、驱动程序的处理以及 GPU 任务的调度等环节,会产生一定的延迟。模型推理需要执行大量重复的 GPU 操作,每个的 GPU 操作都要重复执行上诉环节,这些非核心的 GPU 开销会成倍数地放大,影响最终响应时间。在传统后台服务,我们使用 Redis 的 Lua 脚本封装多个 Redis 操作和计算逻辑,一次提交,减少网络开销。与之相似,AI Infra 利用 CUDA Graph 技术将多个 GPU 操作转化为一个有向无环图(DAG),然后一次性提交整个 DAG 提交到 GPU 执行,由GPU自身来管理这些操作的依赖关系和执行顺序,从而减少 CPU 与 GPU 之间的交互开销。
- KV Cache:空间换时间。
- 流式响应
- 提高吞吐量。实现 AI 应用的高吞吐本质上就是提高昂贵的 GPU 的利用率,让 GPU 单位时间能完成更多的任务。
- 传统批处理。其实传统后台服务也大量使用了批处理,例如 Redis 的 MGet 命令,单次请求就完成所有 key 的获取,将 N 次网络往返(RTT)压缩为1次。与之相似,模型推理的批处理就是将多个输入样本打包(batch),将原本串行的 N 次轻量的推理计算,合并为 1 次重量的计算,实现单位时间内处理更多的请求,提高了 GPU 利用率。传统批处理类似 “固定班次的公交车”:乘客(请求)必须等待发车时间(组建一个batch),发车后所有乘客同步前进。即使有乘客提前下车(短请求完成),车辆仍需等待所有乘客到达终点(长请求完成)才能返程接新乘客。传统批处理存在着资源浪费:GPU 要等待长请求处理完,不能处理新的请求而空闲。这个问题在 LLM 应用领域显得特别突出,因为不同用户请求 Prompt,模型的回答结果长度差异巨大,如果使用传统批处理,GPU 空闲率很高。这个本质上是个任务调度问题,传统后台服务我们使用工作窃取算法(work stealing)解决线程空闲问题,与之相似,AI Infra 提出“连续批处理”解决这个问题。
- 连续批处理。连续批处理类似“随时随地拼车的顺风车”,每辆车(GPU)在行程中可随时上/下客。新乘客(请求)直接加入当前车辆的空位(空闲计算单元),已完成的乘客立即下车(释放资源)。
显存管理技术的演进
- 虚拟化与按需分配: PagedAttention在请求长度高度不均、并发持续变化的服务负载下,把“为每个请求随序列增长而扩张的KV Cache”从粗放的预分配,变成可共享、可回收、可迁移的精细化资源,从而同时改善吞吐、TTFT与显存上限。PS:就好比linux即使有内存管理,也会有tcmalloc来提高内存管理效率。
- 结构化复用:在实际应用中,许多推理请求共享相同的前缀(Prefix),例如系统提示词(System Prompt)或多轮对话中的历史记录。SGLang框架引入的RadixAttention进一步扩展了显存管理的维度,它将KV Cache组织成一棵基数树(Radix Tree)。当新的请求到达时,系统会在树中进行最长前缀匹配。如果匹配成功,则直接复用已有的KV Cache,无需重新计算。
- 分层与分布式扩展:尽管PagedAttention优化了单卡显存的使用,但面对超长上下文(如1M+ Token),单机显存依然不足。此时,分层存储(Tiered Storage)成为必然选择。PrisKV和InfiniGen等系统提出将KV Cache卸载(Offload)到宿主内存(Host Memory)甚至NVMe SSD上。为了解决卸载带来的高延迟问题,PrisKV利用了RDMA(Remote Direct Memory Access)技术。通过构建一个分布式的、分层的KV存储池,PrisKV允许GPU直接通过PCIe和网络读取远程节点的内存,绕过CPU的干预。
注意力计算优化演进。在Transformer架构中,Attention算子的计算复杂度随序列长度呈二次方增长( ),且涉及大量的显存读写。
- 单卡优化:FlashAttention系列
- 灵活性提升:FlexAttention, 虽然FlashAttention性能强劲,但其代码实现极其复杂,且缺乏灵活性。一旦研究人员想要尝试新的Attention变体(如Sliding Window Attention, Document Masking, Tanh Soft-capping等),往往需要重新编写CUDA Kernel。为了解决这一问题,PyTorch团队推出了FlexAttention。
- 从单卡算子到多卡并行:长上下文的边界。当上下文长度超过单卡显存与计算的可承载边界时,Attention的主要矛盾会从“单卡内核效率”转向“如何切分序列、如何通信与重叠、如何在尾延迟约束下扩展并行度”。
调度与批处理:从动态批处理到PD分离。推理服务的端到端体验不仅由单次前向计算决定,还高度依赖于请求如何切分(Batching)与调度(Scheduling)。在解码阶段,若Batch过小会导致GPU利用率不足;若Batch过大或调度不当,又会导致Token间延迟抖动与队头阻塞。
- Static / Continuous / In-flight。
- PD分离架构
分与合:当模型规模、上下文长度或并发量超过单卡能力边界时,必须通过多卡协同扩展。 并行策略:TP/PP/DP/SP/EP。并行维度决定了“怎么切分”,但系统能否扩展、延迟是否稳定,往往取决于“怎么通信与同步”。推理系统中常见的通信形态包括:
- All-Reduce: TP/DP等场景常见,用于参数/激活的聚合。
- All-to-All: MoE(EP)与部分SP场景常见,用于重分布数据(如token到专家、QKV/Head的重排与交换)。
- 拓扑与介质: NVLink适合机内高带宽低延迟;RoCE/InfiniBand + RDMA适合跨节点直连;工程上常通过通信-计算重叠(overlap)来掩盖延迟。
软件栈
AI计算的开源技术栈:Kubernetes + Ray + PyTorch + vLLMAI计算的常见技术栈:Kubernetes + Ray + PyTorch + vLLM
- 训练与推理框架:在GPU上高效运行模型,包括模型优化、并行策略、模型定义和自动微分。
- 分布式计算引擎:在任务内调度作业、移动数据、处理故障、自动扩展工作负载、管理进程生命周期。
- 容器编排器:分配节点、调度整个作业、启动容器、管理多租户资源共享。
后训练目前以强化学习为中心,因其复杂性而引人注目。与常规训练相比,后训练结合了模型训练和模型推理。推理是为了生成额外的训练数据。模型推理通常与模拟器或代理环境交互。奖励模型对生成数据的质量进行评分。模型权重需要从算法的训练部分传输到推理部分,而rollouts 需要从生成部分传输回训练部分。因此,存在许多移动部件,分布式系统挑战更加艰巨。
汇总
教模型做事的成本太高,任何系统的可持续性,最终都得回归到单位经济模型(UE)。如果 Agent 创造的价值覆盖不了它消耗的成本,那么无论模型多么先进,这个系统在商业上都是不可持续的。当前 Agent 的门槛主要存在于数据与设施上。在 SFT(监督微调)模式下,,我们依赖人类专家来教模型做事。但在很多场景(比如GUI Agent让 AI 操作电脑界面这种高门槛任务中),这种依赖变成了难以承受的负担。 这反向逼迫行业必须转向 RL(强化学习)——让 Agent 在虚拟环境里自己试错、自我博弈,摆脱对昂贵人工数据的依赖。只有这样,才能把数据成本从”按人头算”变成”按算力算”,实现边际成本的下降。但是,RL 的门槛也不低。传统的工业级 RL 训练往往依赖庞大的算力集群。即使是经过优化的训练流程,仍然需要 16 张显卡(8 卡采样、8 卡训练)以及大量的 CPU 资源来支撑仿真环境。破局的关键是构建高仿真环境,让 Agent 通过自主探索产生海量交互数据,再通过设计有效的奖励信号,用 RL 训练出更强的策略。
- 光速的 GPU 算力,配上了龟速的操作系统。在传统的 RL 任务(比如下棋、打游戏)中,环境反馈是毫秒级的,步长短、速度快。但在 GUI Agent 场景下,Agent 执行一个动作——比如在虚拟机里点击 Excel 按钮——需要经历”虚拟机渲染→截屏→图像回传→视觉模型处理”的漫长链路。极高的延迟又进一步导致了计算资源的极度浪费——在传统的 RL 流程中,架构通常是紧耦合的。这意味着,当 GPU 在更新模型时,环境在等待;而当环境在采样数据时,GPU 又在空转。
- 环境的复杂度也呈指数级上升。不同于文本生成,GUI Agent 面临的是一个像素级(Pixel-level)的动作空间,理论上它可以在屏幕上的任意坐标进行点击或拖拽,这使得动作空间接近无限。这使得奖励极为稀疏。比如”将 Excel 内容打印为 PDF”这样的任务,Agent 需要连续执行几十个步骤。在这个过程中,环境往往一片死寂,不会告诉 Agent 中间某次点击是对是错,只有最后一步才能得到结果。
- 如何解决环境问题?
- 横向解耦:其核心逻辑是将采样端与训练端在物理上彻底分开。这也意味着,Agent 的 Infra 必须具备处理异步数据流的能力,而非传统的同步批处理,将训练过程转变成了一个持续流动的、高吞吐的流水线。
- 纵向解耦:降低算力门槛。开发模块化框架,将算法逻辑、模型架构与分布式引擎分离。
- 状态管理(Long Context vs 记忆)。当前大多数 Agent 依赖自然语言进行思维链推理,但自然语言在精确计算和状态追踪上有局限。Transformer 架构虽然强大,但它缺乏可读写存储器,无法显式地存储或更新中间的推理状态,也没有循环或递归机制。在处理简单问答时,这种无状态特性不是大问题;但在面对复杂的软件开发或长程逻辑推理时,这种缺陷是致命的。单纯拉长上下文窗口既不经济也不实用。一种思路是将其设计为file system 式的分层存储。当 Agent 需要回顾时,它执行的是读取文件的操作,而非在上下文窗口中大海捞针。 我们需要全新的基础设施,不是传统的云计算,而是专门为 Agent 设计的诸如异步训练框架、解耦的采样环境和向量化记忆文件系统之类的 Agent Native Infra。