feat(trellis_mac): close the fal quality gap — RAM-sized bake cap + forced-opaque alpha
Local GLBs were crushed to exactly 94,535 faces (fal ships ~495k) by the 200k laptop mtlbvh guard + o_voxel cleanup, and noisy baked alpha flipped materials to BLEND (speckle-veil hair, 'broken face'). Neither was the diffusion — local decode was already 2.2M tris. - run.py: default TRELLIS2_MAX_BAKE_FACES by node RAM (>=96GB -> 500k, else 200k laptop-safe); pass max_bake_faces/alpha_mode/steps/baker params through (server forwards only client-sent params — manifest defaults are UI-only) - manifest: new params, quality defaults - BENCHMARKS.md: 2026-07-22 entry — 500k cap verified crash-free on M3 Ultra, 351,898-face GLB, bake 7s->14s, farm-path e2e verified Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
61c63e513e
commit
b1d37b1629
@ -448,3 +448,30 @@ monster/trellis-2-mrp-mlx to ~/trellis2-mlx + scripts/setup_macos.sh
|
||||
(no HF login needed on workers). Both Ultras now serve the fastest
|
||||
local TRELLIS.2 in existence. TRELLIS.2 fleet: m3 primary (72s),
|
||||
m1 second lane (182s), zero dollars per asset.
|
||||
|
||||
## 2026-07-22 — trellis_mac closes the fal quality gap (m3ultra, black-model image, seed 0, pipeline 1024)
|
||||
|
||||
Root-caused why local GLBs looked far worse than fal's TRELLIS.2 despite the
|
||||
same 4B weights. Two independent bugs, neither in the diffusion (local decode
|
||||
was already 2.23M tris / 101s):
|
||||
|
||||
1. **Decimation ceiling.** generate.py's `TRELLIS2_MAX_BAKE_FACES=200000`
|
||||
laptop mtlbvh guard + o_voxel's cleanup pass (dup/degenerate removal +
|
||||
small-component pruning) crushed every model to exactly **94,535 faces**
|
||||
(fal ships ~495k). The 23× pre-bake simplify also shredded thin shells —
|
||||
hair fragments then got deleted by `remove_small_connected_components`.
|
||||
Fix: cap raised to **500k → 351,898-face GLB**, bake 7s→14s, no Metal
|
||||
watchdog crash on the M3 Ultra Studio. Now the operator default
|
||||
(`max_bake_faces` param; drop to 200k on laptops).
|
||||
|
||||
2. **Speckle-veil alpha.** o_voxel's Metal baker samples the decoder's alpha
|
||||
attr noisily (same family as the 07-19 dark-patch bug); any texel <250
|
||||
flips the material to BLEND → solid hair renders as a transparent speckle
|
||||
veil, "broken face". Fix: generate.py now rewrites the exported GLB to
|
||||
`alphaMode=OPAQUE` by default (`TRELLIS2_ALPHA_MODE=auto` keeps baked
|
||||
alpha for glassy subjects; `alpha_mode` operator param).
|
||||
|
||||
Verified in Blender side-by-side (old 95k / new 352k opaque / fal 495k):
|
||||
face + hair now read at fal level. Remaining deltas vs fal: slightly fuller
|
||||
fal hair (try `max_bake_faces=1000000`), and the known Metal dark-patch
|
||||
texels (workaround: `baker=vertex`). Also wired `steps` param passthrough.
|
||||
|
||||
@ -14,7 +14,11 @@
|
||||
"pipeline_type": {"type": "string", "enum": ["512", "1024", "1024_cascade"], "default": "1024", "description": "Resolution tier (1024_cascade = highest quality on Mac)"},
|
||||
"texture_size": {"type": "integer", "enum": [512, 1024, 2048], "default": 2048, "description": "Baked texture resolution"},
|
||||
"seed": {"type": "integer", "default": 0, "description": "Random seed"},
|
||||
"no_texture": {"type": "boolean", "default": false, "description": "Geometry only (skip texture stage, much faster)"}
|
||||
"no_texture": {"type": "boolean", "default": false, "description": "Geometry only (skip texture stage, much faster)"},
|
||||
"max_bake_faces": {"type": "integer", "enum": [200000, 500000, 1000000], "default": 500000, "description": "Pre-bake simplify cap. 500k ≈ fal parity, verified crash-free on the M3 Ultra (2026-07-22); drop to 200k on laptops (mtlbvh guard)"},
|
||||
"steps": {"type": "integer", "default": 0, "description": "Sampler steps override for all 3 flow phases (0 = pipeline default, 12)"},
|
||||
"baker": {"type": "string", "enum": ["", "vertex"], "default": "", "description": "'vertex' = KDTree vertex-color bake (dark-patch workaround, no PBR maps)"},
|
||||
"alpha_mode": {"type": "string", "enum": ["opaque", "auto"], "default": "opaque", "description": "opaque = force alphaMode OPAQUE in the GLB (fixes speckle-veil hair from noisy baked alpha); auto = keep o_voxel's BLEND detection for glassy subjects"}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,6 +34,8 @@ cmd = [
|
||||
]
|
||||
if p.get("no_texture"):
|
||||
cmd.append("--no-texture")
|
||||
if p.get("steps"):
|
||||
cmd += ["--steps", str(p["steps"])]
|
||||
|
||||
env = os.environ.copy()
|
||||
# xet chunked downloader fails on these BFL/Meta repos ("Unable to parse string
|
||||
@ -43,6 +45,22 @@ env["HF_HUB_DISABLE_XET"] = "1"
|
||||
env["KMP_DUPLICATE_LIB_OK"] = "TRUE"
|
||||
env.setdefault("OMP_NUM_THREADS", "1")
|
||||
env.setdefault("MKL_NUM_THREADS", "1")
|
||||
# Pre-bake simplify cap. The 200k generate.py default is a laptop-derived
|
||||
# mtlbvh guard that costs most of the mesh detail (2.2M-tri decode → 95k GLB
|
||||
# vs fal's 495k). 500k verified crash-free on the M3 Ultra Studio 2026-07-22.
|
||||
# The server passes only client-sent params (manifest defaults are UI-only),
|
||||
# so default here, sized by node RAM: big-memory Studios get the quality cap.
|
||||
if p.get("max_bake_faces") is not None:
|
||||
env["TRELLIS2_MAX_BAKE_FACES"] = str(p["max_bake_faces"])
|
||||
else:
|
||||
mem_gb = os.sysconf("SC_PAGE_SIZE") * os.sysconf("SC_PHYS_PAGES") / 1e9
|
||||
env.setdefault("TRELLIS2_MAX_BAKE_FACES", "500000" if mem_gb >= 96 else "200000")
|
||||
if p.get("baker"):
|
||||
env["TRELLIS2_BAKER"] = str(p["baker"])
|
||||
# "auto" keeps o_voxel's baked-alpha BLEND detection (glass etc.); default
|
||||
# opaque — the Metal baker's noisy alpha turns solid hair into speckles.
|
||||
if p.get("alpha_mode"):
|
||||
env["TRELLIS2_ALPHA_MODE"] = str(p["alpha_mode"])
|
||||
|
||||
print("+", " ".join(cmd), flush=True)
|
||||
print("(first run downloads TRELLIS.2-4B + dinov3 + RMBG-2.0 weights)", flush=True)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user