stratus-labs/nocturne-v1-teacher
Nocturne v1.1 (Teacher) — Bioacoustic Species Recognition for Non-Bird Taxa
Nocturne is a bioacoustic species classifier trained by Stratus Labs covering the taxa that BirdNET and Perch don't: insects, amphibians, non-bird mammals, and reptiles. It's the "night side" of the soundscape — the taxa that are dominantly nocturnal or crepuscular, whose acoustic signal is the half of biodiversity monitoring bird-focused models leave behind.
v1.1 (this revision) uses a 3× higher learning rate than v1 during backbone fine-tuning. Independent runs at both LRs plateaued around macro-F1 0.10; v1.1 edged past by ~3 %. Prior v1 weights are preserved in the commit history if you want to pin to revision=<v1-commit-sha>.
A newer model is available. **Nocturne v1.2d** beats this one on the same held-out test set — calibrated macro-F1 0.1511 vs 0.1488 and mAP 0.1541 vs 0.1498. One caveat before you switch: on a held-out monitoring site v1.2d's anuran top-1 is 0.138 against this model's 0.544, so for deploying to an unseen site for anuran work, v1 may still suit you better. v1 remains the model behind the live endpoint below.
Try it live (no install)
Live public endpoint hosted on Stratus Labs infra (Apple M4 Max, MPS-backed):
- UI: https://nocturne.runstratus.com/ — drag-and-drop upload
- API:
curl -X POST "https://nocturne.runstratus.com/predict?top_k=5&threshold=0.15" \
-F "file=@your_clip.wav"Rate-limited to 10 requests per minute per IP. Uploads capped at 25 MB / 5 minutes per request.
Python client (one-liner install):
pip install nocturne-clientfrom nocturne_client import Nocturne
n = Nocturne() # points at nocturne.runstratus.com by default
for p in n.predict("clip.wav", top_k=5).predictions:
print(f"{p.score:.3f} {p.species}")Model at a glance
See `stratus-labs/nocturne-v1-mini` for a distilled ~9.3M-parameter EfficientNet-B1 student for CPU / edge deployment.
Evaluation
Real numbers, run on the held-out splits. Earlier drafts of this card cited macro-F1 at threshold 0.5 (too high — kills recall). These are the corrected numbers at threshold 0.3 (default) and with per-class thresholds calibrated on val:
Per-class thresholds are shipped as thresholds.json in this repo. Use them for best F1; use sigmoid > 0.3 (or 0.15 for higher recall) as a simple default. mAP is threshold-independent and the honest number for downstream ranking-quality use cases (top-k, similarity search).
Class coverage: 2,182 species in vocab; 732 have positives in the val split (long-tail — many rare species have zero test-set representation). Median calibrated threshold: 0.30. Range: 0.02–0.94.
Full report at eval_report.json in this repo. Reproduce with:
python -m soundscape.calibrate_and_eval \
--config soundscape/configs/ast_nonbird.yaml \
--checkpoint model.safetensors --arch ast \
--out-dir report/vs BirdNET on non-bird taxa (release headline)
Head-to-head on 300 randomly-sampled non-bird test clips (insects, amphibians, mammals, reptiles). Top-1 species identification:
That's an 11.5× lift. BirdNET catches ~7% because a handful of amphibians and mammals slip into its vocab, but for the non-avian half of the soundscape it's the wrong tool and Nocturne is the fit-for-purpose one. This is the point of the release.
Taxonomic coverage (unchanged from v1)
Intended use
- Passive acoustic monitoring for biodiversity surveys, especially where BirdNET/Perch leave gaps.
- Agricultural pest early warning (Orthoptera + Cicadidae are heavily represented via InsectSet459).
- Amphibian presence surveys.
- Ecological research and citizen-science integration.
Out of scope
- Absence detection — a negative prediction means "no confident detection," not "the species is absent."
- Bird identification — use BirdNET / Perch. Nocturne can separate bird from non-bird signal but is not tuned for species-level bird ID.
- Bat echolocation — most is > 8 kHz relative to our 16 kHz sample rate. Use a dedicated ultrasonic pipeline.
- Legal or conservation determinations without human review.
Training data
Total training exposure: ~42k annotated non-bird clips across 2182 species.
Training recipe (v1.1)
- Backbone: AudioSet-pretrained AST (86M params). 3-epoch head warm-up with backbone frozen; then joint fine-tune.
- Optimizer: AdamW — backbone 1.5e-4, head 3.0e-3 (3× v1), cosine schedule, weight decay 0.01, grad clip 1.0.
- Loss: focal BCE (γ=2.0) for long-tail multi-label imbalance.
- Augmentation: SpecAugment (2×32 freq masks, 2×40 time masks), MixUp (α=0.3).
- Sampler: √-frequency class-balanced.
- Precision: bf16 mixed precision + gradient checkpointing.
- Batch: 32.
- 40 epochs total, best-of-N by val macro-F1 tracked.
Inference (Python)
model.py in this repo is a standalone, dependency-light loader (torch, torchaudio, transformers, safetensors, soundfile). It loads strictly and remaps parameter names across transformers versions.
from huggingface_hub import snapshot_download
import sys
path = snapshot_download("stratus-labs/nocturne-v1-teacher")
sys.path.insert(0, path)
from model import load_nocturne, predict_file
model, vocab, thresholds = load_nocturne(path) # raises on any missing/unexpected key
for species, score in predict_file(model, "clip.wav", vocab, top_k=5):
print(f"{score:.3f} {species}")
# thresholds[species] = per-class calibrated threshold (see Evaluation); predict_file(..., threshold=0.3) filters instead of top-ktransformers compatibility (fixed 2026-09-06). This checkpoint was saved under transformers 5.8. transformers 5.16 renamed every AST encoder parameter, and loading withstrict=Falseon a newer install silently left the backbone at AudioSet weights — only the head loaded, with no error.load_nocturnedetects the naming, remaps, and refuses a partial load. Verified identical outputs on 5.8-style and 5.16-style names. If you reconstruct the model yourself, never usestrict=False.
Limitations and ethical considerations
- Coverage bias. Over-represents temperate-zone Orthoptera and Cicadidae (via InsectSet459) and geographies over-represented on iNaturalist. Under-represented: tropical arthropods, deep-forest amphibians, most reptiles.
- Recording bias. iNat recordings are opportunistic. Do not interpret model confidence as population density.
- Absence != silence. Many target species have narrow calling windows (breeding season, temperature, time of day). A survey without detections is not a survey without species.
- Dual-use. Species localization from acoustic recordings can be misused (e.g. locating rare taxa for illegal collection). Consider redacting precise GPS in public datasets built with this model.
- Data licensing. Downstream users must comply with InsectSet459 (CC-BY-4.0) and iNat 2024 (MIT). Redistribution of raw training clips is not permitted; this model is a derived work.
Citation
@misc{stratuslabs2026nocturne,
title = {Nocturne: Bioacoustic Species Recognition for Non-Bird Taxa},
author = {Stratus Labs},
year = {2026},
publisher = {Hugging Face},
howpublished = {\url{https://huggingface.co/stratus-labs/nocturne-v1-teacher}}
}Please also cite the training datasets:
- InsectSet459 (Zenodo 10.5281/zenodo.18554693)
- iNat Sounds 2024 (Chasmai et al., NeurIPS 2024)
