Spaces:
Running on Zero
Running on Zero
Weijie Lyu Claude Opus 4.8 (1M context) commited on
Commit ·
fdba6dc
1
Parent(s): 06957f5
Revert cu130 forcing; use ZeroGPU-native cu128 torch + pip cu128 nvcc
Browse filesRoot cause found via [GPU-DIAG]: 42 GiB free yet allocation fails --
not a real OOM. The forced cu130 torch is incompatible with ZeroGPU's
fork-based GPU memory management (ZeroGPU targets the cu128 builds of
its supported torch versions). Stop forcing cu130: drop the startup
torch reinstall and the allocator-env band-aids, and run the cu128
torch the base image provides. diff-gaussian then needs a CUDA 12.8
compiler (container only has 13.0), so install nvidia-cuda-nvcc-cu12 /
cccl and point the build's CUDA_HOME at it (arch list incl. sm_120).
Net: fewer hacks than before, aligned with ZeroGPU's supported stack.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- app.py +25 -58
- requirements.txt +8 -6
app.py
CHANGED
|
@@ -22,59 +22,15 @@ if os.environ.get("HF_HUB_ENABLE_HF_TRANSFER") == "1":
|
|
| 22 |
print("⚠️ hf_transfer not available, disabling fast download")
|
| 23 |
os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "0"
|
| 24 |
|
| 25 |
-
# ZeroGPU attaches the GPU inside a forked subprocess where NVML can't reinit.
|
| 26 |
-
# PyTorch's expandable_segments allocator uses CUDA VMM, whose NVML query then
|
| 27 |
-
# asserts ("NVML_SUCCESS == r" in CUDACachingAllocator.cpp). Disabling ONLY
|
| 28 |
-
# expandable segments avoids that NVML path while keeping the normal caching
|
| 29 |
-
# allocator (so memory is still pooled/reused -- disabling caching entirely OOMs).
|
| 30 |
-
# Must be set before torch initializes CUDA, i.e. before "import torch".
|
| 31 |
-
os.environ.setdefault("PYTORCH_CUDA_ALLOC_CONF", "expandable_segments:False")
|
| 32 |
-
|
| 33 |
import json
|
| 34 |
from pathlib import Path
|
| 35 |
from datetime import datetime
|
| 36 |
import random
|
| 37 |
|
| 38 |
-
# -----------------------------
|
| 39 |
-
# Ensure a CUDA-13.0 (cu130) torch BEFORE torch is imported.
|
| 40 |
-
# The ZeroGPU container ships the CUDA 13.0 toolkit, but the image's torch is a
|
| 41 |
-
# cu128 build (torch.version.cuda == "12.8"), so the runtime compile of
|
| 42 |
-
# diff-gaussian-rasterization fails with a 13.0-vs-12.8 mismatch. Build-time pip
|
| 43 |
-
# kept resolving the cu128 wheel regardless of index config, so fix it here: if
|
| 44 |
-
# the installed torch isn't a +cu130 build, reinstall the cu130 stack. This runs
|
| 45 |
-
# before "import torch" so the whole process and the build subprocess use cu130.
|
| 46 |
-
def _ensure_cu130_torch():
|
| 47 |
-
import subprocess as _sp
|
| 48 |
-
import sys as _sys
|
| 49 |
-
import importlib.metadata as _md
|
| 50 |
-
try:
|
| 51 |
-
installed = _md.version("torch")
|
| 52 |
-
except _md.PackageNotFoundError:
|
| 53 |
-
installed = ""
|
| 54 |
-
print(f"[CU130-CHECK] installed torch == {installed or '<none>'}")
|
| 55 |
-
if "+cu130" in installed:
|
| 56 |
-
print("[CU130-CHECK] cu130 torch already present, skipping reinstall")
|
| 57 |
-
return
|
| 58 |
-
print("[CU130-CHECK] reinstalling torch/torchvision/xformers from the cu130 index...")
|
| 59 |
-
# NOT --no-deps: torch 2.11.0+cu130 must pull its matching nvidia-*-cu13 CUDA
|
| 60 |
-
# runtime libs. With --no-deps the container kept the base image's nvidia-*-cu12
|
| 61 |
-
# (12.8) libs, so cu130 torch ran on cu12 runtime -- a broken mix that made
|
| 62 |
-
# allocations fail (surfacing as the NVML/OOM assert). --extra-index-url lets
|
| 63 |
-
# torch's non-NVIDIA deps still resolve from PyPI.
|
| 64 |
-
_sp.check_call([
|
| 65 |
-
_sys.executable, "-m", "pip", "install", "--no-cache-dir",
|
| 66 |
-
"--index-url", "https://download.pytorch.org/whl/cu130",
|
| 67 |
-
"--extra-index-url", "https://pypi.org/simple",
|
| 68 |
-
"torch==2.11.0+cu130", "torchvision==0.26.0+cu130", "xformers==0.0.35",
|
| 69 |
-
])
|
| 70 |
-
print("[CU130-CHECK] cu130 stack installed")
|
| 71 |
-
|
| 72 |
-
_ensure_cu130_torch()
|
| 73 |
-
|
| 74 |
import gradio as gr
|
| 75 |
import numpy as np
|
| 76 |
import torch
|
| 77 |
-
print(f"[
|
| 78 |
import yaml
|
| 79 |
from easydict import EasyDict as edict
|
| 80 |
from einops import rearrange
|
|
@@ -142,20 +98,31 @@ try:
|
|
| 142 |
except ImportError:
|
| 143 |
print("Installing diff-gaussian-rasterization (compiling for detected CUDA arch)...")
|
| 144 |
env = os.environ.copy()
|
| 145 |
-
try:
|
| 146 |
-
import torch as _torch
|
| 147 |
-
if _torch.cuda.is_available():
|
| 148 |
-
maj, minr = _torch.cuda.get_device_capability()
|
| 149 |
-
arch = f"{maj}.{minr}" # e.g., "9.0" on H100/H200, "8.0" on A100
|
| 150 |
-
env["TORCH_CUDA_ARCH_LIST"] = f"{arch}+PTX"
|
| 151 |
-
else:
|
| 152 |
-
# Build stage may not see a GPU on HF Spaces: compile a cross-arch set
|
| 153 |
-
env["TORCH_CUDA_ARCH_LIST"] = "8.0;8.6;8.9;9.0+PTX"
|
| 154 |
-
except Exception:
|
| 155 |
-
env["TORCH_CUDA_ARCH_LIST"] = "8.0;8.6;8.9;9.0+PTX"
|
| 156 |
|
| 157 |
-
#
|
| 158 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
|
| 160 |
# --no-build-isolation: the package's setup.py imports torch to detect the
|
| 161 |
# CUDA arch, but pip's isolated build env has no torch. Reuse the main env
|
|
|
|
| 22 |
print("⚠️ hf_transfer not available, disabling fast download")
|
| 23 |
os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "0"
|
| 24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
import json
|
| 26 |
from pathlib import Path
|
| 27 |
from datetime import datetime
|
| 28 |
import random
|
| 29 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
import gradio as gr
|
| 31 |
import numpy as np
|
| 32 |
import torch
|
| 33 |
+
print(f"[GPU-DIAG] torch {torch.__version__} / CUDA {torch.version.cuda}")
|
| 34 |
import yaml
|
| 35 |
from easydict import EasyDict as edict
|
| 36 |
from einops import rearrange
|
|
|
|
| 98 |
except ImportError:
|
| 99 |
print("Installing diff-gaussian-rasterization (compiling for detected CUDA arch)...")
|
| 100 |
env = os.environ.copy()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
|
| 102 |
+
# Compile against the pip-installed CUDA 12.8 toolkit (nvidia-cuda-nvcc-cu12),
|
| 103 |
+
# NOT the container's CUDA 13.0 toolkit. torch here is the cu128 build ZeroGPU
|
| 104 |
+
# requires, and torch's build check errors on a major CUDA mismatch (nvcc 13 vs
|
| 105 |
+
# torch 12.8). Point CUDA_HOME at the pip nvcc and feed the runtime/cub headers
|
| 106 |
+
# and cudart lib via CPATH/LIBRARY_PATH so nvcc 12.8 matches torch 12.8.
|
| 107 |
+
import site
|
| 108 |
+
_site = site.getsitepackages()[0]
|
| 109 |
+
_nv = os.path.join(_site, "nvidia")
|
| 110 |
+
_nvcc_home = os.path.join(_nv, "cuda_nvcc")
|
| 111 |
+
if os.path.isdir(_nvcc_home):
|
| 112 |
+
env["CUDA_HOME"] = _nvcc_home
|
| 113 |
+
env["PATH"] = os.path.join(_nvcc_home, "bin") + os.pathsep + env.get("PATH", "")
|
| 114 |
+
_incs = [os.path.join(_nv, "cuda_runtime", "include"),
|
| 115 |
+
os.path.join(_nv, "cuda_cccl", "include")]
|
| 116 |
+
env["CPATH"] = os.pathsep.join(_incs + ([env["CPATH"]] if env.get("CPATH") else []))
|
| 117 |
+
_rt_lib = os.path.join(_nv, "cuda_runtime", "lib")
|
| 118 |
+
env["LIBRARY_PATH"] = _rt_lib + os.pathsep + env.get("LIBRARY_PATH", "")
|
| 119 |
+
env["LD_LIBRARY_PATH"] = _rt_lib + os.pathsep + env.get("LD_LIBRARY_PATH", "")
|
| 120 |
+
else:
|
| 121 |
+
print(f"⚠️ pip CUDA toolkit not found at {_nvcc_home}; falling back to system nvcc")
|
| 122 |
+
|
| 123 |
+
# Build a cross-arch set incl. Blackwell sm_120 (the ZeroGPU GPU is cap 12.0);
|
| 124 |
+
# the build stage may not see a GPU, so don't rely on get_device_capability.
|
| 125 |
+
env["TORCH_CUDA_ARCH_LIST"] = "8.0;8.6;8.9;9.0;12.0+PTX"
|
| 126 |
|
| 127 |
# --no-build-isolation: the package's setup.py imports torch to detect the
|
| 128 |
# CUDA arch, but pip's isolated build env has no torch. Reuse the main env
|
requirements.txt
CHANGED
|
@@ -1,11 +1,13 @@
|
|
| 1 |
-
# torch 2.11.0 is ZeroGPU-supported
|
| 2 |
-
#
|
| 3 |
-
#
|
| 4 |
-
#
|
| 5 |
-
# cu130 for diff-gaussian-rasterization to compile. Build-time pip resolves the
|
| 6 |
-
# cu128 wheel here, so the cu130 reinstall is forced at startup in app.py.
|
| 7 |
torch==2.11.0
|
| 8 |
torchvision==0.26.0
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
numpy==1.26.4
|
| 10 |
pillow==10.4.0
|
| 11 |
diffusers[torch]==0.30.3
|
|
|
|
| 1 |
+
# torch 2.11.0 is ZeroGPU-supported and the version line where torchvision 0.26.0
|
| 2 |
+
# and xformers 0.0.35 agree (xformers 0.0.33 hard-pinned torch==2.9.0, which ZeroGPU
|
| 3 |
+
# rejects; 0.0.35 relaxed to >=2.10). This is the cu128 (CUDA 12.8) build ZeroGPU
|
| 4 |
+
# ships -- required for ZeroGPU's GPU memory management to work.
|
|
|
|
|
|
|
| 5 |
torch==2.11.0
|
| 6 |
torchvision==0.26.0
|
| 7 |
+
# CUDA 12.8 compiler + headers so diff-gaussian-rasterization compiles against a
|
| 8 |
+
# toolkit matching cu128 torch (the container only ships CUDA 13.0). See app.py.
|
| 9 |
+
nvidia-cuda-nvcc-cu12~=12.8.0
|
| 10 |
+
nvidia-cuda-cccl-cu12~=12.8.0
|
| 11 |
numpy==1.26.4
|
| 12 |
pillow==10.4.0
|
| 13 |
diffusers[torch]==0.30.3
|