Skip to content

Navigation Menu

Sign in
Sign up

Latest commit

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

train-dspark-draft-models

Train a DSpark draft model for speculative decoding, with Qwen/Qwen3-0.6B as the verifier. Two notebooks do the training job in two ways — offline and online — and differ only in where the verifier's hidden states come from. A third notebook evaluates the drafter that comes out.

A drafter guesses several tokens ahead, the verifier checks them in one forward pass and keeps what it agrees with — same output, faster. DSpark drafts a whole block at a time and conditions on the verifier's hidden states, which is why a vLLM server runs during training. Built on vllm-project/speculators.

Contents

What's in here

.
├── notebooks/
│ ├── [offline] train-dspark-drafter-qwen-3-0.6b.ipynb
│ ├── [online] train-dspark-drafter-qwen-3-0.6b.ipynb
│ └── evaluate-dspark-qwen-3-0.6b.ipynb
├── LICENSE
└── README.md

Everything runs inside the notebooks — there is no package to install from this repo, and speculators is cloned by each notebook at run time.

Choosing a training mode

speculators can source hidden states three ways — online (fetched from a live vLLM server on demand and discarded), offline (all pre-generated to disk before training), and hybrid (generated during epoch 0, cached, reused). These notebooks cover the first two.

Both were tested on Kaggle with ×ばつ NVIDIA T4, and the table describes that setup. Data generation uses both T4s either way; the modes diverge once training starts.

offline online
Hidden states extracted up front into ./output/hidden_states, read via --hidden-states-path fetched from the endpoint per batch (--on-missing generate --on-generate delete)
vLLM server shut down before training starts must stay up for the entire training run
Training both T4s (CUDA_VISIBLE_DEVICES=0,1, --nproc_per_node 2) GPU 1 only (--nproc_per_node 1) — GPU 0 is hosting the verifier
Runs on 1 GPU? yes not really — the server would have to share the GPU with the trainer
Cost one extra extraction pass, and a lot of disk no disk overhead, but the verifier occupies a GPU for the whole run
Samples 1200 1600
Wall clock (×ばつ T4) 5 h 53 min (1200 samples) 8 h 54 min (1600 samples)

Offline is strongly recommended if you have a single GPU — it materializes the hidden states, frees the GPU, and then gives the whole thing to training, whereas online has the server and the trainer competing for the same memory the entire run. With two or more GPUs both work: offline still trains twice as wide, so pick online mainly when disk, not GPU count, is the tighter constraint.

The wall-clock row is whole-notebook time — clone to Hub upload — at each notebook's own sample count, so it is not a clean head-to-head. The three-hour gap runs the same direction as the recommendation anyway: offline finishes sooner despite paying for an extra extraction pass, because training gets both GPUs. Runtime is roughly linear in the sample count, so scale these figures with the knob below.

Run it

Prerequisites: vllm>=0.22.0, a GPU (two if you want the online notebook), and a Hugging Face write token for the upload step. Everything else installs from inside the notebooks.

1. Train a drafter — pick one

[offline] train-dspark-drafter-qwen-3-0.6b.ipynb

clone speculators → regenerate + tokenize data → serve the verifier → extract hidden states → stop the server → train on both GPUs → push to yosefw/Qwen3-0.6B-DSpark-v2.

[online] train-dspark-drafter-qwen-3-0.6b.ipynb

clone speculators → regenerate + tokenize data → serve the verifier → train against it live → push to yosefw/Qwen3-0.6B-DSpark.

Both write output/checkpoints/checkpoint_best and upload it to the Hub. Budget for a long session: end to end on ×ばつ T4 the offline notebook took 5 h 53 min and the online one 8 h 54 min — both fit a 12 h Kaggle session, neither by a comfortable margin. The sample count below is the lever if you need them shorter.

The one knob that matters is the sample count, and it appears in more than one place: --limit on response regeneration and --max-samples on prepare_data.py must always move together (offline has a third one to match, on data_generation_offline.py). The defaults are 1200 offline and 1600 online; drop them to ~200 to smoke-test the pipeline, and raise them well beyond the defaults for a drafter you actually plan to deploy.

2. Evaluate it

evaluate-dspark-qwen-3-0.6b.ipynb

clone speculators → serve the drafter in vLLM, which pulls in its verifier automatically → evaluate.py throughput → acceptance metrics in acceptance.csv. Its sweep subcommand runs the full performance benchmark instead, across all 9 RedHatAI/speculator_benchmarks subsets.

Point it at either the Hub id or the local checkpoint_best path from step 1. Takes about 40 min on ×ばつ T4, most of it model download and server startup.

Trained models

The drafters these notebooks produced, on the Hugging Face Hub:

Model Notebook Verifier
yosefw/Qwen3-0.6B-DSpark-v2 offline, 1200 samples Qwen/Qwen3-0.6B
yosefw/Qwen3-0.6B-DSpark online, 1600 samples Qwen/Qwen3-0.6B

Both are trained on small sample counts, so treat them as pipeline demonstrations rather than deployment-ready drafters.

Evaluation

Per-subset results for yosefw/Qwen3-0.6B-DSpark (the online-mode drafter, trained on 1600 samples), produced by evaluate-dspark-qwen-3-0.6b.ipynbevaluate.py throughput against a vLLM server running the drafter on ×ばつ T4:

subset num_drafts num_draft_tokens num_accepted_tokens acceptance_length acceptance_at_pos_0 acceptance_at_pos_1 acceptance_at_pos_2 acceptance_at_pos_3
HumanEval 225107 900428 196043 1.8709 0.2504 0.1168 0.0501 0.0204
math_reasoning 59956 239824 58168 1.9702 0.2673 0.1351 0.0647 0.0281
qa 20925 83700 16763 1.8011 0.2681 0.1258 0.0396 0.0188
question 56063 224252 44305 1.7903 0.2753 0.1265 0.0543 0.0217
rag 22824 91296 14539 1.637 0.2114 0.0898 0.039 0.0158
summarization 20684 82736 10040 1.4854 0.1568 0.0569 0.0224 0.009
tool_call 57005 228020 41188 1.7225 0.2036 0.0868 0.0384 0.0152
translation 21638 86552 9425 1.4356 0.1433 0.0519 0.0182 0.0063
writing 55683 222732 44927 1.8068 0.2074 0.0953 0.0435 0.019

acceptance_length is the mean number of tokens kept per verification round (1 + accepted / drafts), capped at 5 here because the drafter is trained with --block-size 4. acceptance_at_pos_N is how often the Nth drafted token in a block survives verification; it decays across the block, which is exactly what DSpark's semi-autoregressive head exists to slow down.

Acceptance is highest on math_reasoning (1.970) and HumanEval (1.871) and lowest on translation (1.436) and summarization (1.485) — the drafter does best where the verifier's next token is most predictable. Across all subsets, weighted by num_drafts, acceptance length is 1.806 (435,398 accepted tokens over 539,885 drafts).

Based on the official speculators training and evaluating performance tutorials.

License

Apache-2.0 — see LICENSE. Builds on speculators, also Apache-2.0.

About

Code to train and evaluate DSpark draft models for speculative decoding using the speculators library and vllm

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

AltStyle によって変換されたページ (->オリジナル) /