SSL-Mamba / ssl_mamba.py
korallll's picture
Wrapper code (speech-spoof-bench)
ae9d1a9 verified
Raw History Blame Contribute Delete
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
@torch.no_grad()
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()