Skip to content

Commit 5423421

Browse files
justinchubyCopilot
andauthored
docs: refresh docs and skills for refactored public API helpers (#337)
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>
1 parent 3e99081 commit 5423421

5 files changed

Lines changed: 61 additions & 7 deletions

File tree

.agents/skills/moe-models/SKILL.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,13 +200,18 @@ Qwen35MoEDecoderLayer
200200

201201
| Class | File | Purpose |
202202
|-------|------|---------|
203-
| `Qwen35MoEBlock` | `models/qwen.py` | MoE block with routed + shared experts |
204-
| `Qwen35MoEDecoderLayer` | `models/qwen.py` | Hybrid attention + MoE FFN layer |
205-
| `Qwen35MoETextModel` | `models/qwen.py` | Stacks decoder layers with RoPE |
206-
| `Qwen35MoECausalLMModel` | `models/qwen.py` | Top-level causal LM model |
203+
| `Qwen35MoEBlock` | `models/qwen35.py` | MoE block with routed + shared experts (subclasses `Qwen2MoELayer`) |
204+
| `Qwen35MoEDecoderLayer` | `models/qwen35.py` | Hybrid attention + MoE FFN layer |
205+
| `Qwen35MoETextModel` | `models/qwen35.py` | Stacks decoder layers with RoPE |
206+
| `Qwen35MoECausalLMModel` | `models/qwen35.py` | Top-level causal LM model |
207207

208208
### MoE block (`Qwen35MoEBlock`)
209209

210+
`Qwen35MoEBlock` is a thin subclass of `Qwen2MoELayer` (`models/moe.py`) —
211+
the routed + gated-shared-expert composition is op-for-op identical, so it
212+
reuses the parent `forward` rather than duplicating the routing loop. Only
213+
construction (config wiring) differs.
214+
210215
- **TopKGate routing**: 256 experts, top-8 in the full model (configurable
211216
via `num_local_experts` / `num_experts_per_tok`)
212217
- **Expert MLPs**: Standard `MLP` (gate/up/down projections, SiLU activation),

.agents/skills/multimodal-models/SKILL.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ Multimodal HF models often prefix text weights differently. Implement
167167
| `language_model.model.layers.0.…` | `layers.0.…` |
168168
| `vision_tower.vision_model.encoder.…` | `vision_tower.encoder.…` |
169169

170+
Prefer the shared helpers in `mobius._weight_utils` over hand-written loops:
171+
`vlm_decoder_weights` (strip + tie), `vlm_embedding_weights` (filter + strip),
172+
and `vlm_vision_weights` (vision-tower filter + `fc1/fc2``up_proj/down_proj`).
173+
See the `weight-name-alignment` skill for the full helper table.
174+
170175
> Read `references/weight-mappings.md` when you need full weight mapping
171176
> tables, shape mismatch fixes, ClippableLinear weight conventions, or
172177
> per-layer embedding splitting details.

.agents/skills/weight-name-alignment/SKILL.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,50 @@ shared transformer + per-layer Q/K/V/MLP low-rank adapters.
378378

379379
4. **For non-eliminable renames**, keep them in `preprocess_weights`.
380380

381+
## Shared helpers (use instead of hand-writing loops)
382+
383+
`mobius._weight_utils` centralises the renames that *do* have to stay in
384+
`preprocess_weights`. Prefer these over a hand-written
385+
`for name, tensor in state_dict.items(): name = name.replace(...)` loop:
386+
387+
| Helper | Use for |
388+
|--------|---------|
389+
| `rename_weight_keys(state_dict, [(old, new), ...])` | Pure substring key renames. Applies ordered, cascading `str.replace` to every key and **raises on key collision**. Returns a new dict (values shared). |
390+
| `rename_mlp_projections(name, old_up, old_down)` | Per-key MLP rename to canonical `up_proj`/`down_proj` (e.g. `fc_in`/`fc_out`, `c_fc`/`c_proj`). |
391+
| `split_fused_qkv` / `split_interleaved_qkv_weights` / `split_codegen_qkv` | Split fused/interleaved QKV projections. |
392+
| `split_gate_up_proj` | Split a fused `gate_up_proj` into `gate_proj` + `up_proj`. |
393+
| `tie_word_embeddings(state_dict)` | Ensure both `embed_tokens.weight` and `lm_head.weight` exist when `tie_word_embeddings=True`. |
394+
| `strip_prefix(state_dict, prefix)` | Drop a common key prefix. |
395+
| `vlm_decoder_weights` / `vlm_embedding_weights` / `vlm_vision_weights` | VLM sub-model weight extraction (decoder strip+tie, embedding filter+strip, vision-tower filter + `fc1/fc2``up_proj/down_proj`). |
396+
| `_rename_moe_expert_weights` (in `mobius.models.moe`, not `_weight_utils`) | MoE expert weight remapping across architectures. |
397+
398+
Example — a pure-rename `preprocess_weights`:
399+
400+
```python
401+
from mobius._weight_utils import rename_weight_keys
402+
403+
def preprocess_weights(self, state_dict):
404+
return super().preprocess_weights(
405+
rename_weight_keys(
406+
state_dict,
407+
[
408+
(".self_attn.dense.", ".self_attn.o_proj."),
409+
(".mlp.fc1.", ".mlp.up_proj."),
410+
(".mlp.fc2.", ".mlp.down_proj."),
411+
],
412+
)
413+
)
414+
```
415+
416+
For VLM vision sub-models, prefer `vlm_vision_weights`:
417+
418+
```python
419+
from mobius._weight_utils import vlm_vision_weights
420+
421+
def preprocess_weights(self, state_dict):
422+
return vlm_vision_weights(state_dict, ("vision_tower.", "multi_modal_projector."))
423+
```
424+
381425
## Non-consecutive index patterns (setattr fallback)
382426

383427
When HF uses `nn.Sequential` with non-consecutive parameter indices AND the

docs/api/build_from_gguf.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Build an ONNX `ModelPackage` from a GGUF model file.
44

55
```python
6-
from mobius.integrations.gguf import build_from_gguf
6+
from mobius import build_from_gguf
77
```
88

99
> **Note**: Requires the optional `gguf` package:
@@ -37,7 +37,7 @@ def build_from_gguf(
3737
## Examples
3838

3939
```python
40-
from mobius.integrations.gguf import build_from_gguf
40+
from mobius import build_from_gguf
4141

4242
# Basic conversion (dequantizes to float)
4343
pkg = build_from_gguf("llama-3.2-1b-q4_0.gguf")

docs/getting-started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ pkg = build("facebook/wav2vec2-base")
9999
Convert a GGUF model (e.g. from llama.cpp) to ONNX:
100100

101101
```python
102-
from mobius.integrations.gguf import build_from_gguf
102+
from mobius import build_from_gguf
103103

104104
pkg = build_from_gguf("path/to/model.gguf")
105105
pkg.save("output/model/")

0 commit comments

Comments
 (0)