|
Download README.md from Paytmlabs/Pi-indic-speaker-embed-v1: direct link, hf CLI and curl.
- Browser
- Download file 5.84 kB
-
https://huggingface.co/Paytmlabs/Pi-indic-speaker-embed-v1/resolve/main/README.md
- Command line
-
hf download hf://Paytmlabs/Pi-indic-speaker-embed-v1/README.md
-
curl -L -o README.md https://huggingface.co/Paytmlabs/Pi-indic-speaker-embed-v1/resolve/main/README.md
5.84 kB
| language: en | |
| tags: | |
| - speaker-verification | |
| - speaker-embedding | |
| - indic | |
| - wavlm | |
| - ecapa-tdnn | |
| - lora | |
| license: mit | |
| # Pi-Indic-Speaker-Embed-v1 | |
| A 512-dimensional speaker embedding model optimized for **Indic languages** (Hindi, Bengali, Marathi, Telugu, and 8 more). Built on top of WavLM Large + ECAPA-TDNN with LoRA fine-tuning, designed for cross-lingual voice cloning and speaker verification tasks. | |
| ## Model Description | |
| | Component | Details | | |
| |-----------|---------| | |
| | **Frontend** | WavLM Large (frozen base, 315M params) + LoRA adapters on layers 9β24 | | |
| | **LoRA scheme** | Layers 9β16: rank 8; Layers 17β24: rank 16; on all 6 projections (q, k, v, out, FFN up, FFN down) | | |
| | **Encoder** | ECAPA-TDNN (3 Res2Net blocks, model_scale=8, ndim=1024, output=1536) | | |
| | **Pooling** | Channel-Attention Statistics Pooling (β 3072-dim) | | |
| | **Projector** | RawNet3 (BatchNorm + Linear β 512-dim) | | |
| | **Embedding dim** | 512 (L2-normalized) | | |
| | **Total trainable params** | ~24M (LoRA 3.5M + ECAPA 18M + Pooling 0.8M + Projector 1.6M) | | |
| | **Checkpoint size** | 96 MB (WavLM base downloaded separately from `microsoft/wavlm-large`) | | |
| ### Training Details | |
| - **Warm-started** from [`espnet/voxcelebs12_ecapa_wavlm_joint`](https://huggingface.co/espnet/voxcelebs12_ecapa_wavlm_joint) (8th epoch) | |
| - **Training data**: Kathbath (12 Indic languages, 960 speakers) + VoxCeleb1 (full) + VoxCeleb2 (~2k sampled) | |
| - **Loss**: AAM-Softmax with sub-centers (K=3, k_top=5, margin=0.2, scale=30) β discarded after training | |
| - **Optimizer**: Adam (lr=1e-4, weight_decay=1e-5), ExponentialLR (gamma=0.87055) | |
| - **Training**: 30 real epochs (150 mini-epochs), early stopped at epoch 29 (best at epoch 3) | |
| - **Checkpoint**: Average of top-5 epochs by validation EER (epochs 3, 5, 6, 14, 20) | |
| ### Performance | |
| | Evaluation Set | EER | minDCF | Description | | |
| |---------------|------|--------|-------------| | |
| | Kathbath Validation (seen conditions, unseen speakers) | **1.586%** | 0.0640 | 79 speakers, 4 Indic languages | | |
| | IndicVoices-R Test (unseen conditions, unseen speakers) | **4.003%** | 0.1699 | 64 speakers, 4 Indic languages | | |
| | SOTA baseline (voxcelebs12, VoxCeleb-trained) | 3.999% / 5.161% | 0.1741 / 0.2248 | Same eval sets for comparison | | |
| The averaged checkpoint (`valid.eer.ave_5best.pth`) consistently outperforms single-epoch checkpoints on unseen data, confirming that weight averaging reduces overfitting. | |
| ## Installation | |
| ```bash | |
| pip install espnet s3prl transformers torch soundfile librosa numpy huggingface_hub | |
| ``` | |
| ## Quick Start | |
| ### Python API | |
| ```python | |
| from inference import PiIndicSpeakerEmbed | |
| # Downloads model files from HuggingFace automatically | |
| model = PiIndicSpeakerEmbed.from_pretrained("Paytmlabs/Pi-indic-speaker-embed-v1") | |
| # Extract a single embedding | |
| embedding = model.extract("audio.wav") | |
| print(embedding.shape) # β (512,) | |
| # Extract embeddings for multiple files | |
| embeddings = model.extract_batch(["speaker1.wav", "speaker2.wav", "speaker3.wav"]) | |
| print(embeddings.shape) # β (3, 512) | |
| ``` | |
| ### Command Line | |
| ```bash | |
| # Single file | |
| python inference.py --audio audio.wav | |
| # Multiple files, save to .npy | |
| python inference.py --audio spk1.wav spk2.wav spk3.wav --output embeddings.npy | |
| ``` | |
| ### Speaker Verification (cosine similarity) | |
| ```python | |
| from inference import PiIndicSpeakerEmbed | |
| import numpy as np | |
| model = PiIndicSpeakerEmbed.from_pretrained("Paytmlabs/Pi-indic-speaker-embed-v1") | |
| emb1 = model.extract("speaker_a_utt1.wav") | |
| emb2 = model.extract("speaker_a_utt2.wav") | |
| emb3 = model.extract("speaker_b_utt1.wav") | |
| # Cosine similarity (higher = more similar) | |
| sim_same = np.dot(emb1, emb2) # same speaker, different utterance | |
| sim_diff = np.dot(emb1, emb3) # different speakers | |
| print(f"Same speaker similarity: {sim_same:.4f}") | |
| print(f"Diff speaker similarity: {sim_diff:.4f}") | |
| # Same speaker similarity: 0.85+ (typically) | |
| # Diff speaker similarity: 0.40-0.60 (typically) | |
| ``` | |
| ## How It Works | |
| ``` | |
| Raw audio (16kHz) | |
| β 3 random crops Γ 96,000 samples (6s each) [Preprocessor] | |
| β WavLM Large (frozen) + LoRA (layers 9-24) [Frontend] | |
| β 1024-dim frame features @ 50Hz [multilayer weighted sum] | |
| β utterance mean normalization [utterance_mvn] | |
| β ECAPA-TDNN (Conv1d + 3 Res2Net blocks) [Encoder] | |
| β 1536-dim frame-level embeddings | |
| β Channel-Attention Statistics Pooling [Pooling] | |
| β 3072-dim utterance embedding (weighted mean β weighted std) | |
| β RawNet3 Projector (BatchNorm + Linear) [Projector] | |
| β 512-dim speaker embedding | |
| β L2 normalize [Inference] | |
| β 512-dim unit vector on hypersphere | |
| ``` | |
| The AAM-Softmax classifier (used during training) is **discarded** after training. At inference, only the encoder + pooling + projector are used to produce embeddings. This means the model can verify **any speaker**, including those never seen during training. | |
| ## Files | |
| | File | Description | | |
| |------|-------------| | |
| | `valid.eer.ave_5best_stripped.pth` | Stripped checkpoint (LoRA + ECAPA + pooling + projector, 96 MB) | | |
| | `config.yaml` | Model architecture configuration | | |
| | `inference.py` | Self-contained inference script | | |
| | `lora_s3prl_frontend.py` | Custom WavLM + LoRA frontend | | |
| | `lora_wavlm.py` | LoRA injection utilities | | |
| | `spk_preprocessor_lora.py` | Custom preprocessor | | |
| ## Citation | |
| If you use this model, please cite: | |
| ```bibtex | |
| @misc{pi-indic-speaker-embed-v1, | |
| title={Pi-Indic-Speaker-Embed-v1: A 512-dim Speaker Embedding Model for Indic Languages}, | |
| author={Paytmlabs}, | |
| year={2026}, | |
| url={https://huggingface.co/Paytmlabs/Pi-indic-speaker-embed-v1} | |
| } | |
| ``` | |
| ## License | |
| MIT License. The WavLM Large base model follows its own license (`microsoft/wavlm-large`). | |