diff --git a/python/sglang/srt/arg_groups/arg_utils.py b/python/sglang/srt/arg_groups/arg_utils.py index d05c39d1a..aa8738e5c 100644 --- a/python/sglang/srt/arg_groups/arg_utils.py +++ b/python/sglang/srt/arg_groups/arg_utils.py @@ -75,17 +75,17 @@ class Arg: # When True, this field is skipped by add_cli_args_from_dataclass. # Use for fields that have no CLI surface (e.g. injected via Python only). no_cli: bool = False - # When True, this field may be resolved by model overrides: it is part of - # the whitelist accepted by the apply_model_overrides gate, and its - # resolved value lives on the flags tier (the server_args field itself - # stays the pristine user input). - model_overridable: bool = False + # When True, this field may be written by config resolution (model + # overrides and post-process passes): it is part of the whitelist accepted + # by the apply_model_overrides gate, and its resolved value lives on the + # flags tier (the server_args field itself stays the pristine user input). + resolvable: bool = False @functools.lru_cache(maxsize=None) -def model_overridable_fields(cls) -> frozenset: +def resolvable_fields(cls) -> frozenset: """Names of ``cls`` dataclass fields whose ``Arg`` metadata declares - ``model_overridable=True`` — the whitelist for model-override resolution. + ``resolvable=True`` — the whitelist for config resolution. Non-dataclass types (e.g. mock config objects in tests) have no Arg metadata and yield an empty whitelist.""" @@ -95,7 +95,7 @@ def model_overridable_fields(cls) -> frozenset: names = set() for field in dataclasses.fields(cls): _, arg = _unwrap_annotated(hints.get(field.name, field.type)) - if arg is not None and arg.model_overridable: + if arg is not None and arg.resolvable: names.add(field.name) return frozenset(names) diff --git a/python/sglang/srt/arg_groups/overrides.py b/python/sglang/srt/arg_groups/overrides.py index f73343522..5bf8106f5 100644 --- a/python/sglang/srt/arg_groups/overrides.py +++ b/python/sglang/srt/arg_groups/overrides.py @@ -32,7 +32,7 @@ import dataclasses import logging from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, Tuple -from sglang.srt.arg_groups.arg_utils import model_overridable_fields +from sglang.srt.arg_groups.arg_utils import resolvable_fields from sglang.srt.model_executor.cuda_graph_config import Backend from sglang.srt.runtime_context import resolve_flag_leaf from sglang.srt.utils.common import ( @@ -1308,7 +1308,7 @@ def apply_model_overrides( Returns the provenance log, one record per declared write. """ if whitelist is None: - whitelist = model_overridable_fields(type(server_args)) + whitelist = resolvable_fields(type(server_args)) whitelist = frozenset(whitelist) ordered = list(declarations) + list(terminal) @@ -1367,9 +1367,9 @@ def apply_declarations_to_server_args( mutate ``server_args`` and only be rejected at publish time. """ # Non-dataclass fixtures carry no Arg metadata (mirrors the - # model_overridable_fields escape); only real ServerArgs is validated. + # resolvable_fields escape); only real ServerArgs is validated. if dataclasses.is_dataclass(type(server_args)): - whitelist = model_overridable_fields(type(server_args)) + whitelist = resolvable_fields(type(server_args)) for source, decl in list(declarations) + list(terminal): unknown = set(decl) - whitelist if unknown: diff --git a/python/sglang/srt/server_args.py b/python/sglang/srt/server_args.py index 72b634361..c37fbe40a 100644 --- a/python/sglang/srt/server_args.py +++ b/python/sglang/srt/server_args.py @@ -567,7 +567,7 @@ class ServerArgs: '* "float32" for FP32 precision.' ), choices=["auto", "half", "float16", "bfloat16", "float", "float32"], - model_overridable=True, + resolvable=True, ), ] = "auto" quantization: A[ @@ -575,7 +575,7 @@ class ServerArgs: Arg( help="The quantization method.", choices=QUANTIZATION_CHOICES, - model_overridable=True, + resolvable=True, ), ] = None quantization_param_path: A[ @@ -655,7 +655,7 @@ class ServerArgs: bool, Arg( help="Enable float32 matmuls to use TensorFloat32 precision for better performance (via torch.set_float32_matmul_precision). CUDA only.", - model_overridable=True, + resolvable=True, ), ] = False @@ -752,7 +752,7 @@ class ServerArgs: ] = 1.0 page_size: A[ Optional[int], - Arg(help="The number of tokens in a page.", model_overridable=True), + Arg(help="The number of tokens in a page.", resolvable=True), ] = None swa_full_tokens_ratio: A[ float, @@ -763,12 +763,12 @@ class ServerArgs: "E.g. 0.5 means if each swa layer has 50 tokens, then each full " "layer has 100 tokens." ), - model_overridable=True, + resolvable=True, ), ] = 0.8 disable_hybrid_swa_memory: A[ bool, - Arg(help="Disable the hybrid SWA memory pool.", model_overridable=True), + Arg(help="Disable the hybrid SWA memory pool.", resolvable=True), ] = False radix_eviction_policy: A[ str, @@ -931,7 +931,7 @@ class ServerArgs: Arg( help="The attention context parallelism size.", aliases=["--attention-context-parallel-size"], - model_overridable=True, + resolvable=True, ), ] = 1 moe_dp_size: A[ @@ -968,7 +968,7 @@ class ServerArgs: bool, Arg( help="Enabling data parallelism for attention and tensor parallelism for FFN. The dp size should be equal to the tp size. Currently DeepSeek-V2 and Qwen 2/3 MoE models are supported.", - model_overridable=True, + resolvable=True, ), ] = False enable_dp_attention_local_control_broadcast: A[ @@ -979,7 +979,7 @@ class ServerArgs: bool, Arg( help="Enable vocabulary parallel across the attention TP group to avoid all-gather across DP groups, optimizing performance under DP attention.", - model_overridable=True, + resolvable=True, ), ] = False enable_attn_tp_input_scattered: A[ @@ -1418,7 +1418,7 @@ class ServerArgs: Arg( help="Choose the kernels for attention layers.", choices=ATTENTION_BACKEND_CHOICES, - model_overridable=True, + resolvable=True, ), ] = None decode_attention_backend: A[ @@ -1440,7 +1440,7 @@ class ServerArgs: Arg( help="Choose the kernels for sampling layers.", choices=SAMPLING_BACKEND_CHOICES, - model_overridable=True, + resolvable=True, ), ] = None grammar_backend: A[ @@ -1618,7 +1618,7 @@ class ServerArgs: bool, Arg( help="Enable multi-layer Eagle speculative decoding.", - model_overridable=True, + resolvable=True, ), ] = False speculative_adaptive: A[ @@ -1705,7 +1705,7 @@ class ServerArgs: Arg( help="The expert parallelism size.", aliases=["--expert-parallel-size", "--ep"], - model_overridable=True, + resolvable=True, ), ] = 1 moe_a2a_backend: A[ @@ -1722,7 +1722,7 @@ class ServerArgs: Arg( help="Choose the backend for MoE A2A.", choices=MOE_A2A_BACKEND_CHOICES, - model_overridable=True, + resolvable=True, ), ] = "none" moe_runner_backend: A[ @@ -1730,7 +1730,7 @@ class ServerArgs: Arg( help="Choose the runner backend for MoE.", choices=MOE_RUNNER_BACKEND_CHOICES, - model_overridable=True, + resolvable=True, ), ] = "auto" flashinfer_mxfp4_moe_precision: A[ @@ -1788,7 +1788,7 @@ class ServerArgs: Optional[int], Arg( help="TP size for MoE dense MLP layers. This flag is useful when, with large TP size, there are errors caused by weights in MLP layers having dimension smaller than the min dimension GEMM supports.", - model_overridable=True, + resolvable=True, ), ] = None elastic_ep_backend: A[ diff --git a/test/registered/unit/test_model_overrides.py b/test/registered/unit/test_model_overrides.py index 51508af95..14fc5cd90 100644 --- a/test/registered/unit/test_model_overrides.py +++ b/test/registered/unit/test_model_overrides.py @@ -16,7 +16,7 @@ from typing import Optional from unittest.mock import patch from sglang.srt.arg_groups import overrides as overrides_module -from sglang.srt.arg_groups.arg_utils import A, Arg, model_overridable_fields +from sglang.srt.arg_groups.arg_utils import A, Arg, resolvable_fields from sglang.srt.arg_groups.overrides import ( OverrideRecord, apply_declarations_to_server_args, @@ -37,18 +37,18 @@ from sglang.test.test_utils import CustomTestCase @dataclasses.dataclass class _FakeArgs: plain: A[int, "help text only"] = 0 - resolved_by_model: A[str, Arg(help="x", model_overridable=True)] = "auto" - also_resolved: A[Optional[int], Arg(help="y", model_overridable=True)] = None + resolved_by_model: A[str, Arg(help="x", resolvable=True)] = "auto" + also_resolved: A[Optional[int], Arg(help="y", resolvable=True)] = None metadata_but_not_overridable: A[bool, Arg(help="z")] = False class TestModelOverridableWhitelist(CustomTestCase): def test_arg_defaults_to_not_overridable(self): - self.assertFalse(Arg().model_overridable) + self.assertFalse(Arg().resolvable) def test_whitelist_derivation_from_annotated_metadata(self): self.assertEqual( - model_overridable_fields(_FakeArgs), + resolvable_fields(_FakeArgs), frozenset({"resolved_by_model", "also_resolved"}), ) @@ -59,7 +59,7 @@ class TestModelOverridableWhitelist(CustomTestCase): from sglang.srt.server_args import ServerArgs self.assertEqual( - model_overridable_fields(ServerArgs), + resolvable_fields(ServerArgs), frozenset( { "dtype", @@ -83,7 +83,7 @@ class TestModelOverridableWhitelist(CustomTestCase): ) def test_non_dataclass_yields_empty_whitelist(self): - self.assertEqual(model_overridable_fields(SimpleNamespace), frozenset()) + self.assertEqual(resolvable_fields(SimpleNamespace), frozenset()) class _IsolatedRegistry(CustomTestCase):