mlco2 / mlco2/codecarbon

Feature proposal: live local dashboard for `codecarbon monitor --ui`

Open
#1,348 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
1.9k
Forks
323
Avg merge
1d 12h
Merged PRs (30d)
12

Description

This is a feature proposal.

The problem

Today the feedback loop for a user who just installed CodeCarbon is: run something, wait for it to finish, open emissions.csv. For a long training run that is hours of nothing, and for a first five-minute evaluation or a workshop it is fatal — the tool never gets to show that it works.

There is also a recurring support question: "is CodeCarbon actually reading my GPU?" A live per-component power readout answers that immediately, without asking anyone to switch on debug logging.

Neither existing visualization covers this case:

  • codecarbon/viz/carbonboard.py (the carbonboard console script) is a Dash app that reads a finished emissions.csv and renders it post-hoc. It needs the optional carbonboard extra (dash, dash_bootstrap_components, fire) and is by design a historical comparison view.
  • webapp/ + carbonserver do show live data, but require FastAPI, PostgreSQL, authentication, an experiment id and network access. That is the right architecture for a team and the wrong one for "what is my laptop doing right now".

Proposed design

An output handler that keeps a bounded rolling window of live samples in memory, plus a stdlib HTTP server that serves one self-contained HTML page polling a JSON endpoint.

CLI surface, on the existing monitor command:

codecarbon monitor --ui                      # http://127.0.0.1:8050
codecarbon monitor --ui --ui-port 9000 --ui-host 127.0.0.1
codecarbon monitor --ui --offline --country-iso-code FRA

Public API, usable like any other output handler:

from codecarbon.viz.live import LiveDashboardOutput
tracker = EmissionsTracker(output_handlers=[LiveDashboardOutput(port=8050)])

Routes: GET / (the page), GET /data (JSON: rolling samples, tasks, static hardware metadata), GET /health.

Why it fits the existing extension points

BaseOutput.live_out(total, delta) already exists and is already called from EmissionsTracker._measure_power_and_energy on every measure_power_secs tick — it is exactly what PrometheusOutput uses. BaseOutput.exit() is already called from stop(), which gives clean server shutdown for free. So the feature is genuinely just "a handler that remembers the last N samples, and something that shows them"; no change to the tracker, the scheduler or the data model.

Scope boundary

  • No new dependency, no build step, no database, no network. http.server, json, threading, collections, importlib.resources. The page is one HTML file with inline SVG for the chart — no CDN, so it works on an air-gapped machine. If this starts wanting a web framework or a JS toolchain, it has overshot.
  • Binds to 127.0.0.1 by default; a non-loopback bind prints a warning, since the server is unauthenticated by design. Remote access is SSH port forwarding's job.
  • A busy port must never take down a measurement run: log clearly and keep monitoring without the UI.
  • Not in scope: reading pre-existing emissions.csv history (that is carbonboard), auth, persistence, or any growth toward replacing either existing dashboard. The two tools answer different questions and neither is touched.

Happy to take feedback on the CLI naming and on whether the config-file keys (ui, ui_port, ui_host) are wanted at all — flags may well be enough for an interactive foreground command.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the existing monitor command, codecarbon/viz/carbonboard.py, BaseOutput.live_out, EmissionsTracker._measure_power_and_energy, and BaseOutput.exit(). Confirm how output handlers are configured, then define the live handler and stdlib server within the stated scope. Done means local polling works without new dependencies or persistence, clean shutdown is supported, and a busy port does not stop monitoring.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, cli
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.