Repository navigation
Conversation
Signed-off-by: Tuukka Sarvi <tuukka.sarvi@amd.com>
Signed-off-by: Tuukka Sarvi <tuukka.sarvi@amd.com>
Signed-off-by: Tuukka Sarvi <tuukka.sarvi@amd.com>
|
This looks great! One question - since the TP4 validation includes #56831, should that PR land first or be a hard dependency? What happens with TP>1 if this PR lands by itself? |
|
This pull request has merge conflicts that must be resolved before it can be |
…aptive Signed-off-by: Tuukka Sarvi <tuukka.sarvi@amd.com>
Yes, #56831 should land first: it is a correctness dependency for adaptive TP>1. If this PR lands alone, adaptive TP=1 works and fixed-K remains unchanged, but adaptive TP>1 is unsafe because ranks can choose different budgets or request boundaries, potentially causing divergent execution or collective hangs. |
Signed-off-by: Tuukka Sarvi <tuukka.sarvi@amd.com>
Signed-off-by: Tuukka Sarvi <tuukka.sarvi@amd.com>
|
|
||
| class DeepseekV4ROCMAiterSparseSWAMetadataBuilder(DeepseekV41SparseSWAMetadataBuilder): | ||
| @classmethod | ||
| def get_cudagraph_support( |
There was a problem hiding this comment.
I believe this is identical code to the function above. create a helper function instead of copy pasting the code
There was a problem hiding this comment.
I have kept these overrides explicit because the only shared code is the adaptive-verification condition. Each override has a builder-specific safety rationale and superclass fallback, so a helper would add indirection without centralizing meaningful behavior.
|
|
||
| @requires_gfx950 | ||
| @torch.inference_mode() | ||
| def test_dsv41_adaptive_mla_swa_metadata_graph_replay(monkeypatch) -> None: |
There was a problem hiding this comment.
is the test running in mi355 CI?
There was a problem hiding this comment.
It was previously only run manually. I added the focused test_dsv41_adaptive_mla_swa_metadata_graph_replay case to the MI355 DPX MLA Kernels CI job. The local MI355X run passes. The CI result will be available once AMD CI runs.
| "DeepseekV4ForCausalLM" in model_config.architectures | ||
| or "DeepseekV41ForCausalLM" in model_config.architectures |
There was a problem hiding this comment.
what is the plan for V42, V43 and so on?
I think we can have something like this here:
_ROCM_FLATTENED_DEVICE_QUERY_LENS_ARCH_RE = re.compile(r"DeepseekV4\d*ForCausalLM")
There was a problem hiding this comment.
I would keep this as an explicit allowlist rather than automatically opt every future V4.x architecture into the capability. This check asserts that the architecture's ROCm metadata and indexer paths safely support device/CPU query-length mismatch and adaptive full-graph replay. A name regex could silently enable an unvalidated future implementation whose backend or metadata layout differs.
New architectures should be added only after they pass the similar focused validation.
| and model_config is not None | ||
| and "DeepseekV4ForCausalLM" in model_config.architectures | ||
| and ( | ||
| "DeepseekV4ForCausalLM" in model_config.architectures |
There was a problem hiding this comment.
I run this change with DSv41 flash and agentic dataset and it is crushing:
- Before the fault, adaptive verification was working: acceptance was about 4.5 per step with 8–11 requests running.
00:54:44 Avg prompt tput: 56530.4 toks/s, Avg generation tput: 186.6 toks/s, Reqs Running: 8, Waiting: 56
00:54:44 SpecDecoding metrics: Mean acceptance length: 4.54, ... Per-position acceptance rate: 0.895, 0.747, 0.637, 0.518, 0.431, ...
00:55:04 Avg prompt tput: 32013.2 toks/s, Avg generation tput: 224.2 toks/s, Reqs Running: 9, Waiting: 55
00:55:04 SpecDecoding metrics: Mean acceptance length: 4.57, ... Per-position acceptance rate: 0.890, 0.752, 0.637, 0.530, 0.436, ...
- The fault, as soon as the batch ramped to 59 running requests:
Warning: Queue error - HSA_STATUS_ERROR_MEMORY_FAULT
Memory access fault by GPU node-8 (Agent handle: 0x192c9d20) on address 0x7eec50800000. Reason: Unknown.
GPU coredump: Pipe handler '/usr/share/apport/apport' not found or not executable.
Falling back to file-based dump. Set HSA_COREDUMP_PATTERN to override.
(RustFrontend) 00:55:14 Avg prompt tput: 32433.0 toks/s, Avg generation tput: 357.7 toks/s, Reqs Running: 59, Waiting: 0, GPU KV cache used: 4.7%, Prefix cache hit rate: 97.3%
(RustFrontend) 00:55:14 SpecDecoding metrics: Mean acceptance length: 3.94, ...
(RustFrontend) 00:55:24 Avg prompt tput: 0.0 toks/s, Avg generation tput: 0.0 toks/s, Reqs Running: 59, Waiting: 0
- Hang, then the engine died after the 5-minute timeout:
(EngineCore) 00:56:09 [shm_broadcast.py:812] No available shared memory broadcast block found in 60 seconds. ...
(EngineCore) 00:57:09 ... (same, every 60 s) ...
(EngineCore) 00:59:09 ...
(EngineCore) ERROR 01:00:08 [dump_input.py:81] Dumping scheduler stats: SchedulerStats(num_running_reqs=59, num_waiting_reqs=0, ...)
(EngineCore) ERROR 01:00:08 [core.py:1449] EngineCore encountered a fatal error.
Traceback (most recent call last):
File ".../vllm/v1/executor/multiproc_executor.py", line 435, in get_response
status, result = mq.dequeue(timeout=dequeue_timeout)
File ".../vllm/distributed/device_communicators/shm_broadcast.py", line 900, in dequeue
with self.acquire_read(timeout, indefinite) as buf:
File ".../vllm/distributed/device_communicators/shm_broadcast.py", line 805, in acquire_read
self._spin_condition.wait(timeout_ms=read_timeout.timeout_ms())
File ".../vllm/distributed/device_communicators/shm_broadcast.py", line 758, in timeout_ms
raise TimeoutError
TimeoutError
The above exception was the direct cause of the following exception:
File ".../vllm/v1/engine/core.py", line 745, in step_with_batch_queue
model_output = future.result()
File ".../vllm/v1/executor/multiproc_executor.py", line 103, in _wait_for_response
response = self.aggregate(self.get_response())
...
RuntimeError: Engine core process EngineCore died unexpectedly.
(RustFrontend) ERROR 01:00:08 [chat_completions.rs:485] ... chat stream failed error=engine-core error: engine core reported f...
I believe this still need more changes similar to the dependencies in #59824
There was a problem hiding this comment.
Please give me the reproducer commands so that I can investigate 🙏 . I haven't seen any errors.
There was a problem hiding this comment.
I'll sent you repro steps in pm.
There was a problem hiding this comment.
Thanks. I reproduced the fault only with block rejection. Standard rejection ran cleanly. It appears to be the shared block-rejection out-of-bounds access fixed by #60945, rather than the V4.1 MLA/indexer changes. With that fix, the same TP8 workload ran cleanly at K=5 and K=6.
Signed-off-by: Tuukka Sarvi <tuukka.sarvi@amd.com>
Update: #56831 is no longer a merge prerequisite for this PR. TP4 focused tests, GSM8K, and multiple full C4–C256 serving sweeps pass without it. |
|
Could you run RULER NIAH at 16K and 64K for fixed K=5 and adaptive? GSM8K looks fine, but the contexts in the tests and the serve runs stay pretty short |
Purpose
Enable confidence-scheduled adaptive verification for
DeepseekV41ForCausalLMon ROCm.This PR extends the existing validated ROCm flattened-query mechanism to V4.1 and adds adaptive-only graph-support declarations for the two builders. Fixed-width DSpark behavior is unchanged.
AI assistance was used for this PR.
Implementation
DeepseekV41ForCausalLM.AttentionCGSupport.ALWAYSfor the V4.1 ROCm compressed sparse-MLA and sparse-SWA builders only when adaptive verification is enabled.Validation stack
deepseek-ai/DeepSeek-V4.1-Flash; expert parallel enabled for baseline and disabled for the matched mono-off/on (referring to [ROCm][Perf][DSv4.1] Mono decode layer for DeepSeek-V4.1-Flash on MI355X #60397) comparisonvllm/vllm-openai-rocm:nightly-7d0b4e57aac4c4323225b0eee9ae960ce75ffffe(vLLM0.31.1rc1.dev253+g7d0b4e57a.rocm723)7d0b4e57aaplus this PR's exact four-file patchVLLM_ROCM_MONO_DECODE=0and1, and the EP-on baseline used mono decode offThe primary validation matrix below used standard rejection sampling. Adaptive block rejection currently also requires #60945, which fixes an out-of-bounds read when adaptive verification chooses fewer steps than the configured maximum. With that fix, GSM8K accuracy and TP4 throughput matched standard rejection.
vLLM server command and environment
The adaptive arm used the following effective command inside the vllm container (the fixed-K=5 arm changed only
enable_adaptive_verificationtofalse; the no-speculation arm omitted--speculative-config;VLLM_ROCM_MONO_DECODEwas set to0or1). The EP-on baseline additionally passed--enable-expert-paralleland usedVLLM_ROCM_MONO_DECODE=0:Test results
Focused tests
test_dsv41_adaptive_mla_swa_metadata_graph_replay, and the shared adaptive-verification tests.Accuracy
GSM8K 5-shot, 1,319 samples per arm, concurrency 16, standard rejection sampling:
All arms completed every sample. Every within-configuration and same-arm topology difference is within 1.2 combined standard errors.
GSM8K command
lm_eval \ --model local-completions \ --model_args 'model=deepseek-ai/DeepSeek-V4.1-Flash,base_url=http://localhost:8000/v1/completions,num_concurrent=16,tokenizer_backend=none,tokenized_requests=False' \ --tasks gsm8k \ --num_fewshot 5 \ --batch_size 1 \ --seed 42SPEED-Bench throughput
All 880 qualitative prompts in original order, 512 forced output tokens, a distinct cache salt per concurrency. Each arm and mono mode used one fresh server and one 64-request C32 warmup. Output tokens per second:
Baseline, EP on and mono decode off:
Matched mono comparison, EP off and mono decode off:
Matched mono comparison, EP off and mono decode on:
All 54 cells completed 880/880 requests with zero failures. In the EP-on baseline, adaptive relative to fixed K=5 was -1.9% at C4 and +3.5% to +13.2% from C16 to C256; it beat no speculation by 27.7% at C128 and 14.2% at C256. In the matched EP-off comparison, adaptive relative to fixed was -2.2% at C4 and +4.7% to +15.0% from C16 to C256 with mono off; with mono on it was -1.6% at C4 and +4.6% to +11.7% from C16 to C256. Adaptive beat no speculation at every measured concurrency in all three configurations.
The mono launches were confirmed active in all three mono-on server logs. Their direct performance effect matched #60397's scope: at C4 mono improved no speculation by 76.5%, fixed K=5 by 35.4%, and adaptive by 36.3%. Above C4 the fixed/adaptive mono-on/off difference was mostly within about 2%, because a full K=5 verify reaches the mono path's 48-row ceiling at eight requests.
SPEED-Bench commands
Each arm used one server and a 64-request C32 random warmup before the measured loop: