Pre-trained Models¶
Trained and converted models are published as GitHub release assets, not tracked repository files. Download a bundle from the latest release.
What's in a bundle¶
Every file in a bundle shares one basename,
BirdNET_Tiny_N6_<REGION>_<SPECIES>_V<VERSION>, where the species count covers
bird species only — nuisance and background outputs are not counted in the name
but are part of the ordered output contract.
| File | Use it for |
|---|---|
<basename>_INT8.tflite |
Deploying to the STM32N6 — this is the model you flash |
<basename>_model_config.json |
Input, frontend, and class contract; drives the firmware config |
<basename>_labels.txt |
Ordered output labels |
<basename>_FP32.keras |
Host inference, fine-tuning, re-conversion |
<basename>_original_FP32.keras |
Pre-QAT checkpoint, for retraining from an untouched state |
<basename>_FP32.onnx |
Host and interchange inference |
<basename>_INT8_stedgeai_report.txt |
Memory footprint and NPU operator coverage |
<basename>_model_card.md |
Contract, provenance, measured accuracy, and on-board timing |
A bundle whose model was exported split carries these as well. The firmware runs
a single network, so _INT8.tflite above is still what you flash; these exist
so a species-list change can be pushed without resending the whole model.
| File | Use it for |
|---|---|
<basename>_INT8_backbone.tflite |
Audio to embeddings. Flashed once and reused across heads |
<basename>_INT8_classifier.tflite |
Embeddings to scores. The only part that changes with the species list |
<basename>_INT8_backbone.tflite.gz, <basename>_INT8_classifier.tflite.gz |
The same two, gzipped; the head is what an over-the-air update carries |
<basename>_INT8_backbone.tflite.fingerprint.json |
Identity of the backbone. A replacement head must be calibrated against a matching one |
<basename>_INT8_classifier_labels.txt |
The head's own ordered labels, so an updated head brings its species list with it |
Chaining the backbone into the classifier reproduces _INT8.tflite; both halves
are gated on that equivalence before either is published. To build a further
head for an already-flashed backbone, see
Updating the head against a flashed backbone.
LICENSE-MODELS.md and ACCEPTABLE_USE.md ship alongside — see
License & Acceptable Use.
The model, config, and labels are one contract
The TFLite model, _model_config.json, and _labels.txt describe a single
trained model. Keep them together and never mix sidecars across bundles or
versions — the frontend parameters and output ordering will not match.
The model card records the exact input contract (sample rate, chunk duration, output count), the accuracy the model reached on its evaluation catalog, and its measured on-board timing. Read it before deploying.
Running a bundle on the board¶
Everything the firmware needs is in the bundle; no extra downloads.
- Install the toolchain and create
config.json— see Deployment for X-CUBE-AI, STM32CubeProgrammer, and ARM GNU setup. - Prepare an SD card with test audio — see
SD card preparation. WAV sample rate
must match the
sample_ratein_model_config.json; mismatched files are skipped. -
Compile, flash, and run:
# Wherever the extracted bundle lives; the globs below pick the files out # of it, so nothing depends on which region or version you downloaded. BUNDLE=~/Downloads/<bundle> python -m birdnet_stm32 board-test \ --model_path "$BUNDLE"/*_INT8.tflite \ --model_config "$BUNDLE"/*_model_config.json \ --labels "$BUNDLE"/*_labels.txt
board-test generates the N6-optimized binary with stedgeai, flashes it over
serial, runs inference on every WAV on the SD card, and streams the top
predictions back over UART. Add --save_results results.csv to capture them.
Validating on device¶
Release bundles do not ship fixed validation inputs. To run stedgeai validate
against a downloaded model, supply your own representative audio — see
Deployment — or re-run
conversion locally to generate a validation set.