Prhub

#28094 fix(server): serialize nested dict config values as JSON

原始 PR 作者 Sunt-ing 合并时间 2026-06-13 10:27 文件变更 2 提交数 2 评论 1 代码增减 +28 / -0

执行摘要

修复嵌套字典配置项 JSON 序列化问题

PR body 指出:--config 目前对嵌套 YAML dict 值使用 str(value),对于声明为 type=json.loads 的参数,会产生 Python repr 字符串,如 {'temperature': 0.5, 'top_p': 0.9},导致 json.loads 在 argparse 校验阶段拒绝,服务启动前退出。影响 --mm-process-config--preferred-sampling-params--limit-mm-data-per-request 等字典类型配置参数。此问题在 #14085 修复了布尔值后仍存在。

建议合并。该修复简洁且必要,专门针对已报告的启动失败问题,并包含回归测试。

讨论亮点

无 review 讨论。PR 无任何 review 评论。

实现拆解

  1. 修改配置转换逻辑:在 _convert_config_to_args 方法中,对 valuedict 类型增加专属 elif 分支,调用 json.dumps(value) 序列化后通过 _add_scalar_arg 传入参数列表。
  2. 添加导入:在 server_args_config_parser.py 顶部添加 import json
  3. 新增回归测试:在 test_server_args.pyTestPrepareServerArgs 类中添加 test_config_nested_dict_args_are_json 测试方法,使用临时 YAML 文件模拟 --mm-process-config 配置,验证 ConfigArgumentMerger 正确将字典序列化为 JSON 字符串,且 parser.parse_args 后能正确解析。
  4. 测试导入调整:在测试文件中导入 ConfigArgumentMerger
文件 模块 状态 重要度
python/sglang/srt/server_args_config_parser.py 配置解析 modified 6.13
test/registered/unit/server_args/test_server_args.py 服务参数 modified 5.77

关键符号

_convert_config_to_args test_config_nested_dict_args_are_json

关键源码片段

python/sglang/srt/server_args_config_parser.py core-logic

核心修复文件:在 `_convert_config_to_args` 方法中增加 `elif isinstance(value, dict)` 分支,使用 `json.dumps` 序列化字典值。

# python/sglang/srt/server_args_config_parser.py
import json # 新增导入def _convert_config_to_args(self, config: Dict[str, Any]) -> List[str]:
    """Convert configuration dictionary to argument list."""
    args = []
    for key, value in config.items():
        key_norm = key.replace("-", "_")
        if key_norm in self.unsupported_actions:
            action = self.unsupported_actions[key_norm]
            msg = f"Unsupported config option '{key_norm}' with action '{action.__class__.__name__}'"
            raise ValueError(msg)
        if isinstance(value, bool):
            self._add_boolean_arg(args, key, value)
        elif isinstance(value, list):
            self._add_list_arg(args, key, value)
        elif isinstance(value, dict):
            # 修复:使用 json.dumps 序列化字典,避免 str() 产生 Python repr 字符串
            self._add_scalar_arg(args, key, json.dumps(value))
        else:
            self._add_scalar_arg(args, key, value)
    return args
test/registered/unit/server_args/test_server_args.py test-coverage

回归测试文件:新增 `test_config_nested_dict_args_are_json` 测试方法,验证嵌套字典配置在转换后能被正确解析为 JSON 对象。

# test/registered/unit/server_args/test_server_args.py
from sglang.srt.server_args_config_parser import ConfigArgumentMerger # 新增导入def test_config_nested_dict_args_are_json(self):
    with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
        # 模拟 YAML 配置:mm-process-config 是嵌套字典
        f.write("mm-process-config:\n  image:\n    resize: 128\n")
        config_file = f.name
    try:
        parser = server_args_module.argparse.ArgumentParser()
        ServerArgs.add_cli_args(parser)
        merged = ConfigArgumentMerger(parser).merge_config_with_args(
            ["--config", config_file, "--model-path", DEFAULT_SMALL_MODEL_NAME_FOR_TEST_QWEN]
        )
        # 获取转换后的参数值
        value = merged[merged.index("--mm-process-config") + 1]
        parsed = parser.parse_args(merged)
        # 验证 value 是有效的 JSON 字符串,且解析后与原始字典一致
        self.assertEqual(json.loads(value), {"image": {"resize": 128}})
        self.assertEqual(parsed.mm_process_config, {"image": {"resize": 128}})
    finally:
        os.unlink(config_file)

评论区精华

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

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

风险与影响

风险极低:变更仅增加了一个 elif isinstance(value, dict) 分支,并引入了 json.dumps 调用,路径与现有 _add_scalar_arg 一致。测试覆盖了典型的嵌套字典场景(mm-process-config),未影响布尔值或列表路径。但需注意:若配置值为 dict 但其中含有非 JSON 可序列化类型(如 set),json.dumps 可能抛出异常,不过 YAML 配置中此类情况罕见。

直接影响所有使用 --config 且包含字典类型参数的用户,使其能正常启动服务。受影响参数包括 --mm-process-config--preferred-sampling-params--limit-mm-data-per-request--extra-metric-labels 等。对其他配置参数无影响。

关联 Issue

#14085 Fix parse args from file(#13911)

完整报告

参与讨论