GPT-OSS 的第 0 天支持
通过采用 FP8、汇聚注意力和 MoE 优化来调整 ROSE,实现 H200 上 GPT-OSS 的第 0 天支持
Perplexity 致力于为追求准确、可靠答案及智能体操作的求知者提供最优的 AI 模型。OpenAI 最近发布了其开放权重模型(gpt-oss-20b 和 gpt-oss-120b)。与众多领先模型一样,Perplexity 是首批评估 gpt-oss-20b 和 gpt-oss-120b 的组织之一。
在本文中,我们将分享我们内部推理堆栈的基础设施决策,正是这些决策使得“第 0 天”(Day-0)支持成为可能。我们将重点介绍在 NVIDIA H200 GPU 上服务这些模型的细节,包括内核变更、部署方案以及速度与成本之间的权衡。
Hopper 架构上的 GPT-OSS
这些开放权重模型使用 MXFP4 量化技术发布,这有助于它们适应消费级硬件的内存,或在 NVIDIA Blackwell 上实现峰值吞吐量。然而,为了进行初步评估,我们希望在现有的 H200 Hopper 集群上运行它们,同时将推理引擎的更改降至最低。Hopper 架构没有 Blackwell 引入的专用 FP4 张量核心。因此,我们决定使用 FP8 精度来服务这些模型,以尽量减少对自定义内核的需求,并充分利用现有硬件资源。
从宏观层面来看,Transformer 大语言模型(LLM)的结构非常简单:
输入嵌入(Input embedding)
一系列 Transformer 层。每一层包含一个注意力模块,以及一个稠密 MLP 或稀疏 MoE 模块。
输出 Logit 投影
当部署一个新的 Transformer 模型时,我们主要关心它们与现有模型的匹配程度,从而确定所需的变更。OpenAI 提前分享了其模型概览,使我们能够相应地调整推理设置。我们发现该模型确实需要进行多次细微的调整。
注意力机制:具有注意力汇聚(Attention Sinks)的 GQA
每个注意力头都有一个预训练的汇聚参数,该参数会被纳入 Softmax 计算中
YaRN 位置编码,类似于 DeepSeek-V3
QKV 投影包含偏置,类似于 Qwen 2
输出投影包含偏置
MLP:稀疏混合专家(MoE)
SwiGLU 激活函数,与大多数开放权重模型不同
专家权重在 Top-K 之后进行 Softmax
专家模块包含偏置
考虑到参数数量预计在 100B 到 200B 左右,我们决定:
扩展 FlashInfer 以支持注意力汇聚
重用已为 DeepSeek-V3 系列模型构建的 MoE 实现
选择 FP8 128x128 块缩放作为量化方案,并扩展 DeepGEMM 内核以支持偏置项。
内部推理引擎
我们的推理工作由内部推理引擎 ROSE 提供支持。我们正将 ROSE 打造成一个灵活的框架,以便快速部署新模型。此外,一旦我们决定大规模服务某个模型,它就能提供一个优化并提升性能以达到行业领先水平的平台。
ROSE 提供了一个 LLM 引擎,该引擎能够加载模型,并通过多种解码器(包括推测解码和 MTP 解码器)为模型生成解码 Token。这些模型本身由一组自定义层组成,支持各种用于量化和并行的配置。在层级之下,它捆绑了 Triton 和 CUDA 内核,以高效地实现并融合各个层执行的计算。
ROSE 主要使用 Python 构建,并依赖 PyTorch 进行模型定义。虽然 Python 使我们能够保持灵活性并适应新模型,但我们正在将大部分对性能敏感的组件(如服务和批处理调度)迁移到 Rust。
为了部署新模型,我们首先定义模型层次结构并构建权重转换器。在处理完所有权重后,我们为最简单的 TP=1 用例定义前向传递,并确保其端到端运行正常。最后,在发布新容器并在集群上部署模型进行评估之前,我们实现并测试了各种形式的并行支持。随后,我们根据仪表盘和细粒度基准测试的反馈来迭代优化性能。
ROSE 对数值 Token 进行操作,除了集成测试外,对聊天格式几乎没有了解。与此同时,我们不得不研究调整周围的基础设施,以支持 Harmony 分词器并正确地将请求映射到输入 Token 序列。
对于 GPT OSS 模型,我们发现无需对解码器、CUDA 图框架或周围的基础设施进行任何更改,这使我们能够集中精力调整支持该模型的内核。
GPT-OSS 内核
汇聚注意力(Sink Attention)
汇聚注意力在 Softmax 之前引入了一个额外的偏置因子,该因子与 Q 和 K 的乘积进行累加:
attn = softmax(q @ k^T * sm_scale + sink) * V虽然简单的实现相当直观,但高效的注意力实现(例如 FlashInfer)会在独立的注意力头和 KV 序列长度上并行计算注意力。此外,为了数值稳定性,Softmax 是在线计算的,同时减去最大元素以保持数值稳定:
softmax(x) = e^x / sum(e^x) = e ^ (x - max(x)) / sum(e ^ (x - max(x))在线实现追踪一个运行中的最大值 m(初始化为 -inf)和一个缩放因子 d(初始化为 1)。通过将最大值初始化为当前头的汇聚值,我们确保它能被正确累加到 Softmax 中。如果注意力沿着序列长度被拆分为多个块,我们需要确保该最大值仅包含在第一个块中。
我们调整了 FlashInfer FA2 内核模板(用于预填充和解码),以包含汇聚参数。
MoE
不同模型的 MoE 层之间的主要区别通常在于路由方案。由于预计存在巨大的可变性,ROSE 在 Triton 中实现了此内核,使我们能够轻松地将其调整为适应新模型。在 GPT-OSS 的情况下,我们不得不调整权重评分,仅在 Top-K 所选专家之间进行 Softmax 计算,这与某些在所有专家之间计算 Softmax 的 DeepSeek 风格模型不同。我们发现,以 bfloat16 精度计算专家权重对于准确性至关重要。
MoE 层面临的挑战源于我们决定重用现有的 DeepGEMM 内核,而这些内核缺乏对偏置项的支持。幸运的是,随着时间的推移,我们与它们进行了深度集成,并做出了更改以更好地将它们与我们的自定义全对全(all-to-all)调度内核连接起来。我们通过将 WGMMA 累加器寄存器初始化为从内存加载的偏置值,为 DeepGEMM 添加了偏置支持。这是在处理 MN 块期间的一次性操作,因此其成本几乎可以忽略不计,且 L2 缓存确保了对这些值的高效访问。
由于这些模型无法从数据并行中直接获益,我们重用了仅限 TP 的调度和合并内核。输入到调度器的内容会在所有 Rank 之间复制,因此调度器会为本地可用的专家选择 Token。合并操作会通过 NVLink 执行加权累加。
性能调优
尽管我们的目标是快速部署模型,但我们仍希望确保性能合理。在对照 OpenAI 提供的参考实现验证了正确性后,我们使用默认的 PyTorch 分析器对实现进行了性能分析,重点关注内核间的块和线程分配。我们重用的功能是为隐藏维度较大(7168)的模型构建的,远大于 GPT-OSS 模型的 2880。我们专门定制了内核启动器以选择更好的网格维度,从而显著提高了吞吐量。
标记化与通道
Harmony 的聊天格式在构建对话、推理内容和函数调用方面有几个重要的概念。在此格式中,每条消息都由头部和内容组成:
<|start|>{header}<|message|>{content}<|end|>头部包含元数据——最重要的是角色(系统、开发者、用户、助手、工具)、通道以及接收者(例如在调用函数时使用 to=functions.<function-name>)。
通道(例如分析、评论和最终答案)使模型的输出更加透明和分段。由于该格式强制执行这种分离,模型可以透明地进行推理(并可被检查以进行调试),而不会将思维链泄露到生产环境中。接收者标签(to= 头部)会准确告知运行时哪个参与者应该接收下一个有效载荷——无论是函数、模型本身还是最终用户。
我们的推理引擎 ROSE 与格式无关。它接收一批输入 Token 并流式传回输出 Token。在我们的推理堆栈中,将输入格式化为 Token 化提示并将 LLM 结果解析回结构化消息的任务由专门的 JSON API 前端服务处理。我们通过向该前端添加一个新的可插拔格式化器/解析器来集成 Harmony,从而允许后端保持不变,同时前端整洁地管理聊天格式规则、函数调用和流式传输。这种关注点分离保持了架构的模块化,使得在极少修改后端的情况下就能快速采用新格式和响应功能。
成本与性能
鉴于 GPT-OSS 模型相对较小,我们将副本的部署限制在单节点内,以避免节点间通信开销。我们的实现支持专家并行(EP)、数据并行(DP)和张量并行(TP)的灵活组合。为了确定最佳部署设置,我们对各种批处理大小(从 1 到 128)下的分片策略组合进行了基准测试。得益于 预填充-解码解耦(Prefill-Decode Disaggregation),我们能够分别讨论预填充和解码的性能-成本权衡。
对于成本估算,我们假设 H200 的名义市场价格为 3.00 美元/小时(注:这不是我们实际的 GPU 价格)。
我们发现设置 batch_size=1 和 DP=1 可获得最佳的预填充性能。不同的 TP 配置在首字延迟和成本之间提供了不同的权衡。下表显示了各种配置和输入长度下的预填充延迟和每百万输入 Token 的成本。
GPT-OSS 120B:
输入长度 | 8192 | 32768 | 65536 | 128000 |
EP1 DP1 TP1 | 0.364s, $0.037 | 2.421s, $0.062 | 7.375s, $0.094 | 23.902s, $0.156 |
EP2 DP1 TP2 | 0.190s, $0.039 | 1.245s, $0.063 | 3.786s, $0.096 | 12.116s, $0.158 |
EP4 DP1 TP4 | 0.165s, $0.067 | 0.900s, $0.092 | 2.449s, $0.125 | 7.165s, $0.187 |
EP8 DP1 TP8 | 0.179s, $0.145 | 0.839s, $0.171 | 2.003s, $0.204 | 5.119s, $0.267 |
GPT-OSS 120B 在不同并行配置和输入长度下的预填充延迟和每百万输入 token 成本。
GPT-OSS 20B:
输入长度 | 8192 | 32768 | 65536 | 128000 |
EP1 DP1 TP1 | 0.239s, $0.024 | 1.610s, $0.041 | 4.895s, $0.062 | 16.037s, $0.104 |
EP2 DP1 TP2 | 0.127s, $0.026 | 0.833s, $0.042 | 2.522s, $0.064 | 8.143s, $0.106 |
EP4 DP1 TP4 | 0.108s, $0.044 | 0.593s, $0.060 | 1.616s, $0.082 | 4.766s, $0.124 |
EP8 DP1 TP8 | 0.116s, $0.094 | 0.547s, $0.111 | 1.310s, $0.133 | 3.365s, $0.175 |
GPT-OSS 20B 在不同并行配置和输入长度下的预填充延迟和每百万输入 token 成本。
对于解码,我们发现 EP4 DP1 TP4 是大多数情况下的最佳配置。下方的四个图表展示了 120B 和 20B 模型在序列长度为 8192 和 32768 时,解码速度与每百万输出 Token 成本之间的权衡。
我们还考虑将较小的 20B 模型用作较大 120B 模型的 推测解码 草稿模型。然而,由于激活的参数数量相似(3B 对 5B),由此产生的速度提升微乎其微。
参考资料
FlashInfer:用于 LLM 推理服务的高效且可定制的注意力引擎
OpenAI Harmony 响应格式 | OpenAI Cookbook
引用
@online{perplexity2025GptOssOnDay0,
author = {{Perplexity} and Nandor Licker and Lequn Chen and Vladimir Zaytsev and Kevin Hu and Lauren Kolm and Jesse Dwyer},
title = {{GPT-OSS on day 0}},
date = {2025-08-08},
url = {https://www.perplexity.ai/hub/blog/gpt-oss-on-day-0}
}