Text-to-Image
MLX
MiniMax H3
Safetensors
English
apple-silicon
macos
image-to-image
image-editing
image-generation
Instructions to use devin-lai/MiniMax-H3-Image-mlx with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use devin-lai/MiniMax-H3-Image-mlx with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] hf download devin-lai/MiniMax-H3-Image-mlx --local-dir MiniMax-H3-Image-mlx
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
File size: 4,391 Bytes
3da88e3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | """Matched image and performance trials. Run from the repository root."""
from __future__ import annotations
import argparse
import gc
import json
import logging
import statistics
from pathlib import Path
from h3_mlx.runtime import Pipeline
PROFILES = {
"native": {},
"fused": {"mlp_chunk": 0, "kernel": "metal-qk", "threads": 256, "vae_batch": 8},
"chunked": {"mlp_chunk": 1024},
"wide-mlp": {"mlp_chunk": 0},
"tuned": {"mlp_chunk": 0, "kernel": "metal", "threads": 256, "vae_batch": 8},
"q8": {"bits": 8, "mlp_chunk": 0, "vae_batch": 8},
"q4": {"bits": 4, "mlp_chunk": 0, "vae_batch": 8},
"q8-g32": {"bits": 8, "group_size": 32, "mlp_chunk": 0, "vae_batch": 8},
"preview": {"mlp_chunk": 0, "kernel": "metal", "threads": 256, "vae_batch": 8},
"stream": {"dit_cache_gb": 0},
}
def main():
p = argparse.ArgumentParser(description=__doc__)
p.add_argument("--model", required=True)
p.add_argument("--text-encoder", required=True)
p.add_argument(
"--profiles",
nargs="+",
choices=PROFILES,
default=["native", "tuned", "q8", "q4", "preview"],
)
p.add_argument("--cases", nargs="+", default=["product", "portrait"])
p.add_argument("--case-file", default="experiments/cases.json")
p.add_argument("--output", default="outputs/suite")
p.add_argument(
"--repeat",
type=int,
default=2,
help="First trial includes model loading; later trials reuse resident models",
)
p.add_argument("--save-trace", action="store_true")
a = p.parse_args()
if a.repeat < 1:
p.error("repeat must be positive")
logging.basicConfig(
level=logging.INFO, format="%(asctime)s %(message)s", datefmt="%H:%M:%S"
)
cases = [c for c in json.loads(Path(a.case_file).read_text()) if c["id"] in a.cases]
if {c["id"] for c in cases} != set(a.cases):
p.error("Requested case not found in case file")
root = Path(a.output)
root.mkdir(parents=True, exist_ok=True)
ledger = root / "trials.jsonl"
for name in a.profiles:
logging.info("PROFILE %s", name)
pipeline = Pipeline(a.model, a.text_encoder, **PROFILES[name])
try:
for c in cases:
for trial in range(a.repeat):
output = root / c["id"] / f"{name}-{trial}.png"
_, row = pipeline.generate(
c["prompt"],
width=c["width"],
height=c["height"],
seed=c["seed"],
output=output,
steps=[0, 2, 4] if name == "preview" else None,
save_trace=a.save_trace,
images=c.get("images", ()),
)
row.update(
profile=name,
case=c["id"],
trial=trial,
sample_type="resident"
if row["dit_was_resident"]
else "load_included",
)
with ledger.open("a") as h:
h.write(json.dumps(row) + "\n")
finally:
pipeline.clear()
del pipeline
gc.collect()
rows = [json.loads(line) for line in ledger.read_text().splitlines()]
summary = []
for profile in a.profiles:
for case in a.cases:
group = [r for r in rows if r["profile"] == profile and r["case"] == case]
resident = [
r["timings"]["total_s"] for r in group if r["sample_type"] == "resident"
]
summary.append(
{
"profile": profile,
"case": case,
"samples": len(group),
"resident_samples": len(resident),
"resident_median_s": statistics.median(resident)
if resident
else None,
"load_included_s": [
r["timings"]["total_s"]
for r in group
if r["sample_type"] == "load_included"
],
}
)
(root / "summary.json").write_text(json.dumps(summary, indent=2) + "\n")
if __name__ == "__main__":
main()
|