Skip to content

[staging CI] unslothai/unsloth#8701 - #312

Open
danielhanchen wants to merge 7 commits into
mainfrom
pr-8701-ci
Open

[staging CI] unslothai/unsloth#8701#312
danielhanchen wants to merge 7 commits into
mainfrom
pr-8701-ci

Conversation

@danielhanchen

Copy link
Copy Markdown
Collaborator

Disposable CI run for unslothai/unsloth#8701. Do not merge; closed after CI.

danielhanchen and others added 5 commits August 13, 2026 14:16
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.
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.
… 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 c160215.
@danielhanchen
danielhanchen requested a review from Datta0 as a code owner August 13, 2026 19:58

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7602088d0c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

"if not (getattr(getattr(self, 'llm', None), 'shared_weights', False) or getattr(self, 'unsloth_fast_inference_lora', False)):",
"generate",
)
generate_patched = install_generate_wrapper()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Roll back when any method patch returns false

When a VLLMGeneration method is absent or inspect.getsource() fails, patch_vllm_generation_method() returns False rather than raising RuntimeError. These results are never checked, so the remaining methods—including this generate wrapper—are still installed and the advertised all-or-nothing rollback does not run. For example, a source-unavailable sync_weights leaves _init_vllm redirected to the shared engine while retaining upstream weight synchronization, which can reload or update that engine unexpectedly; treat any false result as a patch failure and restore the snapshot.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant