Downloads · 30 days
41
4% of all-time downloads
Aniemore/wav2vec2-bert-tiny2-s-emotion-russian-resd
wav2vec2-bert-tiny2-s-emotion-russian-resd is a audio classification model from Aniemore. Use it for the audio classification task on the model card, and read the license before you ship it in a product. It is set up for transformers. The card lists the license as mit.
Speech emotion recognition for Russian over seven classes: anger, disgust, enthusiasm, fear, happiness, neutral, sadness.
Downloads · 30 days
41
4% of all-time downloads
All-time downloads
914
Public
Repo size
2.8 GB
Likes
2
Public
Click a slice to open those files.
.bin1.4 GB · 100%
From the Hugging Face model README
Speech emotion recognition for Russian over seven classes: anger, disgust, enthusiasm, fear, happiness, neutral, sadness.
Audio tower jonatasgrosman/wav2vec2-large-xlsr-53-russian (WavLM/wav2vec2 fine-tuned for Russian ASR) paired with the text encoder cointegrated/rubert-tiny2; the model reads the waveform and a transcript together. Trained on Aniemore/resd.
wav2vec2-bert-tiny2-s-emotion-russian-resd-quantized — INT8, FP8 and INT4, up to 5.8x smaller on disk at the same score| Test set | n | UA | WA | macro-F1 |
|---|---|---|---|---|
| RESD test | 280 | 0.7217 | 0.7286 | 0.7228 |
| Dusha podcast test | 12079 | 0.2594 | 0.2267 | 0.1361 |
| CAMEO test | 5187 | 0.2723 | 0.3108 | 0.2589 |
| RESD test, transcript blanked | 280 | 0.5515 | 0.5607 | 0.5064 |
The last row is the audio branch alone. Production rarely has a gold transcript, and the gap between 0.723 with one and 0.506 without is what a transcript is worth here.
<img src="assets/confusion.svg" alt="Confusion matrix on RESD test" width="640">import torch, librosa
from transformers import AutoConfig, AutoTokenizer, AutoModel
repo = "Aniemore/wav2vec2-bert-tiny2-s-emotion-russian-resd"
cfg = AutoConfig.from_pretrained(repo, trust_remote_code=True)
model = AutoModel.from_pretrained(repo, trust_remote_code=True).eval()
tok = AutoTokenizer.from_pretrained(repo)
# Resample to 16 kHz. RESD ships at 44.1 kHz, and 44.1 kHz audio
# labelled as 16 kHz is stretched 2.8x in time — the model answers,
# it just answers about other audio.
wav, _ = librosa.load("clip.wav", sr=16000, mono=True)
wav = torch.tensor((wav - wav.mean()) / (wav.std() + 1e-7))[None]
t = tok("расшифровка реплики", return_tensors="pt")
with torch.no_grad():
logits = model(input_ids=t['input_ids'], input_values=wav,
text_attention_mask=t['attention_mask'],
audio_attention_mask=torch.ones_like(wav).long()).logits
probs = logits.softmax(-1)[0]
print({model.config.id2label[i]: round(p.item(), 3) for i, p in enumerate(probs)})
<details><summary>Loading the audio without librosa</summary>
# torchaudio
import torchaudio
wav, sr = torchaudio.load("clip.wav")
wav = torchaudio.functional.resample(wav, sr, 16000).mean(0).numpy()
# torchcodec, the newer decoder
from torchcodec.decoders import AudioDecoder
wav = AudioDecoder("clip.wav", sample_rate=16000).get_all_samples().data.mean(0).numpy()
# straight from the dataset — `datasets` resamples on the column, so
# the mixed 16/44.1 kHz in RESD is handled for you
from datasets import load_dataset, Audio
ds = load_dataset("Aniemore/resd", split="test")
ds = ds.cast_column("speech", Audio(sampling_rate=16000))
wav = ds[0]["speech"]["array"]
</details>
Audio resampled to 16 kHz mono, clips capped at 12 s, normalized per utterance, padding masked. UA is macro-averaged recall, WA is accuracy, F1 is macro-averaged. All three test sets went through the same harness, so the rows are comparable to each other.
The RESD split matches fold 1 of EmoBox bit for bit. The top entry there is WavLM-large at WA 56.47 / UA 55.87 / F1 55.82. These numbers are higher, but the training protocol differs — EmoBox freezes the encoder and trains a probe, this is a full fine-tune — so read it as a different recipe on the same split, not as a like-for-like win.
RESD is acted and class-balanced. Real speech is neither. The Dusha podcast row above is the honest signal for spontaneous audio, and it is far below the RESD row. Spontaneous Russian is roughly 93% neutral, and a model tuned on balanced acted data over-predicts the emotional classes on it. Measure on your own material, and calibrate the neutral logit if you deploy.
Seven classes only, Russian only, single-speaker clips.
@misc{aniemore,
author = {Lubenets, Ilya and Davidchuk, Nikita and Amentes, Aleksandr},
title = {Aniemore: an open library for emotion recognition in Russian speech},
url = {https://github.com/Aniemore/Aniemore},
year = {2023}
}
MIT.