Skip to content
C.W.K.
Stream
Lesson 04 of 07 · published

Image Generation — Diffusion on the Mac

~14 min · diffusion, image-generation, stable-diffusion

Level 0Curious
0 XP0/51 lessons0/15 achievements
0/100 XP to next level100 XP to go0% complete

Diffusion on the Mac

Image generation in MLX runs through diffusion models — Stable Diffusion variants, FLUX (the current quality leader for many use cases), and the long tail of community-trained models. The package the commands below actually invoke is mflux, which alongside the older mlx-examples/stable_diffusion reference targets Apple Silicon's unified memory directly. Read mflux as a runner, not as a FLUX wrapper: since this lesson was first written it has grown console scripts for a whole shelf of model families beyond FLUX.1, and it will have grown more by the time you read this. So do not memorize the list — learn where it lives. pip show -f mflux lists every mflux-generate-* entry point the installed version provides, and that list is the honest answer for your machine on your day. The same discipline lesson 5 applies to video and music applies here: the loop (pick a model, quantize on load, generate, save) is what lasts; the model names are inventory. There is a second MLX stack worth knowing about and worth not confusing with this one: argmaxinc publishes MLX-format FLUX weights and ships its own runner for them, DiffusionKit. Nothing in this lesson touches that stack — mflux pulls Black Forest Labs' own FLUX weights and quantizes them itself.

The fast path is black-forest-labs/FLUX.1-schnell, a 4-step model mflux fetches on first run. "Schnell" is German for "quick," and it lives up to it; you get full-quality generations in a fraction of the steps required by older Stable Diffusion variants.

The wall-clock you should expect

The honest answer is that chip generation decides it — 'M-Pro' is one word covering four generations from M1 Pro to M4 Pro, so any single number is a lie. Published reference points: an M4 Max (128 GB) reported in the mflux repo generates a 1024×1024 schnell image at 2 steps in about 15 seconds (closer to 40 with model load), and mflux's earlier README table put an M3 Pro around 30 seconds on the 4-bit pipeline. Budget roughly double the 2-step time for 4 steps, and about a minute per image on older or lower-tier chips. On a recent higher-tier chip that's a working iteration loop — you can sketch with a model, no GPU rental needed — and one run of the command below tells you your own machine's number.

The MLX vs CoreML decision for image generation

Speed comparisons between MLX and CoreML come out differently depending on the model, the version, and how much optimization each side got — the record is too mixed to crown either one. So the decision isn't about raw speed; it's about workflow:

  • MLX — Python-first, easy to script and integrate into pipelines, full control over the diffusion sampler, easy A/B between quantization levels. Use this for research or any pipeline where Python is already the integration layer.
  • CoreML — Swift-first, easy to embed in macOS / iOS apps, optimized for on-device deployment. Use this when you're shipping a feature inside an app and need the App Store distribution + privacy guarantees.

Hosted APIs vs local generation

For commercial-grade image generation as a single user, a hosted API (Replicate, fal, OpenAI's image API) is often cheaper per image than running a local Mac that's idle most of the day. Local Mac generation wins when (1) the privacy or air-gap matters, (2) you're generating in volume and the per-image cost adds up, or (3) you want full control over the model and sampler. For one-off use, the hosted API is usually the right call; for a creative tool you use daily, the Mac wins on cumulative cost.

Code

Generate one image with FLUX schnell (MLX)·bash
# Run with mflux via its console script. (`python -m mflux.generate`
# was the old entry point — src/mflux/generate.py was removed 2025-12,
# so the module form no longer exists.)
# black-forest-labs/FLUX.1-schnell is a GATED repo:
# accept its terms on the Hugging Face page while logged in and have a
# token in place (`hf auth login`, or HF_TOKEN) or the first run
# 401s. That first run then pulls the full bf16 weights (~34 GB) into
# ~/.cache/huggingface/hub/; --quantize 4 quantizes them on the fly as
# they load. As written this command fetches no pre-quantized artifact —
# pre-quantized copies do exist on Hugging Face, and `mflux-save` writes
# one locally.
mflux-generate \
  --model schnell \
  --quantize 4 \
  --steps 4 \
  --width 1024 --height 1024 \
  --seed 42 \
  --prompt "A red panda data scientist debugging code at 3am, anime style, soft lighting." \
  --output ./red-panda.png

# Wall-clock varies by chip GENERATION — published reference points:
#   M4 Max (128 GB) : ~15 s generation for 1024x1024 schnell at 2 steps
#                     (~38 s total with model load) — mflux issue #92
#   M3 Pro          : ~30 s at 4-bit — mflux's earlier README table
# Expect roughly 2x the 2-step time at --steps 4, and budget about a
# minute per image on older or lower-tier chips.
Generate the same image programmatically·python
# Verified against mflux 0.18 — the current programmatic API.
# (Older tutorials show `Flux1.from_alias(...)` + `Config(...)`;
# that shape predates 0.18 and no longer imports.)

from mflux.models.common.config.model_config import ModelConfig
from mflux.models.flux.variants.txt2img.flux import Flux1

flux = Flux1(
    quantize=4,
    model_config=ModelConfig.schnell(),
)

image = flux.generate_image(
    seed=42,
    prompt="A red panda data scientist debugging code at 3am, anime style.",
    num_inference_steps=4,
    height=1024,
    width=1024,
)

image.save("red-panda.png", export_json_metadata=True)

External links

Exercise

Generate three images with FLUX schnell at 4 steps using the same seed but three different prompts. Then generate the same prompt three times with three different seeds. Note how seed-stability gives you the same image across runs (useful for reproducible art) and how prompt changes drive composition. Two sentences on whether the wall-clock latency on your machine is fast enough for an iterative creative loop.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.