use super::*;
fn bidirectional_config() -> Qwen3Config {
let mut config = tiny_config();
config.is_causal = false;
config
}
fn bidirectional_model() -> Qwen3Model {
let varmap = VarMap::new();
let vb = VarBuilder::from_varmap(&varmap, DType::F32, &Device::Cpu);
Qwen3Model::load(bidirectional_config(), vb).unwrap()
}
#[test]
fn bidirectional_branch_lets_earlier_positions_attend_to_later_ones() {
let model = bidirectional_model();
let a = run(&model, &[vec![2, 5, 7]]);
let b = run(&model, &[vec![2, 5, 9]]);
let earlier_position_moved = (0..2).any(|pos| {
a[0][pos]
.iter()
.zip(&b[0][pos])
.any(|(x, y)| (x - y).abs() > 1e-5)
});
assert!(
earlier_position_moved,
"an earlier position must see the changed later token under bidirectional attention"
);
}
#[test]
fn bidirectional_branch_excludes_padded_positions() {
let model = bidirectional_model();
let alone = run(&model, &[vec![2, 9, 3]]);
let batched = run(&model, &[vec![2, 5, 7, 8, 3], vec![2, 9, 3]]);
for (pos, token) in alone[0].iter().enumerate() {
for (a, b) in token.iter().zip(&batched[1][pos]) {
assert!((a - b).abs() < 1e-5, "position {pos}: {a} vs {b}");
}
}
}