Skip to content

Add vlm_vision_weights helper and adopt it in VLM vision sub-models - #336

Merged
justinchuby merged 1 commit into
mainfrom
justinchu/vlm-vision-weights-helper
Jun 5, 2026
Merged

Add vlm_vision_weights helper and adopt it in VLM vision sub-models#336
justinchuby merged 1 commit into
mainfrom
justinchu/vlm-vision-weights-helper

Conversation

@justinchuby

Copy link
Copy Markdown
Member

Summary

DRY refactor: dedupe the VLM vision-tower preprocess_weights boilerplate.

The vision sub-models of LLaVA, Gemma3, and Mllama hand-wrote the identical loop: filter to the vision-tower prefixes, then rename the HuggingFace vision MLP projections mlp.fc1mlp.up_proj and mlp.fc2mlp.down_proj to match our FCMLP component naming.

Changes

  • Add vlm_vision_weights(state_dict, prefixes) to _weight_utils.py, alongside the existing vlm_decoder_weights / vlm_embedding_weights helpers.
  • Adopt it in gemma3, llava, mllama. The only per-model difference is the prefix tuple: gemma3/llava use ("vision_tower.", "multi_modal_projector."), mllama uses ("vision_model.",).
  • Add 3 unit tests (filter+rename, single prefix, no-match).

Behaviour-preserving: same filtering and same renames, just centralised.

Verification

  • Fast suite: 2792 passed (baseline 2789 + 3 new tests), 43 skipped.
  • ruff check + ruff format --check clean.

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

🏗️ Architecture Diff

Comparing 329d15ee1781d5

Model Sub-model Changes Status

No architecture changes detected.


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

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 common VLM vision-tower weight preprocessing into a shared helper to remove duplicated boilerplate across vision sub-models, while preserving existing behavior and adding focused unit coverage.

Changes:

  • Added vlm_vision_weights(state_dict, prefixes) to src/mobius/_weight_utils.py to (a) filter by vision-related prefixes and (b) rename mlp.fc1/fc2mlp.up_proj/down_proj to match FCMLP initializer naming.
  • Updated LLaVA, Gemma3, and Mllama vision sub-models to delegate their preprocess_weights() implementations to the new helper with the appropriate prefix tuple.
  • Added unit tests covering filter+rename behavior, single-prefix usage, and the no-match case.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/mobius/models/mllama.py Replaces local vision weight filtering/rename loop with vlm_vision_weights(..., ("vision_model.",)).
src/mobius/models/llava.py Replaces local vision weight filtering/rename loop with vlm_vision_weights(..., ("vision_tower.", "multi_modal_projector.")).
src/mobius/models/gemma3.py Replaces local vision weight filtering/rename loop with vlm_vision_weights(..., ("vision_tower.", "multi_modal_projector.")).
src/mobius/_weight_utils.py Introduces the shared vlm_vision_weights helper (filter + fc1/fc2 rename).
src/mobius/_weight_utils_test.py Adds unit tests for vlm_vision_weights covering key behaviors and edge cases.

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

Performance Comparison

Comparing 329d15ee1781d5

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.

@codecov

codecov Bot commented Jun 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.65517% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/mobius/models/gemma3.py 50.00% 1 Missing ⚠️
src/mobius/models/llava.py 50.00% 1 Missing ⚠️
src/mobius/models/mllama.py 50.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

The vision sub-models of LLaVA, Gemma3 and Mllama hand-wrote the same
preprocess_weights body: filter to the vision-tower prefixes and rename
the HF vision MLP projections (mlp.fc1 → mlp.up_proj, mlp.fc2 →
mlp.down_proj) to match our FCMLP component naming.

Add `vlm_vision_weights(state_dict, prefixes)` to `_weight_utils.py`
next to the existing `vlm_decoder_weights` / `vlm_embedding_weights`
helpers, and adopt it in those three models. The only per-model
difference is the prefix tuple (gemma3/llava use
("vision_tower.", "multi_modal_projector."); mllama uses
("vision_model.",)). Behaviour-preserving.

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/vlm-vision-weights-helper branch from 5df878f to e1781d5 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 3e99081 into main Jun 5, 2026
20 of 23 checks passed
@justinchuby
justinchuby deleted the justinchu/vlm-vision-weights-helper branch June 5, 2026 17:33
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