[CI][RFC] Replace black-jupyter with ruff-format (#37210)
Co-authored-by: Alison Shao <a.shao@wustl.edu>
This commit is contained in:
co-authored by
Alison Shao
parent
2641e427be
commit
28262c20df
@@ -189,11 +189,11 @@ def run_accuracy_test(
|
||||
"""
|
||||
base_url = base_url or DEFAULT_URL_FOR_TEST
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f"\n{'=' * 60}")
|
||||
print(f"Running ACCURACY test for {model.model_path}")
|
||||
print(f" Dataset: {params.dataset}")
|
||||
print(f" Baseline: {params.baseline_accuracy}")
|
||||
print(f"{'='*60}\n")
|
||||
print(f"{'=' * 60}\n")
|
||||
|
||||
success, error, metrics = _run_simple_eval(
|
||||
model=model,
|
||||
|
||||
@@ -138,7 +138,7 @@ def get_rdma_devices_args():
|
||||
if not (base_rdma_group <= gpu_idx < base_rdma_group + 4):
|
||||
warnings.warn(
|
||||
f"GPU index {gpu_idx} is outside expected group "
|
||||
f"{base_rdma_group}-{base_rdma_group+3}"
|
||||
f"{base_rdma_group}-{base_rdma_group + 3}"
|
||||
)
|
||||
|
||||
# 3. Generate RDMA device names
|
||||
|
||||
@@ -164,7 +164,7 @@ def generate_custom_dataset(
|
||||
for item in output_data
|
||||
]
|
||||
print(
|
||||
f"Token count stats: min={min(token_counts)}, max={max(token_counts)}, avg={sum(token_counts)/len(token_counts):.1f}"
|
||||
f"Token count stats: min={min(token_counts)}, max={max(token_counts)}, avg={sum(token_counts) / len(token_counts):.1f}"
|
||||
)
|
||||
|
||||
return output_data
|
||||
@@ -459,8 +459,8 @@ def generate_random_dataset(
|
||||
}
|
||||
)
|
||||
|
||||
print(f"#Input tokens: {np.sum(input_lens[:len(input_requests)])}")
|
||||
print(f"#Output tokens: {np.sum(output_lens[:len(input_requests)])}")
|
||||
print(f"#Input tokens: {np.sum(input_lens[: len(input_requests)])}")
|
||||
print(f"#Output tokens: {np.sum(output_lens[: len(input_requests)])}")
|
||||
|
||||
output_dir = os.path.dirname(output_file)
|
||||
if output_dir:
|
||||
|
||||
@@ -196,8 +196,7 @@ def run_evalscope(
|
||||
process.wait()
|
||||
|
||||
logger.info(
|
||||
f"run_evalscope finished: pid={process.pid} "
|
||||
f"returncode={process.returncode}"
|
||||
f"run_evalscope finished: pid={process.pid} returncode={process.returncode}"
|
||||
)
|
||||
|
||||
kill_process_group(process)
|
||||
@@ -641,7 +640,9 @@ class TestNpuAccuracyMultiNodePdSepTestCaseBase(CustomTestCase):
|
||||
cls.role = (
|
||||
"router"
|
||||
if "router" in cls.hostname
|
||||
else "prefill" if "prefill" in cls.hostname else "decode"
|
||||
else "prefill"
|
||||
if "prefill" in cls.hostname
|
||||
else "decode"
|
||||
)
|
||||
logger.info(f"Init {cls.host} {cls.role=}!")
|
||||
|
||||
|
||||
@@ -970,7 +970,7 @@ class TestNpuMultiNodePdMixTestCaseBase(CustomTestCase):
|
||||
self.assertGreaterEqual(
|
||||
metrics["accuracy"],
|
||||
expect_accuracy,
|
||||
f'Accuracy is {str(metrics["accuracy"])}, is lower than {expect_accuracy}',
|
||||
f"Accuracy is {str(metrics['accuracy'])}, is lower than {expect_accuracy}",
|
||||
)
|
||||
|
||||
|
||||
@@ -988,7 +988,9 @@ class TestNpuMultiNodePdSepTestCaseBase(CustomTestCase):
|
||||
cls.role = (
|
||||
"router"
|
||||
if "router" in cls.hostname
|
||||
else "prefill" if "prefill" in cls.hostname else "decode"
|
||||
else "prefill"
|
||||
if "prefill" in cls.hostname
|
||||
else "decode"
|
||||
)
|
||||
logger.info(f"Init {cls.host} {cls.role=}!")
|
||||
cls.sglang_thread = None
|
||||
@@ -1078,7 +1080,7 @@ class TestNpuMultiNodePdSepTestCaseBase(CustomTestCase):
|
||||
self.assertGreaterEqual(
|
||||
metrics["accuracy"],
|
||||
expect_accuracy,
|
||||
f'Accuracy is {str(metrics["accuracy"])}, is lower than {expect_accuracy}',
|
||||
f"Accuracy is {str(metrics['accuracy'])}, is lower than {expect_accuracy}",
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -721,7 +721,7 @@ def run_aisbench(
|
||||
else:
|
||||
logger.warning("Could not extract mean_tpot from output")
|
||||
logger.error(
|
||||
f"Simplified output snippet around TPOT: {simplified_output[simplified_output.find('TPOT')-20:simplified_output.find('TPOT')+50] if 'TPOT' in simplified_output else 'TPOT not found'}"
|
||||
f"Simplified output snippet around TPOT: {simplified_output[simplified_output.find('TPOT') - 20 : simplified_output.find('TPOT') + 50] if 'TPOT' in simplified_output else 'TPOT not found'}"
|
||||
)
|
||||
|
||||
tps_matches = re.findall(
|
||||
@@ -751,7 +751,7 @@ def run_aisbench(
|
||||
else:
|
||||
logger.warning("Could not extract total_tps from output")
|
||||
logger.warning(
|
||||
f"Simplified output snippet around Output Token Throughput: {simplified_output[simplified_output.find('Output')-20:simplified_output.find('Output')+100] if 'Output' in simplified_output else 'Output not found'}"
|
||||
f"Simplified output snippet around Output Token Throughput: {simplified_output[simplified_output.find('Output') - 20 : simplified_output.find('Output') + 100] if 'Output' in simplified_output else 'Output not found'}"
|
||||
)
|
||||
|
||||
ttft_match = re.search(r"TTFT\s+total\s+([\d.]+)\s+ms", simplified_output)
|
||||
@@ -761,7 +761,7 @@ def run_aisbench(
|
||||
else:
|
||||
logger.warning("Could not extract mean_ttft from output")
|
||||
logger.warning(
|
||||
f"Simplified output snippet around TTFT: {simplified_output[simplified_output.find('TTFT')-20:simplified_output.find('TTFT')+50] if 'TTFT' in simplified_output else 'TTFT not found'}"
|
||||
f"Simplified output snippet around TTFT: {simplified_output[simplified_output.find('TTFT') - 20 : simplified_output.find('TTFT') + 50] if 'TTFT' in simplified_output else 'TTFT not found'}"
|
||||
)
|
||||
|
||||
e2el_match = re.search(r"E2EL\s+total\s+([\d.]+)\s+ms", simplified_output)
|
||||
@@ -771,7 +771,7 @@ def run_aisbench(
|
||||
else:
|
||||
logger.warning("Could not extract mean_e2e_latency from output")
|
||||
logger.warning(
|
||||
f"Simplified output snippet around E2EL: {simplified_output[simplified_output.find('E2EL')-20:simplified_output.find('E2EL')+50] if 'E2EL' in simplified_output else 'E2EL not found'}"
|
||||
f"Simplified output snippet around E2EL: {simplified_output[simplified_output.find('E2EL') - 20 : simplified_output.find('E2EL') + 50] if 'E2EL' in simplified_output else 'E2EL not found'}"
|
||||
)
|
||||
|
||||
concurrency_match = re.search(
|
||||
@@ -783,7 +783,7 @@ def run_aisbench(
|
||||
else:
|
||||
logger.warning("Could not extract concurrency from output")
|
||||
logger.warning(
|
||||
f"Simplified output snippet around Concurrency: {simplified_output[simplified_output.find('Concurrency')-20:simplified_output.find('Concurrency')+50] if 'Concurrency' in simplified_output else 'Concurrency not found'}"
|
||||
f"Simplified output snippet around Concurrency: {simplified_output[simplified_output.find('Concurrency') - 20 : simplified_output.find('Concurrency') + 50] if 'Concurrency' in simplified_output else 'Concurrency not found'}"
|
||||
)
|
||||
|
||||
max_concurrency_match = re.search(
|
||||
@@ -795,7 +795,7 @@ def run_aisbench(
|
||||
else:
|
||||
logger.warning("Could not extract max_concurrency from output")
|
||||
logger.warning(
|
||||
f"Simplified output snippet around Max Concurrency: {simplified_output[simplified_output.find('Max Concurrency')-20:simplified_output.find('Max Concurrency')+50] if 'Max Concurrency' in simplified_output else 'Max Concurrency not found'}"
|
||||
f"Simplified output snippet around Max Concurrency: {simplified_output[simplified_output.find('Max Concurrency') - 20 : simplified_output.find('Max Concurrency') + 50] if 'Max Concurrency' in simplified_output else 'Max Concurrency not found'}"
|
||||
)
|
||||
|
||||
req_throughput_match = re.search(
|
||||
@@ -810,7 +810,7 @@ def run_aisbench(
|
||||
else:
|
||||
logger.warning("Could not extract request_throughput from output")
|
||||
logger.warning(
|
||||
f"Simplified output snippet around Request Throughput: {simplified_output[simplified_output.find('Request')-20:simplified_output.find('Request')+50] if 'Request' in simplified_output else 'Request not found'}"
|
||||
f"Simplified output snippet around Request Throughput: {simplified_output[simplified_output.find('Request') - 20 : simplified_output.find('Request') + 50] if 'Request' in simplified_output else 'Request not found'}"
|
||||
)
|
||||
|
||||
total_requests_match = re.search(
|
||||
@@ -822,7 +822,7 @@ def run_aisbench(
|
||||
else:
|
||||
logger.warning("Could not extract total_requests from output")
|
||||
logger.warning(
|
||||
f"Simplified output snippet around Total Requests: {simplified_output[simplified_output.find('Total Requests')-20:simplified_output.find('Total Requests')+50] if 'Total Requests' in simplified_output else 'Total Requests not found'}"
|
||||
f"Simplified output snippet around Total Requests: {simplified_output[simplified_output.find('Total Requests') - 20 : simplified_output.find('Total Requests') + 50] if 'Total Requests' in simplified_output else 'Total Requests not found'}"
|
||||
)
|
||||
|
||||
failed_requests_match = re.search(
|
||||
@@ -834,7 +834,7 @@ def run_aisbench(
|
||||
else:
|
||||
logger.warning("Could not extract failed_requests from output")
|
||||
logger.warning(
|
||||
f"Simplified output snippet around Failed Requests: {simplified_output[simplified_output.find('Failed Requests')-20:simplified_output.find('Failed Requests')+50] if 'Failed Requests' in simplified_output else 'Failed Requests not found'}"
|
||||
f"Simplified output snippet around Failed Requests: {simplified_output[simplified_output.find('Failed Requests') - 20 : simplified_output.find('Failed Requests') + 50] if 'Failed Requests' in simplified_output else 'Failed Requests not found'}"
|
||||
)
|
||||
|
||||
logger.info(f"All extracted metrics: {metrics}")
|
||||
@@ -1365,7 +1365,9 @@ class TestNpuPerfMultiNodePdSepTestCaseBase(CustomTestCase):
|
||||
cls.role = (
|
||||
"router"
|
||||
if "router" in cls.hostname
|
||||
else "prefill" if "prefill" in cls.hostname else "decode"
|
||||
else "prefill"
|
||||
if "prefill" in cls.hostname
|
||||
else "decode"
|
||||
)
|
||||
logger.info(f"Init {cls.host} {cls.role=}!")
|
||||
|
||||
|
||||
@@ -102,12 +102,12 @@ class GSM8KAscendMixin(ABC):
|
||||
self.assertGreaterEqual(
|
||||
metrics["score"],
|
||||
accuracy_threshold,
|
||||
f'Accuracy of {self.model} is {str(metrics["score"])}, is lower than {accuracy_threshold}',
|
||||
f"Accuracy of {self.model} is {str(metrics['score'])}, is lower than {accuracy_threshold}",
|
||||
)
|
||||
self.assertGreaterEqual(
|
||||
metrics["output_throughput"],
|
||||
output_throughput_threshold,
|
||||
f'Output throughput of {self.model} is {str(metrics["output_throughput"])}, is lower than {output_throughput_threshold}',
|
||||
f"Output throughput of {self.model} is {str(metrics['output_throughput'])}, is lower than {output_throughput_threshold}",
|
||||
)
|
||||
except Exception as e:
|
||||
model_metrics["error"] = e
|
||||
|
||||
@@ -87,9 +87,9 @@ class BaseEmbeddingTest(ABC):
|
||||
print("similarity diff", abs(similarity - 1))
|
||||
|
||||
if len(prompts[i]) <= 1000:
|
||||
assert torch.all(
|
||||
abs(similarity - 1) < prefill_tolerance
|
||||
), "embeddings are not all close"
|
||||
assert torch.all(abs(similarity - 1) < prefill_tolerance), (
|
||||
"embeddings are not all close"
|
||||
)
|
||||
|
||||
def test_prefill_logits(self):
|
||||
"""Main test method to run for all models and dtypes"""
|
||||
|
||||
@@ -6,7 +6,6 @@ from sglang.test.run_eval import run_eval
|
||||
|
||||
|
||||
class TestMMLU:
|
||||
|
||||
mmlu_num_examples = 128
|
||||
|
||||
def test_mmlu(self):
|
||||
|
||||
@@ -199,9 +199,7 @@ def get_jitter_engine(
|
||||
|
||||
port = portpicker.pick_unused_port_range( # pyright: ignore[reportAttributeAccessIssue]
|
||||
DP_ATTENTION_HANDSHAKE_PORT_DELTA + 1
|
||||
)[
|
||||
0
|
||||
]
|
||||
)[0]
|
||||
engine_kwargs["dist_init_addr"] = f"127.0.0.1:{port}"
|
||||
|
||||
scheduler_process = (
|
||||
@@ -307,9 +305,9 @@ def _record_response(
|
||||
out_ids = [int(t) for t in out["output_ids"]]
|
||||
out_lps = meta["output_token_logprobs"]
|
||||
out_top = meta["output_top_logprobs"]
|
||||
assert (
|
||||
len(out_ids) == req.max_new_tokens
|
||||
), f"{req.label}: got {len(out_ids)} output tokens, expected {req.max_new_tokens}"
|
||||
assert len(out_ids) == req.max_new_tokens, (
|
||||
f"{req.label}: got {len(out_ids)} output tokens, expected {req.max_new_tokens}"
|
||||
)
|
||||
expected = out_ids if baseline is None else baseline[req.cut :]
|
||||
for m, (tid, lp_entry, top) in enumerate(
|
||||
zip(out_ids, out_lps, out_top, strict=True)
|
||||
|
||||
@@ -149,12 +149,12 @@ class StressTestRunner:
|
||||
Returns:
|
||||
True if successful, False otherwise
|
||||
"""
|
||||
print(f"\n{'='*60}")
|
||||
print(f"\n{'=' * 60}")
|
||||
print(f"Starting stress test for: {model_path}")
|
||||
print(f"Input length: {random_input_len}")
|
||||
print(f"Output length: {random_output_len}")
|
||||
print(f"Num prompts: {self.num_prompts}")
|
||||
print(f"{'='*60}\n")
|
||||
print(f"{'=' * 60}\n")
|
||||
|
||||
# Launch server
|
||||
process = popen_launch_server(
|
||||
|
||||
@@ -434,11 +434,11 @@ def run_unittest_files(
|
||||
logger.info(f"Fail. Time elapsed: {elapsed_total:.2f}s")
|
||||
|
||||
# Print summary
|
||||
logger.info(f"\n{'='*60}")
|
||||
logger.info(f"\n{'=' * 60}")
|
||||
logger.info(f"Test Summary: {len(passed_tests)}/{len(files)} passed")
|
||||
if enable_retry and retried_tests:
|
||||
logger.info(f"Retries: {len(retried_tests)} test(s) were retried")
|
||||
logger.info(f"{'='*60}")
|
||||
logger.info(f"{'=' * 60}")
|
||||
if passed_tests:
|
||||
logger.info("✓ PASSED:")
|
||||
for test in passed_tests:
|
||||
@@ -451,7 +451,7 @@ def run_unittest_files(
|
||||
logger.info("\n↻ RETRIED:")
|
||||
for test, attempts, result in retried_tests:
|
||||
logger.info(f" {test} ({attempts} attempts, {result})")
|
||||
logger.info(f"{'='*60}\n")
|
||||
logger.info(f"{'=' * 60}\n")
|
||||
|
||||
# Machine-readable timings block for downstream scrapers/dashboards.
|
||||
# One JSON object per executed file (post-retry: only the latest
|
||||
|
||||
@@ -441,9 +441,9 @@ class MXFP4QuantizeUtil:
|
||||
new_data = (
|
||||
right_side.clone() << 4
|
||||
) # Put odd indices (higher addresses) in high bits
|
||||
new_data[
|
||||
..., : left_side.shape[-1]
|
||||
] += left_side # Put even indices in low bits
|
||||
new_data[..., : left_side.shape[-1]] += (
|
||||
left_side # Put even indices in low bits
|
||||
)
|
||||
return new_data
|
||||
|
||||
original_shape = input.shape
|
||||
|
||||
@@ -324,9 +324,9 @@ def assert_canary_state_equal(
|
||||
*, log_a: FakeViolationLog, log_b: FakeViolationLog
|
||||
) -> None:
|
||||
for name in ("ring", "write_index", "slot_run_counter", "kernel_run_counter"):
|
||||
assert torch.equal(
|
||||
getattr(log_a, name), getattr(log_b, name)
|
||||
), f"{name} diverged (CUDA vs ref)"
|
||||
assert torch.equal(getattr(log_a, name), getattr(log_b, name)), (
|
||||
f"{name} diverged (CUDA vs ref)"
|
||||
)
|
||||
|
||||
|
||||
def assert_canary_buf_equal(*, buf_a: torch.Tensor, buf_b: torch.Tensor) -> None:
|
||||
@@ -334,11 +334,9 @@ def assert_canary_buf_equal(*, buf_a: torch.Tensor, buf_b: torch.Tensor) -> None
|
||||
|
||||
|
||||
def assert_only_bits_set(fail_bits: int, expected_bits: int) -> None:
|
||||
assert (
|
||||
fail_bits & expected_bits
|
||||
) == expected_bits, (
|
||||
assert (fail_bits & expected_bits) == expected_bits, (
|
||||
f"missing expected bits: expected {expected_bits:#b} got {fail_bits:#b}"
|
||||
)
|
||||
assert (
|
||||
fail_bits & ~expected_bits
|
||||
) == 0, f"unexpected extra bits: got {fail_bits:#b} extras {fail_bits & ~expected_bits:#b}"
|
||||
assert (fail_bits & ~expected_bits) == 0, (
|
||||
f"unexpected extra bits: got {fail_bits:#b} extras {fail_bits & ~expected_bits:#b}"
|
||||
)
|
||||
|
||||
@@ -130,18 +130,18 @@ def _assert_plans_byte_equal(
|
||||
else int(triton_verify.verify_num_valid[0].item())
|
||||
)
|
||||
n_verify_ref = int(ref_verify.verify_num_valid[0].item())
|
||||
assert (
|
||||
n_verify == n_verify_ref
|
||||
), f"verify_num_valid diverged: triton={n_verify} ref={n_verify_ref}"
|
||||
assert n_verify == n_verify_ref, (
|
||||
f"verify_num_valid diverged: triton={n_verify} ref={n_verify_ref}"
|
||||
)
|
||||
# When total_verify > VERIFY_CAPACITY the offsets kernel clears verify_enable and
|
||||
# plan_entries skips its scatter — leaving verify_slot_indices/positions/prev_slot_indices
|
||||
# as whatever the (torch.empty) allocation contained. Skip the byte-equal probe in that
|
||||
# case; verify_num_valid being clamped + verify_enable=0 is the contract here.
|
||||
triton_enable = int(triton_verify.enable[0].item())
|
||||
ref_enable = int(ref_verify.enable[0].item())
|
||||
assert (
|
||||
triton_enable == ref_enable
|
||||
), f"verify_enable diverged: triton={triton_enable} ref={ref_enable}"
|
||||
assert triton_enable == ref_enable, (
|
||||
f"verify_enable diverged: triton={triton_enable} ref={ref_enable}"
|
||||
)
|
||||
if n_verify > 0 and triton_enable != 0:
|
||||
assert torch.equal(
|
||||
triton_verify.verify_slot_indices[:n_verify],
|
||||
@@ -166,9 +166,9 @@ def _assert_plans_byte_equal(
|
||||
else int(triton_write.write_num_valid_reqs[0].item())
|
||||
)
|
||||
n_write_ref = int(ref_write.write_num_valid_reqs[0].item())
|
||||
assert (
|
||||
n_write == n_write_ref
|
||||
), f"write_num_valid_reqs diverged: triton={n_write} ref={n_write_ref}"
|
||||
assert n_write == n_write_ref, (
|
||||
f"write_num_valid_reqs diverged: triton={n_write} ref={n_write_ref}"
|
||||
)
|
||||
assert torch.equal(
|
||||
triton_write.write_offsets[: n_write + 1],
|
||||
ref_write.write_offsets[: n_write + 1],
|
||||
@@ -350,7 +350,8 @@ def _yield_simpler(inputs: Any) -> Iterator[tuple[str, Any]]:
|
||||
Plan / Verify / Write fuzz failures uniformly.
|
||||
"""
|
||||
fields = {
|
||||
f: getattr(inputs, f) for f in inputs.__dataclass_fields__ # type: ignore[attr-defined]
|
||||
f: getattr(inputs, f)
|
||||
for f in inputs.__dataclass_fields__ # type: ignore[attr-defined]
|
||||
}
|
||||
|
||||
def emit(label: str, **overrides: Any) -> Iterator[tuple[str, Any]]:
|
||||
|
||||
@@ -76,9 +76,9 @@ class PlanInvariants:
|
||||
raise AssertionError(f"write_num_valid_reqs negative: {n_active}")
|
||||
offsets = write_plan.write_offsets[: n_active + 1].detach().cpu().tolist()
|
||||
for i in range(len(offsets) - 1):
|
||||
assert (
|
||||
offsets[i] <= offsets[i + 1]
|
||||
), f"write_offsets non-monotone at {i}: {offsets[i]} > {offsets[i + 1]}"
|
||||
assert offsets[i] <= offsets[i + 1], (
|
||||
f"write_offsets non-monotone at {i}: {offsets[i]} > {offsets[i + 1]}"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _assert_write_offsets_total_matches_active_extend_sum(
|
||||
@@ -92,9 +92,9 @@ class PlanInvariants:
|
||||
rpi_cpu = req_pool_indices.detach().cpu().tolist()
|
||||
ext_cpu = extend_seq_lens.detach().cpu().tolist()
|
||||
expected_total = sum(ext for rpi, ext in zip(rpi_cpu, ext_cpu) if rpi != 0)
|
||||
assert (
|
||||
total == expected_total
|
||||
), f"write_offsets total {total} != active extend sum {expected_total}"
|
||||
assert total == expected_total, (
|
||||
f"write_offsets total {total} != active extend sum {expected_total}"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _assert_extras_land_at_tail(
|
||||
@@ -111,9 +111,9 @@ class PlanInvariants:
|
||||
tail_start = derived_verify_count
|
||||
tail_end = derived_verify_count + extras_count
|
||||
n_valid = int(verify_plan.verify_num_valid[0].item())
|
||||
assert (
|
||||
tail_end <= n_valid
|
||||
), f"extras tail {tail_end} exceeds verify_num_valid {n_valid}"
|
||||
assert tail_end <= n_valid, (
|
||||
f"extras tail {tail_end} exceeds verify_num_valid {n_valid}"
|
||||
)
|
||||
plan_slots = verify_plan.verify_slot_indices[tail_start:tail_end]
|
||||
plan_positions = verify_plan.verify_expected_positions[tail_start:tail_end]
|
||||
plan_prevs = verify_plan.verify_prev_slot_indices[tail_start:tail_end]
|
||||
@@ -136,9 +136,9 @@ class PlanInvariants:
|
||||
)
|
||||
for r in range(min(n_active, len(rpi_cpu))):
|
||||
if rpi_cpu[r] == 0:
|
||||
assert (
|
||||
seeds_cpu[r] == -1
|
||||
), f"padding row {r} has seed {seeds_cpu[r]} != -1"
|
||||
assert seeds_cpu[r] == -1, (
|
||||
f"padding row {r} has seed {seeds_cpu[r]} != -1"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _assert_prev_slot_minus_one_iff_chain_head(
|
||||
@@ -163,14 +163,14 @@ class PlanInvariants:
|
||||
)
|
||||
for i, (pos, prev) in enumerate(zip(positions_cpu, prevs_cpu)):
|
||||
if pos == 0:
|
||||
assert (
|
||||
prev == -1
|
||||
), f"entry {i} at position 0 must have prev=-1, got {prev}"
|
||||
assert prev == -1, (
|
||||
f"entry {i} at position 0 must have prev=-1, got {prev}"
|
||||
)
|
||||
else:
|
||||
if swa_window_size == 0:
|
||||
assert (
|
||||
prev != -1
|
||||
), f"FULL entry {i} at position {pos} must have prev != -1, got {prev}"
|
||||
assert prev != -1, (
|
||||
f"FULL entry {i} at position {pos} must have prev != -1, got {prev}"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _assert_verify_num_valid_equals_derived_plus_extras(
|
||||
@@ -251,9 +251,9 @@ class VerifyInvariants:
|
||||
canary_buf_before: torch.Tensor,
|
||||
canary_buf_after: torch.Tensor,
|
||||
) -> None:
|
||||
assert torch.equal(
|
||||
canary_buf_before, canary_buf_after
|
||||
), "verify kernel mutated canary_buf (must be read-only)"
|
||||
assert torch.equal(canary_buf_before, canary_buf_after), (
|
||||
"verify kernel mutated canary_buf (must be read-only)"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _assert_violation_count_le_active_entries(
|
||||
@@ -266,9 +266,9 @@ class VerifyInvariants:
|
||||
log_before.write_index[0].item()
|
||||
)
|
||||
n_active = int(plan.verify_num_valid[0].item())
|
||||
assert (
|
||||
0 <= delta <= n_active
|
||||
), f"violation_write_index delta {delta} out of [0, {n_active}]"
|
||||
assert 0 <= delta <= n_active, (
|
||||
f"violation_write_index delta {delta} out of [0, {n_active}]"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _assert_violation_rows_have_valid_slot_and_kernel_kind(
|
||||
@@ -292,13 +292,13 @@ class VerifyInvariants:
|
||||
rows = log_after.ring[visible_start:visible_end].detach().cpu()
|
||||
for i in range(rows.shape[0]):
|
||||
kind = int(rows[i, consts.VIOLATION_FIELD_KERNEL_KIND].item())
|
||||
assert kind == int(
|
||||
kernel_kind
|
||||
), f"row {visible_start + i} kernel_kind {kind} != expected {int(kernel_kind)}"
|
||||
assert kind == int(kernel_kind), (
|
||||
f"row {visible_start + i} kernel_kind {kind} != expected {int(kernel_kind)}"
|
||||
)
|
||||
slot = int(rows[i, consts.VIOLATION_FIELD_SLOT_IDX].item())
|
||||
assert (
|
||||
slot in plan_slots
|
||||
), f"row {visible_start + i} slot {slot} not in plan_slots"
|
||||
assert slot in plan_slots, (
|
||||
f"row {visible_start + i} slot {slot} not in plan_slots"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _assert_slot_run_counter_incremented_by_active_entries(
|
||||
@@ -311,9 +311,9 @@ class VerifyInvariants:
|
||||
delta = int(log_after.slot_run_counter[0].item()) - int(
|
||||
log_before.slot_run_counter[0].item()
|
||||
)
|
||||
assert (
|
||||
delta == n_active
|
||||
), f"slot_run_counter delta {delta} != active entries {n_active}"
|
||||
assert delta == n_active, (
|
||||
f"slot_run_counter delta {delta} != active entries {n_active}"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _assert_kernel_run_counter_incremented_by_one(
|
||||
@@ -401,12 +401,12 @@ class WriteInvariants:
|
||||
continue
|
||||
stored_token = int(view[slot, 0].item())
|
||||
stored_position = int(view[slot, 1].item())
|
||||
assert (
|
||||
stored_token == tokens_cpu[i]
|
||||
), f"slot {slot}: stored token {stored_token} != input {tokens_cpu[i]}"
|
||||
assert (
|
||||
stored_position == pos_cpu[i]
|
||||
), f"slot {slot}: stored position {stored_position} != input {pos_cpu[i]}"
|
||||
assert stored_token == tokens_cpu[i], (
|
||||
f"slot {slot}: stored token {stored_token} != input {tokens_cpu[i]}"
|
||||
)
|
||||
assert stored_position == pos_cpu[i], (
|
||||
f"slot {slot}: stored position {stored_position} != input {pos_cpu[i]}"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _assert_slot_minus_one_skipped(
|
||||
@@ -428,9 +428,9 @@ class WriteInvariants:
|
||||
for slot in range(num_slots):
|
||||
if slot in written_slots:
|
||||
continue
|
||||
assert torch.equal(
|
||||
view_before[slot], view_after[slot]
|
||||
), f"slot {slot} not in out_cache_loc but canary_buf changed"
|
||||
assert torch.equal(view_before[slot], view_after[slot]), (
|
||||
f"slot {slot} not in out_cache_loc but canary_buf changed"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _assert_pseudo_violation_only_on_mismatch(
|
||||
@@ -449,9 +449,9 @@ class WriteInvariants:
|
||||
log_before.write_index[0].item()
|
||||
)
|
||||
if not enable_write_verify_inputs:
|
||||
assert (
|
||||
delta == 0
|
||||
), f"enable_write_verify_inputs=OFF must produce no violations, got {delta}"
|
||||
assert delta == 0, (
|
||||
f"enable_write_verify_inputs=OFF must produce no violations, got {delta}"
|
||||
)
|
||||
return
|
||||
if expected_input_tokens is None or expected_input_positions is None:
|
||||
return
|
||||
@@ -472,13 +472,13 @@ class WriteInvariants:
|
||||
)
|
||||
no_mismatch = mismatch_entries == 0
|
||||
if no_mismatch:
|
||||
assert (
|
||||
delta == 0
|
||||
), f"enable_write_verify_inputs=ON with no mismatch produced {delta} violations"
|
||||
assert delta == 0, (
|
||||
f"enable_write_verify_inputs=ON with no mismatch produced {delta} violations"
|
||||
)
|
||||
else:
|
||||
assert (
|
||||
delta == mismatch_entries
|
||||
), f"write input mismatch count {mismatch_entries} produced {delta} violations"
|
||||
assert delta == mismatch_entries, (
|
||||
f"write input mismatch count {mismatch_entries} produced {delta} violations"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _assert_write_slot_run_counter_incremented(
|
||||
|
||||
@@ -1456,8 +1456,7 @@ def run_dsa_sparse_cuda_graph_decode_impl_variant_case(
|
||||
)
|
||||
if not case.forward_mode.is_decode():
|
||||
raise ValueError(
|
||||
"run_dsa_sparse_cuda_graph_decode_impl_variant_case expects a "
|
||||
"DECODE case."
|
||||
"run_dsa_sparse_cuda_graph_decode_impl_variant_case expects a DECODE case."
|
||||
)
|
||||
from ..runner_modes.cuda_graph_decode_runner import (
|
||||
run_dsa_sparse_cuda_graph_decode_case,
|
||||
|
||||
@@ -1015,8 +1015,7 @@ def make_dsv4_padded_replay_inputs(
|
||||
pad_token_count = case.num_input_tokens - base_inputs["input_hidden"].shape[0]
|
||||
if pad_token_count < 0:
|
||||
raise ValueError(
|
||||
f"replay input shrink not supported: {pad_token_count=}; "
|
||||
f"case={case.name}"
|
||||
f"replay input shrink not supported: {pad_token_count=}; case={case.name}"
|
||||
)
|
||||
if pad_token_count == 0:
|
||||
padded_input_hidden = base_inputs["input_hidden"]
|
||||
@@ -1446,12 +1445,12 @@ def _seed_c4_sparse_prefill_indices(
|
||||
max_len = int(lens.max().item())
|
||||
pool = fixture.runner.token_to_kv_pool
|
||||
c4_page_size = pool.get_extra_key_page_size(layer_id=0)
|
||||
assert max_len <= min(
|
||||
num_entries, c4_page_size
|
||||
), f"case attends {max_len} c4 entries; only {min(num_entries, c4_page_size)} populated"
|
||||
assert (
|
||||
md.page_table[:, 0] == 0
|
||||
).all(), "sparse seeding requires the raw==physical identity (first page 0)"
|
||||
assert max_len <= min(num_entries, c4_page_size), (
|
||||
f"case attends {max_len} c4 entries; only {min(num_entries, c4_page_size)} populated"
|
||||
)
|
||||
assert (md.page_table[:, 0] == 0).all(), (
|
||||
"sparse seeding requires the raw==physical identity (first page 0)"
|
||||
)
|
||||
seq = (
|
||||
torch.arange(width, dtype=raw_indices.dtype, device=raw_indices.device)
|
||||
.unsqueeze(0)
|
||||
@@ -1487,9 +1486,9 @@ def run_dsv4_target_verify_attention_case(
|
||||
"DSV4 target_verify is chain-only — `deepseek_v4_backend.py:369` "
|
||||
"asserts `self.topk in [0, 1]`. Pass topk=1."
|
||||
)
|
||||
assert (
|
||||
case.forward_mode.is_target_verify()
|
||||
), f"run_dsv4_target_verify_attention_case requires TARGET_VERIFY case; got {case.forward_mode}"
|
||||
assert case.forward_mode.is_target_verify(), (
|
||||
f"run_dsv4_target_verify_attention_case requires TARGET_VERIFY case; got {case.forward_mode}"
|
||||
)
|
||||
# Lazy import to avoid cycles (runner_modes imports attention_methods).
|
||||
from sglang.test.kits.attention_unittest.runner_modes.speculative_target_verify_runner import (
|
||||
_make_eagle_verify_input,
|
||||
@@ -1560,9 +1559,9 @@ def run_dsv4_draft_extend_attention_case(
|
||||
"`deepseek_v4_backend.py:636-663` and the 'Production-Unsupported' "
|
||||
"section in dsv4/README.md."
|
||||
)
|
||||
assert (
|
||||
case.forward_mode.is_draft_extend_v2()
|
||||
), f"run_dsv4_draft_extend_attention_case requires DRAFT_EXTEND; got {case.forward_mode}"
|
||||
assert case.forward_mode.is_draft_extend_v2(), (
|
||||
f"run_dsv4_draft_extend_attention_case requires DRAFT_EXTEND; got {case.forward_mode}"
|
||||
)
|
||||
from sglang.test.kits.attention_unittest.runner_modes.speculative_draft_extend_runner import (
|
||||
_make_eagle_draft_extend_input,
|
||||
)
|
||||
@@ -1631,11 +1630,13 @@ def run_dsv4_compress_attention_case(
|
||||
assert case.compress_ratio in (
|
||||
4,
|
||||
128,
|
||||
), f"DSV4 compact runner requires compress_ratio in (4, 128); got {case.compress_ratio}"
|
||||
), (
|
||||
f"DSV4 compact runner requires compress_ratio in (4, 128); got {case.compress_ratio}"
|
||||
)
|
||||
if sparse_prefill:
|
||||
assert (
|
||||
case.forward_mode.is_extend_without_speculative()
|
||||
), f"sparse prefill only serves extend; got {case.forward_mode}"
|
||||
assert case.forward_mode.is_extend_without_speculative(), (
|
||||
f"sparse prefill only serves extend; got {case.forward_mode}"
|
||||
)
|
||||
fixture = build_dsv4_attention_fixture(
|
||||
testcase,
|
||||
case,
|
||||
|
||||
+3
-2
@@ -567,8 +567,9 @@ def _run_eagle_draft_extend_eager(
|
||||
model_runner = (
|
||||
worker.model_runner if hasattr(worker, "model_runner") else worker.draft_runner
|
||||
)
|
||||
with torch.no_grad(), forward_context(
|
||||
ForwardContext(attn_backend=worker.draft_extend_attn_backend)
|
||||
with (
|
||||
torch.no_grad(),
|
||||
forward_context(ForwardContext(attn_backend=worker.draft_extend_attn_backend)),
|
||||
):
|
||||
worker.draft_extend_attn_backend.init_forward_metadata(batch)
|
||||
ret = model_runner.model.forward(
|
||||
|
||||
+15
-15
@@ -606,9 +606,9 @@ class _DenseEagleDraftForward:
|
||||
)
|
||||
|
||||
def __call__(self, forward_batch: ForwardBatch):
|
||||
assert (
|
||||
forward_batch.forward_metadata_ready
|
||||
), "draft-loop forward reached the runner without a pre-planned batch"
|
||||
assert forward_batch.forward_metadata_ready, (
|
||||
"draft-loop forward reached the runner without a pre-planned batch"
|
||||
)
|
||||
spec_info = forward_batch.spec_info
|
||||
hidden_states = spec_info.hidden_states
|
||||
if hidden_states is None:
|
||||
@@ -645,9 +645,9 @@ class _FrozenKVMTPDenseDraftForward:
|
||||
)
|
||||
|
||||
def __call__(self, forward_batch: ForwardBatch):
|
||||
assert (
|
||||
forward_batch.forward_metadata_ready
|
||||
), "draft-loop forward reached the runner without a pre-planned batch"
|
||||
assert forward_batch.forward_metadata_ready, (
|
||||
"draft-loop forward reached the runner without a pre-planned batch"
|
||||
)
|
||||
spec_info = forward_batch.spec_info
|
||||
hidden_states = spec_info.hidden_states
|
||||
if hidden_states is None:
|
||||
@@ -1034,9 +1034,9 @@ class _MLAEagleDraftForward:
|
||||
)
|
||||
|
||||
def __call__(self, forward_batch: ForwardBatch):
|
||||
assert (
|
||||
forward_batch.forward_metadata_ready
|
||||
), "draft-loop forward reached the runner without a pre-planned batch"
|
||||
assert forward_batch.forward_metadata_ready, (
|
||||
"draft-loop forward reached the runner without a pre-planned batch"
|
||||
)
|
||||
spec_info = forward_batch.spec_info
|
||||
hidden_states = spec_info.hidden_states
|
||||
if hidden_states is None:
|
||||
@@ -1292,9 +1292,9 @@ class _DSV4EagleDraftForward:
|
||||
)
|
||||
|
||||
def __call__(self, forward_batch: ForwardBatch):
|
||||
assert (
|
||||
forward_batch.forward_metadata_ready
|
||||
), "draft-loop forward reached the runner without a pre-planned batch"
|
||||
assert forward_batch.forward_metadata_ready, (
|
||||
"draft-loop forward reached the runner without a pre-planned batch"
|
||||
)
|
||||
spec_info = forward_batch.spec_info
|
||||
hidden_states = spec_info.hidden_states
|
||||
if hidden_states is None:
|
||||
@@ -1603,9 +1603,9 @@ class _DSAEagleDraftForward:
|
||||
)
|
||||
|
||||
def __call__(self, forward_batch: ForwardBatch):
|
||||
assert (
|
||||
forward_batch.forward_metadata_ready
|
||||
), "draft-loop forward reached the runner without a pre-planned batch"
|
||||
assert forward_batch.forward_metadata_ready, (
|
||||
"draft-loop forward reached the runner without a pre-planned batch"
|
||||
)
|
||||
spec_info = forward_batch.spec_info
|
||||
hidden_states = spec_info.hidden_states
|
||||
if hidden_states is None:
|
||||
|
||||
+9
-9
@@ -493,8 +493,8 @@ def _run_spec_verify_cuda_graph_case(
|
||||
make_capture_case=lambda base, name, capture_prefix_len, bs: (
|
||||
make_case_with_prefix_lens(base, name, (capture_prefix_len,) * bs)
|
||||
),
|
||||
make_replay_case=lambda base, name, pad_prefix_lens: (
|
||||
make_case_with_prefix_lens(base, name, base.prefix_lens + pad_prefix_lens)
|
||||
make_replay_case=lambda base, name, pad_prefix_lens: make_case_with_prefix_lens(
|
||||
base, name, base.prefix_lens + pad_prefix_lens
|
||||
),
|
||||
make_forward_batch=make_forward_batch,
|
||||
fixture_inputs=fixture_inputs,
|
||||
@@ -740,8 +740,8 @@ def run_gdn_eagle_verify_cuda_graph_case(
|
||||
make_forward_batch=_make_gdn_forward_batch,
|
||||
fixture_inputs=gdn_fixture_inputs,
|
||||
make_capture_inputs=make_gdn_random_inputs,
|
||||
make_replay_inputs=lambda _case, fixture, *_args, **_kwargs: (
|
||||
gdn_fixture_inputs(fixture)
|
||||
make_replay_inputs=lambda _case, fixture, *_args, **_kwargs: gdn_fixture_inputs(
|
||||
fixture
|
||||
),
|
||||
prepare_batch=lambda spec_case, batch: _prepare_gdn_verify_batch(
|
||||
spec_case,
|
||||
@@ -928,9 +928,9 @@ def run_dsv4_eagle_verify_cuda_graph_case(
|
||||
)
|
||||
|
||||
num_draft_tokens = case.extend_lens[0] if case.extend_lens else 0
|
||||
assert (
|
||||
num_draft_tokens > 0
|
||||
), "DSV4 verify cases must set `extend_lens=(num_draft, ...)`."
|
||||
assert num_draft_tokens > 0, (
|
||||
"DSV4 verify cases must set `extend_lens=(num_draft, ...)`."
|
||||
)
|
||||
|
||||
def _prepare_dsv4_verify_batch(spec_case, batch):
|
||||
_prepare_target_verify_batch(batch, spec_case, device)
|
||||
@@ -1080,8 +1080,8 @@ def run_kda_eagle_verify_cuda_graph_case(
|
||||
make_forward_batch=_make_kda_forward_batch,
|
||||
fixture_inputs=kda_fixture_inputs,
|
||||
make_capture_inputs=make_kda_random_inputs,
|
||||
make_replay_inputs=lambda _case, fixture, *_args, **_kwargs: (
|
||||
kda_fixture_inputs(fixture)
|
||||
make_replay_inputs=lambda _case, fixture, *_args, **_kwargs: kda_fixture_inputs(
|
||||
fixture
|
||||
),
|
||||
prepare_batch=lambda spec_case, batch: _prepare_kda_verify_batch(
|
||||
spec_case,
|
||||
|
||||
@@ -4,7 +4,6 @@ import requests
|
||||
|
||||
|
||||
class EBNFConstrainedMixin:
|
||||
|
||||
ebnf_grammar = 'root ::= "test"' # Default grammar
|
||||
|
||||
def _run_decode_ebnf(
|
||||
|
||||
@@ -60,9 +60,9 @@ def _run_accuracy_eval(
|
||||
``None``, so the common case stays identical to ``run_eval``'s defaults.
|
||||
Returns the metrics dict.
|
||||
"""
|
||||
assert (
|
||||
score_threshold == score_threshold
|
||||
), f"{type(test_case).__name__} must set the {eval_name} score threshold"
|
||||
assert score_threshold == score_threshold, (
|
||||
f"{type(test_case).__name__} must set the {eval_name} score threshold"
|
||||
)
|
||||
|
||||
model = eval_overrides.pop("model", getattr(test_case, "model", None))
|
||||
kwargs = dict(
|
||||
@@ -113,9 +113,9 @@ def _run_sgl_eval(
|
||||
True}`` so the server separates reasoning from the final answer. Skips the test
|
||||
if sgl-eval is not installed. Returns the RunResult.
|
||||
"""
|
||||
assert (
|
||||
score_threshold == score_threshold
|
||||
), f"{type(test_case).__name__} must set the {eval_name} score threshold"
|
||||
assert score_threshold == score_threshold, (
|
||||
f"{type(test_case).__name__} must set the {eval_name} score threshold"
|
||||
)
|
||||
|
||||
try:
|
||||
from sgl_eval.registry import get as get_eval_spec
|
||||
@@ -299,7 +299,7 @@ class MMMUProMixin:
|
||||
|
||||
def test_mmmu_pro(self):
|
||||
assert self.mmmu_pro_load_preset_from_model_id, (
|
||||
f"{type(self).__name__} must set " "mmmu_pro_load_preset_from_model_id"
|
||||
f"{type(self).__name__} must set mmmu_pro_load_preset_from_model_id"
|
||||
)
|
||||
_run_accuracy_eval(
|
||||
self,
|
||||
|
||||
@@ -51,9 +51,7 @@ class FwdOccupancyMixin:
|
||||
# Measurement: one long single-batch request -- max_new_tokens must
|
||||
# span several decode_log_interval windows for enough samples.
|
||||
fwd_occupancy_max_new_tokens: int = 2048
|
||||
fwd_occupancy_prompt: str = (
|
||||
"Human: Give me a fully functional FastAPI server. Show the python code.\n\nAssistant:"
|
||||
)
|
||||
fwd_occupancy_prompt: str = "Human: Give me a fully functional FastAPI server. Show the python code.\n\nAssistant:"
|
||||
|
||||
def _scrape_fwd_occupancy(self):
|
||||
"""Max non-NaN gauge value across exposed labels (e.g. dp ranks);
|
||||
|
||||
@@ -6,7 +6,6 @@ import requests
|
||||
|
||||
|
||||
class JSONConstrainedMixin:
|
||||
|
||||
json_schema = json.dumps(
|
||||
{
|
||||
"type": "object",
|
||||
|
||||
@@ -45,12 +45,12 @@ class MatchedStopMixin:
|
||||
if not isinstance(matched_stop, list):
|
||||
matched_stop = [matched_stop]
|
||||
|
||||
assert (
|
||||
res["choices"][0]["finish_reason"] == finish_reason
|
||||
), f"Expected finish_reason: {finish_reason}, but got: {res['choices'][0]['finish_reason']}"
|
||||
assert (
|
||||
res["choices"][0]["matched_stop"] in matched_stop
|
||||
), f"Expected matched_stop: {matched_stop}, but got: {res['choices'][0]['matched_stop']}"
|
||||
assert res["choices"][0]["finish_reason"] == finish_reason, (
|
||||
f"Expected finish_reason: {finish_reason}, but got: {res['choices'][0]['finish_reason']}"
|
||||
)
|
||||
assert res["choices"][0]["matched_stop"] in matched_stop, (
|
||||
f"Expected matched_stop: {matched_stop}, but got: {res['choices'][0]['matched_stop']}"
|
||||
)
|
||||
|
||||
def _run_chat_completions_generation(
|
||||
self,
|
||||
@@ -89,12 +89,12 @@ class MatchedStopMixin:
|
||||
if not isinstance(matched_stop, list):
|
||||
matched_stop = [matched_stop]
|
||||
|
||||
assert (
|
||||
res["choices"][0]["finish_reason"] == finish_reason
|
||||
), f"Expected finish_reason: {finish_reason}, but got: {res['choices'][0]['finish_reason']}"
|
||||
assert (
|
||||
res["choices"][0]["matched_stop"] in matched_stop
|
||||
), f"Expected matched_stop: {matched_stop}, but got: {res['choices'][0]['matched_stop']}"
|
||||
assert res["choices"][0]["finish_reason"] == finish_reason, (
|
||||
f"Expected finish_reason: {finish_reason}, but got: {res['choices'][0]['finish_reason']}"
|
||||
)
|
||||
assert res["choices"][0]["matched_stop"] in matched_stop, (
|
||||
f"Expected matched_stop: {matched_stop}, but got: {res['choices'][0]['matched_stop']}"
|
||||
)
|
||||
|
||||
def test_finish_stop_str(self):
|
||||
self._run_completions_generation(
|
||||
|
||||
@@ -161,7 +161,7 @@ class MMMUMixin:
|
||||
os.makedirs(output_path, exist_ok=True)
|
||||
|
||||
# -------- compose --model_args --------
|
||||
model_args = f'model_version="{model_version}",' f"tp={tp}"
|
||||
model_args = f'model_version="{model_version}",tp={tp}'
|
||||
|
||||
# -------- build command list --------
|
||||
cmd = [
|
||||
@@ -293,7 +293,7 @@ class MMMUMultiModelTestBase(CustomTestCase):
|
||||
os.makedirs(output_path, exist_ok=True)
|
||||
|
||||
# -------- compose --model_args --------
|
||||
model_args = f'model_version="{model_version}",' f"tp={tp}"
|
||||
model_args = f'model_version="{model_version}",tp={tp}'
|
||||
|
||||
# -------- build command list --------
|
||||
cmd = [
|
||||
|
||||
@@ -41,10 +41,10 @@ class PrefixCacheBranchingMixin:
|
||||
expected_cached_tokens = (
|
||||
branching_pos // cls.cache_chunk_size * cls.cache_chunk_size
|
||||
)
|
||||
assert (
|
||||
cached_tokens == expected_cached_tokens
|
||||
), f"{i=}, {cache_hit=}, {cached_tokens=} is not equal to {expected_cached_tokens=}, {branching_pos=}"
|
||||
assert cached_tokens == expected_cached_tokens, (
|
||||
f"{i=}, {cache_hit=}, {cached_tokens=} is not equal to {expected_cached_tokens=}, {branching_pos=}"
|
||||
)
|
||||
else:
|
||||
assert (
|
||||
cached_tokens == 0
|
||||
), f"{i=}, {cache_hit=}, {cached_tokens=} is not 0"
|
||||
assert cached_tokens == 0, (
|
||||
f"{i=}, {cache_hit=}, {cached_tokens=} is not 0"
|
||||
)
|
||||
|
||||
@@ -4,7 +4,6 @@ import requests
|
||||
|
||||
|
||||
class RegexConstrainedMixin:
|
||||
|
||||
def _run_decode_regex(
|
||||
self,
|
||||
regex,
|
||||
|
||||
@@ -111,9 +111,9 @@ class StreamingSessionKitMixin:
|
||||
# No logprob
|
||||
asyncio.run(_concurrent_logprob_run(self.base_url, self.tokenizer))
|
||||
time.sleep(3)
|
||||
assert (
|
||||
requests.get(self.base_url + "/health").status_code == 200
|
||||
), "Server unhealthy after concurrent logprob sessions."
|
||||
assert requests.get(self.base_url + "/health").status_code == 200, (
|
||||
"Server unhealthy after concurrent logprob sessions."
|
||||
)
|
||||
|
||||
def test_stress_concurrent_sessions(self) -> None:
|
||||
"""High concurrency streaming + non-streaming with retract pressure;
|
||||
|
||||
@@ -44,9 +44,9 @@ __all__ = [
|
||||
def default_prefill_cache_assert(result: dict, prefix_len: int, label: str):
|
||||
"""Standard radix cache: cached_tokens == prefix_len."""
|
||||
actual = result["meta_info"]["cached_tokens"]
|
||||
assert (
|
||||
actual == prefix_len
|
||||
), f"{label}: expected cached_tokens={prefix_len}, got {actual}"
|
||||
assert actual == prefix_len, (
|
||||
f"{label}: expected cached_tokens={prefix_len}, got {actual}"
|
||||
)
|
||||
|
||||
|
||||
def default_decode_cache_assert(
|
||||
@@ -55,9 +55,9 @@ def default_decode_cache_assert(
|
||||
"""Standard radix cache: cached_tokens == history_len + output_len."""
|
||||
expected = history_len + output_len
|
||||
actual = result["meta_info"]["cached_tokens"]
|
||||
assert (
|
||||
actual == expected
|
||||
), f"{label}: expected cached_tokens={expected}, got {actual}"
|
||||
assert actual == expected, (
|
||||
f"{label}: expected cached_tokens={expected}, got {actual}"
|
||||
)
|
||||
|
||||
|
||||
def make_mamba_prefill_assert(chunk_size: int = 64) -> Callable:
|
||||
@@ -67,9 +67,9 @@ def make_mamba_prefill_assert(chunk_size: int = 64) -> Callable:
|
||||
actual = result["meta_info"]["cached_tokens"]
|
||||
upper = (prefix_len // chunk_size) * chunk_size
|
||||
lower = max(0, upper - chunk_size)
|
||||
assert (
|
||||
lower <= actual <= upper
|
||||
), f"{label}: expected cached_tokens in [{lower}, {upper}], got {actual}"
|
||||
assert lower <= actual <= upper, (
|
||||
f"{label}: expected cached_tokens in [{lower}, {upper}], got {actual}"
|
||||
)
|
||||
|
||||
return _check
|
||||
|
||||
@@ -85,9 +85,9 @@ def make_mamba_decode_assert(track_interval: int = 16) -> Callable:
|
||||
expected = (
|
||||
(history_len + output_len - 1) // track_interval
|
||||
) * track_interval
|
||||
assert (
|
||||
actual >= expected
|
||||
), f"{label}: expected cached_tokens={expected}, got {actual}"
|
||||
assert actual >= expected, (
|
||||
f"{label}: expected cached_tokens={expected}, got {actual}"
|
||||
)
|
||||
|
||||
return _check
|
||||
|
||||
@@ -458,9 +458,9 @@ def test_input_output_logprobs_match_decode_cache_hit_helper(
|
||||
different suffixes per branch. Use branches_per_group for interleaved
|
||||
submission to stress the radix tree.
|
||||
"""
|
||||
assert (
|
||||
len(turn_suffixes) >= 1
|
||||
), "turn_suffixes must have at least 1 entry (for turn 2)"
|
||||
assert len(turn_suffixes) >= 1, (
|
||||
"turn_suffixes must have at least 1 entry (for turn 2)"
|
||||
)
|
||||
if assert_decode_cached_tokens is None:
|
||||
assert_decode_cached_tokens = default_decode_cache_assert
|
||||
|
||||
|
||||
@@ -285,9 +285,9 @@ def test_input_output_logprobs_match_prefill_cache_hit_helper(
|
||||
output_logprobs.append(_extract_output_logprobs(result))
|
||||
|
||||
if not os.environ.get("SGLANG_TEST_SKIP_CACHE_HIT_ASSERT"):
|
||||
assert len(new_input_ids) > 0.5 * len(
|
||||
input_ids
|
||||
), f"Too few prefill cache hits: {len(new_input_ids)}/{len(input_ids)}"
|
||||
assert len(new_input_ids) > 0.5 * len(input_ids), (
|
||||
f"Too few prefill cache hits: {len(new_input_ids)}/{len(input_ids)}"
|
||||
)
|
||||
|
||||
print("Flush Cache and run prefill to get input logprobs ...")
|
||||
input_logprobs = _get_input_logprobs(base_url, new_input_ids, output_logprobs)
|
||||
@@ -367,9 +367,9 @@ def test_input_output_logprobs_match_decode_cache_hit_helper(
|
||||
# Page-aligned SWA retention decides which prompts hit at all, so the default
|
||||
# only screens out a vacuous run. A caller whose checkpoint interval makes
|
||||
# every prompt hit raises this to pin that down.
|
||||
assert len(new_input_ids) > min_cache_hit_ratio * len(
|
||||
second_turn_input_ids
|
||||
), f"Too few decode cache hits: {len(new_input_ids)}/{len(second_turn_input_ids)}"
|
||||
assert len(new_input_ids) > min_cache_hit_ratio * len(second_turn_input_ids), (
|
||||
f"Too few decode cache hits: {len(new_input_ids)}/{len(second_turn_input_ids)}"
|
||||
)
|
||||
|
||||
print("Flush Cache and run prefill to get input logprobs ...")
|
||||
input_logprobs = _get_input_logprobs(base_url, new_input_ids, output_logprobs)
|
||||
|
||||
@@ -9,7 +9,6 @@ PP_SIZE: int = 2
|
||||
|
||||
|
||||
class CanaryPPFixture(CanaryE2EBase):
|
||||
|
||||
model_mode: ClassVar[str] = "swa"
|
||||
workload_n_batches: ClassVar[int] = 2
|
||||
|
||||
|
||||
@@ -616,7 +616,6 @@ def run_lora_test_by_batch(
|
||||
)
|
||||
|
||||
for i in range(len(prompts)):
|
||||
|
||||
srt_output_str = srt_outputs.output_strs[i].strip()
|
||||
hf_output_str = hf_outputs.output_strs[i].strip()
|
||||
rouge_score = calculate_rouge_l([srt_output_str], [hf_output_str])[0]
|
||||
@@ -785,7 +784,7 @@ def run_lora_multiple_batch_on_model_cases(
|
||||
with srt_runner, hf_runner:
|
||||
for i, (prompts, lora_paths) in enumerate(batches):
|
||||
print(
|
||||
f"\n--- Running Batch {i+1} --- prompts: {prompts}, lora_paths: {lora_paths}"
|
||||
f"\n--- Running Batch {i + 1} --- prompts: {prompts}, lora_paths: {lora_paths}"
|
||||
)
|
||||
|
||||
srt_outputs = srt_runner.batch_forward(
|
||||
@@ -816,7 +815,7 @@ def run_lora_multiple_batch_on_model_cases(
|
||||
f"for base '{base_path}', adaptor '{lora_paths}', prompt: '{prompts}...'"
|
||||
)
|
||||
|
||||
print(f"--- Batch {i+1} Comparison Passed --- ")
|
||||
print(f"--- Batch {i + 1} Comparison Passed --- ")
|
||||
|
||||
|
||||
def run_lora_batch_splitting_equivalence_test(
|
||||
@@ -851,9 +850,9 @@ def run_lora_batch_splitting_equivalence_test(
|
||||
|
||||
def _run_test(model_case: LoRAModelCase, torch_dtype: torch.dtype):
|
||||
lora_adapter_paths = [a.name for a in model_case.adaptors]
|
||||
assert (
|
||||
len(lora_adapter_paths) >= max_loras_per_batch
|
||||
), f"Need at least {max_loras_per_batch} adapters for this test"
|
||||
assert len(lora_adapter_paths) >= max_loras_per_batch, (
|
||||
f"Need at least {max_loras_per_batch} adapters for this test"
|
||||
)
|
||||
|
||||
max_new_tokens = 64
|
||||
base_path = model_case.base
|
||||
|
||||
@@ -55,7 +55,7 @@ def run_performance_test(
|
||||
if batch_sizes is None:
|
||||
batch_sizes = [1, 8, 16, 64]
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f"\n{'=' * 60}")
|
||||
print(f"Running PERFORMANCE test for {model.model_path}")
|
||||
print(f" Variant: {model.variant}")
|
||||
print(f" Batch sizes: {batch_sizes}")
|
||||
@@ -63,7 +63,7 @@ def run_performance_test(
|
||||
print(f" Output lens: {output_lens}")
|
||||
if spec_accept_length_threshold is not None:
|
||||
print(f" Spec accept length threshold: {spec_accept_length_threshold}")
|
||||
print(f"{'='*60}\n")
|
||||
print(f"{'=' * 60}\n")
|
||||
|
||||
# Build extra args for benchmarks
|
||||
extra_bench_args = ["--trust-remote-code"]
|
||||
|
||||
@@ -935,9 +935,9 @@ def check_close_model_outputs(
|
||||
print(f"{srt_outputs.output_strs=}")
|
||||
rouge_l_scores = calculate_rouge_l(hf_outputs.output_strs, srt_outputs.output_strs)
|
||||
print(f"{rouge_l_scores=}")
|
||||
assert all(
|
||||
score >= rouge_l_tolerance for score in rouge_l_scores
|
||||
), f"Not all ROUGE-L scores are greater than rouge_l_tolerance={rouge_l_tolerance}"
|
||||
assert all(score >= rouge_l_tolerance for score in rouge_l_scores), (
|
||||
f"Not all ROUGE-L scores are greater than rouge_l_tolerance={rouge_l_tolerance}"
|
||||
)
|
||||
|
||||
if check_logprobs:
|
||||
for i in range(len(hf_outputs.output_strs)):
|
||||
|
||||
@@ -14,7 +14,6 @@ JOIN_TIMEOUT_S: float = 10.0
|
||||
|
||||
|
||||
class BackgroundHttpPoster:
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._session: Optional[aiohttp.ClientSession] = None
|
||||
self._loop = asyncio.new_event_loop()
|
||||
|
||||
@@ -30,7 +30,6 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ScriptedContext:
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
@@ -38,9 +37,9 @@ class ScriptedContext:
|
||||
tokenizer_recv_proxy: Optional[ScriptedTokenizerRecvProxy],
|
||||
http_poster: BackgroundHttpPoster,
|
||||
) -> None:
|
||||
assert (
|
||||
scheduler_hook._is_driver
|
||||
), "ScriptedContext only exists on the driver rank"
|
||||
assert scheduler_hook._is_driver, (
|
||||
"ScriptedContext only exists on the driver rank"
|
||||
)
|
||||
self.scheduler = scheduler_hook.scheduler
|
||||
self._scheduler_hook = scheduler_hook
|
||||
self._tokenizer_recv_proxy = tokenizer_recv_proxy
|
||||
@@ -100,9 +99,9 @@ class ScriptedContext:
|
||||
return lifecycle.flush_cache(self)
|
||||
|
||||
def evict_radix(self, *, prefix_tokens: Optional[List[int]]) -> None:
|
||||
assert (
|
||||
prefix_tokens is None
|
||||
), "evict_radix currently supports only full eviction (prefix_tokens=None)"
|
||||
assert prefix_tokens is None, (
|
||||
"evict_radix currently supports only full eviction (prefix_tokens=None)"
|
||||
)
|
||||
return lifecycle.flush_cache(self)
|
||||
|
||||
def exhaust_kv(self, *, leave_pages: int) -> None:
|
||||
|
||||
@@ -9,7 +9,6 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class ScriptedKvPoolExhauster:
|
||||
|
||||
def __init__(self, scheduler: Scheduler) -> None:
|
||||
self.scheduler = scheduler
|
||||
self._held: List[torch.Tensor] = []
|
||||
@@ -23,9 +22,9 @@ class ScriptedKvPoolExhauster:
|
||||
return
|
||||
|
||||
held = allocator.alloc(need)
|
||||
assert (
|
||||
held is not None
|
||||
), f"exhaust_kv: allocator could not grab {need} tokens to create pressure"
|
||||
assert held is not None, (
|
||||
f"exhaust_kv: allocator could not grab {need} tokens to create pressure"
|
||||
)
|
||||
self._held.append(held)
|
||||
|
||||
def release(self) -> None:
|
||||
|
||||
@@ -9,7 +9,6 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class ScriptedLockRefExhauster:
|
||||
|
||||
def __init__(self, scheduler: Scheduler) -> None:
|
||||
self.scheduler = scheduler
|
||||
self._locked: List[Any] = []
|
||||
|
||||
@@ -34,7 +34,6 @@ SERVER_HOST: str = "127.0.0.1"
|
||||
|
||||
|
||||
class ScriptedHttpServer:
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
|
||||
@@ -8,7 +8,6 @@ from typing import Any, Tuple, Union
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class RunScript:
|
||||
|
||||
fn_path: str
|
||||
args: Tuple[Any, ...] = ()
|
||||
|
||||
@@ -30,13 +29,11 @@ class ScriptSucceeded:
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class ScriptFailed:
|
||||
|
||||
traceback: str
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class OutOfBandError:
|
||||
|
||||
traceback: str
|
||||
|
||||
def to_json(self) -> str:
|
||||
|
||||
@@ -117,7 +117,6 @@ def _reset_engine_state(ctx: ScriptedContext) -> Generator:
|
||||
|
||||
|
||||
class ScriptedSchedulerHook:
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
|
||||
@@ -7,7 +7,6 @@ from sglang.test.test_utils import CustomTestCase
|
||||
|
||||
|
||||
class ScriptedTestCase(CustomTestCase):
|
||||
|
||||
ENGINE_KWARGS: ClassVar[Dict[str, Any]] = {}
|
||||
|
||||
server: ClassVar[ScriptedHttpServer]
|
||||
|
||||
@@ -23,7 +23,6 @@ _WORK_REQ_TYPES = (
|
||||
|
||||
|
||||
class ScriptedTokenizerRecvProxy:
|
||||
|
||||
def __init__(self, *, underlying: zmq.Socket) -> None:
|
||||
self._underlying = underlying
|
||||
self._buffer: deque = deque()
|
||||
|
||||
@@ -57,9 +57,9 @@ def run_until_all_finished(handles: List[Any], *, max_steps: int = DEFAULT_MAX_S
|
||||
def warmup_radix(t, prompt_tokens: List[int], *, max_steps: int = DEFAULT_MAX_STEPS):
|
||||
assert prompt_tokens, "warmup_radix needs a non-empty prompt"
|
||||
token = prompt_tokens[0]
|
||||
assert all(
|
||||
x == token for x in prompt_tokens
|
||||
), "warmup_radix supports only uniform prompts"
|
||||
assert all(x == token for x in prompt_tokens), (
|
||||
"warmup_radix supports only uniform prompts"
|
||||
)
|
||||
handle = t.start_req(
|
||||
prompt_len=len(prompt_tokens), max_new_tokens=1, prompt_token=token
|
||||
)
|
||||
@@ -126,9 +126,9 @@ def advance_to_decode_step(
|
||||
r, target_output_len: int, *, max_steps: int = DEFAULT_MAX_STEPS
|
||||
):
|
||||
for _ in range(max_steps):
|
||||
assert (
|
||||
not r.finished
|
||||
), f"req finished before reaching decode step {target_output_len}"
|
||||
assert not r.finished, (
|
||||
f"req finished before reaching decode step {target_output_len}"
|
||||
)
|
||||
req = r.req
|
||||
if req is not None and len(req.output_ids) >= target_output_len:
|
||||
return
|
||||
|
||||
@@ -39,9 +39,7 @@ class BenchArgs:
|
||||
presence_penalty: float = 0.0
|
||||
json: bool = False
|
||||
return_logprob: bool = False
|
||||
prompt: str = (
|
||||
"Human: Give me a fully functional FastAPI server. Show the python code.\n\nAssistant:"
|
||||
)
|
||||
prompt: str = "Human: Give me a fully functional FastAPI server. Show the python code.\n\nAssistant:"
|
||||
image: bool = False
|
||||
many_images: bool = False
|
||||
stop: Optional[list] = None
|
||||
@@ -144,7 +142,7 @@ def send_one_prompt(
|
||||
else:
|
||||
if args.different_prompts:
|
||||
prompt = [
|
||||
f"Test case {i+1}: " + args.prompt for i in range(args.batch_size)
|
||||
f"Test case {i + 1}: " + args.prompt for i in range(args.batch_size)
|
||||
]
|
||||
else:
|
||||
prompt = [args.prompt] * args.batch_size
|
||||
|
||||
@@ -378,7 +378,7 @@ def get_rdma_devices_args():
|
||||
if not (base_rdma_group <= gpu_idx < base_rdma_group + 4):
|
||||
warnings.warn(
|
||||
f"GPU index {gpu_idx} is outside expected group "
|
||||
f"{base_rdma_group}-{base_rdma_group+3}"
|
||||
f"{base_rdma_group}-{base_rdma_group + 3}"
|
||||
)
|
||||
|
||||
# 3. Generate RDMA device names
|
||||
|
||||
@@ -40,7 +40,6 @@ DEFAULT_HYBRID_ATTN_SERVER_ARGS = [
|
||||
|
||||
@unittest.skipIf(get_device_sm() < 90, "Test requires CUDA SM 90 or higher")
|
||||
class TestHybridAttnBackendBase(CustomTestCase):
|
||||
|
||||
model = DEFAULT_MODEL_NAME_FOR_TEST
|
||||
base_url = DEFAULT_URL_FOR_TEST
|
||||
accuracy_threshold = 0.65 # derived tests need to override this
|
||||
|
||||
@@ -40,9 +40,9 @@ class PCGSpecBase:
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
assert (
|
||||
cls.model and cls.server_args
|
||||
), f"{cls.__name__} must set `model` and `server_args`"
|
||||
assert cls.model and cls.server_args, (
|
||||
f"{cls.__name__} must set `model` and `server_args`"
|
||||
)
|
||||
cls.base_url = DEFAULT_URL_FOR_TEST
|
||||
kwargs = dict(
|
||||
timeout=DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH * cls.timeout_mult,
|
||||
|
||||
@@ -314,8 +314,7 @@ async def _concurrent_logprob_run(base_url: str, tokenizer: Any, **gen_kwargs) -
|
||||
tasks = []
|
||||
for s in range(CONCURRENT_LOGPROB_SESSIONS):
|
||||
text = (
|
||||
f"S{s} T{turn}: "
|
||||
f"{LOGPROB_PROMPTS[turn % len(LOGPROB_PROMPTS)]}"
|
||||
f"S{s} T{turn}: {LOGPROB_PROMPTS[turn % len(LOGPROB_PROMPTS)]}"
|
||||
)
|
||||
ids = tokenizer.encode(text)
|
||||
tasks.append(
|
||||
@@ -360,9 +359,7 @@ async def _stress_run_all(base_url: str, tokenizer: Any) -> None:
|
||||
# Streaming requests — long prompts to trigger chunked prefill.
|
||||
for s in range(STRESS_NUM_SESSIONS):
|
||||
offset = (s * STRESS_NUM_TURNS + turn) * 200
|
||||
text = (
|
||||
f"Session {s} turn {turn}: " f"{LEAK_FILLER[offset : offset + 800]}"
|
||||
)
|
||||
text = f"Session {s} turn {turn}: {LEAK_FILLER[offset : offset + 800]}"
|
||||
ids = tokenizer.encode(text)
|
||||
tasks.append(
|
||||
_async_generate(
|
||||
|
||||
@@ -112,7 +112,6 @@ class GSM8KEval(Eval):
|
||||
|
||||
|
||||
class MixedPrefixGSM8KEval(GSM8KEval):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
num_examples: Optional[int],
|
||||
|
||||
@@ -192,9 +192,9 @@ def bench_kineto(
|
||||
kernel_names = (kernel_names,) if isinstance(kernel_names, str) else kernel_names
|
||||
assert all([isinstance(name, str) for name in kernel_names])
|
||||
for name in kernel_names:
|
||||
assert (
|
||||
sum([name in line for line in prof_lines]) == 1
|
||||
), f"Errors of the kernel {name} in the profiling table"
|
||||
assert sum([name in line for line in prof_lines]) == 1, (
|
||||
f"Errors of the kernel {name} in the profiling table"
|
||||
)
|
||||
|
||||
# Save chrome traces
|
||||
if trace_path is not None:
|
||||
|
||||
@@ -510,7 +510,7 @@ def test_deterministic(args):
|
||||
|
||||
# If logprobs are enabled, compare them across different batch sizes
|
||||
if args.return_logprob:
|
||||
print(f"\n{'='*60}")
|
||||
print(f"\n{'=' * 60}")
|
||||
print("Logprobs Comparison Across Batch Sizes")
|
||||
print("=" * 60)
|
||||
|
||||
@@ -536,7 +536,7 @@ def test_deterministic(args):
|
||||
match, msg = compare_logprobs(ref_logprobs, resp_logprobs)
|
||||
|
||||
if not match:
|
||||
print(f" ✗ Sample {j+1}: {msg}")
|
||||
print(f" ✗ Sample {j + 1}: {msg}")
|
||||
mismatches.append((j + 1, msg))
|
||||
all_match = False
|
||||
|
||||
@@ -549,7 +549,7 @@ def test_deterministic(args):
|
||||
)
|
||||
logprob_results.append(0)
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f"\n{'=' * 60}")
|
||||
if all(r == 1 for r in logprob_results):
|
||||
print("✓✓✓ Logprobs are identical across all batch sizes! ✓✓✓")
|
||||
else:
|
||||
@@ -653,7 +653,7 @@ def test_deterministic(args):
|
||||
print(f" Logprob: {uncached_logprob:.10f}")
|
||||
|
||||
# Step 6: Compare results
|
||||
print(f"\n{'='*60}")
|
||||
print(f"\n{'=' * 60}")
|
||||
print("Comparison 1: Decode (Request 1) vs Prefill with Cache (Request 2)")
|
||||
print("=" * 60)
|
||||
|
||||
@@ -679,7 +679,7 @@ def test_deterministic(args):
|
||||
print(f" Logprob difference: {diff:.10e}")
|
||||
print(f" Note: We expect these to be DIFFERENT (decode vs prefill kernels)")
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f"\n{'=' * 60}")
|
||||
print(
|
||||
"Comparison 2: Cached Prefill (Request 2) vs Uncached Prefill (Request 3)"
|
||||
)
|
||||
@@ -708,7 +708,7 @@ def test_deterministic(args):
|
||||
print(f" Difference: {diff:.10e}")
|
||||
print(f" Note: We expect these to be IDENTICAL (both prefill kernels)")
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f"\n{'=' * 60}")
|
||||
if token_match and logprob_match:
|
||||
print("✓✓✓ TEST PASSED - Radix cache is consistent! ✓✓✓")
|
||||
return [1]
|
||||
|
||||
@@ -27,12 +27,11 @@ from sglang.srt.layers.quantization.utils import (
|
||||
|
||||
|
||||
class MarlinWorkspace:
|
||||
|
||||
def __init__(self, out_features, min_thread_n, max_parallel):
|
||||
assert (
|
||||
out_features % min_thread_n == 0
|
||||
), "out_features = {} is undivisible by min_thread_n = {}".format(
|
||||
out_features, min_thread_n
|
||||
assert out_features % min_thread_n == 0, (
|
||||
"out_features = {} is undivisible by min_thread_n = {}".format(
|
||||
out_features, min_thread_n
|
||||
)
|
||||
)
|
||||
|
||||
max_workspace_size = (out_features // min_thread_n) * max_parallel
|
||||
|
||||
@@ -262,16 +262,16 @@ def test_parallel_decoding():
|
||||
# Generate detailed tips
|
||||
forks = s.fork(fork_size)
|
||||
for i in range(fork_size):
|
||||
forks[
|
||||
i
|
||||
] += f"Now, I expand tip {i+1} into a detailed paragraph:\nTip {i+1}:"
|
||||
forks[i] += (
|
||||
f"Now, I expand tip {i + 1} into a detailed paragraph:\nTip {i + 1}:"
|
||||
)
|
||||
forks[i] += sgl.gen("detailed_tip", max_tokens, stop=["\n\n"])
|
||||
forks.join()
|
||||
|
||||
# Concatenate tips and summarize
|
||||
s += "Here are these tips with detailed explanation:\n"
|
||||
for i in range(fork_size):
|
||||
s += f"Tip {i+1}:" + forks[i]["detailed_tip"] + "\n"
|
||||
s += f"Tip {i + 1}:" + forks[i]["detailed_tip"] + "\n"
|
||||
|
||||
s += "\nIn summary," + sgl.gen("summary", max_tokens=512)
|
||||
|
||||
@@ -294,7 +294,7 @@ def test_parallel_encoding(check_answer=True):
|
||||
forks += lambda i: f"Statement {i}: " + contexts[i] + "\n"
|
||||
forks.join(mode="concate_and_append")
|
||||
|
||||
s += "Now, please answer the following question. " "Do not list options."
|
||||
s += "Now, please answer the following question. Do not list options."
|
||||
s += "\nQuestion: " + question + "\n"
|
||||
s += "ASSISTANT:" + sgl.gen("answer", max_tokens=max_tokens)
|
||||
|
||||
@@ -474,9 +474,9 @@ def test_completion_speculative():
|
||||
gen_character_no_spec().sync()
|
||||
usage_with_no_spec = token_usage.prompt_tokens
|
||||
|
||||
assert (
|
||||
usage_with_spec < usage_with_no_spec
|
||||
), f"{usage_with_spec} vs {usage_with_no_spec}"
|
||||
assert usage_with_spec < usage_with_no_spec, (
|
||||
f"{usage_with_spec} vs {usage_with_no_spec}"
|
||||
)
|
||||
|
||||
|
||||
def test_chat_completion_speculative():
|
||||
@@ -612,9 +612,9 @@ def test_gen_min_new_tokens():
|
||||
|
||||
def assert_min_tokens(tokenizer, text):
|
||||
token_ids = tokenizer.encode(text)
|
||||
assert (
|
||||
len(token_ids) >= MIN_TOKENS
|
||||
), f"Generated {len(token_ids)} tokens, min required: {MIN_TOKENS}. Text: {text}"
|
||||
assert len(token_ids) >= MIN_TOKENS, (
|
||||
f"Generated {len(token_ids)} tokens, min required: {MIN_TOKENS}. Text: {text}"
|
||||
)
|
||||
|
||||
tokenizer = get_tokenizer(model_path)
|
||||
|
||||
|
||||
@@ -2144,7 +2144,6 @@ def server_args_variant(server_args, **fields):
|
||||
|
||||
|
||||
class CustomTestCase(unittest.TestCase):
|
||||
|
||||
def __init_subclass__(cls, **kwargs):
|
||||
super().__init_subclass__(**kwargs)
|
||||
|
||||
|
||||
@@ -263,14 +263,14 @@ def _test_reasoning_usage(client, model):
|
||||
)
|
||||
usage = response.usage
|
||||
assert usage is not None, "usage should not be None"
|
||||
assert (
|
||||
usage.reasoning_tokens and usage.reasoning_tokens > 0
|
||||
), f"expected reasoning_tokens > 0, got {usage.reasoning_tokens}"
|
||||
assert usage.reasoning_tokens and usage.reasoning_tokens > 0, (
|
||||
f"expected reasoning_tokens > 0, got {usage.reasoning_tokens}"
|
||||
)
|
||||
if usage.completion_tokens_details:
|
||||
detail_reasoning = usage.completion_tokens_details.get("reasoning_tokens", 0)
|
||||
assert (
|
||||
detail_reasoning > 0
|
||||
), f"expected completion_tokens_details.reasoning_tokens > 0, got {detail_reasoning}"
|
||||
assert detail_reasoning > 0, (
|
||||
f"expected completion_tokens_details.reasoning_tokens > 0, got {detail_reasoning}"
|
||||
)
|
||||
|
||||
|
||||
def _test_parallel(client, model):
|
||||
|
||||
@@ -95,9 +95,9 @@ class AudioOpenAITestMixin(TestOpenAIMLLMServerBase):
|
||||
"art",
|
||||
]
|
||||
for check_word in check_list:
|
||||
assert (
|
||||
check_word in text.lower()
|
||||
), f"audio_response: |{text}| should contain |{check_word}|"
|
||||
assert check_word in text.lower(), (
|
||||
f"audio_response: |{text}| should contain |{check_word}|"
|
||||
)
|
||||
|
||||
def prepare_audio_messages(self, prompt, audio_file_name):
|
||||
messages = [
|
||||
@@ -285,9 +285,9 @@ class ImageOpenAITestMixin(TestOpenAIMLLMServerBase):
|
||||
assert isinstance(text, str)
|
||||
|
||||
# `driver` is for gemma-3-it
|
||||
assert any(
|
||||
keyword in text for keyword in ("man", "person", "driver")
|
||||
), f"text: {text}, should contain man, person or driver"
|
||||
assert any(keyword in text for keyword in ("man", "person", "driver")), (
|
||||
f"text: {text}, should contain man, person or driver"
|
||||
)
|
||||
assert (
|
||||
"cab" in text
|
||||
or "taxi" in text
|
||||
@@ -377,9 +377,9 @@ class ImageOpenAITestMixin(TestOpenAIMLLMServerBase):
|
||||
assert response.choices[0].message.role == "assistant"
|
||||
text = response.choices[0].message.content
|
||||
assert isinstance(text, str)
|
||||
assert (
|
||||
"man" in text or "cab" in text
|
||||
), f"text: {text}, should contain man or cab"
|
||||
assert "man" in text or "cab" in text, (
|
||||
f"text: {text}, should contain man or cab"
|
||||
)
|
||||
assert response.id
|
||||
assert response.created
|
||||
assert response.usage.prompt_tokens > 0
|
||||
@@ -429,9 +429,9 @@ class ImageOpenAITestMixin(TestOpenAIMLLMServerBase):
|
||||
or "taxi" in text
|
||||
or "car" in text
|
||||
), f"text: {text}, should contain man, cab, SUV, taxi or car"
|
||||
assert (
|
||||
"logo" in text or '"S"' in text or "SG" in text or "graphic" in text
|
||||
), f"text: {text}, should contain logo, S or SG or graphic"
|
||||
assert "logo" in text or '"S"' in text or "SG" in text or "graphic" in text, (
|
||||
f"text: {text}, should contain logo, S or SG or graphic"
|
||||
)
|
||||
assert response.id
|
||||
assert response.created
|
||||
assert response.usage.prompt_tokens > 0
|
||||
@@ -594,16 +594,20 @@ class VideoOpenAITestMixin(TestOpenAIMLLMServerBase):
|
||||
or "speaker" in video_response
|
||||
or "presenter" in video_response
|
||||
or "hand" in video_response
|
||||
), f"video_response: {video_response}, should either have 'man' in video_response, or 'person' in video_response, or 'individual' in video_response or 'speaker' in video_response or 'presenter' or 'hand' in video_response"
|
||||
), (
|
||||
f"video_response: {video_response}, should either have 'man' in video_response, or 'person' in video_response, or 'individual' in video_response or 'speaker' in video_response or 'presenter' or 'hand' in video_response"
|
||||
)
|
||||
assert (
|
||||
"present" in video_response
|
||||
or "examine" in video_response
|
||||
or "display" in video_response
|
||||
or "hold" in video_response
|
||||
), f"video_response: {video_response}, should contain 'present', 'examine', 'display', or 'hold'"
|
||||
assert (
|
||||
"black" in video_response or "dark" in video_response
|
||||
), f"video_response: {video_response}, should contain 'black' or 'dark'"
|
||||
), (
|
||||
f"video_response: {video_response}, should contain 'present', 'examine', 'display', or 'hold'"
|
||||
)
|
||||
assert "black" in video_response or "dark" in video_response, (
|
||||
f"video_response: {video_response}, should contain 'black' or 'dark'"
|
||||
)
|
||||
self.assertIsNotNone(video_response)
|
||||
self.assertGreater(len(video_response), 0)
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ class SimpleEvalGSM8KXPUMixin(ABC):
|
||||
self.assertGreaterEqual(
|
||||
metrics["score"],
|
||||
accuracy_threshold,
|
||||
f'Accuracy of {self.model} is {metrics["score"]}, '
|
||||
f"Accuracy of {self.model} is {metrics['score']}, "
|
||||
f"is lower than {accuracy_threshold}",
|
||||
)
|
||||
if "output_throughput" in metrics:
|
||||
@@ -113,7 +113,7 @@ class SimpleEvalGSM8KXPUMixin(ABC):
|
||||
metrics["output_throughput"],
|
||||
output_throughput_threshold,
|
||||
f"Output throughput of {self.model} is "
|
||||
f'{metrics["output_throughput"]}, is lower than '
|
||||
f"{metrics['output_throughput']}, is lower than "
|
||||
f"{output_throughput_threshold}",
|
||||
)
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user