# PR #32862 完整报告

- 仓库：`sgl-project/sglang`
- 标题：[AMD] Pin mem_fraction_static for the piecewise CUDA graph 1-GPU test on MI300
- 合并时间：2026-08-01 05:56
- 原文链接：http://prhub.com.cn/sgl-project/sglang/pull/32862

---

# 执行摘要

- 一句话：AMD CI 固定内存分数 0.6 修复分段 CUDA 图测试 OOM
- 推荐动作：值得快速阅读，作为“测试适配硬件差异”的参考案例。重点关注模块级常量 + is_in_amd_ci() 分支的做法，以及它如何保持两个测试类配置同步。若后续 AMD runner 硬件再次变化，应优先重新评估该魔数。

# 功能与动机

PR body 中明确说明：test/registered/cuda_graph/piecewise/test_piecewise_cuda_graph_support_1_gpu.py 在 stage-b-test-1-gpu-large-amd 套件中失败，原因是 #31409 将 AMD CI runner 从 MI325X（256 GB）切换为 MI300X（192 GB）后，测试依赖 ServerArgs 按 GPU 内存自动推导的 mem_fraction_static，在 192 GB 上不足以覆盖 Qwen2.5-VL 的 ViT 激活和分段 CUDA 图私有内存池，1024 线程 gsm8k 负载下服务器中途崩溃，所有请求变成连接错误，评估分数为 0.0（AssertionError: 0.0 not greater than or equal to 0.8）。

# 实现拆解

1. 引入 AMD CI 判断与常量：在 test/registered/cuda_graph/piecewise/test_piecewise_cuda_graph_support_1_gpu.py 顶部从 sglang.test.test_utils 新增导入 is_in_amd_ci，并定义模块级常量 AMD_MEM_FRACTION_STATIC = 0.6，注释说明 MI300X 显存余量不足的原因。
2. 修改 TestPiecewiseCudaGraphQwen25VL.setUpClass：将 popen_launch_server 的 other_args 改为先构造列表，再在 is_in_amd_ci() 为真时追加 --mem-fraction-static 0.6，保证非 AMD 环境不改变原有行为。
3. 修改 TestPiecewiseCudaGraphQwen25VLEmbedding.test_embedding：新增 extra_args 字典，在 AMD CI 下为 tc_piecewise 与 disabled 两个 Engine 实例都传入 mem_fraction_static=0.6，确保分段 CUDA 图与普通模式对比的配置一致。
4. 验证配套：提交历史显示内存分数从 0.75 下调到 0.6，并在 AMD/CUDA 两侧 CI 上验证通过；无运行时、服务参数 schema 或部署配置变更。

关键文件：
- `test/registered/cuda_graph/piecewise/test_piecewise_cuda_graph_support_1_gpu.py`（模块 测试用例；类别 test；类型 test-coverage；符号 AMD_MEM_FRACTION_STATIC, TestPiecewiseCudaGraphQwen25VL.setUpClass, TestPiecewiseCudaGraphQwen25VLEmbedding.test_embedding）: 唯一变更文件。在 AMD CI 分支为分段 CUDA 图测试固定 mem_fraction_static=0.6，修复 MI300X 上服务端 OOM 导致的 gsm8k 分数归零问题，同时同步 embedding 测试的 Engine 配置。

关键符号：TestPiecewiseCudaGraphQwen25VL.setUpClass, TestPiecewiseCudaGraphQwen25VLEmbedding.test_embedding

## 关键源码片段

### `test/registered/cuda_graph/piecewise/test_piecewise_cuda_graph_support_1_gpu.py`

唯一变更文件。在 AMD CI 分支为分段 CUDA 图测试固定 mem_fraction_static=0.6，修复 MI300X 上服务端 OOM 导致的 gsm8k 分数归零问题，同时同步 embedding 测试的 Engine 配置。

```python
# AMD CI 专用内存分数常量：MI300X（192 GB）比 MI325X（256 GB）显存小，
# 自动推导的分数无法为 ViT 激活和分段 CUDA 图私有池留足空间，
# 高并发 gsm8k 负载下服务端会 OOM 崩溃。
AMD_MEM_FRACTION_STATIC = 0.6


class TestPiecewiseCudaGraphQwen25VL(CustomTestCase):
    """Qwen2.5-VL 分段 CUDA 图 GSM8K 精度测试。"""

    @classmethod
    def setUpClass(cls):
        cls.model = "Qwen/Qwen2.5-VL-7B-Instruct"
        cls.base_url = DEFAULT_URL_FOR_TEST

        # 基础启动参数；仅在 AMD CI 下追加内存分数固定值，
        # NVIDIA CI 仍沿用 ServerArgs 中的自动推导逻辑
        other_args = [
            "--cuda-graph-backend-prefill=tc_piecewise",
            "--disable-radix-cache",
        ]
        if is_in_amd_ci():
            other_args += ["--mem-fraction-static", str(AMD_MEM_FRACTION_STATIC)]

        cls.process = popen_launch_server(
            cls.model,
            cls.base_url,
            timeout=DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
            other_args=other_args,
        )


class TestPiecewiseCudaGraphQwen25VLEmbedding(CustomTestCase):
    """分段 CUDA 图嵌入一致性测试。"""

    def test_embedding(self):
        model_path = "Qwen/Qwen2.5-VL-3B-Instruct"
        chat_template = get_chat_template_by_model_path(model_path)
        text = f"{chat_template.image_token}What is in this picture? Answer: "

        # 在 AMD CI 下为两个 Engine 实例同步传入相同的内存分数，
        # 保证分段 CUDA 图与普通模式对比的公平性
        extra_args = (
            {"mem_fraction_static": AMD_MEM_FRACTION_STATIC} if is_in_amd_ci() else {}
        )

        engine = Engine(
            model_path=model_path,
            enable_multimodal=True,
            is_embedding=True,
            cuda_graph_backend_prefill="tc_piecewise",
            **extra_args,
        )
        out = engine.encode([text], image_data=[DEFAULT_IMAGE_URL])[0]["embedding"]
        engine.shutdown()

        engine = Engine(
            model_path=model_path,
            enable_multimodal=True,
            is_embedding=True,
            cuda_graph_backend_prefill="disabled",
            **extra_args,
        )
        out_without_pcg = engine.encode([text], image_data=[DEFAULT_IMAGE_URL])[0]["embedding"]
        engine.shutdown()
        # 后续逻辑为对比两个 embedding 的 max_abs_diff 与 allclose 断言

```

# 评论区精华

issue 评论中作者 yctseng0211 主动请求在 AMD CI 上 checkout 运行该测试，随后报告 resolved，并再次 /rerun-test 在 1-gpu-h100 上验证。最终作者总结“For test_piecewise_cuda_graph_support_1_gpu.py amd/cuda ci all passed, safe to merge @HaiShaw”。Gemini Code Assist 机器人仅提示其审查服务已停止。整个讨论以 CI 验证闭环为主，没有出现技术争议或未解决的疑虑。

- AMD CI 修复验证与重跑确认 (testing): 修复经 AMD/CUDA 两侧 CI 验证通过，无技术争议。

# 风险与影响

- 风险：本 PR 仅修改测试文件，不改运行时代码，回归风险极低。主要风险点：
 - 固定魔数 0.6 只适用于当前 MI300X（192 GB）环境；若 AMD runner 硬件或显存再次调整，该值可能失效，需要重新校准。
 - 仅在 is_in_amd_ci() 分支生效，本地或 NVIDIA CI 不会覆盖到 AMD 专用路径，存在配置漂移的可能。
 - 0.6 的余量是经验值，未来测试负载（如更大的并发线程数或更长 prompt）可能再次触发 OOM，而测试本身无法自动发现这种边界。
 - 影响：影响范围严格限定在 AMD CI 的 stage-b-test-1-gpu-large-amd 套件：修复了 test_piecewise_cuda_graph_support_1_gpu.py 的稳定性，避免因硬件更换导致的持续 CI 红。NVIDIA nightly-1-gpu 套件与所有运行时、服务端行为完全不受影响。对团队而言，消除了 AMD CI 的一个高频失败源，降低后续 PR 合并时的噪音。
 - 风险标记：AMD CI 专用配置 , 固定魔数 0.6, 运行时未覆盖

# 关联脉络

- PR #31409 Swap AMD CI runners from MI325X to MI300X: PR body 明确说明本 PR 是对 #31409 将 AMD CI runner 从 MI325X（256 GB）切换到 MI300X（192 GB）后的 CI 测试适配修复。