mod common;
use coremlit::{
ComputeUnits,
audio::lid::{Identifier, IdentifierOptions, Language, NUM_LANGUAGES, frame_count},
};
const CLIP_SHA256: &str = "bf3b3ec7a039eed14de04cccec5cff682943111c3df82c8027acc3f3160c125e";
const CLIP_SAMPLES: usize = 207_952;
const CLIP_FRAMES: usize = 1_300;
const THAI_INDEX: usize = 94;
const MAX_RAW_ROW_MASS_DEVIATION: f64 = 1e-2;
const THAI_LOG_PROBABILITY: f32 = -0.010_064;
fn clip() -> Vec<f32> {
common::read_wav_16k_mono(&common::fixture_path("audio/udhr_th_16k.wav"))
}
#[test]
fn reference_clip_is_the_pinned_bytes_and_geometry() {
let path = common::fixture_path("audio/udhr_th_16k.wav");
assert_eq!(common::sha256_file(&path), CLIP_SHA256, "clip drift");
let samples = clip();
assert_eq!(samples.len(), CLIP_SAMPLES);
assert_eq!(frame_count(samples.len()), CLIP_FRAMES);
assert!(samples.iter().all(|s| s.is_finite()));
assert!(
samples.iter().any(|s| s.abs() > 0.05),
"the clip must actually carry speech, not silence"
);
let seconds = samples.len() as f64 / 16_000.0;
assert!((seconds - 12.997).abs() < 1e-3, "{seconds} s");
}
#[test]
fn the_anchor_column_is_thai() {
let thai = Language::from_index(THAI_INDEX).expect("Thai must be in the roster");
assert_eq!(thai.code(), "th");
assert_eq!(thai.name(), "Thai");
}
#[test]
#[ignore = "requires the staged LID model (LID_TEST_MODELS)"]
fn reference_clip_identifies_as_thai() {
let identifier = Identifier::from_file(common::model_path()).expect("load identifier");
let ranked = identifier.identify(&clip(), 3).expect("identify");
assert_eq!(ranked.len(), 3);
assert_eq!(ranked[0].index(), THAI_INDEX, "top-1 must be Thai");
assert_eq!(ranked[0].code(), "th");
assert!(
(ranked[0].log_probability() - THAI_LOG_PROBABILITY).abs() < 0.01,
"top-1 log probability {} is not the reference {THAI_LOG_PROBABILITY}",
ranked[0].log_probability()
);
assert!(
ranked[0].probability() > 0.95,
"the reference clip is a confident call, got {}",
ranked[0].probability()
);
assert!(ranked[0].log_probability() > ranked[1].log_probability());
assert!(ranked[1].log_probability() > ranked[2].log_probability());
assert!(
ranked[0].log_probability() - ranked[1].log_probability() > 3.0,
"the top call must be decisive"
);
}
#[test]
#[ignore = "requires the staged LID model (LID_TEST_MODELS)"]
fn raw_row_is_an_already_normalized_log_distribution() {
let identifier = Identifier::from_file(common::model_path()).expect("load identifier");
let row = identifier.log_probabilities(&clip()).expect("scores");
assert_eq!(row.len(), NUM_LANGUAGES);
assert!(row.iter().all(|v| v.is_finite() && *v <= 0.0));
let mass: f64 = row.iter().map(|v| f64::from(*v).exp()).sum();
let deviation = (mass - 1.0).abs();
println!(" raw row mass 1{:+.3e}", mass - 1.0);
assert!(
deviation < MAX_RAW_ROW_MASS_DEVIATION,
"exp of the row must sum to 1 to within {MAX_RAW_ROW_MASS_DEVIATION:e}, \
got {mass} ({deviation:e} away) — a row that is still a log-softmax output \
misses by fp16 noise, so this size of gap means the graph stopped emitting \
a normalized log distribution"
);
let argmax = (0..NUM_LANGUAGES)
.max_by(|&a, &b| row[a].total_cmp(&row[b]))
.expect("non-empty row");
assert_eq!(argmax, THAI_INDEX);
}
#[test]
#[ignore = "requires the staged LID model (LID_TEST_MODELS)"]
fn default_placement_agrees_with_the_gpu_arm_bit_for_bit() {
let samples = clip();
let load = |compute| {
Identifier::load(
common::model_path(),
IdentifierOptions::new().with_compute(compute),
)
.expect("load identifier")
};
let all = load(ComputeUnits::All)
.log_probabilities(&samples)
.expect("scores under All");
let gpu = load(ComputeUnits::CpuAndGpu)
.log_probabilities(&samples)
.expect("scores under CpuAndGpu");
assert_eq!(all, gpu, "`All` is expected to dispatch to the GPU here");
}
#[test]
#[ignore = "requires the staged LID model (LID_TEST_MODELS)"]
fn prewarm_exercises_the_prediction_path() {
Identifier::from_file(common::model_path())
.expect("load identifier")
.prewarm()
.expect("prewarm");
}