From c69f0e8cc603ac5c68b0aab1b84b26db9a1e9af2 Mon Sep 17 00:00:00 2001 From: Laurent Zuijdwijk Date: Sun, 6 Sep 2026 15:17:15 +0100 Subject: [PATCH] speculative : give MTP targets their recurrent rollback slots back f169e0b7d dropped DRAFT_MTP from need_n_rs_seq(), so an MTP target context is created with n_rs_seq = 0 and every partially accepted draft goes through the checkpoint restore path: restore the state, then decode the accepted tokens a second time as a replay batch. On Qwen3.8-27B that is a second target forward pass on most steps (90 draft decodes for 48 accepted steps in a verbose run, against 62 for 62 on mainline). Put MTP back on the list, as upstream has it. The target then rolls the recurrent state back in place and the replay disappears. Cost: the recurrent state holds n_max extra slots (150 MiB -> 750 MiB on this model). Qwen3.8-27B UD-Q4_K_XL, Vulkan (RADV, Mesa 26.1.7), MTP n_max 4, decode tok/s, 3 runs: 9.6/9.8/9.9 on master -> 12.0/12.2/12.0 with this change; with GGML_VK_MMV_NO_SPLIT=1 on top, 19.9/20.0/20.0, matching ggml-org master (19.7/19.7/20.2). Fixes #25 together with the mat-vec chunking change. Assisted-by: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01LTnaB4ucGc5vkzctYns4Nq --- common/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/common.h b/common/common.h index 23fc54fedb81..431424304011 100644 --- a/common/common.h +++ b/common/common.h @@ -434,7 +434,7 @@ struct common_params_speculative { } uint32_t need_n_rs_seq() const { bool needs_rs_seq = std::any_of(types.begin(), types.end(), [&](auto t) { - return t == COMMON_SPECULATIVE_TYPE_DRAFT_EAGLE3 || t == COMMON_SPECULATIVE_TYPE_DRAFT_DFLASH || t == COMMON_SPECULATIVE_TYPE_DRAFT_DSPARK; + return t == COMMON_SPECULATIVE_TYPE_DRAFT_MTP || t == COMMON_SPECULATIVE_TYPE_DRAFT_EAGLE3 || t == COMMON_SPECULATIVE_TYPE_DRAFT_DFLASH || t == COMMON_SPECULATIVE_TYPE_DRAFT_DSPARK; }); return needs_rs_seq ? draft.n_max : 0u;