斯坦福 CS336 从零开始的语言建模:推理引擎与全栈创新

推理:将电能转化为智能的引擎

推理是关键阶段,将训练好的语言模型从静态的数学对象(操作的有向无环图)转化为可用工具。理解底层的推理引擎和 GPU 内核对于“全栈创新”至关重要,因为这些组件决定了模型在生产环境中的实际效率、延迟和能力。

Token 的生命周期

当向推理系统发出请求时,它会遵循以下流水线:

  1. 调度: 请求被路由到特定的 GPU,可能在不同机器上分离预填充和解码操作。
  2. KV 缓存查找: 系统检查请求或其变体是否已出现,以节省计算。
  3. 执行: 核心机器学习代码被执行,通常根据模型规模在节点或 GPU 上并行。
  4. Token 生成: 系统输出 token,随后进行停止序列和安全检查的处理。

预填充 与 解码 工作负载

推理由两个截然不同的阶段组成,它们在计算特性上根本不同:

  • 预填充: 此阶段处理初始输入提示(例如 10,000 个 token),计算初始激活。它是 计算受限 的,类似于训练(没有反向传播),利用高 FLOPs。
  • 解码: 此阶段逐个生成 token。它是 内存带宽受限 的,因为必须从内存加载整个模型来生成单个 token,尽管所需 FLOPs 相对较少。

由于这些差异,现代系统通常将预填充和解码分离到不同的工作节点或专用硬件上(例如,使用 NVIDIA GPU 进行预填充,使用 LPU/Grok 芯片进行解码)。

生产挑战与系统优化

每日服务数万亿 token 会暴露出在小规模下不易发现的细微错误和瓶颈。这些包括由于内核错误导致模型无限重复 token 的“doom loops”,以及由于内核读取未初始化的 GPU 内存时的越界错误导致的意外语言切换(例如,从英语切换到中文)。

KV 缓存管理

为了最大化吞吐量,系统必须高效管理键值(KV)缓存。由于 GPU 内存受限,采用分层存储方式:

  • GPU 内存: 访问速度最快,空间最受限。
  • CPU DRAM: 较慢,用于卸载不常用的激活。
  • SSD/磁盘: 最慢,用于会话数据的长期存储。

这类似于经典的操作系统内存管理,通常采用最近最少使用(LRU)启发式算法决定将哪些激活驱逐到较慢的存储。

缓存感知的分离

一种简单但有效的优化是根据缓存命中率路由请求。将“新鲜”请求(缓存命中率低、预填充成本高)发送到一组 GPU,将“温热”请求(缓存命中率高、预填充成本低)发送到另一组 GPU,服务速度可提升至 40%。

Megakernels:实现“光速”推理

传统的推理引擎逐个执行操作(例如先执行 Norm 内核,再执行 MatMul 内核)。这会因内核启动开销和“尾部效应”导致显著的空闲时间,即 GPU 必须等待批次中最长序列完成后才开始下一操作。

Megakernel 方法

Megakernel 将多个操作融合为单个内核,将 GPU 视为大规模分布式系统而非顺序操作器。这使得操作可以重叠进行,例如:

  • 在 QKV 投影和 RoPE 缩放仍在运行时加载 KV 缓存。
  • 在注意力操作完全完成之前加载 O 投影的权重。

使用 ThunderKittens 库进行低层 CUDA 控制,Megakernel 可以实现接近“光速”的性能,在 H100 GPU 上达到最高 72% 的带宽利用率。

Parcae:稳定的循环架构

虽然大多数现有 LLM 通过增加参数和数据进行扩展,Parcae 研究探索通过 循环(对 transformer 块进行循环)进行扩展。

稳定性问题

朴素的循环 transformer 以不稳定著称,若学习率等超参数稍有调整就会出现损失尖峰和 NaN。这种不稳定性源于变换矩阵的谱半径;如果矩阵范数大于 1,激活在循环中会指数级爆炸。

Parcae 方案

Parcae 通过重新参数化循环系统的 A 矩阵和 B 矩阵来稳定训练:

  • 矩阵 A: 受限为负对角矩阵,以确保系统稳定,激活最终衰减而非爆炸。
  • 矩阵 B: 通过简单的线性范数进行控制。

此数学约束保证了稳定的损失曲线,使模型在每个参数上实现比传统 transformer 更高的质量。

循环的尺度定律

初步发现表明,循环应与数据和参数一起进行扩展。具体而言,随着训练数据量的增加,循环次数也应增加以保持计算最优性。这暗示对预训练进行循环可能在固定参数预算下产生更高质量的模型。

Sources