Measured, rebound-aware lifecycle energy profiling and prompt optimization for local LLM inference.
Project description
PromptWatt
Measured lifecycle truth for prompt optimization.
PromptWatt profiles local LLM inference, detects energy rebound after prompt compression, and selects prompt variants only when they save measured energy after search cost, output expansion, quality, constraints, and expected reuse are accounted for.
The project does not claim that fewer input tokens automatically save energy. It records how every value was obtained: direct measurement, baseline-adjustment, estimation, proxy, or unavailable evidence.
Status: pre-release research alpha. The core API and schemas are tested; publish a tagged
1.0only after cross-GPU and external-meter validation described indocs/validation-plan.mdis complete.
What is different
- Zeus and direct NVML backends, plus an external cumulative-meter adapter.
- Synchronized measurement windows and no silent zero samples.
- Gross energy as the primary physical observation; optional resident-idle baseline adjustment is clearly labeled and retains the signed result.
- Explicit Hugging Face prefill and KV-cached decode tracing. No one-token run is subtracted from a separate full generation.
- Whole-batch vLLM attribution with a warning when request isolation is absent.
- Constraint extraction with source spans; no invented fallback constraints.
- Real
max_new_tokensbudget enforcement, separate from prose instructions. - Rebound classification from paired input, output, quality, and energy data.
- Optimization that measures the target model and amortizes the entire search.
- Stable SHA-256 row identities and atomic, preemption-safe result fragments.
- Paired randomization and cluster-bootstrap confidence intervals.
Install
pip install promptwatt
pip install "promptwatt[zeus,hf]" # recommended NVIDIA + Transformers path
pip install "promptwatt[nvml,hf,stats]" # direct NVML and scientific extras
PromptWatt has no mandatory runtime dependency. Hardware and inference engines are optional extras and are imported lazily. It never installs packages at runtime or import time.
Quick start
Create the monitor after loading and warming the model, so any baseline is calibrated in the actual resident state:
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from promptwatt.adapters import GenerationSettings, HuggingFaceAdapter
from promptwatt.measurement import EnergySession, ZeusBackend
model_id = "Qwen/Qwen2.5-0.5B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(model_id)
device = "cuda" if torch.cuda.is_available() else "cpu"
model = AutoModelForCausalLM.from_pretrained(model_id, dtype="auto").to(device)
model.eval()
adapter = HuggingFaceAdapter(model, tokenizer)
session = EnergySession(ZeusBackend([0]), synchronizer=adapter.synchronizer)
settings = GenerationSettings(max_new_tokens=96)
profiled = adapter.profile_phases("Explain KV caching in exactly two sentences.", settings, session)
for phase in profiled.trace.phases:
print(phase.name, phase.reading.gross_j, phase.reading.evidence.value)
For an idle-adjusted sensitivity analysis, use direct power polling:
from promptwatt.measurement import NVMLBackend
backend = NVMLBackend(mode="power", poll_interval_s=0.1)
# First measurement calibrates a robust 10-second model-loaded idle baseline.
Gross joules remain available even when active_j is reported. “Active” here
means resident-baseline-adjusted device energy, not perfectly attributable
compute energy.
Rebound-aware optimization
from promptwatt.optimize import (
HeuristicCandidateGenerator,
OptimizationConfig,
ReboundAwareOptimizer,
)
optimizer = ReboundAwareOptimizer(
adapter,
session,
HeuristicCandidateGenerator(),
config=OptimizationConfig(
repeats=5,
expected_deployments=10_000,
quality_floor=0.85,
),
)
report = optimizer.optimize(
"Please answer the question. Use JSON and no more than 50 tokens.", settings
)
print(report.modified, report.selected_method, report.total_optimization_energy_j)
The built-in lexical evaluator is labeled proxy. For claims about task
quality, provide a task metric or human evaluation through QualityEvaluator.
CLI
promptwatt doctor
promptwatt rebound --original-input 500 --optimized-input 300 \
--original-output 80 --optimized-output 190 \
--original-energy 12 --optimized-energy 18
promptwatt lifecycle --original-energy 12 --optimized-energy 9 \
--search-energy 600 --deployments 10000
promptwatt hf-profile Qwen/Qwen2.5-0.5B-Instruct \
--prompt "Summarize this in three bullets" --phases --backend zeus
Repository map
src/promptwatt/
measurement/ backend contracts, NVML, Zeus, external meters, integration
tracing/ sequential lifecycle spans
adapters/ callable, Hugging Face, and vLLM inference
constraints/ extraction, restoration, and decoding ceilings
analysis/ rebound, lifecycle, statistics
optimize/ candidate generation and measured selection
integrations/ LLMLingua-compatible compression
benchmark/ paired factorial runs, batching, atomic fragments
diagnostics/ optional research plots
provenance.py runtime, package, and CUDA visibility manifest
Read the measurement contract, architecture, and validation plan before publishing comparative energy claims.
Scope and non-claims
PromptWatt measures energy inside explicit local hardware windows. It does not infer datacenter cooling, networking, embodied carbon, or provider-side energy from API token counts. Carbon conversion is available only when the caller supplies a grid-intensity assumption. Baseline-adjusted GPU energy is a useful sensitivity metric, not exact causal attribution.
Contributing and citation
See CONTRIBUTING.md. If this supports published work, use the metadata in CITATION.cff. PromptWatt is MIT licensed.
PromptWatt is maintained by Abhay Phani Rao, an independent researcher (ORCID 0009-0003-9495-7697).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file promptwatt-0.1.0a1.tar.gz.
File metadata
- Download URL: promptwatt-0.1.0a1.tar.gz
- Upload date:
- Size: 45.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1901529d3cb79992aa12a8fd1e4492f491fc2426e5f71fe3fa70f8393026f4e9
|
|
| MD5 |
e5ebfa5a5845f11adc816f7cc4320ec1
|
|
| BLAKE2b-256 |
01d41f231f1b43c91a77670333767e7c685c836740df6621ff96cb748cf2d1e1
|
Provenance
The following attestation bundles were made for promptwatt-0.1.0a1.tar.gz:
Publisher:
release.yml on AbhayRao38/promptwatt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
promptwatt-0.1.0a1.tar.gz -
Subject digest:
1901529d3cb79992aa12a8fd1e4492f491fc2426e5f71fe3fa70f8393026f4e9 - Sigstore transparency entry: 2321358931
- Sigstore integration time:
-
Permalink:
AbhayRao38/promptwatt@f1f9a09df67af3baf524fc00c3f046a96142b665 -
Branch / Tag:
refs/tags/v0.1.0a1 - Owner: https://github.com/AbhayRao38
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f1f9a09df67af3baf524fc00c3f046a96142b665 -
Trigger Event:
release
-
Statement type:
File details
Details for the file promptwatt-0.1.0a1-py3-none-any.whl.
File metadata
- Download URL: promptwatt-0.1.0a1-py3-none-any.whl
- Upload date:
- Size: 49.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed2afa1e6d6eb1c62feaa1b194548ee1009a0c546ec83fa1e48542733582483f
|
|
| MD5 |
ef482a29a532f1c7958498409b153ec5
|
|
| BLAKE2b-256 |
5df25cc3f6d33e68ec5f26433b7a8776ea2f12eed5f740cac426386dade6dd1d
|
Provenance
The following attestation bundles were made for promptwatt-0.1.0a1-py3-none-any.whl:
Publisher:
release.yml on AbhayRao38/promptwatt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
promptwatt-0.1.0a1-py3-none-any.whl -
Subject digest:
ed2afa1e6d6eb1c62feaa1b194548ee1009a0c546ec83fa1e48542733582483f - Sigstore transparency entry: 2321358982
- Sigstore integration time:
-
Permalink:
AbhayRao38/promptwatt@f1f9a09df67af3baf524fc00c3f046a96142b665 -
Branch / Tag:
refs/tags/v0.1.0a1 - Owner: https://github.com/AbhayRao38
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f1f9a09df67af3baf524fc00c3f046a96142b665 -
Trigger Event:
release
-
Statement type: