Training
Solarian's training is library-agnostic. The framework ships only the
generic solarian train command plus a small plugin contract; the actual
training logic for a given model family (diffusion, ACT, a VLA, ...) lives in a
policy plugin. The same plugin also ships the PolicyServer that serves
the trained policy, so a policy is self-contained.
How solarian train works
The command never imports any ML library. It:
- Reads the
trainerkey from the composed training file. - Resolves the matching
PolicyTrainersubclass through thesolarian.trainersentry-point group. - Registers that trainer's
resolvers(), then resolves the file, so it can use interpolations only its trainer defines (${eval:...}for UMI). - Validates the config with that trainer's
config_class(). - Resolves an
output_dir(defaults to$SOLARIAN_PROJECT_PATH/models/<job_name>). - Runs it in this process:
TrainerCls(cfg, output_dir).train().
The solarian-modal plugin's solarian modal-train runs the same config on
Modal; see Cloud training.
solarian train --conf conf/training/cup_arrange
solarian train --conf conf/training/cup_arrange training.num_epochs=10
--conf names the training file; there is no default. Any key in it can be
overridden on the command line as key=value.
One file per training run
Every run is one complete file in conf/training/: which trainer runs it, the
data, the model, the optimizer, the schedule and the tracking. Nothing is
inherited from another file and no value hides in code, so the file is the
whole record of the run.
A trainer plugin ships templates/training/<name>.yaml. solarian install
copies it to conf/training/<name>.yaml once, when that file is not already
there. Copy it per run. trainer: stays the trainer's entry-point name, so
several runs share one trainer.
cp conf/training/umi.yaml conf/training/cup_arrange.yaml
solarian train --conf conf/training/cup_arrange
UMI
solarian-umi-skill registers trainer: umi and seeds four training files:
conf/training/umi.yaml (camera and proprioception, no target),
conf/training/umi_pick.yaml (the target box as a 4th image channel),
conf/training/umi_pick_mask.yaml (the object's mask, CLS token and
box_pool) and conf/training/umi_place.yaml (a place point, drawn as a
square on the 4th channel). A target is any task.shape_meta.obs entry with
bbox_mode: mask_channel, point_mode: mask_channel or type: mask, read
from the dataset array of the same name (bbox, point or mask, written by
the track and track_point dataset ops). Each target adds one input channel
to the ViT, so a policy can take several, and a checkpoint with fewer starts
one with more (training.init_from_ckpt; the new channel starts at zero).
Each is the UMI training config written as python train.py
reads it in the UMI repo, with the task inlined under task:, plus four
Solarian keys at the top: trainer, job_name, output_dir and modal.
Copy one per run and set:
job_name— checkpoints land inmodels/<job_name>/.task.dataset_mix— the datasets,[{path, weight}], fromsolarian umi-slam.task.dataset.val_dataset_path,training.init_from_ckpt,batch_size,training.num_epochs, ... — every other value of the run, already written out.
Training runs in this process from the UMI code copied into the plugin. It writes
models/<job_name>/checkpoints/latest.ckpt. Pair each training file with a
skill yaml copied from conf/skills/umi.yaml, and set that file's
server.checkpoint to the same path. solarian run-service cup_arrange then
serves it, and the same UMISkill loads whichever file you name:
self.start_skill(UMISkill(params={"config": "cup_arrange.yaml"}))
conf/training/cup_arrange.yaml job_name: cup_arrange
conf/skills/cup_arrange.yaml server.checkpoint: models/cup_arrange/checkpoints/latest.ckpt
A checkpoint with targets also needs the skill yaml's targets, which maps
each to the camera field holding it, such as {point: target_point} for a
place policy. conf/skills/umi_target.yaml is the template; see
Skills.
The copied training and SLAM code is from
Universal Manipulation Interface,
copyright 2023 Columbia Artificial Intelligence and Robotics Lab, MIT
license. The license text ships beside each copy, as slam/LICENSE.umi and diffusion_policy/LICENSE.umi.
solarian umi-slam <session_dir> turns a directory of GoPro or Lumi collector
MP4s into a dataset, which is a task.dataset_mix path above.
ORB-SLAM3 runs in Docker image chicheng/orb_slam3:latest and GoPro IMU
extraction in chicheng/openicc:latest. An image already on the machine is
used as it is. A missing image is downloaded only after you agree.
The trainer declares a modal_spec(), so solarian modal-train runs these
configs on Modal too.
The PolicyTrainer contract
Defined in
solarian/core/ai/system1/policy_trainer.py.
A plugin subclasses it and implements train():
from solarian.core.ai.system1 import PolicyTrainer, ModalSpec
class MyTrainer(PolicyTrainer):
@classmethod
def config_class(cls):
return MyTrainConfig # a TrainConfig subclass
@classmethod
def modal_spec(cls):
return ModalSpec(pip_packages=["torch", "my-lib"])
def train(self):
... # the real training loop, using self.cfg and self.output_dir
| Member | Purpose |
|---|---|
train(self) | Required. Runs training to completion. |
config_class() | Pydantic schema validating the config (defaults to the thin TrainConfig). |
resolvers() | OmegaConf resolvers the trainer's files may use, registered before they resolve. |
modal_spec() | Declares the container image (apt/pip deps) for cloud training. |
add_arguments / from_args / main | Standalone CLI launching (e.g. under accelerate launch). |
Thin base config
The framework's TrainConfig
(solarian/core/configs.py)
only knows common fields — trainer, train_dataset, val_dataset,
output_dir, job_name, batch_size, steps and logging — and uses extra="allow", so any plugin-specific keys (model architecture,
optimizer, ...) pass through untouched. A plugin's config_class() is a
TrainConfig subclass that re-adds and validates those fields.
Registering a trainer
A policy plugin advertises its trainer under the solarian.trainers
entry-point group, and its policy server as a service under solarian.services:
[project.entry-points."solarian.trainers"]
my_policy = "my_policy_pkg.trainer:MyTrainer"
[project.entry-points."solarian.services"]
my-policy = "my_policy_pkg.service:MyPolicyService"
Then trainer: my_policy in a training file selects it, and
solarian run-service my-policy --checkpoint <ckpt> serves what it trained; see
Policies. Install missing
plugins with pip install <plugin>; solarian train lists the available
trainers if the requested one isn't installed.
Cloud training (Modal)
Install the solarian-modal plugin and call solarian modal-train with the
same config as solarian train, plus a modal: block:
solarian modal-train --conf conf/training/cup_arrange
modal:
gpu_type: A100-80GB
gpus: 2
volume: solarian-data
profile: null # a ~/.modal.toml profile
forward_env: [WANDB_API_KEY]
It builds a modal.Image from the trainer's modal_spec() and uploads the
local files the config names to the volume, rewriting their paths. Then it
spawns a detached job that runs the trainer under accelerate launch, with
checkpoints in /outputs/<job_name> on the volume. The command returns once the
job is spawned, so calling it once per config runs jobs in parallel. The
plugin's README covers the details.
To train without a Modal account, or on datasets stored in Solarian Base, deploy
the project and use solarian base train with the same config; see
Training & Runs. Base serves the checkpoints its
jobs write, too; see Services, Policies & Models. Metrics go wherever
logging.backend says, Solarian Base by default; see
Experiment tracking.
Reference plugins
solarian-policy-lerobot(trainer: lerobot_act) — trains and serves a LeRobot ACT policy.solarian-umi-skill(trainer: umi) — trains a UMI diffusion policy locally. The same plugin'sUMISkillruns the checkpoint over HTTP. See One file per training run.
See also
- Experiment tracking — log to wandb, Solarian Base, or both.
- Training & Runs on Solarian Base — deploy the project and train on cloud GPUs.
- Skills — behaviors that consume a policy server.
- Policies — the
PolicyServer/PolicyClientHTTP contract, and serving a checkpoint. - Plugins — how Solarian discovers plugins.