Debug ML while it's training.
Pulse catches the bug while the run is still training: about 1.3 minutes to a fix and $0.19 per task in our benchmark. Built for terminals, SSH, containers, Colab, remote servers and cloud GPUs.
Quickstart Open the dashboard ↗Try the terminal below to tick these off.
What are you trying to do?
New to Pulse?
Installation
Requires Python 3.9+, a supported backend (NumPy, PyTorch, TensorFlow, CuPy or JAX), and a model for the agent: sign in to OpenRouter from Pulse (no key to handle, free models available) or bring an API key.
Installing puts a pulse command on your path. Run it and Pulse takes you through setup.
Start Pulse
To make the plain pulse command work, add Python's scripts folder to your PATH once:
Try it
A simulated terminal. Click a command or type it. Tab completes, ↑ recalls.
Quickstart
Three steps, and no changes to your training code. Click through.
The Pulse app
This is what Pulse looks like in your terminal: the run on the left, the agent on the right. It is a working illustration, not live data. Click a thought, a tool line or an edit to open it. Press CtrlO to open all of them. Type a message, or start with / to see commands.
Colour has a job: orange for what is live, selected or worth a look, red for what is wrong, grey for everything else. The agent's thinking is orange italic, a command it ran is bold grey, and Pulse's own output is dim.
Start Pulse
One command. It does the rest: setup, running scripts, watching runs, the agent.
Supported backends
How Pulse works
Pulse separates AI reasoning from exact numerical calculation: instead of asking a model to estimate whether a gradient or update is unusually large, Pulse calculates the quantity directly. Click a stage.
Detection & auditing
Findings
A finding carries a check id, a variable, a severity, its numbers and a confidence. It is deduplicated on (check, variable), so "spiked to 4.12" and "4.13" aren't two problems. A check must hold for two consecutive evaluations before it is raised, except NaN and Inf, where waiting is itself the damage. Findings clear when the condition goes away and can fire again. Detection runs whether or not auto-fix is on.
When the agent looks again
After each model turn the brain asks when to come back, and why. A fix that just landed, a metric heading the wrong way or anything uncertain pulls the next look in to minutes; a smoothly descending run is left alone for an hour. A NaN, a critical finding or a fix brings the next look forward immediately, and the schedule survives a brain restart.
The audit pass
It is handed the whole run: every curve downsampled into min/mean/max buckets (a two-step spike survives), current findings, tensors, what was fixed, earlier audits, and how many samples were dropped. It is asked for what deterministic checks can't see: a loss decreasing far slower than it should, two metrics that disagree, a plausible-but-wrong value.
ML lint (mllint)
Deterministic code-level checks: incompatible loss/metric combinations, redundant activation/loss combinations, backward() without the expected optimizer update, train/eval mode issues, suspicious learning rates, and other ML-specific static patterns.
Benchmark
Injected ML faults in real training code. Each tool must find the cause and apply the fix. Pulse runs on DeepSeek v4.1; Claude Code on Opus.
Claude Code: 3.9 min
Claude Code Opus: $0.39
Claude Code: 9 / 11
stream mode, 20k steps (single process: 0.059 s)
How the benchmark changed Pulse
Expanded mllint checks · minimal-fix-first behaviour · whitespace-tolerant patch matching · retry-on-mismatch patching · stronger verification of correctness and patch scope · more agentic debugging workflows.
Tracking
Pick a variable. Illustrative example, not real runtime data.
GPU tracking
GPU tracking can introduce device-to-host transfer overhead. It is opt-in.
Command explorer
Choose your agent
Auto-fix & approver
Who approves commands? (auto mode)
Some shell commands the agent wants need an OK first: ones that delete files, rewrite git state, reach outside the project, start a background process or overwrite a file. So a long run never stops to wait, a model answers that y/N. By default it is the agent's own model, asked separately.
Or set "approver": "<model>" to pick a different model. The same commands are flagged either way; only who answers changes.
What the approver sees and decides
Only the command, why it was flagged, the project folder, and what the agent was working on, never the agent's reasoning. It answers APPROVE or DENY with a reason that goes back to the agent. It is told to deny anything that could destroy work that can't be regenerated, touch files outside the project, handle credentials or use sudo, and to deny when unsure.
It also answers "apply this change?" for each edit the agent proposes, judging the diff against your request. Every applied change stays one /undo away. If it can't be reached, Pulse asks you (or declines in a non-interactive run). Every decision is printed and recorded in the agent log.
Cloud workspaces & dashboard
TRAINING MACHINE
pulsePULSE WORKSPACE
Sessions · IncidentsAgent logs · Tracebacks
Commit · Team members
What gets synced?
Dashboard
Workspaces can be named and managed from the CLI; members can leave, and admins can delete one. A run opened in the app (via /run, /monitor, or attached) gets its own session, with its environment, metric snapshots, findings and crashes as incidents, the agent's turns, and uptime, synced in the background. Sign in at the dashboard to pick a workspace, then a project, then a run. Runs show loss, grad norm, learning rate, uptime/downtime, commit, GPU and incidents. A run counts as live if it had activity in the last 5 minutes. Secret projects appear only to workspace admins and members who joined with the project's join code.
Telemetry
Two processes: monitor and brain
TRAINING PROCESS
pulse_monitor.Monitorreads values · writes frames
never blocks, never thinks
BRAIN PROCESS
pulse_brain.Brainhistory · detection
the audit · the agent
pulse. It is the better default. Stream mode is for when you want a run to keep going with nobody attached.Pulse used to be one process, so a run stopped dead while the model thought. Measured on a 20k-step loop, PulseCLI.update() held the training thread for 84% of the wall clock, almost all of it two blocking model calls.
Start a stream run from the training side:
What the training process pays
Nothing is installed into the loop: no sys.settrace, no callback into user code. A background thread reads the training thread's variables a few times a second. It never converts data to answer a question about its shape; only 0-d and few-element values cross the device boundary, on a schedule; and it holds no references, so tracking a tensor doesn't keep it alive.
Why the stream is lossy on purpose
Under backpressure the oldest frame is dropped and the loss is recorded, so the brain knows its view has a hole rather than the loop being slowed. It is an append-only file, not a socket, so the brain can attach late, crash or restart without the run ever waiting.
A debugger shouldn't become the bottleneck.
Measured on a 20k-step loop in stream mode. Method and caveats: docs/overhead.md in the repo. In stream mode the training process runs no Pulse code beyond a background thread, and never waits for a model.
Keras
logs dict, not in local variables, so the stream monitor can't see them by sampling. Streaming needs one line of setup, documented in docs/streaming-keras.md. In-process modes (cli, ui) patch Model.fit and need nothing.Troubleshooting
pulse not found
Add Python's scripts folder to PATH (see Installation), or use python3 -m pulse.
The app doesn't open
Pulse falls back to line-by-line screens without a real terminal (a pipe, CI), on a very small one. On Windows it needs a console that understands escape sequences: Windows Terminal, or the console of Windows 10 and later.
Keys and secrets
Don't put API keys in source code or commit them. A pasted key is never written to disk.