diff --git a/common/speculative.cpp b/common/speculative.cpp index 01c7ee41b87..bd34c27e545 100644 --- a/common/speculative.cpp +++ b/common/speculative.cpp @@ -1096,6 +1096,16 @@ struct common_speculative_impl_draft_dflash : public common_speculative_impl { const int32_t n_ubatch = (int32_t) llama_n_ubatch(ctx_dft); + // The target context may advance over a vision chunk using positions that the + // independent DFlash context cannot reproduce exactly. Keep the draft in its + // own consecutive position space so a later decode always satisfies the + // one-axis RoPE invariant (Y = X + 1). + auto * mem_dft = llama_get_memory(ctx_dft); + std::vector dnext(n_seq, 0); + for (llama_seq_id seq_id = 0; seq_id < (llama_seq_id) n_seq; ++seq_id) { + dnext[seq_id] = llama_memory_seq_pos_max(mem_dft, seq_id) + 1; + } + // Flatten token-wise encoder work into shared chunks while preserving each row's position and sequence. for (int32_t offset = 0; offset < n_tokens; offset += n_ubatch) { const int32_t n_chunk = std::min(n_ubatch, n_tokens - offset); @@ -1139,7 +1149,7 @@ struct common_speculative_impl_draft_dflash : public common_speculative_impl { GGML_ASSERT(batch_in.n_seq_id[j] == 1); const llama_seq_id seq_id = batch_in.seq_id[j][0]; GGML_ASSERT(seq_id >= 0 && seq_id < (llama_seq_id) n_seq); - batch_inject.pos[i] = batch_in.pos[j]; + batch_inject.pos[i] = dnext[seq_id]++; batch_inject.n_seq_id[i] = 1; batch_inject.seq_id[i][0] = seq_id; batch_inject.logits[i] = false; @@ -1163,6 +1173,7 @@ struct common_speculative_impl_draft_dflash : public common_speculative_impl { common_batch_clear(batch); + auto * mem_dft = llama_get_memory(ctx_dft); // build one batch holding every drafting sequence's noise block into a single decode) // record where each block starts and its size std::vector i_block_beg(n_seq, -1); @@ -1176,7 +1187,7 @@ struct common_speculative_impl_draft_dflash : public common_speculative_impl { common_sampler_reset(smpls[seq_id].get()); - const int32_t n = (int32_t) dp.n_past; + const int32_t n = llama_memory_seq_pos_max(mem_dft, seq_id) + 1; const int32_t n_draft = params.n_max;