Audio Classification
Transformers
Safetensors
Japanese
animescore_ranknet
feature-extraction
audio
speech
preference
anime
custom_code
Instructions to use spellbrush/animescore with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use spellbrush/animescore with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("audio-classification", model="spellbrush/animescore", trust_remote_code=True)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("spellbrush/animescore", trust_remote_code=True, dtype="auto") - Notebooks
- Google Colab
- Kaggle
| """Sanity check for the AnimeScore HuBERT release. | |
| What it verifies: | |
| 1. modeling_animescore.AnimeScoreRankNet can be built from config.json. | |
| 2. model.safetensors loads with zero missing/unexpected non-SSL keys. | |
| 3. A forward pass on a 3-second random waveform runs and returns a finite scalar. | |
| 4. (Optional) If --wav is given, prints the AnimeScore for that file. | |
| Usage: | |
| python sanity_test.py | |
| python sanity_test.py --wav path/to/clip.wav | |
| """ | |
| import argparse | |
| import math | |
| import os | |
| import sys | |
| import torch | |
| from safetensors.torch import load_file | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--wav", help="Optional: score this wav file as a real-data check.") | |
| ap.add_argument("--device", default="cuda" if torch.cuda.is_available() else "cpu") | |
| args = ap.parse_args() | |
| here = os.path.dirname(os.path.abspath(__file__)) | |
| sys.path.insert(0, here) | |
| from modeling_animescore import AnimeScoreConfig, AnimeScoreRankNet | |
| print("[1/4] Building model from config.json...") | |
| cfg_path = os.path.join(here, "config.json") | |
| if not os.path.exists(cfg_path): | |
| raise FileNotFoundError(cfg_path) | |
| cfg = AnimeScoreConfig.from_json_file(cfg_path) | |
| model = AnimeScoreRankNet(cfg).to(args.device).eval() | |
| print(f" backbone = {cfg.ssl_backbone}") | |
| n_head = sum(p.numel() for n, p in model.named_parameters() if not n.startswith("ssl.")) | |
| n_ssl = sum(p.numel() for n, p in model.named_parameters() if n.startswith("ssl.")) | |
| print(f" ssl = {n_ssl/1e6:.2f} M, head = {n_head/1e6:.2f} M") | |
| print("[2/4] Loading head weights from model.safetensors...") | |
| sd = load_file(os.path.join(here, "model.safetensors")) | |
| missing, unexpected = model.load_state_dict(sd, strict=False) | |
| head_missing = [m for m in missing if not m.startswith("ssl.")] | |
| if head_missing: | |
| raise RuntimeError(f"head keys missing after load: {head_missing}") | |
| if unexpected: | |
| raise RuntimeError(f"unexpected keys in safetensors: {unexpected}") | |
| print(f" loaded {len(sd)} head tensors, 0 missing, 0 unexpected.") | |
| print("[3/4] Forward pass on 3 s of random audio...") | |
| wav = torch.randn(1, 16000 * 3).to(args.device) | |
| with torch.no_grad(): | |
| s = model.score(wav).item() | |
| if not math.isfinite(s): | |
| raise RuntimeError(f"non-finite score: {s}") | |
| print(f" score = {s:+.4f} (random audio; value is uninformative, just non-NaN check)") | |
| if args.wav: | |
| print(f"[4/4] Scoring real audio: {args.wav}") | |
| import torchaudio | |
| try: | |
| import soundfile as sf | |
| data, sr = sf.read(args.wav, dtype="float32", always_2d=True) | |
| wav = torch.from_numpy(data.T).contiguous() | |
| except Exception: | |
| wav, sr = torchaudio.load(args.wav) | |
| if wav.size(0) > 1: | |
| wav = wav.mean(0, keepdim=True) | |
| if sr != cfg.target_sr: | |
| wav = torchaudio.functional.resample(wav, sr, cfg.target_sr) | |
| with torch.no_grad(): | |
| s = model.score(wav.to(args.device)).item() | |
| print(f" AnimeScore({os.path.basename(args.wav)}) = {s:+.4f}") | |
| else: | |
| print("[4/4] (skipped) Pass --wav to score a real audio file.") | |
| print("\nAll sanity checks passed.") | |
| if __name__ == "__main__": | |
| main() | |