Changelog¶
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Unreleased¶
1.1.1 - 2026-09-02¶
Bugfixes¶
A worker killed while writing a large result no longer freezes the whole run. Above 16 KB a queue message crosses the pipe in more than one write, so a killed writer can leave a message whose remainder never arrives — and reading it blocks with nothing raised, before any of the pipeline’s failure handling gets a chance to run. Reachable with
top_k=None, withencodeatbatch_size >= 4, and for large-batch GPU work; library defaults were not affected. The parent now reads every child-to-parent queue through a sacrificial thread with real timeouts, so a half-written message costs a parked thread instead of the session, and the existing liveness check reports the dead worker (#83, #104).A child killed on its way out — after signalling it had finished but before its last message was flushed — left the parent waiting on that message forever, invisible to the liveness check because the finish signal was already set. This covered a worker’s end-of-work sentinel, a producer’s unprocessable-input report and per-file completion markers, and the performance tracker’s summary; all of those waits now carry a deadline and fail the run with a clear error naming what was lost (#104).
Oversized log records (exception dumps with stack traces, exactly what a dying child emits) are truncated before crossing the process boundary, narrowing the widest window for a killed child to leave the session log’s reader a half-written record (#104).
The official v3.0 model downloads (acoustic and geo,
tf/onnx/pt) could serve a stale file: the cache was judged current by byte size alone, which cannot tell two releases apart — a retrained model of the same architecture keeps its size — and let two installed versions sharing one app data directory overwrite each other’s ~0.5 GB downloads on every load. Like the label and taxonomy downloads since 1.1.0, they are now checksum-verified and cached under content-addressed names, so replacing a model in a release forces exactly one re-download; a file cached before this release is renamed to its new name after a one-time hash check, which costs an older installed version sharing the directory one re-download (#105).
1.1.0 - 2026-08-21¶
Breaking changes¶
TensorFlow is now an optional dependency (
pip install birdnet[tf];and-cudaimplies it,reprostill pins it,onnxstays a no-op alias). The base package ships ONNX Runtime and LiteRT instead, sopip install birdnetruns the 3.0 models viaonnxand the 2.4 models viabirdnet.load(.., "tf", library="litert"), and is ~1.5 GB smaller.birdnet.load("acoustic", "2.4", "tf"), thepbbackend and Perch V2 now raise aValueErrorpointing atbirdnet[tf]; install that extra to keep the previous behavior. Where LiteRT has no wheels (macOS x86_64, Windows ARM64) the base install cannot run the 2.4 models at all; see the release notes for GPU inference withonnxruntime-gpu(#94).
Added¶
Added
birdnet.set_download_progress_callback(cb)and a scopedbirdnet.download_progress_callback(cb)context manager, so an application can render its own progress for first-run downloads instead of a tqdm bar nobody sees. The callback receivesstarted, throttledprogress,retryingand one terminalfinished/failed; raising from it cancels the download (#89, #90).
Bugfixes¶
TensorFlow’s startup banner is no longer printed by every worker process; it comes from native code, which the previous logging settings could not reach. Failed-import diagnostics are still shown, and
BIRDNET_TF_VERBOSE=1restores the old output (#98).V3.0 species names could be silently wrong when two installed versions shared one app data directory, because each judged the other’s label and taxonomy downloads stale by byte size and overwrote them. Those downloads are now checksum-verified and cached per release, and the generated label files record what was actually read, so they regenerate once on upgrade (#99).
Label and taxonomy setup interrupted by a killed process left a lock directory behind, after which every later load waited out a 300 s timeout and failed until it was removed by hand; the lock now records its owner and is reclaimed when that process is gone. The acoustic V3.0 label setup is serialized across processes as well now, as the geo V3.0 one already was (#99).
A cached SavedModel from an older release was never recognised as stale, because the
pbdownloaders only checked that the files were present. Each download now records its source URL and re-downloads on a mismatch, sopband Perch V2 models cached before this release are fetched once more (#95).The
reproextra’s TensorFlow pin never applied on Windows, because its marker spelled the platformwindows/amd64instead ofwin32/AMD64(#94).birdnet.load(.., "tf", library="litert")no longer fails without TensorFlow: the loader rejected everytfload although the LiteRT interpreter never imports TensorFlow. It is now required only for the defaulttfliteinterpreter and forpb, so the 2.4 models and custom 2.4 classifiers run in a TensorFlow-free install (#91).Acoustic V3.0 confidences were sigmoid-squashed twice — the exports already apply it in-graph — which compressed every score into 0.5–0.73.
predict(..)now returns the model’s probabilities unchanged, andsigmoid_sensitivityother than 1.0 orapply_softmax=Trueraise aValueErrorfor V3.0, which need logits the exports do not expose (#86).The acoustic V3.0
pbbackend requested v2.4’s SavedModel signatures, so everypredict(..)/encode(..)died withKeyError: 'basic'; it now reads the export’sserving_defaultsignature (#86).A worker killed while processing a batch — the realistic out-of-memory case — no longer wedges the surviving workers: waiters on the ring-buffer lock it leaves held now notice the cancelled run and shut down, so the death is reported instead of hanging the call (#73, #82).
Teardown after a cancelled run no longer hangs on a message a killed child never finished writing: the parent drains the child-to-parent queues on background threads and joins its queue-reader threads with a bound (#77, #82).
A child killed while writing to the shared logging queue no longer keeps the surviving children from exiting, at the cost of the few records still buffered (#82).
The progress display’s slot and busy-worker gauges are read without taking the counter’s lock, so a killed process cannot block the stats interval; a reading may be one count behind (#82).
birdnet.load_perch_v2()required thedeviceargument at runtime although the type stub declared it optional; it now defaults to"CPU"as documented (#94).Still open: the consumer’s own read of the results queue can block on a message truncated by a killed worker (#83).
1.0.0 - 2026-08-14¶
Added¶
Added an
on_file_completecallback to acousticpredict(..)/encode(..)and their session variants, fired once per file with a single-file result, for streaming per-file persistence and live output. File inputs only, and off the inference hot path, so throughput is unaffected (#57).Added the BirdNET V3.0 (preview) acoustic model in the
tf,pb,ptandonnxbackends, all supportingpredict(..)andencode(..). Load viabirdnet.load("acoustic", "3.0", <backend>);pt/onnxneed the newbirdnet[pt]/birdnet[onnx]extras (#41).Added the BirdNET-Geomodel V3.0 (v3.0.4, 14,082 classes covering birds, insects, amphibians and mammals) in the same four backends, via
birdnet.load("geo", "3.0", <backend>). Theptbackend applies the sigmoid the TorchScript export omits, so all four return the same probabilities (#41).Added an
apply_softmaxoption to acousticpredict(..), mirroringapply_sigmoid: scores become a softmax over the model logits, useful for confidence scores (e.g. Perch V2). Defaults toFalse(#54).Added partial Python 3.14 support: TensorFlow has no 3.14 wheels, so
birdnetinstalls without it there and runs acoustic 3.0 and geo 3.0 viaonnx/pt, while TensorFlow-only paths raise a clear error instead of anImportError(#55).
Changed¶
The inference pipeline now creates its processes with
spawnon all platforms instead of inheriting Linux’sfork, which could deadlock workers after TensorFlow had started its multi-threaded runtime. A globally fixed start method is honored andBIRDNET_START_METHODoverrides both, sofork/forkserverstay available by opt-in (#63).The V3.0 models now share the geomodel’s versioned taxonomy (
taxonomy_v0.2-Jun2026.csv), which resolves every geo label. Estonian (et) was dropped from the V3.0 languages, as the new taxonomy has no Estonian column (#41).The progress callback now runs on a background thread with a copy of the caller’s context (contextvars), matching the new
on_file_completecallback (#53).
Bugfixes¶
A pipeline process that dies mid-run — typically an operating-system kill when memory runs out — is now reported with its name and exit code instead of hanging the call forever. Not covered: a worker killed while processing a batch still deadlocks the survivors on Linux and macOS (#73).
Fixed the progress callback’s closing update, which reported zero processed segments for completed runs and published nothing at all for a run without predictions, leaving the call waiting indefinitely (#75).
Model, label and taxonomy downloads now retry with a growing back-off instead of failing on the first transient network fault; permanent client errors still fail immediately.
Removed a fixed ~1 s barrier from every
run_arrays(..)call — on a warm session a 3 s clip went from 1069 ms to 39 ms. Cancelled runs still tear down on the poll interval.Fixed an assertion firing in the prediction and encoding workers when the ring-buffer scan finds no readable slot, which aborted the run instead of taking the clean exit already there.
Producers and the performance tracker no longer attach the ring buffers from inside a
forkchild, whereSharedMemory(create=False)could block forever on a lock CPython does not reinitialize afterfork.Fixed corrupt rows in acoustic prediction/encoding output caused by growing the internal result buffer with
numpy.ndarray.resize, plus an off-by-one in the initial segment count (#50).Geo model v3.0 caches now self-heal across releases: a cached SavedModel or label files from an older release were not detected as stale, so a version bump could keep serving outdated labels (#41).
V3.0 label files now record which taxonomy they were generated from and regenerate when it changes; the taxonomy is shared, so the first model to fetch a new one made it look current for every other model (#41).
0.2.16 - 2026-05-09¶
Added¶
Add support for overriding BirdNET’s application-data directory via an environment variable
BIRDNET_APP_DATA, enabling users to place downloaded models/benchmarks in a custom location (useful for deployments with restricted home directories or shared storage).
Bugfixes¶
Fixed acoustic inference session being aborted on macOS when stats were enabled: hardened parent/child memory tracking against
psutil.AccessDenied, and replaced the two tracked semaphores with a wrapper that mirrors the count into shared memory soget_value()works on macOS (#39)Fixed float16 quantization of segment timestamps in prediction results, which caused up to ±0.05 s drift in CSV/DataFrame/Parquet output (#38, #42). Also closed an analogous hole in encoding results where a hop duration that is exactly representable in float16 (e.g. hop=1.5) could still produce drifting accumulated timestamps. Timestamps are now always materialized at >= float32 precision at the source.
0.2.15 - 2026-05-02¶
Bugfixes¶
Fix issue with float16 input durations and hop duration not being exactly representable, which caused rounding errors to accumulate across segments and thus wrong segment times in the output (#32)
0.2.14 - 2026-04-30¶
Bugfixes¶
0.2.13 - 2026-04-06¶
Changed¶
Changed sigmoid function to match birdnet_analyzer by @Josef-Haupt
Bugfixes¶
Fixed issue #29
0.2.12 - 2026-02-22¶
Added¶
Added convenience functions to export embeddings by @Josef-Haupt
Added some code documentation
Changed¶
Updated flat sigmoid to match birdnet_analyzer by @Josef-Haupt
Bugfixes¶
Fixed issue with one test on Python 3.11 & 3.12
Fixed issue with building package in tox environments
0.2.11 - 2025-12-09¶
Added¶
Added model metadata to output
Added more classes to
__init__.pyfor easier importsAdded skipping of unprocessable inputs
Fixed¶
Loading multiple GPUs in parallel processes was not possible
Fixed hanging problem after error in processing occurred
Changed¶
Renamed many of the classes and functions for better clarity
0.2.10 - 2025-11-28¶
Added¶
Added support for Perch model v2
Fixed¶
Removed support for LiteRT on macOS ARM64 due to incompatibility issues
0.2.9 - 2025-11-27¶
Added¶
Added option to supervise progress using callback function during inference
0.2.8 - 2025-11-26¶
Added¶
Added option to predict and encode raw audio numpy arrays
0.2.7 - 2025-11-25¶
Added¶
Added parameter
speedto control playback speed of audio during inference
0.2.5 - 2025-11-17 & 0.2.6 - 2025-11-21¶
Bugfix¶
Changed¶
Removed
litertinstall option, now litert is always installed if possibleRename
tflibrary totfliteto better reflect the usage of TFLite/LiteRTImproved prediction speed, esp. for half-precision models (+10 seg/s)
Lowered dependencies
Update
ai-edge-litertto version 2.0.3 onreproBetter download progress indication of model files
Model loading in tests is done before running other tests
Added¶
Added
reprooption to be able to get reproducible resultsAdded support for Python 3.13
Added CI on GitHub Actions for testing on multiple OS and Python versions
Removed¶
Remove unused dependencies
numbaandresampy
0.2.4 - 2025-11-05¶
Bugfixes¶
Fixed issue with loading supported files from a folder
Changed¶
Increased half-precision prediction speed
Set “pyarrow==22.0.0”
Set “numpy==2.0.2” because of compatibility with
perch-hopliteSet default “half_precision” parameter to False because of lower speed
Added¶
Add half precision to CLI
0.2.3 - 2025-11-04¶
Added¶
Added support for Python 3.12
Changed¶
Changed tensorflow to newest version 2.20.0
0.2.2 - 2025-11-03¶
Added¶
Added support for running multiple sessions in a row or in parallel using threading or multiprocessing
Each session has its own logger and log file
Changed¶
Changed naming of the benchmark output files
0.2.1 - 2025-10-29¶
Added¶
Added parameter
is_ravento load function to specify whether a custom Protobuf model is a Raven model or notFix int8 acoustic model wrong inference parameters
Added tests
0.2.0 - 2025-10-27¶
Changed¶
Refactored the whole codebase to be able to load model and predict scores in two separate steps
0.2.0a0 - 2025-07-29¶
Changed¶
Refactored the whole codebase
0.1.7 - 2025-03-19¶
Changed¶
Switched model download links from TUCcloud to Zenodo #10
Fixed¶
Added check for mono files #9
0.1.6 - 2024-09-04¶
Added¶
Support for multiprocessing using
predict_species_within_audio_files_mp
Changed¶
Separate
ModelV2M4TFLiteintoAudioModelV2M4TFLiteandMetaModelV2M4TFLiteSeparate
ModelV2M4ProtobufintoAudioModelV2M4ProtobufandMetaModelV2M4ProtobufSeparate
ModelV2M4intoAudioModelV2M4andMetaModelV2M4Move v2.4 models to
birdnet.models.v2m4Yield results of
predict_species_within_audio_fileinstead of returning an OrderedDictExtracted method
predict_species_within_audio_fileandpredict_species_at_location_and_timefrom their respective modelset default value for
batch_sizeto 100
0.1.5 - 2024-08-16¶
Fixed¶
Custom Raven audio model didn’t return same results as custom TFLite model because of sigmoid layer
TFLite meta model was not returning correct results
Changed¶
Rename
CustomModelV2M4TFLitetoCustomAudioModelV2M4TFLiteRename
CustomModelV2M4RaventoCustomAudioModelV2M4Raven
0.1.4 - 2024-08-13¶
Added¶
Support to load custom TFLite models using
CustomModelV2M4TFLiteSupport to load custom Raven (Protobuf) models using
CustomModelV2M4Raven
0.1.3 - 2024-08-13¶
Changed¶
Make CUDA dependency optional, install with
birdnet[and-cuda]
Fixed¶
Bugfix ‘ERROR: Could not find a version that satisfies the requirement nvidia-cuda-nvcc-cu12 (Mac/Ubuntu/Windows)’ (#4)
0.1.2 - 2024-08-07¶
Added¶
Add GPU support by introducing the Protobuf model (v2.4)
Changed¶
Rename class ‘ModelV2M4’ to ‘ModelV2M4TFLite’
‘ModelV2M4’ defaults to Protobuf model now
Sorting of prediction scores is now: score (desc) & name (asc)
Fixed¶
Bugfix output interval durations are now always of type ‘float’
0.1.1 - 2024-08-02¶
Added¶
Add parameter ‘chunk_overlap_s’ to define overlapping between chunks (#3)
Removed¶
Remove parameter ‘file_splitting_duration_s’ instead load files in 3s chunks (#2)
Remove ‘librosa’ dependency
0.1.0 - 2024-07-23¶
Initial release