Prhub

#30117 Support Cutedsl BF16 GEMM JIT kernel

原始 PR 作者 b8zhong 合并时间 2026-07-07 10:16 文件变更 6 提交数 8 评论 5 代码增减 +1506 / -0

执行摘要

支持 Blackwell CuTe DSL BF16 GEMM JIT 内核

由于 FlashInfer 0.6.14 被 PyPi 限制,无法在预期时间内发布,因此需要提供独立的 CuTe DSL BF16 GEMM JIT 内核作为低延迟替代方案。该内核针对 Blackwell 架构进行了手动 warp 专业化和静态启发式优化,以接近 FlashInfer 的性能。

建议重点阅读以下设计:

  • CuTe DSL warp 专业化模式(7 warp 分工)如何降低延迟。
  • 静态战术表的设计流程:离线 autotune + Claude 启发式优化生成 29 种配置。
  • 后端注册与配置下发模式(server_args -> initialize_bf16_gemm_config -> 运行时分发)。
    此 PR 展示了完整的 JIT 内核集成范例,适合关注 Blackwell 优化的读者精读。
讨论亮点

Review 评论由 gemini-code-assist[bot] 提出,共 3 条,均未在合并前解决:

  • _detect_leading_dim 搜索方向应从右向左以避免错误识别大小为 1 的外层维度。
  • cta_n 验证应添加显式上限 256 检查以匹配硬件限制。
  • --bf16-gemm-backend 帮助字符串存在括号位置错误。
    PR 由 Fridge003 审核并合并,未见回复以上建议。

实现拆解

  1. JIT 内核模块:在 cutedsl_bf16_gemm.py 中实现 TgvGemmCuteExtKernel,使用 cute_ext 原语编写,支持 1CTA/2CTA 模式,共 29 种战术配置(tactic table),默认使用 tactic 1(64×8 stages=8)。
  2. 配置层server_args.py 添加 --bf16-gemm-backend 参数;unquant.py 新增 Bf16GemmBackend 枚举和 initialize_bf16_gemm_config() 初始化函数;scheduler.py 在启动时调用初始化。
  3. 未量化 GEMM 路径:在 UnquantizedLinearMethod.apply() 中新增 cutedsl 分支,当 backend 为 cutedsl 且满足硬件和数据类型条件时,调用 cutedsl_bf16_gemm JIT 内核替代默认的 F.linear
  4. DeepSeek-V2 适配deepseek_v2.pyprepare_qkv_latent 中,当 cutedsl 后端生效且 use_cutedsl_bf16_gemm 返回 True 时,跳过原有的 dsv3_fused_a_gemm 低延迟融合路径,避免重复优化。
  5. 测试覆盖:新增 test/registered/jit/test_cutedsl_bf16_gemm.py,通过参数化测试(M、N、K、bias)验证 384 种组合,注册到 CI(4-gpu-b200,30s)。
文件 模块 状态 重要度
python/sglang/jit_kernel/cutedsl_bf16_gemm.py JIT 内核 added 9.08
python/sglang/srt/layers/quantization/unquant.py 量化层 modified 8.19
python/sglang/srt/models/deepseek_v2.py 模型 modified 6.35
test/registered/jit/test_cutedsl_bf16_gemm.py 测试 added 6.23
python/sglang/srt/server_args.py 配置 modified 5.34
python/sglang/srt/managers/scheduler.py 调度器 modified 5.1

关键符号

get_tgv_cute_ext_tactic_num get_tgv_cute_ext_default_tactic WorkTileInfo TgvGemmCuteExtKernel.__init__ TgvGemmCuteExtKernel.__repr__ TgvGemmCuteExtKernel.__call__ TgvGemmCuteExtKernel.kernel Bf16GemmBackend initialize_bf16_gemm_config get_bf16_gemm_backend test_cutedsl_bf16_gemm prepare_qkv_latent

关键源码片段

python/sglang/jit_kernel/cutedsl_bf16_gemm.py core-logic

新增 CuTe DSL BF16 GEMM JIT 内核核心实现,包含 TgvGemmCuteExtKernel 类、战术配置表、warp 专业化调度。

# CuTe DSL TGV BF16 GEMM 内核 (sglang/jit_kernel/cutedsl_bf16_gemm.py)
# 
# 计算 : out[M, N] = x[M, K] @ weight[N, K].T (+ bias[N])
# 输入 / 输出均为 bf16, 内部 fp32 累加。
# 
# Warp 专业化 (256 threads/CTA, 8 warps, warp 3 空闲 ):
# - Warp 0: DMA_A (TMA 加载 A 矩阵 )
# - Warp 1: DMA_B (TMA 加载 B 矩阵 ; PDL 栅格依赖控制等待 )
# - Warp 2: MMA (tcgen05.mma 计算至 TMEM; 负责 alloc/dealloc)
# - Warps 4-7: EPILOG (TMEM -> RMEM -> bf16 转换 -> st.global)
#
# 战术配置表 : 共 29 种 ( 索引 0-28),按 use_2cta 分组。
# cta_k 固定为 128。
_TGV_CUTE_EXT_CTA_K: int = 128
_TGV_CUTE_EXT_DEFAULT_TACTIC: int = 1
_TGV_CUTE_EXT_TACTIC_CONFIGS = [
    # (cta_m, cta_n, num_ab_stage, use_2cta)
    # 1-CTA 配置 (use_2cta=False)
    (64, 8, 6, False), # 0
    (64, 8, 8, False), # 1 ( 默认 )
    (64, 8, 10, False), # 2
    (64, 8, 12, False), # 3
    (64, 16, 6, False), # 4
    (64, 16, 8, False), # 5
    (64, 16, 11, False), # 6
    (64, 32, 6, False), # 7
    (64, 32, 9, False), # 8
    (64, 64, 7, False), # 9
    (64, 128, 4, False), # 10
    (128, 8, 6, False), # 11
    (128, 16, 6, False), # 12
    (128, 32, 5, False), # 13
    (128, 64, 4, False), # 14
    (128, 128, 3, False),# 15
    # 2-CTA 配置 (use_2cta=True)
    (64, 16, 6, True), # 16
    (64, 16, 8, True), # 17
    (64, 16, 12, True), # 18
    (64, 32, 6, True), # 19
    (64, 32, 8, True), # 20
    (64, 32, 11, True), # 21
    (64, 64, 6, True), # 22
    (64, 64, 9, True), # 23
    (64, 128, 7, True), # 24
    (128, 16, 6, True), # 25
    (128, 32, 6, True), # 26
    (128, 64, 5, True), # 27
    (128, 128, 4, True), # 28
]
​
​
def get_tgv_cute_ext_tactic_num() -> int:
    return len(_TGV_CUTE_EXT_TACTIC_CONFIGS)
