s123hree/green-code-optimizer-a100
π± Green-Code Optimizer
An RL agent that refactors Python code for energy efficiency, not readability β and tells you exactly how much COβ it saves.
  
π― The Problem
AI workloads are projected to consume 2β4 % of global electricity by 2030. Most of that goes to training, but inference at scale β the same algorithms running millions of times a day in production β is the silent giant. A single inefficient nested loop in a hot path, replicated across millions of executions, can add up to real COβ.
Meanwhile, almost every existing code-refactoring tool optimises for readability (line length, naming, type hints). None of them refactor for energy.
*What if we trained an RL agent whose only goal was to make Python cheaper to run β measured in CPU cycles, memory footprint, and ultimately grams of COβ?*
That's the Green-Code Optimizer.
π‘ The Pitch
The agent receives a negative reward for high peak memory and high execution time, and a positive reward for the opposite. It uses graphlet analysis to represent the program's control-flow structure, so it learns which structural patterns (nested loops, function calls inside loops, deep branching) are expensive β and swaps them for cheap alternatives (vectorised ops, comprehensions, hoisted invariants).
π Concrete Example
A real corruption from the env (Level-1 episode):
Before β a list comprehension is exploded into an append-loop, and a 50-iteration energy-waste loop is injected at the top:
def get_priority_users(users):
_energy_waste = []
for _ in range(50):
_energy_waste.append(list(range(100)))
out = []
for u in users:
out.append(u.upper())
return outAfter β the agent's target refactor:
def get_priority_users(users):
return [u.upper() for u in users]Impact (at 10 000 runs/day): ~1.1 kg COβ/year saved per call site. With one trained agent and a few thousand call sites, you're talking about trees worth of carbon.
βοΈ How It Works
flowchart LR
A["Corrupted /<br/>energy-inefficient<br/>Python codebase"] --> B[Episode Generator]
B --> C["RL Agent<br/>(Qwen-1.5B + LoRA)"]
C -->|edits| D[Updated codebase]
D --> E1[Graphlet Analyzer]
D --> E2[CPU + Memory Profiler]
D --> E3[Compliance / Test Gate]
E1 --> R[GRPO Reward]
E2 --> R
E3 --> R
R -->|policy update| C
D --> F["COβ Dashboard<br/>kg/year Β· trees Β· car-km"]1. Episode Generation with Curriculum-Driven Corruption
Each episode loads a real Python codebase and applies energy-degrading corruptions that scale with the agent's skill:
The CurriculumManager escalates the level once 3 consecutive 50-episode windows all average a reward > 0.7 β so the agent's own progress drives the difficulty.
2. Graphlet Analysis β environment/graphlet_analyzer.py
Parses each file into an AST and detects 4 classes of expensive control-flow graphlets:
Lower total cost β higher graphlet score (range [0, 1]).
3. Runtime Profiling β environment/track_c.py
Each candidate refactor is actually executed in a timeout-bounded subprocess profiler: CPU time via time.perf_counter, peak memory via tracemalloc. If a file cannot be safely executed, Track C falls back to compile-time profiling so training never hangs.
4. Composable Rubric β environment/rubrics.py
Following OpenEnv RFC 004, the reward is a tree of named, composable child rubrics β modeled on PyTorch's nn.Module. When openenv-core is installed we extend its Rubric base class directly; otherwise we provide a zero-dependency fallback shim with the same surface area.
GreenCodeRubric (root)
ββ Sequential β short-circuits if any gate fails
ββ syntax_gate {0,1} β reward = 0 if any file doesn't parse
ββ hack_gate {0,1} β reward = -1 if test files are tampered with
ββ WeightedSum β soft signals
ββ green (0.70)
β ββ graphlet (0.40) β [0,1]
β ββ cpu (0.35) β [0,1]
β ββ memory (0.25) β [0,1]
ββ compliance (0.30)Each child is independently inspectable via rubric.named_rubrics(), so training infrastructure logs every component without modifying the rubric. Adding a new signal (e.g. a Big-O complexity penalty) is a 5-line subclass + WeightedSum weight tweak.
The rubric tree is also exposed at runtime via GET /rubric so judges can introspect the reward without touching server internals.
R = (syntax_gate β§ hack_gate) Γ (0.70Β·green + 0.30Β·compliance) β P_efficiency- Why this is hard to game β the
Sequentialshort-circuits any soft reward when the syntax gate fails. Agents can't get points for "memory-efficient" code that doesn't compile. - `P_efficiency` β
0.01per file edited; held outside the rubric (it's a training-time minimal-edits nudge, not a property of the env).
5. COβ Dashboard β environment/co2_calculator.py
CPU-time savings Γ CPU TDP Γ grid carbon intensity β kg COβ/year, with real-world equivalents (tree-years, car-km). Live HTML dashboard at /dashboard/co2/{episode_id}.
π Evidence the Agent Actually Learns
We ran a 25-episode baseline comparison before any RL training, scoring policies on identical episodes:
The 96 % gap between no-op and oracle proves the env has a strong, learnable signal. Reproduce locally:
python training/compare_baseline.py --num-episodes 20
# β assets/baseline_vs_trained.png + .jsonTraining curves
training/train_grpo.py writes assets/training_curves.png and assets/log_history.json after the A100 GRPO run. Commit those files immediately after the final run so judges can verify the real loss/reward curves.
π Why This Wins (mapped to judging criteria)
π Submission Links
π§© OpenEnv Compatibility
This env follows the OpenEnv spec (RFC 001 + RFC 004).
- Manifest: `openenv.yaml`
- Server: uses
openenv-core>=0.2.3for theRubricbase class - Gym-style API:
POST /reset,POST /step,GET /state/{id} - Rubric introspection:
GET /rubricreturns the named child tree - Sync client: `client.py` β drop-in
EnvClient, mirrorsHTTPEnvClient - Observation space:
{ files, violation_report, steps_remaining, curriculum_level } - Action space:
[read_file, edit_file, run_tests, check_compliance] - Reward range:
[-1.0, 1.0] - Max episode length: 70 steps
# Three-line judge-friendly usage:
from client import GreenCodeEnv
env = GreenCodeEnv("https://s123hree-green-code-optimizer-a100.hf.space")
obs = env.reset(curriculum_level=2) # gym-style reset
state = env.state() # gym-style state
print(env.rubric_tree()) # introspect the rewardπ API
π Quickstart
Run the env locally
git clone https://huggingface.co/spaces/s123hree/green-code-optimizer-a100
cd green-code-optimizer-a100
pip install -r requirements.txt
uvicorn server:app --host 0.0.0.0 --port 7860
# Visit http://localhost:7860/demoReproduce training (A100, deadline-safe)
The Space defaults to a fast final run: TRAIN_MAX_STEPS=80, TRAIN_NUM_GENERATIONS=2, TRAIN_NUM_EPISODES=80, LORA_RANK=8, and compile-mode green profiling. Increase these env vars only if you have extra time.
Reproduce baseline comparison (CPU, ~30 s)
python training/compare_baseline.py --num-episodes 20Smoke-test the deployed Space
SPACE_URL=https://s123hree-green-code-optimizer-a100.hf.space \
python test_deployment.pyπ Repository Layout
.
βββ server.py # FastAPI: /reset /step /state /rubric /demo /dashboard
βββ client.py # Sync EnvClient β mirrors OpenEnv HTTPEnvClient
βββ inference.py # Loads adapter from HF Hub, runs predictions
βββ openenv.yaml # OpenEnv manifest
βββ Dockerfile # HF Space image
βββ blog_post.md # Writeup (problem β env β rubric β results)
βββ environment/
β βββ rubrics.py # β Composable Rubric tree (RFC 004)
β βββ episode_generator.py # Corruption pipeline + curriculum
β βββ track_a.py # Code-quality evaluator
β βββ track_b.py # Compliance checker
β βββ track_c.py # Green-code evaluator (CPU + memory)
β βββ graphlet_analyzer.py # Control-flow pattern detection
β βββ co2_calculator.py # CPU-time β kg COβ/year
β βββ rule_engine.py # 150-rule cascading rule engine
β βββ ENGINEERING_STANDARDS.md # The 150 rules
β βββ base_codebase/ # Original clean Python codebase
βββ training/
β βββ train_grpo.py # GRPO trainer with auto-plotting
β βββ compare_baseline.py # Baseline-vs-trained comparison
β βββ verify_pipeline.py # CPU-only pipeline sanity check
βββ notebooks/train_grpo.ipynb # Colab-ready training notebook
βββ assets/
βββ baseline_vs_trained.png
βββ baseline_vs_trained.json
βββ system_architecture_diagram.png
βββ architecture_pipeline.png
βββ co2_pipeline_diagram.pngπ€ Extending the Env
- New reward signal β write a 5-line
Rubricsubclass and add it to theWeightedSuminenvironment/rubrics.py::build_green_rubric. Every leaf is auto-logged vianamed_rubrics(). - New graphlet patterns β add to
PATTERN_COSTSinenvironment/graphlet_analyzer.py. - New energy-degrading corruptions β add a method to
EpisodeGeneratorand append it toenergy_corruptionslist. - Tune carbon constants for your region's grid β
environment/co2_calculator.py.
# Drop-in custom rubric example:
from environment.rubrics import Rubric, build_green_rubric, WeightedSum
class BigOPenalty(Rubric):
def forward(self, action, observation) -> float:
# ... your big-O analysis ...
return score # range [0, 1]
base = build_green_rubric()
base.green = WeightedSum(
[base.green.graphlet, base.green.cpu, base.green.memory, BigOPenalty()],
weights=[0.30, 0.30, 0.20, 0.20],
)π License
Apache-2.0. Fork it, use it, save some carbon.
Built for the OpenEnv India Hackathon 2026 β Meta PyTorch.
