Skip to content

feat: Expose Multi-Sequence Speculative Decoding & MTP to Public C API - #27788

Open
zsogitbe wants to merge 1 commit into
ggml-org:masterfrom
zsogitbe:SpeculativeDecodingLLamaSharp
Open

feat: Expose Multi-Sequence Speculative Decoding & MTP to Public C API#27788
zsogitbe wants to merge 1 commit into
ggml-org:masterfrom
zsogitbe:SpeculativeDecodingLLamaSharp

Conversation

@zsogitbe

@zsogitbe zsogitbe commented Aug 27, 2026

Copy link
Copy Markdown

Context: I am submitting this on behalf of the LLamaSharp maintainer team (cc @martindevans). We needed a way to cleanly expose speculative decoding and MTP to our C# users without bloating the upstream core. This standalone C API has been heavily battle-tested across both C++ and C# environments.

Overview

This PR introduces a standalone, dependency-free C API for multi-sequence speculative decoding and Multi-Token Prediction (MTP). It extracts the core speculative execution loop from the internal common/speculative.cpp utilities into a public-facing implementation (src/llama-speculative.cpp). This enables downstream bindings (such as llama-cpp-python, LLamaSharp, etc.) to easily integrate draft-simple and Draft-MTP capabilities via native pointers, without needing to recreate complex draft/verify loops or context routing mechanics.

Additional information

Key Architectural Changes

  • Public C API (include/llama.h): Introduced llama_speculative_init, llama_speculative_decode, llama_speculative_free, and the llama_speculative_result struct.
  • MTP Staging Integration: Exposed llama_set_embeddings_nextn and llama_get_embeddings_nextn_ith to the public header. These are strictly required to route hidden states across MTP projection heads for architectures like DeepSeek-R1 and Qwen.
  • Standalone Engine (src/llama-speculative.cpp): Implemented a core multi-sequence engine relying solely on llama.h and the C++ standard library, keeping the footprint minimal and avoiding common dependencies.
  • Continuous Batching: Dynamically tracks batch->n_seq_id to draft and verify multiple independent sequences concurrently, mapping accepted tokens back to their origin sequence ID.
  • M-RoPE / RNN Safe Rollback: Engineered an unconditional byte-level llama_state_seq backup mechanism prior to verification. If a sequence is rejected, the engine performs a hard memory wipe and transparent re-decodes accepted tokens. This specifically prevents fatal X < Y M-RoPE position collision crashes on hybrid recurrent architectures.
  • Verification Alignment: Ensures the sampled base token is explicitly prepended to the verification batch so the target model evaluates draft tokens with perfect context alignment.

Validation

  • Added tests/test-speculative.cpp and integrated it into CMakeLists.txt using the test-download-model fixture.
  • The test uses a self-speculation approach (where target and draft contexts share the same model) to validate decoding loops, cache rollbacks, sequence mapping, and state recovery in CI, requiring zero multi-model external dependencies.
  • Cross-Ecosystem Testing: (Note: This PR is paired with a companion PR in LLamaSharp feat: Native Speculative Decoding & MTP (Multi-Token Prediction) - #1431. The API and underlying engine have been exhaustively tested across both C++ and C# environments. This includes the native CI test provided here, alongside extensive managed C# unit tests validating multi-sequence multiplexing, KV cache deduplication, and real-world interactive Tokens-Per-Second (TPS) benchmarks.)

Requirements

  • I have read and agree with the contributing guidelines
  • AI usage disclosure: YES - I used AI assistants to help brainstorm architectural approaches, assist with the C++ implementation, and structure the PR description. However, all testing, benchmarking, CI validation, and cross-ecosystem integration (C++/C#) were conducted manually, and I take full responsibility for the accuracy and maintenance of this code.

ANNEX: Model Selection & Evaluation

1. Model Compatibility & Selection Rules

  • Dual-Model Speculation: The target and draft models must share the exact same tokenizer architecture and vocabulary size to prevent immediate cache desynchronization crashes. Crucially, the larger the target model and the smaller/faster the draft model, the higher the resulting speedup.

  • Multi-Token Prediction (MTP): This requires a single model with pre-trained speculative projection layers (nextn_predict_layers >= 1). The more draft heads the model has, the higher the potential speedup, as it can verify more tokens per native API call without context-switching overhead. The draft budget must match the available heads.


2. Real-World Benchmark Examples

Draft-Simple (Expected Speedup)
Pairing Meta-Llama-3-8B-Instruct-Q8_0.gguf (Target) with Llama-3.2-1B-Instruct-Q4_0.gguf (Draft) yielded a 1.26x speedup (+25.7%). Even on a fast GPU, the 1B draft model was lightweight enough to outpace the compute overhead of the 8B target.

MTP Speculation (Hardware Slowdown)
Running Qwen3.5-4B-MTP-Q4_K_M.gguf (1 MTP head) resulted in a 0.47x slowdown (-53.2%). Because the 4B base model is computed incredibly fast on high-end hardware, the API overhead and CUDA graph launch latency of evaluating the MTP head completely overshadowed the memory bandwidth savings. To achieve a speedup instead, you must use a much larger model (like 14B or 32B) where the GPU's memory bandwidth becomes a true bottleneck as it fetches massive weight matrices from VRAM for every single token. Alternatively, using an MTP model with multiple prediction heads allows you to verify several tokens in a single API roundtrip, making the overhead worthwhile.


3. Hardware & Workload Dynamics

  • 100% VRAM Offloading: Both models (or the full MTP model) must fit entirely within GPU VRAM. If layers spill over to the CPU, parallel batch verification turns into serialized matrix multiplication, causing a severe net slowdown.

  • The Size Threshold: Speculative decoding is an optimization for memory-bandwidth-bound workloads. Speedups reliably appear on mid-to-large models (8B, 14B, 32B, 70B) where reading massive weight matrices per token is the actual bottleneck.

  • Task Predictability: Deterministic tasks (code completion, JSON extraction) achieve high draft acceptance rates (>70%), maximizing throughput. Creative writing and high-temperature sampling trigger frequent draft rejections, wasting compute cycles.


4. Quick Selection & Viability Matrix

Strategy Required Model Setup Minimum Target Size Ideal Workload Expected Result
Draft-Simple Target + Draft (Same Vocab & Family) >= 8B (100% VRAM) Code, JSON, Structured Tasks 1.4x – 2.2x Speedup
Draft-Simple Target + Draft (Different Vocab) Any Any Immediate Crash
MTP Single Model (nextn_predict_layers >= 1) >= 8B–14B (100% VRAM) Low-Temperature / High-Confidence 1.3x – 1.8x Speedup
Any Speculative Model partially offloaded to CPU Any Any Slowdown
Any Speculative Models <= 4B on High-End GPU <= 4B (100% VRAM) High-Entropy / Creative Prompts Slowdown

@zsogitbe
zsogitbe requested a review from ggerganov as a code owner August 27, 2026 08:15
@github-actions github-actions Bot added the testing Everything test related label Aug 27, 2026
@ggml-gh-bot

ggml-gh-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown

Hi @zsogitbe, thanks for your contribution!

Per our contribution guidelines, the automated PR checker found the following issue(s) that need your attention:

  • PR Template not respected: Please respect the template when creating a new pull request. Make sure to fill out all required sections.

Please note that maintainers reserve the right to make final decisions on PRs. If you believe there is a mistake, please comment below.

@ggml-gh-bot ggml-gh-bot Bot added the draft PR will be changed to draft by github-actions bot label Aug 27, 2026
@github-actions
github-actions Bot marked this pull request as draft August 27, 2026 08:21
@github-actions github-actions Bot removed the draft PR will be changed to draft by github-actions bot label Aug 27, 2026
@zsogitbe
zsogitbe marked this pull request as ready for review August 27, 2026 09:50
@zsogitbe

Copy link
Copy Markdown
Author
  • PR Template not respected: Please respect the template when creating a new pull request. Make sure to fill out all required sections.

I have updated the main PR description to fully comply with the required template.

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

Labels

testing Everything test related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant