Prhub

#26666 [UnifiedTree]: Split unified tree kl ci into multiple files to reduce GPU usage.

原始 PR 作者 hzh0425 合并时间 2026-05-29 17:46 文件变更 7 提交数 3 评论 3 代码增减 +192 / -214

执行摘要

拆分 UnifiedRadixTree KL CI 测试文件以减少 GPU 占用量。

原测试文件(如 test_unified_radix_cache_kl_mamba.py 和 test_unified_radix_cache_kl_hicache.py)包含了多种模型类型的测试,导致单次 CI 运行需要较高端 GPU(如 8*H200)。拆分后,每种模型类型独立运行,可以选用更经济的 GPU 配置,从而减少 CI 资源占用和排队时间。

适合 CI 维护者和测试架构学习者精读,了解如何通过测试文件拆分和资源配置优化 CI 成本。设计决策值得注意:每个测试文件按模型类型和资源需求独立配置,而非统一使用最高配置。

讨论亮点
  • gemini-code-assist[bot] 指出 test_unified_radix_cache_kl_full.py 中缺少 --tp-size 参数,可能影响 32B 模型的运行。该问题在随后提交中已修复。
  • hnyls2002 批准并评论 "Good job. Once the lint is fixed, we can merge it"。

实现拆解

  1. 整合 Mamba 相关测试:新建 test_unified_radix_cache_kl_mamba.py 到 unified_radix_tree/ 目录,将原 test_unified_radix_cache_kl_mamba.py 中的 TestUnifiedMambaRadixCache、原 test_unified_radix_cache_kl_hicache.py 中的 TestUnifiedMambaHiCache 以及原 test_unified_radix_cache_kl_hicache_part2.py 中的 TestUnifiedMambaHiCacheL3 合并,统一使用 runner_config "4-gpu-h100" 替代之前的 "8-gpu-h200"。
  2. DSV4 测试精简:原 test_unified_radix_cache_kl_hicache.py 同时包含 Mamba 和 DSV4 测试。本 PR 移除其中的 Mamba 部分,只保留 TestUnifiedDeepSeekV4FlashHiCache,并重命名为 test_unified_radix_cache_kl_dsv4.py,放入 unified_radix_tree/,GPU 配置从 "8-gpu-h200" 降为 "4-gpu-h100"。
  3. Full Attention 和 SWA 测试降配:将 test_unified_radix_cache_kl_full.pytest_unified_radix_cache_kl_swa.py 移至 unified_radix_tree/ 子目录,TP 大小从 4 改为 2,runner_config 从 "4-gpu-h100" 改为 "2-gpu-large",以匹配模型需求并降低 GPU 占用。
  4. 删除旧文件:删除合并后不再需要的 test_unified_radix_cache_kl_mamba.pytest_unified_radix_cache_kl_hicache_part2.pytest_unified_radix_cache_kl_hicache_nightly.py 无内容变更仅重命名迁移。
文件 模块 状态 重要度
test/registered/radix_cache/unified_radix_tree/test_unified_radix_cache_kl_mamba.py Mamba 测试 added 7.95
test/registered/radix_cache/unified_radix_tree/test_unified_radix_cache_kl_dsv4.py DSV4 测试 renamed 7.09
test/registered/radix_cache/test_unified_radix_cache_kl_mamba.py 测试删除 removed 7.08
test/registered/radix_cache/test_unified_radix_cache_kl_hicache_part2.py 测试删除 removed 7.13
test/registered/radix_cache/unified_radix_tree/test_unified_radix_cache_kl_full.py Full 测试 renamed 4.23
test/registered/radix_cache/unified_radix_tree/test_unified_radix_cache_kl_swa.py SWA 测试 renamed 4.23
test/registered/radix_cache/unified_radix_tree/test_unified_radix_cache_kl_hicache_nightly.py Nightly 测试 renamed 3.11

关键符号

setUpClass tearDownClass TestUnifiedMambaRadixCache TestUnifiedMambaHiCache TestUnifiedMambaHiCacheL3 TestUnifiedDeepSeekV4FlashHiCache

关键源码片段

test/registered/radix_cache/unified_radix_tree/test_unified_radix_cache_kl_mamba.py test-coverage

新增文件,整合了所有 Mamba 相关测试(纯 Radix、HiCache L2/L3),是本次拆分的核心合并产物。

import os
import shutil
import tempfile
import unittest# 从 nightly 混入类导入双精度测试基类
from test_unified_radix_cache_kl_hicache_nightly import AccuracyTwoPassMixinfrom sglang.srt.utils import kill_process_tree
from sglang.test.ci.ci_register import register_cuda_ci
from sglang.test.kits.unified_radix_cache_kit import UnifiedRadixTreeTestMixin
from sglang.test.kl_multiturn_utils import (
    get_input_ids,
    make_mamba_decode_assert,
    make_mamba_prefill_assert,
)
from sglang.test.test_utils import (
    DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
    DEFAULT_URL_FOR_TEST,
    CustomTestCase,
    popen_launch_server,
)# 注册 CI 舞台,估计时间 768s,运行于 4-gpu-h100 机器
register_cuda_ci(est_time=768, stage="base-c", runner_config="4-gpu-h100")# 模型与参数常量
MAMBA_MODEL = "Qwen/Qwen3-Next-80B-A3B-Instruct-FP8"
MAMBA_CHUNK_SIZE = 64
MAMBA_TRACK_INTERVAL = 128
​
​
class TestUnifiedMambaRadixCache(UnifiedRadixTreeTestMixin, CustomTestCase):
    """Mamba hybrid + UnifiedRadixCache 测试类"""
    kl_threshold = 0.003
    prefill_cache_assert = staticmethod(
        make_mamba_prefill_assert(chunk_size=MAMBA_CHUNK_SIZE)
    )
    decode_cache_assert = staticmethod(
        make_mamba_decode_assert(track_interval=MAMBA_TRACK_INTERVAL)
    )
​
    @classmethod
    def setUpClass(cls):
        # 启动模型服务器,4*TP、启用 unified radix tree
        cls.model = MAMBA_MODEL
        cls.base_url = DEFAULT_URL_FOR_TEST
        cls.process = popen_launch_server(
            cls.model,
            cls.base_url,
            timeout=DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH,
            other_args=[
                "--tp-size", "4",
                "--chunked-prefill-size", "2048",
                "--mem-fraction-static", "0.85",
                "--mamba-scheduler-strategy", "extra_buffer",
                "--mamba-track-interval", str(MAMBA_TRACK_INTERVAL),
            ],
            env={"SGLANG_ENABLE_UNIFIED_RADIX_TREE": "1"},
        )
        cls.input_ids = get_input_ids(cls.model, num_samples=18)
​
    @classmethod
    def tearDownClass(cls):
        kill_process_tree(cls.process.pid)
test/registered/radix_cache/unified_radix_tree/test_unified_radix_cache_kl_dsv4.py rename-or-move

从原混合文件拆分出的 DSV4 测试,移除了 Mamba 部分并调整 GPU 配置。

import unittestfrom sglang.srt.utils import kill_process_tree
from sglang.test.ci.ci_register import register_cuda_ci
from sglang.test.kits.unified_radix_cache_kit import UnifiedRadixTreeTestMixin
from sglang.test.kl_multiturn_utils import get_input_ids
from sglang.test.test_utils import (
    DEFAULT_URL_FOR_TEST,
    CustomTestCase,
    is_in_ci,
    popen_launch_server,
)DSV4_FLASH_MODEL = "sgl-project/DeepSeek-V4-Flash-FP8"
DSV4_FLASH_LAUNCH_TIMEOUT = 3600# 调整 CI 配置:8-gpu-h200 -> 4-gpu-h100
register_cuda_ci(est_time=768, stage="base-c", runner_config="4-gpu-h100")
​
​
def _assert_dsv4_decode_cached_tokens(result, history_len, output_len, label):
    """断言解码缓存 token 数在合理范围内。"""
    expected = history_len + output_len
    actual = result["meta_info"]["cached_tokens"]
    lower = max(0, expected - 256)
    assert actual >= lower, f"{label}: expected cached_tokens>={lower}, got {actual}"
​
​
class TestUnifiedDeepSeekV4FlashHiCache(UnifiedRadixTreeTestMixin, CustomTestCase):
    """DeepSeek V4 Flash FP8 + HiCache + UnifiedRadixCache 测试类"""
    hicache_io_backend = "direct"
    hicache_mem_layout = "page_first_direct"
    max_running_requests = 4
    kl_threshold = 0.005
    sampling_temperature = 0
    decode_hit_request_batch_size = 3
    decode_hit_inter_batch_delay_s = 0.5
    decode_cache_assert = staticmethod(_assert_dsv4_decode_cached_tokens)
    gsm8k_threshold = 0.90
    num_gsm8k_questions = 100
​
    # 跳过 Multiturn 测试(CI 中不执行)
    @unittest.skipIf(is_in_ci(), "To reduce the CI execution time.")
    def test_multiturn_logprobs_match(self):
        pass
​
    @classmethod
    def setUpClass(cls):
        cls.model = DSV4_FLASH_MODEL
        cls.base_url = DEFAULT_URL_FOR_TEST
        # 启动服务器配置省略(与之前一致但改用 4-gpu-h100)

评论区精华

缺失 --tp-size 参数问题 正确性

gemini-code-assist[bot] 指出 `test_unified_radix_cache_kl_full.py` 新文件中缺少 `--tp-size` 参数,可能导致 32B 模型无法在 2 GPU 上运行。

结论:后续提交中已修复,添加了 `--tp-size 2`。 · 已解决

审核批准 other

hnyls2002 批准 PR,并指出修复 lint 后可合并。

结论:PR 已合并。 · 已解决

风险与影响

  • 测试覆盖风险:拆分过程中可能遗漏某些测试用例,但通过导入确认所有测试类已迁移至新文件。
  • 资源配置风险:TP 大小和 runner 配置调整可能在某些 GPU 环境下导致 OOM 或推理超时,需确保配置与模型内存需求匹配。
  • 路径变更风险:旧文件被删除,依赖绝对路径的 CI 脚本可能需要更新。

主要影响 CI 流程:降低单次测试 GPU 资源需求,提升资源利用率和并行度。对最终用户无功能影响。团队 CI 等待时间有望缩短。

配置变更可能影响测试可靠性 测试覆盖完整性需验证 旧路径删除需同步 CI 脚本

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论