执行摘要
- 一句话:为NPU扩散测试增加GT生成并重构套件
- 推荐动作:值得仔细阅读,特别是
run_suite.py中的条件导入模式和compute_diffusion_partitions.py的环境变量切换,这是多平台测试框架的设计模板。同时关注后续的路径优化和URL迁移,避免遗留硬编码风险。
功能与动机
PR描述指出需要在Ascend测试中增加一致性检查的GT生成,这是实现扩散模型在NPU上持续集成的基础设施改造。
实现拆解
-
新增NPU GT生成workflow:创建.github/workflows/diffusion-ci-gt-gen-npu.yml,支持workflow_dispatch触发,包含计算分区、1-NPU和2-NPU的ground truth生成作业,测试结果发布到sgl-project/ci-data仓库。
-
重构测试套件结构:修改python/sglang/multimodal_gen/test/run_suite.py,移除内联的套件定义(FILE_SUITES、PARAMETRIZED_CASE_GROUPS等),改为通过current_platform.is_npu()条件导入对应平台配置:NPU从testcase_configs_npu.py导入,GPU从gpu_cases.py导入。这消除了原有的run_suite_npu.py重复代码。
-
删除冗余文件和测试:删除run_suite_npu.py(299行)和test_server_8_npu.py(31行),将8-NPU测试用例(如wan2_2_t2v_14b_w8a8_8npu)转换为2-NPU,减少设备占用。
-
移动配置集中化:在python/sglang/multimodal_gen/test/server/gpu_cases.py尾部新增_discover_unit_tests函数及一系列套件常量,在testcase_configs_npu.py中导出NPU版配置,形成平台独立的配置模块。
-
更新性能基线:修改perf_baselines_npu.json,将所有基线数据替换为在Ascend A3硬件上重新测量后的数值,并调整hardware字段为Ascend A3。
-
调整CI脚本:修改compute_diffusion_partitions.py和diffusion_case_parser.py,通过环境变量USE_NPU_CONFIGS切换NPU配置,避免在CPU协调器上误判平台。同时更新pr-test-npu.yml移除8-NPU相关作业。
-
添加辅助配置:在test_utils.py中添加Ascend专用的ground truth URL常量(指向sgl-project/ci-data),并在CODEOWNERS中新增NPU测试目录的所有者行。
关键文件:
.github/workflows/diffusion-ci-gt-gen-npu.yml(模块 CI工作流;类别 infra;类型 infrastructure): 新增NPU扩散CI ground truth生成工作流,是整个PR的核心交付物。定义了workflow_dispatch触发、计算分区、1-NPU和2-NPU的GT生成作业,以及结果发布到ci-data仓库。
python/sglang/multimodal_gen/test/run_suite.py(模块 测试套件;类别 test;类型 test-coverage;符号 _discover_unit_tests): 重构核心文件,改为通过平台检测动态导入配置,消除了run_suite_npu.py的重复。
python/sglang/multimodal_gen/test/server/gpu_cases.py(模块 GPU用例;类别 test;类型 test-coverage;符号 _discover_unit_tests, FILE_SUITES, PARAMETRIZED_CASE_GROUPS, STANDALONE_FILES): 原run_suite.py中的套件配置被移到该文件尾部,使其成为GPU套件配置的中心文件。
python/sglang/multimodal_gen/test/run_suite_npu.py(模块 测试套件;类别 test;类型 deletion;符号 parse_args, collect_test_items, run_pytest, main): 因功能重复被删除,是PR中最大的删除文件(299行),反映重构意图。
python/sglang/multimodal_gen/test/server/ascend/test_server_8_npu.py(模块 8-NPU测试;类别 test;类型 deletion;符号 TestDiffusionServerEightNpu, case): 被删除,8-NPU测试被2-NPU替代,以节省设备。
python/sglang/multimodal_gen/test/server/ascend/perf_baselines_npu.json(模块 性能基线;类别 test;类型 test-coverage): 更新了所有性能基线数据,反映Ascend A3硬件和老化的2-NPU测试。
python/sglang/multimodal_gen/test/server/ascend/testcase_configs_npu.py(模块 NPU配置;类别 test;类型 test-coverage): 导出NPU版套件配置,是条件导入的目标模块。
关键符号:_discover_unit_tests, parse_args, collect_test_items, run_pytest, TestDiffusionServerEightNpu.case
关键源码片段
python/sglang/multimodal_gen/test/run_suite.py
重构核心文件,改为通过平台检测动态导入配置,消除了run_suite_npu.py的重复。
# python/sglang/multimodal_gen/test/run_suite.py (head)
"""
Test runner for multimodal_gen that manages test suites and parallel execution.
For diffusion 1-gpu/2-gpu suites, cases are partitioned by estimated runtime
using LPT so each CI shard has a similar total runtime.
"""
from sglang.multimodal_gen.runtime.platforms import current_platform
from sglang.multimodal_gen.test.server.testcase_configs import (
BASELINE_CONFIG,
DiffusionTestCase,
)
# 根据当前平台动态导入对应的套件配置
# 避免维护两份 run_suite.py 复制,TODO: remove duplicated code
if current_platform.is_npu():
from sglang.multimodal_gen.test.server.ascend.testcase_configs_npu import (
_UPDATE_WEIGHTS_FROM_DISK_TEST_FILE,
COMPONENT_ACCURACY_SUITES,
DEFAULT_EST_TIME_SECONDS,
DEFAULT_STANDALONE_EST_TIME_SECONDS,
FILE_SUITES,
PARAMETRIZED_CASE_GROUPS,
STANDALONE_FILES,
STARTUP_OVERHEAD_SECONDS,
SUITES,
)
else:
from sglang.multimodal_gen.test.server.gpu_cases import ( # noqa: F401
_UPDATE_WEIGHTS_FROM_DISK_TEST_FILE,
_UPDATE_WEIGHTS_MODEL_PAIR_ENV,
_UPDATE_WEIGHTS_MODEL_PAIR_IDS,
COMPONENT_ACCURACY_FILE_NUM_GPUS,
COMPONENT_ACCURACY_SUITES,
DEFAULT_EST_TIME_SECONDS,
DEFAULT_STANDALONE_EST_TIME_SECONDS,
FILE_SUITES,
ONE_GPU_CASES,
PARAMETRIZED_CASE_GROUPS,
STANDALONE_FILE_EST_TIMES,
STANDALONE_FILES,
STARTUP_OVERHEAD_SECONDS,
STRICT_SUITES,
SUITES,
TWO_GPU_CASES,
)
python/sglang/multimodal_gen/test/server/gpu_cases.py
原run_suite.py中的套件配置被移到该文件尾部,使其成为GPU套件配置的中心文件。
# python/sglang/multimodal_gen/test/server/gpu_cases.py (head 末尾新增部分 )
def _discover_unit_tests() -> list[str]:
"""自动发现 unit 目录下的测试文件"""
unit_dir = Path(__file__).resolve().parent.parent / "unit"
if not unit_dir.is_dir():
return []
return sorted(
f"../unit/{f.name}" for f in unit_dir.glob("test_*.py") if f.is_file()
)
FILE_SUITES = {
"unit": _discover_unit_tests(),
"component-accuracy": ["test_component_accuracy_1_gpu.py", "test_component_accuracy_2_gpu.py"],
"component-accuracy-1-gpu": ["test_component_accuracy_1_gpu.py"],
"component-accuracy-2-gpu": ["test_component_accuracy_2_gpu.py"],
"1-gpu-b200": ["test_server_b200.py"],
}
PARAMETRIZED_CASE_GROUPS = {
"1-gpu": [("test_server_1_gpu.py", ONE_GPU_CASES)],
"2-gpu": [("test_server_2_gpu.py", TWO_GPU_CASES)],
}
# ... 其他常量和向后兼容的 SUITES 字典
评论区精华
核心讨论聚焦于平台检测的正确性、代码复用和环境适配:
风险与影响
关联脉络
参与讨论