test: switch the Inkling-Small NVFP4 deterministic suite to DSPARK (#35293)

This commit is contained in:
Shuwen Wang
2026-08-20 21:54:52 +08:00
committed by GitHub
parent b03ac355e7
commit 9b249a25a1
@@ -48,11 +48,14 @@ from sglang.test.test_utils import (
popen_launch_server,
)
register_cuda_ci(est_time=1700, stage="extra-b", runner_config="4-gpu-b200")
register_cuda_ci(est_time=2000, stage="extra-b", runner_config="4-gpu-b200")
_MODEL_PATH = os.environ.get(
"INKLING_SMALL_TEST_MODEL_PATH", "thinkingmachines/Inkling-Small-NVFP4"
)
_DSPARK_DRAFT_PATH = os.environ.get(
"INKLING_SMALL_DSPARK_DRAFT_PATH", "RadixArk/Inkling-Small-DSpark"
)
# Measured 0.900 (10-shot, 200 questions, tp=4, invalid=0.000) -- completion,
# so no thinking. The floor sits ~4.5 sigma of the 200-question sampling noise
@@ -139,13 +142,20 @@ class TestInklingSmallNvfp4(CustomTestCase):
self.assertGreaterEqual(metrics["accuracy"], GSM8K_THRESHOLD)
class TestInklingSmallNvfp4Deterministic(CustomTestCase):
class TestInklingSmallNvfp4DsparkDeterministic(CustomTestCase):
"""Prefill and decode must score a token identically once every kernel on
the path is batch-invariant, which is what deterministic inference buys.
Drift here is then a state-reuse bug -- a stale conv/mamba checkpoint, or a
prefix restored from the radix cache that does not reproduce a fresh
prefill -- rather than the float noise a loose threshold would hide.
DSPARK drives the decode loop because the spec-side mamba/sconv save is
otherwise unreachable: that gate lives in PrefillCudaGraphRunner, and EAGLE
targets disable the prefill graph outright (#28386), so the MTP class in
test_unified_radix_cache_kl_hybrid_bitexact.py never reaches it. Reverting
#34043 reads 1.10e-01 on prefill_cache_hit here and exactly 0 without
speculation.
Runs its own server: the accuracy case above has to stay on the production
numerics, so it cannot share this one.
"""
@@ -178,11 +188,19 @@ class TestInklingSmallNvfp4Deterministic(CustomTestCase):
"0.1",
"--mamba-full-memory-ratio",
"0.1",
# The draft weights and the speculative CUDA graphs need the
# headroom; 0.85 OOMs mid-run on a 178 GB B200.
"--mem-fraction-static",
"0.85",
"0.80",
"--mamba-track-interval",
str(KL_TRACK_INTERVAL),
"--enable-deterministic-inference",
"--speculative-algorithm",
"DSPARK",
"--speculative-draft-model-path",
_DSPARK_DRAFT_PATH,
"--speculative-draft-attention-backend",
"fa4",
],
env={**os.environ, "SGLANG_ENABLE_UNIFIED_RADIX_TREE": "1"},
)
@@ -210,9 +228,12 @@ class TestInklingSmallNvfp4Deterministic(CustomTestCase):
self._run(assert_logprobs_match_prefill_cache_hit)
def test_input_output_logprobs_match_decode_cache_hit(self):
# 0.99 is every prompt: the interval above makes the reuse unconditional, so
# a single miss is a state-reuse regression rather than a geometry coincidence.
self._run(assert_logprobs_match_decode_cache_hit, min_cache_hit_ratio=0.99)
# Not every prompt: speculation commits up to block_size-1 tokens past
# max_new_tokens, and those reach the radix insert but not the returned
# output. For roughly one prompt in 32 that puts the request's only mamba
# checkpoint past the prefix a follow-up turn can reach, and its decode
# region is not reusable. Tighten to 0.99 once that is fixed.
self._run(assert_logprobs_match_decode_cache_hit, min_cache_hit_ratio=0.9)
# The multi-turn branching harness, unlike the single-turn helpers above, replays