mirror of
https://github.com/exo-explore/exo.git
synced 2026-06-02 19:27:55 -04:00
## Motivation Energy was reported as a single aggregate. Split into prefill vs. generation so each phase can be analysed independently. ## Changes - `PowerSampler`: `mark_prefill_done()` + `trapezoidal_energy_range()` helper; `result()` now emits per-phase splits. - `PowerUsage` / `NodePowerStats`: optional `prefill_*` / `generation_*` fields (back-compat: `None` if unmarked). - API marks the boundary on the first non-`PrefillProgressChunk`. - `bench/exo_bench.py` surfaces the split in the log line and persists `power_usage` to JSON. - METHODOLOGY: one sentence + one bullet. ## Why It Works First non-prefill chunk *is* the boundary. Anchoring a sample there and interpolating power at the boundary makes phase energies sum exactly to the unsplit total. ## Test Plan ### Manual Testing `eco`-reserved nodes: - M3 Ultra, Qwen3-VL-4B, pp=8192/tg=1024: server 1940 J vs client 1931 J (+0.5 %) - M4 Pro, Qwen3.6-27B, pp=16384/tg=2048: server 20,292 J vs client 20,221 J (+0.35 %) ### Automated Testing 5 new tests in `test_power_sampler.py` (range integrator, splits-sum-to-total, `None`-when-unmarked, idempotency). 14/14 pass.