Files
wehub-resource-sync 94057c3d3e
PR Test (NPU) / check-changes (push) Has been cancelled
PR Test (NPU) / pr-gate (push) Has been cancelled
PR Test (NPU) / set-image-config (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-4-npu-a3 (push) Has been cancelled
PR Test (NPU) / stage-b-test-16-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-1-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-2-npu-a3 (push) Has been cancelled
PR Test (Arm64) / pr-gate (push) Has been cancelled
PR Test (Arm64) / check-changes (push) Has been cancelled
PR Test (Arm64) / build-test (push) Has been cancelled
PR Test (sgl-router) / gate (push) Has been cancelled
PR Test (sgl-router) / tier-1 — lint (push) Has been cancelled
PR Test (sgl-router) / tier-2 — build + test (push) Has been cancelled
PR Test (sgl-router) / tier-3 — docker (placeholder) (push) Has been cancelled
PR Test (sgl-router) / tier-3 — k8s integration (push) Has been cancelled
PR Test (sgl-router) / tier-3 — e2e (push) Has been cancelled
PR Test (sgl-router) / finish (push) Has been cancelled
PR Test (NPU) / single-node-poc (map[name:qwen3_6_27b_w8a8_1p_in64k_out1k_50ms runner:linux-aarch64-a3-2 test_case:test/registered/ascend/performance/qwen3_6_27b/test_npu_qwen3_6_27b_w8a8_1p_in64k_out1k_50ms.py test_type:perf]) (push) Has been cancelled
PR Test (NPU) / pr-test-npu-finish (push) Has been cancelled
PR Test (Xeon) / pr-gate (push) Has been cancelled
PR Test (Xeon) / check-changes (push) Has been cancelled
PR Test (Xeon) / build-test (, xeon-gnr, base-b-test-cpu) (push) Has been cancelled
PR Test (XPU) / check-changes (push) Has been cancelled
PR Test (XPU) / pr-gate (push) Has been cancelled
PR Test (XPU) / stage-a-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / wait-for-stage-a (push) Has been cancelled
PR Test (XPU) / stage-b-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / finish (push) Has been cancelled
CI Model Inventory / build-inventory (push) Has been cancelled
Lint / lint (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Compilation Check (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Manual Policy (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Request Processing (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Summary (push) Has been cancelled
PR Test (SMG) / build-wheel (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on windows (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (x86_64 - auto) (push) Has been cancelled
PR Test (SMG) / python-unit-tests (push) Has been cancelled
PR Test (SMG) / unit-tests (push) Has been cancelled
PR Test (SMG) / benchmarks (push) Has been cancelled
PR Test (SMG) / chat-completions (push) Has been cancelled
PR Test (SMG) / chat-completions-4gpu (push) Has been cancelled
PR Test (SMG) / e2e (push) Has been cancelled
PR Test (SMG) / docker-build-test (push) Has been cancelled
PR Test (SMG) / k8s-integration (push) Has been cancelled
PR Test (SMG) / finish (push) Has been cancelled
PR Test (SMG) / summarize-benchmarks (push) Has been cancelled
Release SGLang Model Gateway Docker Image / publish (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Build SDist (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Upload to PyPI (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (aarch64, 12.9, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (x86_64, 12.9, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu129 (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (aarch64, 13.0, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (x86_64, 13.0, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu130 (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 700) (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 720) (push) Has been cancelled
Release SGLang Kernels / release-rocm700 (push) Has been cancelled
Release SGLang Kernels / release-rocm720 (push) Has been cancelled
Release SGLang Kernels / build-musa43 (43, 3.10) (push) Has been cancelled
Release SGLang Kernels / release-musa43 (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:38:16 +08:00

237 lines
8.2 KiB
Python

"""Internal storage backing ``SpeculativeAlgorithm.register``. Plugins
should use that classmethod API; do not import from this module directly.
"""
from __future__ import annotations
import logging
from typing import TYPE_CHECKING, Callable, Dict, Optional, Type
import torch
if TYPE_CHECKING:
from sglang.srt.managers.overlap_utils import FutureMap
from sglang.srt.managers.schedule_batch import ScheduleBatch
from sglang.srt.server_args import ServerArgs
from sglang.srt.speculative.spec_info import SpecInput
WorkerFactory = Callable[["ServerArgs"], Type]
ServerArgsValidator = Callable[["ServerArgs"], None]
logger = logging.getLogger(__name__)
class CustomSpecAlgo:
"""A plugin-registered speculative algorithm. Duck-types
``SpeculativeAlgorithm`` enum values (same ``is_*()`` / ``create_worker``
interface).
Plugins may subclass this to override any ``is_*()`` / ``supports_*()`` /
``create_worker`` method (e.g. to integrate with builtin-specific
branches like ``if spec_algorithm.is_eagle():`` in scheduler /
model_runner). Pass the subclass via ``spec_class=...`` at registration.
Defaults: all ``is_*()`` return ``False`` except ``is_speculative``.
``supports_overlap=False`` is deprecated: the spec V1 worker path has been
removed, so such algorithms run on the V2 scheduler schema with overlap
disabled (synchronous). Migrate plugin workers to the V2 schema and
overlap scheduling.
"""
def __init__(
self,
name: str,
factory: WorkerFactory,
*,
supports_overlap: bool = False,
validate_server_args: Optional[ServerArgsValidator] = None,
):
self.name = name
self.factory = factory
self.supports_overlap = supports_overlap
self.validate_server_args = validate_server_args
def __repr__(self) -> str:
return f"CustomSpecAlgo({self.name!r})"
def is_some(self) -> bool:
return True
def is_none(self) -> bool:
return False
def is_speculative(self) -> bool:
return True
def is_eagle(self) -> bool:
return False
def is_eagle3(self) -> bool:
return False
def is_frozen_kv_mtp(self) -> bool:
return False
def is_dflash(self) -> bool:
return False
def is_dspark(self) -> bool:
return False
def is_dflash_family(self) -> bool:
return False
def is_standalone(self) -> bool:
return False
def is_ngram(self) -> bool:
return False
def supports_target_verify_for_draft(self) -> bool:
return False
def supports_ragged_verify(self) -> bool:
return False
def has_draft_kv(self) -> bool:
# Conservative default: the larger KV reserve.
return True
def handle_server_args(self, server_args: ServerArgs) -> None:
pass
def create_worker(self, server_args: ServerArgs) -> Type:
if not server_args.disable_overlap_schedule and not self.supports_overlap:
raise ValueError(
f"Speculative algorithm {self.name} does not support overlap scheduling."
)
if not self.supports_overlap:
# Reached only when overlap is disabled, so the algorithm really
# does run synchronously on the V2 schema below.
logger.warning(
"Speculative algorithm %s is registered with "
"supports_overlap=False, which is deprecated: the spec V1 "
"worker path has been removed, and the algorithm now runs on "
"the V2 scheduler schema with overlap disabled (synchronous). "
"Migrate the plugin worker to support overlap scheduling.",
self.name,
)
return self.factory(server_args)
def get_num_tokens_per_bs_for_target_verify(
self, num_draft_tokens: int, is_draft_worker: bool
) -> int:
# FIXME: Remove this after the forward mode refactor. Target verify is
# essentially a fixed sequence length prefill/extend with full cuda
# graph support. We can use it for target verify, or we can use it for
# other cases which is not target verify but fixed length prefill.
# Here, we expose this interface to allow the other use cases.
return num_draft_tokens
def build_disagg_draft_input(
self,
batch: ScheduleBatch,
server_args: ServerArgs,
last_tokens_tensor: torch.Tensor,
future_map: FutureMap,
) -> Optional[SpecInput]:
return None
_REGISTRY: Dict[str, CustomSpecAlgo] = {}
# CLI spellings that are not ``SpeculativeAlgorithm`` members but still resolve
# to a builtin (e.g. NEXTN -> EAGLE). Reserved alongside the enum members so
# plugins cannot shadow them.
_RESERVED_ALIASES = frozenset({"NEXTN"})
def _reserved_names() -> frozenset:
"""Names plugins cannot register under: every ``SpeculativeAlgorithm``
member plus ``_RESERVED_ALIASES``.
Derived from the enum (lazily, to avoid a circular import — ``spec_info``
imports this module) so any new builtin is reserved automatically without
editing a second list.
"""
from sglang.srt.speculative.spec_info import SpeculativeAlgorithm
return frozenset(algo.name for algo in SpeculativeAlgorithm) | _RESERVED_ALIASES
def _assert_custom_spec_algo_conforms(spec_class: Type[CustomSpecAlgo]) -> None:
"""Fail fast if ``spec_class`` drifts from the ``SpeculativeAlgorithm``
duck-typing contract.
``from_string`` returns either type and callers dispatch on the shared
``is_*()`` / ``supports_*()`` interface without isinstance checks, so every
such method on the enum must also exist on the registered spec class —
otherwise a plugin-registered algo hits ``AttributeError`` at a call site
(this is how ``is_some`` / ``is_frozen_kv_mtp`` silently went missing). New
predicates are covered automatically; no second list to maintain.
Called from ``register_algorithm`` rather than at import time because
``spec_info`` imports this module, so ``SpeculativeAlgorithm`` does not yet
exist while this module is loading; at registration time it is fully
defined.
"""
# NOTE: use ``vars()`` not ``dir()`` for the enum — ``EnumMeta.__dir__``
# hides instance methods, so ``dir(SpeculativeAlgorithm)`` would yield an
# empty interface and turn this guard into a silent no-op.
from sglang.srt.speculative.spec_info import SpeculativeAlgorithm
interface = {
name
for name in vars(SpeculativeAlgorithm)
if name.startswith(("is_", "supports_"))
}
missing = sorted(interface - set(dir(spec_class)))
if missing:
raise TypeError(
f"{spec_class.__name__} is missing duck-typed methods from "
f"SpeculativeAlgorithm: {missing}. Add them to {spec_class.__name__} "
"so plugin-registered algorithms stay dispatchable."
)
def register_algorithm(
name: str,
*,
supports_overlap: bool = False,
validate_server_args: Optional[ServerArgsValidator] = None,
spec_class: Type[CustomSpecAlgo] = CustomSpecAlgo,
) -> Callable[[WorkerFactory], WorkerFactory]:
"""Return a decorator that registers a plugin algorithm under ``name``.
Pass a ``spec_class`` subclass of ``CustomSpecAlgo`` to override any
``is_*()`` / ``supports_*()`` / ``create_worker`` method.
"""
upper = name.upper()
if upper in _reserved_names():
raise ValueError(
f"'{upper}' is a reserved speculative algorithm name; cannot be re-registered."
)
if upper in _REGISTRY:
raise ValueError(f"Speculative algorithm '{upper}' already registered.")
_assert_custom_spec_algo_conforms(spec_class)
def decorator(factory: WorkerFactory) -> WorkerFactory:
_REGISTRY[upper] = spec_class(
name=upper,
factory=factory,
supports_overlap=supports_overlap,
validate_server_args=validate_server_args,
)
return factory
return decorator
def get_spec(name: Optional[str]) -> Optional[CustomSpecAlgo]:
"""Return the registered spec for ``name``, or ``None`` for builtin /
unknown names."""
if name is None:
return None
return _REGISTRY.get(name.upper())