launching a training run

train Mar 19, 2026 5 min read

once you have your environment and dataset ready, launching a training run consists of the following steps:

  1. make sure to actually validate everything before you start a training run. see testing for more information.
  2. bundle your environment, then upload the bundle and datasets
  3. (optional) adjust any training parameters
  4. launch the training run!

if you scaffolded your project with castform setup, all of this is already wired into main.py: bare python main.py prepares data, uploads, and validates the uploaded assets, and python main.py launch runs the same path and then a confirmed launch that trains on precisely what was validated. the calls are worth knowing either way.

quickstart

launching is three calls: dump_bundle serializes your environment, upload_assets uploads the bundle and datasets, and TrainerClient.launch_training_run starts the job.

import dataclasses

from benchmax.bundle import dump_bundle
from castform.platform import ensure_session
from castform.platform.environment_assets import upload_assets
from castform.platform.client import TrainerClient

ensure_session()

# 1. bundle the env (via cloudpickle): the class + its constructor args
bundle = dump_bundle(
    MyEnv,
    constructor_args={"search": search},  # kwargs passed to MyEnv.__init__
    pip_dependencies=["some-package>=1.0"],  # installed remotely before unpickling
)

# 2. upload the bundle + datasets (stored under one dataset prefix)
uploaded = upload_assets(
    bundle=bundle,
    train_dataset=train_data,
    eval_dataset=eval_data,
    run_name="my-run",
)

# 3. start the job
trainer = TrainerClient()
run_id = trainer.launch_training_run(
    **dataclasses.asdict(uploaded),
)
# view at https://app.castform.com/experiments/{run_id}

bundle parameters

dump_bundle captures project-local Python modules reachable from your environment automatically. list every package the environment imports at rollout time in pip_dependencies; source from a different project must be passed through local_modules or named as an installed distribution.

parameterdefaultdescription
env_classrequiredyour environment class — a BaseEnv or HarborEnv subclass (first positional argument)
constructor_argsNonedict of kwargs passed to your environment’s __init__. must be pickle-safe: use connection parameters (URLs, keys, config dicts), not SDK clients or open connections
pip_dependenciesNonepip packages to install on the remote machine before unpickling (PEP 508 strings)
local_modulesNonemodule objects from outside your project to pickle by value

upload parameters

upload_assets writes train_dataset as train.jsonl and eval_dataset as eval.jsonl, plus any dataset_files, under a single dataset prefix. the returned dataset_path is that blob prefix (None when no dataset files were supplied), and launch_training_run accepts it as its dataset_path argument.

parameterdefaultdescription
bundlerequiredthe Bundle returned by dump_bundle
train_datasetNonelist of dicts, training examples. omit when the environment resolves this split at runtime (e.g. Harbor); [] uploads an empty JSONL deliberately
eval_datasetNonelist of dicts, evaluation examples, same semantics
dataset_filesNoneextra dataset content: relative file name mapped to bytes, text, or a local path; uploaded under the same prefix as the JSONL splits
run_namerequiredname for the run (used in upload paths)
api_keyNonecastform API key; when omitted the bearer resolves from the active credential seam
base_urlconfig.platform_url()platform URL override

training parameters

pass training hyperparameters via launcher_args to control the training loop:

run_id = trainer.launch_training_run(
    **dataclasses.asdict(uploaded),
    launcher_args={
        "model": "Qwen/Qwen3.5-4B",
        "learning_rate": 1e-5,
        "num_epochs": 5,
        "group_size": 9,
        "max_context_tokens": 8000,
        "lora_rank": 128,
        "lora_alpha": 256,
    },
)

the platform validates launcher_args against a fixed schema; unknown keys return a 400. for the authoritative list of accepted args (names, defaults, ranges, soft caps), call:

trainer.print_launch_args()  # human-readable
trainer.list_launch_args()   # programmatic: list[LaunchArgSpec]

or hit GET /v1/train/launch-args directly.

parametertypedefaultdescription
modelstringQwen/Qwen3.5-4Bhuggingface model id. see supported models
learning_ratenumber1e-5adam learning rate
num_epochsinteger5passes over the training dataset. kept small by default for fast first-launch feedback; increase for longer runs
group_sizeintegermodel defaultrollouts generated per prompt for GRPO advantage estimation
max_context_tokensintegermodel defaulttotal prompt and response tokens across the whole rollout. values above 32768 trigger a memory-risk warning
max_train_examplesintegeroptional source-level limit applied while the environment constructs the training dataset
max_eval_examplesintegeroptional source-level limit applied while the environment constructs the evaluation dataset
lora_rankinteger128LoRA rank, controlling the dimensionality of the low-rank adapter matrices
lora_alphanumber256LoRA alpha, scaling the adapter output. convention is 2x lora_rank
kl_loss_coefnumber0KL penalty coefficient. 0 disables the penalty
eval_intervalintegerhow often (in rollout steps) to run the eval loop. defaults to 20 when omitted
hf_checkpointstringhuggingface repo id of a compatible custom starting checkpoint

next steps