config: retire the last process-global config field reads (#33338)

`get_server_args().<field>` reads one process's startup record. Nine sites still
did that for a value that has a namespace: the attention backend (5),
`skip_tokenizer_init` (2), the draft-aware `load_format`, and a chunked-prefill
size in `sglang.kernels`. They now read `get_exec().kernel` / `get_serving()` /
`get_model()` / `get_schedule()`, so they see the resolved value including
post-publish overrides.

The multimodal processor's device selection moves to the instance it was
constructed with rather than to a namespace: `base_gpu_id` differs per worker (the
encode-server DP workers each specialise their own copy), so no process-global
value can stand in for it, and engines sharing a tokenizer process each need their
own. Branch order, the NPU preprocess patches, and the case that leaves "device"
unset are unchanged.

What stays on `get_server_args()` is the derived API — `@property` and method
members computed from several fields plus the HF config
(`mamba_cache_chunk_size`, `get_model_config()`, `enable_mamba_extra_buffer*`) —
plus three config-intent reads of live-shadowed sizes, each of which needs an
answer the live topology property cannot give (the DSA indexer's PP gate must
short-circuit before touching the PP group, `allocation`'s DCP gate asks whether
DCP was configured at all, and the CUDA-IPC recycler runs where no group exists).

A new AST ratchet pins both shapes it can see — the direct call and an alias
bound from it in the same function — at 0 and 12 respectively, exempting the
derived APIs and those three sites by name. The alias-form baseline is not zero:
those reads are mostly per-runner fields in model code, and lowering them is the
next slice.

Two fixtures stopped faking config: `test_dllm_fdfo_kv_reuse` rebound
`allocation.get_server_args` to a SimpleNamespace, which silently stops
intercepting the moment a reader migrates; it publishes a real config instead.
This commit is contained in:
Cheng Wan
2026-08-02 21:24:42 -07:00
committed by GitHub
parent aa3bbbc6e8
commit b8109b5d63
13 changed files with 307 additions and 57 deletions
+2 -2
View File
@@ -579,10 +579,10 @@ def prewarm_mhc_pre(
the TileLang/DeepGEMM on-disk JIT cache, so this cost is paid only on a cold
cache; later server runs hit the cache. Driven once per process from load_weights.
"""
from sglang.srt.runtime_context import get_server_args
from sglang.srt.runtime_context import get_schedule
hc_mult, hidden_size = residual.shape[-2], residual.shape[-1]
max_num_tokens = get_server_args().chunked_prefill_size
max_num_tokens = get_schedule().chunked_prefill_size
buckets = get_mhc_pre_token_count_representatives(
max_num_tokens, hc_mult * hidden_size
)
@@ -40,7 +40,7 @@ from sglang.srt.model_executor.forward_batch_info import (
compute_position,
)
from sglang.srt.model_executor.forward_context import get_attn_backend
from sglang.srt.runtime_context import get_device, get_parallel, get_server_args
from sglang.srt.runtime_context import get_device, get_exec, get_parallel
from sglang.srt.speculative.spec_info import SpecInput
from sglang.srt.utils import BumpAllocator, empty_context, get_bool_env_var, is_hip
@@ -634,7 +634,7 @@ class TboForwardBatchPreparer:
sum_field=None,
)
_, child_b.extend_start_loc = compute_position(
get_server_args().attention_backend,
get_exec().kernel.attention_backend,
child_b.extend_prefix_lens,
child_b.extend_seq_lens,
child_b.extend_num_tokens,
@@ -376,7 +376,9 @@ def attn_backend_wrapper(runner: "ModelRunner", full_attn_backend: "AttentionBac
"gdn_backend.sm100_flashinfer_default",
linear_attn_prefill_backend=prefill_default,
)
initialize_linear_attn_config(runner.server_args, prefill_default)
initialize_linear_attn_config(
runner.server_args, prefill_default=prefill_default
)
hybrid_backend_cls = HybridLinearAttnBackend
if hybrid_gdn_config(runner.model_config) is not None:
if is_blackwell():
@@ -18,7 +18,7 @@ from sglang.srt.layers.rotary_embedding.yarn import (
yarn_get_mscale_simple,
yarn_linear_ramp_mask,
)
from sglang.srt.runtime_context import get_exec, get_server_args
from sglang.srt.runtime_context import get_exec
from sglang.srt.utils import (
cpu_has_amx_support,
is_cuda,
@@ -42,7 +42,6 @@ if _is_xpu:
from sgl_kernel import multimodal_rotary_embedding
from sglang.kernels.ops.attention.mrope import apply_interleaved_rope_triton
from sglang.srt.runtime_context import get_server_args
def apply_interleaved_rope(x: torch.Tensor, mrope_section: list) -> torch.Tensor:
@@ -144,7 +143,7 @@ class MRotaryEmbedding(RotaryEmbedding):
last_dim = cos_sin.size()[-1]
cos, sin = cos_sin.chunk(2, dim=-1)
if self.mrope_interleaved:
if support_triton(get_server_args().attention_backend):
if support_triton(get_exec().kernel.attention_backend):
cos = apply_interleaved_rope_triton(cos, self.mrope_section)
sin = apply_interleaved_rope_triton(sin, self.mrope_section)
else:
+4 -3
View File
@@ -38,6 +38,7 @@ from sglang.srt.runtime_context import (
get_parallel,
get_schedule,
get_server_args,
get_serving,
)
from sglang.srt.utils import flatten_nested_list, is_hip, is_npu, print_warning_once
from sglang.srt.utils.stale_shm_cleanup import make_shm_name
@@ -554,7 +555,7 @@ def _acknowledge_deferred_cuda_ipc_cache_hits(
return
# The pool's recycler counts the whole TP group, so the acknowledgement must
# match that count even when an attention subgroup is smaller.
consumer_count = max(get_server_args().tp_size, 1)
consumer_count = max(parallel.tp_size, 1)
for item in items:
item.acknowledge_deferred_cuda_ipc_feature(consumer_count)
@@ -2024,7 +2025,7 @@ def wrap_shm_features(obj):
"""
Scan the object for multimodal tensors and wrap them in SHM pointers.
"""
if _get_is_default_transport() or get_server_args().skip_tokenizer_init:
if _get_is_default_transport() or get_serving().skip_tokenizer_init:
return obj
if obj.mm_inputs:
@@ -2085,7 +2086,7 @@ def unwrap_shm_features(obj):
Restore ShmPointerMMData wrappers back into standard torch.Tensors.
Handles both single requests and batch requests.
"""
if _get_is_default_transport() or get_server_args().skip_tokenizer_init:
if _get_is_default_transport() or get_serving().skip_tokenizer_init:
return obj
# Handle batch requests
if isinstance(obj, BaseBatchReq):
+3 -3
View File
@@ -26,7 +26,7 @@ from sglang.srt.mem_cache.common import (
evict_from_tree_cache,
)
from sglang.srt.mem_cache.memory_pool import HybridReqToTokenPool, ReqToTokenPool
from sglang.srt.runtime_context import get_server_args
from sglang.srt.runtime_context import get_exec, get_server_args
from sglang.srt.utils import (
is_cpu,
is_cuda,
@@ -65,7 +65,7 @@ def write_cache_indices(
prefix_tensors: list[torch.Tensor],
req_to_token_pool: ReqToTokenPool,
):
if support_triton(get_server_args().attention_backend):
if support_triton(get_exec().kernel.attention_backend):
prefix_pointers = torch.tensor(
[t.data_ptr() for t in prefix_tensors],
dtype=torch.uint64,
@@ -106,7 +106,7 @@ def get_last_loc(
req_pool_indices_tensor: torch.Tensor,
prefix_lens_tensor: torch.Tensor,
) -> torch.Tensor:
attn_backend = get_server_args().attention_backend
attn_backend = get_exec().kernel.attention_backend
uses_triton_dispatch = attn_backend not in ("ascend", "torch_native")
if _is_hip and uses_triton_dispatch:
+1 -2
View File
@@ -72,7 +72,6 @@ from sglang.srt.runtime_context import (
get_exec,
get_forward,
get_parallel,
get_server_args,
)
from sglang.srt.utils import (
LazyValue,
@@ -421,7 +420,7 @@ class GptOssAttention(nn.Module):
# Choose dtype of sinks based on attention backend: trtllm_mha requires float32,
# others can use bfloat16
attn_backend = get_server_args().attention_backend
attn_backend = get_exec().kernel.attention_backend
sinks_dtype = torch.float32 if attn_backend == "trtllm_mha" else torch.bfloat16
self.sinks = nn.Parameter(
torch.empty(self.num_heads, dtype=sinks_dtype), requires_grad=False
@@ -18,7 +18,7 @@ from sglang.srt.models.inkling_common.util import (
lora_compatible_layout_enabled,
)
from sglang.srt.models.llama import LlamaMLP
from sglang.srt.runtime_context import get_exec, get_server_args
from sglang.srt.runtime_context import get_exec, get_model
logger = logging.getLogger(__name__)
@@ -484,7 +484,7 @@ class InklingBatchDenseMLP(nn.Module, FusedMoELoadingMixin):
# All shared experts must share one global weight scale (reshard with
# single_global_scale=True). ModelOpt's input_scale = amax / (6 * 448).
flat2 = scale2.reshape(-1).float()
if get_server_args().load_format == "dummy" and not bool(
if get_model().load_format == "dummy" and not bool(
torch.all(flat2 == flat2[0])
):
# Dummy loading uses per-element noise; replace it with a valid scale.
@@ -20,7 +20,6 @@ from sglang.srt.managers.schedule_batch import (
MultimodalProcessorOutput,
)
from sglang.srt.multimodal.processors.executor import MultimodalProcessorExecutor
from sglang.srt.runtime_context import get_server_args
from sglang.srt.utils import (
CLIENT_MEDIA_EXCEPTIONS,
envs,
@@ -485,6 +484,37 @@ class BaseMultimodalProcessor(ABC):
return self._processor, self._tokenizer
return processor, processor.tokenizer
def _fast_image_processor_device(self, processor) -> Optional[str]:
"""The device for the fast image processor, or None to leave it unset.
Resolved from this processor's own ``server_args``: engines sharing a
tokenizer process each carry their own ``base_gpu_id``.
"""
server_args = self.server_args
if _is_cpu or server_args.rl_on_policy_target is not None:
return "cpu"
if _is_xpu:
return "xpu"
if not _is_npu:
return f"cuda:{server_args.base_gpu_id}"
if processor.__class__.__name__ not in {"Glm4vProcessor", "Glm46VProcessor"}:
# For qwen-vl, the processor hits a reshape issue from the Ascend
# dims restriction.
from sglang.srt.hardware_backend.npu.modules.qwen_vl_processor import (
npu_apply_qwen_image_preprocess_patch,
)
npu_apply_qwen_image_preprocess_patch()
return "npu"
if processor.__class__.__name__ == "Glm46VProcessor":
from sglang.srt.hardware_backend.npu.modules.glm46v_processor import (
npu_apply_glm46v_image_preprocess_patch,
)
npu_apply_glm46v_image_preprocess_patch()
return "npu"
return None
def process_mm_data(
self,
input_text,
@@ -537,31 +567,9 @@ class BaseMultimodalProcessor(ABC):
and isinstance(processor.image_processor, BaseImageProcessor)
and not self.disable_fast_image_processor
):
if _is_cpu or get_server_args().rl_on_policy_target is not None:
kwargs["device"] = "cpu"
elif _is_xpu:
kwargs["device"] = "xpu"
elif not _is_npu:
base_gpu_id = get_server_args().base_gpu_id
kwargs["device"] = f"cuda:{base_gpu_id}"
elif processor.__class__.__name__ not in {
"Glm4vProcessor",
"Glm46VProcessor",
}:
# Note: for qwen-vl, processor has some reshape issue because of dims restriction on Ascend.
from sglang.srt.hardware_backend.npu.modules.qwen_vl_processor import (
npu_apply_qwen_image_preprocess_patch,
)
npu_apply_qwen_image_preprocess_patch()
kwargs["device"] = "npu"
elif processor.__class__.__name__ == "Glm46VProcessor":
from sglang.srt.hardware_backend.npu.modules.glm46v_processor import (
npu_apply_glm46v_image_preprocess_patch,
)
npu_apply_glm46v_image_preprocess_patch()
kwargs["device"] = "npu"
device = self._fast_image_processor_device(processor)
if device is not None:
kwargs["device"] = device
# Avoid double BOS when the chat template already wrote one.
if self._tokenizer_auto_adds_specials and isinstance(input_text, str):