quantize
birdnet_stm32.conversion.quantize
¶
Post-training quantization (PTQ) conversion from Keras to TFLite.
Provides representative dataset generation and TFLite conversion with float32 I/O and INT8 internal ops for STM32N6 NPU deployment.
calibration_source(data_path_train, classes)
¶
Audio files that INT8 calibration draws from: the training files of the model's classes.
The draw from them is stratified by class folder and seeded. Calibrating on
field recordings instead (--calibration_dir, 1.5 to 2.1) was measured
twice and never helped: 1.5 Raw catalog -0.022 at flat WABAD; 2.2's N6-B0
with a 50/50 focal + field set, WABAD bench 0.4685 -> 0.4619.
Source code in birdnet_stm32/conversion/quantize.py
stratified_sample_paths(file_paths, num_samples, *, seed, exclude=None)
¶
Select an exact, deterministic, class-balanced audio manifest.
Source code in birdnet_stm32/conversion/quantize.py
representative_data_gen(file_paths, cfg, num_samples=100, snr_threshold=0.0)
¶
Build a representative dataset generator for TFLite PTQ calibration.
Yields one input tensor per iteration in the exact shape expected by the model. Includes quiet and nuisance recordings by default because they are part of the deployed input distribution and every requested calibration path must contribute deterministically. Callers may opt into energy filtering.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_paths
|
list[str]
|
Audio file paths to sample from. |
required |
cfg
|
dict
|
Training config dict (sample_rate, num_mels, spec_width, chunk_duration, fft_length, audio_frontend, mag_scale). |
required |
num_samples
|
int
|
Maximum number of samples to draw. |
100
|
snr_threshold
|
float
|
Minimum RMS energy for a chunk to be included (0 to disable). |
0.0
|
Yields:
| Type | Description |
|---|---|
list[ndarray]
|
Single-element list containing the input tensor with batch dimension. |
Source code in birdnet_stm32/conversion/quantize.py
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | |
range_percentile(name)
¶
The range percentile for an activation tensor (or QAT boundary) by name.
clip_activation_ranges(calibrated, samples, percentile=range_percentile)
¶
Shrink a calibrated model's activation ranges to a percentile of the calibration values.
calibrated is the converter's calibrate-only model, whose tensors carry the
min/max calibration measured. Each tensor's values on samples are binned
between that min and max, and the range is cut to the given percentile at each
end (the low end only where it is negative); percentile is one value or a
function of the tensor name (default range_percentile). The model input and
outputs keep min/max: clipping the outputs would flatten the top scores. Ranges
only shrink.
Source code in birdnet_stm32/conversion/quantize.py
convert_to_tflite(model, rep_data_gen, output_path, per_tensor=False)
¶
Convert a Keras model to quantized TFLite with float32 I/O and INT8 internals.
Full INT8 post-training quantization: the converter calibrates every
activation range on rep_data_gen, the ranges are clipped to
range_percentile of the same data (clip_activation_ranges),
and the model is quantized with those ranges.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Model
|
Loaded Keras model. |
required |
rep_data_gen
|
Callable[[], Iterable[list[ndarray]]]
|
Callable returning an iterable of [input_tensor] for calibration. |
required |
output_path
|
str
|
Path to save the .tflite model. |
required |
per_tensor
|
bool
|
If True, use per-tensor instead of per-channel quantization. |
False
|
Returns:
| Type | Description |
|---|---|
bytes
|
Raw TFLite model bytes. |