Proof-of-concept track · Bench experiments

What two devices say about on-device inference cost

Before predicting the cost of running a language model on a device, Stargazer v2 measured it: a reproduction of the Stargazer v1 regressions, then latency, memory and energy of three Qwen2.5 models under llama.cpp on a laptop and an Android phone.

Pilot measurements — devices · — models · one quantization Target: ICSE 2028

Three findings

Memory

Peak memory is a property of the loaded model: on the laptop it moved by at most — across output lengths.

Fixed vs. marginal cost →
Latency & energy

On stable hardware they split into a fixed load cost plus a per-token cost (R² ≥ — on the laptop).

Fixed vs. marginal cost →
Transfer

How reliably cost can be measured and modelled depends on the device: the phone admits no single roofline correction (ratios —).

Roofline validation →

Findings as stated in methodology.tex §Summary; the numbers are recomputed from data/.

How to read this page

Each result section comes from its own measurement run, so absolute speeds differ between sections: laptop decode of the 0.5B model is — tok/s in the latency run, — in the roofline run and — on the CPU backend of the llama-bench session. Compare values within a section. Hover a number to see the file it comes from.

Reproducing Stargazer v1

Stargazer v1 (Dantas Cruz et al., SMDS 2020) estimated the performance of clustering applications on an edge cluster from static code complexity and input size. Before adapting that method to language models, the team re-ran its released regression scripts on the v1 dataset: — rows of clustering benchmarks repeated on a Raspberry Pi 3 cluster.

What had to be fixed

The released scripts select columns by position. Their header comments still list the positions of an earlier, wider layout, while the released dataset has fewer columns (its header is listed in README.md). The _fixed copies in scripts/ select by the positions of the released file. They fit every target with the same polynomial degree (—), whereas v1 reports metric-specific degrees for some targets, which is the paper's explanation for the larger gaps in memory and CPU utilization.

Trained on the same data for duration only, the original DNN reached R² = —, against — for the polynomial fit (methodology.tex). For one target and two input features, the network adds little over a polynomial; its value in v1 was predicting several dependent metrics jointly.

What transfers, and what does not

The method's skeleton transfers: measure, fit a regression, validate on held-out data. Three things do not: the input feature (static code complexity, computed with Singularity, has no analogue for a downloaded weights file), the hardware (a cluster versus one consumer device) and the task (distributed clustering versus local autoregressive inference).

Reproduce
Scripts
scripts/ml_regression_{duration,energy,memory,cpu,tps,breadps}_fixed.py, scripts/ml_dnn_duration_fixed.py
Input
client_Z.csv in the v1 dataset layout for the regressions; all_clusterers_1.csv for the DNN. Neither file is committed; the v1 datasets are published in brenodan/stargazer (fork: luanaa2005/stargazer).
Run
from the folder that holds the input file:
python <repo>/scripts/ml_regression_duration_fixed.py

Testbed

Three instruction-tuned Qwen2.5 checkpoints (—), all quantized to Q4_K_M and distributed as GGUF. Holding the family and the quantization fixed and varying only parameter count follows v1's one-variable-at-a-time design. Q4_K_M is llama.cpp's default recommendation for on-device use; the — checkpoint takes — bytes at Q4_K_M against — at fp16, — smaller.

On both devices llama.cpp was built from source and ran on the CPU only for the main runs; the backend comparison in §6.5 is the one exception. Memory bandwidth was measured rather than taken from vendor specifications, because the roofline estimate in §6.4 needs the bandwidth a single thread actually sustains. On the phone, scripts/bandwidth_test.c copies an array of — doubles — times and reads back a checksum so the compiler cannot drop the copy; on the laptop an equivalent NumPy measurement was used.

Reproduce
Script
scripts/bandwidth_test.c (phone); the laptop's NumPy script is not committed
Output
bandwidth column of data/roofline.csv
clang -O2 scripts/bandwidth_test.c -o bandwidth_test
./bandwidth_test

Measurement protocol

Source: methodology.tex §Measurement Protocol. Run counts for energy are in the table of §6.2.

Not recorded in the repository

These details are not in the repository or in the experiment report on Overleaf. They are listed so a reader knows what a re-run cannot copy exactly.

Results

6.1 · Latency and memory

LaptopPhone

Prefill throughput (tok/s)

Decode throughput (tok/s)

Figure 1 — Throughput by model and device, —-token budget. Separate axes: decode is an order of magnitude slower than prefill.

LaptopPhone

Peak memory (GiB)

Figure 2 — Peak resident memory over the whole run, by model and device.

On the laptop, throughput falls steadily with model size, as expected when decode is limited by memory bandwidth. On the phone, going from 1.5B to 3B cuts prefill by — although the parameter count only grows —. Memory does not explain it: the phone's 3B peak (— GiB) is below the laptop's (— GiB). The paper attributes the drop to thermal throttling under sustained load, as reported for phones by Tummalapalli et al. (2026). No temperature was recorded, so this is an inferred explanation, not a measured one.

Reproduce
Data
data/speed_memory.csv
Protocol
see §5; the run scripts are not committed
/usr/bin/time -v llama-cli -m <model>.gguf -p "<prompt>" -st -n —

6.2 · Energy per generated token

Laptop (RAPL)Phone (battery drop, upper bound)

Energy per generated token (mJ)

Figure 3 — Energy per generated token. The values of the largest model are labelled: it is where the ordering of the two devices flips.

