prime-rl training run — the RL trainer (and the distillation algorithms that run through it) and the SFT trainer. For multi-node and cluster layouts, see Scaling. For the loss math and algorithm knobs, see Algorithms.
AI agents working in this repo: the equivalent runbooks are atskills/training/— top-level routing inskills/training/SKILL.md, launch details inskills/training/start-run/SKILL.md, and check-in / restart procedures inskills/training/monitor-run/SKILL.md.
Table of Contents
Entrypoints
RL Trainer
Launch
The minimal RL run trains an SFT-warmedQwen3-0.6B on the reverse-text task — the env is bundled with the verifiers submodule, so nothing else needs to be installed:
Useful Knobs
A condensed view of the knobs you’ll most often tune. For trainer-side parallelism, sampling, optimizer, and loss knobs see Scaling and Algorithms. Data and algorithm:
Monitoring:
Run management:
Algorithms
The RL entrypoint supports several training algorithms, switched via[orchestrator.algo]’s type (see Algorithms for the full reference, model references, and per-algorithm customization):
A new algorithm is a named class in code, not a config — see Algorithms § Authoring an Algorithm.
Frozen models are declared inline on the algorithm, named where the model is used —
[orchestrator.algo.teacher] for opd (the frozen model scored against), [orchestrator.algo.sampling.source] for sft (the model it samples from) — each with name + base_url. opsd declares no frozen model: it self-distills against the live policy. The rl entrypoint only manages policy inference — start frozen-model servers yourself and point base_url at them:
uv run sft entrypoint is the more traditional SFT path — pure dataset-based, no orchestrator. Use the sft algorithm only when you want a frozen model to generate the supervision on the fly.
Important Metrics
Pulled from the console logs and mirrored to W&B. Progress (orchestrator):reward/{all,env}/mean— main signal. Should trend upward over hundreds of steps.seq_len/{all,env}/meanandis_truncated/{all,env}/mean— rollout length and truncation rate.num_turns/{all,env}/mean— for multi-turn envs.empty_rollouts/{all,env},errored_rollouts/{all,env}— non-zero is fine in small numbers; sustained > 5% is a smell.eval/{env}/{avg@k,pass@k}— eval scores when[orchestrator.eval]is set.
mismatch_kl/{all,env}/{mean,std,max}— KL between trainer’s current policy and the (older) inference policy that generated the rollouts. A sustained, growing mean is the early-warning sign for off-policy collapse.entropy/{all,env}/mean— too low means mode-collapse; too high means the model isn’t committing.masked_advantage_{positive,negative}/mean— fraction of DPPO-masked tokens, split by sign.optim/grad_norm— spikes precede divergence; check the loss config or lower the LR.
SFT Trainer
uv run sft runs supervised fine-tuning from a HF dataset. It shares model loaders, FSDP setup, checkpointing, and the chat-template plumbing with the RL trainer, so a typical workflow is SFT → RL → SFT → … without any reformatting.
Dataset Format
Two accepted layouts:- Prompt-completion: a HF dataset with
promptandcompletioncolumns (TRL format). The trainer masks out the prompt and computes loss only over the completion. - Messages: a HF dataset with a single
messagescolumn containing a list of chat turns. The trainer interprets the whole conversation as one sample, applies role-based loss masking, and trains over all assistant turns.
messages takes precedence.
Tool definitions and renderer controls. For tool-use SFT, add a tools column (OpenAI function-calling format) or tool_defs (verifiers rollout format). Each row’s value can be either a list of dicts or a JSON-encoded string of a list — both are accepted, and tool_defs rows are auto-converted to OAI shape before being passed into the renderer.
Renderer-backed SFT reads template controls from the typed [renderer] config in the SFT TOML. For example:
renderers (for example a new field on the relevant *RendererConfig) and consume it in the renderer implementation.
Renderer-backed tokenization. SFT tokenization is renderer-only. The renderers package owns message-to-token conversion and loss attribution end-to-end, so position-dependent chat templates (for example templates that strip past <think> blocks across user turns) do not corrupt the loss mask. [renderer] defaults to name = "auto"; set a typed renderer config only when you need model-specific template controls. Hand-coded renderers ship for Qwen3, Qwen3.5, GLM-5, GLM-4.5, Kimi K2/K2.5, MiniMax M2, DeepSeek V3, Nemotron 3, GPT-OSS, and VLM families such as Qwen3-VL/Qwen3.5.
VLM training requires a custom PrimeRL implementation. Training a model with [model.vlm] set (SFT or RL) requires model.impl = "custom" and only works for models with a registered PrimeRL VLM class (currently Qwen3.5 dense and MoE).
See Algorithms § Multi-Turn Trajectories for the full picture.
Launch
The minimal SFT run trainsQwen3-0.6B on the reverse-text SFT dataset:
sft entrypoint manages this for you — see Scaling § SFT and Torchrun for non-default layouts; multi-node SFT goes through SLURM).
SFT-Specific Knobs
Important Metrics
Pulled from the console log and mirrored to W&B. Progress and loss:loss/mean— main signal. Should decrease through the run.val/loss— validation loss when[val]is set, logged everyval.intervalsteps.progress/epoch,progress/num_samples,progress/num_tokens— dataset progress.progress/<subset>/ratio_{samples,tokens}— when training on multiple HF subsets/splits, the realized mixing ratio.
optim/grad_norm— spikes precede divergence.optim/lr,optim/zero_grad_ratio— LR schedule and the fraction of params that received zero gradients (high → dead path or wrong loss masking).- For MoE:
max_vio/mean(load-balancing violation),routing_confidence/mean— both are logged when non-zero.
Checkpointing
Checkpointing is split across processes because the orchestrator and trainer can be on different machines and on different steps at any given time. Inference is stateless.Enabling Checkpoints
Checkpointing is off by default to save disk. Enable it with--ckpt:
Resuming a Run
Re-run the same launch command and pass--ckpt.resume-step <N> (or -1 for “latest”). Make sure --max-steps is at least the target final step, not the remaining delta:
Serving Checkpoints
HF-compatible weight snapshots are written under<output_dir>/weights/step_N/ whenever a full checkpoint runs (or you can write weights-only via --ckpt.weights-only for cheaper snapshots). Upload directly:
ckpt.weights.save_adapter_separately = true to also write the raw adapter alongside the merged weights — useful when serving the adapter through a separate /load_lora_adapter call.
Observability
Log Files
The launcher tees every process’s stdout/stderr into<output_dir>/logs/. The full layout (single-node runs skip the node_*.log and router_*.log files):
orchestrator.log.vf_level. For multi-rank trainer debugging, drop into logs/trainer/torchrun/<rdzv>/attempt_0/<rank>/{stdout,stderr}.log — verbose and per-rank.
Live tailing from a single point (works on the head node for multi-node runs over a shared filesystem):
Console Output
scripts/tmux.sh opens a 4-pane tmux session that follows trainer.log, orchestrator.log, inference.log, and the union of env worker logs. Start it before launching:
-s <session> and -o <output_dir> to run multiple parallel experiments side-by-side in different sessions. The helper also works on a SLURM head node — bash scripts/tmux.sh my-rl-job /shared/outputs/my-rl-job.
Weights & Biases
W&B is off by default. Enable with--wandb:
wandb.offline = true.
By default, every 10 steps each process also logs a sample of prompts/completions (with rewards and advantages) and reward/advantage/entropy distributions as W&B tables. Tune via --wandb.log-extras.interval and --wandb.log-extras.sample-ratio, or disable subsets:
all/effective), per statistic (mean/max/min/p10/p90), and per environment alongside a cross-env aggregate, so a multi-env run can emit thousands of series. To keep that navigable, W&B mode auto-creates an overview saved view on the first run into a project — curating the handful of metrics that matter into train, eval, stability, and performance sections (with per-env breakdowns). The view is created once per project and adapts to the run’s environments; if a later run uses a different set of environments, a new versioned view (overview-v2, …) is created instead of overwriting the first.
Platform Monitoring
Register a run on the Prime Intellect platform (Prime Lab) and stream training metrics, samples, and distributions to the platform dashboard. Bare flag uses defaults:PRIME_API_KEY (set via prime login or env var) and an allowlisted team. Currently internal-only.
Rules of Thumb
- Start small. Run
examples/basic/reverse-text/rl.tomlend-to-end on 2 GPUs before scaling. If the smoke run finishes cleanly, your install is good. - Batch size ≥ 64. Smaller batches give noisy gradient estimates and the trainer’s overhead-per-step dominates throughput. 64 is the practical floor; 128–512 is the range for quick ablations; production RL often runs at 1024+.
- Group size ≥ 8. Bigger groups (
orchestrator.group_size) make it more likely that a task produces a mix of high- and low-reward rollouts, which is what gives the trainer a usable signal — if all rollouts in a group succeed or all fail, the within-group advantage collapses to zero and the trainer learns nothing from that task. Bigger groups also tighten advantage normalization. 8 is the floor; 16–32 is common. - Pin
output_dirper run. Sharing a directory across runs will mix rollouts and break resumes.--output-dir outputs/<unique-name>is the simplest discipline. - Use
--dry-runbefore SLURM. Validators (e.g. CP needs flash-attention) fail fast in dry-run and slow in queue.