Download ssl_mamba.py from SpeechAntiSpoofingBenchmarks/SSL-Mamba: direct link, hf CLI and curl.
- Browser
- Download file 1.58 kB
-
https://huggingface.co/SpeechAntiSpoofingBenchmarks/SSL-Mamba/resolve/main/ssl_mamba.py
- Command line
-
hf download hf://SpeechAntiSpoofingBenchmarks/SSL-Mamba/ssl_mamba.py
-
curl -L -o ssl_mamba.py https://huggingface.co/SpeechAntiSpoofingBenchmarks/SSL-Mamba/resolve/main/ssl_mamba.py
1.58 kB
| from __future__ import annotations | |
| import os | |
| import numpy as np | |
| import torch | |
| import torch.nn.functional as F | |
| from speech_spoof_bench.model import AntiSpoofingModel | |
| from _net import WINDOW, SSLMambaNet, load_state, pad_repeat | |
| _DIR = os.path.dirname(os.path.abspath(__file__)) | |
| # HF hoanmyTran/ssl_spoofing_mamba @ 4e72dfc interspeech2025.pt -> safetensors (loss_fn.weight dropped) | |
| _CKPT = os.path.join(_DIR, "model.safetensors") | |
| class SSLMamba(AntiSpoofingModel): | |
| name = "SSL-Mamba" | |
| expected_sample_rate = 16000 | |
| batch_size = 16 # sweep 2026-11-01 (pure torch, GPUs shared): RTX 4070 Ti SUPER ~57 utt/s, plateau bs 4-32 | |
| def load(self) -> None: | |
| self.device = "cuda" if torch.cuda.is_available() else "cpu" | |
| net = SSLMambaNet() | |
| net.load_state_dict(load_state(_CKPT), strict=True) | |
| self.net = net.to(self.device).eval() | |
| if self.device == "cuda" and "5060" in torch.cuda.get_device_name(): | |
| self.batch_size = 4 # sweep 2026-11-01: RTX 5060 Ti ~28.6 utt/s at bs 2-4, ~22 at bs >= 8 | |
| def score_batch(self, audios, srs): | |
| x = np.stack([pad_repeat(a, WINDOW) for a in audios]) | |
| out = self.net(torch.from_numpy(x).to(self.device)).float().reshape(-1, 2) | |
| ls = F.log_softmax(out, dim=-1) | |
| # source _produce_evaluation_file: llr = log_softmax[:,1] - log_softmax[:,0]; class 1 = bona fide | |
| return (ls[:, 1] - ls[:, 0]).cpu().tolist() | |
| def unload(self) -> None: | |
| self.net = None | |
| if torch.cuda.is_available(): | |
| torch.cuda.empty_cache() | |