执行摘要
- 一句话:降级 triton_kernels 到 v3.5.1 恢复 GPT-OSS 解码性能
- 推荐动作:此 PR 值得精读,尤其是
triton_kernel_moe_forward 中的路由分支选择(if use_legacy_triton_kernels and expert_map is None)展示了如何在不破坏新 API 的前提下回滚关键优化。设计上通过 import 时判断 API 版本来选择路径,是一种干净的兼容性模式。未来需要关注上游修复后如何平滑过渡回 v3.6.0+。
功能与动机
PR 正文指出,triton_kernels v3.5.1 → v3.6.0 的升级(#30525)以及路由重写(#38504)导致 GPT-OSS 模型解码性能从 307.4 tok/s 降至 230.1 tok/s。本 PR 旨在恢复该性能,同时保持对 v3.6.0+ 的兼容。上游性能回归已追踪至 triton-lang/triton#9969。
实现拆解
- 降级 triton_kernels 版本:修改 cmake/external_projects/triton_kernels.cmake,将默认标签从 v3.6.0 改为 v3.5.1,确保构建时拉取旧版本。
- 放宽 legacy 路径触发条件:在
gpt_oss_triton_kernels_moe.py 的启动块中,原先仅在 ROCm 平台当 SparseMatrix 导入失败时设置 use_legacy_triton_kernels = True,现在改为在所有平台上当导入失败时均激活 legacy 路径,并添加注释说明这是临时候选,等待上游修复(triton-lang/triton#9969)。
- 优化无 EP 时的路由:在
triton_kernel_moe_forward 函数中,当 use_legacy_triton_kernels 为 True 且 expert_map 为 None 时,直接调用 triton_kernels.routing.routing() 融合内核(一次 launch)完成 softmax、topk、bitmatrix 打包和路由元数据构建;否则回到通用路径(topk + pack_bitmatrix + routing_from_bitmatrix 三次 launch),通过 make_routing_data 组织数据。
- 兼容垫片:保留 v3.6.0+ 路径(通过
_patch_make_bitmatrix_metadata 修补 SparseMatrix 的元数据函数),确保使用系统级安装的 triton_kernels v3.6.0+ 时仍能正常工作。
- 测试调整:在
tests/kernels/quantization/test_mxfp4_triton_ep.py 中移除 pytest 参数化,仅保留 test_expert_map_remap 用例,聚焦 EP 路径的正确性验证(因为非 EP 路径改为使用融合路由,mock 不再适用)。
关键文件:
vllm/model_executor/layers/fused_moe/experts/gpt_oss_triton_kernels_moe.py(模块 MoE路由;类别 source;类型 core-logic;符号 use_legacy_triton_kernels, triton_kernel_moe_forward): 核心逻辑变更:实现 triton_kernels 版本选择、legacy 路径激活以及融合路由优化。
tests/kernels/quantization/test_mxfp4_triton_ep.py(模块 路由测试;类别 test;类型 test-coverage;符号 test_routing_path_selection, test_expert_map_remap): 测试适配:移除非 EP 路径的 mock 测试,专注验证 EP 下的 expert_map 重映射逻辑。
cmake/external_projects/triton_kernels.cmake(模块 构建配置;类别 infra;类型 configuration): 构建依赖版本控制:将默认 triton_kernels 标签从 v3.6.0 改为 v3.5.1,是降级的直接执行点。
关键符号:triton_kernel_moe_forward
关键源码片段
vllm/model_executor/layers/fused_moe/experts/gpt_oss_triton_kernels_moe.py
核心逻辑变更:实现 triton_kernels 版本选择、legacy 路径激活以及融合路由优化。
# Two API generations of triton_kernels are supported:
# - v3.5.1 (the version bundled with vLLM): exposes `routing()` and
# `routing_from_bitmatrix()` in triton_kernels.routing; the `Bitmatrix`
# constructor takes a `scratchpad` argument.
# - v3.6.0+: removes the `routing` module in favor of a `SparseMatrix`
# based path, and adds a `dtype=BIT` kwarg to `Bitmatrix`. Used only
# when the user has triton_kernels installed system-wide at v3.6.0+.
#
# `use_legacy_triton_kernels` selects between them at import time based on
# whether `SparseMatrix` is importable.
use_legacy_triton_kernels = False
if has_triton_kernels():
try:
import triton_kernels.swiglu
from triton_kernels.matmul_ogs import (
FnSpecs,
FusedActivation,
GatherIndx,
RoutingData,
ScatterIndx,
matmul_ogs,
)
from triton_kernels.tensor import (
BIT,
Bitmatrix,
)
try:
from triton_kernels.tensor import (
SparseMatrix,
make_ragged_tensor_metadata,
)
except ImportError:
# TODO(mgoin): drop the v3.5.1 pin and remove this fallback once
# the gpt-oss perf regression in v3.6.0+ is resolved upstream.
# Tracking: https://github.com/triton-lang/triton/issues/9969
use_legacy_triton_kernels = True
if not use_legacy_triton_kernels:
_patch_make_bitmatrix_metadata()
except (AttributeError, ImportError) as e:
logger.error(
"Failed to import Triton kernels. Please make sure your triton "
"version is compatible. Error: %s",
e,
)
评论区精华
风险与影响
关联脉络
- PR #30525 Bump triton_kernels to v3.6.0: 该 PR 升级了 triton_kernels 版本,是引入性能回归的根源之一。
- PR #38504 Rewrite gpt-oss routing path: 该 PR 重写了路由逻辑,丢弃了融合路由内核,是引入性能回归的另一原因。
- PR #39236 Alternative downgrade PR: 该 PR 是备选方案,采取了更小 diff 的方式恢复性能,但本 PR 选择了 deprecate v3.6.0 路径并保留兼容垫片。
参与讨论