The RL Toolchain: TRL, Unsloth, verl, OpenRLHF and vLLM Rollouts
By the end of this lesson you will be able to name the layers a reinforcement-learning run stands on and say which of them your track supplies; choose between TRL’s three rollout paths with a reason; say what Unsloth changes and what its documentation claims for it; recognise when a job has outgrown one machine and which of verl and OpenRLHF is the shape of the answer; and predict the memory a GRPO run will need before you start it.
The stack
Section titled “The stack”A reinforcement-learning run is more layers than a fine-tune, and the extra ones are where jobs fail.
What a GRPO run on one machine stands on
- Accelerator and driverCUDA on Tracks S and N, ROCm on Track X, Metal through MPS on Track M.decides everything above
- PyTorch buildThe CUDA, ROCm or MPS wheel from Part 11. Training happens here whichever trainer you use.
- TrainerTRL GRPOTrainer, or Unsloth wrapping it, or verl or OpenRLHF at cluster scale. Owns the objective, the advantages and the optimiser step.
- Rollout engineThe model's own generate(), vLLM in colocate or server mode, or an OpenAI-compatible server. Produces the G completions per prompt.the wall clock lives here
- Reward functionsYour Python. Deterministic, tested, and the only statement of what the run is optimising.you own this
- Run log and evaluationOne JSON line per run, and pass@1 on held-out problems before and after.the only evidence
TRL, and its three rollout paths
Section titled “TRL, and its three rollout paths”TRL TRL 1.12.0 · verified 2026-09-08 is the reference implementation for this course, because it is already
in the environment from Part 11 and because its GRPOTrainer is a few lines away from the
SFTTrainer you have used. The quick start is genuinely this short:
Fragment — not complete on its own
trainer = GRPOTrainer( model="Qwen/Qwen3-1.7B", reward_funcs=[numeric_reward, format_reward], train_dataset=dataset, # prompt-only, plus any columns the rewards need)trainer.train()The decision that matters is where the completions come from.
In-process generation is the default and needs nothing installed. The trainer calls the model’s
own generate(). It is correct by construction, because the weights doing the sampling are the
weights being trained, and it is slow, because a training-shaped forward pass is not an inference
engine.
vLLM in colocate mode runs vLLM inside the trainer process, sharing the GPU. TRL describes it
as avoiding “launching a separate server”, which “can improve GPU utilization, but may lead to
memory contention on the training GPUs”. It is the default when use_vllm=True and the right
answer on a single accelerator.
vLLM in server mode runs vLLM as a separate process. TRL’s description of the loop is the
useful part: the trainer “asks for completions on the OpenAI-compatible /v1/completions endpoint,
sending the prompt token IDs”, and “after each optimizer step the trainer streams the updated
weights into it over NCCL”. That last clause is what makes it a rollout engine rather than a
generic server.
TRL also documents an escape hatch for tracks with no vLLM: GRPOTrainer accepts a rollout_func,
“a function to use for generating completions”, which “must return a dict with prompt_ids,
completion_ids, and logprobs fields”, and which the documentation marks as “experimental and may
change or be removed at any time without prior notice”. The lab uses it to sample from
llama.cpp’s server, whose /completion endpoint documents an n_probs parameter returning
completion_probabilities with the token identifiers and log-probabilities such a function needs.
Unsloth
Section titled “Unsloth”Unsloth, pinned at Unsloth 0.1.807-beta (GitHub tag) · verified 2026-09-08, wraps the same trainers with custom kernels and memory work. Its reinforcement-learning documentation is specific about what that buys, and the figures below are the vendor’s own, quoted as published rather than measured here.
| Case | Reported figure |
|---|---|
| Llama 3.1 8B, 20K context, 8 generations per prompt, standard implementation | 510.8 GB total VRAM |
| The same case with Unsloth | 54.3 GB total VRAM |
| Smallest local training run named in the guide | 5 GB VRAM, for a model of 1.5B parameters or less |
| QLoRA rule of thumb given in the guide | model parameters in billions is roughly the VRAM in GB |
| LoRA at 16-bit relative to QLoRA at 4-bit | at minimum 4x more VRAM |
not stated in the source beyond the model and context length · Unsloth with vLLM generation, against an unnamed standard implementation Unsloth documentation read 2026-09-09 · Llama 3.1 8B for the first two rows, 4-bit QLoRA except where stated · 20,000 tokens of context · 2026-09-09
Published by Unsloth in its reinforcement-learning guide, not measured by this course. The comparison baseline is described as a standard implementation without naming its configuration, so treat the ratio as an order of magnitude rather than a number to plan with. The validation pass will measure the course's own runs on the four tracks.
The same guide is unusually candid about expectations, and these sentences are worth more than the memory table: it advises applying GRPO “to a model at least 1.5B in parameters”, says to “wait for at least 300 steps for the reward to actually increase”, suggests “at least 500 rows of data” for good results, and warns to expect “a minimum of 12 hours” for a decent result. The labs in this part are deliberately shorter than that, which is why they are written to demonstrate the machinery and measure a small change rather than to produce a reasoning model.
verl and OpenRLHF
Section titled “verl and OpenRLHF”Both are cluster-scale systems, and both are worth knowing about precisely so you can recognise the point at which one machine is the wrong tool.
verl (https://github.com/volcengine/verl) began at ByteDance’s Seed team and is maintained by a community that its README lists as including Anyscale, LMSys.org, the Alibaba Qwen team, Tsinghua University and UC Berkeley. It is Apache-2.0 licensed. Its algorithm list is the whole of this part and more: PPO, GRPO, GSPO, DAPO, Dr. GRPO, RLOO, REINFORCE++, ReMax and PRIME among others. It takes rollouts from vLLM, SGLang or Hugging Face Transformers, trains with FSDP, FSDP2 or Megatron-LM, and its README describes support for models up to 671 billion parameters and scaling “to hundreds of GPUs with expert parallelism”, on NVIDIA GPUs, AMD ROCm and Ascend NPUs.
OpenRLHF (https://github.com/OpenRLHF/OpenRLHF) describes itself as combining “Ray + vLLM distributed architecture with a unified agent-based design paradigm”, and is also Apache-2.0. It supports PPO with a full critic, GRPO, RLOO, REINFORCE++ and its baseline variant, and the direct preference family including DPO and IPO. Its three pillars are Ray as the “distributed scheduler and controller”, separating actor, reward, reference and critic models onto different GPUs; vLLM for generation, on the reasoning that “RLHF training spends 80% of the time on sample generation”; and DeepSpeed ZeRO-3 for memory-efficient training. Its README discusses models of 70 billion parameters and above and gives tuning guidance for machines such as eight A100s.
Neither is pinned in this course’s version table, because neither is on the path any lab takes. The signal that you need one of them is structural rather than a matter of taste: you have more than one machine’s worth of accelerators, you want a separately trained reward model as well as a policy, and you are prepared to operate a scheduler. Until all three are true, TRL on one box is less to go wrong.
Hosted alternatives
Section titled “Hosted alternatives”Several vendors will run a reinforcement-learning job for you against an uploaded dataset. That is a reasonable choice for some work and it is not what this course teaches, for three reasons that have nothing to do with quality. Your prompts and your reward function are the two most revealing artefacts in the whole pipeline, and both leave the machine. The result is not reproducible by you, because you do not control the versions. And the thing being taught here is the mechanism, which is much harder to learn from an API that returns a finished adapter.
The memory arithmetic
Section titled “The memory arithmetic”A GRPO run holds more than a fine-tune does. Count five things: the policy weights, the trainable parameters with their gradients and optimiser states, the reference model if beta is above zero, the rollout engine’s own memory, and the logits and activations of the update.
GRPO on a 16 GB machine: Qwen3-1.7B, rank-16 adapter, 8 rollouts of 512 completion tokens, beta above zero
- Policy weights, BF16
- 3.4 GB
- Reference model, BF16 (only when beta is above zero)
- 3.4 GB
- Adapter, gradients and Adam states
- 0.3 GB
- Rollout key-value cache, 8 sequences
- 0.7 GB
- Logits and activations for the update
- 2 GB
- Reserved for the operating system
- 2 GB
- Free
- 4.2 GB
- Total
- 16 GB
GRPO on a 128 GB machine: Qwen3-4B with vLLM in colocate mode
- Policy weights, BF16
- 8 GB
- Reference model, BF16
- 8 GB
- Adapter, gradients and Adam states
- 0.5 GB
- vLLM allocation at the default 0.3 memory fraction
- 38.4 GB
- Logits and activations for the update
- 4 GB
- Reserved for the operating system
- 4 GB
- Free
- 65.1 GB
- Total
- 128 GB
What each track can run
Section titled “What each track can run”Track S — NVIDIA DGX Spark
TRL with vLLM in colocate mode, and the memory to hold a reference model as well. The 128 GB unified pool is what makes the second diagram above comfortable rather than a squeeze. Check vLLM’s version against TRL’s supported range first, and remember that this is an aarch64 machine, so wheels come from NVIDIA’s arm64 builds as Part 11’s environment lesson describes.
Track X — AMD Ryzen AI Max+ 395Partial
vLLM's GPU installation page read on 2026-09-09 lists Ryzen AI MAX (gfx1151) among its ROCm targets with pre-built wheels, which this course's validation pass has not yet exercised; PyTorch on ROCm for this chip is itself unqualified in AMD's documentation.
Plain TRL with in-process generation is the path that is certain to work, on ROCm if PyTorch sees the GPU and on the CPU if it does not. If the ROCm vLLM wheels install and run on your machine, colocate mode is worth trying and worth writing down as a result either way. The llama-server rollout path is available and carries the stale-weights caveat above.
Track M — Apple siliconPartial
mlx-lm's README, read on 2026-09-09, documents low-rank and full-model fine-tuning and no reinforcement-learning trainer; vLLM's documented GPU path does not cover macOS.
TRL on PyTorch’s MPS backend in float32, with in-process generation, on a model of 0.5 to 1.7 billion parameters. There is no rollout engine to add: vLLM does not run here, and mlx-lm has no GRPO to offer. Expect this to be the slowest of the four tracks and plan the run length accordingly.
Track N — NVIDIA desktop or laptop
TRL with vLLM in colocate mode on one card, subject to the same version constraint. A 16 GB card runs the first diagram above with beta at zero; 24 GB runs it with a reference model and room to raise the rollout count. Server mode is documented for machines with a second card to give it.
| Track | Rollout path | Wall clock | Peak memory, GB | Seconds per step |
|---|---|---|---|---|
| S: DGX Spark, 128 GB | vLLM colocate | to be measured | to be measured | to be measured |
| X: Ryzen AI Max+ 395 | in-process, ROCm or CPU | to be measured | to be measured | to be measured |
| M: Apple silicon | in-process, MPS float32 | to be measured | to be measured | to be measured |
| N: NVIDIA desktop or laptop | vLLM colocate | to be measured | to be measured | to be measured |
the four platform tracks, one machine each · TRL GRPOTrainer with a PEFT LoRA adapter; vLLM where the track supports it trl 1.12.0, transformers 5.16.1, peft 0.20.0; vLLM within TRL's documented range · Qwen3-1.7B with a rank-16 LoRA adapter, BF16, float32 on Track M · 1,024 tokens of context · 2026-09-09
Not yet run on hardware on any track. Fill in your own four figures from the run log after the GRPO lab, and compare the peak against the arithmetic in the diagrams above rather than against another machine.
The first run on a new machine
Section titled “The first run on a new machine”Do not start with the lab. Start with a run designed to fail fast, because six layers means six places to be wrong and the useful skill is telling them apart in minutes rather than in an evening.
Take the smallest model that has a chat template, ten training prompts, four rollouts and ten steps, and watch what the first thirty seconds print. Each layer announces itself in order, and the first line that is missing or wrong tells you which one to fix.
- The device line. If it says
cpuon a machine with an accelerator, the problem is the PyTorch build, not the trainer, and Part 11’s environment lesson is where it lives. Fix this before anything else: everything above will be slow and misleading otherwise. - The trainable-parameter count. PEFT prints it. A count of zero means
target_modulesmatched nothing, which is a name mismatch rather than a memory problem. - The reward line. The training script prints the reward functions and their weights. If a reward you meant to include is missing, you are about to optimise something else.
- The first logged step. A reward of exactly zero on step one is the group-collapse failure from the previous lesson, and it is far cheaper to diagnose now than after two hours.
- The rollout path. With vLLM enabled, an engine that fails to initialise usually fails on its version rather than on memory, and the message says so. With the served path, the first failure is normally the response shape rather than the network.
Ten steps of a 0.6 billion parameter model takes a couple of minutes on any track and tells you whether the machinery is assembled. Only then is it worth spending an hour on a real run.
What to write down before you scale up
Section titled “What to write down before you scale up”Three things, from the smoke test, that decide the shape of the real run. The seconds per step, which multiplied by your step count is the wall clock you are committing to. The peak memory, against the arithmetic in the diagrams above, because a prediction that was wrong by a factor of two is worth understanding before you make the run four times larger. And the rollout path, which is the single field in the run log that most often explains why two runs disagree.
Track the policy version that generated each rollout
Section titled “Track the policy version that generated each rollout”An RL loop alternates generation, verification and parameter updates. If generation runs in another process, it must use the policy version the algorithm expects. A server still holding the initial checkpoint can produce valid text while silently turning an intended on-policy experiment into something else.
Record the policy revision or update step with rollout batches and verify the weight-refresh mechanism documented by the selected trainer. Start with a tiny in-process run where ownership is easier to inspect. Move generation to another engine only after you can explain how weights, tokenisation and sampling remain consistent.
Budget memory for the complete loop: trainable policy, reference if used, optimiser state, rollout buffers and the serving engine’s allocations. A generator and trainer sharing one accelerator can each fit alone and fail together. Measure generation, verification and update time separately. If verification dominates, faster sampling will not remove the bottleneck. An RL stack is operationally correct only when the feedback is computed from the intended policy and delivered to the intended update.
A reinforcement-learning run stands on six layers, of which two are new relative to a fine-tune: the
rollout engine and the reward function. TRL’s GRPOTrainer offers in-process generation, vLLM in
colocate mode and vLLM in server mode, plus an experimental rollout_func for anything else; its
documented vLLM version range does not currently include this course’s serving pin, and server mode
expects a spare accelerator. Unsloth publishes substantial memory savings and equally useful advice
about how long a real run takes. verl and OpenRLHF are cluster systems, both Apache-2.0, and the
signal to reach for one is structural rather than aspirational. The memory to plan for is five
terms, and the largest single decision is whether beta is zero, because a nonzero beta loads a second
copy of the model.
Check your understanding
Sources for this lesson
7 verified · checked 2026-09-09
- 01TRL documentation — GRPO Trainer§ Quick start; GRPOConfig; Speeding up training with vLLM; rollout_funchuggingface.co/docs/trl/grpo_trainer2026-09-09
- 02TRL documentation — vLLM integration§ Supported versions; How TRL uses the server; Modes of using vLLM during training; Advanced usagehuggingface.co/docs/trl/vllm_integration2026-09-09
- 03Unsloth documentation — Reinforcement learning and GRPO guide§ Memory requirements; model size guidance; dataset and step recommendationsunsloth.ai/docs/get-started/reinforcement-learning-rl-guide2026-09-09
- 04verl — README§ Overview; supported algorithms; backends; hardware; licencegithub.com/volcengine/verl2026-09-09
- 05OpenRLHF — README§ Overview; supported algorithms; Ray, vLLM and DeepSpeed; licencegithub.com/OpenRLHF/OpenRLHF2026-09-09
- 06llama.cpp — llama-server README§ OpenAI-compatible endpoints; /completion n_probsgithub.com/ggml-org/llama.cpp/blob/master/tools/server/README.md2026-09-09
- 07mlx-lm — README§ Feature list; command line toolsgithub.com/ml-explore/mlx-lm2026-09-09
Every technical claim on this page was checked against the official documentation of the tool, vendor or model publisher on the date shown, at the version pinned for the course. Where the course disagrees with folklore, the source is how you can tell which one to trust.