[2/3] feat(dsv4): implement exact DSpark speculative decoding - #69
[2/3] feat(dsv4): implement exact DSpark speculative decoding#69calvarado2004 wants to merge 3 commits into
Conversation
Shard MLA heads, vocabulary, shared experts, and routed FP4 expert banks across TP ranks. Give every shard independent storage, size collectives for skewed expert loading, partition CPU workers, and avoid redundant checkpoint reads. This is the foundation that makes DeepSeek-V4-Flash fit and start reliably on 4x RTX A4000.
Load the checkpoint DSpark blocks and heads, capture target features, maintain draft KV, run non-causal block drafting, verify candidate prefixes, and integrate multi-token request advancement. Use standard p/q rejection sampling for temperature-1 requests and preserve DSV4 compressor state across rejected tails.
Correct target-feature addressing, per-row rotary context writes, target-layer taps, GPU affinity and NUMA placement, speculative page release, and drafter residency. Route short verification blocks through FreeToken hybrid CPU/GPU MoE execution, and harden the TP service lifecycle and startup diagnostics.
|
Flagging one thing here rather than only on #71, since this is the PR that introduces the file.
|
|
Measured this on 2× RTX 6000 Ada + 2× Xeon Gold 6526Y,
~8% slower at a 42% acceptance rate. Why I think it loses here specifically. This deployment is bound by expert traffic over PCIe, not by per-step latency. Speculation trades more work per step for fewer steps, but with offloaded experts "more tokens per step" means more expert traffic per step — so it pushes on the exact resource that is already the constraint. Two compounding effects:
That is not an argument against the PR. On a machine where the expert pool is resident (or nearly so) and decode is latency-bound rather than bandwidth-bound, the same 42% acceptance should pay off — it is the offload regime specifically that inverts it. Worth noting in the docs, since If you have an acceptance-rate/step-time breakdown for a resident-expert configuration, that would make the tradeoff legible. And if there is a knob for block size, a smaller block would fetch fewer experts per verify and might land better under offload — I did not see one exposed. Merged cleanly on top of #70 with no conflicts against my CPU MoE work. No test regressions attributable to it. |
|
Thank you for validating both correctness and the negative performance result. I agree with the diagnosis: at 42% proposal acceptance, exact verification expands the offloaded expert working set without producing enough accepted prefix to amortize it. That is a real losing regime, not something we should hide behind the aggregate A4000 result. The fixed five-token block in this PR is deliberate: #69 establishes the exact DSpark sampling and rollback semantics first. #71 adds the hardware-measured width choice over 0–5 proposals, so it can decline or shorten speculation when the measured Our workload split supports your result:
I agree the expected-regime note should be explicit: exactness does not imply a workload-independent speedup. Resident/hybrid expert placement and high prefix survival are favorable; offload-dominated verification and low survival can lose. The proposal acceptance, selected width, draft cost, and verification cost should be visible together so users can tell which regime they are in. On NUMA, the approaches are complementary. The current intent is rank binding before expert-bank allocation, allowing loader first-touch to follow that affinity. Explicit Thanks for running the full stack on a materially different topology. This is exactly the kind of result needed to define the boundary of the implementation honestly. |
|
Follow-up from the DSpark TP>1 hybrid CPU+GPU integration work in #71. First, thanks again for the pure-offload measurements and for calling out the autoregressive dependency. We took that result seriously. Our measurements suggest that it is important to separate two regimes:
On our 4x GPU + dual-NUMA workstation, after adopting Gabriel Devenyi's fused HC inverse-RMS improvement and retaining the exact speculative acceptance/rejection semantics, the current isolated branch produced:
The reprofile is also useful: the old symmetric NCCL path accounted for 878.0 ms / 92.1% of CUDA time over 87 calls. With direct standard NCCL, those same 87 calls were 27.2 ms / 15.8%; the new largest kernel category is repeated expert-cache index copying at 65.9 ms / 38.3%. That moves the next optimization target to the paper's hybrid fetch fraction/q* balance, rather than removing exact verification or assuming more CPU work is free. So our proposed direction remains: keep #69's findings as the warning against universal pure-offload claims, keep exact probabilistic verification and block/rejection behavior, and let #71 adapt speculative width/fetch policy to the measured target curve. The repeated-token issue we saw during integration was our shared detokenizer state regression, not caused by this PR, and is fixed in the current #71 head. Detailed integration measurements: #71 (comment) |
Outcome
FreeToken can now load the DSpark drafter shipped inside
DeepSeek-V4-Flash-0731, generate its five-token proposal block, verify that block with the TP target, and commit or reject it without changing the target model's output distribution.This is the correctness and operational milestone: it connects the checkpoint architecture to FreeToken's scheduler, KV/SWA pools, recurrent compressor state, hybrid CPU/GPU MoE backend, TP collectives, OpenAI response path, and service lifecycle. PR 3 adds hardware-aware adaptive width selection and removes remaining sampler transfers.
Stack and review boundary
This is PR 2 of 3 and depends on PR 1 (
pr/dsv4-tp-runtime). GitHub will show the TP foundation until PR 1 merges; the new review delta here is:423edd1d42be9bDelta from PR 1: 45 files, 4,466 additions, 79 deletions.
Design references
This implementation follows, rather than reinterprets:
The checkpoint remains authoritative for
gamma, the noise token, draft layer count, Markov rank, target feature layers, and all tensor dimensions.End-to-end speculative cycle
Checkpoint-faithful DSpark architecture
mtp.*, continuing the target's layer-ID space so target and draft experts share one cache address space without collision.kconditions on proposalk-1; the first proposal conditions on the anchor.qand confidence scores. Keeping only argmax tokens would make correct sampled verification impossible.The trained maximum is
gamma=5. This PR does not manufacture a longer block that the checkpoint never learned.Exact decoding semantics
The implementation supports both greedy and probabilistic requests.
Greedy
Accept a contiguous prefix while proposal tokens match the target argmax. Stop at the first disagreement and emit the target token already computed at that position. A later accidental match cannot be accepted after an earlier rejection.
Probabilistic
Both target
pand drafterqare formed after applying the request's temperature, top-p, and top-k policy. For each proposed tokenx:At the first rejection, sample the replacement token from normalized:
If the complete proposal prefix survives, sample the bonus token from the target's next-position distribution. This is standard rejection sampling: the emitted sequence remains distributed exactly as target-only decoding. An argmax comparison for a sampled request would be faster but biased, so it is not used.
State ownership and rollback
A verify writes speculative state before acceptance is known. Every state owner therefore has an explicit commit/release rule:
The carry journal is required because several speculative positions may share one 128-token recurrent ring page. Releasing a page is insufficient when the rejected row overwrote state inside a page that an accepted row still owns.
Disconnect and abort paths use the same cleanup contracts, so a client that disappears during verification cannot leak speculative pages until process teardown.
FreeToken hybrid execution
A target verify contains only
anchor + gammarows per request. Treating it as bulk prefill would stream whole expert layers and erase the value of speculation. It instead uses the short-decode hybrid path:The split follows FreeToken Eq. 4 using measured overlapping bandwidth, not a hand-tuned expert count. The validation profile resolved to approximately 28% PCIe fetch / 72% CPU computation.
Draft MoE layers stay on the GPU/cache path because the draft is a serial dependency of every cycle; assigning those layers to the CPU pool would put the slowest resource before every target verify.
Serving and operational work
The manager treats
ready to serveas readiness; an early HTTP bind is not considered ready while the expert banks are still loading.Suggested review order
deepseek_v4/dspark.py,args.py,weight.pymtp.*mapping, anchor/noise inputs, target taps, Markov conditioningmodel.py,attention.py,compress.py, sparse backendsdspark.py,engine.pyp/qtest, residual recovery, target bonusrollback.py, scheduler/cache and KV/SWA poolsoffload_cache.py,cpu_executor.py,utils/numa.pyutils/banner.py,scripts/freetoken-dsv4.shValidation
Focused coverage includes:
p/qdistributions;The completed stack passes on the TP4 validation server:
Runtime validation uses temperature-1 probabilistic generation, not only a greedy diagnostic path.
Scope and limitations
gamma=5in this milestone. Hardware-aware prefix admission is isolated in PR 3.