Skip to content

[Bugfix] Support strided weights in sharded state saving - #61432

Open
mgehre-amd wants to merge 2 commits into
vllm-project:mainfrom
ROCm:matthias.sharded-state-strided-save
Open

mgehre-amd wants to merge 2 commits into
vllm-project:mainfrom
ROCm:matthias.sharded-state-strided-save

Conversation

@mgehre-amd

@mgehre-amd mgehre-amd commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Purpose

save_sharded_state serializes each worker's in-memory state_dict(), i.e. the
weights after process_weights_after_loading. Some post-processing leaves a
weight as a non-contiguous view with a widened row stride. On ROCm,
VLLM_ROCM_FP8_PADDING (on by default) does exactly that with F.pad(w, (0, n))[..., :-n].

Saving such a model fails twice over:

  1. ShardedStateLoader._filter_subtensors computes a tensor's end address with
    tensor.view(-1)[-1], which raises on a strided view:
    RuntimeError: view size is not compatible with input tensor's size and stride.
  2. Even past that, safetensors.save_file refuses non-contiguous tensors:
    ValueError: You are trying to save a non contiguous tensor.

Test plan

1. FP8 model Qwen/Qwen3-0.6B-FP8

python examples/features/sharded_state/save_sharded_state_offline.py \
    --model Qwen3-0.6B-FP8 --output /tmp/q3-fp8-sharded
  • fails on main, passes here

Loading that FP8 checkpoint back is a separate, pre-existing problem: it fails
with Missing keys (...attn.q_scale, ...k_scale, ...v_scale, ...prob_scale)
on main too, even with VLLM_ROCM_FP8_PADDING=0, because those attention
scales are deleted in process_weights_after_loading and so never saved. It
is out of scope here.

**2. w4a16 model ** Qwen/Qwen3-0.6B:

python examples/features/sharded_state/save_sharded_state_offline.py \
    --model Qwen3-0.6B --output /tmp/q3-sharded
python examples/features/sharded_state/load_sharded_state_offline.py \
    --model /tmp/q3-sharded --load-format sharded_state \
    --prompt "The capital of France is" --max-tokens 32 --temperature 0
  • fails on main, passes here

Not a duplicate

No duplicate PRs found.

AI assistance

AI assistance was used for this PR. I reviewed every changed line, and ran the
tests and the end-to-end round trip listed above.

save_sharded_state serializes the in-memory state dict, i.e. weights after
process_weights_after_loading. On ROCm, VLLM_ROCM_FP8_PADDING and
VLLM_ROCM_MOE_PADDING (both on by default) offset weight row strides there via
F.pad(...)[..., :-n], leaving non-contiguous views. _filter_subtensors flattened
every tensor with view(-1), which raises on such views, and safetensors refuses
to save non-contiguous tensors, so saving failed for any padded model.

Compute a tensor's end address from its strides, and save a contiguous copy.
The saved checkpoint holds the plain weights; loading copies them into freshly
allocated dense parameters before process_weights_after_loading, which
re-applies the padding, so the load side needs no change.

Signed-off-by: Matthias Gehre <matthias.gehre@amd.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 bug Something isn't working label Oct 13, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant