Skip to content

Single owner for edge timings and variance (#72, #73)#75

Open
ff225 wants to merge 1 commit into
fix/sciot-011-device-state-managerfrom
fix/sciot-072-073-edge-ema-single-owner
Open

Single owner for edge timings and variance (#72, #73)#75
ff225 wants to merge 1 commit into
fix/sciot-011-device-state-managerfrom
fix/sciot-072-073-edge-ema-single-owner

Conversation

@ff225

@ff225 ff225 commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Closes #72. Closes #73.

Stacked on #74 — base is fix/sciot-011-device-state-manager, not main. Review #74 first; this diff is only the second commit.

Two tangled problems in the same ~15 lines, so the fixes land together.

#72 — the edge EMA was applied twice

track_inference_time applied an EMA with a hard-coded alpha = 0.2 to self.inference_times. That dict is device_profiles[device_id]["edge_inference_times"], passed by reference (edge_initialization.py:140,152model_manager.py:285). The request handler then applied the configured EMA on top of it.

Two consequences:

  • Over-smoothing. Edge times were smoothed twice, device times once, so the two sides of the offloading cost comparison responded to change at different rates — the edge estimate lagged and the split point adapted slower than intended.
  • The config was bypassed. Make EMA alpha configurable instead of hard-coded 0.5 #9 made ema_alpha configurable, but the first application ignored it.

The fix turned out simpler than the issue suggested. Edge.run_inference already measures each layer and returns the raw times — the decorator was cronometering the same call a second time. So rather than reconciling the two paths, one is removed: the decorator is now instrumentation only, and DeviceStateManager.update_edge_times is the single place that smooths, with the configured alpha.

#73 — a second variance detector nobody read

Edge.variance_detector was a process-global detector fed from the same decorator. No production code calls should_retest_offloading() on it — every such call is in tests. It burned time on the hot path and logged re-test warnings that triggered no re-test. Removed; the per-device detectors from #74 are now the only ones.

Fallout cleanup

With the decorator no longer writing, ModelManager.inference_times had no writers left, so the plumbing goes: the inference_times/variance_detector params, the edge_inference_times argument threaded through Edge.run_inference and _get_model_manager, save_inference_times (no callers), and a commented-out __init__ referencing attributes that no longer exist.

Two judgement calls worth a look

  • time.time()perf_counter() in run_inference. Now that this is the authoritative measurement of edge cost, a monotonic clock is the right tool — but it is a change nobody asked for.
  • scripts/analysis/variance_analysis.py moved to the per-device API. Extract per-device state out of RequestHandler (#11) #74 broke it (it read RequestHandler.variance_detector) and I missed it there. Worth knowing: that script reads the running server's in-memory state from a separate process, so it always found an empty detector. This makes it coherent, it does not make it useful.

Testing

244 passed, 1 skipped (fast suite + HTTP end-to-end). New tests/unit/test_edge_inference_time_ownership.py pins the single-EMA behaviour and the configured alpha. ruff clean on touched files (the 8 findings in variance_analysis.py are pre-existing — confirmed against main).

⚠️ Edge.run_inference is not exercised by the fast suite — its real tests are marked model_artifact. The regression tests here cover signatures and the EMA maths, but the edge inference chain itself has not been run end-to-end. Worth a run with the model artifacts before merging.

Two tangled problems in the same code path; the fixes share the same lines, so
they land together.

#72 — Edge per-layer times were smoothed twice. `track_inference_time` applied
an EMA with a hard-coded alpha=0.2 to `self.inference_times` — which is the
very dict `device_profiles[device_id]["edge_inference_times"]`, passed by
reference — and the request handler then applied the configured EMA on top.
Edge times were therefore smoothed twice while device times were smoothed once,
so the two sides of the offloading cost comparison responded to change at
different rates; and the `ema_alpha` setting added in #9 never reached the
first application.

`Edge.run_inference` already measures and returns the raw per-layer times, so
the decorator's copy was redundant. It is now instrumentation only, and
`DeviceStateManager.update_edge_times` is the single place that smooths, with
the configured alpha. The timing there now uses perf_counter rather than
time.time, since it became the authoritative measurement.

#73 — `Edge.variance_detector` was a second, process-global detector fed from
the same decorator. Nothing ever read it: no production code calls
`should_retest_offloading()` on it, so it only burned time on the hot path and
logged re-test warnings that triggered no re-test. Removed; the per-device
detectors from #11 remain the only ones.

Also drops the now-unwritten `inference_times` plumbing from ModelManager,
`save_inference_times` (no callers), and a commented-out __init__ referencing
attributes that no longer exist. `scripts/analysis/variance_analysis.py` moves
to the per-device API.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant