use super::{
resolve_drafter, resolve_speculation, DrafterChoice, Speculation, SpeculationPlan,
SpeculativeDrafter,
};
use crate::families::qwen::{
install_has_dflash, install_has_mtp_head, DFLASH_SERVING_BLOCK, MOE_SPECULATION_BLOCKER_MARKER,
VISION_SPECULATION_BLOCKER_MARKER,
};
use crate::speculative::DEFAULT_SPECULATION_BLOCK;
#[test]
fn auto_takes_each_drafters_own_block() {
let block_of = |d| match resolve_speculation(Speculation::Auto, d, None, true) {
Ok(SpeculationPlan::Enabled { block }) => block,
other => panic!("expected an enabled plan, got {other:?}"),
};
assert_eq!(block_of(SpeculativeDrafter::Mtp), DEFAULT_SPECULATION_BLOCK);
assert_eq!(block_of(SpeculativeDrafter::Dflash), DFLASH_SERVING_BLOCK);
assert_eq!(
DEFAULT_SPECULATION_BLOCK, DFLASH_SERVING_BLOCK,
"the serving defaults diverged; restore a discriminating assertion here"
);
}
#[test]
fn an_explicit_drafter_is_never_re_resolved() {
let missing = std::path::Path::new("/nonexistent/turbospark/install");
for named in [SpeculativeDrafter::Mtp, SpeculativeDrafter::Dflash] {
let choice = resolve_drafter(named, missing);
assert_eq!(choice.drafter, named);
assert_eq!(choice.note, None, "an explicit ask needs no explanation");
}
}
#[test]
fn an_explicit_drafter_still_records_whether_the_install_has_a_head() {
let dir = std::env::temp_dir().join(format!(
"turbospark-explicit-head-{}-{:?}",
std::process::id(),
std::thread::current().id()
));
let _ = std::fs::remove_dir_all(&dir);
turbospark_repack::build_synthetic_qwen_gdn_dense_install_with_dflash(
&dir,
512,
4,
"drafter-toy-explicit",
4,
)
.expect("synthetic dflash install");
for named in [SpeculativeDrafter::Mtp, SpeculativeDrafter::Dflash] {
let choice = resolve_drafter(named, &dir);
assert_eq!(choice.drafter, named, "the ask is still honoured");
assert_eq!(
choice.install_has_mtp_head,
Some(false),
"an explicit ask must still read the index"
);
assert_eq!(
choice.install_has_dflash,
Some(true),
"the dflash-only fixture carries one"
);
}
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn an_unreadable_index_resolves_to_the_pre_existing_default() {
let choice = resolve_drafter(
SpeculativeDrafter::Auto,
std::path::Path::new("/nonexistent/turbospark/install"),
);
assert_eq!(choice.drafter, SpeculativeDrafter::Mtp);
assert_eq!(choice.note, None);
assert_eq!(choice.install_has_mtp_head, None);
assert_eq!(choice.install_has_dflash, None);
}
#[test]
fn auto_detects_dflash_but_leaves_it_off() {
let dir = std::env::temp_dir().join(format!(
"turbospark-drafter-choice-{}-{:?}",
std::process::id(),
std::thread::current().id()
));
let _ = std::fs::remove_dir_all(&dir);
turbospark_repack::build_synthetic_qwen_gdn_dense_install_with_dflash(
&dir,
512,
4,
"drafter-toy",
4,
)
.expect("synthetic dflash install");
let index = model_io::load_resident_index(&dir.join("model_weights.bin"))
.expect("the fixture's resident index");
assert!(
install_has_dflash(&index) && !install_has_mtp_head(&index),
"the fixture must be dflash-only or it cannot see this branch"
);
let choice = resolve_drafter(SpeculativeDrafter::Auto, &dir);
assert_eq!(
choice.drafter,
SpeculativeDrafter::Mtp,
"auto must not enable dflash: it is 0.96x on prose"
);
assert_eq!(choice.install_has_mtp_head, Some(false));
let note = choice.note.expect("a detected drafter must be reported");
assert!(
note.contains("--speculative-drafter dflash"),
"the note must name the flag that runs it, got: {note}"
);
assert!(
note.contains("speculativeDrafter"),
"the note must name the C ABI option too, got: {note}"
);
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn an_install_with_both_drafters_keeps_the_mtp_head_and_says_nothing() {
let dir = std::env::temp_dir().join(format!(
"turbospark-drafter-both-{}-{:?}",
std::process::id(),
std::thread::current().id()
));
let _ = std::fs::remove_dir_all(&dir);
turbospark_repack::build_synthetic_qwen_gdn_dense_install_with_both_drafters(
&dir,
512,
4,
"drafter-toy-both",
4,
)
.expect("synthetic install with both drafters");
let index = model_io::load_resident_index(&dir.join("model_weights.bin"))
.expect("the fixture's resident index");
assert!(
install_has_dflash(&index) && install_has_mtp_head(&index),
"the fixture must carry BOTH or it cannot see this branch"
);
let choice = resolve_drafter(SpeculativeDrafter::Auto, &dir);
assert_eq!(choice.drafter, SpeculativeDrafter::Mtp);
assert_eq!(
choice.note, None,
"the MTP head is being used, so there is nothing to explain"
);
assert_eq!(choice.install_has_mtp_head, Some(true));
let _ = std::fs::remove_dir_all(&dir);
}
const NO_HEAD: &str = "this install carries no multi-token-prediction head \
(mtp.fc.weight is not in the resident index); the mlx conversion \
drops mtp.*, so stream an install that adds the official \
checkpoint's last shard (docs/MTP.md)";
const NOT_BATCHED_DTYPE: &str = "the batched verify covers INT4-affine (4) and the \
1-bit (15) / 2-bit (16) affine pair, and this install's ...q_proj.weight is dtype 5";
fn moe() -> String {
format!(
"{MOE_SPECULATION_BLOCKER_MARKER}: this install routes to 128 experts, and no \
published MoE conversion of this architecture ships a drafter this port can \
ingest (every mlx conversion drops mtp.*). The batched routed verify itself \
runs, so this is a checkpoint gap and not a missing kernel"
)
}
fn vision() -> String {
format!(
"{VISION_SPECULATION_BLOCKER_MARKER}: this runner has a vision tower, and the \
batched verify embeds every row from the token table and rotates at the raw \
position, so a speculative round past an image would attend and rotate by \
the wrong values; run text-only or disable speculation (docs/VISION.md)"
)
}
#[test]
fn a_vision_blocker_fails_hard_under_a_named_block_and_warns_under_auto() {
let err = resolve_speculation(
Speculation::Block(2),
SpeculativeDrafter::Mtp,
Some(vision()),
true,
)
.expect_err("a named block on a vision-active runner must fail");
assert!(
err.contains(VISION_SPECULATION_BLOCKER_MARKER),
"got: {err}"
);
let plan = resolve_speculation(
Speculation::Auto,
SpeculativeDrafter::Mtp,
Some(vision()),
true,
)
.expect("auto degrades to disabled rather than failing");
match plan {
SpeculationPlan::Disabled {
reason: Some(reason),
} => assert!(
reason.contains(VISION_SPECULATION_BLOCKER_MARKER),
"got: {reason}"
),
other => panic!("expected disabled-with-reason, got {other:?}"),
}
}
#[test]
fn a_named_block_fails_hard_when_it_cannot_be_served() {
let err = resolve_speculation(
Speculation::Block(2),
SpeculativeDrafter::Mtp,
Some(NO_HEAD.to_string()),
true,
)
.expect_err("a named block on a headless install must fail");
assert!(err.contains("no multi-token-prediction head"), "got: {err}");
let err = resolve_speculation(
Speculation::Block(2),
SpeculativeDrafter::Dflash,
None,
false,
)
.expect_err("a named block on a sampled block-drafter run must fail");
assert!(err.contains("not a distribution"), "got: {err}");
let plan = resolve_speculation(Speculation::Block(2), SpeculativeDrafter::Mtp, None, false)
.expect("the step drafter serves sampled runs");
assert_eq!(plan, SpeculationPlan::Enabled { block: 2 });
}
#[test]
fn auto_warns_and_continues_where_a_named_block_fails() {
let cases = [
(Some(NO_HEAD.to_string()), true, SpeculativeDrafter::Mtp),
(
Some(NOT_BATCHED_DTYPE.to_string()),
true,
SpeculativeDrafter::Mtp,
),
(Some(moe()), false, SpeculativeDrafter::Mtp),
(None, false, SpeculativeDrafter::Dflash),
];
for (blocker, deterministic, drafter) in cases {
let plan = resolve_speculation(Speculation::Auto, drafter, blocker, deterministic)
.expect("auto never fails; it declines");
match plan {
SpeculationPlan::Disabled { reason: Some(_) } => {}
other => panic!("auto must warn and continue, got {other:?}"),
}
}
}
#[test]
fn auto_speculates_when_the_install_and_the_settings_allow_it() {
let plan = resolve_speculation(Speculation::Auto, SpeculativeDrafter::Mtp, None, true)
.expect("serviceable");
assert_eq!(
plan,
SpeculationPlan::Enabled {
block: DEFAULT_SPECULATION_BLOCK
}
);
}
#[test]
fn off_is_silent_even_where_speculation_would_have_worked() {
for (blocker, deterministic) in [
(None, true),
(Some(NO_HEAD.to_string()), true),
(None, false),
(Some(NOT_BATCHED_DTYPE.to_string()), false),
] {
let plan = resolve_speculation(
Speculation::Off,
SpeculativeDrafter::Mtp,
blocker.clone(),
deterministic,
)
.expect("off never fails");
assert_eq!(
plan,
SpeculationPlan::Disabled { reason: None },
"off must stay silent at blocker={blocker:?} deterministic={deterministic}"
);
}
}
#[test]
fn a_named_block_is_honoured_rather_than_replaced_by_the_default() {
let plan = resolve_speculation(Speculation::Block(7), SpeculativeDrafter::Mtp, None, true)
.expect("serviceable");
assert_eq!(plan, SpeculationPlan::Enabled { block: 7 });
}
#[test]
fn a_noted_dflash_install_opens_with_both_drafters_off() {
use crate::families::qwen::{DflashDraftPolicy, MtpDraftPolicy};
let noted = DrafterChoice {
drafter: SpeculativeDrafter::Mtp,
install_has_mtp_head: Some(false),
install_has_dflash: Some(true),
note: Some("carries a DFlash2 drafter".to_string()),
};
for asked in [Speculation::Auto, Speculation::Block(2)] {
let policies = super::draft_policies(¬ed, asked);
assert_eq!(
policies.mtp,
MtpDraftPolicy::Off,
"a noted install must not ask the open for a head it has not got"
);
}
let plain = DrafterChoice {
drafter: SpeculativeDrafter::Mtp,
install_has_mtp_head: Some(true),
install_has_dflash: Some(false),
note: None,
};
assert_eq!(
super::draft_policies(&plain, Speculation::Block(2)).mtp,
MtpDraftPolicy::Fixed(2)
);
assert_eq!(
super::draft_policies(&plain, Speculation::Auto).mtp,
MtpDraftPolicy::Auto
);
let dflash = DrafterChoice {
drafter: SpeculativeDrafter::Dflash,
install_has_mtp_head: Some(false),
install_has_dflash: Some(true),
note: None,
};
let policies = super::draft_policies(&dflash, Speculation::Block(4));
assert_eq!(policies.mtp, MtpDraftPolicy::Off);
assert_eq!(policies.dflash, DflashDraftPolicy::Fixed(4));
}
#[test]
fn a_named_block_on_a_headless_install_lets_the_open_succeed() {
use crate::families::qwen::MtpDraftPolicy;
let headless = DrafterChoice {
drafter: SpeculativeDrafter::Mtp,
install_has_mtp_head: Some(false),
install_has_dflash: Some(false),
note: None,
};
assert_eq!(
super::draft_policies(&headless, Speculation::Block(2)).mtp,
MtpDraftPolicy::Off,
"a block on a known-headless install must not be asked of the open"
);
assert_eq!(
super::draft_policies(&headless, Speculation::Auto).mtp,
MtpDraftPolicy::Auto
);
let unknown = DrafterChoice {
drafter: SpeculativeDrafter::Mtp,
install_has_mtp_head: None,
install_has_dflash: None,
note: None,
};
assert_eq!(
super::draft_policies(&unknown, Speculation::Block(2)).mtp,
MtpDraftPolicy::Fixed(2)
);
}
#[test]
fn a_named_block_on_a_drafterless_install_lets_the_open_succeed_for_dflash_too() {
use crate::families::qwen::DflashDraftPolicy;
let choice = |install_has_dflash| DrafterChoice {
drafter: SpeculativeDrafter::Dflash,
install_has_mtp_head: Some(false),
install_has_dflash,
note: None,
};
assert_eq!(
super::draft_policies(&choice(Some(false)), Speculation::Block(2)).dflash,
DflashDraftPolicy::Off,
"a block on a known-drafterless install must not be asked of the open"
);
assert_eq!(
super::draft_policies(&choice(Some(false)), Speculation::Auto).dflash,
DflashDraftPolicy::Auto,
"`Auto` never had this failure and must be left alone"
);
assert_eq!(
super::draft_policies(&choice(Some(true)), Speculation::Block(2)).dflash,
DflashDraftPolicy::Fixed(2),
"an install that carries the drafter must still enable it"
);
assert_eq!(
super::draft_policies(&choice(None), Speculation::Block(2)).dflash,
DflashDraftPolicy::Fixed(2)
);
}
#[test]
fn a_headless_moe_install_is_refused_for_its_architecture_not_its_head() {
let moe = resolve_speculation(
Speculation::Block(2),
SpeculativeDrafter::Mtp,
Some(moe()),
true,
)
.expect_err("a named block on a MoE install must fail");
assert!(
moe.contains(MOE_SPECULATION_BLOCKER_MARKER) && moe.contains("128 experts"),
"a MoE install must be refused for its architecture, got: {moe}"
);
assert!(
!moe.contains("multi-token-prediction head"),
"no checkpoint helps here, so the head must not be named: {moe}"
);
let dense = resolve_speculation(
Speculation::Block(2),
SpeculativeDrafter::Mtp,
Some(NO_HEAD.to_string()),
true,
)
.expect_err("a named block on a headless install must fail");
assert!(
dense.contains("multi-token-prediction head"),
"got: {dense}"
);
assert!(
dense.contains("last shard"),
"the NO_HEAD fixture must stay a verbatim copy of the engine's arm: {dense}"
);
}
#[test]
fn a_block_outside_allowed_range_is_refused() {
for invalid in [0, 16, 100] {
let err = resolve_speculation(
Speculation::Block(invalid),
SpeculativeDrafter::Mtp,
None,
true,
)
.expect_err("block outside allowed range must be refused");
assert!(
err.contains("outside allowed range"),
"expected 'outside allowed range' in refusal, got: {err}"
);
}
}