use candle_nn::VarMap;
use super::*;
use crate::models::jina_bert::AlibiSlopeVariant;
const TWELVE_HEADS: &str = r#"{"vocab_size":32,"hidden_size":24,"num_hidden_layers":1,
"num_attention_heads":12,"intermediate_size":16,"max_position_embeddings":64,"type_vocab_size":2,
"layer_norm_eps":1e-12,"position_embedding_type":"alibi","feed_forward_type":"geglu"}"#;
fn fill_from_names(varmap: &VarMap) {
for (name, var) in varmap.data().lock().unwrap().iter() {
let seed = name.bytes().fold(2_166_136_261u32, |h, b| {
(h ^ u32::from(b)).wrapping_mul(16_777_619)
});
let values: Vec<f32> = (0..var.elem_count() as u32)
.map(|i| {
let x = seed ^ i.wrapping_mul(2_654_435_761);
(x >> 8) as f32 / (1u32 << 24) as f32 - 0.5
})
.collect();
var
.set(&Tensor::from_vec(values, var.shape(), &Device::Cpu).unwrap())
.unwrap();
}
}
fn twelve_head_score(varmap: &VarMap, alibi_variant: Option<AlibiSlopeVariant>) -> f32 {
let vb = VarBuilder::from_varmap(varmap, DType::F32, &Device::Cpu);
let model = load_rerank(
"jina_bert",
TWELVE_HEADS,
vb,
RerankConventions {
head: RerankHead::BertPooler,
score_activation: ScoreActivation::Identity,
alibi_variant,
position_scheme: None,
},
)
.unwrap();
let input_ids = Tensor::new(
&[[1u32, 5, 9, 2, 13, 17, 21, 25, 29, 3, 7, 11, 15, 19, 23, 2]],
&Device::Cpu,
)
.unwrap();
let attention_mask = input_ids.ones_like().unwrap();
let token_type_ids = Tensor::new(
&[[0u32, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]],
&Device::Cpu,
)
.unwrap();
let lengths = vec![16];
let input = EncoderInput {
input_ids: &input_ids,
attention_mask: &attention_mask,
token_type_ids: &token_type_ids,
lengths: &lengths,
};
model.forward(&input).unwrap()[0].value()
}
#[test]
fn the_alibi_variant_load_rerank_hands_a_twelve_head_encoder_changes_its_score() {
let varmap = VarMap::new();
twelve_head_score(&varmap, None);
fill_from_names(&varmap);
let canonical = twelve_head_score(&varmap, Some(AlibiSlopeVariant::Canonical));
let halved = twelve_head_score(&varmap, Some(AlibiSlopeVariant::HalvedInterpolatedTail));
let default = twelve_head_score(&varmap, None);
assert!(
(halved - canonical).abs() > 1e-4,
"the halved tail must move the score: canonical {canonical}, halved {halved}"
);
assert_eq!(default, canonical, "None is the canonical slope formula");
}