Prhub

#29664 [Diffusion] Reuse shared AlignedVector and tidy jit_kernel/diffusion

原始 PR 作者 BBuf 合并时间 2026-06-30 11:38 文件变更 10 提交数 1 评论 4 代码增减 +116 / -159

执行摘要

统一扩散 CUDA 内核向量化实现并清理冗余代码

KDA-Pilot扩散原生CUDA快速路径都需要128位向量化加载/存储。第一个落地的norm_scale_shift(PR#27392)已使用sgl_kernel/vec.cuh中的共享device::AlignedVector组件,但两个更新的内核(PR#29281, PR#29361)仍然手写自己的本地union。本PR使所有扩散CUDA内核复用共享AlignedVector,并合并了在审查其余jit_kernel/diffusion/时发现的一些小的、已验证的清理。无行为变更。

值得深度阅读,特别是对SGLang扩散内核或CUDA JIT内核感兴趣的开发者。PR展示了:

1) 如何通过提取公共组件消除重复代码;
2) 用SASS不变量验证重构无回退;
3) 清理死代码和参数简化。这些实践可在同类重构中复用。

讨论亮点

本PR无审查评论。作者在PR body中提供了完整的准确性测试结果(B200上所有扩散pytest通过)和性能基准表,并通过SASS指令对比(ncu)证明生成的二进制码与旧版几乎完全一致(指令数相同,仅有编译器调度差异),确认无性能回归。

实现拆解

  1. 提取公共工具函数:将 to_cute_argto_fake_cute_argsscale_residual_norm_scale_shift.pynorm_tanh_mul_add_norm_scale.py 中删除,统一添加到 utils.py,后续所有 CuTe-DSL 内核从同一处导入。

  2. 替换 Native CUDA 向量化结构:在 residual_gate_add.cuhcausal_conv3d_cat_pad.cuhtimestep_embedding.cuh 中,将手写的 union Vec16<T>union Packfloat4 分别替换为 device::AlignedVector<T, kVec>,并通过 load()/store()/operator[] 保持接口一致。

  3. 修复 copy_if 类型检查 bugnorm_tanh_mul_add_norm_scale.py@cute.jit 装饰的 copy_if 函数的条件 isinstance(src, Tensor) and isinstance(src, Tensor) 第二个应为 dst,本PR修正为 isinstance(dst, cute.Tensor)

  4. 删除死代码sana_wm_gdn.py_precompute_inv_rms 函数已被后续的 fused_qk_inv_rms Triton 融合内核取代,无调用者,直接删除;同时修复 docstring 中错误的模块名引用。

  5. 简化参数签名scale_shift.py_fused_scale_shift_4d_kernel 删除未使用的参数 rows 及其调用处;validate_weight_bias 删除未使用的 B/S 参数,仅保留必需的 D

  6. 添加命名空间timestep_embedding.cuh 添加 #pragma once 和命名空间 sglang_timestep_embedding,对应的 Python wrapper 中加上了命名空间前缀,使其与兄弟内核一致。

文件 模块 状态 重要度
python/sglang/jit_kernel/diffusion/cutedsl/utils.py 公共工具 modified 7.49
python/sglang/jit_kernel/diffusion/cutedsl/norm_tanh_mul_add_norm_scale.py 扩散内核 modified 7.55
python/sglang/jit_kernel/diffusion/cutedsl/scale_residual_norm_scale_shift.py 扩散内核 modified 7.94
python/sglang/jit_kernel/diffusion/triton/sana_wm_gdn.py 扩散内核 modified 6.43
python/sglang/jit_kernel/timestep_embedding.py 扩散内核 modified 5.39
python/sglang/jit_kernel/diffusion/triton/scale_shift.py 扩散内核 modified 4.54

关键符号

to_cute_arg to_fake_cute_args validate_weight_bias copy_if _precompute_inv_rms fused_norm_scale_shift fused_scale_residual_norm_scale_shift

关键源码片段

python/sglang/jit_kernel/diffusion/cutedsl/utils.py core-logic

新增公共工具函数 `to_cute_arg` 和 `to_fake_cute_args`,后续所有 CuTe-DSL 内核从 ** 此处 ** 导入,消除 ~36 行重复代码。

