transformers-upgrade
Skill683 starsChanged 19 days agoApache-2.0View on GitHub
Playbook for changing vLLM's Transformers version bounds. Use when bumping the pinned or maximum Transformers version, raising the minimum Transformers version, or deleting vendored configs, processors, or compat shims that upstream Transformers now provides.
2 other projects use a version of this; 2 new projects in the last 4 weeks, against 0 the 4 before.
Adopted by
Surging: 2 new projects took it in the last 4 weeks, none the 4 weeks before.thin data
Most recently taken up by
- guqiong96/Lvllmword for word, first seen Nov 9, 2026
- vllm-project/vllmword for word, first seen Oct 17, 2026
Other versions2 projects use a version of this.
Word for word · 2
- vllm-project/vllm★ 97k100% same
- guqiong96/Lvllm★ 475100% same
Edited · 0
None found.
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository11 other files it gives its agents.
- AGENTS.mdAGENTS.md
- rust/AGENTS.mdAGENTS.md
- tests/AGENTS.mdAGENTS.md
- check-api-compatSkill
- ci-fails-buildkiteSkill
- debug-imaSkill
- kernel-microbenchmarkSkill
- model-microbenchmarkSkill
- model-recipesSkill
- pr-checklistSkill
- triton-kernel-writingSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
15 rules. About 0 are common, 8 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈8
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 16
Every floor raise ends with an unvendoring pass.
- Distinctive: line 23
Read the release notes for config validation changes, renamed auto-mapping formats, and removed attributes.
- Very specific: line 25
Search tests/ for min_transformers_version and skip markers naming the new version, and run those tests on the new pin.
- Very specific: line 29
Run the suites in Testing and fix what breaks.
- Distinctive: line 60
Every hit is deleted by default.
- Distinctive: line 69
Keep a vendored class only when upstream cannot load a checkpoint vLLM must keep serving, and record why in the PR description.
- Distinctive: line 78
Run both dumps; each catches what the other misses:
- Very specific: line 96
Add --trust-remote-code for checkpoints whose config.json has an auto_map, and dump both ways.
- Very specific: line 115
Remove its entries from _CLASS_TO_MODULE and __all__ in vllm/transformers_utils/configs/__init__.py.
- Very specific: line 117
Remove its entries from _CONFIG_REGISTRY in vllm/transformers_utils/config.py.
- Very specific: line 120
Remove the source_file_dependencies lines naming the file from .buildkite/.
- Distinctive: line 126
Before merging, rebase and grep again for the old field names: PRs that land in between still read them.
- Distinctive: line 155
Code: only reachable below the floor is deleted.
- Distinctive: line 167
Delete the patch when its fix is in the floor release.
- Very specific: line 184
Add tests/models/test_initialization.py -k "<archs>" where a GPU is available, and a model eval for any model whose resolved config changed.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Upgrading Transformers
The supported range lives in requirements/common.txt. CI pins one exact
version in requirements/test/*.in and the compiled requirements/test/*.txt.
A version change is one of two jobs, and they usually come as a pair:
- Bump the pin: a new Transformers release becomes the CI version and the upper bound. vLLM grows compat code for it.
- Raise the floor: the minimum moves up. That compat code, and every vendored config or processor upstream now ships, becomes dead weight. Every floor raise ends with an unvendoring pass.
Bump the pin
- Edit the pin line in each
requirements/test/*.inand*.txtand the upper bound inrequirements/common.txt. Past bumps edit only the pin line in the compiled files; seegit log -- requirements/common.txt. - Read the release notes for config validation changes, renamed auto-mapping formats, and removed attributes; these are what break vLLM.
- Search
tests/formin_transformers_versionand skip markers naming the new version, and run those tests on the new pin. Keep the gates: older versions in the supported range still lack the feature, so a gate goes only when the floor reaches it. - Run the suites in Testing and fix what breaks. Mark every
shim with a
# Transformers >= Xcomment so the next floor raise finds it.
Done when the Testing suites and every test gated on this version pass on the new pin.
Raise the floor (unvendoring pass)
1. Inventory
Inventory candidates with the floor version installed (no vLLM install needed):
uv run --no-project --with transformers==<floor> \
python .agents/skills/transformers-upgrade/scripts/find_upstreamed.pyIt lists:
- vendored configs whose
model_typeupstream now owns; _CONFIG_REGISTRYoverrides of upstream types;- registered processors that collide with upstream class names or models;
- version-gated code at or below the floor;
- code that reads the installed Transformers version, whatever its threshold;
- patches citing a Transformers issue or PR (with whether a referenced PR is in the floor release) or a future minimum version.
It finds candidates by name only. Every hit still needs a verdict.
2. Port each candidate to upstream
Every hit is deleted by default. A vendored copy is a liability: it drifts from upstream, hides upstream fixes, and shadows the native class. Port the vLLM model code to the upstream schema instead, renaming attribute reads and deriving values from upstream fields.
Fan candidates out to parallel subagents. Each one compares the vendored and upstream classes, then greps every attribute the vLLM model code reads. Upstreaming hazards lists the usual fixes.
Keep a vendored class only when upstream cannot load a checkpoint vLLM must keep serving, and record why in the PR description. A different upstream schema, a model-code rewrite, or a needed eval is work for the PR, not a reason to keep.
3. Prove it on real checkpoints
For every checkpoint in tests/models/registry.py that uses a ported
config, dump what vLLM builds before and after the change, then diff the two.
Run both dumps; each catches what the other misses:
dump_configs.py: the resolved config, attribute by attribute.dump_model.py: the model built on the meta device with no GPU or weights. It records ModelConfig sizes, every parameter shape, and every module's scalar attributes (head_dim,num_kv_heads,scaling, ...). Missing fields that are read with defaults only show up here.
git worktree add --detach <scratch>/vllm-base upstream/main
S=.agents/skills/transformers-upgrade/scripts
for dump in dump_configs dump_model; do
PYTHONPATH=<scratch>/vllm-base .venv/bin/python $S/$dump.py before.jsonl <repos>
PYTHONPATH=$PWD .venv/bin/python $S/$dump.py after.jsonl <repos>
.venv/bin/python $S/diff_dumps.py before.jsonl after.jsonl
doneAdd --trust-remote-code for checkpoints whose config.json has an
auto_map, and dump both ways.
How to read the diffs:
- A
<MISSING>config field the model reads: this crashes or silently falls back to a default. Port the model code to the upstream field. - New upstream-only defaults (
attention_bias=False,pad_token_id=None): usually benign. A model diff of 0 confirms it. - Any model diff: this is a numerics change, and the PR needs a model
eval. For example, A.X-K1 gained the checkpoint's YaRN rope scaling, which
the vendored class had been dropping; it shows up as
layers.*.self_attn.scaling (x61).
4. Delete
For each deleted config:
- Delete the file.
- Remove its entries from
_CLASS_TO_MODULEand__all__invllm/transformers_utils/configs/__init__.py. - Remove its entries from
_CONFIG_REGISTRYinvllm/transformers_utils/config.py. - Switch every importer, including tests, to
from transformers import .... - Remove the
source_file_dependencieslines naming the file from.buildkite/.
Deleted processors follow the same steps in
vllm/transformers_utils/processors/__init__.py.
Before merging, rebase and grep again for the old field names: PRs that land in between still read them.
Done when every line of the inventory output is deleted, or kept with a reason that meets the bar in step 2. The PR also carries the config diff results and evals for any changed values.
Upstreaming hazards
Upstream configs are @strict dataclasses. Checkpoint keys upstream does not
declare survive as plain attributes, but only when the checkpoint sets them.
Defaults that only vLLM sets, and values vLLM derives, vanish.
| Hazard | Signal | Fix |
| Upstream consumes legacy keys | __post_init__ pops keys the model reads (deepseek_v4 compress_ratios) | Read the upstream replacement (layer_types, mlp_layer_types, per-layer rope_parameters) |
| Renamed or dropped fields | Diff shows <MISSING> for a field the model reads | Read the upstream name; derive dropped flags from what implies them (enable_moe_block from num_experts) |
| Undeclared field without a default | config.x raises AttributeError for configs that omit x, e.g. minimal test configs (A.X-K1 scoring_func). Dumps of real checkpoints miss it | Upstream ignoring x usually means vLLM can stop reading it; if vLLM truly needs it, read getattr(config, "x", <old default>) |
| Top-level config stops forwarding | The vendored top-level config forwarded reads to text_config; upstream does not. getattr(config, "x", default) silently takes the default, e.g. on MTP draft configs from SpeculativeConfig.hf_config_override, which the dumps do not build | Read from get_text_config(); grep getattr reads of every field, including speculative-decoding paths |
| Type check on the config | ctx.get_hf_config(SomeConfig) relies on the vendored base class | Accept the upstream class too, e.g. a Cosmos3ProcessingInfo overriding get_hf_config |
| Remote code takes over | Checkpoint config.json has auto_map; with --trust-remote-code, the hub class replaces the native one once vLLM stops registering its own | Check the remote class loads; if not, register the upstream class for that model_type |
| Read-only upstream fields | Properties or derived fields break subclasses and hf_overrides (nemotron_h hybrid_override_pattern) | Override the source field (layers_block_type) instead |
| Behavioural rewrite | Upstream derives fields differently (diffusion_gemma sliding_window) | Upstream matches the reference implementation; verify with an eval |
| Original checkpoint format | Upstream targets -hf conversions; vLLM serves the originals (qwen3_asr, qianfan_ocr) | Keep only if upstream cannot load the original at all |
| Processor output contract | Model code consumes keys upstream does not emit | Port the model to upstream's keys |
| Name collision | A registered vendored processor shares an upstream class name and hijacks get_processor (InternVLProcessor) | Drop the registry entry |
Version gates from the inventory need a decision:
Code only reachable below the floor is deleted. This covers:
- comparisons against
TRANSFORMERS_VERSION; - branches labelled
# Transformers < X; - fallbacks for fields that upstream configs now always set, e.g.
mlp_layer_types,per_layer_configor legacylayer_typesnames.
A
skipifwhose condition is now always true becomes an unconditionalskipwith the same reason.- comparisons against
min_transformers_versionat or below the floor is removed.max_transformers_versionbelow the floor means CI never tests that model; report it rather than deleting it silently.- Patches citing a Transformers issue or PR:
- Delete the patch when its fix is in the floor release.
- For an issue, find the PR that closed it and check that PR. A closed issue is not a fixed one: issues get closed while the bug is still in the release.
- Re-run the patched behaviour before deleting. A fix in the release does not always cover vLLM's path: Emu3's processor gained BOS upstream, but vLLM tokenizes without the processor.
- Links that only explain a design choice (e.g. a float32 RoPE note) are not patches; leave them.
Testing
.venv/bin/python -m pytest tests/transformers_utils tests/config tests/tokenizers_
.venv/bin/python -m pytest tests/models/multimodal/processing/test_common.py -k "<models>"Add tests/models/test_initialization.py -k "<archs>" where a GPU is
available, and a model eval for any model whose resolved config changed.
Models in vllm/models/ are high priority: whenever their config or model
code changes, run GSM8k (tests/evals/gsm8k/) and GPQA Diamond
(tests/evals/gpt_oss/) on main and the branch, even when the dumps show
no diff, and put both scores in the PR. FlashInfer autotuning picks kernel
tactics afresh on every server start, which moved DeepSeek-V4-Flash GSM8k by
about 1 point; pass --kernel-config '{"enable_flashinfer_autotune": false}'
to both servers so greedy outputs are comparable.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

