[CI][RFC] Replace black-jupyter with ruff-format (#37210)

Co-authored-by: Alison Shao <a.shao@wustl.edu>
This commit is contained in:
Alex Nails
2026-09-02 19:46:08 -07:00
committed by GitHub
co-authored by Alison Shao
parent 2641e427be
commit 28262c20df
1411 changed files with 7766 additions and 8176 deletions
@@ -91,9 +91,9 @@ def handle_attention_backend_compatibility(server_args: Any):
cfg.cuda_graph_config, Phase.PREFILL, backend=Backend.DISABLED
),
)
assert (
cfg.speculative_algorithm is None
), "Speculative decoding is currently not supported with Flex Attention backend"
assert cfg.speculative_algorithm is None, (
"Speculative decoding is currently not supported with Flex Attention backend"
)
# Whisper's encoder token padding conflicts with prefix caching.
# Only disable for Whisper; other encoder-decoder models (e.g., mllama) use radix cache.
+40 -25
View File
@@ -148,7 +148,7 @@ def apply_cuda_graph_compatibility(server_args: Any):
and attention_backends_of(resolved_view(server_args))[0] != "trtllm_mla"
):
logger.info(
"Using tc_piecewise CUDA graph for validated multimodal " "decoder prefill."
"Using tc_piecewise CUDA graph for validated multimodal decoder prefill."
)
declare_resolution(
server_args,
@@ -183,16 +183,20 @@ def disable_tc_piecewise_cudagraph_if_incompatible(server_args: Any):
("pipeline parallelism (pp_size > 1)", lambda: cfg.pp_size > 1),
(
"non-CUDA hardware (HIP/NPU/CPU/MPS/XPU)",
lambda: get_platform().is_hip
or get_platform().is_npu
or is_cpu()
or is_mps()
or get_platform().is_xpu,
lambda: (
get_platform().is_hip
or get_platform().is_npu
or is_cpu()
or is_mps()
or get_platform().is_xpu
),
),
(
"OOT platform without piecewise support",
lambda: current_platform.is_out_of_tree()
and not current_platform.support_piecewise_cuda_graph(),
lambda: (
current_platform.is_out_of_tree()
and not current_platform.support_piecewise_cuda_graph()
),
),
(
"MoE A2A backend",
@@ -203,16 +207,20 @@ def disable_tc_piecewise_cudagraph_if_incompatible(server_args: Any):
("LoRA", lambda: bool(cfg.lora_paths) or cfg.enable_lora),
(
"multimodal model",
lambda: model_config_of(server_args).is_multimodal
and not model_config_of(
server_args
).is_multimodal_piecewise_cuda_graph_supported,
lambda: (
model_config_of(server_args).is_multimodal
and not model_config_of(
server_args
).is_multimodal_piecewise_cuda_graph_supported
),
),
(
"GGUF quantization",
lambda: cfg.load_format == "gguf"
or resolved_view(server_args).quantization == "gguf"
or check_gguf_file(cfg.model_path),
lambda: (
cfg.load_format == "gguf"
or resolved_view(server_args).quantization == "gguf"
or check_gguf_file(cfg.model_path)
),
),
("DLLM (diffusion LLM)", lambda: cfg.dllm_algorithm is not None),
(
@@ -227,8 +235,9 @@ def disable_tc_piecewise_cudagraph_if_incompatible(server_args: Any):
("symmetric memory", lambda: cfg.enable_symm_mem),
(
"expert distribution recorder",
lambda: cfg.enable_eplb
or cfg.expert_distribution_recorder_mode is not None,
lambda: (
cfg.enable_eplb or cfg.expert_distribution_recorder_mode is not None
),
),
(
"context parallel (attn_cp_size > 1)",
@@ -279,8 +288,10 @@ def disable_breakable_cudagraph_if_incompatible(server_args: Any):
# CP all_gather replay size mismatch under BCG.
(
"context parallel (attn_cp_size > 1)",
lambda: resolved_view(server_args).attn_cp_size > 1
and not supports_prefill_cp_bcg(server_args),
lambda: (
resolved_view(server_args).attn_cp_size > 1
and not supports_prefill_cp_bcg(server_args)
),
),
# Capture builds a dummy extend forward with attn_dcp_metadata=None.
(
@@ -294,16 +305,20 @@ def disable_breakable_cudagraph_if_incompatible(server_args: Any):
),
(
"unvalidated a2a backend",
lambda: resolved_view(server_args).moe_a2a_backend
not in ("none", "deepep", "megamoe", "flashinfer"),
lambda: (
resolved_view(server_args).moe_a2a_backend
not in ("none", "deepep", "megamoe", "flashinfer")
),
),
# Multimodal prefill replay faults under BCG; allowlisted archs opt back in.
(
"multimodal model",
lambda: model_config_of(server_args).is_multimodal
and not model_config_of(
server_args
).is_multimodal_breakable_cuda_graph_supported,
lambda: (
model_config_of(server_args).is_multimodal
and not model_config_of(
server_args
).is_multimodal_breakable_cuda_graph_supported
),
),
]
for name, predicate in rules:
@@ -148,11 +148,13 @@ def apply_deepseek_v4_defaults(server_args: ServerArgs, model_arch: str) -> None
assert cfg.speculative_algorithm in (
"EAGLE",
"DSPARK",
), f"Only EAGLE and DSPARK speculative algorithms are supported for {model_arch}"
), (
f"Only EAGLE and DSPARK speculative algorithms are supported for {model_arch}"
)
if cfg.speculative_algorithm == "EAGLE":
assert (
cfg.speculative_eagle_topk == 1
), f"Only EAGLE speculative algorithm with topk == 1 is supported for {model_arch}"
assert cfg.speculative_eagle_topk == 1, (
f"Only EAGLE speculative algorithm with topk == 1 is supported for {model_arch}"
)
def validate_deepseek_v4_cp(server_args: ServerArgs) -> None:
@@ -163,7 +165,7 @@ def validate_deepseek_v4_cp(server_args: ServerArgs) -> None:
if cfg.cp_strategy != "interleave":
raise ValueError(
"DeepSeekV4 only supports interleave CP strategy, " f"got {cfg.cp_strategy}"
f"DeepSeekV4 only supports interleave CP strategy, got {cfg.cp_strategy}"
)
declare_resolution(
@@ -196,12 +198,12 @@ def validate_deepseek_v4_cp(server_args: ServerArgs) -> None:
"validate_deepseek_v4_cp",
attn_cp_size=cfg.tp_size // cfg.dp_size,
)
assert (
cfg.dp_size == 1
), "For round-robin split mode, dp attention is not supported."
assert (
cfg.tp_size <= 8
), "Context parallel only supports single machine (tp_size <= 8). Cross-machine CP has precision issues."
assert cfg.dp_size == 1, (
"For round-robin split mode, dp attention is not supported."
)
assert cfg.tp_size <= 8, (
"Context parallel only supports single machine (tp_size <= 8). Cross-machine CP has precision issues."
)
supported_a2a_backends = ("none", "deepep", "megamoe", "mori")
if cfg.moe_a2a_backend not in supported_a2a_backends:
raise ValueError(
@@ -96,9 +96,9 @@ def validate_hisparse(server_args: ServerArgs) -> None:
"models (e.g., DeepSeek V3.2, GLM-5) and DeepSeek V4 now. "
)
assert (
cfg.disable_radix_cache
), "Hierarchical sparse attention currently requires --disable-radix-cache."
assert cfg.disable_radix_cache, (
"Hierarchical sparse attention currently requires --disable-radix-cache."
)
# DSv4 hisparse handles its own dtype/backend pairing elsewhere; the dtype-
# aware checks below only apply to the DSA hisparse path.
+12 -12
View File
@@ -76,9 +76,9 @@ def check_lora_server_args(server_args: Any):
pinned=False,
)
elif isinstance(lora_path, dict):
assert (
"lora_name" in lora_path and "lora_path" in lora_path
), f"When providing LoRA paths as a list of dict, each dict should contain 'lora_name' and 'lora_path' keys. Got: {lora_path}"
assert "lora_name" in lora_path and "lora_path" in lora_path, (
f"When providing LoRA paths as a list of dict, each dict should contain 'lora_name' and 'lora_path' keys. Got: {lora_path}"
)
lora_ref = LoRARef(
lora_id=LoRARef.deterministic_id(
lora_path["lora_name"], lora_path["lora_path"]
@@ -129,14 +129,14 @@ def check_lora_server_args(server_args: Any):
lora_target_modules=set(cfg.lora_target_modules),
)
if "all" in cfg.lora_target_modules:
assert (
len(cfg.lora_target_modules) == 1
), "If 'all' is specified in --lora-target-modules, it should be the only module specified."
assert len(cfg.lora_target_modules) == 1, (
"If 'all' is specified in --lora-target-modules, it should be the only module specified."
)
# Ensure sufficient information is provided for LoRA initialization.
assert cfg.lora_paths or (
cfg.max_lora_rank and cfg.lora_target_modules
), "When no initial --lora-paths is provided, you need to specify both --max-lora-rank and --lora-target-modules for LoRA initialization."
assert cfg.lora_paths or (cfg.max_lora_rank and cfg.lora_target_modules), (
"When no initial --lora-paths is provided, you need to specify both --max-lora-rank and --lora-target-modules for LoRA initialization."
)
# Validate max_loaded_loras
if cfg.max_loaded_loras is not None:
@@ -158,9 +158,9 @@ def check_lora_server_args(server_args: Any):
if cfg.lora_use_virtual_experts:
logger.info("Virtual expert computation enabled.")
assert (
cfg.lora_drain_wait_threshold >= 0.0
), "--lora-drain-wait-threshold must be non-negative."
assert cfg.lora_drain_wait_threshold >= 0.0, (
"--lora-drain-wait-threshold must be non-negative."
)
def check_lora_speculative_compatibility(server_args: Any):
+9 -9
View File
@@ -97,9 +97,9 @@ def handle_int8_mamba_checkpoint(server_args: Any):
def validate_mamba_extra_buffer(view, model_arch: str, *, mamba_cache_chunk_size_of):
assert supports_mamba_cache_extra_buffer(
view, model_arch
), f"extra_buffer is not supported for {model_arch}; use no_buffer."
assert supports_mamba_cache_extra_buffer(view, model_arch), (
f"extra_buffer is not supported for {model_arch}; use no_buffer."
)
assert (
get_platform().is_cuda
or get_platform().is_musa
@@ -142,9 +142,9 @@ def validate_mamba_extra_buffer(view, model_arch: str, *, mamba_cache_chunk_size
def validate_mamba_no_buffer(view, model_arch: str):
assert view.page_size in (1, None), "no_buffer only supports page_size=1."
assert (
view.disable_overlap_schedule
), "no_buffer do not support overlap schedule. Try to set disable_overlap_schedule=True."
assert (
view.attention_backend != "trtllm_mha"
), "no_buffer do not support trtllm_mha attention backend."
assert view.disable_overlap_schedule, (
"no_buffer do not support overlap schedule. Try to set disable_overlap_schedule=True."
)
assert view.attention_backend != "trtllm_mha", (
"no_buffer do not support trtllm_mha attention backend."
)
+3 -3
View File
@@ -177,9 +177,9 @@ def handle_gpu_memory_settings(server_args: Any, gpu_mem):
)
decode_cuda_graph_config.bs = generate_cpu_graph_batch_sizes(server_args)
assert (
cfg.torch_compile_max_bs > 0
), "cuda_graph_config[decode].bs should contain positive batch sizes"
assert cfg.torch_compile_max_bs > 0, (
"cuda_graph_config[decode].bs should contain positive batch sizes"
)
decode_cuda_graph_config.max_bs = cfg.torch_compile_max_bs
if prefill_cuda_graph_config.max_bs is None:
+15 -13
View File
@@ -218,9 +218,9 @@ def handle_model_specific_adjustments(server_args: Any):
run_post_process_pass(server_args, _dsa_split_backend_resolution)
if cfg.enable_prefill_cp:
assert (
cfg.disaggregation_mode != "decode"
), "CP is only supported for prefill when PD disaggregation, please remove --enable-prefill-cp."
assert cfg.disaggregation_mode != "decode", (
"CP is only supported for prefill when PD disaggregation, please remove --enable-prefill-cp."
)
if (
cfg.enable_dsa_cache_layer_split
and cfg.disaggregation_mode != "prefill"
@@ -423,9 +423,9 @@ def handle_model_specific_adjustments(server_args: Any):
# (arg_groups/overrides.py: _gpt_oss_overrides).
if resolved_view(server_args).moe_runner_backend == "triton_kernel":
assert (
resolved_view(server_args).ep_size == 1
), "Triton kernel MoE is only supported when ep_size == 1"
assert resolved_view(server_args).ep_size == 1, (
"Triton kernel MoE is only supported when ep_size == 1"
)
elif model_arch in ("MiMoV2ForCausalLM", "MiMoV2FlashForCausalLM"):
if model_arch == "MiMoV2ForCausalLM" and not cfg.encoder_only:
@@ -481,7 +481,9 @@ def handle_model_specific_adjustments(server_args: Any):
"ascend",
"trtllm_mha",
"intel_xpu",
}, f"fa3, aiter, triton, ascend, trtllm_mha or intel_xpu is required for Llama4 model but got {attention_backend}"
}, (
f"fa3, aiter, triton, ascend, trtllm_mha or intel_xpu is required for Llama4 model but got {attention_backend}"
)
# The moe_runner_backend selection moved to the override registry
# (arg_groups/overrides.py: _llama4_overrides).
# Gemma2/Gemma3 (disable_hybrid_swa_memory) moved to the override registry
@@ -523,9 +525,9 @@ def handle_model_specific_adjustments(server_args: Any):
# https://docs.sglang.ai/advanced_features/attention_backend.html
accepted_backends = ["fa3", "triton", "trtllm_mha"]
attention_backend = resolved_view(server_args).attention_backend
assert (
attention_backend in accepted_backends
), f"One of the attention backends in {accepted_backends} is required for {model_arch}, but got {attention_backend}"
assert attention_backend in accepted_backends, (
f"One of the attention backends in {accepted_backends} is required for {model_arch}, but got {attention_backend}"
)
elif model_arch in ["Olmo2ForCausalLM"]:
# disable_hybrid_swa_memory + attention backend selection moved to
# the override registry (arg_groups/overrides.py: _olmo2_overrides).
@@ -534,9 +536,9 @@ def handle_model_specific_adjustments(server_args: Any):
# is used for the Olmo2 architecture. Olmo2 does not use sliding window attention
# but Olmo3 does.
attention_backend = resolved_view(server_args).attention_backend
assert (
attention_backend != "flashinfer"
), "FlashInfer backend can significantly degrade the performance of Olmo3 models."
assert attention_backend != "flashinfer", (
"FlashInfer backend can significantly degrade the performance of Olmo3 models."
)
logger.info(f"Using {attention_backend} as attention backend for {model_arch}.")
elif model_arch in [
@@ -59,12 +59,12 @@ def _deepseek_family_overrides(server_args: Any, hf_config: Any) -> dict:
"moe_a2a_backend=deepep, ep_size=tp_size, batch_size=1."
)
else:
assert (
cfg.dp_size == 1
), "interleave DSA CP does not support DP attention."
assert (
cfg.tp_size <= 8
), "Context parallel only supports single machine (tp_size <= 8). Cross-machine CP has precision issues."
assert cfg.dp_size == 1, (
"interleave DSA CP does not support DP attention."
)
assert cfg.tp_size <= 8, (
"Context parallel only supports single machine (tp_size <= 8). Cross-machine CP has precision issues."
)
# Note(kpham-sgl): Keep attn_tp_size == 1 under DSA CP.
# DSACPLayerCommunicator does not all-reduce attention-TP
# partial o_proj outputs before replicated dense FFNs.
@@ -70,7 +70,5 @@ def _deepseek_v4_overrides(server_args: Any, hf_config: Any) -> dict:
)
):
overrides["moe_runner_backend"] = "flashinfer_mxfp4"
logger.info(
"Use flashinfer_mxfp4 as MoE runner backend for " f"{model_arch}."
)
logger.info(f"Use flashinfer_mxfp4 as MoE runner backend for {model_arch}.")
return overrides
@@ -67,7 +67,6 @@ def _gpt_oss_overrides(server_args: Any, hf_config: Any) -> dict:
# use bf16 for mxfp4 triton kernels
overrides["dtype"] = "bfloat16"
if cfg.moe_runner_backend == "auto":
if get_platform().is_sm100 and is_mxfp4_quant_format:
overrides["moe_runner_backend"] = "flashinfer_mxfp4"
logger.warning(
+18 -8
View File
@@ -47,7 +47,9 @@ def handle_moe_kernel_config(server_args: Any):
"modelopt_fp8",
"modelopt_mixed",
None,
], f"Invalid quantization '{view.quantization}'. \nFlashInfer Cutlass MOE supports only: 'modelopt_fp4', 'modelopt_fp8', 'modelopt_mixed', or bfloat16 (None)."
], (
f"Invalid quantization '{view.quantization}'. \nFlashInfer Cutlass MOE supports only: 'modelopt_fp4', 'modelopt_fp8', 'modelopt_mixed', or bfloat16 (None)."
)
assert view.ep_size in [
1,
cfg.tp_size,
@@ -58,7 +60,9 @@ def handle_moe_kernel_config(server_args: Any):
assert (
view.quantization in ["modelopt_fp4", "modelopt_mixed", "nvfp4_online"]
or model_config_of(server_args).nvfp4_moe_meta is not None
), f"Invalid quantization '{view.quantization}'. \nFlashInfer CuteDSL MOE currently supports only: 'modelopt_fp4', 'modelopt_mixed' (with NVFP4 MoE layers), 'nvfp4_online', or hybrid NVFP4 models."
), (
f"Invalid quantization '{view.quantization}'. \nFlashInfer CuteDSL MOE currently supports only: 'modelopt_fp4', 'modelopt_mixed' (with NVFP4 MoE layers), 'nvfp4_online', or hybrid NVFP4 models."
)
assert view.ep_size in [
1,
cfg.tp_size,
@@ -90,7 +94,9 @@ def handle_moe_kernel_config(server_args: Any):
"modelopt_mixed",
"compressed-tensors",
None,
], f"Invalid quantization '{view.quantization}'. \nFlashInfer TRTLLM MOE supports only: 'modelopt_fp4', 'nvfp4_online', 'fp8', 'modelopt_fp8', 'modelopt_mixed', 'compressed-tensors', or bfloat16 (None)."
], (
f"Invalid quantization '{view.quantization}'. \nFlashInfer TRTLLM MOE supports only: 'modelopt_fp4', 'nvfp4_online', 'fp8', 'modelopt_fp8', 'modelopt_mixed', 'compressed-tensors', or bfloat16 (None)."
)
if view.moe_runner_backend == "flashinfer_trtllm_routed":
assert view.quantization in [
@@ -100,7 +106,9 @@ def handle_moe_kernel_config(server_args: Any):
"modelopt_mixed",
"nvfp4_online",
None,
], f"Invalid quantization '{view.quantization}'. \nFlashInfer TRTLLM routed MOE supports only: 'fp8', 'mxfp8', 'modelopt_fp4', 'modelopt_mixed', 'nvfp4_online', or bfloat16 (None)."
], (
f"Invalid quantization '{view.quantization}'. \nFlashInfer TRTLLM routed MOE supports only: 'fp8', 'mxfp8', 'modelopt_fp4', 'modelopt_mixed', 'nvfp4_online', or bfloat16 (None)."
)
# The runner-driven shared-experts fusion disables moved to the
# pipeline (arg_groups/overrides.py: _moe_runner_fusion_disable),
@@ -113,9 +121,9 @@ def handle_moe_kernel_config(server_args: Any):
"fp8",
"mxfp8",
]:
assert (
resolved_view(server_args).ep_size == 1
), "FP8/MXFP8 Cutlass MoE is only supported with ep_size == 1"
assert resolved_view(server_args).ep_size == 1, (
"FP8/MXFP8 Cutlass MoE is only supported with ep_size == 1"
)
def handle_a2a_moe(server_args: Any):
@@ -256,7 +264,9 @@ def handle_a2a_moe(server_args: Any):
assert (
resolved_view(server_args).enable_dp_attention
and cfg.dp_size == cfg.tp_size
), "Flashinfer MoE A2A is only supported with dp_size == tp_size and --enable-dp-attention"
), (
"Flashinfer MoE A2A is only supported with dp_size == tp_size and --enable-dp-attention"
)
if cfg.deepep_mode != "auto":
logger.warning("--deepep-mode is ignored for Flashinfer MoE A2A")
use_cutedsl_w4a16 = (
+14 -14
View File
@@ -449,8 +449,9 @@ import sglang.srt.arg_groups.model_overrides # noqa: F401
@register_model_override_predicate(
lambda arch: "Step3p5ForCausalLM" in arch
or "Step3p7ForConditionalGeneration" in arch
lambda arch: (
"Step3p5ForCausalLM" in arch or "Step3p7ForConditionalGeneration" in arch
)
)
def _step3p_overrides(server_args: Any, hf_config: Any) -> dict:
cfg = resolving_view(server_args)
@@ -1261,9 +1262,9 @@ def _cutedsl_prefill_backend_fill(view: Any) -> dict:
or view.prefill_attention_backend == "cutedsl_mla"
):
return {}
assert (
view.prefill_attention_backend != "cutedsl_mla"
), "CuteDSL MLA only supports decoding for now"
assert view.prefill_attention_backend != "cutedsl_mla", (
"CuteDSL MLA only supports decoding for now"
)
if not get_platform().is_sm100:
raise ValueError(
"CuteDSL MLA backend is only supported on Blackwell GPUs (SM100). Please use a different backend."
@@ -1435,12 +1436,12 @@ def _dp_lm_head_validation(view: Any) -> dict:
dp LM head and the TP LM-head all-to-all path. Reads the mid-resolution
values through the view."""
if view.enable_dp_lm_head:
assert (
view.enable_dp_attention
), "Please enable dp attention when setting enable_dp_lm_head. "
assert view.enable_dp_attention, (
"Please enable dp attention when setting enable_dp_lm_head. "
)
if view.enable_tp_lm_head_all_to_all:
assert view.enable_dp_attention, (
"Please enable dp attention when setting " "enable_tp_lm_head_all_to_all."
"Please enable dp attention when setting enable_tp_lm_head_all_to_all."
)
assert not view.enable_dp_lm_head, (
"--enable-tp-lm-head-all-to-all uses a TP-sharded LM head and is "
@@ -1500,7 +1501,7 @@ def _moe_runner_backend_quant_constraints(view: Any) -> dict:
moe_runner_backend = mxfp8_default
elif moe_runner_backend not in allowed:
logger.warning(
"mxfp8 quantization supports only %s backends. " "Overriding %r.",
"mxfp8 quantization supports only %s backends. Overriding %r.",
", ".join(allowed),
moe_runner_backend,
)
@@ -1845,7 +1846,6 @@ def mamba_cache_chunk_size(server_args: Any) -> int:
from sglang.srt.arg_groups.overrides import model_config_of
if not hasattr(server_args, "_mamba_cache_chunk_size"):
try:
from sglang.kernels.ops.attention.fla.chunk_delta_h import (
CHUNK_SIZE as FLA_CHUNK_SIZE,
@@ -1857,9 +1857,9 @@ def mamba_cache_chunk_size(server_args: Any) -> int:
hf_config = model_config_of(server_args).hf_config
chunk_size = getattr(hf_config, "mamba_chunk_size", FLA_CHUNK_SIZE)
page_size = resolved_view(server_args).page_size
assert (
max(chunk_size, page_size) % min(chunk_size, page_size) == 0
), f"For SSM models, either chunk_size or page_size must be divisible by the other, got {chunk_size=}, {page_size=}"
assert max(chunk_size, page_size) % min(chunk_size, page_size) == 0, (
f"For SSM models, either chunk_size or page_size must be divisible by the other, got {chunk_size=}, {page_size=}"
)
if not getattr(server_args, "_resolution_finished", False):
return max(chunk_size, page_size)
server_args._mamba_cache_chunk_size = max(chunk_size, page_size)
+56 -56
View File
@@ -59,8 +59,7 @@ def handle_context_parallelism(server_args: Any):
and not cfg.language_model_only
):
raise ValueError(
"MiMo V2 CP-v2 only supports text inference; add "
"--language-only."
"MiMo V2 CP-v2 only supports text inference; add --language-only."
)
if cfg.enable_prefill_cp and cfg.cp_strategy is None:
@@ -81,40 +80,40 @@ def handle_context_parallelism(server_args: Any):
view = resolved_view(server_args)
if view.attn_cp_size > 1:
# The tp_size is the world size, not the real tensor parallel size
assert (
cfg.tp_size % view.attn_cp_size == 0
), "tp_size must be divisible by attn_cp_size"
assert (
cfg.tp_size % (cfg.dp_size * view.attn_cp_size) == 0
), "tp_size must be divisible by dp_size * attn_cp_size"
assert cfg.tp_size % view.attn_cp_size == 0, (
"tp_size must be divisible by attn_cp_size"
)
assert cfg.tp_size % (cfg.dp_size * view.attn_cp_size) == 0, (
"tp_size must be divisible by dp_size * attn_cp_size"
)
assert (
not cfg.enable_aiter_allreduce_fusion
), "Aiter allreduce fusion is not supported with context parallelism"
assert not cfg.enable_aiter_allreduce_fusion, (
"Aiter allreduce fusion is not supported with context parallelism"
)
if cfg.moe_dp_size > 1:
# The tp_size is the world size, not the real tensor parallel size
assert (
cfg.tp_size % cfg.moe_dp_size == 0
), "tp_size must be divisible by moe_dp_size"
assert (
view.ep_size * cfg.moe_dp_size <= cfg.tp_size
), "ep_size * moe_dp_size must be less than or equal to tp_size"
assert cfg.tp_size % cfg.moe_dp_size == 0, (
"tp_size must be divisible by moe_dp_size"
)
assert view.ep_size * cfg.moe_dp_size <= cfg.tp_size, (
"ep_size * moe_dp_size must be less than or equal to tp_size"
)
assert cfg.pp_size == 1, "PP is not supported with context parallelism"
if view.ep_size > 1:
assert (
view.ep_size * cfg.moe_dp_size == cfg.tp_size
), "ep_size * moe_dp_size must be equal to tp_size"
assert view.ep_size * cfg.moe_dp_size == cfg.tp_size, (
"ep_size * moe_dp_size must be equal to tp_size"
)
assert (
not cfg.enable_aiter_allreduce_fusion
), "Aiter allreduce fusion is not supported with context parallelism"
assert not cfg.enable_aiter_allreduce_fusion, (
"Aiter allreduce fusion is not supported with context parallelism"
)
if view.attn_cp_size != cfg.moe_dp_size:
assert (
cfg.moe_dp_size == 1
), "attn_cp_size != moe_dp_size is only supported when moe_dp_size == 1"
assert cfg.moe_dp_size == 1, (
"attn_cp_size != moe_dp_size is only supported when moe_dp_size == 1"
)
from sglang.srt.layers.cp.base import init_cp_strategy
@@ -244,26 +243,26 @@ def handle_dwdp(server_args: Any):
if cfg.dwdp_size <= 1:
return
assert (
cfg.dwdp_size >= 2
), f"dwdp_size must be >= 2 when enabled, got {cfg.dwdp_size}"
assert (
cfg.dwdp_size == cfg.tp_size
), f"dwdp_size ({cfg.dwdp_size}) must equal tp_size ({cfg.tp_size})"
assert cfg.dwdp_size >= 2, (
f"dwdp_size must be >= 2 when enabled, got {cfg.dwdp_size}"
)
assert cfg.dwdp_size == cfg.tp_size, (
f"dwdp_size ({cfg.dwdp_size}) must equal tp_size ({cfg.tp_size})"
)
assert cfg.disaggregation_mode in (
"null",
"prefill",
), "DWDP requires --disaggregation-mode null or prefill"
assert (
not cfg.enable_eplb
), "EPLB dynamic migration conflicts with static DWDP partitioning"
assert (
cfg.speculative_algorithm is None
), "DWDP does not support speculative decoding (MTP/draft workers)"
assert not cfg.enable_eplb, (
"EPLB dynamic migration conflicts with static DWDP partitioning"
)
assert cfg.speculative_algorithm is None, (
"DWDP does not support speculative decoding (MTP/draft workers)"
)
assert cfg.pp_size == 1, "DWDP requires pp_size == 1"
assert (
not cfg.enable_two_batch_overlap
), "DWDP's prefetch event protocol does not support two-batch overlap"
assert not cfg.enable_two_batch_overlap, (
"DWDP's prefetch event protocol does not support two-batch overlap"
)
if cfg.disaggregation_mode == "null":
logger.warning(
@@ -359,7 +358,9 @@ def handle_elastic_ep(server_args: Any):
assert cfg.eplb_algorithm in [
"elasticity_aware",
"elasticity_aware_hierarchical",
], "Elastic EP requires eplb_algorithm to be set to 'auto' or 'elasticity_aware(_hierarchical)'."
], (
"Elastic EP requires eplb_algorithm to be set to 'auto' or 'elasticity_aware(_hierarchical)'."
)
assert cfg.pp_size == 1, "PP size should be set to 1 under elastic EP"
@@ -370,9 +371,9 @@ def handle_elastic_ep(server_args: Any):
mooncake_ib_device=validate_ib_devices(cfg.mooncake_ib_device),
)
if cfg.ep_join_mode is not None:
assert (
cfg.elastic_ep_backend is not None
), "--elastic-ep-join-mode requires --elastic-ep-backend to be set."
assert cfg.elastic_ep_backend is not None, (
"--elastic-ep-join-mode requires --elastic-ep-backend to be set."
)
if cfg.ep_join_mode == "scale":
assert cfg.node_rank == 1, (
"Elastic EP scale-up requires one joining TP group at "
@@ -390,9 +391,9 @@ def handle_elastic_ep(server_args: Any):
)
assert cfg.ep_join_rank_offset >= 0, "elastic EP join rank offset must be >= 0."
if cfg.max_ep_size is not None:
assert (
cfg.elastic_ep_backend is not None
), "--max-ep-size requires --elastic-ep-backend to be set."
assert cfg.elastic_ep_backend is not None, (
"--max-ep-size requires --elastic-ep-backend to be set."
)
assert cfg.max_ep_size > 0, "--max-ep-size must be a positive integer."
scaling_active = (
@@ -407,16 +408,15 @@ def handle_elastic_ep(server_args: Any):
)
if scaling_active:
resolved = resolved_view(server_args)
assert (
cfg.elastic_ep_scale_timeout > 0
), "--elastic-ep-scale-timeout must be greater than zero."
assert cfg.elastic_ep_scale_timeout > 0, (
"--elastic-ep-scale-timeout must be greater than zero."
)
assert cfg.tokenizer_worker_num == 1, (
"Elastic EP runtime scale-up currently requires "
"--tokenizer-worker-num 1."
"Elastic EP runtime scale-up currently requires --tokenizer-worker-num 1."
)
assert not cfg.use_ray, (
"Elastic EP runtime scale-up does not support --use-ray."
)
assert (
not cfg.use_ray
), "Elastic EP runtime scale-up does not support --use-ray."
assert not cfg.enable_elastic_expert_backup, (
"Elastic EP runtime scale-up does not support "
"--enable-elastic-expert-backup."
@@ -129,9 +129,9 @@ def handle_pd_disaggregation(server_args: ServerArgs) -> None:
)
elif cfg.disaggregation_mode == "prefill":
assert (
cfg.disaggregation_transfer_backend != "fake"
), "Prefill server does not support 'fake' as the transfer backend"
assert cfg.disaggregation_transfer_backend != "fake", (
"Prefill server does not support 'fake' as the transfer backend"
)
if envs.SGLANG_RUST_SERVER.get():
_alias_bootstrap_port_to_api_port(server_args)
+4 -7
View File
@@ -75,7 +75,7 @@ def handle_ssl_validation(server_args: Any):
if cfg.enable_http2:
if not 0 < cfg.http2_max_concurrent_streams < 2**32:
raise ValueError(
"--http2-max-concurrent-streams must be between 1 and " "4294967295."
"--http2-max-concurrent-streams must be between 1 and 4294967295."
)
if not 1024 <= cfg.http2_initial_connection_window_size < 2**31:
raise ValueError(
@@ -343,8 +343,7 @@ def handle_deprecated_args(server_args: Any):
)
if cfg.grpc_worker_threads is not None and cfg.grpc_worker_threads < 1:
raise ValueError(
"SGLANG_GRPC_WORKER_THREADS "
f"({cfg.grpc_worker_threads}) must be >= 1"
f"SGLANG_GRPC_WORKER_THREADS ({cfg.grpc_worker_threads}) must be >= 1"
)
# Native gRPC is incompatible with launch paths it doesn't wire into.
@@ -482,8 +481,7 @@ def handle_other_validations(server_args: Any):
)
elif resolved_view(server_args).uses_mamba_radix_cache:
logger.warning(
"Optimistic prefill does not support models that use "
"mamba radix cache."
"Optimistic prefill does not support models that use mamba radix cache."
)
declare_resolution(
server_args,
@@ -851,8 +849,7 @@ def handle_multimodal_feature_transport(server_args: Any):
raise ValueError("--mm-feature-transport=cuda_vmm requires NVIDIA CUDA.")
if cfg.pp_size != 1:
raise ValueError(
"--mm-feature-transport=cuda_vmm does not support pipeline "
"parallelism."
"--mm-feature-transport=cuda_vmm does not support pipeline parallelism."
)
if envs.SGLANG_RUST_SERVER.get():
raise ValueError(
@@ -559,7 +559,6 @@ def _resolve_dflash_draft_attention_backend(server_args: ServerArgs) -> None:
draft_backend = cfg.speculative_draft_attention_backend
if draft_backend is None:
draft_backend, _ = attention_backends_of(resolved_view(server_args))
if draft_backend is None:
draft_backend = fallback_backend
+54 -50
View File
@@ -31,9 +31,9 @@ def check_server_args(server_args: Any):
# Check parallel size constraints
if cfg.ep_join_mode != "scale":
assert (
cfg.tp_size * cfg.pp_size
) % cfg.nnodes == 0, "tp_size must be divisible by number of nodes"
assert (cfg.tp_size * cfg.pp_size) % cfg.nnodes == 0, (
"tp_size must be divisible by number of nodes"
)
assert cfg.pp_max_micro_batch_size is None or cfg.pp_max_micro_batch_size >= 1, (
"pp_max_micro_batch_size must be a positive integer or None (for auto-compute). "
@@ -49,18 +49,18 @@ def check_server_args(server_args: Any):
)
if cfg.pp_size > 1:
assert (
cfg.disable_overlap_schedule and cfg.speculative_algorithm is None
), "Pipeline parallelism is not compatible with overlap schedule, speculative decoding"
assert cfg.disable_overlap_schedule and cfg.speculative_algorithm is None, (
"Pipeline parallelism is not compatible with overlap schedule, speculative decoding"
)
assert cfg.min_free_slots_delay is None, (
"--min-free-slots-delay is not supported with pipeline "
"parallelism: allocatable slots per microbatch are bounded by "
"pp-max-micro-batch-size, so the threshold may never be reached"
)
assert not (
cfg.dp_size > 1 and cfg.nnodes != 1 and not cfg.enable_dp_attention
), "multi-node data parallel is not supported unless dp attention!"
assert not (cfg.dp_size > 1 and cfg.nnodes != 1 and not cfg.enable_dp_attention), (
"multi-node data parallel is not supported unless dp attention!"
)
assert cfg.base_gpu_id >= 0, "base_gpu_id must be non-negative"
assert cfg.gpu_id_step >= 1, "gpu_id_step must be positive"
@@ -102,24 +102,24 @@ def check_server_args(server_args: Any):
# Skip validation if chunked prefill is disabled (i.e., size <= 0).
# Skip validation if disaggregation mode is decode.
if cfg.chunked_prefill_size > 0 and cfg.disaggregation_mode != "decode":
assert (
cfg.chunked_prefill_size % cfg.page_size == 0
), "chunked_prefill_size must be divisible by page_size"
assert cfg.chunked_prefill_size % cfg.page_size == 0, (
"chunked_prefill_size must be divisible by page_size"
)
# Check pdmux
if cfg.enable_pdmux:
assert (
cfg.pp_size == 1
), "PD-Multiplexing is only supported with pipeline parallelism disabled (pp_size=1)."
assert (
cfg.chunked_prefill_size == -1
), "PD-Multiplexing is not compatible with chunked prefill."
assert (
cfg.disaggregation_mode == "null"
), "PD-Multiplexing is not compatible with disaggregation mode."
assert (
cfg.disable_overlap_schedule
), "PD-Multiplexing is not compatible with overlap schedule."
assert cfg.pp_size == 1, (
"PD-Multiplexing is only supported with pipeline parallelism disabled (pp_size=1)."
)
assert cfg.chunked_prefill_size == -1, (
"PD-Multiplexing is not compatible with chunked prefill."
)
assert cfg.disaggregation_mode == "null", (
"PD-Multiplexing is not compatible with disaggregation mode."
)
assert cfg.disable_overlap_schedule, (
"PD-Multiplexing is not compatible with overlap schedule."
)
# NOTE: CUDA Green Context may encounter potential issues with CudaGraph on torch 2.7.x – 2.8.x, leading to performance degradation.
import torch
@@ -143,7 +143,9 @@ def check_server_args(server_args: Any):
assert cfg.schedule_policy in [
"fcfs",
"lof",
], f"To use priority scheduling, schedule_policy must be 'fcfs' or 'lof'. '{cfg.schedule_policy}' is not supported."
], (
f"To use priority scheduling, schedule_policy must be 'fcfs' or 'lof'. '{cfg.schedule_policy}' is not supported."
)
if cfg.default_priority_value is None:
logger.warning(
"--default-priority-value is not set while --enable-priority-scheduling is enabled. "
@@ -170,14 +172,14 @@ def check_server_args(server_args: Any):
run_post_process_pass(server_args, _hisparse_validation)
assert (
cfg.schedule_conservativeness >= 0
), "schedule_conservativeness must be non-negative"
assert cfg.schedule_conservativeness >= 0, (
"schedule_conservativeness must be non-negative"
)
if cfg.model_impl == "mindspore":
assert (
get_platform().is_npu
), "MindSpore model impl is only supported on Ascend npu."
assert get_platform().is_npu, (
"MindSpore model impl is only supported on Ascend npu."
)
# Check metrics labels
if (
@@ -239,43 +241,45 @@ def validate_buckets_rule(arg_name: str, buckets_rule: List[str]):
"tse",
"default",
"custom",
], f"Unsupported {arg_name} rule type: '{rule}'. Must be one of: 'tse', 'default', 'custom'"
], (
f"Unsupported {arg_name} rule type: '{rule}'. Must be one of: 'tse', 'default', 'custom'"
)
if rule == "tse":
assert (
len(buckets_rule) == 4
), f"{arg_name} TSE rule requires exactly 4 parameters: ['tse', middle, base, count], got {len(buckets_rule)}"
assert len(buckets_rule) == 4, (
f"{arg_name} TSE rule requires exactly 4 parameters: ['tse', middle, base, count], got {len(buckets_rule)}"
)
try:
middle = float(buckets_rule[1])
base = float(buckets_rule[2])
count = int(buckets_rule[3])
except (ValueError, IndexError):
assert (
False
), f"{arg_name} TSE rule parameters must be: ['tse', <float:middle>, <float:base>, <int:count>]"
assert False, (
f"{arg_name} TSE rule parameters must be: ['tse', <float:middle>, <float:base>, <int:count>]"
)
assert base > 1, f"{arg_name} TSE base must be larger than 1, got: {base}"
assert count > 0, f"{arg_name} TSE count must be positive, got: {count}"
assert middle > 0, f"{arg_name} TSE middle must be positive, got: {middle}"
elif rule == "default":
assert (
len(buckets_rule) == 1
), f"{arg_name} default rule should only have one parameter: ['default'], got {len(buckets_rule)}"
assert len(buckets_rule) == 1, (
f"{arg_name} default rule should only have one parameter: ['default'], got {len(buckets_rule)}"
)
elif rule == "custom":
assert (
len(buckets_rule) >= 2
), f"{arg_name} custom rule requires at least one bucket value: ['custom', value1, ...]"
assert len(buckets_rule) >= 2, (
f"{arg_name} custom rule requires at least one bucket value: ['custom', value1, ...]"
)
try:
bucket_values = [float(x) for x in buckets_rule[1:]]
except ValueError:
assert False, f"{arg_name} custom rule bucket values must be numeric"
assert len(set(bucket_values)) == len(
bucket_values
), f"{arg_name} custom rule bucket values should not contain duplicates"
assert all(
val >= 0 for val in bucket_values
), f"{arg_name} custom rule bucket values should be non-negative"
assert len(set(bucket_values)) == len(bucket_values), (
f"{arg_name} custom rule bucket values should not contain duplicates"
)
assert all(val >= 0 for val in bucket_values), (
f"{arg_name} custom rule bucket values should be non-negative"
)
def check_load_publish_args(server_args: Any):
@@ -176,9 +176,9 @@ def _matmul_persistent_triton(
# Check constraints.
assert a.shape[1] == b.shape[0], "Incompatible dimensions"
assert a.dtype == b.dtype, "Incompatible dtypes"
assert (
bias is None or bias.dim() == 1
), "Currently assuming bias is 1D, let Horace know if you run into this"
assert bias is None or bias.dim() == 1, (
"Currently assuming bias is 1D, let Horace know if you run into this"
)
NUM_SMS = get_device_core_count()
M, K = a.shape
K, N = b.shape
@@ -501,9 +501,9 @@ def mean_dim(
"""
# Validate inputs
assert input.is_cuda or input.is_xpu, "Input must be a CUDA or XPU tensor"
assert (
-input.ndim <= dim < input.ndim
), f"Invalid dimension {dim} for tensor with {input.ndim} dimensions"
assert -input.ndim <= dim < input.ndim, (
f"Invalid dimension {dim} for tensor with {input.ndim} dimensions"
)
# Handle negative dim
if dim < 0:
@@ -191,9 +191,9 @@ class _StateDict:
if key == "_data":
super().__setattr__(key, value)
return
assert (
key not in self._data
), f"`{key}` already exist, are you sure you want to override it?"
assert key not in self._data, (
f"`{key}` already exist, are you sure you want to override it?"
)
self._data[key] = value
def __getattr__(self, item):
@@ -630,9 +630,9 @@ class TboForwardBatchPreparer:
sum_field="extend_num_tokens",
)
assert (
child_a.extend_num_tokens == half_seq_lens_sum
), f"{child_a.extend_num_tokens=}, {half_seq_lens_sum=}"
assert child_a.extend_num_tokens == half_seq_lens_sum, (
f"{child_a.extend_num_tokens=}, {half_seq_lens_sum=}"
)
child_a.seq_lens_cpu = copy.deepcopy(child_a.seq_lens_cpu)
child_a.seq_lens_cpu[-1] = (
@@ -674,9 +674,9 @@ class TboForwardBatchPreparer:
out_num_token_non_padded: torch.Tensor,
out_num_token_non_padded_cpu: Optional[int] = None,
):
assert (
end_token_index >= start_token_index
), f"{end_token_index=}, {start_token_index=}, batch={batch}"
assert end_token_index >= start_token_index, (
f"{end_token_index=}, {start_token_index=}, batch={batch}"
)
num_tokens = batch.input_ids.shape[0]
num_seqs = batch.batch_size
@@ -688,9 +688,9 @@ class TboForwardBatchPreparer:
"out_cache_loc",
]:
old_value = getattr(batch, key)
assert (
old_value.shape[0] == num_tokens
), f"{key=} {old_value=} {num_tokens=} {batch=}"
assert old_value.shape[0] == num_tokens, (
f"{key=} {old_value=} {num_tokens=} {batch=}"
)
output_dict[key] = old_value[start_token_index:end_token_index]
attention_tp_size = get_parallel().attn_tp_size
@@ -736,9 +736,9 @@ class TboForwardBatchPreparer:
start_seq_index : min(end_seq_index, len(old_value))
]
continue
assert (
len(old_value) == num_seqs
), f"{key=} {old_value=} {num_seqs=} {batch=}"
assert len(old_value) == num_seqs, (
f"{key=} {old_value=} {num_seqs=} {batch=}"
)
output_dict[key] = old_value[start_seq_index:end_seq_index]
spec_info = getattr(batch, "spec_info")
+3 -3
View File
@@ -211,9 +211,9 @@ class BeamGroup:
cums = sel.cum_logprobs.tolist()
# A parent outside the committed frontier means a tick-gating bug let an
# unsynchronized step through; fail rather than build a corrupt DAG.
assert not parents or max(parents) < len(
self.leaves
), "beam commit consumed an unsynced or misordered step"
assert not parents or max(parents) < len(self.leaves), (
"beam commit consumed an unsynced or misordered step"
)
for token, parent, cum in zip(tokens, parents, cums):
leaf = BeamNode(token, self.leaves[parent])
self.completed.append(CompletedBeam(leaf, cum, new_len, matched_token=None))
+6 -8
View File
@@ -121,15 +121,14 @@ class CompilerManager:
)
if runtime_shape is None:
logger.debug(
"Directly load the %s-th graph for dynamic shape from %s via "
"handle %s",
"Directly load the %s-th graph for dynamic shape from %s via handle %s",
graph_index,
self.compiler.name,
handle,
)
else:
logger.debug(
"Directly load the %s-th graph for shape %s from %s via " "handle %s",
"Directly load the %s-th graph for shape %s from %s via handle %s",
graph_index,
str(runtime_shape),
self.compiler.name,
@@ -184,7 +183,7 @@ class CompilerManager:
)
if runtime_shape is None:
logger.debug(
"Store the %s-th graph for dynamic shape from %s via " "handle %s",
"Store the %s-th graph for dynamic shape from %s via handle %s",
graph_index,
self.compiler.name,
handle,
@@ -352,9 +351,9 @@ model_tag: str = "backbone"
def set_model_tag(tag: str):
"""Context manager to set the model tag."""
global model_tag
assert (
tag != model_tag
), f"Model tag {tag} is the same as the current tag {model_tag}."
assert tag != model_tag, (
f"Model tag {tag} is the same as the current tag {model_tag}."
)
old_tag = model_tag
model_tag = tag
try:
@@ -364,7 +363,6 @@ def set_model_tag(tag: str):
class SGLangBackend:
graph_pool: Any
_called: bool = False
# the graph we compiled
@@ -256,9 +256,7 @@ class InductorAdaptor(CompilerInterface):
break
return inductor_compiled_graph
hijacked_compile_fx_inner = (
torch._inductor.compile_fx.compile_fx_inner
) # noqa
hijacked_compile_fx_inner = torch._inductor.compile_fx.compile_fx_inner # noqa
elif torch_release >= (2, 6):
# function renamed in 2.6
original_load_name = None
@@ -45,7 +45,6 @@ class ConcreteSizeEntry:
class CUDAPiecewiseBackend:
def __init__(
self,
graph: fx.GraphModule,
@@ -190,8 +189,9 @@ class CUDAPiecewiseBackend:
stack.enter_context(patch("gc.collect", lambda: None))
stack.enter_context(patch("torch.cuda.empty_cache", lambda: None))
# mind-exploding: carefully manage the reference and memory.
with graph_pool_capture_scope(), torch.cuda.graph(
cudagraph, pool=self.graph_pool, stream=stream
with (
graph_pool_capture_scope(),
torch.cuda.graph(cudagraph, pool=self.graph_pool, stream=stream),
):
# `output` is managed by pytorch's cudagraph pool
output = entry.runnable(*args)
@@ -119,9 +119,9 @@ class FixFunctionalizationPass(SGLangInductorPass):
:param args: If we cannot use kwargs, specify args directly.
If an arg is a string, `node.kwargs[arg]` is used.
""" # noqa: E501
assert is_func(
node, auto_functionalized
), f"node must be auto-functionalized, is {node} instead"
assert is_func(node, auto_functionalized), (
f"node must be auto-functionalized, is {node} instead"
)
# Create a new call to the original function
with graph.inserting_before(node):
@@ -22,7 +22,6 @@ _pass_context = None
class PassContext:
def __init__(self, runtime_shape: Optional[int]):
self.runtime_shape = runtime_shape
@@ -114,7 +113,6 @@ class CallableInductorPass(InductorPass):
class SGLangInductorPass(InductorPass):
def __init__(
self,
):
@@ -133,7 +131,6 @@ class SGLangInductorPass(InductorPass):
class PrinterInductorPass(SGLangInductorPass):
def __init__(self, name: str):
super().__init__()
self.name = name
+3 -4
View File
@@ -37,7 +37,6 @@ class HybridLayerType(enum.Enum):
class BailingHybridConfig(PretrainedConfig):
model_type = "bailing_hybrid"
keys_to_ignore_at_inference = ["past_key_values"]
@@ -175,9 +174,9 @@ class BailingHybridConfig(PretrainedConfig):
layer_type_list.append(HybridLayerType.linear_attention.value)
else:
# Per-layer schedule: 1 marks a linear-attention layer.
assert (
len(self.layer_group_size) == self.num_hidden_layers
), "When layer_group_size is a list, its length must be equal to num_hidden_layers"
assert len(self.layer_group_size) == self.num_hidden_layers, (
"When layer_group_size is a list, its length must be equal to num_hidden_layers"
)
for l in range(self.num_hidden_layers):
if self.layer_group_size[l] == 1:
layer_type_list.append(HybridLayerType.linear_attention.value)
+3 -4
View File
@@ -193,7 +193,6 @@ class ImageTransform(object):
elif not x.is_floating_point():
x = x.to(torch.float32)
if self.normalize:
import torchvision.transforms as T
x = T.Normalize(self.mean, self.std)(x)
@@ -620,9 +619,9 @@ class DeepseekOCRProcessor(ProcessorMixin):
tokenized_str = tokenized_str + [self.eos_id]
images_seq_mask = images_seq_mask + [False]
assert len(tokenized_str) == len(
images_seq_mask
), f"tokenize_with_images func: tokenized_str's length {len(tokenized_str)} is not equal to imags_seq_mask's length {len(images_seq_mask)}"
assert len(tokenized_str) == len(images_seq_mask), (
f"tokenize_with_images func: tokenized_str's length {len(tokenized_str)} is not equal to imags_seq_mask's length {len(images_seq_mask)}"
)
masked_tokenized_str = []
for token_index in tokenized_str:
+12 -12
View File
@@ -21,8 +21,9 @@ def select_best_resolution(image_size, candidate_resolutions):
for width, height in candidate_resolutions:
scale = min(width / original_width, height / original_height)
downscaled_width, downscaled_height = int(original_width * scale), int(
original_height * scale
downscaled_width, downscaled_height = (
int(original_width * scale),
int(original_height * scale),
)
effective_resolution = min(
downscaled_width * downscaled_height, original_width * original_height
@@ -205,9 +206,9 @@ class DeepseekVLV2Processor(ProcessorMixin):
images_seq_mask += seq_mask
images_spatial_crop += spatial_crop
assert len(tokenized_data) == len(
images_seq_mask
), f"format_messages_v2: tokenized_str's length {len(tokenized_str)} is not equal to imags_seq_mask's length {len(images_seq_mask)}"
assert len(tokenized_data) == len(images_seq_mask), (
f"format_messages_v2: tokenized_str's length {len(tokenized_str)} is not equal to imags_seq_mask's length {len(images_seq_mask)}"
)
return (
tokenized_data,
@@ -274,9 +275,9 @@ class DeepseekVLV2Processor(ProcessorMixin):
- num_image_tokens (List[int]): the number of image tokens
"""
assert (
prompt is None or conversations is None
), "prompt and conversations cannot be used at the same time."
assert prompt is None or conversations is None, (
"prompt and conversations cannot be used at the same time."
)
(
tokenized_str,
@@ -458,9 +459,9 @@ class DeepseekVLV2Processor(ProcessorMixin):
tokenized_str = tokenized_str + [self.eos_id]
images_seq_mask = images_seq_mask + [False]
assert len(tokenized_str) == len(
images_seq_mask
), f"tokenize_with_images func: tokenized_str's length {len(tokenized_str)} is not equal to imags_seq_mask's length {len(images_seq_mask)}"
assert len(tokenized_str) == len(images_seq_mask), (
f"tokenize_with_images func: tokenized_str's length {len(tokenized_str)} is not equal to imags_seq_mask's length {len(images_seq_mask)}"
)
return tokenized_str, images_list, images_seq_mask, images_spatial_crop
@@ -547,7 +548,6 @@ class DeepseekVL2MlpProjectorConfig(PretrainedConfig):
class DeepseekV2Config(PretrainedConfig):
model_type = "deepseek_v2"
keys_to_ignore_at_inference = ["past_key_values"]
+6 -6
View File
@@ -104,9 +104,9 @@ class InklingModelConfig(PretrainedConfig):
mtp_swa_head_dim = swa_head_dim
if mtp_local_layer_ids:
local_id_set = set(mtp_local_layer_ids)
assert len(local_id_set) == len(
mtp_local_layer_ids
), f"mtp_local_layer_ids must be unique: {mtp_local_layer_ids}"
assert len(local_id_set) == len(mtp_local_layer_ids), (
f"mtp_local_layer_ids must be unique: {mtp_local_layer_ids}"
)
assert all(0 <= i < num_nextn_predict_layers for i in local_id_set), (
f"mtp_local_layer_ids must be in [0, {num_nextn_predict_layers}): "
f"{mtp_local_layer_ids}"
@@ -231,9 +231,9 @@ class InklingModelConfig(PretrainedConfig):
if get_exec().comm.enable_scattered_sconv:
# Scattered sconv: the attn/mlp output sconvs run on the [T, H/P]
# hidden shard, so their conv-state caches shard with them.
assert (
self.hidden_size % tp_size == 0
), f"hidden_size {self.hidden_size} not divisible by attn tp {tp_size}"
assert self.hidden_size % tp_size == 0, (
f"hidden_size {self.hidden_size} not divisible by attn tp {tp_size}"
)
stream_dim = self.hidden_size // tp_size
conv_len = self.sconv_kernel_size - 1
shape = InklingConvStateShape(
+6 -5
View File
@@ -1593,7 +1593,6 @@ class ModelConfig:
# of an NVFP4/mixed checkpoint) must not be overridden back to the
# source format
if self.quantization not in REQUANTIZATION_METHODS:
# Detect which checkpoint is it
if not preserve_online_draft_quantization:
for _, method in QUANTIZATION_METHODS.items():
@@ -2242,12 +2241,14 @@ def get_hybrid_layer_ids(
elif "InklingForConditionalGeneration" in model_architectures:
local_layer_ids = hf_text_config.local_layer_ids
local_layer_id_set = set(local_layer_ids)
assert len(local_layer_id_set) == len(
local_layer_ids
), f"Inkling local_layer_ids must be unique: {local_layer_ids}"
assert len(local_layer_id_set) == len(local_layer_ids), (
f"Inkling local_layer_ids must be unique: {local_layer_ids}"
)
assert all(
0 <= layer_id < num_hidden_layers for layer_id in local_layer_id_set
), f"Inkling local_layer_ids must be in [0, {num_hidden_layers}): {local_layer_ids}"
), (
f"Inkling local_layer_ids must be in [0, {num_hidden_layers}): {local_layer_ids}"
)
swa_attention_layer_ids = [
i for i in range(num_hidden_layers) if i in local_layer_id_set
]
@@ -26,7 +26,6 @@ _ARCH = "muse-glimmer"
class MuseGlimmerAssistantConfig(PretrainedConfig):
model_type = "muse_glimmer_assistant"
is_causal = False
# The DFlash draft has no head; draft_worker_common borrows the target's.
@@ -34,7 +33,6 @@ class MuseGlimmerAssistantConfig(PretrainedConfig):
class MuseGlimmerVisionConfig(PretrainedConfig):
model_type = "muse_glimmer_vision"
def __init__(
@@ -24,9 +24,9 @@ from sglang.srt.multimodal.internvl_utils import IMAGENET_MEAN, IMAGENET_STD
def float_triplet(seq: Any):
a, b, c = tuple(seq)
assert (
isinstance(a, float) and isinstance(b, float) and isinstance(c, float)
), "expected three floats"
assert isinstance(a, float) and isinstance(b, float) and isinstance(c, float), (
"expected three floats"
)
return a, b, c
-1
View File
@@ -28,7 +28,6 @@ class Olmo3LayerType(enum.Enum):
class Olmo3Config(PretrainedConfig):
model_type = "olmo3"
keys_to_ignore_at_inference = ["past_key_values"]
-5
View File
@@ -235,7 +235,6 @@ class Qwen3OmniMoeThinkerConfig(PretrainedConfig):
class Qwen3OmniMoeTalkerCodePredictorConfig(PretrainedConfig):
model_type = "qwen3_omni_moe_talker_code_predictor"
keys_to_ignore_at_inference = ["past_key_values"]
@@ -325,7 +324,6 @@ class Qwen3OmniMoeTalkerCodePredictorConfig(PretrainedConfig):
class Qwen3OmniMoeTalkerTextConfig(PretrainedConfig):
model_type = "qwen3_omni_moe_talker_text"
keys_to_ignore_at_inference = ["past_key_values"]
@@ -415,7 +413,6 @@ class Qwen3OmniMoeTalkerTextConfig(PretrainedConfig):
class Qwen3OmniMoeTalkerConfig(PretrainedConfig):
sub_configs = {
"code_predictor_config": Qwen3OmniMoeTalkerCodePredictorConfig,
"text_config": Qwen3OmniMoeTalkerTextConfig,
@@ -486,7 +483,6 @@ class Qwen3OmniMoeTalkerConfig(PretrainedConfig):
class Qwen3OmniMoeCode2WavConfig(PretrainedConfig):
def __init__(
self,
codebook_size=2048,
@@ -538,7 +534,6 @@ class Qwen3OmniMoeCode2WavConfig(PretrainedConfig):
class Qwen3OmniMoeConfig(PretrainedConfig):
model_type = "qwen3_omni_moe"
sub_configs = {
"thinker_config": Qwen3OmniMoeThinkerConfig,
+3 -4
View File
@@ -38,9 +38,9 @@ def get_moe_padding_size(weight_block_size):
2,
], "Only len(weight_block_size) in [1, 2] is supported"
if len(weight_block_size) == 2:
assert (
weight_block_size[0] == weight_block_size[1]
), "Only weight_block_size[0] == weight_block_size[1] is supported"
assert weight_block_size[0] == weight_block_size[1], (
"Only weight_block_size[0] == weight_block_size[1] is supported"
)
return weight_block_size[0]
return DEFAULT_MOE_PADDING_SIZE
@@ -238,7 +238,6 @@ def adjust_config_with_unaligned_cpu_tp(
model_config.num_attention_heads % tp_size != 0
or model_config.get_total_num_kv_heads() % tp_size != 0
):
if hasattr(model_config.hf_config, "qk_nope_head_dim") and hasattr(
model_config.hf_config, "qk_rope_head_dim"
):
+3 -4
View File
@@ -167,9 +167,9 @@ class ZayaConfig(PretrainedConfig):
self.head_dim = head_dim
self.kv_channels = kv_channels if kv_channels is not None else head_dim
assert self.head_dim is not None, "head_dim is required for ZayaConfig"
assert (
self.num_query_groups == num_key_value_heads
), "num_query_groups must equal num_key_value_heads for ZAYA1 checkpoints"
assert self.num_query_groups == num_key_value_heads, (
"num_query_groups must equal num_key_value_heads for ZAYA1 checkpoints"
)
self.num_key_value_heads = num_key_value_heads
self.activation_func = activation_func
self.max_position_embeddings = max_position_embeddings
@@ -266,7 +266,6 @@ class ZayaConfig(PretrainedConfig):
# equals the global TP group (DP attention is unsupported), so the two
# are always identical in practice.
try:
tp_size = get_parallel().tp_size
except (AssertionError, RuntimeError, ValueError):
tp_size = 1
@@ -73,7 +73,6 @@ class BaseConnector(ABC):
class BaseKVConnector(BaseConnector):
@abstractmethod
def get(self, key: str) -> Optional[torch.Tensor]:
raise NotImplementedError()
-1
View File
@@ -14,7 +14,6 @@ logger = logging.getLogger(__name__)
class RedisConnector(BaseKVConnector):
def __init__(self, url: str):
import redis
+9 -10
View File
@@ -14,11 +14,10 @@ logger = logging.getLogger(__name__)
class RemoteInstanceConnector(BaseConnector):
def __init__(self, url: str, device: torch.device = "cpu"):
assert (
device.type == "cuda" or device.type == "npu"
), "RemoteInstanceConnector only supports cuda device."
assert device.type == "cuda" or device.type == "npu", (
"RemoteInstanceConnector only supports cuda device."
)
super().__init__(url)
self.url = url
self.device = device
@@ -31,12 +30,12 @@ class RemoteInstanceConnector(BaseConnector):
group_rank: int = 1,
world_size: int = 2,
):
assert (
self.device.type == "cuda" or self.device.type == "npu"
), "RemoteInstanceConnector only supports cuda device."
assert (
gpu_id != -1 and tp_rank != -1
), "gpu_id and tp_rank must be specified for RemoteInstanceConnector. "
assert self.device.type == "cuda" or self.device.type == "npu", (
"RemoteInstanceConnector only supports cuda device."
)
assert gpu_id != -1 and tp_rank != -1, (
"gpu_id and tp_rank must be specified for RemoteInstanceConnector. "
)
self.device_id = torch.device(self.device.type, gpu_id)
-1
View File
@@ -67,7 +67,6 @@ def list_files(
class S3Connector(BaseFileConnector):
def __init__(self, url: str) -> None:
import boto3
@@ -9,7 +9,6 @@ from sglang.srt.connector.serde.serde import Deserializer, Serializer
class SafeSerializer(Serializer):
def __init__(self):
super().__init__()
@@ -18,7 +17,6 @@ class SafeSerializer(Serializer):
class SafeDeserializer(Deserializer):
def __init__(self):
# TODO: dtype options
super().__init__(torch.float32)
@@ -7,7 +7,6 @@ import torch
class Serializer(ABC):
@abstractmethod
def to_bytes(self, t: torch.Tensor) -> bytes:
"""
@@ -25,7 +24,6 @@ class Serializer(ABC):
class Deserializer(metaclass=abc.ABCMeta):
def __init__(self, dtype):
self.dtype = dtype
@@ -56,7 +56,6 @@ class GrammarRow(NamedTuple):
class BaseGrammarObject:
def __init__(self):
self._finished = False
self.grammar_stats = None
@@ -113,7 +113,6 @@ def _create_llguidance_tokenizer(
class GuidanceGrammar(BaseGrammarObject):
def __init__(
self,
llguidance_tokenizer: LLTokenizer,
@@ -226,7 +225,6 @@ class GuidanceGrammar(BaseGrammarObject):
class GuidanceBackend(BaseGrammarBackend):
def __init__(
self,
tokenizer,
@@ -71,7 +71,6 @@ def _allocate_token_bitmask(vocab_size: int, batch_size: int) -> torch.Tensor:
class XGrammarGrammar(BaseGrammarObject):
def __init__(
self,
matcher: GrammarMatcher,
@@ -135,15 +135,15 @@ class _SGLangPlugin(_AuxFrameworkPlugin):
seq_lens = step_data["seq_lens"]
rids_raw = step_data.get("rids")
assert isinstance(
input_ids, torch.Tensor
), f"input_ids: expected Tensor, got {type(input_ids)}"
assert isinstance(
positions, torch.Tensor
), f"positions: expected Tensor, got {type(positions)}"
assert isinstance(
seq_lens, torch.Tensor
), f"seq_lens: expected Tensor, got {type(seq_lens)}"
assert isinstance(input_ids, torch.Tensor), (
f"input_ids: expected Tensor, got {type(input_ids)}"
)
assert isinstance(positions, torch.Tensor), (
f"positions: expected Tensor, got {type(positions)}"
)
assert isinstance(seq_lens, torch.Tensor), (
f"seq_lens: expected Tensor, got {type(seq_lens)}"
)
seq_lens_list: list[int] = seq_lens.tolist()
num_seqs: int = len(seq_lens_list)
@@ -108,7 +108,11 @@ def _build_bs_collapse_pattern(
lhs: str = " ".join(names) # type: ignore[arg-type]
rhs_names: list[str] = list(names[:lo]) + [f"({BATCH_DIM_NAME} {SEQ_DIM_NAME})"] + list(names[hi + 1 :]) # type: ignore[misc]
rhs_names: list[str] = (
list(names[:lo])
+ [f"({BATCH_DIM_NAME} {SEQ_DIM_NAME})"]
+ list(names[hi + 1 :])
) # type: ignore[misc]
rhs: str = " ".join(rhs_names)
new_names: list[str | None] = (
@@ -283,10 +283,7 @@ def _format_non_tensor_rich_body(
target_val: str = escape(record.target_value)
if record.values_equal:
return (
f"═ {name}{suffix} = {baseline_val} "
f"({record.baseline_type}) [green]✓[/]"
)
return f"═ {name}{suffix} = {baseline_val} ({record.baseline_type}) [green]✓[/]"
return (
f"═ [bold red]{name}{suffix}[/]\n"
f" baseline = {baseline_val} ({record.baseline_type})\n"
@@ -86,7 +86,7 @@ def report():
if not coredump_files:
return
print(f"\n{'='*60}")
print(f"\n{'=' * 60}")
print(f"CUDA coredump(s) detected ({len(coredump_files)} file(s)):")
for f in coredump_files:
size_mb = os.path.getsize(f) / (1024 * 1024)
@@ -98,7 +98,7 @@ def report():
repo = os.environ.get("GITHUB_REPOSITORY", "sgl-project/sglang")
print(f"Download from CI: gh run download {run_id} --repo {repo}")
print(f"{'='*60}\n")
print(f"{'=' * 60}\n")
# Auto-inject CUDA coredump env vars at import time.
@@ -152,7 +152,7 @@ def check_tensor_pair(
value_baseline = fn(x_baseline).item()
value_target = fn(x_target).item()
print(
f"[{name}] {value_baseline :.4f} vs {value_target:.4f} (diff: {value_target - value_baseline:.4f})"
f"[{name}] {value_baseline:.4f} vs {value_target:.4f} (diff: {value_target - value_baseline:.4f})"
)
if x_baseline.shape != x_target.shape:
+3 -3
View File
@@ -77,9 +77,9 @@ class DumpLoader:
step = dumper._state.step
conditions = dict(name=name, step=step, **kwargs)
row = find_row(self._df, conditions=conditions)
assert (
row is not None
), f"DumpLoader cannot find row given query {name=} {kwargs=} {self._directory=}"
assert row is not None, (
f"DumpLoader cannot find row given query {name=} {kwargs=} {self._directory=}"
)
path = self._directory / row["filename"]
output = torch.load(path, weights_only=False)
+6 -7
View File
@@ -179,9 +179,9 @@ class DumperConfig(_BaseConfig):
f"grafter_role must be 'baseline' or 'target' when grafter_enable=True, "
f"got {self.grafter_role!r}"
)
assert (
self.grafter_master_address
), "grafter_master_address must be set when grafter_enable=True"
assert self.grafter_master_address, (
"grafter_master_address must be set when grafter_enable=True"
)
assert self.grafter_master_port > 0, (
f"grafter_master_port must be a positive port when grafter_enable=True, "
f"got {self.grafter_master_port}"
@@ -996,9 +996,9 @@ class _Grafter:
return
cfg = self._config
assert (
dist.is_initialized()
), "[Grafter] default torch.distributed must be initialized"
assert dist.is_initialized(), (
"[Grafter] default torch.distributed must be initialized"
)
role = _GraftRole(cfg.grafter_role)
local_world = dist.get_world_size()
local_rank = dist.get_rank()
@@ -1795,7 +1795,6 @@ class _SGLangPlugin(_FrameworkPlugin):
return None
try:
args = get_server_args()
if args is None:
return None
@@ -158,7 +158,7 @@ def register_forward_hook_for_model(
model_top_level_module_matched, _ = tensor_dumper._add_hook_recursive(
model, "", top_level_module_name, layers_module_name
)
assert (
model_top_level_module_matched
), f"model should have a module named {top_level_module_name}"
assert model_top_level_module_matched, (
f"model should have a module named {top_level_module_name}"
)
return tensor_dumper
@@ -22,7 +22,6 @@ logger = logging.getLogger(__name__)
class AscendTransferEngine(MooncakeTransferEngine):
def __init__(
self,
hostname: str,
@@ -1010,9 +1010,9 @@ class CommonKVManager(BaseKVManager):
"""
start_layer = self.kv_args.prefill_start_layer
end_layer = getattr(self.kv_args, "prefill_end_layer", None)
assert (
end_layer is not None
), "KVArgs.prefill_end_layer must be set when using compressed-MLA PD with PP"
assert end_layer is not None, (
"KVArgs.prefill_end_layer must be set when using compressed-MLA PD with PP"
)
c4_full = sum(1 for r in mla_ratios if r == 4)
c128_full = sum(1 for r in mla_ratios if r == 128)
@@ -1066,8 +1066,7 @@ class CommonKVManager(BaseKVManager):
list(dst_kv_ptrs[swa_s:swa_e])
+ list(
dst_kv_ptrs[
compress_section_start
+ c4_off_s : compress_section_start
compress_section_start + c4_off_s : compress_section_start
+ c4_off_e
]
)
@@ -146,7 +146,7 @@ class StagingBuffer:
self.data_ptr = self.buffer.data_ptr()
logger.info(
f"StagingBuffer allocated: {size_bytes / (1024*1024):.1f} MB "
f"StagingBuffer allocated: {size_bytes / (1024 * 1024):.1f} MB "
f"on {device}, method={alloc_method}, ptr=0x{self.data_ptr:x}"
)
@@ -207,7 +207,7 @@ class StagingAllocator:
logger.info(
f"StagingAllocator (ring+overcommit): "
f"{total_size_bytes / (1024*1024):.1f} MB "
f"{total_size_bytes / (1024 * 1024):.1f} MB "
f"on {device}, ptr=0x{self.base_ptr:x}"
)
@@ -301,7 +301,7 @@ class DecodeStagingHandler:
receiver = self._room_to_receiver.get(room)
if receiver is None:
logger.warning(
"Staging chunk arrived for unregistered room=%s chunk=%d, " "skipping",
"Staging chunk arrived for unregistered room=%s chunk=%d, skipping",
room,
chunk_idx,
)
@@ -901,9 +901,9 @@ class StagingManagerMixin:
room = int(msg[1].decode("ascii"))
session_id = msg[4].decode("ascii")
handler = self._staging_handler
assert (
handler is not None
), "STAGING_REQ received before staging handler initialized"
assert handler is not None, (
"STAGING_REQ received before staging handler initialized"
)
decode_req = handler._room_to_decode_req.get(room)
if decode_req is None:
logger.warning(
@@ -40,7 +40,7 @@ def pack_list_of_buffers(buffers: List[bytes]) -> bytes:
if not buffers:
return b""
n = len(buffers)
header = struct.pack(f"<{n+1}I", n, *(len(b) for b in buffers))
header = struct.pack(f"<{n + 1}I", n, *(len(b) for b in buffers))
return header + b"".join(buffers)
@@ -64,7 +64,7 @@ def pack_int_lists(lists, fmt: str) -> bytes:
def unpack_int_lists(buf: bytes, fmt: str) -> List[List[int]]:
width = struct.calcsize(fmt)
return [
list(struct.unpack(f"<{len(b)//width}{fmt}", b))
list(struct.unpack(f"<{len(b) // width}{fmt}", b))
for b in unpack_list_of_buffers(buf)
]
+9 -9
View File
@@ -190,9 +190,9 @@ class DecodeReqToTokenPool:
# Indices of reqs that already have a req_pool_idx and will reuse
# their existing slot (e.g. chunked prefill continuing across chunks).
reusing = [i for i, r in enumerate(reqs) if r.kv.holds_kv]
assert all(
reqs[i].kv.kv_allocated_len > 0 for i in reusing
), "a reused row must carry allocated KV"
assert all(reqs[i].kv.kv_allocated_len > 0 for i in reusing), (
"a reused row must carry allocated KV"
)
need_size = len(reqs) - len(reusing)
if need_size > len(self.free_slots):
@@ -1766,9 +1766,9 @@ class DecodePreallocQueue(DecodeHiCachePreallocMixin):
req_pool_indices = self.req_to_token_pool.alloc([req])
assert (
req_pool_indices is not None
), "req_pool_indices is full! There is a bug in memory estimation."
assert req_pool_indices is not None, (
"req_pool_indices is full! There is a bug in memory estimation."
)
fill_len = self._pre_alloc_fill_len(req)
req.kv.kv_committed_len = fill_len
@@ -2202,9 +2202,9 @@ class DecodeTransferQueue(DecodeHiCacheTransferMixin):
].tolist()
)
if decode_req.req.return_sampling_mask:
assert (
output_token_sampling_mask_idx is not None
), "sampling mask buffer disabled on decode side"
assert output_token_sampling_mask_idx is not None, (
"sampling mask buffer disabled on decode side"
)
sampling_mask_len = int(output_token_sampling_mask_len[0].item())
if sampling_mask_len < 0:
decode_req.req.output_token_sampling_mask.append(None)
@@ -19,7 +19,6 @@ if TYPE_CHECKING:
class ScheduleBatchDisaggregationDecodeMixin:
def prepare_for_prebuilt(self: ScheduleBatch):
"""
Prepare a prebuilt extend by populate metadata
@@ -49,18 +48,18 @@ class ScheduleBatchDisaggregationDecodeMixin:
chunk = self.req_to_token_pool.req_to_token[req.kv.req_pool_idx][
pre_len : pre_len + req.extend_range.length
]
assert (
offset + req.extend_range.length <= total_size
), f"Exceeds total size: offset={offset}, req.extend_range.length={req.extend_range.length}, total_size={total_size}"
assert offset + req.extend_range.length <= total_size, (
f"Exceeds total size: offset={offset}, req.extend_range.length={req.extend_range.length}, total_size={total_size}"
)
out_cache_loc[offset : offset + req.extend_range.length] = chunk
offset += req.extend_range.length
seq_len = len(req.origin_input_ids) + max(0, len(req.output_ids) - 1)
seq_lens.append(seq_len)
if len(req.output_ids) == 0:
assert (
seq_len - pre_len == req.extend_range.length
), f"seq_len={seq_len}, pre_len={pre_len}, req.extend_range.length={req.extend_range.length}"
assert seq_len - pre_len == req.extend_range.length, (
f"seq_len={seq_len}, pre_len={pre_len}, req.extend_range.length={req.extend_range.length}"
)
if not req.retracted_stain:
# Clamp to avoid double-counting: already_computed is seeded from
@@ -1465,8 +1465,7 @@ async def _extract_encoder_error(responses, endpoint, context, encode_requests=N
if isinstance(resp, asyncio.TimeoutError):
timeout_val = envs.SGLANG_ENCODER_HTTP_TIMEOUT.get()
logger.error(
f"Encoder {endpoint} timeout ({timeout_val}s) for {ctx} "
f"(request {i})"
f"Encoder {endpoint} timeout ({timeout_val}s) for {ctx} (request {i})"
)
return f"Encoder {endpoint} timeout ({timeout_val}s)"
if isinstance(resp, Exception):
@@ -1692,9 +1691,9 @@ def _view_pool_buffer_by_modality(raw_buffer, embedding_data, dtype):
if info is None:
mod_info[mod] = [start, end, shape[0], shape[1]]
else:
assert (
info[3] == shape[1]
), f"hidden_dim mismatch in modality {mod}: {info[3]} vs {shape[1]}"
assert info[3] == shape[1], (
f"hidden_dim mismatch in modality {mod}: {info[3]} vs {shape[1]}"
)
assert info[1] == start, f"non-contiguous parts in modality {mod}"
info[1] = end
info[2] += shape[0]
@@ -892,8 +892,7 @@ class DPDispatcher:
)
self._listener_failed = True
self._fail_all_pending(
"encoder DP result listener stopped after repeated "
"recv errors",
"encoder DP result listener stopped after repeated recv errors",
"ResultListenerStopped",
)
return
@@ -1301,8 +1300,7 @@ async def _dp_worker_handle_request(
# Error envelope, not 200 + phantom count: the decoder must
# fail fast instead of waiting for a ZMQ ack that never comes.
raise MMError(
f"no staged embedding for /send req_id={req_id} "
f"(already released)"
f"no staged embedding for /send req_id={req_id} (already released)"
)
# Releasing on the first /send breaks decoder TP > 1. No count means
# a pre-refcount decoder: stay eager rather than pin until the sweep.
@@ -950,9 +950,10 @@ class MMEncoder:
modality_str = modality.name.lower()
preprocess_start = time.perf_counter()
try:
preprocess_result, items_per_req = (
await self.preprocessor.process_batch_mm_items(requests, modality)
)
(
preprocess_result,
items_per_req,
) = await self.preprocessor.process_batch_mm_items(requests, modality)
except NotImplementedError as e:
raise InternalError(f"Not implemented error: {str(e)}")
except Exception as e:
@@ -162,8 +162,8 @@ class KVArgsRegisterInfo:
endpoint=msg[1].decode("ascii"),
dst_port=int(msg[2].decode("ascii")),
mooncake_session_id=msg[3].decode("ascii"),
dst_kv_ptrs=list(struct.unpack(f"{len(msg[4])//8}Q", msg[4])),
dst_aux_ptrs=list(struct.unpack(f"{len(msg[5])//8}Q", msg[5])),
dst_kv_ptrs=list(struct.unpack(f"{len(msg[4]) // 8}Q", msg[4])),
dst_aux_ptrs=list(struct.unpack(f"{len(msg[5]) // 8}Q", msg[5])),
dst_state_data_ptrs=unpack_int_lists(msg[6], "Q"),
dst_tp_rank=int(msg[7].decode("ascii")),
dst_attn_tp_size=int(msg[8].decode("ascii")),
@@ -2152,9 +2152,9 @@ class MooncakeKVManager(StagingManagerMixin, CommonKVManager):
num_pages = int(msg[4].decode("ascii"))
session_id = msg[5].decode("ascii")
handler = self._staging_handler
assert (
handler is not None
), "CHUNK_READY received before staging handler initialized"
assert handler is not None, (
"CHUNK_READY received before staging handler initialized"
)
handler.handle_chunk_arrived(
room,
chunk_idx,
@@ -2339,7 +2339,6 @@ class MooncakeFailureExceptionMixin:
class MooncakeKVSender(MooncakeFailureExceptionMixin, CommonKVSender):
def __init__(
self,
mgr: MooncakeKVManager,
@@ -1722,7 +1722,6 @@ class MoriKVSender(CommonKVSender):
class MoriKVReceiver(CommonKVReceiver):
def __init__(
self,
mgr: MoriKVManager,
+24 -21
View File
@@ -708,9 +708,9 @@ class NixlKVManager(StagingManagerMixin, CommonKVManager):
)
prep_handle = self.agent.prep_xfer_dlist(peer_name, np.vstack(arrays), mem_kind)
assert (
prep_handle is not None
), f"prep_xfer_dlist returned None for peer '{peer_name}'"
assert prep_handle is not None, (
f"prep_xfer_dlist returned None for peer '{peer_name}'"
)
return prep_handle
def _init_equal_tp_prep_handle(
@@ -859,9 +859,9 @@ class NixlKVManager(StagingManagerMixin, CommonKVManager):
]
)
src_handle = self.agent.prep_xfer_dlist("", src_array, src_mem_kind)
assert (
src_handle is not None
), f"prep_xfer_dlist returned None for slice src (decode_tp_size={decode_tp_size})"
assert src_handle is not None, (
f"prep_xfer_dlist returned None for slice src (decode_tp_size={decode_tp_size})"
)
self.prep_handle_slice_src = (
src_handle,
num_groups,
@@ -896,9 +896,9 @@ class NixlKVManager(StagingManagerMixin, CommonKVManager):
]
)
dst_handle = self.agent.prep_xfer_dlist(peer_name, dst_array, dst_mem_kind)
assert (
dst_handle is not None
), f"prep_xfer_dlist returned None for slice dst for peer '{peer_name}'"
assert dst_handle is not None, (
f"prep_xfer_dlist returned None for slice dst for peer '{peer_name}'"
)
self.prep_handles_slice_dst[peer_name] = (
dst_handle,
num_slots_dst,
@@ -1331,8 +1331,7 @@ class NixlKVManager(StagingManagerMixin, CommonKVManager):
or not self.kv_args.kv_data_ptrs
):
aux_notif += (
f"_nokv_{self.transfer_source_rank}"
f"_{kv_chunk.chunk_id}"
f"_nokv_{self.transfer_source_rank}_{kv_chunk.chunk_id}"
)
aux_xfer_handle = self.send_aux(
req.agent_name,
@@ -2097,9 +2096,9 @@ class NixlKVManager(StagingManagerMixin, CommonKVManager):
):
"""Transfer Mamba states via RDMA."""
assert len(prefill_state_indices) == 1, "Mamba should have single state index"
assert len(dst_state_indices) == len(
prefill_state_indices
), "State indices count mismatch between Prefill and Decode"
assert len(dst_state_indices) == len(prefill_state_indices), (
"State indices count mismatch between Prefill and Decode"
)
src_addrs = []
dst_addrs = []
@@ -2556,8 +2555,10 @@ class NixlKVManager(StagingManagerMixin, CommonKVManager):
expected = int(components[4]) if len(components) > 4 else 0
self.transfer_statuses[room].expected_kvs_per_pp[pp_rank] = expected
if self.transfer_statuses[room].num_pp_ranks_expected is None:
self.transfer_statuses[room].num_pp_ranks_expected = (
self.required_prefill_response_num_table.get(room, 1)
self.transfer_statuses[
room
].num_pp_ranks_expected = self.required_prefill_response_num_table.get(
room, 1
)
if (
self.enable_staging
@@ -2574,8 +2575,10 @@ class NixlKVManager(StagingManagerMixin, CommonKVManager):
if is_last_chunk:
self.transfer_statuses[room].expected_kvs_per_pp[pp_rank] = chunk_id + 1
if self.transfer_statuses[room].num_pp_ranks_expected is None:
self.transfer_statuses[room].num_pp_ranks_expected = (
self.required_prefill_response_num_table.get(room, 1)
self.transfer_statuses[
room
].num_pp_ranks_expected = self.required_prefill_response_num_table.get(
room, 1
)
if (
self.enable_staging
@@ -2739,9 +2742,9 @@ class NixlKVManager(StagingManagerMixin, CommonKVManager):
if self._handle_abort_notification(waiting_req_bytes):
continue
assert (
waiting_req_bytes[0] == GUARD
), f"First message should be {GUARD}. Foreign traffic?"
assert waiting_req_bytes[0] == GUARD, (
f"First message should be {GUARD}. Foreign traffic?"
)
waiting_req_bytes = waiting_req_bytes[1:]
room = waiting_req_bytes[0].decode("ascii")
agent_name = waiting_req_bytes[3].decode("ascii")
+3 -3
View File
@@ -852,9 +852,9 @@ class SchedulerDisaggregationPrefillMixin:
# In non-overlap-mode, KV is sent in process_prefill_chunk
# Only send when req's sender is initialized
if self.enable_overlap and not req.pending_bootstrap:
assert (
req.metadata_buffer_index >= 0
), f"Req {req.rid} does not have metadata buffer allocated"
assert req.metadata_buffer_index >= 0, (
f"Req {req.rid} does not have metadata buffer allocated"
)
self.send_kv_chunk(req, last_chunk=False, end_idx=req.tmp_end_idx)
req.time_stats.set_last_chunked_prefill_finish_time()
@@ -63,7 +63,7 @@ def update_environment_variables(envs: Dict[str, str]):
for k, v in envs.items():
if k in os.environ and os.environ[k] != v:
logger.warning(
"Overwriting environment variable %s " "from '%s' to '%s'",
"Overwriting environment variable %s from '%s' to '%s'",
k,
os.environ[k],
v,
@@ -445,9 +445,9 @@ def can_use_custom_all_reduce_with_nvlink(
supported_world_size: List[int],
cls_name: str,
) -> Optional[bool]: # None if fail; otherwise return whether NVLink is available
assert (
dist.get_backend(group) != dist.Backend.NCCL
), f"{cls_name} should be attached to a non-NCCL group."
assert dist.get_backend(group) != dist.Backend.NCCL, (
f"{cls_name} should be attached to a non-NCCL group."
)
rank = dist.get_rank(group=group)
world_size = dist.get_world_size(group=group)
@@ -459,7 +459,7 @@ def can_use_custom_all_reduce_with_nvlink(
# No need to initialize custom allreduce for multi-node case.
if not all(in_the_same_node_as(group, source_rank=0)):
logger.warning(
f"{cls_name} is disabled because this process group" " spans across nodes."
f"{cls_name} is disabled because this process group spans across nodes."
)
return
@@ -404,9 +404,9 @@ class CustomAllReduceV2:
yield
finally:
self._graph_mode_allowed = False
assert (
not torch.cuda.is_current_stream_capturing()
), "Cannot register graph inputs while capturing CUDA graph"
assert not torch.cuda.is_current_stream_capturing(), (
"Cannot register graph inputs while capturing CUDA graph"
)
self._register_graph_inputs()
def _register_graph_inputs(self) -> None:
@@ -13,7 +13,6 @@ if is_hpu():
class HpuCommunicator:
def __init__(self, group: ProcessGroup):
if not is_hpu():
self.disabled = True
@@ -11,7 +11,6 @@ if _is_npu:
class NpuCommunicator:
def __init__(self, group: ProcessGroup):
if not _is_npu:
self.disabled = True
@@ -267,9 +267,9 @@ class PyMscclppCommunicator:
self.available = True
self.group = group
assert (
dist.get_backend(group) != dist.Backend.NCCL
), "CustomAllreduce should be attached to a non-NCCL group."
assert dist.get_backend(group) != dist.Backend.NCCL, (
"CustomAllreduce should be attached to a non-NCCL group."
)
rank = dist.get_rank(group=self.group)
world_size = dist.get_world_size(group=self.group)
@@ -28,7 +28,6 @@ logger = logging.getLogger(__name__)
class PyNcclCommunicator:
def __init__(
self,
group: Union[ProcessGroup, StatelessProcessGroup],
@@ -50,9 +49,9 @@ class PyNcclCommunicator:
"""
if not isinstance(group, StatelessProcessGroup):
assert dist.is_initialized()
assert (
dist.get_backend(group) != dist.Backend.NCCL
), "PyNcclCommunicator should be attached to a non-NCCL group."
assert dist.get_backend(group) != dist.Backend.NCCL, (
"PyNcclCommunicator should be attached to a non-NCCL group."
)
# note: this rank is the rank in the group
self.rank = dist.get_rank(group)
self.world_size = dist.get_world_size(group)
@@ -266,14 +266,14 @@ class SymmetricMemoryContext:
self._comm_ptr = self.group_coordinator.pynccl_comm.comm.value
def __enter__(self):
assert (
self.group_coordinator.pynccl_comm is not None
), f"Symmetric memory requires pynccl to be enabled in group '{self.group_coordinator.unique_name}'"
assert self.group_coordinator.pynccl_comm is not None, (
f"Symmetric memory requires pynccl to be enabled in group '{self.group_coordinator.unique_name}'"
)
if self.is_graph_capture:
assert (
_graph_pool_id is not None
), "graph_pool_id is not set under graph capture"
assert _graph_pool_id is not None, (
"graph_pool_id is not set under graph capture"
)
# Pause graph memory pool to use symmetric memory with cuda graph
if after_2_8_0:
torch._C._cuda_endAllocateToPool(_cur_device, _graph_pool_id)
@@ -322,9 +322,9 @@ class SymmetricMemoryContext:
# Call C++ API to register all segments with this comm
# C++ layer tracks per-comm registration state internally
result = _register_func(self._comm_ptr)
assert (
result == 0
), f"nccl_allocator_register_segments_with_comm failed with return code: {result}"
assert result == 0, (
f"nccl_allocator_register_segments_with_comm failed with return code: {result}"
)
def use_symmetric_memory(group_coordinator: GroupCoordinator, disabled: bool = False):
@@ -50,7 +50,6 @@ MB = 1024 * 1024
class QuickAllReduce:
_SUPPORTED_WORLD_SIZES = [2, 4, 8]
_SUPPORTED_DTYPES = [torch.float16, torch.bfloat16]
# The following data is based on kernel tests.
@@ -103,9 +102,9 @@ class QuickAllReduce:
return
self.group = group
assert (
dist.get_backend(group) != dist.Backend.NCCL
), "Custom quick allreduce should be attached to a non-NCCL group."
assert dist.get_backend(group) != dist.Backend.NCCL, (
"Custom quick allreduce should be attached to a non-NCCL group."
)
if not all(in_the_same_node_as(group, source_rank=0)):
# No need to initialize custom quick allreduce for
# multi-node case.
@@ -31,7 +31,6 @@ logger = logging.getLogger(__name__)
class ShmRingBuffer:
def __init__(
self,
n_reader: int,
@@ -173,7 +172,6 @@ class Handle:
class MessageQueue:
def __init__(
self,
n_reader, # number of all readers
@@ -374,9 +374,9 @@ def all_gather_inner(
f"hidden_states.data_ptr()={hex(hidden_states.data_ptr())} must be "
f"16-byte aligned for 128-bit multimem.st"
)
assert (
tp_hidden_dim % world_size == 0
), f"tp_hidden_dim={tp_hidden_dim} must be divisible by world_size={world_size}"
assert tp_hidden_dim % world_size == 0, (
f"tp_hidden_dim={tp_hidden_dim} must be divisible by world_size={world_size}"
)
local_hidden = tp_hidden_dim // world_size
assert local_hidden % _NUMEL_PER_THREAD == 0, (
f"per-rank hidden shard ({local_hidden}) must be a multiple of "
@@ -387,12 +387,12 @@ def all_gather_inner(
f"state.hidden_dim={state.hidden_dim}"
)
total_tokens, in_hidden = hidden_states.shape
assert (
in_hidden == local_hidden
), f"input hidden ({in_hidden}) != this rank's shard ({local_hidden})"
assert (
total_tokens <= state.max_token_num
), f"total_tokens={total_tokens} exceeds max_token_num={state.max_token_num}"
assert in_hidden == local_hidden, (
f"input hidden ({in_hidden}) != this rank's shard ({local_hidden})"
)
assert total_tokens <= state.max_token_num, (
f"total_tokens={total_tokens} exceeds max_token_num={state.max_token_num}"
)
hidden_offset = local_hidden * state.rank_in_group
symm_mem_hdl = state.symm_mem_hdl
@@ -10,7 +10,6 @@ from sglang.srt.utils import is_xpu
class XpuCommunicator:
def __init__(self, group: ProcessGroup):
if not is_xpu():
self.disabled = True
+55 -55
View File
@@ -1036,9 +1036,9 @@ class GroupCoordinator:
# Bypass the function if we are using only 1 GPU.
if world_size == 1:
return input_
assert (
-input_.dim() <= dim < input_.dim()
), f"Invalid dim ({dim}) for input tensor with shape {input_.size()}"
assert -input_.dim() <= dim < input_.dim(), (
f"Invalid dim ({dim}) for input tensor with shape {input_.size()}"
)
if dim < 0:
# Convert negative dim to positive.
@@ -1178,9 +1178,9 @@ class GroupCoordinator:
pynccl_comm = self.pynccl_comm
with pynccl_comm.change_state(enable=True):
assert (
pynccl_comm is not None and not pynccl_comm.disabled
), "pynccl is required for reduce_scatterv"
assert pynccl_comm is not None and not pynccl_comm.disabled, (
"pynccl is required for reduce_scatterv"
)
if sizes is not None:
assert len(sizes) == world_size
@@ -1303,9 +1303,9 @@ class GroupCoordinator:
output_tensor_list, input_, group=self.device_group
)
assert (
-input_.dim() <= dim < input_.dim()
), f"Invalid dim ({dim}) for input tensor with shape {input_.size()}"
assert -input_.dim() <= dim < input_.dim(), (
f"Invalid dim ({dim}) for input tensor with shape {input_.size()}"
)
# For HPUs, use HPU communicator.
hpu_comm = self.hpu_communicator
@@ -1369,9 +1369,9 @@ class GroupCoordinator:
pynccl_comm = self.pynccl_comm
with pynccl_comm.change_state(enable=True):
assert (
pynccl_comm is not None and not pynccl_comm.disabled
), "pynccl is required for all_gatherv"
assert pynccl_comm is not None and not pynccl_comm.disabled, (
"pynccl is required for all_gatherv"
)
def _all_gather_allocate_output(
input_: torch.Tensor,
@@ -1435,9 +1435,9 @@ class GroupCoordinator:
# Bypass the function if we are using only 1 GPU.
if world_size == 1:
return input_
assert (
-input_.dim() <= dim < input_.dim()
), f"Invalid dim ({dim}) for input tensor with shape {input_.size()}"
assert -input_.dim() <= dim < input_.dim(), (
f"Invalid dim ({dim}) for input tensor with shape {input_.size()}"
)
if dim < 0:
# Convert negative dim to positive.
dim += input_.dim()
@@ -1580,9 +1580,9 @@ class GroupCoordinator:
"""NOTE: `src` is the local rank of the source rank."""
assert src < self.world_size, f"Invalid src rank ({src})"
assert (
src != self.rank_in_group
), "Invalid source rank. Source rank is the same as the current rank."
assert src != self.rank_in_group, (
"Invalid source rank. Source rank is the same as the current rank."
)
size_tensor = torch.empty(1, dtype=torch.long, device="cpu")
@@ -1629,9 +1629,9 @@ class GroupCoordinator:
rank_in_group = self.rank_in_group
if rank_in_group == src:
metadata_list: List[Tuple[Any, Any]] = []
assert isinstance(
tensor_dict, dict
), f"Expecting a dictionary, got {type(tensor_dict)}"
assert isinstance(tensor_dict, dict), (
f"Expecting a dictionary, got {type(tensor_dict)}"
)
metadata_list, tensor_list = _split_tensor_dict(tensor_dict)
# `metadata_list` lives in CPU memory.
# `broadcast_object_list` has serialization & deserialization,
@@ -1716,9 +1716,9 @@ class GroupCoordinator:
dst = (self.rank_in_group + 1) % self.world_size
assert dst < self.world_size, f"Invalid dst rank ({dst})"
assert isinstance(
tensor_dict, dict
), f"Expecting a dictionary, got {type(tensor_dict)}"
assert isinstance(tensor_dict, dict), (
f"Expecting a dictionary, got {type(tensor_dict)}"
)
metadata_list, tensor_list = _split_tensor_dict(tensor_dict)
# Note: While switching to Device-to-Device (D2D) would introduce an extra
# Device-to-Host (D2H) memory copy overhead for serialization, our benchmarks
@@ -1948,25 +1948,25 @@ def set_pdmux_status(enable_prefill_multiplexing: bool):
def get_tp_group() -> GroupCoordinator:
if _ENABLE_PDMUX_P_TP:
assert (
_PDMUX_PREFILL_TP_GROUP is not None
), "tensor model parallel group for PD-Multiplexing Prefill is not initialized"
assert _PDMUX_PREFILL_TP_GROUP is not None, (
"tensor model parallel group for PD-Multiplexing Prefill is not initialized"
)
return _PDMUX_PREFILL_TP_GROUP
assert _TP is not None, "tensor model parallel group is not initialized"
return _TP
def get_attn_tp_group() -> GroupCoordinator:
assert (
_ATTN_TP is not None
), "attention tensor model parallel group is not initialized"
assert _ATTN_TP is not None, (
"attention tensor model parallel group is not initialized"
)
return _ATTN_TP
def get_attn_cp_group() -> GroupCoordinator:
assert (
_ATTN_CP is not None
), "attention context model parallel group is not initialized"
assert _ATTN_CP is not None, (
"attention context model parallel group is not initialized"
)
return _ATTN_CP
@@ -1987,9 +1987,9 @@ def _init_attn_cp_overlap_group(
"""Second communicator over the attention CP ranks; RCCL deadlocks when one
communicator is driven from two streams at once."""
global _ATTN_CP_OVERLAP
assert (
_ATTN_CP_OVERLAP is None
), "attention context parallel overlap group is already initialized"
assert _ATTN_CP_OVERLAP is None, (
"attention context parallel overlap group is already initialized"
)
if attn_cp_size <= 1:
return
@@ -2259,7 +2259,7 @@ def init_distributed_environment(
max_world_size: Optional[int] = None,
):
logger.debug(
"world_size=%d rank=%d local_rank=%d " "distributed_init_method=%s backend=%s",
"world_size=%d rank=%d local_rank=%d distributed_init_method=%s backend=%s",
world_size,
rank,
local_rank,
@@ -2334,9 +2334,9 @@ def init_distributed_environment(
ranks, local_rank, backend, recovered_rank=recovered_rank
)
else:
assert (
_WORLD.world_size == torch.distributed.get_world_size()
), "world group already initialized with a different world size"
assert _WORLD.world_size == torch.distributed.get_world_size(), (
"world group already initialized with a different world size"
)
def initialize_model_parallel(
@@ -2470,9 +2470,9 @@ def initialize_model_parallel(
if duplicate_tp_group:
global _PDMUX_PREFILL_TP_GROUP
assert (
_PDMUX_PREFILL_TP_GROUP is None
), "tensor model parallel group for PD-Multiplexing Prefill is already initialized"
assert _PDMUX_PREFILL_TP_GROUP is None, (
"tensor model parallel group for PD-Multiplexing Prefill is already initialized"
)
_PDMUX_PREFILL_TP_GROUP = init_model_parallel_group(
group_ranks,
get_world_group().local_rank,
@@ -2526,9 +2526,9 @@ def initialize_model_parallel(
attn_tp_size = derived_widths["attn_tp_size"]
global _ATTN_CP
assert (
_ATTN_CP is None
), "attention context model parallel group is already initialized"
assert _ATTN_CP is None, (
"attention context model parallel group is already initialized"
)
if attn_cp_size == tensor_model_parallel_size:
_ATTN_CP = _TP
else:
@@ -2573,9 +2573,9 @@ def initialize_model_parallel(
from sglang.srt.layers.sampler import SYNC_TOKEN_IDS_ACROSS_TP
global _ATTN_TP
assert (
_ATTN_TP is None
), "attention tensor model parallel group is already initialized"
assert _ATTN_TP is None, (
"attention tensor model parallel group is already initialized"
)
if attn_tp_size == tensor_model_parallel_size:
_ATTN_TP = _TP
else:
@@ -2821,9 +2821,9 @@ def ensure_model_parallel_initialized(
)
if decode_context_parallel_size > 1:
dcp_world_size = get_dcp_group().world_size
assert (
dcp_world_size == decode_context_parallel_size
), f"decode context parallel group already initialized, but of unexpected size: {dcp_world_size=} {decode_context_parallel_size=}"
assert dcp_world_size == decode_context_parallel_size, (
f"decode context parallel group already initialized, but of unexpected size: {dcp_world_size=} {decode_context_parallel_size=}"
)
def model_parallel_is_initialized():
@@ -3084,9 +3084,9 @@ def in_the_same_node_as(pg: ProcessGroup, source_rank: int = 0) -> List[bool]:
as the source rank. It tests if processes are attached to the same
memory system (shared access to shared memory).
"""
assert (
torch.distributed.get_backend(pg) != torch.distributed.Backend.NCCL
), "in_the_same_node_as should be tested with a non-NCCL group."
assert torch.distributed.get_backend(pg) != torch.distributed.Backend.NCCL, (
"in_the_same_node_as should be tested with a non-NCCL group."
)
# local rank inside the group
rank = torch.distributed.get_rank(group=pg)
world_size = torch.distributed.get_world_size(group=pg)
+2 -2
View File
@@ -197,13 +197,13 @@ class StatelessProcessGroup:
"""
if self.rank == src:
self.expire_data()
key = f"broadcast_from/{src}/" f"{self.broadcast_send_counter}"
key = f"broadcast_from/{src}/{self.broadcast_send_counter}"
self.store.set(key, pickle.dumps(obj))
self.broadcast_send_counter += 1
self.entries.append((key, time.perf_counter()))
return obj
else:
key = f"broadcast_from/{src}/" f"{self.broadcast_recv_src_counter[src]}"
key = f"broadcast_from/{src}/{self.broadcast_recv_src_counter[src]}"
recv_obj = pickle.loads(self.store.get(key))
self.broadcast_recv_src_counter[src] += 1
return recv_obj
+3 -3
View File
@@ -86,8 +86,8 @@ class ReqDllmMixin:
def _update_block_offset_for_dllm(self):
prefix_len = len(self.prefix_indices)
assert (
prefix_len % self.dllm_config.block_size == 0
), f"Unexpected prefix len: {prefix_len}"
assert prefix_len % self.dllm_config.block_size == 0, (
f"Unexpected prefix len: {prefix_len}"
)
if prefix_len > self.dllm_block_offset:
self.dllm_block_offset = prefix_len
+5 -6
View File
@@ -75,9 +75,9 @@ class SchedulerDllmMixin:
result.copy_done.synchronize()
fdfo_mode = self.dllm_config.first_done_first_out_mode
assert (
not fdfo_mode or result.accept_length_per_req_cpu is not None
), "FDFO dLLM result is missing accept lengths."
assert not fdfo_mode or result.accept_length_per_req_cpu is not None, (
"FDFO dLLM result is missing accept lengths."
)
# FDFO also commits unresolved blocks so their KV can be reused.
if fdfo_mode or result.next_token_ids:
@@ -317,9 +317,8 @@ class SchedulerDllmMixin:
# Try preemption if batch is full
if running_batch.batch_is_full:
if (
not self.enable_priority_preemption
or not adder.preempt_to_schedule(req)
if not self.enable_priority_preemption or not adder.preempt_to_schedule(
req
):
break
@@ -284,13 +284,13 @@ class AnthropicThinkingParam(BaseModel):
if self.type == "enabled":
if self.budget_tokens is None:
raise ValueError(
"thinking.budget_tokens is required when "
"thinking.type is 'enabled'"
"thinking.budget_tokens is required when thinking.type is 'enabled'"
)
if self.budget_tokens < 1024:
raise ValueError(
"thinking.budget_tokens must be >= 1024 "
"(got {})".format(self.budget_tokens)
"thinking.budget_tokens must be >= 1024 (got {})".format(
self.budget_tokens
)
)
elif self.type == "disabled":
if self.budget_tokens is not None:
@@ -300,8 +300,7 @@ class AnthropicThinkingParam(BaseModel):
)
if self.display is not None:
raise ValueError(
"thinking.display is not allowed when "
"thinking.type is 'disabled'"
"thinking.display is not allowed when thinking.type is 'disabled'"
)
elif self.type == "adaptive":
if self.budget_tokens is not None:
@@ -1069,8 +1069,7 @@ class AnthropicServing:
effective_finish = finish_reason or "stop"
if effective_finish not in STOP_REASON_MAP:
logger.warning(
"Unmapped streaming finish_reason %r; defaulting "
"to end_turn",
"Unmapped streaming finish_reason %r; defaulting to end_turn",
effective_finish,
)
stop_reason = STOP_REASON_MAP.get(effective_finish, "end_turn")
-4
View File
@@ -24,7 +24,6 @@ from sglang.srt.entrypoints.tool import Tool
class ConversationContext(ABC):
@abstractmethod
def append_output(self, output) -> None:
pass
@@ -43,7 +42,6 @@ class ConversationContext(ABC):
class SimpleContext(ConversationContext):
def __init__(self):
self.last_output = None
@@ -61,7 +59,6 @@ class SimpleContext(ConversationContext):
class HarmonyContext(ConversationContext):
def __init__(
self,
messages: list,
@@ -182,7 +179,6 @@ class HarmonyContext(ConversationContext):
class StreamingHarmonyContext(HarmonyContext):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.last_output = None
+5 -3
View File
@@ -545,9 +545,11 @@ class RuntimeHandle:
obj = UpdateWeightFromDiskReqInput(
model_path=model_path, load_format=load_format
)
success, message, num_paused = (
await self.tokenizer_manager.update_weights_from_disk(obj, request=None)
)
(
success,
message,
num_paused,
) = await self.tokenizer_manager.update_weights_from_disk(obj, request=None)
return {
"success": success,
"message": message,
+13 -11
View File
@@ -231,9 +231,9 @@ async def init_multi_tokenizer() -> ServerArgs:
publish(server_args, role="tokenizer")
# API key authentication is not supported in multi-tokenizer mode
assert (
get_serving().api_key is None
), "API key is not supported in multi-tokenizer mode"
assert get_serving().api_key is None, (
"API key is not supported in multi-tokenizer mode"
)
# Create a new ipc name for the current process
port_args.tokenizer_ipc_name = (
@@ -819,9 +819,9 @@ async def server_info():
HiCache mirror by `GET /hicache/storage-backend`.
"""
# Returns internal states per DP.
internal_states: List[Dict[Any, Any]] = (
await _global_state.tokenizer_manager.get_internal_state()
)
internal_states: List[
Dict[Any, Any]
] = await _global_state.tokenizer_manager.get_internal_state()
server_args = _global_state.tokenizer_manager.server_args
@@ -1523,9 +1523,12 @@ async def check_weights(
):
if obj is None:
obj = CheckWeightsReqInput()
success, message, ranks, per_engine_checksum = (
await _global_state.tokenizer_manager.check_weights(obj, request)
)
(
success,
message,
ranks,
per_engine_checksum,
) = await _global_state.tokenizer_manager.check_weights(obj, request)
body = {"success": success, "message": message}
if ranks is not None:
body["ranks"] = ranks
@@ -2395,8 +2398,7 @@ def _wait_and_warmup(
skip_elastic_joiner_warmup = server_args.is_ep_scale_joiner
if skip_elastic_joiner_warmup:
logger.debug(
"[Elastic EP] Skipping server warmup for elastic joiner "
"(ep_join_mode=%s)",
"[Elastic EP] Skipping server warmup for elastic joiner (ep_join_mode=%s)",
get_exec().moe.ep_join_mode,
)
@@ -46,9 +46,7 @@ user_msg_template: str = "<|User|>{content}<|Assistant|>"
assistant_msg_template: str = "{reasoning}{content}{tool_calls}<|end▁of▁sentence|>"
thinking_template = "{reasoning_content}"
response_format_template: str = (
"## Response Format:\n\nYou MUST strictly adhere to the following schema to reply:\n{schema}"
)
response_format_template: str = "## Response Format:\n\nYou MUST strictly adhere to the following schema to reply:\n{schema}"
tool_call_template: str = (
'<{dsml_token}invoke name="{name}">\n{arguments}\n</{dsml_token}invoke>'
)
@@ -47,9 +47,7 @@ assistant_msg_template: str = "{reasoning}{content}{tool_calls}" + eos_token
assistant_msg_wo_eos_template: str = "{reasoning}{content}{tool_calls}"
thinking_template: str = "{reasoning_content}"
response_format_template: str = (
"## Response Format:\n\nYou MUST strictly adhere to the following schema to reply:\n{schema}"
)
response_format_template: str = "## Response Format:\n\nYou MUST strictly adhere to the following schema to reply:\n{schema}"
tool_call_template: str = (
'<{dsml_token}invoke name="{name}">\n{arguments}\n</{dsml_token}invoke>'
)
@@ -447,9 +445,9 @@ def render_message(
task = messages[index].get("task")
if task is not None:
# Task special token for internal classification tasks
assert (
task in VALID_TASKS
), f"Invalid task: '{task}'. Valid tasks are: {list(VALID_TASKS)}"
assert task in VALID_TASKS, (
f"Invalid task: '{task}'. Valid tasks are: {list(VALID_TASKS)}"
)
task_sp_token = DS_TASK_SP_TOKENS[task]
if task != "action":
@@ -843,9 +841,9 @@ def parse_message_from_completion_text(text: str, thinking_mode: str) -> Dict[st
index, text, [thinking_end_token, tool_calls_start_token]
)
reasoning_content = content_delta
assert (
stop_token == thinking_end_token
), "Invalid thinking format: missing </think>"
assert stop_token == thinking_end_token, (
"Invalid thinking format: missing </think>"
)
index, content_delta, stop_token = _read_until_stop(
index, text, [eos_token, tool_calls_start_token]
@@ -874,9 +872,9 @@ def parse_message_from_completion_text(text: str, thinking_mode: str) -> Dict[st
thinking_end_token,
dsml_token,
]:
assert (
sp_token not in summary_content and sp_token not in reasoning_content
), f"Unexpected special token '{sp_token}' in content"
assert sp_token not in summary_content and sp_token not in reasoning_content, (
f"Unexpected special token '{sp_token}' in content"
)
return {
"role": "assistant",
@@ -308,9 +308,7 @@ class OpenAIServingCompletion(OpenAIServingBase):
output_top_logprobs = content["meta_info"].get(
"output_top_logprobs", []
)
if (
not self.tokenizer_manager.server_args.incremental_streaming_output
):
if not self.tokenizer_manager.server_args.incremental_streaming_output:
output_token_logprobs = output_token_logprobs[
n_prev_token:total_output_logprobs
]
@@ -329,9 +327,7 @@ class OpenAIServingCompletion(OpenAIServingBase):
chunk_prompt_token_ids = None
if request.return_token_ids:
output_ids = content["output_ids"]
if (
not self.tokenizer_manager.server_args.incremental_streaming_output
):
if not self.tokenizer_manager.server_args.incremental_streaming_output:
n_prev_token_id = n_prev_token_ids.get(index, 0)
chunk_token_ids = output_ids[n_prev_token_id:]
n_prev_token_ids[index] = len(output_ids)
@@ -333,8 +333,7 @@ class OpenAIServingResponses(OpenAIServingChat):
)
):
return self.create_error_response(
"MCP tool server is not supported in background mode and "
"streaming mode"
"MCP tool server is not supported in background mode and streaming mode"
)
# Schedule the request and get the result generator
@@ -540,17 +539,17 @@ class OpenAIServingResponses(OpenAIServingChat):
require_reasoning=require_reasoning,
)
try:
result: Union[ORJSONResponse, ResponsesResponse] = (
await self.responses_full_generator(
request,
sampling_params,
result_generator,
context,
model_name,
tokenizer,
request_metadata,
require_reasoning=require_reasoning,
)
result: Union[
ORJSONResponse, ResponsesResponse
] = await self.responses_full_generator(
request,
sampling_params,
result_generator,
context,
model_name,
tokenizer,
request_metadata,
require_reasoning=require_reasoning,
)
return result
except Exception as e:
@@ -609,7 +608,7 @@ class OpenAIServingResponses(OpenAIServingChat):
):
if request.tool_choice != "auto":
raise NotImplementedError(
"Only 'auto' tool_choice is supported in " "response API"
"Only 'auto' tool_choice is supported in response API"
)
messages = self._construct_input_messages_with_harmony(request, prev_response)
prompt_token_ids = render_for_completion(messages)
@@ -1333,9 +1332,7 @@ class OpenAIServingResponses(OpenAIServingChat):
recent_turn_msgs = prev_msgs[prev_final_msg_idx + 1 :]
del prev_msgs[prev_final_msg_idx + 1 :]
for msg in recent_turn_msgs:
if (
hasattr(msg, "channel") and msg.channel != "analysis"
): # type: ignore[union-attr]
if hasattr(msg, "channel") and msg.channel != "analysis": # type: ignore[union-attr]
prev_msgs.append(msg)
messages.extend(prev_msgs)
# Append the new input.
@@ -1489,8 +1486,7 @@ class OpenAIServingResponses(OpenAIServingChat):
# Get event type from the event's type field if it exists
event_type = getattr(event, "type", "unknown")
return (
f"event: {event_type}\n"
f"data: {event.model_dump_json(indent=None)}\n\n"
f"event: {event_type}\ndata: {event.model_dump_json(indent=None)}\n\n"
)
current_content_index = 0
@@ -1919,8 +1915,7 @@ class OpenAIServingResponses(OpenAIServingChat):
sequence_number += 1
event_type = getattr(event, "type", "unknown")
return (
f"event: {event_type}\n"
f"data: {event.model_dump_json(indent=None)}\n\n"
f"event: {event_type}\ndata: {event.model_dump_json(indent=None)}\n\n"
)
# The streaming Response* event models echo ``tools`` through a
@@ -72,7 +72,6 @@ def post_process_tools_description(
class ToolServer(ABC):
@abstractmethod
def has_tool(self, tool_name: str):
pass
@@ -86,7 +85,6 @@ class ToolServer(ABC):
class MCPToolServer(ToolServer):
def __init__(self):
self.harmony_tool_descriptions = {}
@@ -143,7 +141,6 @@ class MCPToolServer(ToolServer):
class DemoToolServer(ToolServer):
def __init__(self, *, enable_python: bool = True):
from sglang.srt.entrypoints.tool import (
HarmonyBrowserTool,
+1 -1
View File
@@ -46,7 +46,7 @@ class SSLCertRefresher:
try:
async for _changes in awatch(self._cert_path, self._key_path):
logger.info(
"SSL cert/key file change detected, reloading: " "cert=%s key=%s",
"SSL cert/key file change detected, reloading: cert=%s key=%s",
self._cert_path,
self._key_path,
)
-3
View File
@@ -20,14 +20,12 @@ logger = logging.getLogger(__name__)
class Tool(ABC):
@abstractmethod
async def get_result(self, context: "ConversationContext") -> Any:
pass
class HarmonyBrowserTool(Tool):
def __init__(self, client: ExaClient | None = None):
self.enabled = True
if client is not None:
@@ -257,7 +255,6 @@ class HarmonyBrowserTool(Tool):
class HarmonyPythonTool(Tool):
def __init__(self):
self.enabled = True
+3 -1
View File
@@ -58,7 +58,9 @@ class EPLBManager:
assert (
get_exec().moe.eplb_rebalance_num_iterations
>= get_exec().moe.expert_distribution_recorder_buffer_size
), "eplb_rebalance_num_iterations must be greater than expert_distribution_recorder_buffer_size"
), (
"eplb_rebalance_num_iterations must be greater than expert_distribution_recorder_buffer_size"
)
if not get_global_expert_distribution_recorder().recording:
get_global_expert_distribution_recorder().start_record()
@@ -24,9 +24,9 @@ def read_mode_per_pass(dir_data: Path):
for record in data_pack["records"]:
forward_pass_id = record["forward_pass_id"]
rank = record["rank"]
assert (
gpc_of_forward_pass_and_rank[forward_pass_id].get(rank) is None
), f"Duplicated {forward_pass_id=} {rank=}"
assert gpc_of_forward_pass_and_rank[forward_pass_id].get(rank) is None, (
f"Duplicated {forward_pass_id=} {rank=}"
)
gpc_of_forward_pass_and_rank[forward_pass_id][rank] = record[
"global_physical_count"
]
+12 -10
View File
@@ -89,9 +89,9 @@ class ExpertDistributionRecorder(ABC):
rank: int,
):
if get_exec().moe.expert_distribution_recorder_mode is not None:
assert (
expert_location_metadata is not None
), "ExpertLocationMetadata is required for expert distribution recording. One possible"
assert expert_location_metadata is not None, (
"ExpertLocationMetadata is required for expert distribution recording. One possible"
)
"reason is that you are using a model that does not support expert distribution"
"recording. Try setting `get_model_config_for_expert_location` in your model."
return _ExpertDistributionRecorderReal(expert_location_metadata, rank)
@@ -265,9 +265,9 @@ class _ExpertDistributionRecorderReal(ExpertDistributionRecorder):
def _reset(self):
"""Reset the expert distribution recorder."""
logger.info("Resetting ExpertDistributionRecorder...")
assert (
self._current_layer_idx.value is None
), f"{self._current_layer_idx.value=}"
assert self._current_layer_idx.value is None, (
f"{self._current_layer_idx.value=}"
)
for gatherer in self._single_pass_gatherers.values():
gatherer.reset()
self._accumulator.reset()
@@ -409,9 +409,9 @@ class _DetailSinglePassGatherer(_SinglePassGatherer):
device=get_device_namespace().device,
)
self._misc_objects: List[Dict[str, Any]] = []
assert (
not get_exec().overlap.enable_two_batch_overlap
), "DetailSinglePassGatherer does not support TBO yet"
assert not get_exec().overlap.enable_two_batch_overlap, (
"DetailSinglePassGatherer does not support TBO yet"
)
# TODO assert shared experts fusion is disabled, o/w data is wrong
def on_forward_pass_start(self, forward_batch: ForwardBatch):
@@ -794,7 +794,9 @@ class _UtilizationRateAccumulatorMixin(_Accumulator):
assert (
self._expert_location_metadata.ep_size
== len(count_of_layer._buckets) - 1
), f"{self._expert_location_metadata.ep_size=}, {len(count_of_layer._buckets)=}"
), (
f"{self._expert_location_metadata.ep_size=}, {len(count_of_layer._buckets)=}"
)
for gpu_rank in range(self._expert_location_metadata.ep_size):
count = gpu_physical_count[layer_idx, gpu_rank]
if count > 0:
+1 -2
View File
@@ -447,8 +447,7 @@ def format_physical_to_logical_map(
row = physical_to_logical_map[layer_id].tolist()
if remainder != 0:
lines.append(
f"layer={layer_id}: "
f"physical={json.dumps(row, separators=(',', ':'))}"
f"layer={layer_id}: physical={json.dumps(row, separators=(',', ':'))}"
)
continue

Some files were not shown because too many files have changed in this diff Show More