use candle_nn::VarBuilder;
const QK_MARKER: &str = "encoder.layer.0.attention.self.layer_norm_q.weight";
const SPLIT_MARKER: &str = "encoder.layer.0.layer_norm_1.weight";
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Variant {
pub qk_norm: bool,
pub split_norms: bool,
}
impl Variant {
pub fn probe(vb: &VarBuilder) -> Self {
Self {
qk_norm: vb.contains_tensor(QK_MARKER),
split_norms: vb.contains_tensor(SPLIT_MARKER),
}
}
}
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use candle_core::DType;
use candle_core::Device;
use candle_core::Tensor;
use super::*;
fn probe_with(names: &[&str]) -> Variant {
let one = Tensor::ones(4, DType::F32, &Device::Cpu).unwrap();
let map: HashMap<String, Tensor> = names
.iter()
.map(|n| ((*n).to_string(), one.clone()))
.collect();
Variant::probe(&VarBuilder::from_tensors(map, DType::F32, &Device::Cpu))
}
#[test]
fn the_header_selects_the_block_shape() {
assert_eq!(
probe_with(&[]),
Variant {
qk_norm: false,
split_norms: false
},
"small-en, base-en, base-de and base-zh"
);
assert_eq!(
probe_with(&[QK_MARKER]),
Variant {
qk_norm: true,
split_norms: false
},
"base-es"
);
assert_eq!(
probe_with(&[QK_MARKER, SPLIT_MARKER]),
Variant {
qk_norm: true,
split_norms: true
},
"base-code"
);
assert_eq!(
probe_with(&[SPLIT_MARKER]),
Variant {
qk_norm: false,
split_norms: true
},
"no published checkpoint, recorded so the probe's answer is defined rather than accidental"
);
}
#[test]
fn the_markers_name_layer_zero() {
assert_eq!(
QK_MARKER,
"encoder.layer.0.attention.self.layer_norm_q.weight"
);
assert_eq!(SPLIT_MARKER, "encoder.layer.0.layer_norm_1.weight");
assert_eq!(
probe_with(&[
"encoder.layer.1.attention.self.layer_norm_q.weight",
"encoder.layer.1.layer_norm_1.weight",
]),
Variant {
qk_norm: false,
split_norms: false
},
"the probe reads layer 0 and nothing else"
);
}
}