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.

4.4×throughput24h real-animal · 2.16M raw rows
423win/sec8,640 windows · was 96
208 / 0pass / failfull suite · output-equivalence verified

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

Throughput · win/sec · higher is better
before
96
after
423
End-to-end pipeline · seconds · lower is better
before
65.8
after
19.9

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