Skip to main content
A Loops run holds the training state for a base model and its LoRA adapter. Your Python process, which can run locally or in a remote instance, sends forward, backward, and optimizer operations to the trainer, then publishes weights for a sampler to generate from. A run’s trainer and sampler work the same way in either availability mode: serverless or dedicated. The mode decides billing, which models you can train, and what you can configure.

Sessions and runs

A session groups Loops runs, samplers, and checkpoints under a training project. Creating a ServiceClient creates a session, and creating a training client adds a run. Use the run ID, TrainingClient.run_id, to manage the run with the CLI or the Loops API. Runs and samplers belong to a team: your organization’s default team, unless you name another with the team argument of ServiceClient.

Trainers

A trainer owns a run’s adapter and optimizer state. It applies forward, backward, and optimizer steps and saves checkpoints. Creating a training client waits until the trainer can accept operations. create_lora_training_client() sets the run’s sequence length, seed, name, and Weights & Biases logging. In the dedicated mode, you can also scale the trainer with data-parallel replicas, use spot capacity, and reuse a warm run’s trainer and sampler. See Dedicated Loops.

Samplers

A sampler generates from a base model or published checkpoint. A paired sampler belongs to a training run; a standalone sampler is created independently, through ServiceClient.create_sampling_client(). Request a sampling client from a training client with save_weights_and_get_sampling_client(), or pass a published checkpoint path to TrainingClient.create_sampling_client(). By default, the run creates its paired sampler when you first request a sampling client. Set with_sampler=True to create it with the trainer.

Weight sync

Publishing sampling weights makes a checkpoint available to the run’s paired sampler. What a sampling client serves afterward depends on the availability mode:
  • Serverless: The client is pinned to the published checkpoint. Publish again and use the returned client to sample from later weights. The returned checkpoint name can include a unique suffix.
  • Dedicated: The client sets a minimum policy version. The paired sampler loads later published weights without restarting, so the client doesn’t guarantee an exact historical snapshot. TrainingClient.policy_version reports the trainer’s optimizer-step count; serverless trainers don’t support it.
A paired sampler accepts checkpoints with the run’s LoRA configuration. To sample from a different configuration, create a standalone sampler. A standalone sampler serves a base model or saved checkpoint without an active trainer. Create one with base_model or a checkpoint’s model_path, using ServiceClient.create_sampling_client(). Use it to evaluate saved weights after a run ends.

Checkpoints

A checkpoint identifies saved trainer state or weights published for sampling. Its path has the form bt://loops:<run_id>/(weights|sampler_weights)/<checkpoint_name>. Use the returned path and checkpoint name instead of constructing them, because serverless publication can add a unique suffix.
  • save_weights_for_sampler() publishes weights for sampling and inference deployment, without optimizer state.
  • save_state() saves training state for recovery. Its optional ttl_seconds controls expiry; omitting it sets no expiry.
Resume with create_training_client_from_state() for a fresh optimizer, or create_training_client_from_state_with_optimizer() to restore optimizer state and step count. Use Get checkpoint source to determine whether the files are available through presigned URLs or a volume reference. The SDK’s download_checkpoint() handles both storage types.

Debug the SDK

Set LOOPS_REQUEST_LOG to a file path and the SDK appends one JSON line per HTTP request and response, so you can inspect exactly what the SDK sent and replay a failed run: