@@ -825,13 +825,10 @@ struct common_speculative_impl_draft_mtp : public common_speculative_impl {
825825
826826 int32_t n_embd = 0 ;
827827
828- // One MTP draft driver, three modes (flags set once in the ctor):
829- // is_mem_shared : gemma4-assistant — the draft shares the target's KV and
830- // runs every nextn layer in a single graph; the catch-up
831- // decode is skipped and all draft tokens reuse one position.
832- // chain_heads : step35 — n_mtp_layers independently-trained heads run one
833- // per step (mtp_layer_offset = k), each on its own KV.
834- // neither : single-block AR (qwen35 / qwen35moe) — one trained MTP head.
828+ // One MTP draft driver, three modes (set once in the ctor):
829+ // is_mem_shared (gemma4): shares the target KV, runs all heads in one graph.
830+ // chain_heads (step35): n_mtp_layers trained heads, one per draft step.
831+ // neither (qwen35 / qwen35moe): a single trained MTP head.
835832 int32_t n_mtp_layers = 1 ;
836833 bool is_mem_shared = false ; // gemma4
837834 bool chain_heads = false ; // derived in the ctor: n_mtp_layers > 1 && !is_mem_shared
@@ -849,8 +846,9 @@ struct common_speculative_impl_draft_mtp : public common_speculative_impl {
849846 std::vector<std::vector<float >> verify_h;
850847 std::vector<int32_t > verify_h_rows;
851848
852- // Per-seq draft length from the single-head draft() path. Currently write-only
853- // (accept() rolls back via verify_h_rows); kept pending a follow-up cleanup.
849+ // Per-seq draft length from the last draft() call, used in accept() to
850+ // roll back ctx_dft's recurrent state past the AR draft's redundant
851+ // pre-advancement before process() mirrored the verify batch.
854852 std::vector<uint16_t > last_n_drafted;
855853
856854 common_speculative_impl_draft_mtp (const common_params_speculative & params, uint32_t n_seq)
@@ -865,7 +863,6 @@ struct common_speculative_impl_draft_mtp : public common_speculative_impl {
865863 GGML_ASSERT (n_embd == llama_model_n_embd (llama_get_model (ctx_tgt)) &&
866864 " MTP input row width must match the target h_nextn width" );
867865 n_mtp_layers = std::max (1 , (int ) llama_model_n_layer_nextn (llama_get_model (ctx_dft)));
868- // note: chain_heads / n_max clamp are derived below, once is_mem_shared is known.
869866
870867 LOG_INF (" %s: adding speculative implementation 'draft-mtp'\n " , __func__);
871868 LOG_INF (" %s: - n_max=%d, n_min=%d, p_min=%.2f, n_embd=%d, backend_sampling=%d\n " , __func__, this ->params .n_max , this ->params .n_min , this ->params .p_min , n_embd, (int ) this ->params .backend_sampling );
@@ -1006,12 +1003,8 @@ struct common_speculative_impl_draft_mtp : public common_speculative_impl {
10061003
10071004 // if kv is shared with target (e.g Gemma4), then we can skip this catch-up decode
10081005 if (!is_mem_shared) {
1009- // Build the teacher-forcing batch ONCE — it is identical for every head:
1010- // tokens at their real positions, tgt nextn-embd right-shifted by one,
1011- // pending_h planted at each seq's first slot. llama_decode only reads the
1012- // batch, so the same buffer is replayed per head; only the layer offset
1013- // and the per-head KV reset differ.
10141006 common_batch_clear (batch);
1007+
10151008 for (int k = 0 ; k < n_tokens; ++k) {
10161009 common_batch_add (batch, batch_in.token [k], batch_in.pos [k], { batch_in.seq_id [k][0 ] }, 0 );
10171010 }
@@ -1025,12 +1018,18 @@ struct common_speculative_impl_draft_mtp : public common_speculative_impl {
10251018 const float * h_tgt = llama_get_embeddings_nextn (ctx_tgt);
10261019 std::memcpy (batch.embd + (size_t ) 1 * n_embd, h_tgt, row_bytes * (n_tokens-1 ));
10271020 }
1021+
1022+ // fill the pending embeddings from a previous run
1023+ auto set_h = [&](int idx, const float * h_row) {
1024+ std::memcpy (batch.embd + (size_t ) idx * n_embd, h_row, row_bytes);
1025+ };
1026+
10281027 for (llama_seq_id seq_id = 0 ; seq_id < (llama_seq_id) n_seq; ++seq_id) {
10291028 if (i_batch_beg[seq_id] < 0 ) {
10301029 continue ;
10311030 }
1032- std::memcpy (batch. embd + ( size_t ) i_batch_beg[seq_id] * n_embd,
1033- pending_h[seq_id].data (), row_bytes );
1031+
1032+ set_h (i_batch_beg[seq_id], pending_h[seq_id].data ());
10341033 }
10351034
10361035 auto * mem_dft = llama_get_memory (ctx_dft);
0 commit comments