Add memory-efficient chunked conversion for large models - #878
Closed
iamadalek wants to merge 1 commit into
Closed
Conversation
Adds --chunked flag to mlx_lm.convert that processes weights one layer at a time, enabling conversion of models larger than available RAM. The chunked path reads safetensors headers for planning, builds a quantization plan from a lightweight (no-weights) model instance, then streams through layer chunks: load → sanitize → cast → quantize → save, clearing memory between chunks. Restores cache settings via try/finally so library callers are unaffected. Produces output identical to the standard conversion path (verified by bit-for-bit comparison tests on synthetic models). Benchmark (8-layer llama, hidden=1024, vocab=32000, 642 MB model): Standard: 742 MB peak memory Chunked: 164 MB peak memory (4.5x reduction) The ratio scales with layer count — a 32-layer model sees ~16x reduction. Scope: standard quantization (affine, mxfp4, nvfp4, mxfp8), mixed recipes, and dtype-only conversion. Not compatible with AWQ/GPTQ/DWQ, --dequantize, VL models, or custom model_file. Closes ml-explore#876 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
iamadalek
force-pushed
the
feature/chunked-convert
branch
from
February 12, 2026 01:44
5154692 to
a080366
Compare
This was referenced Feb 12, 2026
Member
|
This is not necessary.. it's already possible to convert a model larger than the RAM of the machine as the conversion is streamed in chunks already. |
Author
Thanks for the quick review, Awni. I appreciate the clarification — I should have dug deeper into how MLX’s lazy evaluation handles the memory pressure during conversion before assuming the bottleneck was where I thought it was. Good to know the existing path already streams effectively. |
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.
Summary
--chunkedflag tomlx_lm.convertthat processes weights one transformer layer at a time, enabling conversion of models larger than available RAMmlx_lm/chunked_convert.pymodule with streaming pipeline: safetensors header scanning, layer-based chunk planning, quantization plan building, per-chunk load/sanitize/cast/quantize/save with aggressive memory reclamation between chunksBenchmark
Synthetic 8-layer Llama model (hidden=1024, vocab=32000, 642 MB total):
The ratio scales with layer count. An 8-layer model processes ~1 layer at a time (plus embeddings/lm_head). A 32-layer model would see ~16x reduction. For the target use case (DeepSeek V3 at 671B), peak memory drops from ~370GB (full model) to ~29GB (one MoE layer).
Test plan
Closes #876
🤖 Generated with Claude Code