Skip to main content

mflux-lora

One-command LoRA training, sampling, and evaluation for mflux on Apple Silicon.

mflux-lora is a thin, opinionated wrapper around mflux. It prepares a dataset, writes a safe training config, calls mflux-train, extracts the adapter, and gives you a repeatable evaluation grid. It does not reimplement the diffusion models: all inference and training math comes from mflux/MLX.

Unofficial community tool. Not affiliated with the mflux maintainers.

Why

mflux exposes powerful primitives, but a first LoRA run still means hand-writing a training JSON, wiring captions, choosing LoRA targets, and finding the checkpoint afterwards. mflux-lora turns that into:

uvx mflux-lora train ./photos --trigger ohwx --preset balanced
uvx mflux-lora sample --lora lora-run/adapter.safetensors --prompt "ohwx, a portrait photo"
uvx mflux-lora eval --lora lora-run/adapter.safetensors --trigger ohwx

Install

No install needed with uvx:

uvx mflux-lora --help

Or install as a tool:

uv tool install mflux-lora
mflux-lora --help

Requirements:

  • macOS on Apple Silicon
  • Python 3.10+
  • 32 GB unified memory minimum (48 GB recommended)
  • Free disk: ~10 GB for q8 FLUX.2 4B weights, plus checkpoints

The first run downloads model weights from Hugging Face. Set HF_ENDPOINT=https://hf-mirror.com if direct access is slow, or pass --model-path to reuse a local model directory.

Quick start

# 1. Check the machine
uvx mflux-lora doctor

# 2. Train (images + optional .txt captions in ./photos)
uvx mflux-lora train ./photos \
  --trigger ohwx \
  --preset balanced \
  --output ./lora-run

# 3. Sample
uvx mflux-lora sample \
  --lora ./lora-run/adapter.safetensors \
  --prompt "ohwx, a close-up portrait photo, natural light" \
  --size 512x768 \
  --seed 42 \
  --output ./sample.png

# 4. Evaluate angles / seeds / scales
uvx mflux-lora eval \
  --lora ./lora-run/adapter.safetensors \
  --trigger ohwx \
  --output-dir ./eval

eval writes one image per prompt × seed × scale plus eval/contact.jpg.

Use --dry-run on train or demo to inspect the plan and generated config without loading a model.

Dataset

Point train at a folder:

photos/
  01.jpg
  01.txt
  02.png
  02.txt
  • Images: .jpg, .jpeg, .png, .webp
  • Caption: a sibling .txt with the same stem
  • Missing captions are generated from --caption-template and prefixed with --trigger
  • The trigger is prepended to existing captions if it is not already the first word
  • By default images are copied to <output>/dataset; use --in-place to write captions next to the source images

Recommended for identity LoRA:

Item Recommendation
Count 20–60 images (80–150 for very high fidelity)
Angles 25% front, 40% three-quarter, 20% profile, 15% other
Resolution 768–1024 px longest side
Consistency Same person, similar age/makeup; avoid heavy retouching
Captions Describe angle, expression, outfit, light; keep the trigger token first

For angle control, write captions such as:

ohwx, front view portrait, neutral expression, soft studio light, white shirt
ohwx, three-quarter view portrait, looking left, outdoor daylight, black coat
ohwx, side profile view portrait, window light, no accessories

This lets the model bind identity to ohwx instead of memorizing one pose.

Inspect a dataset without training:

uvx mflux-lora dataset validate ./photos
uvx mflux-lora dataset sheet ./photos --output ./sheet.jpg
uvx mflux-lora dataset caption ./photos --trigger ohwx

Supported models

Key Train on Sample on Weights
flux2-klein-base-4b FLUX.2 klein base 4B same bf16, q8, q5, q4
flux2-klein-base-9b FLUX.2 klein base 9B same bf16, q8
z-image-turbo Z-Image Turbo same bf16, q8
z-image Z-Image base same bf16
ernie-image-turbo ERNIE-Image Turbo same bf16, q8
ernie-image ERNIE-Image base same bf16
krea-2-raw Krea 2 Raw Krea 2 Turbo bf16, q8

Default: flux2-klein-base-4b with q8 (≈8.6 GB download). Use --weights bf16 to download the full checkpoint and quantize at load.

uvx mflux-lora models

Presets

Preset Resolution Rank Targets Epochs
fast 512 8 attention 10
balanced 512 8 attention 20
quality 768 16 attention + MLP/FF 20
max 1024 32 attention + MLP/FF 30

Override any of them:

uvx mflux-lora train ./photos --preset balanced --resolution 768 --rank 16 --epochs 30

Models that do not define FF/MLP targets (Z-Image) automatically fall back to attention targets.

Memory guide

Rough peak memory with q8 weights and gradient checkpointing:

Mac memory Suggested
32 GB flux2-klein-base-4b, fast/balanced, 512 px
48 GB 4B at 768 px, 9B at 512 px
64 GB+ 9B at 768 px, Krea 2 Raw at 512 px

Flags for tight machines:

uvx mflux-lora train ./photos \
  --low-ram \
  --cache-limit-gb 12 \
  --resolution 512

--low-ram trades speed for memory. --cache-limit-gb bounds MLX's buffer cache and is usually enough without the full low-RAM overhead.

Commands

train

uvx mflux-lora train IMAGES [options]

Key options: --model, --preset, --trigger, --weights, --output, --resolution, --rank, --epochs, --targets, --lr, --batch-size, --grad-accum, --seed, --model-path, --low-ram, --cache-limit-gb, --save-frequency, --no-preview, --dry-run, --in-place.

The generated config is <output>/train.json. Checkpoints are <output>/train*/checkpoints/*.zip. The best/latest adapter is copied to <output>/adapter.safetensors.

sample

uvx mflux-lora sample \
  --lora ./lora-run/adapter.safetensors \
  --prompt "ohwx, a portrait photo" \
  --scale 1.0 \
  --size 512x768 \
  --seed 42 \
  --output ./out.png
  • --lora accepts either an adapter .safetensors or a mflux checkpoint .zip
  • --no-bake-lora is the default; q8 baking can drop part of the update
  • --compare-base writes a base/LoRA side-by-side image
  • Use --model-path to reuse a local model directory

eval

uvx mflux-lora eval \
  --lora ./lora-run/adapter.safetensors \
  --trigger ohwx \
  --seeds 42,123 \
  --scales 0.8,1.0 \
  --size 512x768 \
  --output-dir ./eval

Without --prompts-file, it generates front / three-quarter / profile / full-body prompts. With --include-base, the contact sheet includes a base-model row for comparison.

Other commands

uvx mflux-lora dataset validate ./photos
uvx mflux-lora dataset sheet ./photos
uvx mflux-lora doctor
uvx mflux-lora models
uvx mflux-lora demo --dry-run

demo uses two bundled images and a 2-epoch run to verify the whole pipeline. It still downloads the model weights on the first real run.

How the config is built

mflux-lora writes a normal mflux training config. You can edit it or pass it directly:

mflux-train --config ./lora-run/train.json

The wrapper chooses:

  • model-specific scheduler steps / guidance / timestep range
  • LoRA targets for the selected model
  • cache_limit_gb, gradient checkpointing, preview cadence
  • a checkpoint every --save-frequency steps

If you already have a config, use mflux directly; this tool is for the common path.

Evaluation and choosing a checkpoint

Do not pick a checkpoint by training loss. Generate the same prompts and seeds for several checkpoints/scales and compare:

uvx mflux-lora eval --lora ./lora-run/train/checkpoints/0000300_checkpoint.zip --trigger ohwx --scales 0.7,1.0 --output-dir ./eval-300
uvx mflux-lora eval --lora ./lora-run/train/checkpoints/0000500_checkpoint.zip --trigger ohwx --scales 0.7,1.0 --output-dir ./eval-500

For quantitative identity checks, run an ArcFace/InsightFace embedding comparison against held-out reference photos. The package intentionally does not bundle a face-recognition model.

If a late checkpoint starts ignoring the prompt (wrong pose, collages), lower the LoRA scale or pick an earlier checkpoint. This is a known overfitting/strength failure mode, not a bug in the wrapper.

Troubleshooting

Pillow import error on Python 3.13

Pillow 13 requires Python 3.14. mflux-lora pins pillow<13; if you install mflux separately, also pin it:

uv tool install mflux --with "pillow<13"

Hugging Face downloads are slow

export HF_ENDPOINT=https://hf-mirror.com

If the mirror is unavailable, direct Hugging Face plus multiple connections is usually faster.

OOM or the machine starts swapping

  • Lower --resolution (512 → 448)
  • Add --low-ram
  • Lower --cache-limit-gb (18 → 12 → 8)
  • Close other MLX/GPU jobs
  • Keep --gradient-checkpointing on (default)

Training is much slower than expected

Check vm.swapusage. If swap is nearly full, another process or session is competing for unified memory. Stop other jobs before restarting training.

LoRA has little effect

  • Include the trigger token in the prompt
  • Use --no-bake-lora (default)
  • Raise --scale from 0.7 to 0.9/1.0
  • Make sure the trigger appears first in captions

Development

git clone <this repo>
cd mflux-lora
uv sync
uv run pytest
uv run mflux-lora --help
uv build
uv publish

License

MIT. mflux is MIT-licensed; the bundled demo images come from mflux's training example assets. Model weights and generated images are subject to their own licenses and, for real people, to likeness and publicity rights.

Metadata

Release files for mflux-lora 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mflux-lora 0.1.0
File Size Uploaded Provenance
mflux_lora-0.1.0.tar.gz 2.1 MB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for mflux-lora 0.1.0
File Interpreter ABI Platform
mflux_lora-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 4.2 MB

Release files / mflux_lora-0.1.0.tar.gz

Download URL mflux_lora-0.1.0.tar.gz
Size 2.1 MB
Tags Source
SHA-256 checksum
How to use checksums
5946f5a56c782d133384ad4767f0b4e97f3c60e23c46c784ce82b1fc66d3e18f
BLAKE2b-256 checksum
How to use checksums
2174d0b606c85d977ed565fdd57dad35a8d1c6c52b2ead3eab869cb639da89f0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / mflux_lora-0.1.0-py3-none-any.whl

Download URL mflux_lora-0.1.0-py3-none-any.whl
Size 2.1 MB
Tags Python 3
SHA-256 checksum
How to use checksums
515835ae9775ec10493798d44e4ca010631e791715dd1b54ff76a30534da647d
BLAKE2b-256 checksum
How to use checksums
6c44a389a720f7b756e6beeb32d98f621c32e009b91c380a1b4a2ee1bea7a576
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for mflux-lora 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page