ik_llama_opt/examples
James 563b798ac9
qwen4exp: MTP (NextN) self-speculative decoding support (#2369)
* qwen4exp: MTP (NextN) self-speculative decoding support

Wires the checkpoint's 2.6B MTP head into the existing MTP speculative
framework for the qwen4exp architecture, following the deepseek4
conventions: block_count includes the NextN tail, the draft pass walks
[n_layer - nextn, n_layer) through the same layer-loop body, and the
target pass emits the pre-final-mixer wide stream as result_mtp_embd.

- hparams: read nextn_predict_layers; the tail is forced non-recurrent
  (the full-attention-interval pattern would classify it as GDN) and
  inherits the last main QSA layer's compress ratio
- loader: the tail layers and seven mtp.* entry/mixer tensors load only
  when an MTP stage is requested (TENSOR_SKIP otherwise), so nextn-
  bearing GGUFs serve normally on plain configs
- graph: MTP entry = per-reference residual_linear_shared fusion (joint
  RMS over the flattened hc*n_embd stream, shared fc_hidden per branch,
  fc_embedding added as a residual to every branch); exit reuses the
  hc_head-shaped mixer with dedicated weights; delta-net construction
  skips the draft pass (the draft context has no recurrent slots)
- llama: qwen4exp joins the MTP-capable arch allowlist and
  llama_mtp_tail_uses_layer_cache; MTP feature width is the wide stream
  (n_embd * hc_mult); the nextn pooling path gets its required
  result_embd tensor

Measured on a 125B-A6B GGUF carrying the head (RTX 5090 + 24-core Zen5
hybrid, -ncmoe 38): draft acceptance 0.93-0.99, per-position 95%/pos on
code at n_max=4; draft passes cost ~2ms wall (131-144 nodes).

* cuda: dispatch the ABS and SGN unary ops

The kernels exist in unary.cu but neither the execution switch nor
supports_op routed them, so the qwen4exp PLE gate split to the CPU
scheduler twice per forward pass once its layer is offloaded (the cost
is the round trip, not the arithmetic — noted in the port's PR text).

* refactor(model): add qwen4exp NextN mixer tensors

* fix(qwen4exp): resolve standard NextN head layouts

* qwen4exp: decline per-step spec checkpoints (PLE conv tail not covered)

The per-step checkpoint path sizes its buffers from the ssm_* hparams
alone, but qwen4exp appends the PLE n-gram convolution history to the
tail of the same recurrent state row. A rejected draft token would roll
back the delta-net state and leave the PLE tail advanced. Decline
per-step (like openPangu) so the mode resolves to the whole-slot
gpu-fallback shadow, which covers the full row.

* qwen4exp: keep legacy mtp.* files loadable without MTP

Pre-rework files carried the NextN head under fork-local mtp.* names.
Register those seven names as known-and-skipped so such files still load
for non-MTP use instead of failing tensor accounting; an MTP request
against them reports the standard missing-layout error.

* loader: summarize skipped tensors in one line (per-tensor detail moves to debug)

An unused NextN/MTP head produces 33 ignore warnings per load; collapse
to a single summary at done_getting_tensors.

* spec: fall back to generic copy when checkpoint rows resolve no backend

Partial offload leaves host-resident recurrent state rows (CUDA_Host) matching
no backend's default buffer type between graphs, so checkpoint save/restore
asserted on a null backend. Drain the scheduler once and use the generic
tensor copy for unresolvable rows; the async fast path is unchanged. Also
guards the split-save branch that previously passed a null backend unchecked.

Diagnosed, patched, and validated by @joelfarthing (round-trip exact on
-ngl 6/8, -ncmoe control unchanged).

Co-authored-by: joelfarthing <joelfarthing@users.noreply.github.com>

* qwen4exp: support separate MTP head via -md (companion pair)

Lets a plain community quant load a predictor-only GGUF as the draft, so MTP
works without re-downloading a merged file and the head can sit on GPU at
full precision while the target runs partially offloaded. Relaxes the five
sites that assumed the target carries the NextN block: predict-layer count,
optional trunk tensors for mtp-only files, hc_attn_norm trunk marker,
n_embd_out derivation, and the wide-embd export predicate, plus qwen4exp
companion pairing enforcement.

Authored by @joelfarthing, replicated by @treo (3090, full 262K context).
Known limitation: llama-quantize on a predictor-only file trips the
attention-tensor count assertion; quantize before extraction.

Co-authored-by: joelfarthing <joelfarthing@users.noreply.github.com>

* server: name the stage chain in the single-slot refusal and say the fix

* qwen4exp: condense verbose NextN comments per CONTRIBUTING.md

* qwen4exp: accept the Dzannotti NextN head layout (predictor-only)

A predictor-only (-md) file may omit blk.N.nextn.shared_head_norm and carry the
head mixer norm only in output_hc_norm (the Dzannotti convention, with the +1
baked in as the direct-multiply grouped-RMS kernel expects). Fall back to
model.hc_head_norm as the head norm in that case, gated to mtp_only files where
output_hc_* is the head's own mixer and not the trunk's. Quimmedes-style raw
(non-baked) tensors remain intentionally unsupported.

Reported by @SamuelOliveirads.

* spec: merge the deepseek4/qwen4exp wide-stream feature-width branches

Both arches return n_embd_out under the same condition; one combined branch.
Suggested by @SamuelOliveirads.

---------

Co-authored-by: joelfarthing <joelfarthing@users.noreply.github.com>
2026-09-02 18:49:42 +02:00
..
baby-llama Merge mainline - Aug 12 2024 (#17) 2024-08-12 15:14:32 +02:00
batched spec : add self speculative decoding, ngram and refactor (#1261) 2026-02-13 19:04:55 +01:00
batched-bench spec : add self speculative decoding, ngram and refactor (#1261) 2026-02-13 19:04:55 +01:00
batched.swift Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
benchmark Chores : tidy up more typos project wide (ggml directory excluded), new -ptcall alias (#2237) 2026-08-03 08:01:18 +03:00
convert-llama2c-to-ggml Chores : tidy up more typos project wide (ggml directory excluded), new -ptcall alias (#2237) 2026-08-03 08:01:18 +03:00
cvector-generator Chores : tidy up more typos project wide (ggml directory excluded), new -ptcall alias (#2237) 2026-08-03 08:01:18 +03:00
deprecation-warning Chores : Typos fixing round 3 (project wide, ggml dir included, comments and user facing msg only) (#2249) 2026-08-04 07:15:28 +03:00
embedding Chores : Typos fixing round 3 (project wide, ggml dir included, comments and user facing msg only) (#2249) 2026-08-04 07:15:28 +03:00
eval-callback eval-callback : sum over the full tensor, not just the printed slice (#2019) 2026-06-24 08:57:19 +02:00
export-lora Merge vulkan code from mainline up to commit of 6/28/2025 (#563) 2025-07-02 08:49:42 +02:00
gbnf-validator common : introduce composable PEG parser combinators for chat parsing and new jinja template engine (#1369) 2026-03-09 11:03:33 +01:00
gguf Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
gguf-hash Chores : tidy up more typos project wide (ggml directory excluded), new -ptcall alias (#2237) 2026-08-03 08:01:18 +03:00
gguf-split Chores : tidy up more typos project wide (ggml directory excluded), new -ptcall alias (#2237) 2026-08-03 08:01:18 +03:00
gritlm spec : add self speculative decoding, ngram and refactor (#1261) 2026-02-13 19:04:55 +01:00
imatrix Chores : Typos fixing round 3 (project wide, ggml dir included, comments and user facing msg only) (#2249) 2026-08-04 07:15:28 +03:00
infill spec : add self speculative decoding, ngram and refactor (#1261) 2026-02-13 19:04:55 +01:00
jeopardy `build`: rename main → llama-cli, server → llama-server, llava-cli → llama-llava-cli, etc... (#7809) 2024-06-13 00:41:52 +01:00
llama-bench Chores : tidy up more typos project wide (ggml directory excluded), new -ptcall alias (#2237) 2026-08-03 08:01:18 +03:00
llama.android Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
llama.swiftui Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
lookahead spec : add self speculative decoding, ngram and refactor (#1261) 2026-02-13 19:04:55 +01:00
lookup spec : add self speculative decoding, ngram and refactor (#1261) 2026-02-13 19:04:55 +01:00
main Dflash 2 speculative decoding (#2345) 2026-08-26 17:09:34 +02:00
main-cmake-pkg Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
mtmd GLM-5.2 vision hack (#2283) 2026-08-09 15:54:53 +02:00
parallel Chores : Typos fixing round 3 (project wide, ggml dir included, comments and user facing msg only) (#2249) 2026-08-04 07:15:28 +03:00
parser Autoparser - complete refactoring of parser architecture (#1376) 2026-04-22 10:04:13 +02:00
passkey spec : add self speculative decoding, ngram and refactor (#1261) 2026-02-13 19:04:55 +01:00
perplexity Chores : Typos fixing round 3 (project wide, ggml dir included, comments and user facing msg only) (#2249) 2026-08-04 07:15:28 +03:00
quantize Quantization fudge factors (#2361) 2026-08-27 17:35:04 +02:00
quantize-stats Chores : tidy up more typos project wide (ggml directory excluded), new -ptcall alias (#2237) 2026-08-03 08:01:18 +03:00
retrieval Chores : Typos fixing round 3 (project wide, ggml dir included, comments and user facing msg only) (#2249) 2026-08-04 07:15:28 +03:00
rpc fix(rpc): update ggml_backend_cuda_init to 3-arg signature (#2084) 2026-07-06 09:26:45 +02:00
save-load-state server: enable checkpoint for recurrent models (#1310) 2026-02-26 06:51:18 +01:00
server qwen4exp: MTP (NextN) self-speculative decoding support (#2369) 2026-09-02 18:49:42 +02:00
simple spec : add self speculative decoding, ngram and refactor (#1261) 2026-02-13 19:04:55 +01:00
spec-bench Feat speculative benchmark standard (#2208) 2026-07-30 18:38:48 +03:00
speculative Fix two speculative-decoding crashes that prevent any usage (#1760) 2026-05-09 08:36:38 +03:00
sweep-bench Fix not commented out fprintf 2026-08-08 14:37:35 +00:00
sycl Merge mainline - Aug 12 2024 (#17) 2024-08-12 15:14:32 +02:00
tokenize spec : add self speculative decoding, ngram and refactor (#1261) 2026-02-13 19:04:55 +01:00
CMakeLists.txt Feat speculative benchmark standard (#2208) 2026-07-30 18:38:48 +03:00
Miku.sh `build`: rename main → llama-cli, server → llama-server, llava-cli → llama-llava-cli, etc... (#7809) 2024-06-13 00:41:52 +01:00
base-translate.sh `build`: rename main → llama-cli, server → llama-server, llava-cli → llama-llava-cli, etc... (#7809) 2024-06-13 00:41:52 +01:00
chat-13B.bat
chat-13B.sh `build`: rename main → llama-cli, server → llama-server, llava-cli → llama-llava-cli, etc... (#7809) 2024-06-13 00:41:52 +01:00
chat-persistent.sh `build`: rename main → llama-cli, server → llama-server, llava-cli → llama-llava-cli, etc... (#7809) 2024-06-13 00:41:52 +01:00
chat-vicuna.sh `build`: rename main → llama-cli, server → llama-server, llava-cli → llama-llava-cli, etc... (#7809) 2024-06-13 00:41:52 +01:00
chat.sh `build`: rename main → llama-cli, server → llama-server, llava-cli → llama-llava-cli, etc... (#7809) 2024-06-13 00:41:52 +01:00
convert_legacy_llama.py Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
json_schema_pydantic_example.py Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
json_schema_to_grammar.py Autoparser - complete refactoring of parser architecture (#1376) 2026-04-22 10:04:13 +02:00
llama.vim llama.vim : added api key support (#5090) 2024-01-23 08:51:27 +02:00
llm.vim
pydantic_models_to_grammar.py Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
pydantic_models_to_grammar_examples.py Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
reason-act.sh `build`: rename main → llama-cli, server → llama-server, llava-cli → llama-llava-cli, etc... (#7809) 2024-06-13 00:41:52 +01:00
regex_to_grammar.py Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
server-llama2-13B.sh `build`: rename main → llama-cli, server → llama-server, llava-cli → llama-llava-cli, etc... (#7809) 2024-06-13 00:41:52 +01:00
server_embd.py Merge mainline llama.cpp (#3) 2024-07-27 07:55:01 +02:00
ts-type-to-grammar.sh JSON schema conversion: ️ faster repetitions, min/maxLength for strings, cap number length (#6555) 2024-04-12 19:43:38 +01:00