sgl-project--sglang
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
207 行
7.0 KiB
Python
207 行
7.0 KiB
Python
import time
|
|
import unittest
|
|
import uuid
|
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
from types import SimpleNamespace
|
|
|
|
import requests
|
|
from prometheus_client.parser import text_string_to_metric_families
|
|
|
|
from sglang.srt.disaggregation.prefill import should_force_retry
|
|
from sglang.srt.environ import envs
|
|
from sglang.test.ci.ci_register import register_cuda_ci
|
|
from sglang.test.run_eval import run_eval
|
|
from sglang.test.server_fixtures.disaggregation_fixture import (
|
|
PDDisaggregationServerBase,
|
|
)
|
|
from sglang.test.test_utils import DEFAULT_MODEL_NAME_FOR_TEST
|
|
|
|
register_cuda_ci(est_time=120, stage="base-b", runner_config="2-gpu-large")
|
|
|
|
|
|
FORCE_RETRY_PROB = 0.1
|
|
|
|
|
|
def rid_that_forces_retry(prefix: str) -> str:
|
|
"""Return a rid that the test retry sampler will select."""
|
|
for _ in range(1000):
|
|
rid = f"{prefix}{uuid.uuid4().hex}"
|
|
req = SimpleNamespace(
|
|
rid=rid,
|
|
is_retracted=False,
|
|
prefill_attempt_count=0,
|
|
)
|
|
if should_force_retry(req):
|
|
return rid
|
|
raise RuntimeError("Failed to sample an optimistic prefill retry rid")
|
|
|
|
|
|
class OptimisticPrefillRetryCounterMixin:
|
|
def _get_retry_counter(self) -> float:
|
|
response = requests.get(f"{self.prefill_url}/metrics")
|
|
response.raise_for_status()
|
|
total = 0.0
|
|
for family in text_string_to_metric_families(response.text):
|
|
if family.name != "sglang:num_prefill_retries":
|
|
continue
|
|
for sample in family.samples:
|
|
if sample.name == "sglang:num_prefill_retries_total":
|
|
total += sample.value
|
|
return total
|
|
|
|
def assert_retry_counter_increases(self, fn):
|
|
before_retries = self._get_retry_counter()
|
|
result = fn()
|
|
after_retries = self._get_retry_counter()
|
|
self.assertGreater(after_retries, before_retries)
|
|
return result
|
|
|
|
|
|
class TestOptimisticPrefill(
|
|
OptimisticPrefillRetryCounterMixin, PDDisaggregationServerBase
|
|
):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls._force_retry_prob_was_set = (
|
|
envs.SGLANG_TEST_FORCE_OPTIMISTIC_PREFILL_RETRY_PROB.is_set()
|
|
)
|
|
cls._force_retry_prob_value = (
|
|
envs.SGLANG_TEST_FORCE_OPTIMISTIC_PREFILL_RETRY_PROB.get()
|
|
)
|
|
envs.SGLANG_TEST_FORCE_OPTIMISTIC_PREFILL_RETRY_PROB.set(FORCE_RETRY_PROB)
|
|
cls.model = DEFAULT_MODEL_NAME_FOR_TEST
|
|
cls.extra_prefill_args = [
|
|
"--optimistic-prefill-attempts",
|
|
"3",
|
|
"--chunked-prefill-size",
|
|
"128",
|
|
"--enable-metrics",
|
|
"--enable-request-time-stats-logging",
|
|
]
|
|
cls.launch_all()
|
|
|
|
@classmethod
|
|
def tearDownClass(cls):
|
|
try:
|
|
super().tearDownClass()
|
|
finally:
|
|
if getattr(cls, "_force_retry_prob_was_set", False):
|
|
envs.SGLANG_TEST_FORCE_OPTIMISTIC_PREFILL_RETRY_PROB.set(
|
|
cls._force_retry_prob_value
|
|
)
|
|
else:
|
|
envs.SGLANG_TEST_FORCE_OPTIMISTIC_PREFILL_RETRY_PROB.clear()
|
|
|
|
def test_gsm8k(self):
|
|
args = SimpleNamespace(
|
|
base_url=f"http://{self.base_host}:{self.lb_port}",
|
|
eval_name="gsm8k",
|
|
api="completion",
|
|
max_tokens=512,
|
|
num_examples=200,
|
|
num_threads=128,
|
|
)
|
|
metrics = self.assert_retry_counter_increases(lambda: run_eval(args))
|
|
print(f"Evaluation metrics: {metrics}")
|
|
self.assertGreater(metrics["score"], 0.62)
|
|
time.sleep(1) # trigger memory check
|
|
|
|
def test_logprob(self):
|
|
request_id = rid_that_forces_retry("logprob-retry-")
|
|
prompt = f"{request_id}: " + "The capital of France is Paris. " * 900
|
|
j = self.assert_retry_counter_increases(
|
|
lambda: requests.post(
|
|
self.lb_url + "/generate",
|
|
json={
|
|
"rid": request_id,
|
|
"text": prompt,
|
|
"sampling_params": {"temperature": 0, "max_new_tokens": 8},
|
|
"return_logprob": True,
|
|
"return_input_logprob": True,
|
|
"logprob_start_len": 0,
|
|
},
|
|
).json()
|
|
)
|
|
completion_tokens = j["meta_info"]["completion_tokens"]
|
|
input_logprobs = j["meta_info"]["input_token_logprobs"]
|
|
output_logprobs = j["meta_info"]["output_token_logprobs"]
|
|
|
|
self.assertGreater(j["meta_info"]["prompt_tokens"], 512)
|
|
assert len(output_logprobs) == completion_tokens
|
|
# Input logprobs must be complete: retried or pending chunks must not
|
|
# drop their logprobs.
|
|
self.assertGreaterEqual(
|
|
len(input_logprobs), j["meta_info"]["prompt_tokens"] - 1
|
|
)
|
|
|
|
|
|
class TestOptimisticPrefillFailure(PDDisaggregationServerBase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
# enable optimistic prefill retry sampling and disagg failure prob
|
|
cls._force_retry_ctx = (
|
|
envs.SGLANG_TEST_FORCE_OPTIMISTIC_PREFILL_RETRY_PROB.override(
|
|
FORCE_RETRY_PROB
|
|
)
|
|
)
|
|
cls._force_retry_ctx.__enter__()
|
|
cls._disagg_failure_ctx = envs.SGLANG_TEST_DISAGG_FAILURE_PROB.override(
|
|
FORCE_RETRY_PROB
|
|
)
|
|
cls._disagg_failure_ctx.__enter__()
|
|
|
|
cls.model = DEFAULT_MODEL_NAME_FOR_TEST
|
|
cls.extra_prefill_args = [
|
|
"--optimistic-prefill-attempts",
|
|
"3",
|
|
"--chunked-prefill-size",
|
|
"128",
|
|
"--enable-metrics",
|
|
"--enable-request-time-stats-logging",
|
|
"--load-format",
|
|
"dummy",
|
|
]
|
|
cls.launch_all()
|
|
|
|
@classmethod
|
|
def tearDownClass(cls):
|
|
try:
|
|
super().tearDownClass()
|
|
finally:
|
|
if getattr(cls, "_force_retry_ctx", None):
|
|
cls._force_retry_ctx.__exit__(None, None, None)
|
|
if getattr(cls, "_disagg_failure_ctx", None):
|
|
cls._disagg_failure_ctx.__exit__(None, None, None)
|
|
|
|
def test_survive_requests(self):
|
|
# send many small requests to ensure the engine survives injected failures
|
|
n = 100
|
|
with ThreadPoolExecutor(max_workers=32) as executor:
|
|
futures = []
|
|
for i in range(n):
|
|
rid = f"survive-{i}-{uuid.uuid4().hex}"
|
|
futures.append(
|
|
executor.submit(
|
|
requests.post,
|
|
self.lb_url + "/generate",
|
|
json={
|
|
"rid": rid,
|
|
"text": "Hello world",
|
|
"sampling_params": {"temperature": 0, "max_new_tokens": 4},
|
|
},
|
|
timeout=30,
|
|
)
|
|
)
|
|
for future in as_completed(futures):
|
|
try:
|
|
_ = future.result()
|
|
except Exception:
|
|
pass
|
|
time.sleep(1) # trigger memory check
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|