
This page covers training several adapters on one model resource. To serve the trained adapters from one inference deployment and compare them, see Multi-LoRA deployment.
How many sessions a resource takes
A resource created withlora_enabled=True accepts up to five concurrent sessions by default, and fewer for some models. A full-weight resource (lora_enabled=False) accepts one. Before you plan a sweep, check the model’s row on Supported models. Creating a session beyond the cap fails with HTTP 429 and an “at capacity” message. The SDK retries the request a few times, then raises RateLimitError.
Sessions on a resource share its base model, GPU type, generator replicas, and optimizer, so a sweep can vary only what each session sets for itself: its LoRA config, its data, its loss function and sampling settings, its learning rate and other per-step optimizer parameters, and its checkpoints.
Attach to a running resource
A training run names exactly one model source:modelprovisions a fresh resource that the run owns. When the run exits, it stops both its session and the resource.model_resources_idattaches a session to an existing resource as a tenant. When the run exits, it stops only its own session and leaves the resource running.
model_resources_id and leave model unset:
- Be
READY. - Be LoRA-enabled when
use_lora=True. - Have a generator when the run samples.
recipes/grpo/deepmath_shared.py.
Run a sweep
A hyperparameter sweep is a set of training runs that are identical except for one or two settings, such as the learning rate or LoRA rank. You compare the resulting adapters to find the values that work best. On a shared resource, a three-run sweep costs the GPU time of one base model instead of three. Provision once, train every run in the sweep concurrently as its own session, and tear down once. The cookbook’s DeepMath sweep (recipes/grpo/deepmath_sweep.py) is the worked example. It trains four arms, each a session with its own learning rate:
- Concurrency:
train_single_turnblocks, so each arm runs in its own thread. The SDK tracks each session’s work separately, so one arm’s teardown doesn’t cancel another arm’s work. - Isolation: An arm that raises doesn’t stop the others. Collect failures with
future.exception()after the pool drains. - Model selection: Put the arms in one
wandb_groupand compare theirval/accuracycurves side by side. Each arm already runs validation, so picking the best adapter takes no extra evaluation code. - Teardown: The
ModelResourcesClientcontext manager stops the resource once on exit, even if an arm raised. If you don’t use the context manager, callresource.stop()yourself.
uv run python recipes/grpo/deepmath_sweep.py. Each arm logs to Weights & Biases, so set up W&B or turn it off, as Monitoring describes, before you run it.
Keep a resource alive
A resource stops on its own after an hour without an operation from any of its sessions. An attached session that sends no operations doesn’t keep it alive: at the one-hour mark, every session on the resource is markedEXPIRED and the resource stops. To keep a shared resource alive between runs, start the next run within the hour.
A ready resource bills whether or not anything is training on it, so when your team is done, stop it with force=True, which also stops any tenant sessions still attached.
Next steps
Multi-LoRA deployment
Compare the trained adapters on one endpoint and pick the winner.
Supported models
Per-model session caps and GPU types.
Manage model resources
Create, inspect, and stop the resource your sessions share.
Pricing
What a shared resource costs and when it stops.