use cera::gguf::GgufFile;
use cera::kv_cache::{InferenceState, KvCompression};
use cera::model::Model;
use cera::model::lfm2::Lfm2Model;
use cera::tokenizer::BpeTokenizer;
fn find_lfm2_model() -> Option<std::path::PathBuf> {
let home = std::env::var("HOME").ok()?;
for candidate in [
".leap/models/LFM2.5-VL-450M-Q4_0/LFM2.5-VL-450M-Q4_0.gguf",
".leap/models/LFM2-VL-450M-Q4_0/LFM2-VL-450M-Q4_0.gguf",
".leap/models/LFM2.5-VL-1.6B-Q4_0/LFM2.5-VL-1.6B-Q4_0.gguf",
] {
let p = std::path::PathBuf::from(&home).join(candidate);
if p.exists() {
return Some(p);
}
}
None
}
fn cosine(a: &[f32], b: &[f32]) -> f32 {
assert_eq!(a.len(), b.len());
let dot: f32 = a.iter().zip(b).map(|(x, y)| x * y).sum();
let na: f32 = a.iter().map(|x| x * x).sum::<f32>().sqrt();
let nb: f32 = b.iter().map(|x| x * x).sum::<f32>().sqrt();
if na == 0.0 || nb == 0.0 {
return 0.0;
}
dot / (na * nb)
}
fn top_k(logits: &[f32], k: usize) -> Vec<usize> {
let mut idx: Vec<usize> = (0..logits.len()).collect();
idx.sort_by(|&a, &b| logits[b].partial_cmp(&logits[a]).unwrap());
idx.truncate(k);
idx
}
fn prefill_and_next_logits(model: &dyn Model, tokens: &[u32], cm: KvCompression) -> Vec<f32> {
let cfg = model.config();
let mut state = InferenceState::from_config_with_compression(cfg, &cm);
model.forward_prefill(tokens, 0, &mut state)
}
#[test]
#[ignore] fn test_kv_compression_quality_gate() {
if std::env::var("CERA_QUALITY_GATE").as_deref() != Ok("1") {
eprintln!("skipping: CERA_QUALITY_GATE=1 not set");
return;
}
let model_path = match find_lfm2_model() {
Some(p) => p,
None => {
eprintln!("skipping: no LFM2 model found in ~/.leap/models/");
return;
}
};
eprintln!("quality gate model: {}", model_path.display());
let tok_gguf = GgufFile::open(&model_path).expect("open gguf");
let tokenizer = BpeTokenizer::from_gguf(&tok_gguf).expect("tokenizer");
let gguf = GgufFile::open(&model_path).expect("open gguf");
let model = Lfm2Model::from_gguf(gguf, 8192).expect("load model");
assert!(model.turboquant_supported(), "TurboQuant not supported");
let prompt = "The capital of France is";
let mut tokens = Vec::new();
if tokenizer.bos_token().is_some()
&& tok_gguf
.get_bool("tokenizer.ggml.add_bos_token")
.unwrap_or(false)
{
tokens.push(tokenizer.bos_token().unwrap());
}
tokens.extend_from_slice(&tokenizer.encode(prompt));
eprintln!("prompt tokens: {} ({:?})", tokens.len(), tokens);
let logits_a = prefill_and_next_logits(&model as &dyn Model, &tokens, KvCompression::None);
let logits_b =
prefill_and_next_logits(&model as &dyn Model, &tokens, KvCompression::turboquant(42));
assert_eq!(logits_a.len(), logits_b.len(), "vocab sizes differ");
let cos = cosine(&logits_a, &logits_b);
let argmax_a = logits_a
.iter()
.enumerate()
.max_by(|x, y| x.1.partial_cmp(y.1).unwrap())
.map(|(i, _)| i)
.unwrap();
let argmax_b = logits_b
.iter()
.enumerate()
.max_by(|x, y| x.1.partial_cmp(y.1).unwrap())
.map(|(i, _)| i)
.unwrap();
let top5_a = top_k(&logits_a, 5);
let top5_b = top_k(&logits_b, 5);
let top5_overlap = top5_a.iter().filter(|t| top5_b.contains(t)).count();
let expected_in_top5 = top5_b.contains(&argmax_a);
eprintln!(" logit cosine similarity: {cos:.4}");
eprintln!(
" argmax A: {argmax_a} ({:?})",
tokenizer.decode(&[argmax_a as u32])
);
eprintln!(
" argmax B: {argmax_b} ({:?})",
tokenizer.decode(&[argmax_b as u32])
);
eprintln!(" top-5 A: {top5_a:?}");
eprintln!(" top-5 B: {top5_b:?}");
eprintln!(" top-5 overlap: {top5_overlap}/5");
eprintln!(" expected token (argmax A) in top-5 B: {expected_in_top5}");
assert!(
cos > 0.85,
"TurboQuant quality gate FAILED: logit cosine {cos:.4} < 0.85 — suggests a math bug"
);
assert!(
top5_overlap >= 2,
"TurboQuant quality gate FAILED: top-5 overlap {top5_overlap}/5 < 2"
);
assert!(
expected_in_top5,
"TurboQuant quality gate FAILED: expected token {argmax_a} ({:?}) not in top-5 of compressed path {top5_b:?}",
tokenizer.decode(&[argmax_a as u32])
);
eprintln!("quality gate passed");
}