Skip to content

LFM3: Liquid's LFM3 models (model_type lfm3) - #57

Merged
rromenskyi merged 2 commits into
mainfrom
lfm3
Oct 31, 2026
Merged

rromenskyi merged 2 commits into
mainfrom
lfm3

Conversation

@rromenskyi

Copy link
Copy Markdown

LiquidAI/LFM3-1.7B-MLX-8bit failed to load with "Model type lfm3 not supported". This adds mlx_lm/models/lfm3.py, written from the Hugging Face reference that ships in the checkpoint (modeling_lfm3.py).

What LFM3 adds over LFM2:

  • Two kinds of attention layers:
    • full attention with partial RoPE. The first pairs follow the whole head's frequency progression; the rest stay unrotated, passed to mx.fast.rope as infinite periods. Checked against the HF formula.
    • sliding-window attention: a RotatingKVCache and its own mask.
  • A sigmoid gate per head on the attention output, before o_proj.
  • Norms: QK norms, plus sandwich norms after the operator and after the FFN.
  • Checkpoint layout: the text model is nested under language_model..
  • Config: Hugging Face defaults for sparse configs. RoPE types other than default are refused rather than computed wrong.

Checked:

  • The 1.7B 8-bit model through generate and the server: a correct answer, reasoning split from the content, a tool call parsed (get_weather {"city": "Paris"}).
  • Tests:
    • partial RoPE leaves the tail unrotated;
    • cached steps match one pass past the sliding window;
    • defaults and the refusal;
    • sanitize;
    • the shared model runner.
  • test_server.py passes.

There's an open upstream PR for the same model (ml-explore#2016); this one was written independently from the reference.

Reviews (codex, muse): the real checkpoint matches the reference numerically. Defaults for sparse configs and the RoPE-type refusal were added in the second commit.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XhEwWJCoJPXFyyCzp988Bx

Roman Romenskyi and others added 2 commits October 30, 2026 23:11
LFM2's gated short convolutions with two kinds of attention layers: full
attention with partial RoPE (the first pairs follow the whole head's
frequency progression, the rest unrotated: infinite periods to
mx.fast.rope) and sliding-window attention (a RotatingKVCache, its own
mask); a sigmoid gate per head on the attention output; QK norms;
sandwich norms after the operator and the FFN. Checkpoints nest the text
model under language_model.

LiquidAI/LFM3-1.7B-MLX-8bit answers through the server with its
reasoning split from the content and tool calls parsed. Tests: partial
RoPE leaves the tail unrotated; cached steps match one pass past the
sliding window; sanitize; the shared model runner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XhEwWJCoJPXFyyCzp988Bx
Review (codex, muse): the real 1.7B checkpoint matches the reference;
configs leaning on defaults didn't. Defaults now as in the HF
configuration (rope parameters, the layer pattern, sizes, conv width),
tie_embedding read as its alias, and a non-default RoPE type or a
missing layer type's entry is refused instead of computed as plain RoPE.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XhEwWJCoJPXFyyCzp988Bx
@rromenskyi
rromenskyi merged commit 394dbcc into main Oct 31, 2026
1 of 2 checks passed
@rromenskyi
rromenskyi deleted the lfm3 branch October 31, 2026 05:14
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