Training run
ProA fine-tuning job card where a live train and validation loss curve draws across a fixed step axis that doubles as the epoch progress bar. It shows the learning rate, elapsed time, ETA and the latest evals and checkpoints, has Pause and Cancel while it runs, and ends in results with a Deploy button.
support-triage-v3
- Epoch
- 0 of 3
- Learning rate
- 0
- Elapsed
- 0s
- ETA
- About 18m 40s
- Evals and checkpoints show here
- A fine-tuning or training job page in an AI platform, where people watch loss, pause, cancel and deploy.
- An eval or distillation run that reports a loss curve, checkpoints and a final score.
- A product onboarding step that trains a custom model on the customer's data and ends in a deploy.
- A generic multi-series chart with no job lifecycle: use line-chart.
- A short agent task with steps rather than a loss curve: use agent-status.
- Explaining how training works conceptually: use model-training.
Installation
Pro source and install commands unlock with a Pro plan.
import { TrainingRun, QwenColorMark, HuggingFaceMark } from "@/components/arc/training-run/training-run"; export function FineTuneJob({ job }: { job: Job }) { return ( <TrainingRun status={job.status} name={job.outputName} model={{ name: "Qwen3.8 Max", mark: <QwenColorMark /> }} details={["LoRA r16", "8× H200"]} dataset={{ name: "arcwork/support-tickets-oct", examples: 48210, mark: <HuggingFaceMark /> }} step={job.step} totalSteps={job.totalSteps} epochs={job.epochs} loss={job.loss} learningRate={job.learningRate} elapsed={job.elapsedSeconds} eta={job.etaSeconds} events={job.events} error={job.error} onPause={() => api.pause(job.id)} onResume={() => api.resume(job.id)} onCancel={() => api.cancel(job.id)} onRetry={() => api.retry(job.id)} onDeploy={signal => api.deploy(job.id, { signal })} /> );}API reference
2 parts. The first is the root.
TrainingRun
A fine-tuning job card with a live train and validation loss curve, epoch progress, learning rate, elapsed time and ETA, recent events, pause and cancel, and results with a Deploy button once the run completes. With no props it plays a simulated LoRA run of Qwen3.8 Max.
status"queued" | "running" | "paused" | "completed" | "failed" | "cancelled"–Where the job is. Running with no loss samples reads as starting up. Leave it out to play the built in simulation.namestring"Fine-tuning job"The job or output model name.model{ name: string; mark?: ReactNode }Qwen3.8 Max with its markThe base model. The mark renders at 24px; color marks keep brand fills, mono marks use currentColor.detailsstring[][]Short facts after the model name, such as ["LoRA r16", "8× H200"].dataset{ name: string; examples?: number; mark?: ReactNode }–The training data, shown in the footer with an optional 14px mark (Hugging Face in the demo).stepnumber0Optimizer steps done.totalStepsnumber1Steps in the whole run. Fixes the x axis so the curve never rescales mid-run.epochsnumber1Number of epochs. The axis splits into one band and one progress segment per epoch.loss{ step: number; train?: number; val?: number }[][]Loss samples, oldest first. Train is drawn raw (faint) and smoothed; validation joins its own samples. The line eases toward each new point.learningRatenumber–The current learning rate, shown as 1.84e-4.elapsednumber–Seconds of training so far, excluding pauses.etanumber–Estimated seconds left. While queued it reads as About 18m 40s.events{ id: string; kind: TrainingEventKind; label: string; step?: number }[][]The event log, oldest first. The newest three show; kinds are start, checkpoint, eval, epoch, info, warning, error and done.metrics{ label: string; value: string; hint?: string }[]–Up to four results that replace the live stats on completion. Defaults to final train loss, validation loss, steps and duration.activitystring–A line over the empty chart while queued or starting, such as Waiting for 8× H200 · 2nd in queue.errorstring–Why the run failed, shown in the footer in place of the dataset.onPause() => void–Shows Pause while running.onResume() => void–Shows Resume while paused.onCancel() => void–Shows Cancel while queued, running or paused. Called after a second press on Confirm cancel within 3 seconds.onRetry() => void–Shows Retry from checkpoint when the run failed.onRestart() => void–Shows Run again after a run completes, fails or is cancelled.onDeploy(signal: AbortSignal) => Promise<{ endpoint?: string } | void>–Shows Deploy on completion. The button loads while the promise runs, then the footer shows the endpoint with a copy button; a rejection shows its message and Retry deploy. Aborted if the card unmounts or the run leaves completed.noticestring–A one-off message for screen readers, such as the result of an action.scenario"healthy" | "oom""healthy"Demo only, when status is left out: oom fails once at step 940 so the retry path can be seen.classNamestring–Extra class on the card.useTrainingRunSimulation
The hook behind the demo. Returns every TrainingRun prop for a simulated run, so you can prototype against it before wiring a real job API.
scenario"healthy" | "oom""healthy"Which simulated run to play.activebooleantrueFreezes the simulation while false, for example when the card is off screen.- Tab
- Moves through the loss chart and the footer actions.
- LeftorRight
- On the focused chart, steps through samples; the legend shows that step's train and validation loss.
- Shift+LeftorRight
- Jumps ten samples.
- HomeorEnd
- Jumps to the first or latest sample.
- Escape
- Clears the inspected step.
- EnterorSpace
- Activates the focused action. Cancel needs a second press on Confirm cancel.
- A polite live region announces status changes (Queued, Training, Paused, Completed, Failed, Deployed) and any notice, never every step.
- Status is an icon plus a label, never color alone; the failure reason is text in the footer and in the event log.
- The chart is a labelled group whose name carries the current step and both losses; the arrow keys inspect samples and the legend reads them out visually.
- Cancel is a two step action so a stray press never stops a long run. Deploy keeps focus while loading.
- Stats are a description list; event steps and numbers use tabular numerals.
- The curve and epoch segments ease toward each new sample every frame (exponential, 120ms), so data arriving in bursts still draws at an even pace with no jumps. A rollback or reset jumps instantly.
- The y axis is fixed from the first samples and the x axis spans the whole run, so nothing rescales mid-run.
- New events slide the list down with one bounce-free spring (0.24s); status, stats and footer text crossfade (100ms out, 160ms in, 2px rise).
- Reduced motion: the curve jumps to each sample, the spinner and shimmer stop, and crossfades become instant.
- The demo simulation freezes while the card is off screen.
- Fills its container up to 640px. Under 440px the card padding drops to 16px, stats go to two columns, the legend shortens Validation to Val and the footer stacks context over actions.
- The chart measures its width and redraws at true pixel size, so strokes stay 2px crisp at any width. Touch drag scrubs the chart horizontally while vertical swipes still scroll.
- Curve paths are written straight to the SVG on animation frames, without React renders; the smoother stops when it reaches the latest sample.
- Comfortable up to a few thousand samples. For longer runs, downsample to about 500 points before passing loss.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Use for one fine-tuning or training job: model, dataset, live loss, controls and deploy. For a list of jobs, render one compact row per job and open this card for the selected one.
- Pass totalSteps and epochs from the job config so the axis is right from the first sample. Send loss as it streams; there is no need to throttle, the card smooths it.
- Each control only appears when its callback is passed, so a read-only monitor needs only data props.
- Real marks: import QwenColorMark, MetaColorMark or HuggingFaceMark from the component, or pass your own SVG as model.mark.
- Primary actions (Resume, Retry, Deploy) use the accent; only Confirm cancel uses danger.
The full library index for assistants is at /llms.txt.