test: cover the second hybrid-attention VLM architecture (LFM2VL) - #52
Merged
Conversation
Follow-up to #49/#50. MLXVLM/Models/LFM2VL.swift was, alongside Qwen35.swift, one of the largest remaining zero-coverage files in the model layer. Its hybrid mechanism differs from Qwen35's fixed-period one: layers are attention only at explicit indices, full_attn_idxs (or derived from layer_types), and a short causal convolution (LFM2ShortConv) everywhere else — a sparser, more arbitrary pattern than a modulus. Setting full_attn_idxs: [1] over 2 layers makes layer 0 the conv block and layer 1 the attention block, so both branches of LFM2DecoderLayer build and run. newCache reads fullAttnIdxs independently of how the layers were built to decide MambaCache versus KVCacheSimple per layer, so the forward-pass test uses it directly (model.newCache(parameters: nil)) rather than assuming construction and cache selection stay in agreement — that agreement is exactly what this exercises. The vision half carries the same silent constraint as Qwen3VL's tower (#50): num_patches must be a perfect square, since a grid side is derived via sqrt. Verified with coverage: MLXVLM/Models/LFM2VL.swift moves from 0% to 34.9% line coverage. Full suite: 120 tests, 21 suites, passing (112 before, +8 across this PR and its sibling for Qwen35). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
solderzzc
added a commit
to SharpAI/SwiftLM
that referenced
this pull request
Aug 15, 2026
…149) Points at c09851f, which carries both: - SharpAI/mlx-swift-lm#51 — the hybrid full-attention/GatedDeltaNet split in MLXVLM/Models/Qwen35.swift, gated by a fixed period (full_attention_interval) - SharpAI/mlx-swift-lm#52 — the hybrid attention/short-conv split in MLXVLM/Models/LFM2VL.swift, gated by explicit layer indices (full_attn_idxs) Both were, alongside Gemma4 (#147) and Qwen3VL (#148), among the largest zero-coverage files in the model layer. Coverage: Qwen35 0% → 66.4%, LFM2VL 0% → 34.9%. No SwiftLM-side code changes; verified the umbrella builds clean against the bumped pointer. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Companion to #51. Follow-up to #49/#50 —
MLXVLM/Models/LFM2VL.swiftwas the other largest remaining zero-coverage file in the model layer.What's different about it
Its hybrid mechanism differs from Qwen35's fixed-period one: layers are attention only at explicit indices,
full_attn_idxs(or derived fromlayer_types), and a short causal convolution (LFM2ShortConv) everywhere else — a sparser, more arbitrary pattern than a modulus. Settingfull_attn_idxs: [1]over 2 layers makes layer 0 the conv block and layer 1 the attention block, so both branches ofLFM2DecoderLayerbuild and run.newCachereadsfullAttnIdxsindependently of how the layers were built to decideMambaCachevsKVCacheSimpleper layer, so the forward-pass test calls it directly (model.newCache(parameters: nil)) rather than assuming construction and cache selection stay in agreement — that agreement is exactly what this exercises.The vision half carries the same silent constraint as Qwen3VL's tower (#50):
num_patchesmust be a perfect square, since a grid side is derived viasqrt.Verification
🤖 Generated with Claude Code