Spaces:
Running
on
Zero
Running
on
Zero
Working now
Browse files- app.py +5 -24
- freesplatter/webui/runner.py +17 -12
- freesplatter/webui/tab_img_to_3d.py +4 -10
- open3d_zerogpu_fix.py +7 -0
app.py
CHANGED
@@ -1,3 +1,4 @@
|
|
|
|
1 |
import os
|
2 |
if 'OMP_NUM_THREADS' not in os.environ:
|
3 |
os.environ['OMP_NUM_THREADS'] = '16'
|
@@ -12,31 +13,14 @@ from freesplatter.webui.runner import FreeSplatterRunner
|
|
12 |
from freesplatter.webui.tab_img_to_3d import create_interface_img_to_3d
|
13 |
|
14 |
|
15 |
-
def install_cuda_toolkit():
|
16 |
-
CUDA_TOOLKIT_URL = "https://developer.download.nvidia.com/compute/cuda/12.1.0/local_installers/cuda_12.1.0_530.30.02_linux.run"
|
17 |
-
CUDA_TOOLKIT_FILE = "/tmp/%s" % os.path.basename(CUDA_TOOLKIT_URL)
|
18 |
-
subprocess.call(["wget", "-q", CUDA_TOOLKIT_URL, "-O", CUDA_TOOLKIT_FILE])
|
19 |
-
subprocess.call(["chmod", "+x", CUDA_TOOLKIT_FILE])
|
20 |
-
subprocess.call([CUDA_TOOLKIT_FILE, "--silent", "--toolkit"])
|
21 |
-
|
22 |
-
os.environ["CUDA_HOME"] = "/usr/local/cuda"
|
23 |
-
os.environ["PATH"] = "%s/bin:%s" % (os.environ["CUDA_HOME"], os.environ["PATH"])
|
24 |
-
os.environ["LD_LIBRARY_PATH"] = "%s/lib:%s" % (
|
25 |
-
os.environ["CUDA_HOME"],
|
26 |
-
"" if "LD_LIBRARY_PATH" not in os.environ else os.environ["LD_LIBRARY_PATH"],
|
27 |
-
)
|
28 |
-
# Fix: arch_list[-1] += '+PTX'; IndexError: list index out of range
|
29 |
-
os.environ["TORCH_CUDA_ARCH_LIST"] = "8.0;8.6"
|
30 |
-
|
31 |
-
install_cuda_toolkit()
|
32 |
-
|
33 |
-
|
34 |
torch.set_grad_enabled(False)
|
35 |
device = torch.device('cuda')
|
36 |
runner = FreeSplatterRunner(device)
|
37 |
|
38 |
-
|
39 |
-
|
|
|
|
|
40 |
|
41 |
|
42 |
_HEADER_ = '''
|
@@ -86,17 +70,14 @@ with gr.Blocks(analytics_enabled=False, title='FreeSplatter Demo') as demo:
|
|
86 |
with gr.Tabs() as sub_tabs_img_to_3d:
|
87 |
with gr.TabItem('Hunyuan3D Std', id='tab_hunyuan3d_std'):
|
88 |
_, var_img_to_3d_hunyuan3d_std = create_interface_img_to_3d(
|
89 |
-
run_segmentation,
|
90 |
run_img_to_3d,
|
91 |
model='Hunyuan3D Std')
|
92 |
with gr.TabItem('Zero123++ v1.1', id='tab_zero123plus_v11'):
|
93 |
_, var_img_to_3d_zero123plus_v11 = create_interface_img_to_3d(
|
94 |
-
run_segmentation,
|
95 |
run_img_to_3d,
|
96 |
model='Zero123++ v1.1')
|
97 |
with gr.TabItem('Zero123++ v1.2', id='tab_zero123plus_v12'):
|
98 |
_, var_img_to_3d_zero123plus_v12 = create_interface_img_to_3d(
|
99 |
-
run_segmentation,
|
100 |
run_img_to_3d,
|
101 |
model='Zero123++ v1.2')
|
102 |
|
|
|
1 |
+
import open3d_zerogpu_fix
|
2 |
import os
|
3 |
if 'OMP_NUM_THREADS' not in os.environ:
|
4 |
os.environ['OMP_NUM_THREADS'] = '16'
|
|
|
13 |
from freesplatter.webui.tab_img_to_3d import create_interface_img_to_3d
|
14 |
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
torch.set_grad_enabled(False)
|
17 |
device = torch.device('cuda')
|
18 |
runner = FreeSplatterRunner(device)
|
19 |
|
20 |
+
|
21 |
+
@spaces.GPU(duration=120)
|
22 |
+
def run_img_to_3d(*args):
|
23 |
+
yield from runner.run_img_to_3d(*args, cache_dir=gr.utils.get_upload_folder())
|
24 |
|
25 |
|
26 |
_HEADER_ = '''
|
|
|
70 |
with gr.Tabs() as sub_tabs_img_to_3d:
|
71 |
with gr.TabItem('Hunyuan3D Std', id='tab_hunyuan3d_std'):
|
72 |
_, var_img_to_3d_hunyuan3d_std = create_interface_img_to_3d(
|
|
|
73 |
run_img_to_3d,
|
74 |
model='Hunyuan3D Std')
|
75 |
with gr.TabItem('Zero123++ v1.1', id='tab_zero123plus_v11'):
|
76 |
_, var_img_to_3d_zero123plus_v11 = create_interface_img_to_3d(
|
|
|
77 |
run_img_to_3d,
|
78 |
model='Zero123++ v1.1')
|
79 |
with gr.TabItem('Zero123++ v1.2', id='tab_zero123plus_v12'):
|
80 |
_, var_img_to_3d_zero123plus_v12 = create_interface_img_to_3d(
|
|
|
81 |
run_img_to_3d,
|
82 |
model='Zero123++ v1.2')
|
83 |
|
freesplatter/webui/runner.py
CHANGED
@@ -156,8 +156,6 @@ class FreeSplatterRunner:
|
|
156 |
image,
|
157 |
do_rembg=True,
|
158 |
):
|
159 |
-
torch.cuda.empty_cache()
|
160 |
-
|
161 |
if do_rembg:
|
162 |
image = remove_background(image, self.rembg)
|
163 |
|
@@ -165,7 +163,7 @@ class FreeSplatterRunner:
|
|
165 |
|
166 |
def run_img_to_3d(
|
167 |
self,
|
168 |
-
|
169 |
model='Zero123++ v1.2',
|
170 |
diffusion_steps=30,
|
171 |
guidance_scale=4.0,
|
@@ -175,7 +173,10 @@ class FreeSplatterRunner:
|
|
175 |
mesh_reduction=0.5,
|
176 |
cache_dir=None,
|
177 |
):
|
178 |
-
|
|
|
|
|
|
|
179 |
|
180 |
self.output_dir = os.path.join(cache_dir, f'output_{uuid.uuid4()}')
|
181 |
os.makedirs(self.output_dir, exist_ok=True)
|
@@ -224,6 +225,10 @@ class FreeSplatterRunner:
|
|
224 |
images = images[[0, 2, 4, 5, 3, 1]]
|
225 |
alphas = alphas[[0, 2, 4, 5, 3, 1]]
|
226 |
images_vis = v2.functional.to_pil_image(rearrange(images, 'nm c h w -> c h (nm w)'))
|
|
|
|
|
|
|
|
|
227 |
images = v2.functional.resize(images, 512, interpolation=3, antialias=True).clamp(0, 1)
|
228 |
alphas = v2.functional.resize(alphas, 512, interpolation=0, antialias=True).clamp(0, 1)
|
229 |
|
@@ -235,10 +240,11 @@ class FreeSplatterRunner:
|
|
235 |
images, alphas = images[view_indices], alphas[view_indices]
|
236 |
legends = [f'V{i}' if i != 0 else 'Input' for i in view_indices]
|
237 |
|
238 |
-
|
239 |
-
images, alphas, legends=legends, gs_type=gs_type, mesh_reduction=mesh_reduction)
|
|
|
|
|
240 |
|
241 |
-
return images_vis, gs_vis_path, video_path, mesh_fine_path, fig
|
242 |
|
243 |
def run_views_to_3d(
|
244 |
self,
|
@@ -248,7 +254,6 @@ class FreeSplatterRunner:
|
|
248 |
mesh_reduction=0.5,
|
249 |
cache_dir=None,
|
250 |
):
|
251 |
-
torch.cuda.empty_cache()
|
252 |
|
253 |
self.output_dir = os.path.join(cache_dir, f'output_{uuid.uuid4()}')
|
254 |
os.makedirs(self.output_dir, exist_ok=True)
|
@@ -297,7 +302,6 @@ class FreeSplatterRunner:
|
|
297 |
gs_type='2DGS',
|
298 |
mesh_reduction=0.5,
|
299 |
):
|
300 |
-
torch.cuda.empty_cache()
|
301 |
device = self.device
|
302 |
|
303 |
freesplatter = self.freesplatter_2dgs if gs_type == '2DGS' else self.freesplatter
|
@@ -313,11 +317,13 @@ class FreeSplatterRunner:
|
|
313 |
c2ws_pred, focals_pred = freesplatter.estimate_poses(images, gaussians, masks=alphas, use_first_focal=True, pnp_iter=10)
|
314 |
fig = self.visualize_cameras_object(images, c2ws_pred, focals_pred, legends=legends)
|
315 |
t2 = time.time()
|
|
|
316 |
|
317 |
# save gaussians
|
318 |
gs_vis_path = os.path.join(self.output_dir, 'gs_vis.ply')
|
319 |
save_gaussian(gaussians, gs_vis_path, freesplatter, opacity_threshold=5e-3, pad_2dgs_scale=True)
|
320 |
print(f'Save gaussian at {gs_vis_path}')
|
|
|
321 |
|
322 |
# render video
|
323 |
with torch.inference_mode():
|
@@ -336,6 +342,7 @@ class FreeSplatterRunner:
|
|
336 |
save_video(video_frames, video_path, fps=30)
|
337 |
print(f'Save video at {video_path}')
|
338 |
t3 = time.time()
|
|
|
339 |
|
340 |
# extract mesh
|
341 |
with torch.inference_mode():
|
@@ -451,7 +458,7 @@ class FreeSplatterRunner:
|
|
451 |
print(f'Generate mesh: {t4-t3:.2f} seconds.')
|
452 |
print(f'Optimize mesh: {t5-t4:.2f} seconds.')
|
453 |
|
454 |
-
|
455 |
|
456 |
def visualize_cameras_object(
|
457 |
self,
|
@@ -497,7 +504,6 @@ class FreeSplatterRunner:
|
|
497 |
image2,
|
498 |
cache_dir=None,
|
499 |
):
|
500 |
-
torch.cuda.empty_cache()
|
501 |
|
502 |
self.output_dir = os.path.join(cache_dir, f'output_{uuid.uuid4()}')
|
503 |
os.makedirs(self.output_dir, exist_ok=True)
|
@@ -527,7 +533,6 @@ class FreeSplatterRunner:
|
|
527 |
images,
|
528 |
legends=None,
|
529 |
):
|
530 |
-
torch.cuda.empty_cache()
|
531 |
|
532 |
freesplatter = self.freesplatter_scene
|
533 |
|
|
|
156 |
image,
|
157 |
do_rembg=True,
|
158 |
):
|
|
|
|
|
159 |
if do_rembg:
|
160 |
image = remove_background(image, self.rembg)
|
161 |
|
|
|
163 |
|
164 |
def run_img_to_3d(
|
165 |
self,
|
166 |
+
image,
|
167 |
model='Zero123++ v1.2',
|
168 |
diffusion_steps=30,
|
169 |
guidance_scale=4.0,
|
|
|
173 |
mesh_reduction=0.5,
|
174 |
cache_dir=None,
|
175 |
):
|
176 |
+
image_rgba = self.run_segmentation(image)
|
177 |
+
|
178 |
+
res = [image_rgba]
|
179 |
+
yield res + [None] * (6 - len(res))
|
180 |
|
181 |
self.output_dir = os.path.join(cache_dir, f'output_{uuid.uuid4()}')
|
182 |
os.makedirs(self.output_dir, exist_ok=True)
|
|
|
225 |
images = images[[0, 2, 4, 5, 3, 1]]
|
226 |
alphas = alphas[[0, 2, 4, 5, 3, 1]]
|
227 |
images_vis = v2.functional.to_pil_image(rearrange(images, 'nm c h w -> c h (nm w)'))
|
228 |
+
|
229 |
+
res += [images_vis]
|
230 |
+
yield res + [None] * (6 - len(res))
|
231 |
+
|
232 |
images = v2.functional.resize(images, 512, interpolation=3, antialias=True).clamp(0, 1)
|
233 |
alphas = v2.functional.resize(alphas, 512, interpolation=0, antialias=True).clamp(0, 1)
|
234 |
|
|
|
240 |
images, alphas = images[view_indices], alphas[view_indices]
|
241 |
legends = [f'V{i}' if i != 0 else 'Input' for i in view_indices]
|
242 |
|
243 |
+
for item in self.run_freesplatter_object(
|
244 |
+
images, alphas, legends=legends, gs_type=gs_type, mesh_reduction=mesh_reduction):
|
245 |
+
res += [item]
|
246 |
+
yield res + [None] * (6 - len(res))
|
247 |
|
|
|
248 |
|
249 |
def run_views_to_3d(
|
250 |
self,
|
|
|
254 |
mesh_reduction=0.5,
|
255 |
cache_dir=None,
|
256 |
):
|
|
|
257 |
|
258 |
self.output_dir = os.path.join(cache_dir, f'output_{uuid.uuid4()}')
|
259 |
os.makedirs(self.output_dir, exist_ok=True)
|
|
|
302 |
gs_type='2DGS',
|
303 |
mesh_reduction=0.5,
|
304 |
):
|
|
|
305 |
device = self.device
|
306 |
|
307 |
freesplatter = self.freesplatter_2dgs if gs_type == '2DGS' else self.freesplatter
|
|
|
317 |
c2ws_pred, focals_pred = freesplatter.estimate_poses(images, gaussians, masks=alphas, use_first_focal=True, pnp_iter=10)
|
318 |
fig = self.visualize_cameras_object(images, c2ws_pred, focals_pred, legends=legends)
|
319 |
t2 = time.time()
|
320 |
+
yield fig
|
321 |
|
322 |
# save gaussians
|
323 |
gs_vis_path = os.path.join(self.output_dir, 'gs_vis.ply')
|
324 |
save_gaussian(gaussians, gs_vis_path, freesplatter, opacity_threshold=5e-3, pad_2dgs_scale=True)
|
325 |
print(f'Save gaussian at {gs_vis_path}')
|
326 |
+
yield gs_vis_path
|
327 |
|
328 |
# render video
|
329 |
with torch.inference_mode():
|
|
|
342 |
save_video(video_frames, video_path, fps=30)
|
343 |
print(f'Save video at {video_path}')
|
344 |
t3 = time.time()
|
345 |
+
yield video_path
|
346 |
|
347 |
# extract mesh
|
348 |
with torch.inference_mode():
|
|
|
458 |
print(f'Generate mesh: {t4-t3:.2f} seconds.')
|
459 |
print(f'Optimize mesh: {t5-t4:.2f} seconds.')
|
460 |
|
461 |
+
yield mesh_fine_path
|
462 |
|
463 |
def visualize_cameras_object(
|
464 |
self,
|
|
|
504 |
image2,
|
505 |
cache_dir=None,
|
506 |
):
|
|
|
507 |
|
508 |
self.output_dir = os.path.join(cache_dir, f'output_{uuid.uuid4()}')
|
509 |
os.makedirs(self.output_dir, exist_ok=True)
|
|
|
533 |
images,
|
534 |
legends=None,
|
535 |
):
|
|
|
536 |
|
537 |
freesplatter = self.freesplatter_scene
|
538 |
|
freesplatter/webui/tab_img_to_3d.py
CHANGED
@@ -5,7 +5,7 @@ from .gradio_custommodel3d import CustomModel3D
|
|
5 |
from .gradio_customgs import CustomGS
|
6 |
|
7 |
|
8 |
-
def create_interface_img_to_3d(
|
9 |
default_views = {
|
10 |
'Zero123++ v1.1': ['Input', 'V2', 'V3', 'V5'],
|
11 |
'Zero123++ v1.2': ['V1', 'V2', 'V3', 'V5', 'V6'],
|
@@ -137,14 +137,8 @@ def create_interface_img_to_3d(segmentation_api, freesplatter_api, model='Zero12
|
|
137 |
)
|
138 |
|
139 |
var_dict['run_btn'].click(
|
140 |
-
fn=
|
141 |
-
inputs=var_dict['in_image'],
|
142 |
-
outputs=var_dict['fg_image'],
|
143 |
-
concurrency_id='default_group',
|
144 |
-
api_name='run_segmentation',
|
145 |
-
).success(
|
146 |
-
fn=partial(freesplatter_api, cache_dir=interface.GRADIO_CACHE),
|
147 |
-
inputs=[var_dict['fg_image'],
|
148 |
var_dict['model'],
|
149 |
var_dict['diffusion_steps'],
|
150 |
var_dict['guidance_scale'],
|
@@ -152,7 +146,7 @@ def create_interface_img_to_3d(segmentation_api, freesplatter_api, model='Zero12
|
|
152 |
var_dict['view_indices'],
|
153 |
var_dict['gs_type'],
|
154 |
var_dict['mesh_reduction']],
|
155 |
-
outputs=[var_dict['out_multiview'], var_dict['
|
156 |
concurrency_id='default_group',
|
157 |
api_name='run_image_to_3d',
|
158 |
)
|
|
|
5 |
from .gradio_customgs import CustomGS
|
6 |
|
7 |
|
8 |
+
def create_interface_img_to_3d(freesplatter_api, model='Zero123++ v1.2'):
|
9 |
default_views = {
|
10 |
'Zero123++ v1.1': ['Input', 'V2', 'V3', 'V5'],
|
11 |
'Zero123++ v1.2': ['V1', 'V2', 'V3', 'V5', 'V6'],
|
|
|
137 |
)
|
138 |
|
139 |
var_dict['run_btn'].click(
|
140 |
+
fn=freesplatter_api,
|
141 |
+
inputs=[var_dict['in_image'],
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
var_dict['model'],
|
143 |
var_dict['diffusion_steps'],
|
144 |
var_dict['guidance_scale'],
|
|
|
146 |
var_dict['view_indices'],
|
147 |
var_dict['gs_type'],
|
148 |
var_dict['mesh_reduction']],
|
149 |
+
outputs=[var_dict['fg_image'], var_dict['out_multiview'], var_dict['out_pose'], var_dict['out_gs_vis'], var_dict['out_video'], var_dict['out_mesh']],
|
150 |
concurrency_id='default_group',
|
151 |
api_name='run_image_to_3d',
|
152 |
)
|
open3d_zerogpu_fix.py
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import fileinput
|
2 |
+
import site
|
3 |
+
from pathlib import Path
|
4 |
+
|
5 |
+
with fileinput.FileInput(f'{site.getsitepackages()[0]}/open3d/__init__.py', inplace=True) as file:
|
6 |
+
for line in file:
|
7 |
+
print(line.replace('_pybind_cuda.open3d_core_cuda_device_count()', '1'), end='')
|