spec-verify
Speculative-decoding verification ops for CPUs, aarch64 first, loadable
through kernels. The reference standard is the analytic law of rejection
sampling, matched to the sampling floor. Companions:
bitnet-cpu,
quant-matmul,
gguf-gemv
(linears),
cpu-attn,
decode-ops.
On a small board the decode wall is memory: every token re-reads every
weight, so one token costs the same bandwidth as many. Speculative decoding
converts that into a win by having a draft model propose K tokens and the
target verify them in a single [K+1, V] forward, which on the companion
linear kernels is several times cheaper per token than K separate decodes.
These ops are the verification step: an accepted prefix plus one correction
token, distribution-preserving, at a cost far below the forwards they gate.
600 verification rounds at K = 4 measured on a Raspberry Pi with a deliberately imperfect draft: the accepted-length histogram gives a mean of 1.84 against the analytic law's 1.86, at 33 us greedy and 117 us sampled per round on a Pi 5 (126 and 657 us on a Pi 4), far below the model forwards they gate.
Usage
import torch
from kernels import get_kernel
sv = get_kernel("phanerozoic/spec-verify", version=1, trust_remote_code=True)
# Greedy: target_probs [K+1, V] (only the argmax is read), draft_tokens [K].
n_accepted, next_token = sv.verify_greedy(target_probs, draft_tokens)
# Keep draft_tokens[:n_accepted], append next_token.
# Or drive the whole draft/verify loop:
dec = sv.SpeculativeDecoder(draft_step, target_step, k=4, greedy=True)
out = dec.generate(prompt_ids, max_new=128)
version selects the release branch; trust_remote_code is required by
kernels for publishers without the trusted-publisher mark.
API
| Symbol | Purpose |
|---|---|
verify_greedy(target_probs, draft_tokens) |
temperature-0 verify -> (n_accepted, next_token) |
accept(target_probs, draft_probs, draft_tokens, generator) |
speculative sampling -> (n_accepted, next_token) |
SpeculativeDecoder(draft_step, target_step, k, greedy, generator) |
draft/verify orchestration loop |
draft_step(prefix, k) -> (tokens, probs) and
target_step(prefix, proposed) -> target_probs [k+1, V] are user callbacks,
so any pair of models (including GGUF drafts and verifiers via the companion
kernels) composes.
Method
Two verification modes:
- Greedy (temperature 0): accept draft token
t_iwhile it equalsargmax(target_i); at the first miss emitargmax(target_i)and stop; all K matched emitargmax(target_K). Deterministic, and the emitted stream is identical to plain greedy target decoding. - Speculative sampling (Leviathan et al. / Chen et al.): accept
t_iwith probabilitymin(1, p_i(t_i) / q_i(t_i)); on rejection resample fromnorm(max(0, p_i - q_i)); all accepted samples the bonus fromp_K. Distribution-preserving when target and draft distributions are warped identically (the caller's contract). Randomness enters only through explicit uniform draws, so a fixed generator gives a fixed result.
Measured
Raspberry Pi 5 (4x Cortex-A76 2.4 GHz) and Pi 4 Model B (4x Cortex-A72 1.8 GHz), torch 2.13 CPU, V = 32000, K = 4 (and V = 128256, K = 5 for the published rows):
| op | Pi 5 | Pi 4 |
|---|---|---|
verify_greedy |
33 us | 126 us |
accept |
117 us | 657 us |
verify_greedy (V=128256, K=5) |
59 us | 140 us |
accept (V=128256, K=5) |
338 us | 754 us |
Over 600 rounds with a mismatched draft, the mean accepted length is 1.84
against the analytic sum_i acceptance^i of 1.86, where the per-token
acceptance probability sum(min(p, q)) is 0.678.
Correctness
The accepted-length distribution and its mean track the analytic law of rejection sampling to the sampling floor at 600 rounds. Probabilities need not be normalized; masses are summed exactly. Greedy verification is deterministic and reproduces plain greedy target decoding exactly.
Requirements and limits
target_probs[K+1, V]f32; foraccept,draft_probs[K, V]warped identically to the target.- x86-64 runs a scalar path; the O(V) reductions vectorize on aarch64.
- Distribution preservation depends on the caller warping both models' distributions identically.
References
Leviathan, Kalman, Matias, "Fast Inference from Transformers via Speculative Decoding" (2023); Chen et al., "Accelerating Large Language Model Decoding with Speculative Sampling" (2023).
License
Apache-2.0.
- Downloads last month
- -
- OS
- linux
- Arch
- x86_64aarch64
- Kernel Builder
- 19aaa64
