open-standards/eoc/standards/sci-for-ai-energy-provenance-annex.md
Transaction Science ac93d9e56e
Some checks failed
energy meters on real hardware / RAPL and NVML on jetson-hub (pull_request) Successful in 44s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 2m20s
standards workspaces build + test / aac-rs (pull_request) Successful in 2m39s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 1m26s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 56s
standards workspaces build + test / map-rs (pull_request) Successful in 56s
standards workspaces build + test / mesh-rs (pull_request) Successful in 53s
standards workspaces build + test / openpay (pull_request) Successful in 3m12s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 54s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 4m33s
jouleclaw public surface must stay documented / Public-surface audit (jouleclaw-rs) (pull_request) Successful in 1m1s
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 4s
no-vanity-metrics / WAI public text names no comparison (pull_request) Successful in 4s
no-vanity-metrics / WAI public text names no company or product (pull_request) Successful in 4s
standards workspaces build + test / arl-rs (pull_request) Successful in 1m17s
standards workspaces build + test / jcp-rs (pull_request) Failing after 42s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m58s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 1m12s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 1m11s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m17s
standards workspaces build + test / sense-rs (pull_request) Successful in 1m14s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m26s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 3m52s
eoc annex: the per-process counter's lumps are the kernel's fold, and a checked read is exact
The annex reported that the macOS per-process energy counter "accrues in
lumps" under sub-millisecond sampling, and left it there. The mechanism
is now established: a thread's energy is added to its process's count
when the thread leaves its core, so a reader on a running thread sees
nothing until its quantum ends. A reader that first leaves its core and
checks its own thread's count moved reads 1 ms spans to within a few
percent of an independent read, where unchecked it read none of them on
an idle host. Say so beside the measured figures, which stand.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 00:54:51 -04:00

222 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Proposed Annex: the provenance and validity of E
*Draft submission for filing to [github.com/Green-Software-Foundation/sci](https://github.com/Green-Software-Foundation/sci). Licensed CC-BY-4.0.*
*Status: working draft v0.1. Authors: Transaction Science. Target: SCI-for-AI, as an annex to the treatment of E. Companion to [`sci-for-ai-submission.md`](sci-for-ai-submission.md), which maps EOC receipts onto the four-component formula and assumes E is already trustworthy; this annex is about whether it is.*
---
## a. Summary
`SCI = (E × I + M) per R` is well specified in every term but one. `I` has a
location-based methodology. `M` has a lifecycle methodology. `R` is
deployment-defined and the specification is explicit that it must be *stated
and reproducible*. **`E` has no comparable requirement.** A figure may be
labelled "measured" without saying what measured it, over what span, on which
silicon, or on whose behalf — and in current practice it frequently is.
This annex proposes five requirements (E1–E5) that make an `E` figure
self-describing, and one refusal: **a figure taken over a span shorter than its
counter's update period is not a measurement of that span and MUST NOT be
reported as measured.** All five are machine-checkable, and a reference
implementation exists.
**What this annex does not propose.** No change to `R`. SCI-for-AI already
supports diverse functional units — tokens for language models, inferences for
classifiers, FLOPs for training — so non-generative inference, including the
typed-decision models that emerged in September and October 2026 and emit no
tokens at all, is already expressible as `R = one inference`. The gap is not in
the unit of work. It is in the energy.
## b. The problem, as evidenced
Three independent observations, none of them about a careless implementer:
1. **Published work that has a sensor reports only part of the machine.** A
survey of recent AI-energy measurement work finds the instrumented studies
are GPU-rail-only — no CPU package, no DRAM, no NIC, no storage, no
power-supply loss — and that none of them declares its sampling interval,
the device's update rate, or the integration method actually used.
2. **"Measured" is being applied to estimators.** A reference implementation in
this ecosystem stamps `measured` on the output of a lifecycle estimator
whose own documentation calls it an estimation. The alternative path uses
hard-coded kWh-per-token constants calibrated from a single figure at ±50%.
Neither is wrong as an estimate; both are wrong as a measurement.
3. **Per-call energy is being taken from provider SDKs**, which report a number
with no stated counter, period or boundary. The reporter cannot tell a
hardware reading from a model, and neither can the reader.
### Why this is not pedantry
The error is not symmetric. A figure used in a *budget* or a *ceiling* that
under-reports admits work the budget cannot cover, silently; one that
over-reports refuses work that would have fit, visibly. A figure used in a
*disclosure* that under-reports understates an obligation. In both cases the
unsafe direction is the one an uncharacterised counter takes.
And counters do take it, by large factors. A 588-run study of one widely used
cumulative-energy counter measured it **under-reporting integrated power by
95.4% at 0.5 ms sampling**, recovering to 1.6% only at 1 s, and recommended
against unvalidated use. Three weeks later a separate paper built its entire
per-token energy decomposition on that same counter, specifically *because*
power sampling cannot resolve short decode windows. Neither cites the other.
A third observation, on different hardware, has the same counter class reading
4–30× the board's actual draw when polled at 100 ms. Three mutually
inconsistent characterisations of one counter class — which means the validity
bound is itself sampling-interval-dependent and cannot be assumed.
We reproduced the shape on a fourth counter. Burning one thread's CPU and
sampling the macOS per-process energy counter 60 times per interval, the
fraction of intervals in which it advanced was **0% at 10 µs and 50 µs, 2% at
100 µs, 5% at 500 µs, 35% at 1 ms, 63% at 2 ms, 87% at 5 ms, and 100% at
10 ms**. Below 1 ms it does not lag smoothly — on the intervals where it moved
at all, the median step was ~20 mJ, two orders above the 1 ms step. It accrues
in lumps. A sampler reading it every 500 µs would see nothing most of the time
and a 20 mJ jump occasionally, and would report both as measurements.
The lumps are the kernel's bookkeeping, not the hardware's. A thread's energy is
added to its process's count when the thread leaves its core, so a reader on a
running thread sees nothing until that thread's scheduling quantum ends, and then
sees all of it at once. A reader that first leaves its core, and checks that its
own thread's count moved across that pause, reads the same 1 ms spans to within a
few percent of an independent read; unchecked, on an idle host, it read none of
them. The counter is exact; an unchecked read of it is not.
## c. Proposed requirements
An `E` figure claiming to be **measured** MUST carry:
**E1 — Source.** The named counter or instrument: `rapl`, `nvml`, `rocm-smi`,
`level-zero`, `ioreport`, `proc-rusage`, `tegra-ina`, `qualcomm-qpt`,
`ascend-smi`, `hl-smi`, `cnmon`, `external-meter`, … Not the word "measured".
Two figures from different sources are not interchangeable: they have different
domains, different periods and different attribution.
**E2 — Period, and the span rule.** The counter's documented or measured update
period, and the span the figure covers. **If the span is shorter than the
period, the figure MUST be reported as modelled, not measured.** A source whose
period is *undeclared* can never support a measured claim at any span, because
the direction of its error is unknown. A per-operation figure for work shorter
than the period is sound only as the mean of many operations over a span longer
than it.
**E3 — Attribution boundary.** Whether the figure counts **one principal's**
work (a per-process or per-container counter) or **the whole machine** (an SoC
rail, a package counter, a board shunt). These are different claims, and the
distinction is independent of how much of the *task* is covered. A machine-wide
figure attributed to one workload MUST state the condition under which that is
valid — normally exclusive use — and MUST report the magnitude of its idle
correction, so a reader can see whether the correction is a rounding error or
the result.
**E4 — Fabric breakdown.** Where the work crosses silicon, `E` SHOULD be
reported per fabric (`cpu`, `gpu`, `npu`, `dram`, `package`, …) and MUST state
which fabrics are **not** covered. A total that silently omits a fabric the
work used is an understatement, and on accelerated inference the omitted
fabric is usually the dominant one.
**E5 — Why a fabric is uncovered.** Where a fabric is not measured, the reason
MUST be one of five, because they are not interchangeable:
| status | meaning |
|---|---|
| `frozen` | counter present, not advancing |
| `absent` | no such silicon on this host |
| `needs-privilege` | present, requires privilege the reporter lacks |
| `no-counter-exists` | present, and exposes **no energy counter at all** |
| `not-implemented` | a counter exists; this reporter has no reader for it |
Only `no-counter-exists` is a property of the hardware. The other four are
properties of the deployment or the tooling, and they are fixable.
This matters beyond accounting hygiene. The EU AI Act's GPAI Code of Practice
requires providers to document known or estimated energy consumption for
training *and* inference, while permitting an exemption where the provider
lacks "critical information from compute or hardware provider". That exemption
is a claim of `no-counter-exists`. E5 is what distinguishes it from the four
statuses that do not justify it — and an unprivileged on-die counter, which
needs no cooperation from the compute provider at all, narrows the set of
accelerators for which the claim can honestly be made.
## d. Worked example
A three-question typed decision served by a 421M-parameter decision model on an
Apple M5 Max, `R = one inference`:
```
E = 1.0413e-4 Wh (104 127 µJ)
R = 1 decision
source = { gpu: ioreport, cpu: proc-rusage }
period = 10 ms both; span = 2.606 s over 200 decisions → measured (E2 met)
fabrics = gpu 96 591 µJ attribution=machine, idle-corrected by 0.08%
cpu 7 536 µJ attribution=process, coverage=whole for CPU work
npu 0 µJ frozen (no ANE Energy aggregate on this part)
dram — not-implemented (rails exist; this reader omits them)
```
Two things the annex makes visible that a single number hides. First, the figure
is a **mean over 200 decisions**, because one decision takes 11.85 ms and a
10 ms-period counter cannot resolve it — under E2 a per-decision counter read
would have had to be reported as modelled. Second, 93% of the energy is on a
**machine-attributed** rail, so the figure is this workload's only under
exclusive use; the idle correction was 0.08%, which is what makes that credible
here and would not be on a shared host.
The same decision class run on the CPU instead costs **0.486–0.555 J** —
roughly five times more energy — and is entirely **principal-attributed** and
whole-coverage. Under E3 those are different claims, and a reporter choosing
the cheaper figure is also choosing the weaker one. Without E3 the two look
like the same kind of number, and the cheaper one wins every comparison.
## e. Conformance
All five requirements are machine-checkable, and we have an implementation
rather than only a proposal:
- A metering ladder that tags every figure with its source and refuses to
upgrade a model's output to a reading.
- A per-fabric survey that returns E1, E3, E4 and E5 for every
`(fabric, source)` pair on a host, probing presence so an unread accelerator
reports `not-implemented` rather than the false claim `absent`.
- The E2 refusal as a predicate over `(declared period, span)`, with the
counter characterisation above as its evidence.
- Measurement harnesses for both the counter characterisation and the
per-decision figures, so the numbers in §d are reproducible rather than
quoted.
We propose filing this as an annex under the extension URN
`urn:gsf:sci-ai:ext:energy-provenance:v1`, additive and imposing nothing on
deployments that report estimates — which remain perfectly conformant, provided
they say so.
## f. References
- **ISO/IEC 21031:2024** — Software Carbon Intensity (SCI) specification.
- **GSF SCI for AI** — ratified 2025; functional units for language models,
classifiers and training.
- **GSF, SCI for AI and EU AI Act environmental compliance** — the policy
framing this annex is intended to support.
- **EU AI Act GPAI Code of Practice**, Model Documentation Form — energy
consumption for training and inference; the compute/hardware-provider
exemption.
- Dauner et al., *Evaluating the Influence of Measurement Frequency on
[GPU energy counters]*, ACM SIGENERGY Energy Informatics Review 6(2),
July 2026 — the 588-run study; 95.4% under-read at 0.5 ms.
- *Characterization of Request and Token Energy Costs for LLM Inference
Workloads*, arXiv:2608.28044 — builds on the same counter for the opposite
reason.
- **CEN/CLC/TR 18145:2025**, *Green and Sustainable AI* — the European
guidance this annex is also offered to.
- **AFNOR SPEC 2314**, *Référentiel général pour l'IA frugale* — prescribes
estimator tooling for claims of frugality; E1/E2 are what would let such a
claim be checked.
- **Blauer Engel DE-UZ 215** — software energy criteria requiring measurement
on a defined test system; the German UBA's own reporting names energy per
classification as a KPI.
- **UNE 0086:2025** — energy, carbon, water and performance of AI systems.
---
*Working draft. The filing to `github.com/Green-Software-Foundation/sci` will
carry a JSON-Schema definition for the E-provenance block, the conformance
predicate for E2, and the reproducible harnesses behind §d.*