|
Download README.md from smdesai/TitaNet-Large-CoreAI: direct link, hf CLI and curl.
- Browser
- Download file 7.36 kB
-
https://huggingface.co/smdesai/TitaNet-Large-CoreAI/resolve/main/README.md
- Command line
-
hf download hf://smdesai/TitaNet-Large-CoreAI/README.md
-
curl -L -o README.md https://huggingface.co/smdesai/TitaNet-Large-CoreAI/resolve/main/README.md
7.36 kB
| license: cc-by-4.0 | |
| base_model: nvidia/speakerverification_en_titanet_large | |
| language: | |
| - en | |
| library_name: coreai | |
| tags: | |
| - coreai | |
| - apple | |
| - ios | |
| - on-device | |
| - speaker-verification | |
| - speaker-recognition | |
| - speaker-embedding | |
| - titanet | |
| - audio | |
| # TitaNet-Large for Core AI | |
| [NVIDIA TitaNet-Large](https://huggingface.co/nvidia/speakerverification_en_titanet_large) (23M parameters) ported | |
| to Apple's **Core AI** runtime for on-device speaker verification and identification on iPhone, iPad and Mac. | |
| Give it 16 kHz mono speech and it returns NeMo's 192-d speaker embedding, numerically matching the original: | |
| **cosine β₯ 0.9999987 against NeMo's `get_embedding` on real recordings from 4 to 65 seconds.** | |
| One small bundle (47 MB) handles audio of any length: the graph is compiled for a single 5.12 s window, and a short | |
| host loop sweeps that window over the clip and rebuilds the model's global statistics exactly. On an iPhone it peaks | |
| at **117 MB** of memory and embeds a 65-second clip in **1.1 s** on the GPU. | |
| ## Results | |
| All comparisons are against NeMo's own embedding of the same audio (the `.nemo` checkpoint, `get_embedding`). | |
| | Check | Clips | Cosine to NeMo (min / mean) | Notes | | |
| |---|---|---|---| | |
| | WAV β Python host β Core AI (Mac, GPU) | 40 VoxCeleb1-test, 4.1β64.7 s | **0.9999987** / 0.9999993 | the whole pipeline: mel front end, windowed host, graph | | |
| | NeMo's mel β Swift host β Core AI (iPhone, GPU) | same 40 | **0.9999987** / 0.9999993 | all embeddings finite | | |
| Because the embeddings agree with NeMo's to within 1.3e-6 in cosine, verification behaves as the original does. | |
| NVIDIA reports **0.66 % EER on VoxCeleb1 (cleaned trials)** for the base model; this port was not separately | |
| re-scored on that benchmark. | |
| ## Files | |
| | Path | What it is | | |
| |---|---| | |
| | `titanet.aimodel/` | the Core AI bundle: functions `scan` and `head`, fp16 weights, fp32 compute | | |
| | `export.json` | window length (512 frames), context margin (46), function signatures, precision recipe | | |
| | `frontend/mel_fb.f32` | slaney mel filterbank [80, 257], float32 little-endian (the checkpoint's own buffer) | | |
| | `frontend/mel_window.f32` | Hann window [400], periodic=False (the checkpoint's own buffer) | | |
| | `frontend/config.json` | front-end constants: 16 kHz, n_fft 512, hop 160, win 400, 80 mels, 192-d embedding, threshold 0.7 | | |
| ## Input | |
| - **16 kHz, mono**, float samples in [-1, 1]. The model was trained on 16 kHz audio; resample anything else first. | |
| - Any length from one 10 ms frame up. A few seconds of speech gives a stable embedding. | |
| - The front end is NeMo's `AudioToMelSpectrogramPreprocessor` in eval mode, reproduced step for step: pre-emphasis | |
| 0.97, centred 512-point STFT (hop 160, Hann 400), power, 80 slaney mel bins, `log(x + 2^-24)`, per-feature | |
| normalization over the valid frames. The filterbank and window are the checkpoint's own buffers. Dither is | |
| training-only and is not applied. | |
| ## How it works | |
| ### Why one window | |
| In a Core AI bundle the activation arena is sized per compiled shape and allocated for every function in the bundle. | |
| A ladder of input-length buckets (the usual way to handle variable-length audio) therefore costs the sum of all its | |
| shapes: 768 MB to over 1.1 GB measured for seven buckets. This port compiles exactly one shape, a 512-frame (5.12 s) | |
| window, and handles longer audio on the host. | |
| ### Why a naive window is wrong, and the fix | |
| TitaNet has three reductions over the whole time axis: | |
| 1. **five SqueezeExcite gates**: each block scales its channels by `sigmoid(W2 relu(W1 mean_t(x)))` over the entire | |
| utterance; | |
| 2. **the pooling mean / std** of the encoder output; | |
| 3. **the attention softmax over time** in attentive statistics pooling. | |
| Computing these per window gives the wrong function: chunk-local SqueezeExcite alone drops the cosine to about 0.36. | |
| The graph here makes all three reductions *injectable* (taken as inputs) and *reportable* (partial sums returned as | |
| outputs), so the host can rebuild them exactly: | |
| | Pass | Calls | Rebuilds | | |
| |---|---|---| | |
| | 1β5 | `scan` per window, gate sums fed back as `s0..s4` | the SqueezeExcite fixed point: block *j*'s mean depends only on gates < *j*, so sweep *k* makes gate *kβ1* exact and five sweeps make all five exact | | |
| | 6 | `scan` per window | pooling mean / std from running sums `x_sum`, `x_sqsum` | | |
| | 7 | `scan` per window, with the pooling stats | the attention softmax, merged across windows by running maximum (`lmax`, `den`, `ax`, `axx`) | | |
| | β | `head` once | the 192-d embedding from the attentive mean and std | | |
| Every convolution is stride 1 with "same" padding and the stack's receptive field is 93 frames, so each window carries | |
| 46 frames of real context on each side and keeps only its interior; the interiors tile the clip exactly once. A clip | |
| of *n* mel frames (10 ms each) uses 1 window if *n* β€ 512, otherwise β(*n* β 512) / 420β + 1, and | |
| **7 Γ windows + 1** model calls. Host accumulation is float64, and host memory is O(channels), never O(frames). | |
| All five sweeps are needed: the gate residual falls to 6e-4 after two sweeps and *looks* converged while the | |
| embedding cosine is still 0.64. Cosine by number of sweeps: 0.066, 0.639, 0.993, 0.99996, 0.9999987. | |
| ### Precision | |
| `wfp16`: weights stored as fp16 (half the bytes), all compute in fp32. A full-fp16 graph was rejected for long | |
| audio: its whole-utterance reductions sum thousands of frames in fp16, and the worst-case cosine fell to 0.72 on | |
| clips up to 65 s, although it looked fine (0.99998) on 4-second clips. | |
| ### Interface | |
| `scan`: one window of the clip. | |
| | Input | Shape | Meaning | | |
| |---|---|---| | |
| | `mel` | [1, 80, 512] | the window's normalized log-mel, zero past the clip's end | | |
| | `valid` | [1, 1, 512] | 1 for frames inside the clip | | |
| | `keep` | [1, 1, 512] | 1 for the window's interior frames, whose statistics this call reports | | |
| | `n_inv` | [1, 1] | 1 / (valid frames in the whole clip) | | |
| | `s0`..`s3`, `s4` | [1, 1024] Γ4, [1, 3072] | SqueezeExcite sums from the previous sweep (zeros on the first) | | |
| | `mean`, `std` | [1, 3072] each | pooling statistics for the attention pass (zeros and ones before they are known) | | |
| Outputs, all [1, C]: `se0`..`se4` (this window's SqueezeExcite contributions), `x_sum`, `x_sqsum`, `lmax`, `den`, | |
| `ax`, `axx` (C = 3072). | |
| `head`: `mu`, `sg` [1, 3072] β `emb` [1, 192]. | |
| ## License and attribution | |
| This is a derivative of [nvidia/speakerverification_en_titanet_large](https://huggingface.co/nvidia/speakerverification_en_titanet_large) | |
| by NVIDIA, released under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/); this port is released under the | |
| same license. | |
| Modifications: converted to Core AI with fp16 weight storage, and the network re-authored so its global reductions | |
| can be supplied and reported per window (the attention-pooling concat is folded into its first convolution). The | |
| weights are NVIDIA's; no retraining or fine-tuning was done. | |
| ```bibtex | |
| @inproceedings{koluguri2022titanet, | |
| title = {TitaNet: Neural Model for Speaker Representation with 1D Depth-wise Separable Convolutions and Global Context}, | |
| author = {Koluguri, Nithin Rao and Park, Taejin and Ginsburg, Boris}, | |
| booktitle = {ICASSP 2022 - 2022 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP)}, | |
| pages = {8102--8106}, | |
| year = {2022} | |
| } | |
| ``` | |