You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Speculative decoding with draft model: extreme slowdown on Vulkan (UMA iGPU) when both models on same device
Describe the bug
When using draft-model speculative decoding on the Vulkan backend with both models loaded on the same GPU, the draft model's per-token generation time increases by ~100,000x compared to running standalone. This makes speculative decoding completely ineffective — the target model with draft is no faster (or slower) than without.
The same hardware runs the draft model at 33-35 t/s when it's the only model loaded. When the target model is also loaded on the same Vulkan device, draft generation slows to effectively zero.
This is a unified memory architecture (UMA) — the GPU and CPU share the same physical RAM. There is no discrete VRAM.
Models
Role
Model
Quant
Size
Layers on GPU
Target
gemma-4-31B-it
Q6_K
23.5 GB
41/41 on Vulkan0
Draft
gemma-4-E2B-it
Q5_K_M
3.1 GB
26/26 on Vulkan0 (ngl=99)
Both models from the same family (same tokenizer, same architecture). Total GPU memory: ~30.3 GB model buffers on Vulkan0 + ~2.3 GB on Vulkan_Host. Well within the 100 GB shared RAM budget.
Build
llama-b9114-bin-ubuntu-vulkan-x64 (pre-built release from GitHub)
Steps to Reproduce
1. Draft model standalone (no target) — works great
Draft model running on CPU is somehow slower when the target model is on GPU
Expected Behavior
With a 35 t/s draft model and even a modest acceptance rate (50-75%), speculative decoding should yield significant speedup over the 3 t/s baseline. The math:
Target alone: ~3 t/s
Draft: 35 t/s, generating 5-16 draft tokens per verification
Expected with 50% acceptance: ~6-12 t/s (2-4x speedup)
Instead, the draft model runs at ~0.014 t/s when the target model is loaded, making spec decoding counterproductive.
Analysis
Not a memory issue
Total model buffers: ~30.3 GB on Vulkan0, well within 100 GB budget
No OOM, no swapping, no mlock failures
Both models load successfully and offload all layers to GPU
Not a context size issue
Both models use 8192 context (explicitly set, verified no 256K leak)
Draft model uses the same context size standalone vs paired
Likely root cause: Vulkan queue serialization
On UMA with Mesa/RADV, there appears to be a single Vulkan compute queue. When two models' compute graphs are submitted:
Draft model graph submission must wait for target model graph to complete
Target model verification must wait for draft model graph to complete
Each context switch between the two models' Vulkan pipelines flushes L2 cache and potentially invalidates the compute state
This serialization makes the draft model's forward pass wait for the entire target model forward pass to complete, destroying the pipelining that makes speculative decoding effective.
The fact that CPU draft (ngl=0) is also slow (1.8 t/s) when the target is on GPU suggests the bottleneck is in the synchronization/barrier between the two models, not in compute throughput.
Speculative decoding with draft model: extreme slowdown on Vulkan (UMA iGPU) when both models on same device
Describe the bug
When using draft-model speculative decoding on the Vulkan backend with both models loaded on the same GPU, the draft model's per-token generation time increases by ~100,000x compared to running standalone. This makes speculative decoding completely ineffective — the target model with draft is no faster (or slower) than without.
The same hardware runs the draft model at 33-35 t/s when it's the only model loaded. When the target model is also loaded on the same Vulkan device, draft generation slows to effectively zero.
Hardware
bios_size)This is a unified memory architecture (UMA) — the GPU and CPU share the same physical RAM. There is no discrete VRAM.
Models
Both models from the same family (same tokenizer, same architecture). Total GPU memory: ~30.3 GB model buffers on Vulkan0 + ~2.3 GB on Vulkan_Host. Well within the 100 GB shared RAM budget.
Build
llama-b9114-bin-ubuntu-vulkan-x64(pre-built release from GitHub)Steps to Reproduce
1. Draft model standalone (no target) — works great
Benchmarked via chat completions API (256 output tokens):
2. Target model alone (no draft) — expected baseline
3. Target + draft model (speculative decoding) — broken
dur(g)for draft model evaluation: ~43,000-73,000 ms (should be ~30ms at 35 t/s)4. CPU draft fallback (ngl=0) — also broken
Same as #3 but with
--spec-draft-ngl 0:Expected Behavior
With a 35 t/s draft model and even a modest acceptance rate (50-75%), speculative decoding should yield significant speedup over the 3 t/s baseline. The math:
Instead, the draft model runs at ~0.014 t/s when the target model is loaded, making spec decoding counterproductive.
Analysis
Not a memory issue
Not a context size issue
Likely root cause: Vulkan queue serialization
On UMA with Mesa/RADV, there appears to be a single Vulkan compute queue. When two models' compute graphs are submitted:
This serialization makes the draft model's forward pass wait for the entire target model forward pass to complete, destroying the pipelining that makes speculative decoding effective.
The fact that CPU draft (ngl=0) is also slow (1.8 t/s) when the target is on GPU suggests the bottleneck is in the synchronization/barrier between the two models, not in compute throughput.
Related issues
seq_rmfor speculative decoding not implemented for Vulkan. This is a dependency for MTP on Vulkan.Proposed Investigation