Sessions
create_lora_training_client and create_full_training_client start a session: a GPU that loads the model, which takes about a minute (longer the first time). They return once it’s ready.
targets says where training goes; by default the action expert for LoRA, the whole model in full. See Where training goes. action_horizon is the length of the action chunks you train on.
A session holds its GPU until you call close() or leave a with block, or until 10 minutes pass without a connection. What you haven’t saved is lost.
training_client.info has the model’s sizes: {"model": "pi05", "action_horizon": 10, "action_dim": 32, "trainable_params": 16026656}.
Data
A batch is a list oftypes.Datum: an observation in OpenPI’s format, as relay.Policy takes, and the action chunk to learn for it.
- State and actions are as the model sees them (normalized), and are padded with zeros to 32.
- Within a batch, each camera’s frames are one size. A camera a datum leaves out is masked.
- Frames are sent losslessly by default. Pass
codec=relay.Codec.JPEG_Q95to the create call to send less.
Steps run in order, without waiting
forward_backward, optim_step, sample, save_state and load_state send their work and return a Future at once. The GPU runs calls in the order you make them, so the next step is sent while the GPU runs this one. Call .result() to wait for a call and get its value.
The steps
forward_backward computes the flow-matching loss (the weighted mean squared error of the predicted velocity) and adds its gradients to those accumulated so far. Call it several times before an optim_step to train on a batch too big for one call.
optim_step takes an AdamW step with the accumulated gradients, then clears them. You pass AdamParams every step, so any schedule is a line of Python:
A step whose gradient isn’t finite is skipped (
"skipped": True).
Custom losses
forward_backward_custom computes your loss on your machine, in PyTorch:
velocity (which requires grad), target, x_t, noise and time. Your function returns the loss and any metrics; the gradient of the loss with respect to velocity goes back to the GPU, which backpropagates it through the model. It waits for the forward pass, so that calls stay in order, and needs pip install "relay-intelligence[train]".
forward(batch) returns the same outputs without gradients.
Sampling
save_weights_and_get_sampling_client(name) saves the weights and returns a client that samples with them, however training goes on, for evaluating a checkpoint while you keep training: