Behavior Classification Inference Pipeline — 4.4× Throughput
Reworked the production core package that extracts 903 features from 6-axis IMU raw signal, for 4.4× throughput and 3.3× end-to-end speedup.
Problem
A core package took 6-axis IMU raw signal from the sensors, cut it into windows, extracted 903 features and classified behavior. It was the bottleneck for the whole pipeline. Processing a single day of one animal took 65.8 seconds end to end, and every additional animal pushed the retraining and reprocessing cycle out further.
The catch: touching this code could change model output. If one feature’s value shifts even slightly, the trained classifier’s verdict wavers. Trading correctness for speed was not an option.
What I did
I measured the bottleneck before assuming where it was. One third-party library call was eating most of the time.
- Replaced that library with a NumPy reimplementation. Before swapping, I verified numerical equivalence against the existing output. Only after equivalence was confirmed did I make the change — so the bottleneck disappeared without any change in results.
- Selectively vectorized the slowest feature set: 61 of 63. The remaining 2 stayed per-row — vectorizing them cost more in memory and code complexity than the speed was worth. The goal was not to convert everything, only what paid off.
- Moved model loading from a local-file fallback structure to a single registry path, making it traceable which model is actually being served.
- Added an input validation gate and removed code duplication within the bounds of unchanged behavior.
Result
Measured on 24 hours of real-animal raw data — 2.16M rows / 8,640 windows. Full suite 208 passed / 0 failed — not a single output value changed.
Measurement
- Subject
- 24 hours of real-animal IMU raw signal (6-axis, 25Hz)
- Sample
- 2.16M rows → 8,640 windows
- Baseline
- Same input before the rework · 96 win/sec · 65.8s end-to-end
- Verification
- Numerical equivalence of output verified before and after the swap · full suite 208 passed / 0 failed