A newer version of the Gradio SDK is available: 6.12.0
Deploy NeAR to Hugging Face Space
Target Space: luh0502/NeAR.
This file lives in the Space clone (e.g. hf-near) — edit and push from this repo, not only from a separate template folder.
1. Clone and push this repo to the Space
git clone https://huggingface.co/spaces/luh0502/NeAR hf-near
cd hf-near
# …copy or sync code, then:
git add .
git commit -m "Update NeAR Space"
git push
If you maintain a separate template tree (e.g. NeAR_space), copy changes into hf-near before git push.
2. Space settings
- Hardware: select a GPU tier. This app needs CUDA for Hunyuan3D, NeAR, and
spconv/xformers. - Secrets: add
HF_TOKEN(read) if you pull gated Hub models or mirrored auxiliary assets from the Hub (e.g. rembg / Hunyuan weights / DINOv2 mirror). - Checkpoints for the NeAR pipeline load from Hub repo
luh0502/NeARby default (NEAR_PRETRAINEDinapp.py). Public repos work without a token; a token avoids rate limits. - Keep binary wheels and mirrored auxiliary assets in separate repos:
luh0502/near-wheels: prebuilt.whlfilesluh0502/near-assets: torch.hub-compatible mirrored repos and other runtime helper assets
2b. ZeroGPU (dynamic GPU allocation)
ZeroGPU shares NVIDIA H200 capacity across Spaces. It is not the same as picking a fixed T4/L4/A10G GPU.
Who can host a ZeroGPU Space
- Personal Hub account: PRO (ZeroGPU appears in hardware when creating/editing the Space).
- Organization: Team / Enterprise plans.
README / SDK (required)
- Use
sdk: gradioinREADME.mdfrontmatter. Official docs state ZeroGPU targets the Gradio SDK path. - Do not use
sdk: dockerfor the same Space if you expect ZeroGPU integration to match the documented path (Docker Spaces are a separate deployment model).
Space settings
- Open the Space → Settings → Hardware.
- Select ZeroGPU (wording may vary slightly in the UI).
- Save and wait for the Space to rebuild/restart.
Python / Gradio versions
- Follow the supported versions in the ZeroGPU doc (e.g. Gradio 4+, specific Python patch versions on the builder). This repo sets
python_versioninREADME.mdfor the Gradio builder.
Dependencies
requirements.txtmust include thespacespackage (HF injects it in some builds, but listing it explicitly is safe).- Keep
gradio[oauth,mcp](or equivalent) aligned with the Space runtime if you use OAuth/MCP features.
Application code (this repo)
import spaces(optionaltry/exceptfor local runs without the package).- Decorate every Gradio callback that uses CUDA with
@spaces.GPU(same as E-RayZer: noduration=in app code — platform defaults apply). This repo aliases it asGPUinapp.pyand uses@GPU; locally, without thespacespackage, it is a no-op. The decorator is effectively a no-op off ZeroGPU per HF docs. - Keep page-load defaults and HDRI preview off the heavy model path. This repo now uses a lightweight CPU image-preprocess path and a CPU-only HDRI preview path, so first page load no longer triggers full model initialization.
- Model init: a background thread (when
NEAR_MODEL_CPU_PRELOAD_AT_START=1) loads Hunyuan + NeAR on CPU at process start (no GPU lease).@spaces.GPUcallbacks callensure_geometry_on_cuda()/ensure_near_on_cuda()to move weights to CUDA once, then run inference. gsplat is exercised only when the pipeline renders (first call may still JIT if no prebuilt wheel). - Space Variables: at the top of
app.py(beforeimport spaces),NEAR_ZEROGPU_MAX_SECONDS/NEAR_ZEROGPU_DURATION_CAPare rewritten inos.environif they exceedNEAR_ZEROGPU_HF_CEILING_S(default 90, max 120) so values like300cannot break the Hub runtime. This does not set per-callbackdurationin Python; it only clamps env vars HF may read.
2b1. Recommended runtime variable matrix
| Variable | ZeroGPU-first recommendation | Fixed GPU / roomier budget |
|---|---|---|
HF_TOKEN |
Set | Set |
NEAR_AUX_REPO |
luh0502/near-assets |
luh0502/near-assets |
NEAR_DINO_REPO_SUBDIR |
dinov2 |
dinov2 |
NEAR_DINO_MODEL_ID |
leave unset unless your mirror renames hubconf entries | leave unset unless your mirror renames hubconf entries |
NEAR_DINO_FILENAME |
optional validation file inside the mirror repo | optional validation file inside the mirror repo |
NEAR_GSPLAT_SOURCE_SPEC |
unset unless you have a proven build path | optional if you want build-time source compile |
NEAR_ZEROGPU_HF_CEILING_S |
90 |
tune to your tier |
NEAR_HYSHAPE_GEOMETRY_CPU_PRELOAD_AT_START |
1 when Space entry is app_hyshape.py (default: background thread runs from_pretrained(..., device="cpu") at startup — no @spaces.GPU) |
0 to defer CPU load until the first Generate Mesh click (inside the GPU callback; longer first click) |
2b2. Mirroring DINOv2 and other auxiliary assets
The app no longer calls torch.hub.load("facebookresearch/dinov2", ...) directly against GitHub at runtime. Instead it resolves a local or HF-cached mirror:
- If
NEAR_DINO_LOCAL_REPOpoints to a local directory containinghubconf.py, that path wins. - Otherwise the app downloads
NEAR_AUX_REPO(defaultluh0502/near-assets) with optional subdirNEAR_DINO_REPO_SUBDIR(defaultdinov2) throughhuggingface_hub. - The resolved directory must be torch.hub-compatible and contain
hubconf.py.
Recommended contents of luh0502/near-assets:
dinov2/— a mirror of the DINOv2 torch.hub repo, includinghubconf.py- mirrored weights or helper files expected by that repo
- any future lightweight runtime-only helper assets you do not want to place in
near-wheels
This split keeps wheel ABI artifacts and runtime model/helper assets separate, which makes upgrades and cache invalidation much easier.
2b3. gsplat: first-render JIT (optional mitigations)
Similar to E-RayZer, the first real call into gsplat can spend a long time compiling CUDA. This repo supports:
| Variable | Purpose |
|---|---|
NEAR_GSPLAT_WHEEL_URL |
If set, app.py / app_gsplat.py runs pip install --force-reinstall on this URL before importing gsplat/trellis. Use when you host a cp310 manylinux wheel on near-wheels built against your exact PyTorch/CUDA pin (official gsplat wheels top out at pt2.4+cu124; see requirements.txt). |
NEAR_GSPLAT_SOURCE_SPEC |
If set, app.py runs pip install --no-build-isolation on this spec before importing trellis (e.g. ./third_party/gsplat after vendoring, or git+https://github.com/nerfstudio-project/gsplat.git@<tag>). Needs nvcc — usually absent on the default Gradio builder. |
Alternatively, pin a VCS gsplat line in requirements.txt (e.g. gsplat @ git+https://...) so the Space build step compiles once; no NEAR_GSPLAT_SOURCE_SPEC needed.
Pushing to the Hub
- Same workflow as §1:
git lfs install, commit,git push(see §4 for binaries / LFS). - Avoid
git push -fwith an empty template commit — it can wipeassets/,trellis/, etc. from history.
Trade-offs vs fixed GPU + Docker
- ZeroGPU + Gradio builder: the image may not include a full CUDA toolkit (
nvcc,CUDA_HOME).git+…nvdiffrast(source install) often fails here. This repo uses a prebuiltnvdiffrastwheel URL inrequirements.txt(see §5) so the builder only downloads a wheel. If that wheel is ABI-incompatible with our PyTorch pin, build your own wheel or add aDockerfilewithnvidia/cuda:*-develand fixed GPU. - Quota: visitors consume daily GPU seconds. This repo keeps plain
@spaces.GPUin Python and clampsNEAR_ZEROGPU_*viaNEAR_ZEROGPU_HF_CEILING_Srather than settingduration=in app code.
2c. Example gallery empty on the Space (assets/ “not deployed”)
Bundled thumbnails / HDRI / SLaTs live under assets/ and are tracked with Git LFS (see root .gitattributes: *.png, *.exr, *.npz, …).
If the UI shows no examples or No PNG examples, usually:
assets/was never pushed on the branch the Space uses — add, commit, andgit push.- Only LFS pointer files reached the Hub — on the website, open
assets/example_image/T.png: if it is ~100–200 bytes and starts withversion https://git-lfs.github.com/spec/v1, LFS objects were not uploaded. From a machine that has the real files:git lfs install git lfs push --all origin - Sparse / partial clone — ensure you are not using a workflow that omits
assets/(e.g. copying onlyapp.pyinto a fresh Space).
app.py logs [NeAR] WARNING: … LFS pointers when it detects pointer stubs at runtime so Space build logs are easier to read.
3. Files used by Spaces
| File | Role |
|---|---|
README.md |
Must start with YAML frontmatter (sdk: gradio, app_file: …, sdk_version, …). The app_file value is what Spaces should launch after each build. |
app.py |
Full NeAR entry point; uses PORT / GRADIO_SERVER_* env vars. |
app_hyshape.py |
Optional HyShape-only diagnostic entry (see repo README). |
app_gsplat.py |
Optional gsplat image-fitting Gradio demo (@spaces.GPU). |
If the running Space does not match README.md app_file, check Space → Settings → App file (dashboard can disagree until you align it) and Restart the Space. Use the spaces URL (/spaces/<user>/<name>), not the model repo URL.
| requirements.txt | pip dependencies. |
| packages.txt | Optional apt packages (OpenGL, etc.). |
Root packages.txt lists libgl1 and libopengl0 so imports that pull in pymeshlab are less likely to spam logs about libOpenGL.so.0. Those plugins are not required for the core NeAR / HyShape paths; if warnings persist after rebuild, they are usually safe to ignore.
4. Git push: large files & binary files on the Hub
4a. Files > 10 MiB in plain Git
HF rejects them unless you use Git LFS or Git Xet.
Example: hy3dshape/demo.glb is a generated demo artifact — remove from Git and ignore it (see .gitignore). If it is already in history, rewrite history (orphan branch or git filter-repo) then git push -f.
4b. Binary files (examples) — “use Xet” rejection
The Hub may reject any tracked binary that is not stored via LFS / Xet. Root .gitattributes only lists NeAR bundle types: images (*.png, …), HDRI (*.exr), meshes (*.glb, *.gltf), and example SLaTs (*.npz). Model weights stay on the Hub — no broad *.safetensors / *.ckpt rules here.
One-time setup on the machine you push from:
git lfs install
# Recommended for Hub (handles Xet-backed transfers): https://huggingface.co/docs/hub/xet/using-xet-storage#git
curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/huggingface/xet-core/refs/heads/main/git_xet/install.sh | sh
git xet install
If those files were already committed as normal Git blobs, migrate them into LFS and rewrite history (then force-push):
cd ~/code/3diclight/hf-near # your Space clone
git lfs install
git lfs migrate import --include="*.png,*.jpg,*.jpeg,*.gif,*.webp,*.exr,*.glb,*.gltf,*.npz" --everything
git push -f origin main
Keep --include in sync with .gitattributes. If you later commit other large binaries, add their extensions there and re-run migrate for those patterns.
4c. Start clean: delete .git and one fresh commit (LFS from day one)
Use this when history is full of plain-Git binaries and you prefer one new root commit over git lfs migrate.
Save the remote (you will need it after
rm -rf .git):cd ~/code/3diclight/hf-near git remote -vInstall Git LFS (if needed):
conda install -c conda-forge git-lfsorsudo apt install git-lfs.Remove Git metadata only (does not delete your working files):
rm -rf .gitRe-init with LFS before the first
git addso every PNG/NPZ/… is stored as LFS from the start:git init git lfs install # Optional but recommended on HF: https://huggingface.co/docs/hub/xet/using-xet-storage#git # curl ... git_xet/install.sh | sh && git xet installConfirm root
.gitattributesis present (it lists*.png,*.npz, etc.). If you add it only aftergit add, rungit rm --cachedon those paths and re-add.Commit and force-push (overwrites Space
main):git branch -M main git add . git commit -m "Initial NeAR Space (LFS from first commit)" git remote add origin git@hf.co:spaces/luh0502/NeAR # or: git remote add origin https://huggingface.co/spaces/luh0502/NeAR git push -u -f origin mainCheck locally before push:
git lfs ls-files | headshould list example images/slats/hdris.Verify LFS has real bytes (not pointer stubs on disk):
head -1 assets/example_image/T.png wc -c assets/example_image/T.pngIf the first line is
version https://git-lfs.github.com/spec/v1and size is ~100–200 bytes, your tree contains LFS pointer text, not the image.git pushwill fail with(missing)because.git/lfs/objects/...was never filled. Fix: copy full binaries from a complete source tree (e.g.NeAR_spaceor an oldhf-nearbackup), then re-stage:git lfs install git rm -rf --cached assets trellis/representations/mesh/flexicubes/images git add assets trellis/representations/mesh/flexicubes/images git commit --amend -m "Initial NeAR Space (LFS from first commit)" # or make a new commit if you do not want to amend git lfs fsck # should not report missing objects for paths you care about git push -u -f origin mainDo not set
lfs.allowincompletepushto true — that pushes broken history.
Caveats: -f replaces all history on the Hub Space. Anyone with an old clone should re-clone. Uncommitted work: commit or stash before step 3 (here you only remove .git, so working tree stays).
4d. Push fails: LFS upload failed / (missing) …
Git is trying to upload LFS objects listed in your commits, but the large files are not in the local LFS store. Common causes:
GIT_LFS_SKIP_SMUDGE=1clone (or a clone from a Space that never stored LFS on the server): working tree stays as tiny pointer files; a latergit add/ commit keeps that broken state.- Copying only
.gitto another machine without copying.git/lfs/objects. git addbeforegit lfs installin a fresh repo (then fixing.gitattributeswithout unstaging and re-adding).
Fix: Restore real PNG/JPG/GIF/EXR/NPZ files on disk (see §4c step 8), then git rm --cached + git add those trees and commit again. Confirm with git lfs fsck before git push.
Alternative (smaller Space repo): do not commit the whole assets/example_image/ gallery — keep only T.png (and one HDRI), add the rest to .gitignore, and use an orphan commit so history contains no offending blobs.
5. nvdiffrast on Gradio / ZeroGPU (prebuilt wheel)
Many 3D repos use nvdiffrast. The HF Gradio builder usually lacks nvcc, so git+https://github.com/NVlabs/nvdiffrast (source build) often fails.
What this repo does
requirements.txtinstallsnvdiffrastfrom a direct.whlURL (same pattern as microsoft/TRELLIS.2 — wheel hosted under JeffreyXiang/Storages releases). The builder only downloads the wheel; no local compile.
ABI / version caveat
- Third-party wheels (e.g. from JeffreyXiang/Storages) are often built for another torch/CUDA stack. Mismatches show up as
ImportError/undefined symbol: _ZN3c10...when loading_nvdiffrast_c. Fix: use a wheel you built with the same torch major/minor asrequirements.txt(here torch 2.8 + cu128 + cp310 + Linux x86_64).
Hosting your own nvdiffrast wheel
The Space builder only sees URLs in requirements.txt, not files on your laptop. After you have e.g. nvdiffrast-0.4.0-cp310-cp310-linux_x86_64.whl:
Upload the file to a stable HTTPS location, for example:
- Hugging Face Hub — create a small repo (e.g.
yourname/near-wheels), then:pip install -U "huggingface_hub[cli]" hf auth login hf upload yourname/near-wheels /path/to/nvdiffrast-0.4.0-cp310-cp310-linux_x86_64.whl ./ - Or GitHub Releases — attach the
.whlas a release asset (same idea as TRELLIS v1 wheels).
- Hugging Face Hub — create a small repo (e.g.
Put the raw download URL on its own line in
requirements.txt(replace the old nvdiffrast URL). Examples:- Hub:
https://huggingface.co/yourname/near-wheels/resolve/main/nvdiffrast-0.4.0-cp310-cp310-linux_x86_64.whl - You may append
?download=trueif a host requires it forpip.
- Hub:
Do not commit multi‑MB wheels into the Space git repo unless you use Git LFS / Xet and accept the history size; a separate wheels Hub repo is usually simpler.
Re‑push the Space;
pipwill download and install the wheel during the image build (nonvccneeded).
Uploading mirrored aux assets
Use the same CLI for near-assets. Example:
pip install -U "huggingface_hub[cli]"
hf auth login
hf upload-large-folder luh0502/near-assets ./near-assets-local
Suggested layout:
near-assets-local/
dinov2/
hubconf.py
...
Fallback: Docker + devel image
- If wheels are not viable, use
sdk: docker, annvidia/cuda:*-develbase,git+…nvdiffrast, and a fixed GPU Space. That path is not ZeroGPU in the usual doc sense; add aDockerfilelocally when needed.
diffoctreerast
Not listed in requirements.txt; trellis/renderers/octree_renderer.py degrades with a warning if it is missing. Add a separate install only if you need that renderer on the Space.
6. If the build fails
- PyTorch / CUDA mismatch: this repo pins CUDA 12.8 (
cu128) and torch 2.8.0 inrequirements.txt. If the Space image’s driver is older, switch hardware or relax the pins. nvdiffrastimport/runtime errors: the third-party wheel may not match torch 2.8/cu128 — build a matching wheel or use a Docker Space withnvidia/cuda:*-develand source install../vox2seqinrequirements.txt: Hugging Face’s Gradio image runspip install -r /tmp/requirements.txtbefore the repo is copied, so path dependencies are invalid (Expected package name…, file not found). Do not list./vox2seq; this repo uses a vendored pure-PyTorch fallback (trellis/.../vox2seq_pytorch/) inserialized_attn.py. Optionallypip install ./vox2seqlocally if you havenvccand want the CUDA extension.spconv/xformers: versions must match the installed PyTorch + CUDA.- Disk / first boot: the NeAR checkpoint snapshot is large; cold start may time out—increase hardware or pre-cache in a custom image.
- DINOv2 mirror not found: confirm
NEAR_DINO_LOCAL_REPOorNEAR_AUX_REPOpoints to a directory/repo containinghubconf.py(default subdirdinov2/). The runtime now expects a local or HF-cached mirror rather than direct GitHubtorch.hubaccess.
7. Local check before push
export NEAR_PRETRAINED=luh0502/NeAR # or a local folder with pipeline.yaml
python app.py --host 0.0.0.0 --port 7860