For —, the phone spends less energy per token than the laptop despite running an order of magnitude slower, which fits the lower power envelope of a mobile system-on-chip. For — the ordering inverts. The paper reads this as the same thermal effect: once the phone lowers its clock to manage temperature, it keeps drawing power while producing fewer tokens per second. Whatever the cause, the relative efficiency of two devices is not fixed; it depends on where a model size falls against each device's limits.

Reproduce
Data
data/energy.csv (method and number of runs per row)
Protocol
RAPL counter and battery batch, see §5

6.3 · Fixed and marginal cost

Three model sizes give one point per model and device, too few to test a fit: a quadratic through three points has R² = 1 by construction. Sweeping the output length over — tokens gives three points per model and one degree of freedom beyond a line, so the fit can fail. Energy on the laptop was regressed on the length n:

E(n) = E0 + c · n

where E0 is the fixed cost of loading the model and c the marginal energy per generated token.

Laptop: energy per run (J) against output length (tokens)

Figure 4 — Measured energy (markers) and the fitted line for each model. The hollow marker at zero tokens is the fitted fixed cost E0.

All three fits reach R² ≥ — with a genuine held-out degree of freedom. The split is more informative than the averages of §6.2, which mix a cost paid once with a cost paid per token; the two grow with model size at different rates. Over the same sweep, peak memory on the laptop moved by at most —: memory belongs to the loaded model, while latency and energy also depend on the workload.

Phone: decode throughput (tok/s) against output length (tokens)

Figure 5 — The same sweep on the phone. On a stable device decode speed would stay roughly flat as the output grows.

The phone did not give a comparably clean picture. Decode throughput was —, and peak memory moved by up to — across lengths, two orders of magnitude more than on the laptop. The paper reports this as a finding in its own right: the reliability with which cost can be measured differs between devices, which bears on how much calibration data a per-device predictor would need.

Reproduce
Data
data/nine_points_laptop.csv, data/nine_points_android.csv
Fit
least squares in scripts/site/build_experiments_data.py (build_sweeps)
python scripts/site/build_experiments_data.py

6.4 · Roofline validation

Following Imai et al. (2024), an analytical estimate needs no training data: when decode is limited by memory bandwidth, tokens per second ≈ bandwidth ÷ model size. The bandwidths are the measured ones (— GB/s on the laptop, — GB/s on the phone).

LaptopPhone

Measured ÷ predicted decode throughput

Figure 6 — Ratio of measured to roofline-predicted decode speed. The vertical line marks a perfect prediction.

On the laptop the estimate under-predicts by a roughly constant factor (—), which the paper attributes to the bandwidth benchmark using one thread while llama.cpp decodes with several. A linear calibration, measured ≈ — + — × predicted, fits the three laptop points with R² = —, one degree of freedom left (methodology.tex prints —). On the phone the ratios are —: no single factor reconciles them. The roofline premise of a stable bandwidth holds on the laptop and not on the phone, which illustrates why a cost model calibrated on one device class does not transfer to another without recalibration (Tu et al. 2026).

Reproduce
Data
data/roofline.csv (bandwidth, predicted and measured decode)
Calibration
least squares in scripts/site/build_experiments_data.py (build_roofline)

6.5 · CPU and GPU backends

All runs above used the CPU. Because the backend is one of the inputs of cost, a separate llama-bench session on the laptop compared the CPU with the Vulkan backend on the integrated GPU (—): —-token prefill and —-token decode, — threads, build —, run on —.

Vulkan ÷ CPU throughput on the laptop

Prefill

Decode

Figure 7 — Speed-up of the Vulkan backend over the CPU backend in the same session. Right of the line, the GPU is faster.

In prefill the GPU was faster on every model (—). In decode the CPU won on the smallest model (—) and the GPU on the two larger ones (—). Which backend is cheaper depends on both the model size and the phase.

Repeating the comparison on the phone failed for three reasons, recorded in the experiment report: the Vulkan backend recognised the GPU (Adreno 618) but could not initialise because the device lacks the storageBuffer16BitAccess feature; OpenCL found no driver (ICD) available to Termux; and the backend for the Hexagon NPU needs Qualcomm's proprietary SDK, which Termux cannot install.

Reproduce
Data
data/backend_comparison_raw.csv (raw llama-bench output, one row per backend, model and phase)
Phone attempt
relatorio_orientador_en.tex, §Additional methodological considerations

What each experiment supports in the paper

ExperimentWhat it supportsAnchor in the literature
v1 reproductionThe measure–fit–validate skeleton transfers to the new problem; v1's input feature, hardware and task do not.Dantas Cruz et al. 2020; Wei et al. 2018
Latency and memoryMemory follows the loaded model; on the phone, speed degrades more than model size explains.Tummalapalli et al. 2026
EnergyWhich device is more efficient depends on the model size, so a static efficiency ranking of devices is not enough.Tummalapalli et al. 2026; Cai et al. 2026
Fixed and marginal costOn stable hardware, cost splits into a load cost and a per-token cost, which a predictor can estimate separately.—
RooflineAn analytical model calibrated on one device class does not transfer to another without device-specific data.Imai et al. 2024; Tu et al. 2026
BackendsThe execution backend is an input of the cost, like model size, and has to be covered by the data a predictor learns from.Cai et al. 2026; Tu et al. 2026

Source: methodology.tex §Summary and relatorio_orientador_en.tex §Additional methodological considerations. Each paper's close reading: Literature; full bibliography: References.

Limitations and threats to validity