osobh and Claude Opus 4.7
e61bd70e03
rtx-csm: WavLM-SV bug fixes — gelu_erf + gru_rel_pos_const loading
...
Two real bugs found via code inspection against HF source:
1. candle's .gelu() is the tanh approximation; PyTorch's default 'gelu'
activation (used in WavLM via ACT2FN['gelu']) is the exact erf-based
version. Switched all 3 sites (feature extractor convs, pos_conv,
FFN) from .gelu() to .gelu_erf() to match the reference.
2. gru_rel_pos_const lookup used vb.pp("name").get(shape, "") which
resolves to "<prefix>.name." (trailing dot) and fails to find the
tensor. The .or_else(|_| zeros) silently swallowed the failure,
leaving all 12 layers' gating constants at zero instead of the
trained values. Fixed to attn.get(shape, "gru_rel_pos_const") which
resolves correctly.
examples/wavlm_sv_inspect.rs: utility for sanity-checking specific
tensors inside converted safetensors (e.g. layer_weights).
Same-content same-speaker cosine: 0.9985 -> 0.9963 (≈unchanged).
Cross-content same-speaker cosine: 0.4882 -> 0.4118 (still drifting).
Phase 5d (Python reference comparison) remains the gate for
identifying the residual numerical drift.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected] >
2026-04-25 22:00:59 -07:00
osobh and Claude Opus 4.7
d1dba7a05c
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] >
2026-04-25 19:57:52 -07:00
osobh and Claude Opus 4.7
3165b9339b
rtx-csm: WavLM transformer encoder with gated rel-pos attention
...
Phase 5b — full implementation of WavLMEncoderLayer.forward, replacing
the Phase 5a stub. With random weights the encoder is no longer a no-op
(verified: L2(output - input) > 1e-6 in unit test).
- relative_position_bucket helper: T5-style bidirectional bucketing
matching HF _relative_positions_bucket. 320 buckets, 800 max distance,
half/half split with linear inner / log-spaced outer.
- WavLmEncoderLayer::compute_position_bias (layer 0 only): builds (T,T)
bucket index, embedding-looks up rel_attn_embed, permutes to
(num_heads, T, T) matching HF's compute_bias output.
- WavLmEncoderLayer::gated_position_bias: HF gating math verbatim —
Linear(head_dim → 8), reshape (..., 2, 4) sum, sigmoid, chunk to
gate_a/gate_b, compute gate_a * (gate_b * gru_rel_pos_const - 1) + 2,
broadcast-multiply position_bias.
- WavLmEncoderLayer::attention: multi-head self-attention with the
gated bias added to scores before softmax. Standard 1/sqrt(d) scale.
- WavLmEncoderLayer::forward_with_bias returns (output, position_bias)
so Encoder::forward_all_layers can thread bias from layer 0 through
layers 1-11 (HF's has_relative_position_bias=(i==0) pattern).
- 3 new tests bring wavlm_sv to 12 tests; 75 lib tests total green.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected] >
2026-04-25 19:48:56 -07:00
osobh and Claude Opus 4.7
90e53b3c0c
rtx-csm: WavLM-Base+ SV scaffold for speaker similarity
...
Phase 5a — architectural skeleton for the microsoft/wavlm-base-plus-sv
reference, drop-in replacement for the SpectralCentroidSimilarity weak
baseline in speaker_sim.rs.
Modules in src/wavlm_sv.rs (~600 LOC):
- FeatureExtractor: 7-layer Conv1d, 320× downsample, GroupNorm at layer
0 (num_groups=num_channels=512), GELU activations.
- FeatureProjection: LayerNorm + Linear 512→768.
- PosConv: Conv1d(768, 768, k=128, groups=16, pad=64) + GELU; SamePad
strips trailing frame for even kernel.
- WavLmEncoderLayer: struct shape complete (Q/K/V/out projections, pre-
attention LN, FFN intermediate/output, final LN, gru_rel_pos_const +
gru_rel_pos_linear, optional rel_attn_embed at layer 0). forward() is
a STUB; Phase 5b implements gated rel-pos attention.
- Encoder: 12 stacked layers, returns Vec<Tensor> of 13 hidden states.
- Tdnn: dilated unfold + Linear(in*kernel, out) — matches HF impl.
- XVectorHead: softmax-weighted layer sum + projector 768→512 + 5 TDNN
layers (kernels [5,3,3,1,1] dilations [1,2,3,1,1]) + statistics pool
+ 3000→512 embedding projection.
- WavLmSv top-level + zero-mean unit-variance normalize + cosine
similarity helper for verification scoring.
9 shape-correctness tests; 72 lib tests total green.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected] >
2026-04-25 19:42:59 -07:00