[RNE Rewrite] test: add an on-device performance regression harness - #1363
Draft
msluszniak wants to merge 3 commits into
Draft
[RNE Rewrite] test: add an on-device performance regression harness#1363msluszniak wants to merge 3 commits into
msluszniak wants to merge 3 commits into
Conversation
Adds apps/benchmarks, a headless Expo app that runs the task pipelines against deterministic synthetic inputs and reports load time, inference latency and peak memory as JSON, plus a driver that collects a run and a comparator that diffs two runs and fails on regressions. Built to bracket an ExecuTorch bump: run the suite on 1.3.1, bump, run it again on the same device, compare. Three things the design turns on: - A raw-execute pass isolates ExecuTorch from the pipeline. Task timings fold model.execute together with preprocessing and post-processing, which are TypeScript and unaffected by a bump. The pass loads the .pte on its own and sizes its tensors from model.schema, so it covers every method a program exports and needs no per-model wiring. - Memory is sampled in a pass of its own. Reading total PSS on Android walks /proc/self/smaps and costs milliseconds, which would otherwise land in the inference numbers. - Inputs are pure functions of their parameters. Post-processing cost is input-dependent, so a harness reading a photo off the device would move for reasons unrelated to the change under test. The comparator refuses to diff runs from different devices, and reports a metric whose workload changed as INCOMPARABLE rather than as a delta. Refs #1078
The case list is heterogeneous, so the array can only be typed as BenchCase<any> — which let a case keep compiling after the pipeline it drives renamed the method it calls. Naming the pipeline's create as a separate leading parameter of defineCase makes it its own inference site, resolved before the case body is checked, so run is checked against the real instance type. Passing create inside the literal does not work: it is then inferred alongside run and TInstance collapses to its constraint. Also stop a failed build from leaving the collector waiting forever. It holds the port, so the next attempt could not start its own.
The first waveform was a harmonic stack, and on device the FSMN VAD scored none of it as speech: the case reported zero segments, so the segmentation path never ran and the comment claiming otherwise was wrong. Replaced with a glottal pulse train swept through three formant resonators plus aspiration noise. Still not speech and still fully deterministic, but close enough in spectral shape that the VAD now opens a segment per burst (10 over the 10 s waveform) and closes it on the gap. Also document that execute.<method> and pipeline.median are not comparable to each other: the raw pass takes dynamic dimensions at the top of their declared domain, so on all-MiniLM-L6-v2 it runs a 254-token forward while the pipeline runs a 20-token one.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds
apps/benchmarks, a headless Expo app that runs the task pipelines against deterministic synthetic inputs and reports model load time, inference latency and peak memory as JSON, plus a driver that collects a run and a comparator that diffs two runs and fails on regressions.Built to bracket the ExecuTorch 1.3.1 to 1.4.1 bump: run the suite on 1.3.1, bump, run it again on the same device, compare.
Three design points worth a look:
model.executetogether with preprocessing and post-processing, which are TypeScript and unaffected by a bump. The pass loads the.pteon its own and sizes its tensors frommodel.schema, so it covers every method a program exports and needs no per-model wiring. Methods whose schema cannot be pinned to concrete shapes are reported as skipped, with the reason./proc/self/smapsand costs milliseconds, which would otherwise land in the inference numbers.modules/bench-probeis a local Expo module readingtask_vm_info.phys_footprinton iOS and total PSS on Android, both of which count the resident pages of a memory mapped.ptethat the native heap counters miss.The comparator refuses to diff runs from different devices, and reports a metric whose workload changed as INCOMPARABLE rather than as a delta. A delta inside the run's own interquartile range is reported but not failed.
Introduces a breaking change?
Type of change
Tested on
Testing instructions
yarn benchstarts a collector, sets the app'sEXPO_PUBLIC_BENCH_*variables, builds and launches the app, and writesresults/<label>-<platform>-<device>.json. It sets upadb reverseon Android and binds to the host LAN address for an iOS device.--suite fulladds the larger models,--only <id>runs a single case,--no-launchwaits for an app started by hand.The full quick suite was run on a Galaxy S26 Ultra (SM-S948B, Android 16) with all six cases reporting. A full suite run covering Whisper and Supertonic was in progress at the time of writing.
Screenshots
Related issues
Closes #1078
Checklist
Additional notes
Not yet run on iOS. The CoreML classification case is in the suite but unexercised, since CoreML programs fail to encode on the Simulator and need a physical device.
Two things the device runs surfaced that are worth knowing when reading a report:
execute.<method>andpipeline.medianare not comparable to each other. The raw pass takes dynamic dimensions at the top of their declared domain, so on all-MiniLM-L6-v2 it runs a 254 token forward while the pipeline runs a 20 token one, and the raw number comes out several times larger. Each is comparable against itself across runs, which is all the comparator asks. The resolved shapes are recorded per method.The suite is triggered by hand rather than run in CI. A host side benchmark on a CI runner would exercise none of the backends a bump actually changes, and its noise floor is wider than most regressions.