Skip to content

feat(vllm-0.24): add Qwen3.5 text-only runtime compatibility - #383

Open
CherryLemon wants to merge 7 commits into
v0.3.0-devfrom
feat/v030dev-qwen35-runtime-compat
Open

feat(vllm-0.24): add Qwen3.5 text-only runtime compatibility#383
CherryLemon wants to merge 7 commits into
v0.3.0-devfrom
feat/v030dev-qwen35-runtime-compat

Conversation

@CherryLemon

@CherryLemon CherryLemon commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

PR Category

Core

PR Type

New Features / Bug Fixes

Description

Add Qwen3.5 text-only dense and MoE runtime support to the v0.3.0-dev branch,
which targets vLLM 0.24.0. The upstream vLLM release contains the causal model
classes but does not fully register their canonical text configs and causal
architectures, hybrid cache helpers, or VL-prefixed checkpoint mapping.

The compatibility layer is installed by the general plugin and leaves the
vLLM package and compiled _moe_C extension untouched.

Related Issues

Related upstream implementations:

Changes

  • Register canonical Qwen3.5 text-only dense and MoE configs/models lazily.
  • Reuse vLLM 0.24 upstream hybrid-cache verification for the causal
    architectures; do not rewrite model architectures or RoPE parameters.
  • Add hybrid/Mamba cache metadata and map model.language_model.* checkpoint
    names, including the shared hf_to_vllm_mapper used by FP8 ignored-layer
    matching.
  • Bridge vLLM moe_sum through CachedOp("moe_sum"), keeping backend
    selection, fallback, per-op policy, operator-list recording, and I/O
    diagnostics under OpManager. Empty batches and non-contiguous tensors retain
    safe fallback handling.
  • Preserve existing quantized MoE methods instead of replacing their
    quantization metadata with the unquantized FlagOS implementation.
  • Install the runtime hooks directly, relying on the target branch vLLM 0.24.0
    dependency contract instead of duplicating version checks.
  • Document the mechanism in the general README as runtime compatibility hooks.

Out of scope for this PR:

Testing

  • pytest -q on the targeted registration, moe_sum adapter, OpManager,
    CUDA fallback, and fused-MoE-layer suites: 61 passed in a vLLM 0.24.0 /
    Python 3.12 image.
  • Qwen3.5 model-shim tests and downstream H100 real-weight smoke had already
    covered VL-prefixed dense and FP8 MoE checkpoints: weight loading, health
    checks, and text generation completed; this update does not change the model
    shim or checkpoint mapper.
  • Changed Python files compile with Python 3.12; ruff check,
    ruff format --check, and git diff --check pass.

Checklist

  • I have run the existing tests and they pass
  • I have added tests for my changes (if applicable)
  • I have updated the documentation (if applicable)

if input.stride(-1) != 1 or output.stride(-1) != 1:
return _torch_moe_sum(input, output)
return _flag_gems_moe_sum(input, output)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why not dispatch moe_sum via opmanager?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good point. The previous adapter bypassed the dispatch layer. I changed the bridge to use CachedOp("moe_sum"), so OpManager now owns backend selection, per-op policy, fallback, operator-list recording, and I/O-dump hooks. The monkey patch remains only because upstream vLLM calls vllm._custom_ops.moe_sum directly. The vendor.cuda implementation unwraps the original vLLM function to avoid recursive re-entry during fallback, and the new tests cover both dispatch and recursion prevention.

Comment thread vllm_fl/patches/qwen3_5_text.py Outdated
Comment on lines +33 to +58
class Qwen3_5TextModelArchConfigConvertor(ModelArchConfigConvertorBase):
"""Normalize multimodal architecture names in text-only Qwen configs."""

def get_architectures(self) -> list[str]:
architectures = super().get_architectures()
if not architectures:
default = _DEFAULT_ARCHITECTURES.get(self.hf_config.model_type)
normalized = [default] if default is not None else architectures
else:
normalized = [
_CONDITIONAL_TO_CAUSAL.get(arch, arch) for arch in architectures
]

# The runtime model loader consults hf_config.architectures again after
# ModelArchitectureConfig has been built. Keep both views synchronized
# so it cannot fall back to a stale VL architecture.
if normalized != architectures:
self.hf_config.architectures = normalized.copy()
return normalized


class Qwen3_5ForCausalLMConfig(Qwen3_5ForConditionalGenerationConfig):
"""Use the upstream cache config checks and remove multimodal RoPE keys."""

@staticmethod
def verify_and_update_config(vllm_config) -> None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why need patch model architecture and rope param?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Agreed. Those two patches were compatibility code for older checkpoint configs that used conditional-generation architecture names and retained multimodal RoPE fields. This PR now targets the canonical final text-only config, which declares the causal architecture directly. I removed the architecture convertor and RoPE mutation and reuse the upstream vLLM hybrid-cache verifier directly for the causal architectures.

Comment thread README.md
whitelist/blacklist. This supports arbitrary MoE top-k with FP32 accumulation
and handles empty-token batches without rebuilding or replacing vLLM's
`_moe_C` extension.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

provide a general readme instead model-level readme

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Updated. I replaced the model-specific section with a general Runtime compatibility hooks section describing plugin-owned config/model registration and OpManager-based operator adapters. Model-specific implementation details remain in the code and PR description.

@physics31415926

Copy link
Copy Markdown
Collaborator

is this pr based on vllm-project/vllm#50210 ?

@CherryLemon

Copy link
Copy Markdown
Collaborator Author

is this pr based on vllm-project/vllm#50210 ?

Yes. The Qwen3.5 text-only model support is a plugin-level backport of vllm-project/vllm#50210 for vLLM 0.24.0. The model registration and hybrid GDN state hooks follow that PR. It is not a direct cherry-pick because the compatibility is installed through plugin runtime hooks, with additional plugin-specific checkpoint/FP8 mapping and MoE fixes.

@CherryLemon
CherryLemon requested a review from ceci3 August 17, 2026 07:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants