Skip to content

prism-v6: dspark Path A, converge on upstream dflash with log-SNR conditioning and drafter-own embeddings - #114

Closed
bri-prism wants to merge 1 commit into
prism-v6from
prism-v6-dspark-dflash
Closed

bri-prism wants to merge 1 commit into
prism-v6from
prism-v6-dspark-dflash

Conversation

@bri-prism

@bri-prism bri-prism commented Aug 11, 2026

Copy link
Copy Markdown

What

Path A of the dspark re-port: instead of re-porting our standalone dspark arch, converge on upstream's merged dflash implementation and re-apply the two drafter-side deltas it lacks.

  1. GIDD log-SNR conditioning (LogSnrEmbed). GIDD-trained drafters ship a log_snr_embed module: a sinusoidal featurization of a per-position log-SNR value through a 2-layer SiLU MLP, added to the draft noise embedding before the backbone (anchor position of each block at max_log_snr, masked positions at min_log_snr). The feature matrix is a pure function of quantities known at graph-build time, so it is precomputed host-side and staged through a new llm_graph_input_dspark_logsnr input. New optional metadata dflash.log_snr_conditioning plus dflash.min_log_snr/max_log_snr (required and validated once the flag is set); new tensors log_snr_fc1/fc2.{weight,bias}, required when the flag is set so a broken conversion fails loudly instead of silently running unconditioned.
  2. Optional drafter-own token_embd/output. Loaded as TENSOR_NOT_REQUIRED; the decoder graph already prefers model-own tensors and only borrows the target's via ctx_other when absent. Carrying the drafter's own full-precision embeddings and head protects accept rate when the target is heavily quantized, and lets such drafters initialize without ctx_other during memory fitting.

Drafters without either feature convert and load exactly as before.

Why

Keeping a standalone arch means carrying a parallel implementation of the same math forever. Upstream's dflash is in-graph, multi-seq, and block-size-sweepable; measured head-to-heads showed our accept advantage came from these two drafter-side deltas, not the algorithm, so this re-applies just the deltas.

How verified

  • Builds clean; loader accepts a converted GIDD drafter (79 tensors including the 4 log_snr tensors and own embd/head) and rejects one whose metadata flag is set without the tensors
  • End-to-end llama-speculative-simple --spec-type draft-dspark run on Metal: graph builds, spec loop executes, coherent output
  • Accept-rate validation (llama-server probe, M5 Pro, GIDD drafter x binary Q1_0 target, greedy): 51.7% accept without conditioning (upstream-equivalent stripped drafter) vs 82.6% accept, mean len 3.43 with log-SNR conditioning active. An embd-less conditioned variant scores the identical 82.6%, so the accept gain is entirely log-SNR. Upstream master measures 41.6% with the stripped drafter on H100, bit-identical at the DSpark merge commit and current master: no upstream regression, and the base path in this branch is healthy (stripped drafter scores the same 51.7% here as on the prism-v6 tip).
  • Do NOT evaluate this with llama-speculative-simple: it never sets ctx_other on the draft context, so embd-less drafters segfault and embd-carrying drafters silently draft without target features (2-6% accept). Use llama-server or the framework path. Details on the fork status board.

Rebased onto prism-v6 tip. Remaining follow-ups tracked on the status board: gguf-py/HF-converter mapping for fresh checkpoints, window-fix fold-in, CUDA speedup numbers.

@khosravipasha
khosravipasha force-pushed the prism-v6-dspark-dflash branch from 0d0265c to ab81cb6 Compare August 11, 2026 01:39
@bri-prism
bri-prism marked this pull request as ready for review August 11, 2026 03:35
Two drafter-side deltas our fork's standalone dspark arch carried, re-applied
on the upstream dflash implementation (Path A of the dspark re-port):

1. GIDD log-SNR conditioning (LogSnrEmbed): some GIDD-trained drafters ship a
   log_snr_embed module, a sinusoidal featurization of a per-position log-SNR
   value through a 2-layer SiLU MLP, added to the draft noise embedding before
   the backbone. Anchor position of each block at max_log_snr, masked
   positions at min_log_snr; the feature matrix is a pure function of
   quantities known at graph-build time, so it is precomputed host-side and
   staged through a new llm_graph_input_dspark_logsnr input.
   New optional metadata: dflash.log_snr_conditioning (bool) plus
   dflash.min_log_snr/max_log_snr (required, validated finite and max > min
   once the flag is set); new tensors log_snr_fc1/fc2.{weight,bias}, REQUIRED
   when the flag is set so a broken conversion fails loudly instead of
   silently running unconditioned.

2. Optional drafter-own token_embd/output: loaded as TENSOR_NOT_REQUIRED; the
   decoder graph already prefers model-own tensors and only borrows the
   target's via ctx_other when absent. Carrying the drafter's own full-precision
   embeddings/head protects accept rate when the target is heavily quantized,
   and makes the drafter loadable without ctx_other during memory fitting.

Drafters without either feature convert and load exactly as before.
@bri-prism
bri-prism force-pushed the prism-v6-dspark-dflash branch from ab81cb6 to 2746240 Compare August 11, 2026 04:06
@bri-prism

Copy link
Copy Markdown
Author

Closing this. Three reasons, and the work is not being abandoned:

The pushed code on this branch does not work. Measured on 2026-08-19 with llama-server accept probes: acceptance collapsed to 0.4 to 2.4 percent on every backend (H100 CUDA target with CUDA drafter, the same with a CPU drafter, all-CPU, and M5 Metal), against the 82.6 percent that was recorded on 8/11. The collapse is backend independent and the signature is a drafter that is not conditioned by target features. The branch tip has not moved since 2026-08-11 04:06, so the 82.6 percent run cannot have been this code: it almost certainly covered a session worktree with uncommitted changes that was later deleted. Worth stating plainly that CI being green says nothing here, because nothing in CI exercises the accept rate.

The base branch is also gone. This targets prism-v6, which the prism-v7 README now marks as a stale mid-migration snapshot that should not be built from.

The diff itself is small and worth keeping: 151 added lines, no deletions, three GGUF keys, two tensors and a graph input class, and prism-v7 already carries src/models/dflash.cpp for it to attach to. So the replacement will be a port of this content onto prism-v7, opened once accept is re-established rather than before.

Suspects for the lost delta, in order: the target hidden-layer extraction indices (n_extract=5 wiring against the drafter's trained target_layer_ids), the feature staging order into the injected KV, and the +1 shift and anchor-row convention from the converter. There is a working log-SNR implementation to diff against in the private fork for reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant