Skip to content

test: cover the third config-overlay pattern in a VLM architecture (GlmOcr) - #53

Merged
solderzzc merged 1 commit into
mainfrom
test/vlm-glmocr-unit-tests
Aug 16, 2026
Merged

test: cover the third config-overlay pattern in a VLM architecture (GlmOcr)#53
solderzzc merged 1 commit into
mainfrom
test/vlm-glmocr-unit-tests

Conversation

@solderzzc

Copy link
Copy Markdown
Member

Companion PR opening next for Qwen25VL. Follow-up to ml-explore#147-ml-explore#149MLXVLM/Models/GlmOcr.swift (938 lines) was the largest remaining zero-coverage file in the model layer.

What's different about it

A third distinct config pattern: BaseConfiguration (`model_type`, `image_token_id`, `vocab_size`, ...) decodes from the same top-level container as `text_config`/`vision_config`, rather than nesting inside either. `GlmOcrConfiguration.init` decodes `TextConfiguration`/`VisionConfiguration` from their keyed children, then re-runs `BaseConfiguration(from: decoder)` against the same decoder to pick up the flat fields.

A real trap, named rather than worked around

`GlmOcr`'s reported `vocabularySize` reads `config.baseConfiguration.vocabularySize` (a top-level field, defaulting to 59392), while the language model's actual output width is `text_config.vocab_size`. A checkpoint that sets one and not the other produces a model whose declared vocabulary size doesn't match its logits' last dimension. The tiny config sets both to the same value on purpose — this establishes the ordinary path, and the type doc records the mismatch for whoever touches this next.

Verification

```
GlmOcr.swift: 0% → 37.9% line coverage
Full suite: 128 tests, 23 suites, passing (120 before, +8 across this PR and its Qwen25VL sibling)
```

🤖 Generated with Claude Code

…lmOcr)

Follow-up to ml-explore#147-ml-explore#149. MLXVLM/Models/GlmOcr.swift (938 lines) was the largest
remaining zero-coverage file in the model layer.

A third distinct config pattern: BaseConfiguration (model_type, image_token_id,
vocab_size, ...) decodes from the same top-level container as
text_config/vision_config rather than nesting inside either.
GlmOcrConfiguration.init decodes TextConfiguration and VisionConfiguration from
their keyed children, then re-runs BaseConfiguration(from: decoder) against the
same decoder to pick up the flat fields.

That split has a real trap the tests name rather than work around: GlmOcr's
reported vocabularySize reads config.baseConfiguration.vocabularySize (a
top-level field defaulting to 59392), while the language model's actual output
width is text_config.vocab_size. A checkpoint that sets one and not the other
produces a model whose declared vocabulary size does not match its logits'
last dimension. The tiny config sets both to the same value on purpose, which
establishes the ordinary path — the mismatch itself is not asserted, just
documented for whoever touches this next.

Verified with coverage: GlmOcr.swift moves from 0% to 37.9% line coverage.
Full suite: 128 tests, 23 suites, passing (120 before, +8 across this PR and
its Qwen25VL sibling).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@solderzzc
solderzzc merged commit 7b95363 into main Aug 16, 2026
6 checks passed
@solderzzc
solderzzc deleted the test/vlm-glmocr-unit-tests branch August 16, 2026 02:50
solderzzc added a commit to SharpAI/SwiftLM that referenced this pull request Aug 16, 2026
#150)

Points at 512dcde, which carries both:

- SharpAI/mlx-swift-lm#53 — MLXVLM/Models/GlmOcr.swift, whose base config
  overlays the same top-level container as text_config/vision_config
- SharpAI/mlx-swift-lm#54 — MLXVLM/Models/Qwen25VL.swift, whose text config
  does the same, with several fields duplicated across two parallel structs

Both were, alongside Gemma4/Qwen3VL/Qwen35/LFM2VL (#147-#149), among the
largest zero-coverage files in the model layer. Coverage: GlmOcr 0% → 37.9%,
Qwen25VL 0% → 26.7%.

No SwiftLM-side code changes; verified the umbrella builds clean against the
bumped pointer.

Co-authored-by: Claude Opus 5 <noreply@anthropic.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.

1 participant