# Building a Speaker Verification App with Gradio, UniSpeech\-SAT and X\-Vectors

- Canonical: https://33rdsquare.com/create-gradio-demo-for-speaker-verification/
- Published: 2024-09-03
- Author: Jordan Brown
- Categories: [Artificial Intelligence & Machine Learning & ChatGPT](https://33rdsquare.com/category/tech/ai/)

---

Speaker verification is the task of confirming a speaker‘s identity based on their voice. Given an audio sample, the goal is to determine if it matches a previously enrolled speaker. This has useful applications in security, access control, fraud prevention, and personalization.

In this tutorial, we‘ll walk through how to build an interactive demo for speaker verification using:

- [Gradio](https://gradio.app/): a Python library for quickly creating customizable UI components for machine learning apps
- [UniSpeech-SAT](https://huggingface.co/microsoft/unispeech-sat-base): a state-of-the-art speech representation model pre-trained on 94,000 hours of speech data in a self-supervised fashion
- [X-Vectors](https://www.danielpovey.com/files/2018_icassp_xvectors.pdf): a technique for extracting compact embeddings from variable-length speech segments for speaker recognition

By the end of this post, you‘ll have a working demo you can try out yourself, plus an understanding of the key concepts and tools involved. Let‘s dive in!

## Overview of the Pipeline

Here are the main steps in our speaker verification pipeline:

1. Obtain the audio samples to compare, either from user input or pre-recorded files
2. Apply audio preprocessing to ensure consistent format and quality
3. Extract X-Vector embeddings from the audio using the UniSpeech-SAT model
4. Calculate cosine similarity between the X-Vector embeddings to get a match score
5. Compare the score to a threshold to make the final verification decision

We‘ll implement this in Python, using Gradio to build the user interface that lets you input audio samples and view the result. The complete code is available on GitHub, but we‘ll go through it step-by-step below.

## Setting Up the Environment

First, make sure you have Python 3.7+ and PyTorch installed. You‘ll also need to install the Gradio, Transformers, and Torchaudio libraries:

```

pip install gradio torch torchaudio transformers
```

We‘ll be deploying our app on Hugging Face Spaces, so create a free account on huggingface.co if you don‘t have one already. Create a new Space and select Gradio as the app framework.

## Importing Dependencies

In a new Python file, import the necessary modules:

```

import torch
import torchaudio
import gradio as gr
from transformers import AutoFeatureExtractor, AutoModelForAudioXVector
```

We‘ll use classes from Hugging Face Transformers to load the UniSpeech-SAT model and feature extractor. Gradio will be used to build the UI.

## Audio Preprocessing

To ensure our input audio is in a consistent format expected by the model, we‘ll apply some preprocessing using Torchaudio:

```

EFFECTS = [
    ["remix", "-"],  # convert to mono
    ["channels", "1"],
    ["rate", "16000"],  # resample to 16kHz
    ["gain", "-3.0"],  # lower volume
    ["silence", "1", "0.1", "0.1%", "-1", "0.1", "0.1%"],  # remove silence
    ["trim", "0", "10"],  # limit to 10 seconds
]
def preprocessaudio(audio):
wav = audio.squeeze(0)
wav,  = torchaudio.sox_effects.apply_effects_tensor(wav, EFFECTS)
return wav
```

This converts the audio to a mono 16kHz WAV, removes silence, and limits the duration to 10 seconds to keep processing time reasonable.

## Loading the Model

Next, let‘s load the UniSpeech-SAT model and feature extractor:

```

model_id = "microsoft/unispeech-sat-base-plus-sv"
device = "cuda" if torch.cuda.is_available() else "cpu"
model = AutoModelForAudioXVector.from_pretrained(model_id).to(device)
extractor = AutoFeatureExtractor.from_pretrained(model_id)
cosine_sim = torch.nn.CosineSimilarity(dim=-1)
```

We‘re using the "base-plus-sv" version fine-tuned for speaker verification on the VoxCeleb dataset. If you don‘t have a GPU available, set device to "cpu".

## Extracting Embeddings

Now we can define a function to extract X-Vector embeddings from the preprocessed audio:

```

def extract_xvectors(wav1, wav2):
    with torch.no_grad():
        emb1 = model(extractor(wav1, return_tensors="pt", sampling_rate=16000).input_values.to(device)).embeddings
        emb2 = model(extractor(wav2, return_tensors="pt", sampling_rate=16000).input_values.to(device)).embeddings
    emb1 = torch.nn.functional.normalize(emb1, dim=-1)
    emb2 = torch.nn.functional.normalize(emb2, dim=-1)
    return emb1, emb2
```

The extractor converts the raw audio into the expected input format (log Mel filterbank features), which is passed into the model to get the X-Vector embeddings. We apply L2 normalization to improve the embeddings‘ robustness.

## Matching Speakers

Finally, we calculate the cosine similarity between the two embedding vectors and compare it to a threshold to determine if they match:

```

THRESHOLD = 0.85
def verify_speakers(wav1, wav2):
wav1 = preprocess_audio(wav1)
wav2 = preprocess_audio(wav2)
emb1, emb2 = extract_xvectors(wav1, wav2)
similarity = cosine_sim(emb1, emb2).item()

if similarity >= THRESHOLD:
    result = f"MATCH: {similarity:.2%} similarity"
else:
    result = f"NO MATCH: {similarity:.2%} similarity"

return result
The THRESHOLD value of 0.85 was chosen based on experiments, but you can adjust it depending on the desired balance of false accepts and false rejects for your application.
Building the Gradio Interface
Now for the exciting part – creating the interactive demo! With just a few lines of Gradio code, we can build a full UI:

inputs = [
    gr.Audio(source="microphone", type="numpy", label="Speaker 1", optional=True),
    gr.Audio(source="microphone", type="numpy", label="Speaker 2", optional=True),
]
output = gr.Textbox(label="Verification Result")
examples = [
["speaker1_audio1.wav", "speaker1_audio2.wav"],
["speaker1_audio1.wav", "speaker2_audio1.wav"],
]
gr.Interface(
verify_speakers,
inputs,
output,
examples=examples,
title="Speaker Verification",
description="Test if two audio samples are from the same speaker using UniSpeech-SAT and X-Vectors"
).launch()

This defines two audio input components that can record from the user‘s microphone or be uploaded, and a text output to display the verification result. We also provide some example audio pairs to demonstrate the functionality.
Finally, we create and launch a Gradio Interface with our verify_speakers function, inputs and output. And that‘s it! You should now be able to run the Python script, interact with your demo, and share the URL.
Deploying on Hugging Face Spaces
To make your app accessible to anyone online, deploy it on Hugging Face Spaces:

In your Space‘s repository, add the Python file, example audios, a requirements.txt listing the dependencies, and a README describing your app
Commit and push the changes
On the Space‘s page, click "Deploy" to build and launch your app
Test it out and share the URL!

You can try out my demo here: https://huggingface.co/spaces/bsub/speaker-verification
Future Directions
While this demo is a great starting point, there are many ways to extend and improve it:
Handling more challenging audio conditions: The current model works best with clean, single-speaker audio. Techniques like speech enhancement, voice activity detection, and speaker diarization could help deal with noisy, multi-speaker scenarios.
Preventing spoofing attacks: Speaker verification systems can be vulnerable to attacks using synthesized or replayed speech. Integrating spoofing detection based on artifacts in the audio could improve security.
Enabling text-independent verification: Our method depends on comparing embeddings from fixed phrases. An even more flexible approach is text-independent verification, which can match speakers across different utterances.
Multimodal authentication: Combining voice with other biometrics like face and fingerprints can provide stronger identity assurance and user experiences across diverse devices and situations.
I‘m excited to see how speaker verification technology will continue to advance and unlock new applications in the coming years. With more capable representation learning models, sophisticated audio processing techniques, and intuitive tools like Gradio, it‘s never been easier to experiment and build practical demos.
Acknowledgments
Thanks to the researchers and developers behind UniSpeech-SAT, X-Vectors, Gradio, and Hugging Face for their amazing open-source work that made this tutorial possible. I also appreciate the MediaPipe team for their sample audios used in the demo.
References
```

- Hsu et al. (2021). "Hubert: Self-supervised speech representation learning by masked prediction of hidden units." IEEE/ACM Transactions on Audio, Speech, and Language Processing.
- Chen et al. (2022). "UNISPEECH-SAT: UNIVERSAL SPEECH REPRESENTATION LEARNING WITH SPEAKER AWARE PRE-TRAINING." ICASSP.
- Snyder et al. (2018). "X-vectors: Robust DNN embeddings for speaker recognition." ICASSP.
- Gradio: [https://gradio.app/](https://gradio.app/)
- Hugging Face Transformers: [https://huggingface.co/docs/transformers/](https://huggingface.co/docs/transformers/)

Let me know if you have any other questions! Feel free to experiment with the code and share your own speaker verification demos.

---

Source: [Building a Speaker Verification App with Gradio, UniSpeech\-SAT and X\-Vectors](https://33rdsquare.com/create-gradio-demo-for-speaker-verification/)
