Prhub

#49512 [CI] Use explicit devices in quantization tests

原始 PR 作者 AndreasKaratzas 合并时间 2026-07-24 00:54 文件变更 2 提交数 1 评论 0 代码增减 +22 / -20

执行摘要

量化测试显式指定设备,消除 fixture 副作用

Kernels Quantization Test 1 和 2 依赖全局 default device 状态,但 module-scope fixture 在参数化测试间重置导致 CPU 张量传入 GPU kernel,造成测试不稳定 (见 Buildkite 构建 #11147)。

可以直接合并。该 PR 虽小,但为解决 CI 不稳定提供了正确且简洁的方案,值得学习其对待全局 fixture 影响测试隔离性的处理方式。

讨论亮点

无 review 讨论。Claude bot 自动评论但因 fork 跳过,mgoin 直接 approve。

实现拆解

  1. 删除 module-scope fixture:在 test_int8_kernel.pytest_block_int8.py 中移除 setup_cuda fixture,该 fixture 通过 torch.set_default_device("cuda") 修改全局状态。
  2. 显式指定设备创建张量:在每个测试函数开头通过 device = current_platform.device_type 获取设备,所有 torch.randtorch.randn 等调用添加 device=device 参数。
  3. 保留参数化覆盖:测试参数化组合不变,仅改动张量创建方式,不影响测试语义。
文件 模块 状态 重要度
tests/kernels/quantization/test_int8_kernel.py 量化测试 modified 5.32
tests/kernels/quantization/test_block_int8.py 量化测试 modified 5.29

关键符号

setup_cuda

关键源码片段

tests/kernels/quantization/test_int8_kernel.py test-coverage

移除 module-scope fixture,测试张量显式指定设备,是解决测试不稳定的主要变更。

# 不再依赖 module-scope fixture,改为在测试函数内显式指定设备DTYPES = [torch.half, torch.bfloat16]
M = [1, 33]
N = [128, 1024]
K = [256, 4096]
E = [8]
TOP_KS = [2, 6]
SEEDS = [0]
​
​
@pytest.mark.parametrize(
    "M, N, K, E, topk, dtype, seed",
    itertools.product(M, N, K, E, TOP_KS, DTYPES, SEEDS),
)
@torch.inference_mode()
def test_w8a8_fp8_fused_moe(default_vllm_config, M, N, K, E, topk, dtype, seed):
    torch.manual_seed(seed)
    device = current_platform.device_type # 获取当前设备类型,不依赖全局默认设备
    # 所有张量创建均指定 device,确保与 kernel 运行设备一致
    a = torch.randn((M, K), dtype=dtype, device=device) / 10
    w1_fp32 = (torch.rand((E, 2 * N, K), dtype=torch.float32, device=device) - 0.5) * 2
    w2_fp32 = (torch.rand((E, K, N), dtype=torch.float32, device=device) - 0.5) * 2
    # ... 其余逻辑不变
tests/kernels/quantization/test_block_int8.py test-coverage

同样移除 fixture 并用显式设备替代张量创建,与 test_int8_kernel.py 对称修复。

# 删除 module-scope fixture,改为局部设备指定,避免 fixture 重置@pytest.mark.parametrize(
    "M,N,K,block_size,out_dtype,seed",
    itertools.product(M, N, K, BLOCK_SIZE, DTYPES, SEEDS),
)
@torch.inference_mode()
def test_w8a8_block_int8_matmul(M, N, K, block_size, out_dtype, seed):
    torch.manual_seed(seed)
    device = current_platform.device_type # 动态获取设备,不依赖全局 default_device
    factor_for_scale = 1e-2
    int8_info = torch.iinfo(torch.int8)
    int8_max, int8_min = int8_info.max, int8_info.min
    # 所有张量都创建在正确 device 上,不再受 fixture 副作用影响
    A_fp32 = torch.rand(M, K, dtype=torch.float32, device=device)
    A_fp32 = (A_fp32 - 0.5) * 2 * int8_max
    A_fp8 = A_fp32.clamp(min=int8_min, max=int8_max).to(torch.float8_e4m3fn)
    # 其余张量类似,均显式指定 device

评论区精华

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

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

风险与影响

风险极低。仅修改测试辅助代码和测试函数内张量创建方式,不涉及生产代码;改动逻辑直观,回归风险小。

  • 用户:无影响。
  • 系统:提高量化 kernel 测试在 AMD CI 的稳定性,消除偶发失败。
  • 团队:减少因测试不稳定导致的 CI 重跑。
测试隔离改进

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论