use super::*;
pub(super) fn bootstrap_seq(
model: &dyn Model,
a: &mut ActiveSeq,
sched: &crate::scheduler::sched_ctx::SchedCtx,
num_drafts: usize,
ladder_nd: usize,
verify_ctx: &crate::scheduler::logit_processors::LogitsContext,
dflash_verify_raw_argmax: bool,
) {
if dflash_verify_raw_argmax
&& !sched.levers.dflash_seam_serial
&& crate::scheduler::adaptive_spec::spec_allowed(a, sched)
{
let eff = if a.grammar_state.is_some() {
1
} else {
num_drafts
};
let _gmask = mtp_grammar_mask_for(a);
match model.run_mtp_propose_multi(
a.last_token,
a.seq.seq_len,
eff,
&mut a.seq,
0,
_gmask.as_deref(),
) {
Ok(init) if !init.is_empty() => {
if eff >= 3 && init.len() >= 3 {
step_verify_k4(
model,
a,
sched,
&init,
num_drafts,
verify_ctx,
dflash_verify_raw_argmax,
);
} else if eff >= 2 && init.len() >= 2 {
step_verify_k3(
model,
a,
sched,
&init,
num_drafts,
verify_ctx,
dflash_verify_raw_argmax,
);
} else {
step_verify_k2(
model,
a,
sched,
&init,
num_drafts,
verify_ctx,
dflash_verify_raw_argmax,
);
}
return;
}
Ok(_) => {
tracing::warn!(target: "met::scheduler::mtp_step", "DFlash bootstrap propose returned empty; falling back to standalone decode"
);
}
Err(e) => {
tracing::error!(target: "met::scheduler::mtp_step", "DFlash bootstrap propose: {e:#}");
}
}
}
if let Err(e) = model.ep_broadcast_cmd_for_seq(a.seq.slot_idx as u32, a.last_token) {
tracing::error!(target: "met::scheduler::mtp_step", "EP broadcast bootstrap token: {e:#}");
a.finished = true;
return;
}
let logits = match model.decode(a.last_token, &mut a.seq, 0) {
Ok(l) => l,
Err(e) => {
tracing::error!(target: "met::scheduler::mtp_step", "bootstrap decode error: {e:#}");
a.finished = true;
return;
}
};
let penalties = crate::scheduler::sample_step::penalty_params_for(
a,
crate::scheduler::sample_step::PositionKind::Verify,
0.0,
None,
Vec::new(),
sched.watchdog.min_reasoning_floor,
);
let history = crate::scheduler::sample_step::penalty_history_scope(
&a.output_tokens,
a.tool_call_end_token,
)
.to_vec();
let eos_mask = crate::scheduler::eos_hold::eos_mask_ids(a, a.output_tokens.len()).to_vec();
let tok = match sample_token_with_grammar(
model,
logits,
a.temperature,
a.top_k,
a.top_p,
&eos_mask,
a.grammar_state.as_mut(),
&penalties,
&history,
&sched.levers.sampling(),
) {
Ok(t) => t,
Err(e) => {
tracing::error!(target: "met::scheduler::mtp_step", "bootstrap sample error: {e:#}");
a.finished = true;
return;
}
};
let lp = if let Some(k) = a.top_logprobs {
extract_single_logprobs(model, logits, tok, k)
} else {
None
};
emit_token(a, tok, lp, sched);
if a.finished {
return;
}
a.last_token = tok;
crate::scheduler::adaptive_spec::tick_serial(a, sched);
let was_suspended = crate::scheduler::adaptive_spec::is_suspended(a, sched);
let will_propose = crate::scheduler::adaptive_spec::spec_allowed(a, sched);
let reprobe_resume = was_suspended && will_propose;
if sched.levers.dflash_unified_ctx
&& (dflash_verify_raw_argmax || !will_propose || reprobe_resume)
{
let base_pos = a.seq.seq_len.saturating_sub(1);
if let Err(e) = model.commit_ctx(&mut a.seq, 1, base_pos, 0) {
tracing::error!(target: "met::scheduler::mtp_step", "commit_ctx (mtp serial): {e:#}");
}
} else if !sched.levers.dflash_unified_ctx
&& sched.levers.dflash_serial_append
&& (!will_propose || reprobe_resume)
&& let Err(e) = model.dflash_serial_ctx_append(&mut a.seq)
{
tracing::error!(target: "met::scheduler::mtp_step", "dflash_serial_ctx_append: {e:#}");
}
if let Err(e) = model.save_hidden_for_mtp(0, 0) {
tracing::error!(target: "met::scheduler::mtp_step", "save_hidden_for_mtp: {e:#}");
return;
}
let _mtp_grammar_mask = mtp_grammar_mask_for(a);
let step_nd = sched
.dflash_rung
.adaptive_drafts(&a.spec_adapt.k, ladder_nd)
.map_or(ladder_nd, |k| k.max(1));
let effective_num_drafts =
crate::scheduler::spec_step::effective_drafts_under_grammar(a, step_nd);
if will_propose {
match model.run_mtp_propose_multi(
tok,
a.seq.seq_len,
effective_num_drafts,
&mut a.seq,
0,
_mtp_grammar_mask.as_deref(),
) {
Ok(drafts) if !drafts.is_empty() => {
tracing::debug!(target: "met::scheduler::mtp_step", "MTP bootstrap: tok={tok} → drafts={drafts:?}");
a.pending_drafts = drafts;
}
Ok(_) => {
tracing::warn!(target: "met::scheduler::mtp_step", "MTP propose returned empty")
}
Err(e) => {
tracing::error!(target: "met::scheduler::mtp_step", "run_mtp_propose_multi: {e:#}");
}
}
}
if let Err(e) = model.start_checkpoint_async(&mut a.seq) {
tracing::error!(target: "met::scheduler::mtp_step", "bootstrap start_checkpoint_async: {e:#}");
}
}