unsloth/tests/version_compat
Daniel Han c3230a749a
Hand the LoRA to vLLM on TRL 1.x GRPO rollouts (#8701)
* Hand the LoRA to vLLM on TRL 1.x GRPO rollouts

TRL 1.10.0 dropped the collective_rpc("reload_weights") call from
VLLMGeneration.generate, so the regex anchored on it matched nothing and
raised. The lora_request injection ran after that anchor in the same
function, so it never happened, and _init_vllm/sync_weights had already
been installed by then. fast_inference=True GRPO therefore sampled every
rollout from the base model with the adapter ignored, and reported finite
losses while doing it.

Wrap VLLMGeneration.generate instead of rewriting its source, and
intercept on the vLLM engine (generate/chat/collective_rpc), which is the
part Unsloth owns. Restore all three methods if any patch fails, so the
half-patched state is unreachable, and wake a sleeping engine before
sync_weights returns early.

* Raise the TRL cap to 1.10.0, and open the datasets cap to 4.x

Two metadata caps, and both have to move together or neither does anything.

trl<=0.24.0 is metadata only. Nothing in unsloth or unsloth_zoo reads the TRL
version and refuses 1.x at runtime; the only comparisons are floors at
trainer.py:725 and :993. Measured against real TRL 1.10.0 with the trees on
PYTHONPATH so no resolver ever sees the cap: import ok, tests/ -k grpo 991
passed, tests/version_compat 1702 passed, and four real 3-step GRPO runs whose
grad-norms and reward stats match TRL 0.22.2 to every digit. The 5-test gap
against 0.22.2 is this repo's own TRL >= 1.7.0 gated assertions, which 0.22.2
skips and 1.10.0 runs and passes.

datasets<4.4.0 is the second cap, and raising only the TRL one ships a pin no
user exercises: with the datasets cap in place, a resolver asked for
trl<=1.10.0 settles on trl==0.29.1, because TRL 1.10.0 requires
datasets>=4.7.0. So the datasets cap has to open at the same time.

It opens as a hole rather than a floor bump. A datasets>=4.7.0 floor would drop
Python 3.9 and force 4.x on TRL 0.22.2 users who do not need it. The hole
!=4.4.*,!=4.5.0 is exactly what patch_datasets in import_fixes.py already
refuses at runtime over the RLock recursion bug, so metadata and the runtime
guard now agree instead of the metadata being the stricter of the two. Verified
on datasets 4.8.5 with TRL 1.10.0: 991 / 1702 passed, exit 0 both, and the GRPO
smoke numbers are identical to the datasets 3.6.0 run to every digit.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Test that the GRPO rollout adapter reaches vLLM on every TRL generate shape

The failure this locks down is silent: with TRL 1.10.0's generate, the old
source patch anchored on collective_rpc("reload_weights") matched nothing,
raised, and took the lora_request injection down with it, so fast_inference
GRPO sampled every rollout from the base model at exit 0.

The tests are shape-driven rather than version-driven. A synthetic
trl.generation.vllm_generation goes into sys.modules with a VLLMGeneration
whose _init_vllm and sync_weights carry the anchors the source patches need,
and whose generate reaches a fake engine the way a given TRL era reaches it:
sync_weights on 1.10.0, collective_rpc on 0.22.2, chat for conversational
rollouts, and no engine at all in server mode. Then the real
vllm_generation_init_patch runs over it and the fake engine records what
arrived. No vLLM, no GPU, no network, and importlib_version is monkeypatched
so the installed TRL is irrelevant - these pass against the 0.25.1 in this
env, which the patch would otherwise skip outright.

Also covered: the engine methods are restored after the call so a later
model.fast_generate is clean, an engine that already carried its own generate
gets it back rather than deleted, a TRL-created engine is left alone, a
sleeping engine is woken before sync_weights returns early, a failed sibling
patch rolls all three methods back, and patching twice does not double wrap.

Seven of the ten fail on c16021504.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Drop the TRL and datasets cap raise, and keep only the rollout fix

The cap raise is what moves anyone onto TRL 1.x, and that is a separate decision from
fixing the silent rollout bug. Split out so this PR changes no resolved version for
anyone: the pins go back to trl<=0.24.0 and datasets<4.4.0 exactly as main has them.

What is left is inert on the TRL this repo installs. vllm_generation_init_patch returns
at rl_replacements.py before touching anything unless the installed TRL is 0.28.0 or
newer, and TRL 0.22.2 has no trl.generation package at all. It only does something for
someone who has installed a newer TRL themselves, which is exactly who hits the bug.

The tests build a synthetic trl module rather than importing the real one, so they run
on any installed version: 10 passed here against TRL 0.25.1.

The cap raise, with the datasets hole it needs to be reachable at all, moves to its own
PR so it can be judged on its own evidence.

* Verify the rollout patch against every vLLM release, and stop injecting over a positional adapter

Checked LLM.generate, LLM.chat, LLM.collective_rpc, LLM.wake_up and LLM.sleep on
every vLLM release from 0.11.0 to 0.27.1. All are present at each one, LLM has no
__slots__ and no __setattr__/__getattr__ hook, and none of the methods are
decorated, so the instance-level override always takes.

One real gap turned up. lora_request is keyword-only on generate at every version,
but on chat it is an ordinary positional parameter whose index has already moved
once (tokenization_kwargs landed in 0.18.0). A TRL that fills it positionally plus
an injector that adds it as a keyword is "got multiple values for argument", not a
missing adapter. Bind the callable's real signature rather than counting arguments,
so a future reshuffle cannot reintroduce it. A keyword lora_request = None is still
overridden: on a shared-weights engine that means base-model rollouts, which is the
bug this patch exists to fix.

Three tests: a signature-accurate engine carrying vLLM 0.27.1's parameter lists on
both entry points, the positional-chat case, and the explicit-None case. The
positional one fails with TypeError without this change. 13 passed.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: danielhanchen <unslothshared@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-08-14 06:46:48 -07:00
..
__init__.py CI: scope GITHUB_TOKEN permissions, add MLX CI, unblock ~60 skipped tests (#5312) 2026-05-11 03:19:13 -07:00
_fetch.py Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
test_bitsandbytes_pinned_symbols.py Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
test_import_leaves_torch_globals_alone.py Stop the CPU fake-train tests from spoofing torch for the whole session (#8259) 2026-08-09 06:14:54 -07:00
test_peft_conversion_symbol_backfill.py Backfill the conversion symbols peft imports and transformers 5 dropped (#8051) 2026-08-09 03:56:53 -07:00
test_peft_pinned_symbols.py Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
test_sentence_transformers_pinned_symbols.py Clear the four main CI reds blocking every open PR (#8506) 2026-08-12 04:41:34 -07:00
test_transformers_pinned_symbols.py Extend the version-compat matrices to the current PyPI releases (#8020) 2026-08-07 02:21:41 -07:00
test_trl_fake_train_cpu.py Stop the CPU fake-train tests from spoofing torch for the whole session (#8259) 2026-08-09 06:14:54 -07:00
test_trl_grpo_fake_run.py (GRPO) Fix PEFT replacement for TRL >= 1.7.0, add missing compute_aux_loss for TRL >= 1.7.0 (#6904) 2026-07-08 04:05:03 -07:00
test_trl_grpo_pinned_symbols.py Extend the version-compat matrices to the current PyPI releases (#8020) 2026-08-07 02:21:41 -07:00
test_trl_loss_normalization_contract.py Keep checkpoint saves working, and portable, once a TRL config is patched (#8344) 2026-08-10 20:49:40 -07:00
test_trl_padding_free_max_length.py Keep checkpoint saves working, and portable, once a TRL config is patched (#8344) 2026-08-10 20:49:40 -07:00
test_trl_vllm_generation_lora_patch.py Hand the LoRA to vLLM on TRL 1.x GRPO rollouts (#8701) 2026-08-14 06:46:48 -07:00
test_unsloth_zoo_save_merged_pinned_symbols.py Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00