一键导入
mflux-debugging
Debug MLX ports by comparing against a PyTorch/diffusers reference via exported tensors/images (export-then-compare).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Debug MLX ports by comparing against a PyTorch/diffusers reference via exported tensors/images (export-then-compare).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Port ML models into mflux/MLX with correctness-first validation, then refactor toward mflux style.
Manually validate mflux CLIs by exercising the changed paths and reviewing output images/artifacts.
Make a clean PR in mflux (inspect diff, quick verification, commit, push, open PR) using repo conventions.
Run tests in mflux (fast/slow/full), preserve image outputs, and handle golden image diffs safely.
Navigate MFLUX CLI capabilities, locate commands by area, and summarize supported features.
Set up and work in the mflux dev environment (arm64 expectation, uv, Makefile targets, lint/format/test).
| name | mflux-debugging |
| description | Debug MLX ports by comparing against a PyTorch/diffusers reference via exported tensors/images (export-then-compare). |
Use this skill when you are porting a model to MLX and need to prove numerical parity (or isolate where it diverges) versus a PyTorch reference implementation (often from diffusers).
This skill defaults to export-then-compare:
mflux-model-porting).uv to run Python: uv run python -m ...MFLUX_PRESERVE_TEST_OUTPUT=1 (see mflux-testing and the Makefile test targets).mflux-model-porting.seed is not enough for parity—export the exact initial noise/latents from the reference and load them in MLX.diffusers/) and mflux/ are frequently next to each other on disk (e.g. both on your Desktop). Use absolute paths when in doubt.For day-to-day debugging, prefer a minimal paired repro:
diffusers/), e.g. diffusers/flux2_klein_edit_debug.pymflux/, e.g. mflux/flux2_klein_edit_debug.pyKeep them “boring”: hardcoded variables, no cli, no framework, and just a few np.savez(...) / mx.save(...) lines at the right spot.
The key trick for RNG parity:
latents=...) so the run definitely uses the dumped tensor.Start coarse, then narrow:
Tip: work “backwards from pixels” like mflux-model-porting suggests: validate VAE decode first with exported latents, then the diffusion/transformer loop, then text encoder.
Create a run directory like:
./debug_artifacts/<run_id>/ref/Export with one of these patterns:
np.savez(path, **tensors_as_numpy)torch.save(dict_of_tensors, path)Create a matching run directory:
./debug_artifacts/<run_id>/mlx/Load and compare tensors. For each checkpoint, report:
Suggested tolerance starting points (adjust per component):
atol=1e-5, rtol=1e-5atol=1e-2, rtol=1e-2png visually, since tiny numeric diffs can look identical.If a checkpoint fails:
float16 can produce NaNs; prefer bfloat16 for reference dumps if you see NaNs.debug_artifacts/<run_id>/... at repo root.debug_artifacts/ unless explicitly asked.mflux-testing).When full end-to-end images differ between mflux and diffusers but you need to trust the core model (transformer, text encoder, VAE decode), export the reference initial noise and run mflux denoising from that tensor. If injected-latent mflux looks good while native-seed runs differ, the forward path is likely sound and any gap is probably RNG, scheduler, or optional reference-only components.
Do not commit these scripts or Desktop .npy files unless asked. Use inline uv run python <<'PY' ... PY heredocs in the reference repo and in mflux/.
Run from the local diffusers/ clone (often next to mflux/ on Desktop). Match mflux settings: height, width, seed, dtype (bfloat16 on MPS).
Load the reference pipeline the same way you would for a normal generation, but disable optional subsystems that mflux does not implement or download (check model_index.json vs mflux get_download_patterns() / weight definition). Pass None for unused components, set pipeline flags to skip them, and use local_files_only=True so missing weights surface immediately instead of downloading extras.
Then export noise with the same shape helper the pipeline uses internally:
from diffusers.utils.torch_utils import randn_tensor
pipe = <ReferencePipeline>.from_pretrained(
"<org/model>",
torch_dtype=torch.bfloat16,
local_files_only=True,
# plus any kwargs to omit optional reference-only modules
)
latent_h = height // pipe.vae_scale_factor # or read from pipeline/config
latent_w = width // pipe.vae_scale_factor
ch = pipe.transformer.config.in_channels # name varies by architecture
generator = torch.Generator(device="mps").manual_seed(seed)
latents = randn_tensor(
(1, ch, latent_h, latent_w),
generator=generator,
device="mps",
dtype=torch.bfloat16,
)
np.save("/path/to/init_latent.npy", latents.detach().cpu().float().numpy())
If generate_image() has no latents= argument, inline the denoising loop from the variant class instead of patching production code:
latents = mx.array(np.load(path)).astype(mx.bfloat16)_encode_prompts, prompt cache, etc.)config.scheduler.step(...) over config.time_stepsImageUtil.to_image(...) (or the variant’s decode helper) → save PNGAlso run one generate_image(seed=...) baseline on the same prompt for side-by-side.
| Comparison | What it tells you |
|---|---|
| mflux native seed vs itself (re-run) | Sampling is deterministic on this hardware |
| mflux + diffusers latent vs diffusers full run | Transformer + VAE + CFG path quality |
| mflux native seed vs diffusers full run | Not a parity test — different RNG (mx.random vs torch.Generator) and often different sigma schedules |
| mflux + diffusers latent vs mflux native seed | Large diff is expected if schedulers/sigmas differ, even with identical starting noise |
If injected-latent mflux looks good, the port’s core forward path is trustworthy. Golden CI tests should still lock mflux-native sampling (see mflux-testing), not diffusers pixel parity.
diffusers/ clone with cd .../diffusers && uv run python.HF_HUB_OFFLINE=1 when weights are cached to catch missing components the reference pipeline expects but mflux omits from its download patterns.-q 8 vs diffusers bf16 is not apples-to-apples for speed or pixels)./usr/bin/time -p.mflux-model-porting: correctness-first workflow (validate components and lock behavior before refactor).mflux-testing: how to run tests safely and handle image outputs/goldens.