From ade30fd494c5c0c50b6ce127c0602702ea345a93 Mon Sep 17 00:00:00 2001 From: Ting SUN Date: Sat, 13 Jun 2026 10:27:31 +0800 Subject: [PATCH] fix(server): serialize nested dict config values as JSON (#28094) Signed-off-by: Ting Sun --- .../sglang/srt/server_args_config_parser.py | 3 +++ .../unit/server_args/test_server_args.py | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/python/sglang/srt/server_args_config_parser.py b/python/sglang/srt/server_args_config_parser.py index 24de2e967..17724ff7b 100644 --- a/python/sglang/srt/server_args_config_parser.py +++ b/python/sglang/srt/server_args_config_parser.py @@ -4,6 +4,7 @@ Handles merging of YAML configuration files with command-line arguments. """ import argparse +import json import logging from pathlib import Path from typing import Any, Dict, List @@ -151,6 +152,8 @@ class ConfigArgumentMerger: self._add_boolean_arg(args, key, value) elif isinstance(value, list): self._add_list_arg(args, key, value) + elif isinstance(value, dict): + self._add_scalar_arg(args, key, json.dumps(value)) else: self._add_scalar_arg(args, key, value) diff --git a/test/registered/unit/server_args/test_server_args.py b/test/registered/unit/server_args/test_server_args.py index b6e1175d1..348025739 100644 --- a/test/registered/unit/server_args/test_server_args.py +++ b/test/registered/unit/server_args/test_server_args.py @@ -14,6 +14,7 @@ from sglang.srt.model_executor.cuda_graph_config import ( PhaseConfig, ) from sglang.srt.server_args import PortArgs, ServerArgs, prepare_server_args +from sglang.srt.server_args_config_parser import ConfigArgumentMerger from sglang.test.ci.ci_register import register_cpu_ci from sglang.test.test_utils import ( DEFAULT_SMALL_MODEL_NAME_FOR_TEST_QWEN, @@ -44,6 +45,30 @@ class TestPrepareServerArgs(CustomTestCase): {"rope_scaling": {"factor": 2.0, "rope_type": "linear"}}, ) + def test_config_nested_dict_args_are_json(self): + with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: + 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) + + self.assertEqual(json.loads(value), {"image": {"resize": 128}}) + self.assertEqual(parsed.mm_process_config, {"image": {"resize": 128}}) + finally: + os.unlink(config_file) + class TestLoadBalanceMethod(unittest.TestCase): def test_non_pd_defaults_to_round_robin(self):