Skip to content

Remove the unreachable prepare_multimodal_messages_vllm - #6946

Open
behroozazarkhalili wants to merge 2 commits into
mainfrom
fix/6928-remove-dead-prepare-multimodal-vllm
Open

Remove the unreachable prepare_multimodal_messages_vllm#6946
behroozazarkhalili wants to merge 2 commits into
mainfrom
fix/6928-remove-dead-prepare-multimodal-vllm

Conversation

@behroozazarkhalili

@behroozazarkhalili behroozazarkhalili commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

What this does

Removes prepare_multimodal_messages_vllm from trl/data_utils.py, its two entries in
trl/__init__.py, and the TestPrepareMultimodalMessagesVLLM test class.

Resolves #6928.

Why remove rather than fix

#6928 reports that the function raises KeyError('content') on an assistant tool-call message that
carries no content key. Reproduced against the function as written:

msgs = [{"role": "assistant", "tool_calls": [{"type": "function", "function": {"name": "f", "arguments": "{}"}}]}]
prepare_multimodal_messages_vllm(msgs)   # KeyError: 'content'

The guard at if isinstance(message["content"], list) assumes every message has a content key.

Nothing calls the function, so fixing it would keep unreachable code alive. @qgallouedec said the
same on the issue and asked for removal instead.

Provenance, checked commit by commit

The function did not become dead in one step:

Commit PR Date Effect
0eb66d8f #4700 2026-01-27 Moved the call out of grpo_trainer and rloo_trainer into vllm_generation.py:509. Still live.
ba89a387 #5238 2026-03-10 Removed that last call site. Dead from here on.

So the function has been unreachable since 2026-03-10, and #5238 is what made it so. The vLLM
path uses to_openai_messages (vllm_client.py:63, called at :327 and :573).

This drops a public name

Worth flagging explicitly, because a call-site search does not surface it: the function was exported
from trl/__init__.py (line 46 in _import_structure, line 95 under TYPE_CHECKING), so
from trl import prepare_multimodal_messages_vllm resolved on main before this PR. TRL uses a
lazy _import_structure dict, where the export appears only as a string literal.

Removing it outright rather than deprecating follows the existing treatment of a redundant utility
of this size: #6158 removed get_kbit_device_map() from those same two lines with no deprecation
cycle. The move-to-experimental-then-remove path in this repo has been used for trainers, not for
helpers.

If anyone is calling this from their own code, say so on #6928 and it can be reconsidered.

Scope

File Change
trl/data_utils.py the function, plus import copy, now unused
trl/__init__.py the two export entries
tests/test_data_utils.py the test class (5 tests), its import, plus import copy, now unused

prepare_multimodal_messages, the sibling without the _vllm suffix, is untouched. It has 26 call
sites across 12 files. require_vision stays imported in the test file because line 47 still uses it.
No documentation references the removed function.

Verification

  • ruff check and ruff format --check on all three files at the CI-pinned 0.13.3, both clean. A
    deliberately broken copy was rejected by the same command, so the gate was reading the files.
  • tests/test_data_utils.py passes.
  • import trl no longer exposes prepare_multimodal_messages_vllm and still exposes
    prepare_multimodal_messages.
  • Zero references to the removed name remain anywhere in the tree.

Both import copy removals were caught by ruff F401 rather than by inspection, which is the failure
mode this change was most likely to hit.


Note

Low Risk
Dead-code deletion with no in-repo callers; the only risk is external code that imported the removed public symbol.

Overview
Removes the unused prepare_multimodal_messages_vllm helper and its public export from trl, along with the dedicated test class. The vLLM path no longer calls this converter (messages go through to_openai_messages instead), and the function was buggy on assistant turns with tool_calls and no content key (#6928).

prepare_multimodal_messages and the rest of the data-utils surface are unchanged. Unused copy imports are dropped where they were only needed for the removed deep-copy logic.

Reviewed by Cursor Bugbot for commit 8ead1b8. Bugbot is set up for automated code reviews on this repo. Configure here.

…ges_vllm

Nothing in trl has called this function since #5238. Its history is two
steps: #4700 moved the call out of the GRPO and RLOO trainers into
trl/generation/vllm_generation.py, and #5238 ("Tokenize before vLLM
generation call") then removed that call site. The vLLM path has used
to_openai_messages since. Only the test suite still exercised the
function.

#6928 reports that it raises KeyError('content') on a tool-call message
that carries no content key. Fixing that would keep an unreachable
function alive, so remove it instead.

The function was also exported from trl/__init__.py, so this drops a
public name. That matches how the repo already treats a redundant
utility of this size: #6158 removed get_kbit_device_map() the same way,
with no deprecation cycle.

Dropping the function leaves `import copy` unused in trl/data_utils.py
and in tests/test_data_utils.py, so both imports go too. The sibling
prepare_multimodal_messages is untouched and still has 26 call
sites across 12 files.

Resolves #6928
@bot-ci-comment

Copy link
Copy Markdown

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.

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.

prepare_multimodal_messages_vllm fails on content-less tool-call messages

1 participant