rtx-csm: WavLM-SV converter + end-to-end speaker similarity
Phase 5c — pure-Rust converter for microsoft/wavlm-base-plus-sv with auto-detecting weight_norm merger; verified on real 100M-param weights: load + embed + cosine-similarity round-trip works on Metal. - wavlm_sv_convert.rs: candle_core::pickle reads pytorch_model.bin directly. merge_weight_norm_auto picks the kept dim from g's shape (dim=0 for AudioSeal SEANet, dim=2 for WavLM pos_conv_embed). Skips classifier.*/objective.* (train-only AMSoftmax head). - examples/wavlm_sv_convert: HF download + convert CLI. Verified output: 1 weight_norm pair merged + 261 passthrough + 3 skipped = 262 tensors. - examples/wavlm_sv_demo: load + embed pair of WAVs + cosine similarity. - examples/audioseal_inspect: gains --which wavlm-sv variant for key discovery. - hub.rs: REPO_WAVLM_SV + resolve_wavlm_sv() helper. - wavlm_sv::XVectorHead bug fix: layer_weights is top-level, not nested under prefix. Verified end-to-end on Metal: cosine sim 0.9985 on same-speaker pair (CSM vs CSM-watermarked, 10s @ 24 kHz resampled to 16 kHz). Numerical parity vs HF reference is Phase 5d. 3 converter tests + 12 wavlm_sv tests; 78 lib tests total green. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
@@ -579,7 +579,7 @@ impl XVectorHead {
|
||||
/// vb is rooted at the *top* of the WavLMForXVector state_dict (so we
|
||||
/// read `layer_weights`, `projector`, `tdnn.{0..4}`, `feature_extractor`).
|
||||
pub fn new(vb: VarBuilder) -> candle_core::Result<Self> {
|
||||
let layer_weights = vb.pp("layer_weights").get(NUM_LAYERS + 1, "")?;
|
||||
let layer_weights = vb.get(NUM_LAYERS + 1, "layer_weights")?;
|
||||
let projector = linear(HIDDEN_DIM, FEATURE_DIM, vb.pp("projector"))?;
|
||||
// TDNN specs: (in, out, kernel, dilation)
|
||||
let tdnn_specs: [(usize, usize, usize, usize); 5] = [
|
||||
|
||||
Reference in New Issue
Block a user