# Hunyuan3D-2.2-mrp-MLX

**One-command image → textured 3D on Apple Silicon.** A tuned, packaged build of Tencent's Hunyuan3D 2.1, running natively on Mac GPUs via Apple MLX — no NVIDIA, no CUDA, no cloud.

```bash
python generate_e2e.py your_image.png --output out/mymesh
# → out/mymesh.glb   (PBR-textured mesh)  +  out/mymesh_shape.glb (untextured)
```

---

## What this is (provenance & credit)

A **fork of a fork** — three layers, credited honestly:

1. **Tencent Hunyuan3D 2.1** — the actual models: `Hunyuan3D-Shape-v2-1` (3.3B, image→mesh) + `Hunyuan3D-Paint-v2-1` (2B, PBR texture). Originally **CUDA/NVIDIA only**.
2. **[dgrauet/Hunyuan3D-2.1-mlx](https://github.com/dgrauet/Hunyuan3D-2.1-mlx)** — the hard part: a native **MLX (Metal)** port of *both* stages. fp16, no bf16 dependency → runs on **any** Apple Silicon Mac (M1–M5). This is what made it work on a Mac at all.
3. **This build (MODELBEAST / `mrp`)** — the usability + tuning layer on top of dgrauet (below).

## What *we* added over upstream

- **`generate_e2e.py`** — a single command chaining Stage 1 (shape) → Stage 2 (PBR texture). Upstream only shipped a test script. Flags: `--steps --guidance --octree-resolution --max-num-view --view-resolution --texture-size --remesh-faces --seed --no-texture`; prints per-stage timings + peak memory.
- **Env-tunable bake mesh** — `HY3D_REMESH_FACES` (upstream hard-coded 40k). The **single biggest quality lever** — it's what un-melts faces.
- **Studio-quality defaults** — `octree 384 / texture 4096 / remesh 120k`, **verified watchdog-free on M3 *and* M1 Ultra**. Upstream capped texture at 2048 because laptop GPUs hit a Metal command-buffer limit; Studio-class GPUs don't, and the existing tiling handles 4096².
- **[HARDWARE.md](HARDWARE.md)** — exact RAM needs per precision and per Mac.
- **Slimmed for inference** — upstream training data (`mini_trainset`) + demo images stripped (~165 MB → ~9 MB). Recover any time via `git fetch upstream` (github.com/dgrauet).

## Quick start

Python **3.11** (the ML stack pins old numpy; 3.12+ won't build it).

```bash
uv venv --python 3.11 .venv && source .venv/bin/activate      # or: python3.11 -m venv .venv
uv pip install mlx mlx-arsenal torch torchvision transformers timm \
  huggingface_hub safetensors numpy scipy scikit-image PyMCubes \
  trimesh pygltflib xatlas opencv-python pillow pymeshlab \
  einops omegaconf pyyaml tqdm torchdiffeq diffusers accelerate fast_simplification

export HF_HUB_DISABLE_XET=1
python generate_e2e.py your_image.png --output out/mymesh
```

Weights (~13 GB, fp16 MLX, **public — no HF login**) auto-download on first run from `dgrauet/hunyuan3d-2.1-mlx`. Override with `HUNYUAN3D_MLX_WEIGHTS_DIR`. Best results: feed a **background-removed cutout**.

## Quality vs speed (generate_e2e.py flags)

| | fast draft | **default (studio)** | max |
|---|---|---|---|
| `--texture-size` | 2048 | **4096** | 4096 |
| `--remesh-faces` | 40000 | **120000** | 200000 |
| `--octree-resolution` | 256 | **384** | 384 |
| `--max-num-view` | 6 | 6 | 8–12 |
| time (M3 Ultra) | ~260 s | ~380 s | longer |
| output | 7.6 MB / 40k faces | 21.5 MB / 120k faces | larger |

`--no-texture` = Stage 1 only (geometry, ~2.5 min, ~10 GB RAM).

## Hardware (full table in [HARDWARE.md](HARDWARE.md))

Peak **~20 GB** fp16 for the full textured pipeline (measured). **Min 16 GB** (INT8/INT4) or **24 GB** (fp16, tight) · **32 GB recommended**. Any M1→M5 — fp16-MLX path, no bf16 gotcha.

Measured full textured gen: **M3 Ultra ~380 s**, **M1 Ultra ~750 s** (4096 / 120k).

## ⚠️ License

Inherits the **Tencent Hunyuan Non-Commercial License** (see `LICENSE` / `Notice.txt`). **Non-commercial use only** — share and use accordingly.

## Credits

Tencent Hunyuan3D team (models) · [@dgrauet](https://github.com/dgrauet) (MLX port) · MODELBEAST (this build).
Original upstream README preserved as [`README_UPSTREAM.md`](README_UPSTREAM.md).
