Skip to content

[Bugfix][RL] Set vLLM config during weight reload - #45989

Merged
Isotr0py merged 1 commit into
vllm-project:mainfrom
aoshen02:fix/set-vllm-config-in-weight-update
Jul 20, 2026
Merged

[Bugfix][RL] Set vLLM config during weight reload#45989
Isotr0py merged 1 commit into
vllm-project:mainfrom
aoshen02:fix/set-vllm-config-in-weight-update

Conversation

@aoshen02

@aoshen02 aoshen02 commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

RL weight updates re-run layer post-processing after model initialization.
Those paths may call get_current_vllm_config(), but the worker reload APIs did
not establish the config context, causing an assertion failure on the FP8 MoE +
DeepEP path.

This PR wraps the stable worker-level reload boundaries with
set_current_vllm_config():

  • regular reload_weights
  • RL start_weight_update, update_weights, and finish_weight_update
  • draft-model weight updates

V1 and the default V2 runner both use these worker entry points. The context is
scoped to each synchronous operation and restored afterward.

Lifecycle investigation

We audited when VllmConfig is first consumed, when it can change, and why the
same config-dependent code is reached again during reload.

Initial model load

  1. VllmConfig.__post_init__ validates the configuration and derives startup
    settings.

  2. GPUWorker.load_model enters set_current_vllm_config(self.vllm_config).
    initialize_model also scopes the model constructor, so modules can read the
    current config without threading it through every constructor.

  3. Initial weight post-processing builds quantized kernels. For the affected
    MoE/EP path, V2 then calls:

    prepare_communication_buffer_for_model(model)
      -> EP communicator.prepare_communication_buffer_for_model
      -> MoE.maybe_init_modular_kernel
      -> maybe_make_prepare_finalize
    

    Some quantization paths create the modular kernel directly from
    process_weights_after_loading; both initial paths are still inside the
    outer GPUWorker.load_model config scope.

  4. Startup may subsequently update the live config: auto-fit writes
    model_config.max_model_len, KV-cache initialization writes
    cache_config.num_gpu_blocks, and compilation/CUDA-graph settings are
    finalized during startup. By engine-ready time, these values are available
    on the same VllmConfig instance.

After initialization

Normal inference mostly consumes the finalized config. The explicit exceptions
we found are:

  • update_config, which can replace model_config or load_config; V2 keeps
    self.vllm_config synchronized. There is no default internal production
    caller—the interface is triggered explicitly by an integration/RPC or tests.
  • Elastic EP / dynamic DP reconfiguration, which updates parallel configuration.
  • Reloading from an explicit weights_path, which updates
    model_config.model to that path.

The RL paths covered by this PR—weights_iterator and the weight-transfer
engines—do not modify VllmConfig.

Why reload still needs the context

Although RL reload does not change the config, it deliberately re-enters code
normally associated with initialization:

Worker.update_weights
  -> weight transfer engine.receive_weights
  -> model.load_weights
  -> layerwise _layerwise_process
  -> quant_method.process_weights_after_loading
  -> rebuild MoE kernel / maybe_make_prepare_finalize
  -> get_current_vllm_config

Regular reload_weights similarly runs initialize_layerwise_reload,
model.load_weights, and finalize_layerwise_reload. Any current or future
quantization/layer post-processing reached from those hooks may legitimately
need the worker's live config.

This is why fixing individual get_current_vllm_config() call sites is fragile:
the repository has many constructor and post-load consumers, and new consumers
can be added later. Establishing the context once at the reload boundaries makes
the already-finalized, live worker config available to the entire operation
without copying fields into every subsystem or keeping a process-global context
active permanently.

Tests

  • .venv/bin/python -m pytest tests/v1/worker/test_gpu_worker_weight_transfer.py -q
    (7 passed)
  • pre-commit run --files vllm/v1/worker/gpu_worker.py tests/v1/worker/test_gpu_worker_weight_transfer.py
    (all hooks passed, including ruff and mypy)

Duplicate-work check

This updates the existing fix in #45989 rather than opening another PR. Searches
for open PRs covering the same config-context failure found no duplicate; the
other weight-reload PRs address different problems.

AI assistance

OpenAI Codex was used to help investigate, implement, and test this change. The
human submitter is responsible for reviewing every changed line and defending
the change end-to-end.

@mergify mergify Bot added the bug Something isn't working label Jun 18, 2026
aoshen02 added a commit to vllm-project/vime that referenced this pull request Jun 18, 2026
…l_utils weight-reload fix (#45989)

v0.23.0 already includes the sleep/scheduler guard from #44483, so the
core.py patch is no longer needed. Replace it with the FP8+DeepEP
weight-reload fix (vllm-project/vllm#45989): snapshot
max_num_batched_tokens from FusedMoEConfig instead of calling
get_current_vllm_config() during layerwise reload.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Ao Shen <aoshen@inferact.ai>
@aoshen02
aoshen02 force-pushed the fix/set-vllm-config-in-weight-update branch from a9c0e56 to c7fe756 Compare June 18, 2026 09:16
aoshen02 added a commit to vllm-project/vime that referenced this pull request Jun 18, 2026
…l_utils weight-reload fix (#45989)

v0.23.0 already includes the sleep/scheduler guard from #44483, so the
core.py patch is no longer needed. Replace it with the FP8+DeepEP
weight-reload fix (vllm-project/vllm#45989): snapshot
max_num_batched_tokens from FusedMoEConfig instead of calling
get_current_vllm_config() during layerwise reload.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Ao Shen <aoshen@inferact.ai>
Signed-off-by: aoshen02 <aoshen@inferact.ai>
aoshen02 added a commit to vllm-project/vime that referenced this pull request Jun 18, 2026
…l_utils weight-reload fix (#45989)

v0.23.0 already includes the sleep/scheduler guard from #44483, so the
core.py patch is no longer needed. Replace it with the FP8+DeepEP
weight-reload fix (vllm-project/vllm#45989): snapshot
max_num_batched_tokens from FusedMoEConfig instead of calling
get_current_vllm_config() during layerwise reload.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Ao Shen <aoshen@inferact.ai>
Signed-off-by: aoshen02 <aoshen@inferact.ai>
CalvinXKY pushed a commit to vllm-project/vime that referenced this pull request Jun 18, 2026
* docker: upgrade base to vLLM 0.23.0, remove CUDA 13 build path

- Base image: v0.22.0-cu129-ubuntu2404 → v0.23.0-cu129-ubuntu2404
- Remove `ENABLE_CUDA_13` ARG and all conditional cu13 blocks:
  - cu13 apt dev headers (libcublas-dev-13-0, cuda-nvrtc-dev-13-0, etc.)
  - TE source build (cu13 wheel didn't exist; cu129 wheel works on arm64)
  - fzyzcjy triton source build (cu13 specific)
  - TMS_CUDA_MAJOR export (no longer needed)
- Simplify cublas-dev to unconditional libcublas-dev-12-9
- Simplify TE install to wheel-only
- justfile: remove `build-cu13` target and cu13 tag scheme
- vllm.patch: adapt line numbers for 0.23.0 (776/1896 vs 750/1844),
  preserve `with self.log_iteration_details(None):` wrapper

cu129 nvcc already supports sm100/sm120 (Blackwell), so cu13 build
path was unnecessary — it caused build failures on gb300 (cu13 apt
packages hijacked /etc/alternatives/cuda, breaking TE CMake).

Tested: built successfully on gb200 (arm64), h200 (x86), gb300 (arm64).
All three confirmed vLLM 0.23.0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: aoshen02 <aoshen@inferact.ai>

* docker/patch: replace core.py sleep fix (already in v023) with all2all_utils weight-reload fix (#45989)

v0.23.0 already includes the sleep/scheduler guard from #44483, so the
core.py patch is no longer needed. Replace it with the FP8+DeepEP
weight-reload fix (vllm-project/vllm#45989): snapshot
max_num_batched_tokens from FusedMoEConfig instead of calling
get_current_vllm_config() during layerwise reload.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Ao Shen <aoshen@inferact.ai>
Signed-off-by: aoshen02 <aoshen@inferact.ai>

---------

Signed-off-by: aoshen02 <aoshen@inferact.ai>
Signed-off-by: Ao Shen <aoshen@inferact.ai>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
aoshen02 referenced this pull request in aoshen02/vllm-detached-backup-20260720 Jun 21, 2026
Add TestWeightReloadCodePaths to test_weight_update.py — exercises the
layerwise weight-reload path (initialize → finalize → process_weights_after_loading)
across model architecture × quantization combinations using vllm.LLM in-process.

Test matrix:
  - moe-bf16-tiny: TitanML/tiny-mixtral (MoE reload baseline)
  - moe-bf16-3b: ibm-research/PowerMoE-3b (real MoE kernel reconstruction)
  - moe-fp8: allenai/OLMoE-1B-7B-0924 with fp8 (#45989 crash path)
  - moe-mxfp8: allenai/OLMoE-1B-7B-0924 with mxfp8 (#44613 crash path, SM100+)

Each case triggers finalize_layerwise_reload which calls
process_weights_after_loading on all layers — the exact code path where
get_current_vllm_config() crashes during MoE kernel reconstruction if
the config context is missing.

Verified on GB200 (SM100): 4/4 passed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@aoshen02

aoshen02 commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator Author
image

@mergify

mergify Bot commented Jul 8, 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, @aoshen02.

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

Assisted-by: OpenAI Codex
Signed-off-by: aoshen02 <aoshen@inferact.ai>
@aoshen02
aoshen02 force-pushed the fix/set-vllm-config-in-weight-update branch from c7fe756 to cf606d5 Compare July 20, 2026 04:28
@aoshen02
aoshen02 requested a review from njhill as a code owner July 20, 2026 04:28
@aoshen02 aoshen02 changed the title [Bugfix][MoE] Snapshot enforce_eager into FusedMoEConfig for weight reload [Bugfix][RL] Set vLLM config during weight reload Jul 20, 2026
@mergify mergify Bot added v1 and removed needs-rebase labels Jul 20, 2026
@aoshen02 aoshen02 added the ready ONLY add when PR is ready to merge/full CI is needed label Jul 20, 2026
@aoshen02

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: cf606d5a2b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Isotr0py
Isotr0py merged commit 9459fc6 into vllm-project:main Jul 20, 2026
96 checks passed
ArjunPakhan pushed a commit to ArjunPakhan/vllm that referenced this pull request Jul 21, 2026
aarushjain29 pushed a commit to ROCm/vllm that referenced this pull request Jul 21, 2026
Signed-off-by: aoshen02 <aoshen@inferact.ai>
Signed-off-by: aarushjain29 <Aarushi.Jain2@amd.com>
edwinlim0919 pushed a commit to chaeminlim-mb/vllm that referenced this pull request Jul 29, 2026
itej89 pushed a commit to itej89/vllm that referenced this pull request Aug 4, 2026
Signed-off-by: aoshen02 <aoshen@inferact.ai>
Signed-off-by: Tej Kiran <kiran.tej@amd.com>
aditi-amd pushed a commit to aditi-amd/vllm that referenced this pull request Aug 4, 2026
Signed-off-by: aoshen02 <aoshen@inferact.ai>
Signed-off-by: root <root@smci355-ccs-aus-m02-09.cs-aus.dcgpu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ready ONLY add when PR is ready to merge/full CI is needed v1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants