Add a vllm_llm_kwargs passthrough to the vLLM LLM() constructor - #6816
Open
behroozazarkhalili wants to merge 3 commits into
Open
Add a vllm_llm_kwargs passthrough to the vLLM LLM() constructor#6816behroozazarkhalili wants to merge 3 commits into
behroozazarkhalili wants to merge 3 commits into
Conversation
…ructor The colocate path builds `LLM(...)` from a fixed set of explicit kwargs, so any engine argument TRL does not expose a field for is unreachable. Reported in #6776: text-only Gemma 4 checkpoints declare a multimodal architecture, so vLLM takes the multimodal path and fails on a missing preprocessor_config.json. The documented workaround is `hf_overrides`, which the trainer had no way to pass, leaving users to monkeypatch `vllm.LLM.__init__`. `vllm_llm_kwargs` is a dict merged over the explicit kwargs, mirroring how `generation_kwargs` merges over the SamplingParams defaults, with the same rule that conflicting keys override. It is annotated `dict[str, Any] | str | None` and listed in `_VALID_DICT_FIELDS`: both are required for a dict field to be settable from the command line, since argparse resolves the field before `__post_init__` gets a chance to json-load it. The knob lands on `VLLMGeneration`, which is shared by 8 trainers, plus the two paths that build `LLM(...)` themselves: the Online DPO trainer, which never migrated to `VLLMGeneration`, and `vllm_serve.py`, where it takes a JSON string matching the existing `speculative_config` flag. `tensor_parallel_size` and `enable_sleep_mode` are rejected rather than merged. Both are read back after construction: the former builds the TP process group and drives prompt gathering and output slicing, the latter drives the sleep/wake cycle and its bookkeeping. Overriding only the engine side would leave the two out of step, and in the tensor-parallel case that is silent rather than fatal, with each rank submitting its own prompts to a shared engine. The server rejects `tensor_parallel_size` for the same reason, as its weight-sync group size is derived from it.
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
The GOLD trainer now reads `args.vllm_llm_kwargs` when constructing VLLMGeneration, but three `SimpleNamespace` stubs in the test file enumerate the attributes a fake args object carries, so two vLLM init tests raised AttributeError. Two of the three stubs are what the failing tests use. The third lives in `_make_vlm_trainer_args`, whose four callers all take the `use_vllm=False` default and so never reach the vLLM path today; it gets the attribute anyway, since the helper already accepts `use_vllm=True` and the same break returns the moment a caller passes it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Closes #6776.
VLLMGeneration._init_vllmbuilds the colocateLLM(...)from a fixed set of explicit kwargs, so any engine argument TRL does not expose a field for is unreachable. Text-only Gemma 4 SFT checkpoints declareGemma4ForConditionalGeneration, so vLLM takes the multimodal path and loading fails on apreprocessor_config.jsonthe checkpoint never ships.hf_overridesfixes it at the vLLM level, but there was no way to pass it, so @marksverdhei is monkeypatchingvllm.LLM.__init__.This adds
vllm_llm_kwargs, a dict merged over the explicit kwargs. It mirrorsgeneration_kwargs, which already merges over theSamplingParamsdefaults with the same documented rule that conflicting keys override.--vllm_llm_kwargs '{"hf_overrides": {"architectures": ["Gemma4ForCausalLM"]}}'Why generic rather than a narrow
vllm_hf_overridesI asked this on the issue and did not get a ruling, so I built the option I argued for there and I am happy to rename if you prefer the narrow one. The generic knob covers
hf_overridesand every future engine arg without another field each time, andVLLMGenerationis shared by 8 trainers, so one parameter reaches all of them. A narrow field would need adding per-argument, per-config, forever.Coverage
grepfor= LLM(acrosstrl/returns no construction site outside these three:trl/generation/vllm_generation.pytrl/experimental/online_dpo/online_dpo_trainer.pyVLLMGenerationand buildsLLM(...)itselftrl/scripts/vllm_serve.pyspeculative_configflagTwo keys are rejected, not merged
tensor_parallel_sizeandenable_sleep_moderaise if present. Both are read back by TRL after construction, so overriding only the engine side leaves the two out of step:tensor_parallel_sizebuilds the TP process group, and drives the prompt/imageall_gather_object, the PEFT barrier, and the output slicing. With a TP=2 engine andself.tensor_parallel_size == 1, every one of those branches evaluates false and each rank submits its own prompts to a shared engine. That is silent, not a crash, which is why it is worth three lines to make impossible.enable_sleep_modedrives the sleep/wake cycle and_llm_weights_sleeping. Disabling it engine-side while TRL still callssleep(level=2)raises inside vLLM.The server rejects
tensor_parallel_sizefor the same reason: its weight-sync group world size is derived from it. Every other engine arg is pure passthrough with no read-back, so nothing else needs guarding.Notes on the field type
dict[str, Any] | str | Noneand an entry in_VALID_DICT_FIELDSare both required for a dict field to be settable from the command line._VALID_DICT_FIELDSis consumed in__post_init__, which only json-loads a value that is already a string, and argparse runs first: without| strin the annotation the field registers astype=dictand argparse rejects the JSON before__post_init__is reached. This is the same class @qgallouedec described in #6791.Testing
Not added to the test suite, since exercising the merge needs a real vLLM engine. Verified locally:
--vllm_llm_kwargs '{...}'round-trips to adicton all 9 configs, via both the CLI parser and direct dataclass constructionhf_overridesruff checkandruff format --checkclean on all 20 filesI cannot test against a Gemma 4 text-only checkpoint. @marksverdhei, if this lands, could you confirm it removes the monkeypatch on your GH200 setup?
Note
Low Risk
Mostly additive config plumbing; reserved-key validation reduces risk of silent distributed/sleep desync.
Overview
Adds
vllm_llm_kwargsso colocated vLLM setups can pass extraLLM(...)arguments (e.g.hf_overridesfor text-only Gemma 4 checkpoints) without monkeypatching vLLM.The option is wired through nine training configs (GRPO, RLOO, Distillation, GOLD, IW-OPD, Online DPO, SDFT, SDPO, SSD) with
_VALID_DICT_FIELDSso JSON CLI values parse correctly. Trainers forward it toVLLMGenerationasllm_kwargs, which merges overrides onto TRL’s defaults beforeLLM(**kwargs). Online DPO merges the same way in its localLLMbuild;trl vllm-serveadds a JSON--llm_kwargsflag.tensor_parallel_sizeandenable_sleep_modeare rejected inside the extra kwargs (andtensor_parallel_sizeon the server) so TRL’s TP groups, output slicing, and sleep/wake logic stay aligned with the engine.Reviewed by Cursor Bugbot for commit 0a2f3a2. Bugbot is set up for automated code reviews on this repo. Configure here.