Repo had a 0-byte README and no CLAUDE.md. README: requirements (NVIDIA GPU + CUDA 12.1 + ≥12GB VRAM), build/run quickstart, project structure, callout that the root-level uv scaffolding is not part of the build path. CLAUDE.md captures the three upstream patches that are deliberately applied (CUDA 12.1 pin, dedup'd conda create, onnxruntime fix for upstream issue #175), the intentional `|| true` on bulk pip install (nvdiffrast needs --no-build-isolation), build performance gotchas, and the absence of an outputs bind mount. Untracked .python-version / InstantMesh/ / uv.lock left out of this commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
122 lines
4.7 KiB
Markdown
122 lines
4.7 KiB
Markdown
# Claude notes — instamesh-docker
|
|
|
|
Agent context for this repo. Read before non-trivial changes.
|
|
|
|
## What this is
|
|
|
|
Docker wrapper around upstream [TencentARC/InstantMesh](https://github.com/TencentARC/InstantMesh)
|
|
for single-image → 3D mesh generation. **Not** a fork of InstantMesh
|
|
itself — this repo owns the docker build + compose plus a small set of
|
|
patches that fix known upstream build breakage.
|
|
|
|
## Repo shape
|
|
|
|
```
|
|
instamesh-docker/
|
|
InstantMesh/ # UNTRACKED — upstream clone. Operators run
|
|
# `git clone https://github.com/TencentARC/InstantMesh.git`
|
|
# once before `docker compose build`. Not a submodule.
|
|
docker/
|
|
Dockerfile # patched (see "Patches applied" below)
|
|
compose.yml # GPU compose, named volume for model cache, port 43839
|
|
requirements.txt # InstantMesh's pip deps, kept here so the Dockerfile
|
|
# can ADD them without changing the upstream tree
|
|
main.py, pyproject.toml, uv.lock, .python-version
|
|
# leftover uv scaffolding from initial repo init;
|
|
# NOT part of the build path. Don't extend these.
|
|
README.md
|
|
CLAUDE.md
|
|
```
|
|
|
|
`InstantMesh/` is intentionally untracked. Don't add it as a submodule
|
|
or vendor it into source control — keep the upstream boundary clean.
|
|
|
|
## Patches applied (vs. upstream)
|
|
|
|
The Dockerfile is forked from InstantMesh's docker config with three
|
|
deliberate changes — call out any churn around these:
|
|
|
|
1. **CUDA aligned to 12.1.** Base image is
|
|
`nvidia/cuda:12.1.0-runtime-ubuntu22.04`; conda installs `cuda` from
|
|
`nvidia/label/cuda-12.1.0`; pip installs `torch==2.1.0 + cu121` and
|
|
`xformers==0.0.22.post7`. All four must stay in sync. Don't bump CUDA
|
|
without re-pinning all of them.
|
|
2. **Duplicate `conda create` removed.** Upstream's Dockerfile created
|
|
the conda env twice; the second one nuked the first's pinned
|
|
packages. Don't reintroduce.
|
|
3. **`onnxruntime` added.** Missing from upstream's `requirements.txt`
|
|
(InstantMesh issue #175). Installed as a separate `pip install` step
|
|
after the bulk requirements install so it's not silently dropped by
|
|
the `|| true` below.
|
|
|
|
## Intentional `|| true` on the bulk pip install
|
|
|
|
```dockerfile
|
|
RUN pip install --no-cache-dir -r requirements.txt || true
|
|
```
|
|
|
|
This is **on purpose**. The requirements include `nvdiffrast` via a git
|
|
URL that needs `--no-build-isolation`, which pip's bulk install won't
|
|
do. We let that line fail, then install `nvdiffrast` correctly:
|
|
|
|
```dockerfile
|
|
RUN pip install git+https://github.com/NVlabs/nvdiffrast.git --no-build-isolation
|
|
```
|
|
|
|
Don't "fix" the bulk install by removing `|| true` — the build will
|
|
hard-fail on nvdiffrast.
|
|
|
|
## Hardware contract
|
|
|
|
- **NVIDIA GPU required**, exposed through Docker via the nvidia
|
|
runtime. InstantMesh wants **≥ 12 GB VRAM** comfortably; smaller cards
|
|
may OOM during inference.
|
|
- **CUDA 12.1** — see patch #1 above.
|
|
|
|
## Build is slow + brittle
|
|
|
|
Expect a 15+ minute first build. Conda + nvdiffrast compilation +
|
|
PyTorch wheels add up. Triggers that re-run the slow layers:
|
|
- Editing `docker/requirements.txt` invalidates the conda install layer.
|
|
- Editing the Dockerfile's `apt-get install` line redoes the whole
|
|
thing from a fresh base image.
|
|
|
|
Lean on Docker's layer cache; don't restructure for "cleanliness"
|
|
without measuring the rebuild cost.
|
|
|
|
## Compose
|
|
|
|
```yaml
|
|
ports:
|
|
- "43839:43839" # Gradio app, host-published
|
|
volumes:
|
|
- instantmesh-models:/workspace/models # weights cache (named volume)
|
|
```
|
|
|
|
No host-network mode, no bind mounts for code (the upstream tree is
|
|
COPYed at build time). If you need to iterate on InstantMesh source,
|
|
edit `InstantMesh/` locally and rebuild — there's no dev-mode wiring.
|
|
|
|
## Where outputs go
|
|
|
|
InstantMesh's Gradio app writes generated meshes inside the container
|
|
(under `/workspace/instantmesh/`). There's **no bind mount** for
|
|
outputs in `compose.yml` — operator downloads results from the Gradio
|
|
UI. If you find yourself wanting to bind-mount an outputs dir, mirror
|
|
`hunyuan3d-sunnie/docker/outputs/`.
|
|
|
|
## Don't-touch zones
|
|
|
|
- The CUDA 12.1 pins (base image / conda label / PyTorch wheel index /
|
|
xformers wheel) — load-bearing as a set.
|
|
- The `|| true` on bulk requirements install — required for nvdiffrast.
|
|
- The `onnxruntime` separate install line — load-bearing per upstream #175.
|
|
- The untracked `InstantMesh/` directory — let operators reclone.
|
|
|
|
## Bigger picture
|
|
|
|
Personal/one-off project, GPU-only. Runs on the dev tower; not part of
|
|
the homelab production stack. Sibling project `hunyuan3d-sunnie/` uses
|
|
a different model (Hunyuan3D-2) for the same general shape of problem
|
|
on a 10 GB card — pick that one if VRAM is tight.
|