Repository navigation
Move vLLM to 0.29.0 and transformers to v5 - #1127
Closed
tengomucho wants to merge 43 commits into
Closed
tengomucho wants to merge 43 commits into
tengomucho wants to merge 43 commits into
Conversation
WorkerBase.compile_or_warm_up_model() now returns a CompilationTimes named tuple, which the executor reduces with max(); returning None raises AttributeError. Return a zeroed CompilationTimes instead. set_random_seed() now delegates to Platform.manual_seed_all(), which is abstract in the base class, so init_device() failed before the model was ever loaded. Add a no-op override. Also drop initialize_cache(): it no longer exists on WorkerBase and has no callers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fixes 25 open advisories over 0.16.0 with no change to torch, transformers or tokenizers. vLLM 0.23.0 declares torch==2.11.0, but torch-neuronx requires torch 2.9.x. That pin is resolver metadata only: vLLM imports and runs fine on torch 2.9.1, so it is overridden via [tool.uv] override-dependencies. Note this is a uv feature -- a plain `pip install optimum-neuron[vllm]` will still hit the conflict. Every install path in CI and docker/vllm already uses uv. 0.23.0 is the last vLLM that still accepts transformers 4.x; it already warns that the v4 codepath is removed in 0.24.0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Brings transformers v5 compatibility fixes in the exporters and the read-only config handling for sentence-transformers >= 5, which is the version already pinned in the test extra. No code change is required: every optimum API used here (ExporterConfig, OptimizedModel, TasksManager, the dummy input generators and the normalized configs) is unchanged. The only removals are the AutoGPTQ helpers, the TensorFlow framework detection and the ipex pipeline accelerator, none of which are referenced. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
neuronx_distributed unconditionally imports transformers.utils.fx, which no longer exists in transformers v5, so `import neuronx_distributed` fails outright. Register a minimal stand-in module when the real one is absent, so this is a no-op on transformers 4.x and stops doing anything once the import is guarded upstream. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- drop the remote URL branch when loading a neuron config: transformers removed download_url / is_remote_url, - check safetensors availability with the local import helpers, - read the token with huggingface_hub.get_token, HfFolder is gone in huggingface_hub v1, - vendor get_preprocessor, removed along with transformers.onnx, - drop the dead T5 head pruning path, head pruning is gone, - drop the question-answering pipeline, removed from transformers, - use the canonical Generate*Output generation output classes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
transformers v5 merged config.rope_theta and config.rope_scaling into a single config.rope_parameters dict, with models using several attention types (Gemma3) nesting one dict per layer type. Route every call site through a single helper. The deprecated config.rope_scaling now always returns a dict, so the checks that relied on it being None had to move to the rope type. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The vendored generation code relies on BeamSearchScorer, removed in transformers v5. Beam search is dropped from the traced seq2seq models rather than vendored further: generate() now rejects num_beams > 1 with an explicit error, and the beam tests are removed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
WorkerBase.load_model now takes a load_dummy_weights keyword argument. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vLLM 0.24 and later require transformers v5, so both move together, and transformers v5 in turn requires huggingface_hub v1. peft, diffusers and compel are bumped to their first releases supporting transformers v5. vLLM declares torch 2.13 and a matching torchcodec, which torch-neuronx does not allow: both stay overridden to the versions torch-neuronx requires, as they are resolver metadata only. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vllm.entrypoints.openai.cli_args is gone and the OpenAI api_server module is deprecated: both moved under vllm.entrypoints.launchers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Neuron configuration classes are registered by importing both the inference and the training configurations. The training models do not support transformers v5, so importing them made loading any inference configuration fail. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
transformers removed the CLIPFeatureExtractor alias of CLIPImageProcessor, and diffusers moved the controlnet models under models/controlnets. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
transformers v5 no longer sets the token id attributes on every configuration, so reading config.pad_token_id raises instead of returning None for a model that does not define one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
transformers v5 types Llama4 attn_temperature_tuning as a boolean, and the configuration of tiny-random/llama-4 still holds the integer the previous version expected, which is now rejected when loading it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
transformers v5 stores the mixture of experts weights as a single tensor per projection, shaped (num_experts, out_features, in_features) with the gate and up projections stacked along the output dimension, instead of one linear layer per expert. Transposing the two fused tensors replaces the per-expert copies. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
EncoderDecoderCache.from_legacy_cache is gone, and iterating a cache no longer yields the flat per-layer tuples the traced decoder relied on. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
transformers no longer falls back to the eager attention when attention weights are requested: the other implementations return none at all, so the traced model was missing its attention outputs. Encoder and decoder stacks keep their own configuration and have to be switched as well. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
transformers v5 always returns a ModelOutput, and CLIP text models no longer run at all with return_dict=False, which is what used to give the tracer the tuple it needs. Select the configured outputs in the export wrapper instead, which also fixes their ordering. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
flaubert/flaubert_small_cased sets pre_norm, and that path of the transformers modeling code cannot run at all: it subscripts an EncoderDecoderCache. Use the tiny random model, as every other architecture in the list does. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Same reason as in the exporter tests: the pre_norm path of the transformers flaubert code cannot run at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
transformers v4 turned its model outputs into a tuple while tracing, and the neuron models read them positionally. transformers v5 dropped that, so the traced models returned a dict of named outputs instead. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
transformers v5 tokenizers no longer return token_type_ids, so a model traced with them was called with one input missing. They default to zeros. The traced inputs are now also ordered as they were traced, rather than as the caller happened to build them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Same reason as in the other model lists: the pre_norm path of the transformers flaubert code cannot run at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
transformers v5 pipelines are PyTorch only and no longer carry a `framework` attribute. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
transformers removed the question-answering pipeline, so the neuron pipeline no longer supports that task either. The model tests are unaffected. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The export CLI runs `python3 -m optimum.exporters.neuron` in a fresh process, whose import root is that package: it only reaches the shim installed by optimum.neuron through the order its imports happen to be sorted in. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The processes neuronx_distributed spawns to trace a tensor parallel model import it while unpickling their work item, before any optimum module: neither of the in-process install points is reached, and the export dies. A path configuration file covers them, and every other process that imports neuronx_distributed first. The shim is now served by a meta path finder appended to sys.meta_path, so the startup hook imports neither transformers nor torch, and the real module still wins wherever transformers provides one. It lives in a top level module for the same reason: importing anything under optimum.neuron would pull transformers into every python process. Editable installs do not get the path configuration file, so the shim only covers spawned processes when optimum-neuron is installed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
transformers v5 leaves the generation configuration fields at None rather than at their default value, and resolves them when generating. The vendored generate compared them directly, so it recognised no generation mode at all and rejected greedy decoding. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The parallel T5 attention is a copy of the transformers implementation, which changed: the relative position bias is now offset by the number of cached tokens instead of indexing a cache position, the layers pass down keyword arguments this implementation does not use, and they unpack three values from every attention call. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both divergences from the CPU model happen at a step where its two best logits are exactly equal, so which token wins is decided by the order argmax breaks the tie in. Every earlier token matches. Which configuration lands on which side moves with any change to the computation: qwen3 now diverges at 1x8192 rather than at 4x1024, and gemma3 diverges on the long prompt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The fractional coordinates the vision position ids are bucketed from are clamped by transformers, not scaled: the (1 - 1e-6) factor this was copied from moved every coordinate just below its bucket boundary, which shifted all but the first position by one. It matched the transformers implementation it mirrored until that one was fixed. The vision features now match the reference to 8e-05, instead of differing by half their own magnitude. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The neuron generation loop pads a sequence once it is done, so it can carry trailing pad tokens transformers does not return: the cross chunk case now generates the very same text and only differed by one of them. SmolVLM also picks the last of its twenty tokens out of two candidates the CPU model separates by less than a bfloat16 step, which is recorded the way the other known divergences are. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The engine core now asks every worker which KV cache layouts it supports, and the base implementation answers by looking up the vLLM attention backends, of which a neuron worker has none. The compiled model owns its KV cache, so any layout the engine can resolve will do. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The image only carried the package and pyproject.toml, so the build hook placing the startup hook in site-packages, and the module it installs, were missing and the install failed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every other option of the serve command is declared in both spellings, and the arguments the command does not declare are forwarded to vLLM: --data_parallel_size reached vLLM instead, which served the model from its own data parallel engines, all of them claiming every visible core. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
huggingface_hub v1, which transformers v5 requires, moved to httpx and no longer installs requests. optimum.exporters.tasks imports it at module level, and so does our own neuron exporter, so a plain install of the package could not run a single optimum-cli command. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The training layer is not migrated to transformers v5, but it still has to import: the documentation autodocs models.training and trainers, and the doc build fails to resolve those objects otherwise. - get_parameter_dtype is gone, the PreTrainedModel dtype property does the same thing, - no_init_weights moved to transformers.initialization, default_logdir to transformers.integrations.integration_utils and PreTrainedTokenizerBase to transformers.tokenization_utils_base, - TensorFlow and Flax are gone along with their weight file names, so the branches reporting checkpoints in those formats go with them, - so are download_url and is_remote_url, dropping the remote URL branch, and is_safetensors_available, safetensors being always available now. Training configurations can be deserialized again, so the guard added while they could not is removed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
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. |
huggingface_hub v1 switched from requests to httpx and made the `response` argument of `HfHubHTTPError` a required keyword-only argument that is dereferenced in the constructor. An error without a response can no longer exist, so drop the now unreachable guard in `_is_commit_conflict` and build the test errors from httpx objects. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
huggingface_hub v1 uses httpx instead of requests, so a network failure while inferring the task now surfaces as an httpx.TransportError. It escaped the requests.ConnectionError handler, and the user got a raw connection error instead of the hint to pass --task. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
uv does not apply [tool.uv.sources] to override-dependencies, so the torch and torchvision overrides no longer resolved from the PyTorch CPU index: every install pulled the CUDA builds from PyPI, along with the nvidia runtime wheels and triton. Pin the local version in the overrides and make the index non explicit, which is what the overrides need to reach it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The pipelines are kept alive by reference cycles, so their Neuron models are only unloaded when the garbage collector runs. When that happens in the middle of the next pipeline load, the runtime fails to unload a model whose cores have been reinitialized, and torch-neuronx throws from a destructor, which aborts the process. Collect after every export fixture and after every test, so the models are unloaded while nothing else is loading. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
transformers v5 fuses the mixtral and qwen3-moe expert weights into per-layer tensors and renames the mixtral sparse block from block_sparse_moe to mlp, but it only applies that conversion when it loads a checkpoint. The neuron exporter reads the safetensors files directly, so checkpoints saved earlier still hold one tensor per expert and per projection, and exporting them failed with a KeyError. Extract the expert weights through a helper that handles both layouts. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vLLM stops the spawned EngineCore process only when the LLM object is finalized, and the engine tests left that to the garbage collector. When the object survives the test, the engine core is still running at interpreter exit, where multiprocessing joins that non-daemon child with no timeout, so the session reports its results and then hangs forever. That is what parked the INF2 vLLM workflow right after "1 passed". Create the engines through a fixture that shuts them down after each test, so the teardown no longer depends on when the collector runs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
tengomucho
marked this pull request as ready for review
September 17, 2026 07:12
JingyaHuang
approved these changes
Sep 17, 2026
JingyaHuang
left a comment
Collaborator
There was a problem hiding this comment.
Thanks for the fix!
| help="The port on which to serve the model.", | ||
| ) | ||
| parser.add_argument( | ||
| "--data_parallel_size", |
Collaborator
There was a problem hiding this comment.
why do you want to enable both flags here? Is it related to the fix?
Member
Author
There was a problem hiding this comment.
because some users expects underscores and others expect dashes, and this is an easy way to support both
|
This PR is stale because it has been open 15 days with no activity. Remove stale label or comment or this will be closed in 5 days. |
|
This PR was closed because it has been stalled for 5 days with no activity. |
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 does this PR do?
This PR is to move vLLM from 0.23.0 to 0.29.0. The reason is to close the security advisories raised by dependabot and prepare a release with less CVE risks.
Since vLLM 0.23 was the last one accepting transformers 4.x, and update to transformers v5 was also necessary, together with the update to huggingface_hub v1.
Even if recent vLLM declares a dependency to
torch==2.13.0, those seem to be metadata only, since vLLM only tests with one version of pytorch and supports only that version, but that can be overridden and that is what is done here, because the latest torch supported by SDK 2.31 is 2.9.1.All the changes were done with an agent. The Claude description details for this PR follows.
Dependencies
peft, diffusers and compel move to their first releases that work with transformers v5 —
the previous pins fail at import.
The neuronx_distributed shim
neuronx_distributed/pipeline/trace.py:43importstransformers.utils.fx, deleted intransformers v5 along with the rest of torch.fx support, so
import neuronx_distributedfails outright. The newest published wheel (0.19.28492) still has it.
_optimum_neuron_fx_shim.pyappends a finder tosys.meta_paththat serves a minimalstand-in module. Being appended, it is consulted only once the regular finders have failed,
so transformers 4.x keeps its real module and the shim retires itself the day AWS guards
that import.
It is installed at interpreter startup by
optimum-neuron-fx-shim.pth, because theprocesses
parallel_model_tracespawns import neuronx_distributed while unpickling theirwork item, before any optimum module: tensor parallel export of encoder-decoder models dies
without it. Nothing is imported until something actually asks for
transformers.utils.fx,so the hook costs a few milliseconds and pulls in neither torch nor transformers.
Note that an editable install does not get the path configuration file, so on a development
checkout the shim only covers the current process.
Two bugs this surfaced
i/N * (1 - 1e-6), copied from transformers 4.57. The bucket boundaries sit exactly atmultiples of
1/N, so that factor pushes every coordinate just below its own boundary:31 of 32 positions were shifted by one, in both dimensions. transformers v5 replaced the
scaling with a clamp, which is what made the copy visibly wrong — the vision features
differed from the reference by 58.8 against a magnitude of 114, and agree to 8e-05 now.
--data_parallel_sizereached vLLM. Every other option ofoptimum-cli neuron serveis declared in both spellings; this one only in the dashed form, so the underscore
spelling fell through to vLLM, which served the model from its own data parallel engines,
all of them claiming every visible core.
API changes
config.rope_thetaandconfig.rope_scalingcollapsed into a singleconfig.rope_parametersdict, which Gemma3 nests per layer type. All call sites gothrough one helper. The deprecated
config.rope_scalingnow always returns a dict, soevery
is not Nonecheck on it had to move to the rope type — silently, had it been left.(through
config.torchscript), and the neuron models read them positionally. v5 droppedthat, so the traced models returned dicts.
instead of one linear layer per expert (mixtral, qwen3_moe).
transformers v4 code built on
BeamSearchScorer.generate()rejectsnum_beams > 1explicitly. Exporting with
num_beams > 1still works, but the result can no longergenerate.
NeuronModelForQuestionAnsweringitself is untouched.download_url/is_remote_url,is_safetensors_available,HfFolder,get_preprocessor,find_pruneable_heads_and_indices,EncoderDecoderCache.from_legacy_cache,CLIPFeatureExtractor, the pipelineframeworkattribute, the
GreedySearch*/Sample*output aliases, and configs no longer carryingpad_token_idor resolved generation parameters.vLLM 0.29
WorkerBase.load_modelgained aload_dummy_weightskeyword, the entrypoint modules movedunder
vllm.entrypoints.launchers, and the engine core now asks every worker which KV cachelayouts it supports — answered through vLLM attention backends, of which a neuron worker has
none. The sampler override and the picklable
ModelConfigpatch still match 0.29 exactly.For the record: vLLM 0.29 deprecates Model Runner V1 with removal targeted at 0.32. Our
runner is our own class so nothing breaks now, but it will need revisiting.
Training is out of scope
The training layer is not migrated and not tested. One guard was needed: neuron
configuration deserialization registered its classes by importing both the inference and
the training configurations, so a broken training import made loading any inference
configuration fail.
Before submitting