Skip to content

Add rename_weight_keys helper and adopt it in pure-rename models - #334

Merged
justinchuby merged 2 commits into
mainfrom
justinchu/weight-rename-helper
Jun 5, 2026
Merged

Add rename_weight_keys helper and adopt it in pure-rename models#334
justinchuby merged 2 commits into
mainfrom
justinchu/weight-rename-helper

Conversation

@justinchuby

Copy link
Copy Markdown
Member

Summary

DRY refactor: centralise the duplicated weight-key rename loop.

Many model preprocess_weights implementations hand-write the same idiom:

new = {}
for name, tensor in state_dict.items():
    name = name.replace(old1, new1)
    name = name.replace(old2, new2)
    new[name] = tensor

Changes

  • Add rename_weight_keys(state_dict, replacements) to _weight_utils.py. Applies an ordered sequence of (old, new) substring replacements to every key (replacements cascade, matching the hand-written loops it replaces), shares tensor values (no clone), and raises ValueError on a key collision (two source keys mapping to the same renamed key) so a silently-dropped weight becomes a hard error instead of a subtle bug.
  • Adopt it in 5 pure-substring-rename models: phi, hunyuan_dit, cogvideox, hunyuan_v1, chatglm. Behaviour-preserving.
  • Add 6 unit tests covering replacement application, ordered/cascading semantics, identity, value-sharing, collision-raises, and empty input.

Out of scope (deliberately left as-is)

Models with interleaved tensor transforms (reshape/split/filter + rename) keep their custom loops — forcing them through the helper would obscure control flow. The vision-tower fc1/fc2 rename triple-duplication (gemma3/llava/mllama) is a separate, filtering-based pattern best handled in the multimodal-task DRY PR.

Verification

  • Fast suite: 2795 passed (baseline 2789 + 6 new tests), 43 skipped.
  • ruff check + ruff format --check clean on all changed files.

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

🏗️ Architecture Diff

Comparing 329d15e3bf0bef

Model Sub-model Changes Status
phi3 model 0
phi3 (static-cache) model 0

No architecture changes detected.


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

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

Performance Comparison

Comparing 329d15e3bf0bef

Model Metric Baseline Current Delta
bert (feature-extraction) model_size_bytes 359 KB 359 KB +0.0%
bert (feature-extraction) num_nodes 60 60 +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 107 107 +0.0%
gpt2 model_size_bytes 388 KB 388 KB +0.0%
gpt2 num_nodes 53 53 +0.0%
llama model_size_bytes 425 KB 425 KB +0.0%
llama num_nodes 61 61 +0.0%
llama (static-cache) model_size_bytes 425 KB 425 KB +0.0%
llama (static-cache) num_nodes 58 58 +0.0%
mamba (ssm-text-generation) model_size_bytes 296 KB 296 KB +0.0%
mamba (ssm-text-generation) num_nodes 98 98 +0.0%
phi3 model_size_bytes 421 KB 421 KB +0.0%
phi3 num_nodes 59 59 +0.0%
phi3 (static-cache) model_size_bytes 421 KB 421 KB +0.0%
phi3 (static-cache) num_nodes 56 56 +0.0%
qwen2 model_size_bytes 425 KB 425 KB +0.0%
qwen2 num_nodes 61 61 +0.0%
qwen2 (static-cache) model_size_bytes 425 KB 425 KB +0.0%
qwen2 (static-cache) num_nodes 58 58 +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 275 275 +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 129 129 +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 413 413 +0.0%
t5 (seq2seq) model_size_bytes 836 KB 836 KB +0.0%
t5 (seq2seq) num_nodes 166 166 +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.

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.

Pull request overview

This PR refactors duplicated preprocess_weights() key-renaming loops by introducing a shared helper (rename_weight_keys) in mobius._weight_utils, then adopting it in several models that only require pure substring renames. It also adds focused unit tests to lock down replacement ordering/cascading semantics, collision detection, and tensor value sharing.

Changes:

  • Added rename_weight_keys(state_dict, replacements) helper (ordered substring replacements; raises on key collisions).
  • Replaced hand-written rename loops in 5 models (phi, hunyuan_dit, cogvideox, hunyuan_v1, chatglm) with the helper.
  • Added unit tests covering behavior (ordering/cascade, identity, collisions, shared tensor values, empty input).

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/mobius/_weight_utils.py Adds rename_weight_keys utility with ordered replacements and collision detection.
src/mobius/_weight_utils_test.py Adds unit tests validating rename semantics, collision behavior, and value sharing.
src/mobius/models/phi.py Switches Phi weight renames to use the shared helper.
src/mobius/models/hunyuan_v1.py Replaces dict-comprehension rename logic with rename_weight_keys.
src/mobius/models/hunyuan_dit.py Refactors DiT rename loop to rename_weight_keys.
src/mobius/models/cogvideox.py Refactors CogVideoX rename loop to rename_weight_keys.
src/mobius/models/chatglm.py Replaces in-place pop/replace logic with rename_weight_keys (pure substring renames).

Comment thread src/mobius/_weight_utils.py
@codecov

codecov Bot commented Jun 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.00000% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/mobius/models/cogvideox.py 50.00% 1 Missing ⚠️
src/mobius/models/hunyuan_dit.py 50.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

justinchuby and others added 2 commits June 5, 2026 15:38
Many model `preprocess_weights` implementations hand-write the same
rename loop:

    new = {}
    for name, tensor in state_dict.items():
        name = name.replace(old1, new1)
        name = name.replace(old2, new2)
        new[name] = tensor

Add `rename_weight_keys(state_dict, replacements)` to `_weight_utils.py`
to centralise this. It applies an ordered sequence of (old, new)
substring replacements to every key (replacements cascade, matching the
hand-written loops), shares tensor values without cloning, and raises
ValueError on a key collision (two source keys mapping to the same
renamed key) so a silently-dropped weight surfaces as a hard error.

Adopt it in the five models whose preprocess_weights is a pure
substring-rename: phi, hunyuan_dit, cogvideox, hunyuan_v1, chatglm. The
transformations are behaviour-preserving; models with interleaved tensor
transforms (reshape/split/filter) are intentionally left as-is.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Justin Chu <11205048+justinchuby@users.noreply.github.com>
Address PR review: when two source keys rename to the same target, the
ValueError now identifies the first producer key (not just "another key"),
which makes the collision actionable when it fires in a large checkpoint.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Justin Chu <11205048+justinchuby@users.noreply.github.com>
@justinchuby
justinchuby force-pushed the justinchu/weight-rename-helper branch from 66d5165 to 3bf0bef Compare June 5, 2026 15:39
justinchuby added a commit that referenced this pull request Jun 5, 2026
Reflect the public-API and DRY changes shipped in PRs #333/#334/#336:

- build_from_gguf is now a top-level export; update the import examples in
  docs/api/build_from_gguf.md and docs/getting-started.md to
  `from mobius import build_from_gguf`.
- weight-name-alignment skill: add a 'Shared helpers' section documenting
  the _weight_utils rename helpers, including the new rename_weight_keys
  and vlm_vision_weights, so future model work reuses them instead of
  hand-written rename loops.
- multimodal-models skill: point at the shared vlm_* weight helpers.
- moe-models skill: note Qwen35MoEBlock subclasses Qwen2MoELayer and fix
  the class file paths (models/qwen.py -> models/qwen35.py).

Depends on #333 (build_from_gguf export), #334 (rename_weight_keys) and
#336 (vlm_vision_weights) landing first.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Justin Chu <11205048+justinchuby@users.noreply.github.com>
@justinchuby
justinchuby merged commit bee5336 into main Jun 5, 2026
21 of 23 checks passed
@justinchuby
justinchuby deleted the justinchu/weight-rename-helper branch June 5, 2026 17:25
justinchuby added a commit that referenced this pull request Jun 5, 2026
Updates outdated docs and agent skills to match the public-API + DRY
refactor shipped across the themed PRs.

## Changes
- **`build_from_gguf` import** — now a top-level export, so
`docs/api/build_from_gguf.md` and `docs/getting-started.md` use `from
mobius import build_from_gguf` instead of the internal
`mobius.integrations.gguf` path.
- **weight-name-alignment skill** — new *Shared helpers* section
documenting the `_weight_utils` rename helpers, including the new
`rename_weight_keys` and `vlm_vision_weights`, so future model work
reuses them instead of hand-written rename loops.
- **multimodal-models skill** — points at the shared `vlm_*` weight
helpers.
- **moe-models skill** — notes `Qwen35MoEBlock` now subclasses
`Qwen2MoELayer`, and fixes stale class file paths (`models/qwen.py` →
`models/qwen35.py`).

## Dependencies
Depends on the API PRs landing first (the helpers/exports documented
here only exist on those branches):
- #333 — `build_from_gguf` top-level export
- #334 — `rename_weight_keys`
- #336 — `vlm_vision_weights`

Docs-only; no code or tests affected.

---------

Signed-off-by: Justin Chu <11205048+justinchuby@users.noreply.github.com>
Co-authored-by: Justin Chu <11205048+justinchuby@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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