Share a TensorBoard report

TensorBoard.dev was the answer to this question and it was switched off in January 2024. What is left is tensorboard --logdir runs/, bound to localhost:6006, on a machine that is usually not the one you are sitting at.

So the ritual is an SSH tunnel, or a screenshot of a loss curve cropped just tightly enough to lose the axis.

Export the scalars to one HTML file

import plotly.graph_objects as go
from tensorboard.backend.event_processing.event_accumulator import EventAccumulator

acc = EventAccumulator("runs/exp-42")
acc.Reload()

fig = go.Figure()
for tag in ("loss/train", "loss/val"):
    events = acc.Scalars(tag)
    fig.add_trace(go.Scatter(
        x=[e.step for e in events],
        y=[e.value for e in events],
        mode="lines",
        name=tag,
    ))

fig.update_layout(title="exp-42", xaxis_title="step", yaxis_title="loss")
fig.write_html("tensorboard.html", include_plotlyjs="inline")

include_plotlyjs="inline" is the part people skip. The default pulls plotly.js from a CDN, and a report whose chart library is a remote script is a report that renders blank the day the CDN is blocked — see self-contained HTML.

Drag the file into the app, or publish from the training job:

curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html tensorboard.html \
        --arg title "exp-42 — step $STEP" '{title: $title, html: $html}')"

Call it every N epochs from a callback and the URL becomes a live-ish training dashboard that costs you nothing to operate.

Why this beats a screenshot in the run channel

  • Anchored threads — "val loss diverges at step 8k, did the LR schedule change?" sits on the chart. See commenting on HTML.
  • Revisions — one report id per experiment; every publish is kept, so the URL is a history of the run rather than its last frame.
  • Access per report — private, team-only, or domain-gated. See the sharing model.

Limits

  • Entry HTML: 5 MB. Inlined plotly.js is about 3 MB of that, so downsample long runs (every Nth step) rather than plotting every point.
  • Assets: 25 MB per file, 250 MB and 500 files per report.
  • 60 requests/minute per token.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Publish a training report →

Related