Skip to main content

Reusable mid-level building blocks for MLX — the missing layer between mlx.nn and full model implementations

Project description

mlx-arsenal

PyPI version CI Python License

Low-level operations and reusable building blocks missing from MLX core — the toolbox you want when porting PyTorch models to Apple Silicon.

Tip: if you use Claude Code for MLX ports, the mlx-porting skill teaches Claude to reach for mlx-arsenal submodules (diffusion, spatial, attention, norm, encoding, moe, tiling, etc.) before hand-rolling ops.

Install

pip install mlx-arsenal

Or directly from source:

pip install git+https://github.com/dgrauet/mlx-arsenal.git

Modules

Module Components Replaces (PyTorch)
mlx_arsenal.spatial interpolate_nearest, interpolate_3d, avg_pool1d, replicate_pad, upsample_nearest/bilinear, pixel_shuffle/unshuffle, patchify/unpatchify, PatchEmbed2d/3d F.interpolate, F.avg_pool1d, F.pad(mode="replicate"), F.pixel_shuffle
mlx_arsenal.layout to_channels_last/first, channels_last ctx manager, convert_conv_weights, load_safetensors NCHW ↔ NHWC conversion, weight transposition
mlx_arsenal.conv weight_norm, WeightNorm nn.utils.weight_norm
mlx_arsenal.attention causal_mask, sliding_window_mask, spatial_only_mask, temporal_only_mask, sliding_tile_block_mask, sliding_tile_centered_mask, radial_box_mask, radial_gaussian_mask, classify_heads_from_qk, classify_heads_from_probs, classify, Kind, block_contiguous_permutation, invert_permutation Attention mask creation, head-pattern profiler, SVG2 block-contiguous token permutation
mlx_arsenal.norm PixelNorm, ScaleNorm Custom normalization layers
mlx_arsenal.encoding FourierEmbedder Sinusoidal positional encoding
mlx_arsenal.diffusion get_timestep_embedding, TimestepEmbedding, get_sampling_sigmas, dynamic_shift_schedule, FlowMatchEulerDiscreteScheduler, DDIMScheduler, euler_step, classifier_free_guidance, TeaCacheController, PerLayerAttentionCache, PerHeadAttentionCache, splice_heads, cfg_head_similarity, cfg_skip_mask, CFGSimilarityProfiler, CFGSkipController, WindowResidualController Flow-matching + DDIM diffusion primitives, TeaCache, AST attention caches, ASC cond/uncond skip, WA-RS residual sharing
mlx_arsenal.moe MoEGate, MoELayer Top-k mixture-of-experts dispatch
mlx_arsenal.rasterize rasterize_triangles, interpolate Differentiable triangle rasterization with Metal z-buffer
mlx_arsenal.tiling tiled_process, temporal_slice_process Memory-efficient large tensor processing
mlx_arsenal.streaming BlockStreamer, BlockLoraSource, LoraFuser Low-RAM transformer block streaming from mmap'd safetensors
mlx_arsenal.modulation AdaLNModulation, ScaleShiftTable, modulate, gated_residual DiT AdaLN modulation primitives (1 / 2 / 6 / 9-param variants)
mlx_arsenal.ffn FeedForward, GatedFFN, GeGLU, SwiGLU Transformer FFN / MLP blocks (vanilla + gated variants)
mlx_arsenal.loader SDOps, SafetensorsStateDictLoader, StateDict, read_safetensors_metadata State-dict key remapping chain + safetensors loader
mlx_arsenal.rope rope_frequencies_1d, rope_frequencies_nd, apply_rotary_emb, rotate_half, meshgrid_nd Rotary Position Embeddings (N-D, interleaved + half-rotated variants)

Quick start

from mlx_arsenal.spatial import interpolate_nearest, avg_pool1d, replicate_pad
from mlx_arsenal.layout import to_channels_last, convert_conv_weights
from mlx_arsenal.attention import causal_mask

# Resize a video tensor (B, D, H, W, C)
x_resized = interpolate_nearest(x, size=(8, 32, 32))

# Temporal pooling
pooled = avg_pool1d(temporal_features, kernel_size=2)

# Pad with edge replication (like F.pad mode="replicate")
padded = replicate_pad(x, [(0,0), (2,0), (1,1), (1,1), (0,0)])

# Convert PyTorch conv weights to MLX channels-last layout
mlx_weights = convert_conv_weights(pytorch_weights)

# Causal attention mask for autoregressive decoding
mask = causal_mask(seq_len=128, offset=kv_cache_len)

Block streaming (low-RAM transformers)

Run a 20+ GB transformer on a Mac without holding every block resident at once: keep one shared block module, and rebind its weights from memory-mapped safetensors before each block's forward.

from mlx_arsenal.streaming import BlockStreamer

# Build the model with ONE block in transformer_blocks (not num_layers).
model = build_my_transformer(num_layers=1)
load_non_block_weights(model, weights_path)

streamer = BlockStreamer(
    weights_path,
    block_prefix="transformer.transformer_blocks.",
)
assert streamer.block_count == num_layers  # discovered from safetensors

shared_block = model.transformer_blocks[0]
prev_idx = None
for i in range(streamer.block_count):
    streamer.bind(shared_block, idx=i, evict_previous=prev_idx)
    x = shared_block(x, ...)  # use the rebound block
    prev_idx = i

For LoRA: pass a lora_fuser callable to BlockStreamer and one or more BlockLoraSource instances to bind(..., lora_sources=...). Quantization-aware fusion strategies stay in the caller — arsenal only handles the discovery + indexing.

Requirements

  • Python >= 3.10
  • MLX >= 0.27.0
  • Apple Silicon Mac

Development

pip install -e ".[dev]"
pytest tests/

# Optional: install the pre-commit hook so ruff runs on every `git commit`.
pip install pre-commit
pre-commit install

License

Apache 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mlx_arsenal-0.10.0.tar.gz (92.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mlx_arsenal-0.10.0-py3-none-any.whl (76.7 kB view details)

Uploaded Python 3

File details

Details for the file mlx_arsenal-0.10.0.tar.gz.

File metadata

  • Download URL: mlx_arsenal-0.10.0.tar.gz
  • Upload date:
  • Size: 92.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mlx_arsenal-0.10.0.tar.gz
Algorithm Hash digest
SHA256 95686768b07c27fa6036aaaa6576d681a74f95222460a2c8bd141d494bd98282
MD5 9b1e709e7781f568fbf4977979a5017d
BLAKE2b-256 24cd00e3aaadc99d8fd687c359680a6b34b7e0e1b43679fa960145390c9ac766

See more details on using hashes here.

Provenance

The following attestation bundles were made for mlx_arsenal-0.10.0.tar.gz:

Publisher: release.yml on dgrauet/mlx-arsenal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mlx_arsenal-0.10.0-py3-none-any.whl.

File metadata

  • Download URL: mlx_arsenal-0.10.0-py3-none-any.whl
  • Upload date:
  • Size: 76.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mlx_arsenal-0.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d45a180d451f9f759bb415b097159d7e0e2f5eeafb2a2faa679a91eb036362f1
MD5 a7ac51aa01ad131f298528878a8d5344
BLAKE2b-256 c0b91c4f0f0efb6af56f4a8e0b0c6f2730710c41df07d0101fee731b7f493f17

See more details on using hashes here.

Provenance

The following attestation bundles were made for mlx_arsenal-0.10.0-py3-none-any.whl:

Publisher: release.yml on dgrauet/mlx-arsenal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page