v1.11.0
Features
Use vLLM's own server instead of TRL's
trl vllm-serve used to run a custom FastAPI app around vLLM's LLM, with its own data-parallel fan-out and a worker extension for weight sync. vLLM's own server covers all of that. The custom server is gone: trl/scripts/vllm_serve.py drops from 1218 to ~130 lines and now translates its flags into vllm serve, prints the equivalent command, forwards any extra argument, and sets the three settings TRL needs (--weight-transfer-config, --logprobs-mode processed_logprobs, --max-logprobs -1). fastapi, uvicorn and pydantic leave the vllm extra.
Weight sync now uses vLLM's NCCL weight-transfer engine — tensors are announced once and streamed in a single packed broadcast, instead of one HTTP request + broadcast per tensor. Distillation teacher logprobs come from prompt_logprobs.
Benchmark (GRPO server-mode on H100, Qwen2.5-1.5B / Qwen2.5-VL-3B, same seed, same data):
| Setup | before | after | speedup |
|---|---|---|---|
| Text, TP=1 | 1.08, 0.91 s/step | 0.63, 0.62 s/step | 1.59× |
| Text, TP=2 | 0.96, 0.96 s/step | 0.62, 0.60 s/step | 1.57× |
| VLM, TP=1 | 2.14, 2.13 s/step | 1.48, 1.48 s/step | 1.44× |
Bit-identical completions vs the old server (16/16 over 4 prompts × n=4, logprobs identical to 0.0 over 499 tokens). trl vllm-serve still accepts the same flags — it just forwards to vllm serve now.
by @qgallouedec in #6765
New experimental AsyncDistillationTrainer (+ multi-teacher MOPD)
Async on-policy distillation, architected like AsyncGRPOTrainer: a background rollout worker generates the student's own completions and scores them against a teacher served over HTTP, so generation and training overlap instead of alternating. The teacher is never loaded locally — just a vLLM server URL.
Also supports MOPD (multi-teacher on-policy distillation): pass more than one entry in teacher_server_urls and route each sample to a teacher via a teacher_id column (e.g. a math teacher and a code teacher, each served independently).
from trl.experimental.async_distillation import AsyncDistillationConfig, AsyncDistillationTrainer
trainer = AsyncDistillationTrainer(
model="Qwen/Qwen3-4B",
args=AsyncDistillationConfig(
teacher_server_urls=["http://teacher-math:8000", "http://teacher-code:8000"],
teacher_top_k=16,
),
train_dataset=dataset, # rows carry a `teacher_id` column for MOPD
)
trainer.train()New model & template support
- Muse Glimmer (+ chat template) by @qgallouedec in #6738 and #6739
- Nemotron 3.5 Lightning by @qgallouedec in #6736
- LFM2.5-VL by @qgallouedec in #6737
- Qwen3.8 by @qgallouedec in #6764
- DeepSeek-R1-Distill chat template by @qgallouedec in #6766
Examples reorganized into per-example folders
examples/ was split by format (scripts/ vs notebooks/), which scattered related files (e.g. sft_nemotron_3 existed as both a script and a notebook, in different folders; OpenEnv notebooks lived apart from OpenEnv scripts). Everything is now one folder per story — the name says the method and the task (grpo_wordle, sft_gpt_oss, ppo_tldr), and the folder holds every file the example needs (scripts, notebooks, prompts, chat templates, eval code). Thin single-trainer demo scripts are removed (they live in trl/scripts/ and each trainer doc page has a runnable snippet). Old examples/scripts/… and examples/notebooks/… GitHub / Colab links will 404 — worth flagging in downstream posts.
by @qgallouedec in #6820
AsyncGRPO: metrics rework, dtype control, and cleanup
- Rework AsyncGRPO metrics + docs by @AmineDiro in #6715
- Training dtype in
AsyncGRPOConfigby @AmineDiro in #6774 - Simplify
AsyncGRPOTrainer— drop redundant metric guards, merge train-begin callbacks by @qgallouedec in #6378 - Fix checkpoint resume triggering unnecessary vLLM inference by @AmmarHassona in #5911
Rewritten TRL skill (Python-API first) + drop trl skills install
The TRL skill is now written around the Python API — trainer selection, dataset format, load-bearing config fields, GRPO reward-function contract — with the CLI as a footnote. trl skills install is dropped and the skill source moves out of the package.
- Rewrite the TRL skill around the Python API by @qgallouedec in #6794
- Drop
trl skills installand move the skill source out of the package by @qgallouedec in #6793
DistillationTrainer supports tool calling
Continuing the graduation cycle from v1.10.
by @qgallouedec in #6723
Suggest migrating to DistillationTrainer when the GKD config is fully covered
GKDTrainer now emits a hint when the config is fully covered by the stable DistillationTrainer — no behavior change, just a nudge for users still on the older API.
by @qgallouedec in #6847
Other
- Allow dict config fields to be set from the command line by @qgallouedec in #6792
- Raise when packing is combined with context parallelism by @qgallouedec in #6843
- Emit
position_idsfrom the SFT collator when sequence parallelism is enabled by @qgallouedec in #6812 - Remove one host sync from SFT
chunked_nllloss by @qgallouedec in #6842 - Align the chunked-loss config access between SFT and Distillation by @qgallouedec in #6744
- Add
dataset_sourceto telemetry by @qgallouedec in #6599 - Raise a clear error when generation returns no completions by @albertvillanova in #6714
- Move GPU CI from T4 to L40S by @qgallouedec in #6741
- Add on-policy multimodal GKD regression test by @sergiopaniego in #6342
vLLM version sweep
- Add support for vLLM 0.27.0 and 0.27.1 by @qgallouedec in #6742
- Drop vLLM 0.17 by @qgallouedec in #6722
- Drop vLLM 0.18 by @qgallouedec in #6844
- Require
liger-kernel0.8.2 and drop the SAPO warning filter by @albertvillanova in #6768
Fixes
- Fix GRPO/RLOO training with multiple images for VLMs without grid metadata by @qgallouedec in #6570
- Fix GRPO/RLOO with dynamic-tiling VLMs (InternVL) by @qgallouedec in #6619
- Handle
Nonetoken logprobs from vLLM in GRPO importance sampling by @behroozazarkhalili in #6693 [GRPO]Match the Ligerdapo/cispo/vesponormalizer to the non-Liger path — completes the fix from v1.10 (#6024) on the Liger path. By @kashif in #5890[SFT]Treatpast_key_valuesandattentionsas optional on the model output by @Hakureirm in #6686- Fix
AsyncGRPOTrainercrashing on environment-owned datasets by @albertvillanova in #6824 - Fix SDPO
scale_rewardsCLI parsing and warn on ignored feedback by @sergiopaniego in #6341 - Fix
opencode.pyproxy trace / log paths after OpenEnv moved them to functions by @sergiopaniego in #6672
Documentation and Examples
- Rework AsyncGRPO docs alongside the metrics rework (@AmineDiro, #6715)
- Reorganize examples into self-contained per-example folders (see above)
- Suggest migrating to
DistillationTrainerwhen GKD config is covered (see above)
CI
Big CI-hygiene cycle by @albertvillanova. Highlights:
- Test one Python version on PRs, matrix nightly by @qgallouedec in #6763
- Notify Slack when the tests of the latest release fail by @albertvillanova in #6900
- Post the Docker image build results to the shared CI Slack channel by @albertvillanova in #6903
- Factor the Slack notification into a local composite action by @albertvillanova in #6895 (+ updates in #6896, #6897, #6908, #6934, #6936)
- Move slow-test job status handling, dependencies, and reporting to Slack by @albertvillanova in #6752, #6754, #6756
- Pin the TruffleHog scanner image by digest + tighten secret scanning by @albertvillanova in #6677, #6757, #6758, #6759
- Various hotfix pins and reverts across the cycle (bitsandbytes / liger-kernel / peft dev builds / transformers dev) by @albertvillanova in #6517, #6835, #6840, #6841, #6838, #6915, #6919
- Bump the actions group across 1 directory with 8 updates by @dependabot[bot] in #6727 and #6902
- Restore Liger Kernel's global patches between tests by @albertvillanova in #6783
- Stub the weight transfer in the AsyncGRPO epoch-stop test by @albertvillanova in #6826
- Align AsyncDistillationTrainer with AsyncGRPOTrainer on pre-init args by @albertvillanova in #6825
- Use Flash Attention compatible models in the continuous batching test / async trainer tests by @albertvillanova in #6853 and #6854
- Derive
head_dimwhen the model config does not declare it by @albertvillanova in #6855 - Build the GRPO VLM test images as PIL images to avoid a datasets downcast warning by @albertvillanova in #6889
- Remove the slow GRPO VLM training test by @albertvillanova in #6912
- Ignore benign NumPy
__array_wrap__deprecation and torch inductor TF32 advisory warnings in CI by @albertvillanova in #6850 and #6851 - Stop excluding the TruffleHog
lob/postgresdetectors by @albertvillanova in #6920, #6921 (+ #6926) - Fix misleading SFT step names, misaligned failed-test report headers, use built-in
GITHUB_ACTIONSby @albertvillanova in #6726, #6753, #6749 - Pin Python version in the publish workflow / align Python version in the experimental tests workflow by @albertvillanova in #6883, #6881, #6882, #6884
- Bump doc-builder pre-commit revision + drop ruff workaround by @albertvillanova in #6784, #6790
- Remove the redundant
VERSIONenv from the Docker build step / fix the Slack title of the TRL Docker image build job by @albertvillanova in #6931, #6932 - Remove unused
RUN_SLOWenv variable from the slow tests workflow by @albertvillanova in #6748 - Remove unnecessary
docstyle-ignoretag from docstrings by @albertvillanova in #6785 - Inline the pre-commit action in the code-quality jobs by @albertvillanova in #6886
New Contributors
- @Hakureirm made their first contribution in #6686
- @AmmarHassona made their first contribution in #5911
What's Changed
- ⬆️ Bump dev version by @qgallouedec in #6725
- Hotfix CI: Skip transformers continuous batching test on pre-Ampere GPUs by @albertvillanova in #6712
- Raise a clear error when generation returns no completions by @albertvillanova in #6714
- Pin the TruffleHog scanner image by digest by @albertvillanova in #6677
- Handle None token logprobs from vLLM in GRPO importance sampling by @behroozazarkhalili in #6693
- Drop vLLM 0.17 support by @qgallouedec in #6722
- Fix misleading SFT step names in slow tests CI workflow by @albertvillanova in #6726
- Bump the actions group across 1 directory with 8 updates by @dependabot[bot] in #6727
- [SFT] Treat past_key_values and attentions as optional on the model output by @Hakureirm in #6686
- Add support for vLLM 0.27.0 and 0.27.1 by @qgallouedec in #6742
- Remove unused RUN_SLOW env variable from slow tests workflow by @albertvillanova in #6748
- Do not run slow tests when the setup steps failed by @albertvillanova in #6752
- Fix misaligned headers in the failed tests report table by @albertvillanova in #6753
- Use built-in GITHUB_ACTIONS variable instead of custom IS_GITHUB_CI by @albertvillanova in #6749
- Fix opencode.py proxy trace/log paths after OpenEnv moved them to functions by @sergiopaniego in #6672
- Add DeepSeek-R1-Distill chat template by @qgallouedec in #6766
- Report slow tests results to Slack based on the job status by @albertvillanova in #6754
- Declare the test report dependencies in the test extra by @albertvillanova in #6756
- Pass the pytest report log flag from the workflow instead of the Makefile by @albertvillanova in #6750
- Add Muse Glimmer support and testing by @qgallouedec in #6738
- Add Nemotron 3.5 Lightning support and testing by @qgallouedec in #6736
- Add LFM2.5-VL support and testing by @qgallouedec in #6737
- Add Qwen3.8 support and testing by @qgallouedec in #6764
- Add Muse Glimmer chat template by @qgallouedec in #6739
- Restore Liger Kernel's global patches between tests by @albertvillanova in #6783
- Bump doc-builder pre-commit revision by @albertvillanova in #6784
- Restrict token access in the secret scanning workflow by @albertvillanova in #6757
- Fail the secret scanning job when the scan errors out by @albertvillanova in #6758
- Remove unnecessary docstyle-ignore tag from docstrings by @albertvillanova in #6785
- Rework AsyncGRPO metrics metrics and docs by @AmineDiro in #6715
- Scan the pushed commits in the secret scanning workflow by @albertvillanova in #6759
- Drop ruff workaround from doc-builder pre-commit hook by @albertvillanova in #6790
- Require liger-kernel 0.8.2 and drop the SAPO warning filter by @albertvillanova in #6768
- AsyncGRPOConfig : dtype asyncgrpo training by @AmineDiro in #6774
- Add AsyncDistillationTrainer by @kashif in #6705
- Simplify AsyncGRPOTrainer: drop redundant metric guards, merge train-begin callbacks by @qgallouedec in #6378
- [GRPO] Match the Liger dapo/cispo/vespo normalizer to the non-Liger path by @kashif in #5890
- Fix AsyncGRPO checkpoint resume triggering unnecessary vLLM inference by @AmmarHassona in #5911
- Fix AsyncGRPOTrainer crashing on environment-owned datasets by @albertvillanova in #6824
- Move GPU CI from T4 to L40S by @qgallouedec in #6741
- Align the chunked-loss config access between SFT and Distillation by @qgallouedec in #6744
- Allow dict config fields to be set from the command line by @qgallouedec in #6792
- Hotfix CI: xfail the transformers continuous batching test by @albertvillanova in #6835
- Hotfix CI: skip the offloading test when several accelerators are visible by @albertvillanova in #6840
- Hotfix CI: xfail the tests that DataParallel breaks on multiple GPUs by @albertvillanova in #6841
- Add
dataset_sourceto telemetry by @qgallouedec in #6599 - Test one Python version on PRs, matrix nightly by @qgallouedec in #6763
- Fix GRPO/RLOO training with multiple images for VLMs without grid metadata by @qgallouedec in #6570
- Hotfix CI: xfail the experimental async trainer training tests by @albertvillanova in #6838
- Fix GRPO/RLOO with dynamic-tiling VLMs (InternVL) by @qgallouedec in #6619
- Ignore benign NumPy
__array_wrap__deprecation warning in CI by @albertvillanova in #6850 - Ignore benign torch inductor TF32 advisory warning in CI by @albertvillanova in #6851
- Use Flash Attention compatible models in the continuous batching test by @albertvillanova in #6853
- Stub the weight transfer in the AsyncGRPO epoch-stop test by @albertvillanova in #6826
- Derive head_dim when the model config does not declare it by @albertvillanova in #6855
- Use a Flash Attention compatible model in the async trainer tests by @albertvillanova in #6854
- Fix SDPO scale_rewards CLI parsing and warn on ignored feedback by @sergiopaniego in #6341
- Add on-policy multimodal GKD regression test by @sergiopaniego in #6342
- Align AsyncDistillationTrainer with AsyncGRPOTrainer on pre-init args by @albertvillanova in #6825
- Align Python version in the experimental tests workflow by @albertvillanova in #6881
- Quote python-version value in the tests workflow by @albertvillanova in #6882
- Set up Python explicitly in the slow tests workflow by @albertvillanova in #6884
- Pin the mutable post-slack action reference to a commit SHA by @albertvillanova in #6891
- Bump the pinned post-slack action SHA to the current main by @albertvillanova in #6892
- Emit position_ids from the SFT collator when sequence parallelism is enabled by @qgallouedec in #6812
- Inline the pre-commit action in the code quality jobs by @albertvillanova in #6886
- Pin Python version in the publish workflow by @albertvillanova in #6883
- Notify Slack when the tests of the latest release fail by @albertvillanova in #6900
- Reorganize examples into self-contained per-example folders by @qgallouedec in #6820
- [DistillationTrainer refactor] Support tool calling by @qgallouedec in #6723
- Factor the Slack notification into a local composite action by @albertvillanova in #6895
- Update slack-github-action from v1 to v4 in the local Slack action by @albertvillanova in #6896
- Let Dependabot update actions pinned in local composite actions by @albertvillanova in #6897
- Build the GRPO VLM test images as PIL images to avoid a datasets downcast warning by @albertvillanova in #6889
- Hotfix CI: Xfail MoE LoRA tests against a broken peft dev build by @albertvillanova in #6915
- Bump the actions group across 1 directory with 8 updates by @dependabot[bot] in #6902
- Revert xfail for MoE LoRA tests now that peft#3602 fixed the autocast dtype bug by @albertvillanova in #6919
- Stop excluding the trufflehog lob detector by @albertvillanova in #6920
- Stop excluding the trufflehog postgres detector by @albertvillanova in #6921
- Remove the stale detector exclusion comment by @albertvillanova in #6926
- Remove the slow GRPO VLM training test by @albertvillanova in #6912
- Post the Docker image build results to the shared CI Slack channel by @albertvillanova in #6903
- Fix the Slack title of the TRL Docker image build job by @albertvillanova in #6931
- Remove the redundant VERSION env from the Docker build step by @albertvillanova in #6932
- Read the job status from the job context in the local Slack action by @albertvillanova in #6908
- Drop vLLM 0.18 support by @qgallouedec in #6844
- Use vLLM's own server instead of TRL's by @qgallouedec in #6765
- Drop
trl skills installand move the skill source out of the package by @qgallouedec in #6793 - Make the Slack CI report readable at a glance by @qgallouedec in #6934
- Fix the Slack report posting twice by @qgallouedec in #6936
- Rewrite the TRL skill around the Python API by @qgallouedec in #6794
- Raise when packing is combined with context parallelism by @qgallouedec in #6843
- Suggest migrating to DistillationTrainer when the GKD config is fully covered by @qgallouedec in #6847
- Remove one host sync from SFT chunked_nll loss by @qgallouedec in #6842
- Release: v1.11 by @qgallouedec in #6937
Full Changelog: v1.10.0...v1.11.0