Skip to main content
Training advances a model’s weights from the rewards a rollout already produces. A TrainingClient drives the managed path against one model slug; lower-level methods expose the gradient-accumulation and custom-loss steps underneath it. For the end-to-end loop (forking a model, rolling out a taskset in groups, feeding rewards back) see training agents.

Training paths

Each path accumulates gradients differently, then applies them with the same optim_step. All operate on a TrainingClient except the last. Gradients accumulate across forward_backward / forward_backward_custom / backward calls until an optim_step (or step, which calls both) applies them, checkpoints, and promotes the new weights.

Objects

TrainingClient

A TrainingClient drives managed training for one model: it accumulates gradients from rewarded trajectories and advances the weights behind the model’s gateway slug in place. Inputs are Runs (sent inline) or trace_id strings (resolved server-side); the two can be mixed.

Methods

Advantages are group-relative (GRPO-style) when group_size is set, normalized within contiguous groups of that size; None treats the whole batch as one group. The loss_fn selects the policy-gradient objective applied on top, defaulting to importance_sampling (not GRPO itself). The batch must divide evenly into groups - forward_backward rejects a partial final group before spending a forward pass. num_substeps splits the batch for gradient accumulation.

Inputs

A training input is a recorded trajectory by id, or an inline one:
The methods accept str | Run | TrajectoryPayload, mixed freely. A Run is converted automatically - inline TrajectoryPayload when it carries token-level samples (local rollout), else its trace_id (remote rollout). Build a TrajectoryPayload yourself when the tokens didn’t come from a Run at all - e.g. an opponent move sampled inside the environment during self-play, trained with its own reward. A sample’s prompt is prompt_token_ids for a flat text prompt, or prompt_chunks (serialized text + image chunks) for a multimodal one, where prompt_token_ids is empty. output_logprobs are per output token under the sampling policy.

Token capture

The token ids and logprobs a sample needs come from the gateway. completion_kwargs carries the flag, and it lives only on OpenAIChatConfig, so token capture runs through OpenAIChatAgent (the agent create_agent selects for gateway models routed over Chat Completions). Setting extra_body={"return_token_ids": True} is enough: that agent sets logprobs=True automatically and writes a Sample onto each turn, which a Run converts to a TrajectoryPayload for training.
Calling the gateway directly with your own OpenAI client (for a hand-built payload) takes both flags, since nothing sets logprobs for you:

Built-in losses

loss_fn is an open string validated against the model’s provider; discover the set with await trainer.available_losses(). BuiltinLoss lists the common Tinker names (each is a str): loss_fn_config forwards provider-specific hyperparameters to the loss (e.g. {"epsilon": 0.2} for the ppo clip). The supported keys are provider-defined and not every loss accepts config, so prefer the defaults (None) unless a provider documents a key.

Custom losses

forward_backward_custom runs the current-policy forward pass server-side, hands you per-token tensors, runs your loss locally (torch autograd), and ships the per-token gradients back. Requires torch (pip install 'hud[train]').
Gradients accumulate on the model session until optim_step applies them, so a custom-loss step is not complete until that call promotes the new weights. logprobs[i] are the current policy for datum i as differentiable leaves. Everything else is constant on the matching DatumTensors: Under the hood forward returns a ForwardResult (forward_id + data: list[DatumTensors]); backward(forward_id, weights) applies weights[d][t] = -dC/dlogprobs.

Results

hud models CLI

For the end-to-end loop see training agents; for the Job and Run the trainer consumes see types, and for where rollouts run see runtimes.