​
​
def get_tgv_cute_ext_default_tactic() -> int:
    return _TGV_CUTE_EXT_DEFAULT_TACTIC
python/sglang/srt/models/deepseek_v2.py data-contract

在 DeepSeek-V2 的 prepare_qkv_latent 中添加对 cutedsl 后端的感知,避免重复使用低延迟 fused GEMM 路径。

# 文件 : sglang/srt/models/deepseek_v2.py (prepare_qkv_latent 方法片段 )
def prepare_qkv_latent(self, hidden_states, forward_batch):
    # ... 前面逻辑 ...
    lora_active = getattr(self.fused_qkv_a_proj_with_mqa, "set_lora", False)
    cutedsl_backend = get_bf16_gemm_backend().is_cutedsl()
    if cutedsl_backend:
        from sglang.jit_kernel.cutedsl_bf16_gemm import use_cutedsl_bf16_gemm
    if (
        (not isinstance(hidden_states, tuple))
        and hidden_states.shape[0] >= 1
        and hidden_states.shape[0] <= 16
        and self.use_min_latency_fused_a_gemm
        and not lora_active
        and not (
            cutedsl_backend
            and use_cutedsl_bf16_gemm(
                hidden_states.shape[0],
                self.fused_qkv_a_proj_with_mqa.weight.shape[0],
                self.fused_qkv_a_proj_with_mqa.weight.shape[1],
            )
        )
    ):
        qkv_latent = dsv3_fused_a_gemm(...)
    else:
        qkv_latent = self.fused_qkv_a_proj_with_mqa(hidden_states)[0]
    return qkv_latent
python/sglang/srt/server_args.py configuration

新增 --bf16-gemm-backend 命令行参数,允许用户选择 BF16 GEMM 后端。

# 文件 : sglang/srt/server_args.py
BF16_GEMM_BACKEND_CHOICES = ["auto", "cutedsl"]class ServerArgs:
    # ...
    bf16_gemm_backend: str = Field(
        default="auto",
        help="选择未量化 BF16 GEMM 的后端。'auto' 使用 cuBLAS (默认), 'cutedsl' 使用 SGLang JIT CuTe DSL TGV BF16 GEMM (SM10X 专用)。",
        choices=BF16_GEMM_BACKEND_CHOICES,
    )

评论区精华

_detect_leading_dim 搜索方向应改为从右向左 正确性

当前从左向右搜索 stride-1 维度,可能错误识别大小为 1 的外层维度。建议改为从右向左搜索以避免误判。

结论:未在合并前解决。 · 待处理

cta_n 验证应添加上限 256 正确性

cta_n 验证仅检查下界和步长,未验证上限 256,可能导致编译或运行时错误。

结论:未在合并前解决。 · 待处理

--bf16-gemm-backend 帮助字符串括号位置错误 documentation

帮助字符串中括号位置错误,导致不匹配。

结论:未在合并前解决。 · 待处理

风险与影响

  • 核心路径变更unquant.py 的线性层和 deepseek_v2.py 的 fused attention 前向被修改,可能影响未启用 cutedsl 的其他场景(如 CPU、非 Blackwell GPU)。
  • 硬件依赖:内核仅编译于 SM10X(Blackwell),若在非 SM10X 设备上指定 cutedsl 后端会直接报错。
  • JIT 编译开销:首次调用需编译,冷启动延迟约 30 秒,后续缓存。
  • 未采纳的 review 意见_detect_leading_dim 可能对非连续张量误判,cta_n 超出 256 可能导致运行时崩溃。
  • 测试覆盖有限:K 值仅测试 2048/6144,未覆盖极端 shape 或非对齐情况。
  • 用户影响:Blackwell GPU 用户可通过 --bf16-gemm-backend cutedsl 启用低延迟 BF16 GEMM;默认行为不变(cuBLAS)。
  • 系统影响:新增 JIT 内核模块,首次编译约 30s;推理性能与 FlashInfer 相当(AIME25 91.25%)。
  • 团队影响:需维护 CuTe DSL 内核与 Cutlass 库的兼容性,未来 FlashInfer 解禁后可能切换。
核心路径变更 硬件依赖 JIT 编译开销 未采纳 review 意见 测试覆盖有限

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论