Spaces:
Running on Zero
Running on Zero
File size: 6,589 Bytes
90fd8f8 c83fca8 1803df3 c83fca8 23d923b b7c04cb 26b3ad9 c83fca8 26b3ad9 bab8ce7 c83fca8 1803df3 c83fca8 1a5d02b 26b3ad9 92f2e1f 90fd8f8 26b3ad9 9452eaa 04605b1 90fd8f8 26b3ad9 90fd8f8 26b3ad9 90fd8f8 26b3ad9 d122969 23d923b 26b3ad9 d122969 26b3ad9 90fd8f8 92f2e1f d122969 90fd8f8 26b3ad9 90fd8f8 26b3ad9 92f2e1f 26b3ad9 92f2e1f 90fd8f8 26b3ad9 92f2e1f 90fd8f8 26b3ad9 90fd8f8 26b3ad9 90fd8f8 26b3ad9 23d923b 90fd8f8 dec9ec5 26b3ad9 23d923b 26b3ad9 90fd8f8 23d923b 90fd8f8 92f2e1f 23d923b e2beaf5 26b3ad9 90fd8f8 26b3ad9 92f2e1f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | import os
import sys
import subprocess
import tempfile
import spaces
import torch
import ctypes
# Monkey-patch xformers.ops.memory_efficient_attention to fall back to
# torch SDPA on Blackwell (sm_120). On the new ZeroGPU GPUs, neither
# the FA3 nor the cutlass xformers kernel supports compute capability
# 12.0, so any call into xformers' MEA raises NotImplementedError.
# imagedream's mv_unet imports xformers.ops directly, so we have to
# patch it before that import happens.
import xformers
import xformers.ops as _xops
def _xformers_mea_sdpa(query, key, value, attn_bias=None, p=0.0, scale=None,
op=None, **kwargs):
# xformers MEA accepts (B, M, K) or (B, M, H, K). Torch SDPA wants
# (B, H, M, K). Reshape appropriately and reverse on output.
if query.dim() == 3:
# Single-head: add an H=1 axis.
q = query.unsqueeze(1)
k = key.unsqueeze(1)
v = value.unsqueeze(1)
squeeze_out = True
else:
# (B, M, H, K) -> (B, H, M, K)
q = query.transpose(1, 2)
k = key.transpose(1, 2)
v = value.transpose(1, 2)
squeeze_out = False
attn_mask = attn_bias
if hasattr(attn_mask, "materialize"):
try:
attn_mask = attn_mask.materialize(
shape=(q.shape[0], q.shape[1], q.shape[2], k.shape[2]),
dtype=q.dtype,
device=q.device,
)
except Exception:
attn_mask = None
out = torch.nn.functional.scaled_dot_product_attention(
q, k, v, attn_mask=attn_mask, dropout_p=p, scale=scale,
)
if squeeze_out:
return out.squeeze(1)
return out.transpose(1, 2)
_xops.memory_efficient_attention = _xformers_mea_sdpa
xformers.ops.memory_efficient_attention = _xformers_mea_sdpa
import gradio as gr
import numpy as np
from diffusers import DiffusionPipeline
CUDA_HOME = "/cuda-image/usr/local/cuda-13.0"
CUDA_LIBDIR = os.path.join(CUDA_HOME, "lib64")
@spaces.GPU(duration=600)
def _first_gpu_setup():
try:
import diff_gaussian_rasterization # noqa
return
except ImportError:
pass
patch_dir = tempfile.mkdtemp(prefix="torch_cuda_patch_")
with open(os.path.join(patch_dir, "sitecustomize.py"), "w") as f:
f.write(
"try:\n"
" import torch.utils.cpp_extension as _c\n"
" _c._check_cuda_version = lambda *a, **k: None\n"
"except Exception:\n"
" pass\n"
)
env = os.environ.copy()
env["CUDA_HOME"] = CUDA_HOME
env["CUDA_PATH"] = CUDA_HOME
env["PATH"] = os.path.join(CUDA_HOME, "bin") + os.pathsep + env.get("PATH", "")
env["PYTHONPATH"] = patch_dir + os.pathsep + env.get("PYTHONPATH", "")
env["TORCH_CUDA_ARCH_LIST"] = "12.0"
subprocess.check_call(
[sys.executable, "-m", "pip", "install", "--no-deps",
"setuptools", "wheel", "ninja", "packaging"],
)
# The PyPI release of `diff-gaussian-rasterization` is the original
# graphdeco-inria version; the LGM model uses that one.
subprocess.check_call(
[sys.executable, "-m", "pip", "install",
"--no-build-isolation", "--no-deps",
"git+https://github.com/graphdeco-inria/diff-gaussian-rasterization.git"],
env=env,
)
_first_gpu_setup()
try:
ctypes.CDLL(os.path.join(CUDA_LIBDIR, "libcudart.so.13"), mode=ctypes.RTLD_GLOBAL)
os.environ["LD_LIBRARY_PATH"] = CUDA_LIBDIR + os.pathsep + os.environ.get("LD_LIBRARY_PATH", "")
except OSError:
pass
TMP_DIR = "/tmp"
os.makedirs(TMP_DIR, exist_ok=True)
image_pipeline = DiffusionPipeline.from_pretrained(
"dylanebert/imagedream",
custom_pipeline="dylanebert/multi-view-diffusion",
torch_dtype=torch.float16,
trust_remote_code=True,
).to("cuda")
splat_pipeline = DiffusionPipeline.from_pretrained(
"dylanebert/LGM",
custom_pipeline="dylanebert/LGM",
torch_dtype=torch.float16,
trust_remote_code=True,
).to("cuda")
@spaces.GPU
def run(input_image, seed):
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
input_image = input_image.astype("float32") / 255.0
images = image_pipeline(
"", input_image, guidance_scale=5, num_inference_steps=30, elevation=0
)
gaussians = splat_pipeline(images)
output_ply_path = os.path.join(TMP_DIR, "output.ply")
splat_pipeline.save_ply(gaussians, output_ply_path)
return output_ply_path
_TITLE = """LGM Mini"""
_DESCRIPTION = """
<div>
A lightweight version of <a href="https://huggingface.co/spaces/ashawkey/LGM">LGM: Large Multi-View Gaussian Model for High-Resolution 3D Content Creation</a>.
To convert to mesh, download the output splat and visit [splat-to-mesh](https://huggingface.co/spaces/dylanebert/splat-to-mesh).
</div>
"""
css = """
#duplicate-button {
margin: auto;
color: white;
background: #1565c0;
border-radius: 100vh;
}
"""
block = gr.Blocks(title=_TITLE, css=css)
with block:
gr.DuplicateButton(
value="Duplicate Space for private use", elem_id="duplicate-button"
)
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("# " + _TITLE)
gr.Markdown(_DESCRIPTION)
with gr.Row(variant="panel"):
with gr.Column(scale=1):
input_image = gr.Image(label="image", type="numpy")
seed_input = gr.Number(label="seed", value=42)
button_gen = gr.Button("Generate")
with gr.Column(scale=1):
output_splat = gr.Model3D(label="3D Gaussians")
button_gen.click(
fn=run, inputs=[input_image, seed_input], outputs=[output_splat]
)
gr.Examples(
examples=[
"https://huggingface.co/datasets/dylanebert/iso3d/resolve/main/jpg@512/a_cat_statue.jpg",
"https://huggingface.co/datasets/dylanebert/iso3d/resolve/main/jpg@512/a_baby_penguin.jpg",
"https://huggingface.co/datasets/dylanebert/iso3d/resolve/main/jpg@512/A_cartoon_house_with_red_roof.jpg",
"https://huggingface.co/datasets/dylanebert/iso3d/resolve/main/jpg@512/a_hat.jpg",
"https://huggingface.co/datasets/dylanebert/iso3d/resolve/main/jpg@512/an_antique_chest.jpg",
"https://huggingface.co/datasets/dylanebert/iso3d/resolve/main/jpg@512/metal.jpg",
],
inputs=[input_image],
outputs=[output_splat],
fn=lambda x: run(input_image=x, seed=42),
cache_examples=True,
label="Image-to-3D Examples",
)
block.queue().launch(debug=True, share=True)
|