Skip to content

[hw-agnostic] Implemented plumbing to support OOT plugins - #57715

Closed
bohnstingl wants to merge 9 commits into
vllm-project:mainfrom
bohnstingl:transformer_hw-agnostic_oot-rebinding
Closed

bohnstingl wants to merge 9 commits into
vllm-project:mainfrom
bohnstingl:transformer_hw-agnostic_oot-rebinding

Conversation

@bohnstingl

Copy link
Copy Markdown
Contributor

Purpose

This PR is an alternative to #53153, addressing the same problem: vllm/model_executor/hw_agnostic/custom_op.py currently owns its own op_registry_oot, so an OOT plugin that registers against the public in-tree name lands in a registry the hw-agnostic layers never read.

  • [hw-agnostic] Implemented plumbing to support OOT plugins #53153 links the two paths by having the hw-agnostic module re-export CustomOp, PluggableLayer and both registries from the in-tree module, leaving a single shared registry.
  • This PR instead keeps the two modules independent and bridges them only at plugin load. In particular:
    hw_agnostic_layer_names() (new, vllm/model_executor/hw_agnostic/layers/_layer_names.py) rebinds each mirrored in-tree layer name to its hw-agnostic counterpart for the duration of _run_general_plugins(). Through this, from vllm.model_executor.layers.layernorm import RMSNorm resolves to the hw-agnostic class and register_oot writes the hw-agnostic registry.

The future of this feature depends a bit on the decision whether the existing CustomOp infrastructure will be solely used for the hardware-agnostic path or not, see #44219 (comment) and following. If the in-tree custom_op.py and its layers have to be removed, they can simply be moved over to the hardware-agnostic path with this lightweight rebinding infrastructure removed. As with #53153, existing OOT plugins can remain unmodified. If not, this infrastructure can simply stay.

Test Plan

VLLM_USE_HW_AGNOSTIC=1 pytest tests/models/transformers/test_layer_registry.py -q

Test Result

31 passed, 14 warnings in 196.28s (0:03:16)

cc @hmellor @tdoublep

bohnstingl and others added 4 commits September 8, 2026 12:12
Signed-off-by: Thomas Ortner <boh@zurich.ibm.com>
…hw-agnostic_p2-monkey-patch

Conflict in .buildkite/test_areas/models_basic.yaml: both sides added a test
file to the Basic Models (Other) step. Resolved as a union -- main's
test_deepseek_v4_vl_rocm.py and this branch's
transformers/test_layer_registry.py both run.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Thomas Ortner <boh@zurich.ibm.com>
`_LayerNameScope.__enter__` rebound every public name a hw-agnostic layer
module defines itself, functions included. `activation` defines
`get_act_and_mul_fn` on both paths and the two are not interchangeable: the
in-tree one takes a `compile_native` keyword and raises `ValueError` for an
unsupported activation, the hw-agnostic one takes neither and raises
`KeyError`. So for the duration of plugin loading, an in-tree caller passing
`compile_native=` got a `TypeError`.

Rebinding a function buys nothing to offset that. The mechanism exists so a
plugin's `from vllm.model_executor.layers.<mod> import X` yields the class it
should subclass and `register_oot` writes into the registry that path reads;
a function is neither subclassed nor registered. It was also unprotected --
`validate_registered_overrides` inspects classes, so the swap was wider than
the backstop that checks it.

Filter to classes in `_own_classes` and share it with `_published_classes`,
so the rebinding and the validation cannot come apart again.

Also build the override in `test_registration_follows_the_imported_class`
with `type()` instead of a `class` statement over a variable base, which
mypy rejects as an invalid base class; this matches the idiom
`test_plugin_import_pattern_reaches_the_entry_point` already uses.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Thomas Ortner <boh@zurich.ibm.com>
…hw-agnostic_p2-monkey-patch

Signed-off-by: Thomas Ortner <boh@zurich.ibm.com>

@claude claude 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.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@mergify mergify Bot added the ci/build label Sep 19, 2026
Signed-off-by: Thomas Ortner <boh@zurich.ibm.com>
…hw-agnostic_oot-rebinding

Signed-off-by: Thomas Ortner <boh@zurich.ibm.com>
@mergify

mergify Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @bohnstingl.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

…hw-agnostic_oot-rebinding

Signed-off-by: Thomas Ortner <boh@zurich.ibm.com>
@mergify mergify Bot removed the needs-rebase label Oct 4, 2026
Signed-off-by: Thomas Ortner <boh@zurich.ibm.com>
…hw-agnostic_oot-rebinding

Signed-off-by: Thomas Ortner <boh@zurich.ibm.com>
@tdoublep
tdoublep self-requested a review October 6, 2026 08:53

@tdoublep tdoublep left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

In general I'm concerned that this machinery to rebind stuff creates confusion.

We already have a mechanism for injecting HW agnostic classes via _resolve (here: https://github.com/vllm-project/vllm/blob/main/vllm/model_executor/models/transformers/layers.py#L23-L35).

I think a cleaner approach would be to expose this function publicly so that OOT plugins can call it before inheriting. This way we keep a single mechanism for selecting the classes. I think having OOT plugins opt-in via code change is fine at this point.

@bohnstingl

Copy link
Copy Markdown
Contributor Author

Closing in favor of #60218

@bohnstingl bohnstingl closed this Oct 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants