Skip to content

Migrate composite model weight adapters - #670

Draft
xiaoyu-work wants to merge 2 commits into
feat/per-component-quantization-loaderfrom
refactor/component-weight-adapters
Draft

Migrate composite model weight adapters#670
xiaoyu-work wants to merge 2 commits into
feat/per-component-quantization-loaderfrom
refactor/component-weight-adapters

Conversation

@xiaoyu-work

Copy link
Copy Markdown
Contributor

Summary

  • add an explicit model-weight adapter boundary while retaining legacy preprocess_weights compatibility
  • make Qwen3.5/QMoE graph construction and expert packing consume the same decoder component plan
  • make Gemma4 decoder, vision, audio, and embedding construction component-aware
  • preserve clipped/scaled quantized subclasses and add explicit HF/local aliases for Gemma4 media modules
  • route Gemma4 packed token tables only to the embedding graph
  • hand T5 and Qwen35 sibling-component sidecars to the generic component codec without double preprocessing
  • fail publication when any MatMulNBits/GatherBlockQuantized parameter remains unbound

Stack

Validation

  • 214 final adapter, model, codec, and component-matrix tests
  • 54 Transformers loader/config resolver tests
  • plan-only Qwen35 QMoE graph/weight alignment regression
  • Gemma4 decoder regex exclusions, vision .linear alias, per-component layouts, sidecar routing, and quantized embedding regressions

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown

Performance Comparison

Comparing e5ce365f998a0b

Model Metric Baseline Current Delta
bert (feature-extraction) model_size_bytes 359 KB 359 KB +0.0%
bert (feature-extraction) num_nodes 68 68 +0.0%
falcon model_size_bytes 364 KB 364 KB +0.0%
falcon num_nodes 66 66 +0.0%
gemma2 model_size_bytes 428 KB 428 KB +0.0%
gemma2 num_nodes 105 105 +0.0%
gpt2 model_size_bytes 324 KB 324 KB +0.0%
gpt2 num_nodes 54 54 +0.0%
llama model_size_bytes 425 KB 425 KB +0.0%
llama num_nodes 60 60 +0.0%
llama (static-cache) model_size_bytes 425 KB 425 KB +0.0%
llama (static-cache) num_nodes 56 56 +0.0%
mamba (ssm-text-generation) model_size_bytes 296 KB 296 KB +0.0%
mamba (ssm-text-generation) num_nodes 94 94 +0.0%
phi3 model_size_bytes 421 KB 421 KB +0.0%
phi3 num_nodes 58 58 +0.0%
phi3 (static-cache) model_size_bytes 421 KB 421 KB +0.0%
phi3 (static-cache) num_nodes 54 54 +0.0%
qwen2 model_size_bytes 425 KB 425 KB +0.0%
qwen2 num_nodes 60 60 +0.0%
qwen2 (static-cache) model_size_bytes 425 KB 425 KB +0.0%
qwen2 (static-cache) num_nodes 56 56 +0.0%
qwen3_5_moe (hybrid-text-generation) model_size_bytes 506 KB 506 KB +0.0%
qwen3_5_moe (hybrid-text-generation) num_nodes 265 265 +0.0%
qwen3_5_text (hybrid-text-generation) model_size_bytes 458 KB 458 KB +0.0%
qwen3_5_text (hybrid-text-generation) num_nodes 127 127 +0.0%
qwen3_5_vl (hybrid-qwen-vl) model_size_bytes 977 KB 977 KB +0.0%
qwen3_5_vl (hybrid-qwen-vl) num_nodes 450 450 +0.0%
t5 (seq2seq) model_size_bytes 836 KB 836 KB +0.0%
t5 (seq2seq) num_nodes 176 176 +0.0%
whisper (speech-to-text) model_size_bytes 1008 KB 1008 KB +0.0%
whisper (speech-to-text) num_nodes 128 128 +0.0%

No performance regressions.

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown

🏗️ Architecture Diff

Comparing e5ce365f998a0b

Model Sub-model Changes Status
bert (feature-extraction) model 0
falcon model 0
gemma2 model 0
gemma4 (gemma4) decoder 0
gemma4 (gemma4) embedding 0
gemma4 (gemma4) vision_encoder 0
gemma4_text model 0
gpt2 model 0
llama model 0
llama (static-cache) model 0
mamba (ssm-text-generation) model 0
phi3 model 0
phi3 (static-cache) model 0
qwen model 0
qwen (static-cache) model 0
qwen2 model 0
qwen2 (static-cache) model 0
qwen2_moe model 0
qwen2_moe (static-cache) model 0
qwen3 model 0
qwen3 (static-cache) model 0
qwen3_5_moe (hybrid-text-generation) model 0
qwen3_5_text (hybrid-text-generation) model 0
qwen3_5_vl (hybrid-qwen-vl) decoder 0
qwen3_5_vl (hybrid-qwen-vl) embedding 0
qwen3_5_vl (hybrid-qwen-vl) vision_encoder 0
qwen3_moe model 0
qwen3_moe (static-cache) model 0
qwen3_next (hybrid-text-generation) model 0
t5 (seq2seq) decoder 0
t5 (seq2seq) encoder 0
whisper (speech-to-text) decoder 0
whisper (speech-to-text) encoder 0

No architecture changes detected.


Legend: ⚪ No change · 🔵 Minor (attrs/inits) · 🟡 Moderate (nodes added/removed) · 🔴 Major (interface changed)

@xiaoyu-work
xiaoyu-work force-pushed the feat/per-component-quantization-loader branch from e409b2d to a8a5c5b Compare August 27, 2026 21:08
@xiaoyu-work
xiaoyu-work force-pushed the refactor/component-weight-adapters branch from ea293cb to 18bdcfd Compare August 27, 2026 21:10
@xiaoyu-work
xiaoyu-work force-pushed the feat/per-component-quantization-loader branch from a8a5c5b to 7562458 Compare August 27, 2026 21:22
@xiaoyu-work
xiaoyu-work force-pushed the refactor/component-weight-adapters branch from 18bdcfd to b4e4bb8 Compare August 27, 2026 21:28
@xiaoyu-work
xiaoyu-work force-pushed the feat/per-component-quantization-loader branch from 7562458 to e5ce365 Compare August 27, 2026 21:30
Add an explicit model-weight adapter boundary and migrate Gemma4, Qwen3.5/QMoE, and T5 to preserve architecture-specific semantics while handing component-routed packed weights to the generic loader. Validate every affine quantized op is fully bound.

Signed-off-by: Xiaoyu Zhang <[email protected]>
Update binding validation and adapter fixtures for ComponentDescriptor.module_attribute_path.

Signed-off-by: Xiaoyu Zhang <[email protected]>
@xiaoyu-work
xiaoyu-work force-pushed the refactor/component-weight-adapters branch from b4e4bb8 to f998a0b Compare August 27, 2026 21:31
@justinchuby
justinchuby requested review from justinchuby and a lite review from Copilot August 29, 2026 15:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

It changes core weight-loading/quantization behavior across multiple model families and build entrypoints, so it warrants final human review despite strong test coverage.

Pull request overview

This PR introduces an explicit model-weight adapter boundary in the checkpoint loading pipeline (while preserving legacy preprocess_weights), updates several model implementations to respect per-component quantization plans, and adds a binding gate that fails builds/publication when affine-quantized ops still have unbound parameters after weight application.

Changes:

  • Add adapt_model_weights() + ModelWeightAdapter/WeightAdapterContext as the new narrow model-specific adapter boundary with legacy fallback.
  • Make Qwen3.5/QMoE, Gemma4, and T5 preprocessing/component-quantization interactions component-plan aware (including routing and aliasing).
  • Add validate_quantized_component_bindings() and invoke it in build paths to ensure MatMulNBits/GatherBlockQuantized parameters are actually bound.
File summaries
File Description
src/mobius/weights/_adapters.py Introduces the explicit model-weight adapter boundary with legacy preprocess_weights fallback.
src/mobius/weights/_adapters_test.py Adds tests covering legacy hook compatibility and explicit adapter precedence.
src/mobius/weights/init.py Exposes adapter API from the mobius.weights public surface.
src/mobius/models/t5.py Adjusts tied-weight handling when component_quantization is active to avoid double preprocessing.
src/mobius/models/qwen35.py Routes decoder quantization decisions through the decoder component plan and avoids double preprocessing in component mode.
src/mobius/models/qwen35_test.py Adds regression test ensuring plan-only quantization keeps QMoE graph/weights aligned.
src/mobius/models/gemma4.py Makes decoder/vision/audio/embedding construction and routing component-quantization aware; adds HF alias metadata.
src/mobius/models/gemma4_test.py Adds component-plan layout, aliasing, routing, and embedding-sidecar routing regressions.
src/mobius/integrations/transformers/_builder.py Switches weight preprocessing to adapt_model_weights() and enforces post-load binding validation.
src/mobius/components/_moe.py Uses decoder component quantization when selecting QMoE quantization compatibility.
src/mobius/_component_quantization.py Extends module→HF-name resolution (incl. .linear alias), allows specialized quantized modules when layouts match, and adds binding validator.
src/mobius/_component_quantization_test.py Adds test ensuring the binding validator rejects unfilled affine-quantized parameters.
src/mobius/main.py Applies adapter boundary in CLI load path and enforces binding validation post-weight-load.
CHANGELOG.md Documents the adapter migration and component-sidecar routing/binding behavior.
Review details
  • Files reviewed: 14/14 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +59 to +61
preprocess = getattr(module, "preprocess_weights", None)
if preprocess is None:
return dict(state_dict)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants