Prhub

#49974 [Test] dynamic_shapes_compilation

原始 PR 作者 JaredforReal 合并时间 2026-07-29 12:54 文件变更 1 提交数 3 评论 0 代码增减 +46 / -56

执行摘要

测试改用 VllmRunner 确保引擎正确关闭

原测试在每次使用 LLM 后需要手动调用 del、gc.collect、empty_cache、synchronize 等步骤,且不同模型之间可能存在 GPU 内存竞争,导致测试不稳定。使用 VllmRunner 上下文管理器可在退出时自动清理引擎状态,确保测试隔离。PR body 明确说明 'replace LLM() with VllmRunner() for a proper shutdown along the testing'。

值得合并。该变更是对测试基础设施的改进,模式清晰,可推广至其他类似测试中。建议在后续 PR 中继续迁移剩余使用 LLM 手动管理的测试代码。

讨论亮点

无实质性讨论。Copilot 代码审查机器人自动总结了变更内容,维护者 Isotr0py 直接批准。

实现拆解

  1. 修改测试函数使用 vllm_runner fixture:在 test_dynamic_shapes_compilationtest_piecewise_backend_empty_sym_shape_indices 中,将原有的 LLM(model=...) 直接构造替换为 with vllm_runner(...) as vllm_model: 上下文管理器。生成逻辑移入 with 块,退出上下文时自动触发引擎关闭和资源释放。

  2. 移除手动内存清理代码:删除 del modelgc.collect()torch.accelerator.empty_cache()synchronize() 以及 wait_for_rocm_memory_to_settle() 等不再需要的清理步骤,这些现在由 VllmRunner.__exit__ 统一处理。

  3. 更新导入语句:移除 gcwait_for_rocm_memory_to_settle 的导入;将 from vllm import LLM, SamplingParams 简化为 from vllm import SamplingParams,因为 LLM 不再需要。

  4. 添加兼容性配置:为 vllm_runner 添加 enable_chunked_prefill=None 参数,以符合 VllmRunner 的默认配置要求,确保测试行为一致。

文件 模块 状态 重要度
tests/compile/test_dynamic_shapes_compilation.py 编译测试 modified 5.46

关键符号

test_dynamic_shapes_compilation test_piecewise_backend_empty_sym_shape_indices

关键源码片段

tests/compile/test_dynamic_shapes_compilation.py test-coverage

本次变更的唯一文件,将测试中直接的 LLM 创建替换为 VllmRunner 上下文管理器,确保引擎正确关闭并移除手动清理代码。

# tests/compile/test_dynamic_shapes_compilation.py@pytest.mark.parametrize('model_name', get_test_models())
@pytest.mark.parametrize(
    'shapes_type',
    [
        DynamicShapesType.BACKED,
        DynamicShapesType.UNBACKED,
        DynamicShapesType.BACKED_SIZE_OBLIVIOUS,
    ],
)
@pytest.mark.parametrize('use_aot_compile', ['0', '1'])
@pytest.mark.parametrize('use_bytecode_hook', [True, False])
@pytest.mark.parametrize('evaluate_guards', [False, True])
@pytest.mark.skipif(not is_torch_equal_or_newer('2.10.0'), reason='requires torch 2.10')
def test_dynamic_shapes_compilation(
    monkeypatch,
    vllm_runner, # VllmRunner fixture 确保上下文退出时 shutdown
    model_name,
    shapes_type,
    use_aot_compile,
    use_bytecode_hook,
    evaluate_guards,
):
    '''Test that all dynamic shapes types compile successfully'''
    if shapes_type == DynamicShapesType.UNBACKED and not is_torch_equal_or_newer('2.11.0'):
        pytest.skip('unbacked dynamic shapes with shape_id require torch>=2.11')
    if evaluate_guards and shapes_type == DynamicShapesType.UNBACKED:
        pytest.skip('unbacked dynamic shapes do not add guards')
    if evaluate_guards and use_aot_compile:
        pytest.skip('evaluate_guards requires use_aot_compile=0')
​
    monkeypatch.setenv('VLLM_USE_AOT_COMPILE', use_aot_compile)
    monkeypatch.setenv('VLLM_USE_BYTECODE_HOOK', '1' if use_bytecode_hook else '0')
​
    prompt = 'Hello, my name is'
    sampling_params = SamplingParams(max_tokens=5, temperature=0, logprobs=10)
    test_prompts = [prompt, 'The capital of France is']
​
    # 使用 VllmRunner 管理编译模型生命周期
    with vllm_runner(
        model_name,
        compilation_config={
            'mode': CompilationMode.VLLM_COMPILE,
            'dynamic_shapes_config': {
                'type': shapes_type.value,
                'evaluate_guards': evaluate_guards,
            },
        },
        max_model_len=1024,
        enable_chunked_prefill=None, # 显式设置与 VllmRunner 默认一致
    ) as vllm_model:
        compiled_outputs = []
        for p in test_prompts:
            output = vllm_model.llm.generate(p, sampling_params)[0].outputs[0]
            assert len(output.text.strip()) > 0, 'Compiled model produced empty output'
            compiled_outputs.append((output.token_ids, output.text, output.logprobs))
​
    # 第二个 VllmRunner 以 eager 模式运行对照
    with vllm_runner(
        model_name,
        enforce_eager=True,
        max_model_len=1024,
        enable_chunked_prefill=None,
    ) as vllm_model:
        eager_outputs = []
        for p in test_prompts:
            output = vllm_model.llm.generate(p, sampling_params)[0].outputs[0]
            assert len(output.text.strip()) > 0, 'Eager model produced empty output'
            eager_outputs.append((output.token_ids, output.text, output.logprobs))
​
    # 验证 eager 与 compiled 输出的 logprobs 一致性
    check_logprobs_close(
        outputs_0_lst=eager_outputs,
        outputs_1_lst=compiled_outputs,
        name_0='eager',
        name_1='compiled',
    )

评论区精华

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

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

风险与影响

极低风险。变更仅涉及测试代码,不改变任何生产逻辑。新代码在 CI 中已通过全部测试用例(包括 GPT2 等模型),验证了行为一致性。唯一需关注的是 enable_chunked_prefill=None 的显式设置,但该值已是 VllmRunner 的默认行为,不会引入功能差异。

仅影响一个测试文件,消除了因引擎未正确关闭导致的 GPU 内存残留和测试不稳定问题。提升了编译测试套件的隔离性和可靠性。对用户无影响,对开发者在本地运行测试时更加稳定。

测试稳定性 资源管理

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论