# 文件 : python/sglang/jit_kernel/diffusion/cutedsl/utils.py
from typing import Optionalimport cutlass
import cutlass.cute as cute
import torchWARP_SIZE = 32# 将 PyTorch dtype 映射到 CuTeDSL 类型
TORCH_TO_CUTE_DTYPE = {
    torch.float16: cutlass.Float16,
    torch.bfloat16: cutlass.BFloat16,
    torch.float32: cutlass.Float32,
}def to_cute_arg(
    t,
    *,
    assume_aligned: Optional[int] = 32,
    use_32bit_stride: bool = False,
    enable_tvm_ffi: bool = True,
):
    # 将 Python 值转换为 CuTeDSL 值
    if isinstance(t, torch.Tensor):
        return cute.runtime.from_dlpack(t, assumed_align=assume_aligned,
                                        use_32bit_stride=use_32bit_stride,
                                        enable_tvm_ffi=enable_tvm_ffi)
    if isinstance(t, int):
        return cutlass.Int32(t)
    if isinstance(t, float):
        return cutlass.Float32(t)
    return tdef to_fake_cute_args(t: torch.Tensor):
    # 将非最后维度替换为符号整数以最大化内核复用
    # 例 : (1,2,1536):(3027,1536,1) -> (?,?,1536):(?,?,1)
    if isinstance(t, torch.Tensor):
        D = t.shape[-1]
        dtype = TORCH_TO_CUTE_DTYPE[t.dtype]
        # 前 n-1 维用符号,最后一维保留真实值
        shape = (*(cute.sym_int() for _ in range(t.ndim - 1)), D)
        stride = (*(cute.sym_int(divisibility=D) for _ in range(t.ndim - 1)), 1)
        fake_t = cute.runtime.make_fake_tensor(
            dtype, shape, stride, memspace=cute.AddressSpace.gmem, assumed_align=32
        )
        return fake_t
    return to_cute_arg(t)
python/sglang/jit_kernel/diffusion/cutedsl/norm_tanh_mul_add_norm_scale.py bugfix

移除本地函数定义并改为从 utils.py 导入;修复 `copy_if` 中第二个 `isinstance` 错写为 `src` 的 bug(应为 `dst`)。

# 文件 : python/sglang/jit_kernel/diffusion/cutedsl/norm_tanh_mul_add_norm_scale.py
from typing import Optional, Tupleimport cuda.bindings.driver as cuda
import cutlass
import cutlass.cute as cute
import torch# 从公共工具导入,而非本地定义
from sglang.jit_kernel.diffusion.cutedsl.utils import (
    WARP_SIZE,
    to_cute_arg,
    to_fake_cute_args,
)# ... 其余导入和类定义 ...class NormTanhMulAddNormScale:
    # ...
    @cute.jit
    def copy_if(src, dst):
        # 修复 : 第二个 isinstance 的参数从 src 改为 dst
        if cutlass.const_expr(
            isinstance(src, cute.Tensor) and isinstance(dst, cute.Tensor)
        ):
            cute.autovec_copy(src, dst)
python/sglang/jit_kernel/diffusion/cutedsl/scale_residual_norm_scale_shift.py core-logic

移除本地复制的 to_cute_arg/to_fake_cute_args,改为从 utils.py 导入;简化 `validate_weight_bias` 签名,删除未使用的 B/S 参数。

# 文件 : python/sglang/jit_kernel/diffusion/cutedsl/scale_residual_norm_scale_shift.py
# 导入改为从公共工具获取 to_fake_cute_args,本地不再定义
from sglang.jit_kernel.diffusion.cutedsl.utils import (
    WARP_SIZE,
    to_fake_cute_args,
)def validate_weight_bias(t: Optional[torch.Tensor], D: int):
    # 验证 weight 或 bias 张量 : dtype, shape 和连续性
    if t is None:
        return
    if t.dtype not in (torch.float16, torch.bfloat16, torch.float32):
        raise ValueError(f'Validate failed: unsupported dtype: {t.dtype}')
    if t.shape != (D,):
        raise ValueError(f'Validate failed: unsupported tensor shape: {t.shape}.')
    if t.stride()[-1] != 1:
        raise ValueError(f'Validate failed: not contiguous on dim D.')

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

低风险。变更设计为行为保持(no behavior change),且通过多维度验证:

1) 所有相关pytest通过;
2) 基准测试与旧版持平;
3) SASS指令级对比未引入新指令或局部内存操作。潜在风险点包括:替换AlignedVector后对齐假设是否一致(已验证无差异);删除死函数可能影响未来复用(已确认无调用者);参数简化可能漏掉隐式使用(通过测试覆盖)。整体风险可控。

对用户无行为改变,推理结果一致;性能无回归,甚至因代码统一可能为未来优化奠定基础。对维护者,代码减少约160行,重复率降低,可维护性提升;新增公共工具函数降低了后续添加类似内核的门槛。对团队,展示了如何通过SASS不变量和基准测试系统化地保障重构质量。

核心路径重构 无行为变化 SASS 对比验证

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论