Spaces:
Sleeping
Sleeping
Commit
·
2eba94f
1
Parent(s):
b37f49c
update code
Browse files- .gitignore +3 -1
- app.py +3 -3
- app_texnet.py +65 -27
- examples/Bunny.obj +0 -321
- model.py +137 -5
- rgb2x/generate_blend.py +142 -0
- rgb2x/gradio_demo_rgb2x.py +157 -0
- rgb2x/load_image.py +119 -0
- rgb2x/pipeline_rgb2x.py +821 -0
- settings.py +2 -2
.gitignore
CHANGED
@@ -1,4 +1,6 @@
|
|
1 |
__pycache__
|
2 |
data
|
3 |
examples
|
4 |
-
.gradio
|
|
|
|
|
|
1 |
__pycache__
|
2 |
data
|
3 |
examples
|
4 |
+
.gradio
|
5 |
+
model_cache
|
6 |
+
output
|
app.py
CHANGED
@@ -28,10 +28,10 @@ with gr.Blocks() as demo:
|
|
28 |
with gr.Tabs():
|
29 |
# with gr.Tab("Canny"):
|
30 |
# create_demo_canny(model.process_canny)
|
31 |
-
with gr.Tab("Texnet"):
|
32 |
-
create_demo_texnet(model.process_texnet)
|
33 |
-
with gr.Tab("Matnet"):
|
34 |
create_demo_texnet(model.process_texnet)
|
|
|
|
|
35 |
|
36 |
with gr.Accordion(label="Base model", open=False):
|
37 |
with gr.Row():
|
|
|
28 |
with gr.Tabs():
|
29 |
# with gr.Tab("Canny"):
|
30 |
# create_demo_canny(model.process_canny)
|
31 |
+
with gr.Tab("Texnet+Matnet"):
|
|
|
|
|
32 |
create_demo_texnet(model.process_texnet)
|
33 |
+
# with gr.Tab("Matnet"):
|
34 |
+
# create_demo_texnet(model.process_texnet)
|
35 |
|
36 |
with gr.Accordion(label="Base model", open=False):
|
37 |
with gr.Row():
|
app_texnet.py
CHANGED
@@ -92,7 +92,11 @@ def create_demo(process):
|
|
92 |
with gr.Blocks() as demo:
|
93 |
with gr.Row():
|
94 |
with gr.Column():
|
95 |
-
|
|
|
|
|
|
|
|
|
96 |
prompt = gr.Textbox(label="Prompt", submit_btn=True)
|
97 |
with gr.Accordion("Advanced options", open=False):
|
98 |
num_samples = gr.Slider(
|
@@ -115,15 +119,25 @@ def create_demo(process):
|
|
115 |
value="longbody, lowres, bad anatomy, bad hands, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality",
|
116 |
)
|
117 |
with gr.Column():
|
118 |
-
|
119 |
-
|
120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
|
122 |
# radio buttons let the user toggle which texture to view
|
123 |
# texture_choice = gr.Radio(["Input", "Coarse", "Fine"], label="Preview texture", value="Input")
|
124 |
# mesh_path_state = gr.State("examples/bunny/mesh.obj")
|
125 |
|
126 |
inputs = [
|
|
|
|
|
127 |
image,
|
128 |
prompt,
|
129 |
a_prompt,
|
@@ -145,47 +159,71 @@ def create_demo(process):
|
|
145 |
).then(
|
146 |
fn=process,
|
147 |
inputs=inputs,
|
148 |
-
outputs=[
|
149 |
api_name="canny",
|
150 |
concurrency_id="main",
|
151 |
)
|
152 |
-
# .then(
|
153 |
-
# fn=show_mesh,
|
154 |
-
# inputs=[texture_choice, mesh_path_state, image, result_coarse, result_fine],
|
155 |
-
# outputs=mesh_viewer,
|
156 |
-
# queue=False,
|
157 |
-
# api_name=False,
|
158 |
-
# )
|
159 |
|
160 |
gr.Examples(
|
161 |
fn=process,
|
162 |
inputs=inputs,
|
163 |
-
outputs=[
|
164 |
examples=[
|
165 |
[
|
|
|
|
|
166 |
"examples/bunny/uv_normal.png", # /dgxusers/Users/jyang/project/ObjectReal/data/control/preprocess/bunny/uv_normal/fused.png
|
167 |
"feather",
|
168 |
-
a_prompt.value,
|
169 |
-
n_prompt.value,
|
170 |
-
num_samples.value,
|
171 |
-
image_resolution.value,
|
172 |
-
num_steps.value,
|
173 |
-
guidance_scale.value,
|
174 |
-
seed.value,
|
175 |
],
|
176 |
[
|
|
|
|
|
177 |
"examples/monkey/uv_normal.png", # /dgxusers/Users/jyang/project/ObjectReal/data/control/preprocess/monkey/uv_normal/fused.png
|
178 |
"wood",
|
179 |
-
a_prompt.value,
|
180 |
-
n_prompt.value,
|
181 |
-
num_samples.value,
|
182 |
-
image_resolution.value,
|
183 |
-
num_steps.value,
|
184 |
-
guidance_scale.value,
|
185 |
-
seed.value,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
],
|
187 |
],
|
188 |
)
|
|
|
189 |
return demo
|
190 |
|
191 |
|
|
|
92 |
with gr.Blocks() as demo:
|
93 |
with gr.Row():
|
94 |
with gr.Column():
|
95 |
+
gr.Markdown("Select from the examples")
|
96 |
+
with gr.Row():
|
97 |
+
name = gr.Textbox(label="Name", interactive=False, visible=False)
|
98 |
+
representative = gr.Image(label="Geometry", interactive=False)
|
99 |
+
image = gr.Image(label="UV Normal", interactive=False)
|
100 |
prompt = gr.Textbox(label="Prompt", submit_btn=True)
|
101 |
with gr.Accordion("Advanced options", open=False):
|
102 |
num_samples = gr.Slider(
|
|
|
119 |
value="longbody, lowres, bad anatomy, bad hands, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality",
|
120 |
)
|
121 |
with gr.Column():
|
122 |
+
# tex_fine = gr.Gallery(label="Output Texture", show_label=True, columns=2, object_fit="scale-down")
|
123 |
+
base_color = gr.Gallery(label="Base Color", show_label=True, columns=1, object_fit="scale-down")
|
124 |
+
normal = gr.Gallery(label="Normal Map", show_label=True, columns=1, object_fit="scale-down")
|
125 |
+
roughness = gr.Gallery(label="Roughness Map", show_label=True, columns=1, object_fit="scale-down")
|
126 |
+
metallic = gr.Gallery(label="Metallic Map", show_label=True, columns=1, object_fit="scale-down")
|
127 |
+
# base_color = gr.Image(label="Base Color", show_label=True, object_fit="scale-down")
|
128 |
+
# normal = gr.Image(label="Normal Map", show_label=True, object_fit="scale-down")
|
129 |
+
# roughness = gr.Image(label="Roughness Map", show_label=True, object_fit="scale-down")
|
130 |
+
# metallic = gr.Image(label="Metallic Map", show_label=True, object_fit="scale-down")
|
131 |
+
|
132 |
+
out_blender_path = gr.File(label="Generated Blender File", file_types=[".blend"])
|
133 |
|
134 |
# radio buttons let the user toggle which texture to view
|
135 |
# texture_choice = gr.Radio(["Input", "Coarse", "Fine"], label="Preview texture", value="Input")
|
136 |
# mesh_path_state = gr.State("examples/bunny/mesh.obj")
|
137 |
|
138 |
inputs = [
|
139 |
+
name, # Name of the object
|
140 |
+
representative, # Geometry mesh
|
141 |
image,
|
142 |
prompt,
|
143 |
a_prompt,
|
|
|
159 |
).then(
|
160 |
fn=process,
|
161 |
inputs=inputs,
|
162 |
+
outputs=[base_color, normal, roughness, metallic, out_blender_path],
|
163 |
api_name="canny",
|
164 |
concurrency_id="main",
|
165 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
|
167 |
gr.Examples(
|
168 |
fn=process,
|
169 |
inputs=inputs,
|
170 |
+
outputs=[base_color, normal, roughness, metallic],
|
171 |
examples=[
|
172 |
[
|
173 |
+
"bunny",
|
174 |
+
"examples/bunny/frame_0001.png", # /dgxusers/Users/jyang/project/ObjectReal/data/control/preprocess/bunny/uv_normal/fused.png
|
175 |
"examples/bunny/uv_normal.png", # /dgxusers/Users/jyang/project/ObjectReal/data/control/preprocess/bunny/uv_normal/fused.png
|
176 |
"feather",
|
177 |
+
# a_prompt.value,
|
178 |
+
# n_prompt.value,
|
179 |
+
# num_samples.value,
|
180 |
+
# image_resolution.value,
|
181 |
+
# num_steps.value,
|
182 |
+
# guidance_scale.value,
|
183 |
+
# seed.value,
|
184 |
],
|
185 |
[
|
186 |
+
"monkey",
|
187 |
+
"examples/monkey/frame_0001.png", # /dgxusers/Users/jyang/project/ObjectReal/data/control/preprocess/monkey/uv_normal/fused.png
|
188 |
"examples/monkey/uv_normal.png", # /dgxusers/Users/jyang/project/ObjectReal/data/control/preprocess/monkey/uv_normal/fused.png
|
189 |
"wood",
|
190 |
+
# a_prompt.value,
|
191 |
+
# n_prompt.value,
|
192 |
+
# num_samples.value,
|
193 |
+
# image_resolution.value,
|
194 |
+
# num_steps.value,
|
195 |
+
# guidance_scale.value,
|
196 |
+
# seed.value,
|
197 |
+
],
|
198 |
+
[
|
199 |
+
"tshirt",
|
200 |
+
"examples/tshirt/frame_0001.png", # /dgxusers/Users/jyang/project/ObjectReal/data/control/preprocess/monkey/uv_normal/fused.png
|
201 |
+
"examples/tshirt/uv_normal.png", # /dgxusers/Users/jyang/project/ObjectReal/data/control/preprocess/monkey/uv_normal/fused.png
|
202 |
+
"wood",
|
203 |
+
# a_prompt.value,
|
204 |
+
# n_prompt.value,
|
205 |
+
# num_samples.value,
|
206 |
+
# image_resolution.value,
|
207 |
+
# num_steps.value,
|
208 |
+
# guidance_scale.value,
|
209 |
+
# seed.value,
|
210 |
+
],
|
211 |
+
[
|
212 |
+
"highheel",
|
213 |
+
"examples/highheel/frame_0001.png", # /dgxusers/Users/jyang/project/ObjectReal/data/control/preprocess/monkey/uv_normal/fused.png
|
214 |
+
"examples/highheel/uv_normal.png", # /dgxusers/Users/jyang/project/ObjectReal/data/control/preprocess/monkey/uv_normal/fused.png
|
215 |
+
"wood",
|
216 |
+
# a_prompt.value,
|
217 |
+
# n_prompt.value,
|
218 |
+
# num_samples.value,
|
219 |
+
# image_resolution.value,
|
220 |
+
# num_steps.value,
|
221 |
+
# guidance_scale.value,
|
222 |
+
# seed.value,
|
223 |
],
|
224 |
],
|
225 |
)
|
226 |
+
|
227 |
return demo
|
228 |
|
229 |
|
examples/Bunny.obj
DELETED
@@ -1,321 +0,0 @@
|
|
1 |
-
<!doctype html>
|
2 |
-
<html class="">
|
3 |
-
<head>
|
4 |
-
<meta charset="utf-8" />
|
5 |
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
|
6 |
-
<meta name="description" content="We’re on a journey to advance and democratize artificial intelligence through open source and open science." />
|
7 |
-
<meta property="fb:app_id" content="1321688464574422" />
|
8 |
-
<meta name="twitter:card" content="summary_large_image" />
|
9 |
-
<meta name="twitter:site" content="@huggingface" />
|
10 |
-
<meta name="twitter:image" content="https://cdn-thumbnails.huggingface.co/social-thumbnails/spaces/gradio/model3D.png" />
|
11 |
-
<meta property="og:title" content="files/Bunny.obj · gradio/model3D at main" />
|
12 |
-
<meta property="og:type" content="website" />
|
13 |
-
<meta property="og:url" content="https://huggingface.co/spaces/gradio/model3D/blob/main/files/Bunny.obj" />
|
14 |
-
<meta property="og:image" content="https://cdn-thumbnails.huggingface.co/social-thumbnails/spaces/gradio/model3D.png" />
|
15 |
-
|
16 |
-
<link rel="stylesheet" href="/front/build/kube-98954b7/style.css" />
|
17 |
-
|
18 |
-
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
19 |
-
<link
|
20 |
-
href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:ital,wght@0,200;0,300;0,400;0,600;0,700;1,200;1,300;1,400;1,600;1,700&display=swap"
|
21 |
-
rel="stylesheet"
|
22 |
-
/>
|
23 |
-
<link
|
24 |
-
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600;700&display=swap"
|
25 |
-
rel="stylesheet"
|
26 |
-
/>
|
27 |
-
|
28 |
-
<link
|
29 |
-
rel="preload"
|
30 |
-
href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.12.0/katex.min.css"
|
31 |
-
as="style"
|
32 |
-
onload="this.onload=null;this.rel='stylesheet'"
|
33 |
-
/>
|
34 |
-
<noscript>
|
35 |
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.12.0/katex.min.css" />
|
36 |
-
</noscript>
|
37 |
-
|
38 |
-
<script>const guestTheme = document.cookie.match(/theme=(\w+)/)?.[1]; document.documentElement.classList.toggle('dark', guestTheme === 'dark' || ( (!guestTheme || guestTheme === 'system') && window.matchMedia('(prefers-color-scheme: dark)').matches));</script>
|
39 |
-
<link rel="canonical" href="https://huggingface.co/spaces/gradio/model3D/blob/main/files/Bunny.obj">
|
40 |
-
|
41 |
-
<title>files/Bunny.obj · gradio/model3D at main</title>
|
42 |
-
|
43 |
-
<script
|
44 |
-
defer
|
45 |
-
data-domain="huggingface.co"
|
46 |
-
event-loggedIn="false"
|
47 |
-
src="/js/script.pageview-props.js"
|
48 |
-
></script>
|
49 |
-
<script>
|
50 |
-
window.plausible =
|
51 |
-
window.plausible ||
|
52 |
-
function () {
|
53 |
-
(window.plausible.q = window.plausible.q || []).push(arguments);
|
54 |
-
};
|
55 |
-
</script>
|
56 |
-
<script>
|
57 |
-
window.hubConfig = {"features":{"signupDisabled":false},"sshGitUrl":"[email protected]","moonHttpUrl":"https:\/\/huggingface.co","captchaApiKey":"bd5f2066-93dc-4bdd-a64b-a24646ca3859","captchaDisabledOnSignup":true,"datasetViewerPublicUrl":"https:\/\/datasets-server.huggingface.co","stripePublicKey":"pk_live_x2tdjFXBCvXo2FFmMybezpeM00J6gPCAAc","environment":"production","userAgent":"HuggingFace (production)","spacesIframeDomain":"hf.space","spacesApiUrl":"https:\/\/api.hf.space","docSearchKey":"ece5e02e57300e17d152c08056145326e90c4bff3dd07d7d1ae40cf1c8d39cb6","logoDev":{"apiUrl":"https:\/\/img.logo.dev\/","apiKey":"pk_UHS2HZOeRnaSOdDp7jbd5w"}};
|
58 |
-
</script>
|
59 |
-
<script type="text/javascript" src="https://de5282c3ca0c.edge.sdk.awswaf.com/de5282c3ca0c/526cf06acb0d/challenge.js" defer></script>
|
60 |
-
</head>
|
61 |
-
<body class="flex flex-col min-h-dvh bg-white dark:bg-gray-950 text-black ViewerBlobPage">
|
62 |
-
<div class="flex min-h-dvh flex-col"><div class="SVELTE_HYDRATER contents" data-target="SystemThemeMonitor" data-props="{"isLoggedIn":false}"></div>
|
63 |
-
|
64 |
-
<div class="SVELTE_HYDRATER contents" data-target="MainHeader" data-props="{"classNames":"","isWide":false,"isZh":false,"isPro":false}"><header class="border-b border-gray-100 "><div class="w-full px-4 container flex h-16 items-center"><div class="flex flex-1 items-center"><a class="mr-5 flex flex-none items-center lg:mr-6" href="/"><img alt="Hugging Face's logo" class="w-7 md:mr-2" src="/front/assets/huggingface_logo-noborder.svg">
|
65 |
-
<span class="hidden whitespace-nowrap text-lg font-bold md:block">Hugging Face</span></a>
|
66 |
-
<div class="relative flex-1 lg:max-w-sm mr-2 sm:mr-4 md:mr-3 xl:mr-6"><input autocomplete="off" class="w-full dark:bg-gray-950 pl-8 form-input-alt h-9 pr-3 focus:shadow-xl " name="" placeholder="Search models, datasets, users..." spellcheck="false" type="text" value="">
|
67 |
-
<svg class="absolute left-2.5 text-gray-400 top-1/2 transform -translate-y-1/2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M30 28.59L22.45 21A11 11 0 1 0 21 22.45L28.59 30zM5 14a9 9 0 1 1 9 9a9 9 0 0 1-9-9z" fill="currentColor"></path></svg>
|
68 |
-
</div>
|
69 |
-
<div class="flex flex-none items-center justify-center p-0.5 place-self-stretch lg:hidden"><button class="relative z-40 flex h-6 w-8 items-center justify-center" type="button"><svg width="1em" height="1em" viewBox="0 0 10 10" class="text-xl" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" preserveAspectRatio="xMidYMid meet" fill="currentColor"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.65039 2.9999C1.65039 2.8066 1.80709 2.6499 2.00039 2.6499H8.00039C8.19369 2.6499 8.35039 2.8066 8.35039 2.9999C8.35039 3.1932 8.19369 3.3499 8.00039 3.3499H2.00039C1.80709 3.3499 1.65039 3.1932 1.65039 2.9999ZM1.65039 4.9999C1.65039 4.8066 1.80709 4.6499 2.00039 4.6499H8.00039C8.19369 4.6499 8.35039 4.8066 8.35039 4.9999C8.35039 5.1932 8.19369 5.3499 8.00039 5.3499H2.00039C1.80709 5.3499 1.65039 5.1932 1.65039 4.9999ZM2.00039 6.6499C1.80709 6.6499 1.65039 6.8066 1.65039 6.9999C1.65039 7.1932 1.80709 7.3499 2.00039 7.3499H8.00039C8.19369 7.3499 8.35039 7.1932 8.35039 6.9999C8.35039 6.8066 8.19369 6.6499 8.00039 6.6499H2.00039Z"></path></svg>
|
70 |
-
</button>
|
71 |
-
|
72 |
-
</div></div>
|
73 |
-
<nav aria-label="Main" class="ml-auto hidden lg:block"><ul class="flex items-center gap-x-1 2xl:gap-x-2"><li class="hover:text-indigo-700"><a class="group flex items-center px-2 py-0.5 dark:text-gray-300 dark:hover:text-gray-100" href="/models"><svg class="mr-1.5 text-gray-400 group-hover:text-indigo-500" style="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path class="uim-quaternary" d="M20.23 7.24L12 12L3.77 7.24a1.98 1.98 0 0 1 .7-.71L11 2.76c.62-.35 1.38-.35 2 0l6.53 3.77c.29.173.531.418.7.71z" opacity=".25" fill="currentColor"></path><path class="uim-tertiary" d="M12 12v9.5a2.09 2.09 0 0 1-.91-.21L4.5 17.48a2.003 2.003 0 0 1-1-1.73v-7.5a2.06 2.06 0 0 1 .27-1.01L12 12z" opacity=".5" fill="currentColor"></path><path class="uim-primary" d="M20.5 8.25v7.5a2.003 2.003 0 0 1-1 1.73l-6.62 3.82c-.275.13-.576.198-.88.2V12l8.23-4.76c.175.308.268.656.27 1.01z" fill="currentColor"></path></svg>
|
74 |
-
Models</a>
|
75 |
-
</li><li class="hover:text-red-700"><a class="group flex items-center px-2 py-0.5 dark:text-gray-300 dark:hover:text-gray-100" href="/datasets"><svg class="mr-1.5 text-gray-400 group-hover:text-red-500" style="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 25 25"><ellipse cx="12.5" cy="5" fill="currentColor" fill-opacity="0.25" rx="7.5" ry="2"></ellipse><path d="M12.5 15C16.6421 15 20 14.1046 20 13V20C20 21.1046 16.6421 22 12.5 22C8.35786 22 5 21.1046 5 20V13C5 14.1046 8.35786 15 12.5 15Z" fill="currentColor" opacity="0.5"></path><path d="M12.5 7C16.6421 7 20 6.10457 20 5V11.5C20 12.6046 16.6421 13.5 12.5 13.5C8.35786 13.5 5 12.6046 5 11.5V5C5 6.10457 8.35786 7 12.5 7Z" fill="currentColor" opacity="0.5"></path><path d="M5.23628 12C5.08204 12.1598 5 12.8273 5 13C5 14.1046 8.35786 15 12.5 15C16.6421 15 20 14.1046 20 13C20 12.8273 19.918 12.1598 19.7637 12C18.9311 12.8626 15.9947 13.5 12.5 13.5C9.0053 13.5 6.06886 12.8626 5.23628 12Z" fill="currentColor"></path></svg>
|
76 |
-
Datasets</a>
|
77 |
-
</li><li class="hover:text-blue-700"><a class="group flex items-center px-2 py-0.5 dark:text-gray-300 dark:hover:text-gray-100" href="/spaces"><svg class="mr-1.5 text-gray-400 group-hover:text-blue-500" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" viewBox="0 0 25 25"><path opacity=".5" d="M6.016 14.674v4.31h4.31v-4.31h-4.31ZM14.674 14.674v4.31h4.31v-4.31h-4.31ZM6.016 6.016v4.31h4.31v-4.31h-4.31Z" fill="currentColor"></path><path opacity=".75" fill-rule="evenodd" clip-rule="evenodd" d="M3 4.914C3 3.857 3.857 3 4.914 3h6.514c.884 0 1.628.6 1.848 1.414a5.171 5.171 0 0 1 7.31 7.31c.815.22 1.414.964 1.414 1.848v6.514A1.914 1.914 0 0 1 20.086 22H4.914A1.914 1.914 0 0 1 3 20.086V4.914Zm3.016 1.102v4.31h4.31v-4.31h-4.31Zm0 12.968v-4.31h4.31v4.31h-4.31Zm8.658 0v-4.31h4.31v4.31h-4.31Zm0-10.813a2.155 2.155 0 1 1 4.31 0 2.155 2.155 0 0 1-4.31 0Z" fill="currentColor"></path><path opacity=".25" d="M16.829 6.016a2.155 2.155 0 1 0 0 4.31 2.155 2.155 0 0 0 0-4.31Z" fill="currentColor"></path></svg>
|
78 |
-
Spaces</a>
|
79 |
-
</li><li class="max-xl:hidden relative"><div class="relative ">
|
80 |
-
<button class="group flex items-center px-2 py-0.5 dark:text-gray-300 hover:text-yellow-700 dark:hover:text-gray-100 " type="button">
|
81 |
-
<svg class="mr-1.5 mr-1.5 text-gray-400 text-yellow-500! group-hover:text-yellow-500" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M20.6081 3C21.7684 3 22.8053 3.49196 23.5284 4.38415C23.9756 4.93678 24.4428 5.82749 24.4808 7.16133C24.9674 7.01707 25.4353 6.93643 25.8725 6.93643C26.9833 6.93643 27.9865 7.37587 28.696 8.17411C29.6075 9.19872 30.0124 10.4579 29.8361 11.7177C29.7523 12.3177 29.5581 12.8555 29.2678 13.3534C29.8798 13.8646 30.3306 14.5763 30.5485 15.4322C30.719 16.1032 30.8939 17.5006 29.9808 18.9403C30.0389 19.0342 30.0934 19.1319 30.1442 19.2318C30.6932 20.3074 30.7283 21.5229 30.2439 22.6548C29.5093 24.3704 27.6841 25.7219 24.1397 27.1727C21.9347 28.0753 19.9174 28.6523 19.8994 28.6575C16.9842 29.4379 14.3477 29.8345 12.0653 29.8345C7.87017 29.8345 4.8668 28.508 3.13831 25.8921C0.356375 21.6797 0.754104 17.8269 4.35369 14.1131C6.34591 12.058 7.67023 9.02782 7.94613 8.36275C8.50224 6.39343 9.97271 4.20438 12.4172 4.20438H12.4179C12.6236 4.20438 12.8314 4.2214 13.0364 4.25468C14.107 4.42854 15.0428 5.06476 15.7115 6.02205C16.4331 5.09583 17.134 4.359 17.7682 3.94323C18.7242 3.31737 19.6794 3 20.6081 3ZM20.6081 5.95917C20.2427 5.95917 19.7963 6.1197 19.3039 6.44225C17.7754 7.44319 14.8258 12.6772 13.7458 14.7131C13.3839 15.3952 12.7655 15.6837 12.2086 15.6837C11.1036 15.6837 10.2408 14.5497 12.1076 13.1085C14.9146 10.9402 13.9299 7.39584 12.5898 7.1776C12.5311 7.16799 12.4731 7.16355 12.4172 7.16355C11.1989 7.16355 10.6615 9.33114 10.6615 9.33114C10.6615 9.33114 9.0863 13.4148 6.38031 16.206C3.67434 18.998 3.5346 21.2388 5.50675 24.2246C6.85185 26.2606 9.42666 26.8753 12.0653 26.8753C14.8021 26.8753 17.6077 26.2139 19.1799 25.793C19.2574 25.7723 28.8193 22.984 27.6081 20.6107C27.4046 20.212 27.0693 20.0522 26.6471 20.0522C24.9416 20.0522 21.8393 22.6726 20.5057 22.6726C20.2076 22.6726 19.9976 22.5416 19.9116 22.222C19.3433 20.1173 28.552 19.2325 27.7758 16.1839C27.639 15.6445 27.2677 15.4256 26.746 15.4263C24.4923 15.4263 19.4358 19.5181 18.3759 19.5181C18.2949 19.5181 18.2368 19.4937 18.2053 19.4419C17.6743 18.557 17.9653 17.9394 21.7082 15.6009C25.4511 13.2617 28.0783 11.8545 26.5841 10.1752C26.4121 9.98141 26.1684 9.8956 25.8725 9.8956C23.6001 9.89634 18.2311 14.9403 18.2311 14.9403C18.2311 14.9403 16.7821 16.496 15.9057 16.496C15.7043 16.496 15.533 16.4139 15.4169 16.2112C14.7956 15.1296 21.1879 10.1286 21.5484 8.06535C21.7928 6.66715 21.3771 5.95917 20.6081 5.95917Z" fill="#FF9D00"></path><path d="M5.50686 24.2246C3.53472 21.2387 3.67446 18.9979 6.38043 16.206C9.08641 13.4147 10.6615 9.33111 10.6615 9.33111C10.6615 9.33111 11.2499 6.95933 12.59 7.17757C13.93 7.39581 14.9139 10.9401 12.1069 13.1084C9.29997 15.276 12.6659 16.7489 13.7459 14.713C14.8258 12.6772 17.7747 7.44316 19.304 6.44221C20.8326 5.44128 21.9089 6.00204 21.5484 8.06532C21.188 10.1286 14.795 15.1295 15.4171 16.2118C16.0391 17.2934 18.2312 14.9402 18.2312 14.9402C18.2312 14.9402 25.0907 8.49588 26.5842 10.1752C28.0776 11.8545 25.4512 13.2616 21.7082 15.6008C17.9646 17.9393 17.6744 18.557 18.2054 19.4418C18.7372 20.3266 26.9998 13.1351 27.7759 16.1838C28.5513 19.2324 19.3434 20.1173 19.9117 22.2219C20.48 24.3274 26.3979 18.2382 27.6082 20.6107C28.8193 22.9839 19.2574 25.7722 19.18 25.7929C16.0914 26.62 8.24723 28.3726 5.50686 24.2246Z" fill="#FFD21E"></path></svg>
|
82 |
-
Community
|
83 |
-
</button>
|
84 |
-
|
85 |
-
|
86 |
-
</div>
|
87 |
-
</li><li class="hover:text-yellow-700"><a class="group flex items-center px-2 py-0.5 dark:text-gray-300 dark:hover:text-gray-100" href="/docs"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="mr-1.5 text-gray-400 group-hover:text-yellow-500" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path d="m2.28 3.7-.3.16a.67.67 0 0 0-.34.58v8.73l.01.04.02.07.01.04.03.06.02.04.02.03.04.06.05.05.04.04.06.04.06.04.08.04.08.02h.05l.07.02h.11l.04-.01.07-.02.03-.01.07-.03.22-.12a5.33 5.33 0 0 1 5.15.1.67.67 0 0 0 .66 0 5.33 5.33 0 0 1 5.33 0 .67.67 0 0 0 1-.58V4.36a.67.67 0 0 0-.34-.5l-.3-.17v7.78a.63.63 0 0 1-.87.59 4.9 4.9 0 0 0-4.35.35l-.65.39a.29.29 0 0 1-.15.04.29.29 0 0 1-.16-.04l-.65-.4a4.9 4.9 0 0 0-4.34-.34.63.63 0 0 1-.87-.59V3.7Z" fill="currentColor" class="dark:opacity-40"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M8 3.1a5.99 5.99 0 0 0-5.3-.43.66.66 0 0 0-.42.62v8.18c0 .45.46.76.87.59a4.9 4.9 0 0 1 4.34.35l.65.39c.05.03.1.04.16.04.05 0 .1-.01.15-.04l.65-.4a4.9 4.9 0 0 1 4.35-.34.63.63 0 0 0 .86-.59V3.3a.67.67 0 0 0-.41-.62 5.99 5.99 0 0 0-5.3.43l-.3.17L8 3.1Zm.73 1.87a.43.43 0 1 0-.86 0v5.48a.43.43 0 0 0 .86 0V4.97Z" fill="currentColor" class="opacity-40 dark:opacity-100"></path><path d="M8.73 4.97a.43.43 0 1 0-.86 0v5.48a.43.43 0 1 0 .86 0V4.96Z" fill="currentColor" class="dark:opacity-40"></path></svg>
|
88 |
-
Docs</a>
|
89 |
-
</li><li class="hover:text-black dark:hover:text-white max-2xl:hidden"><a class="group flex items-center px-2 py-0.5 dark:text-gray-300 dark:hover:text-gray-100" href="/enterprise"><svg class="mr-1.5 text-gray-400 group-hover:text-black dark:group-hover:text-white" xmlns="http://www.w3.org/2000/svg" fill="none" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 33 27"><path fill="currentColor" fill-rule="evenodd" d="M13.5.7a8.7 8.7 0 0 0-7.7 5.7L1 20.6c-1 3.1.9 5.7 4.1 5.7h15c3.3 0 6.8-2.6 7.8-5.7l4.6-14.2c1-3.1-.8-5.7-4-5.7h-15Zm1.1 5.7L9.8 20.3h9.8l1-3.1h-5.8l.8-2.5h4.8l1.1-3h-4.8l.8-2.3H23l1-3h-9.5Z" clip-rule="evenodd"></path></svg>
|
90 |
-
Enterprise</a>
|
91 |
-
</li>
|
92 |
-
|
93 |
-
<li><a class="group flex items-center px-2 py-0.5 dark:text-gray-300 dark:hover:text-gray-100" href="/pricing">Pricing
|
94 |
-
</a></li>
|
95 |
-
|
96 |
-
<li><div class="relative group">
|
97 |
-
<button class="px-2 py-0.5 hover:text-gray-500 dark:hover:text-gray-600 flex items-center " type="button">
|
98 |
-
<svg class=" text-gray-500 w-5 group-hover:text-gray-400 dark:text-gray-300 dark:group-hover:text-gray-100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" viewBox="0 0 32 18" preserveAspectRatio="xMidYMid meet"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.4504 3.30221C14.4504 2.836 14.8284 2.45807 15.2946 2.45807H28.4933C28.9595 2.45807 29.3374 2.836 29.3374 3.30221C29.3374 3.76842 28.9595 4.14635 28.4933 4.14635H15.2946C14.8284 4.14635 14.4504 3.76842 14.4504 3.30221Z" fill="currentColor"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M14.4504 9.00002C14.4504 8.53382 14.8284 8.15588 15.2946 8.15588H28.4933C28.9595 8.15588 29.3374 8.53382 29.3374 9.00002C29.3374 9.46623 28.9595 9.84417 28.4933 9.84417H15.2946C14.8284 9.84417 14.4504 9.46623 14.4504 9.00002Z" fill="currentColor"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M14.4504 14.6978C14.4504 14.2316 14.8284 13.8537 15.2946 13.8537H28.4933C28.9595 13.8537 29.3374 14.2316 29.3374 14.6978C29.3374 15.164 28.9595 15.542 28.4933 15.542H15.2946C14.8284 15.542 14.4504 15.164 14.4504 14.6978Z" fill="currentColor"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M1.94549 6.87377C2.27514 6.54411 2.80962 6.54411 3.13928 6.87377L6.23458 9.96907L9.32988 6.87377C9.65954 6.54411 10.194 6.54411 10.5237 6.87377C10.8533 7.20343 10.8533 7.73791 10.5237 8.06756L6.23458 12.3567L1.94549 8.06756C1.61583 7.73791 1.61583 7.20343 1.94549 6.87377Z" fill="currentColor"></path></svg>
|
99 |
-
|
100 |
-
</button>
|
101 |
-
|
102 |
-
|
103 |
-
</div></li>
|
104 |
-
<li><hr class="h-5 w-0.5 border-none bg-gray-100 dark:bg-gray-800"></li>
|
105 |
-
<li><a class="block cursor-pointer whitespace-nowrap px-2 py-0.5 hover:text-gray-500 dark:text-gray-300 dark:hover:text-gray-100" href="/login">Log In
|
106 |
-
</a></li>
|
107 |
-
<li><a class="whitespace-nowrap rounded-full border border-transparent bg-gray-900 px-3 py-1 leading-none text-white hover:border-black hover:bg-white hover:text-black" href="/join">Sign Up
|
108 |
-
</a></li></ul></nav></div></header></div>
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
<div class="SVELTE_HYDRATER contents" data-target="SSOBanner" data-props="{}"></div>
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
<main class="flex flex-1 flex-col"><div class="SVELTE_HYDRATER contents" data-target="SpaceHeader" data-props="{"activeTab":"files","author":{"avatarUrl":"https://cdn-avatars.huggingface.co/v1/production/uploads/1654078732719-61d5c0530435582ab69f8f70.png","fullname":"Gradio","name":"gradio","type":"org","isHf":false,"isHfAdmin":false,"isMod":false,"isEnterprise":false,"followerCount":277},"canDisable":false,"canReadRepoSettings":false,"canWriteRepoSettings":false,"discussionsStats":{"closed":0,"open":0,"total":0},"query":{},"space":{"author":"gradio","colorFrom":"indigo","colorTo":"indigo","cardData":{"title":"model3D","emoji":"🔥","colorFrom":"indigo","colorTo":"indigo","sdk":"gradio","sdk_version":"5.33.0","app_file":"run.py","pinned":false,"hf_oauth":true},"createdAt":"2022-09-16T03:09:19.000Z","emoji":"🔥","discussionsDisabled":false,"duplicationDisabled":false,"id":"gradio/model3D","isLikedByUser":false,"lastModified":"2025-06-05T16:43:09.000Z","likes":14,"pinned":false,"private":false,"gated":false,"repoType":"space","subdomain":"gradio-model3d","sdk":"gradio","sdkVersion":"5.33.0","title":"model3D","runtime":{"stage":"RUNNING","hardware":{"current":"cpu-basic","requested":"cpu-basic"},"storage":null,"gcTimeout":86400,"replicas":{"current":1,"requested":1},"devMode":false,"domains":[{"domain":"gradio-model3d.hf.space","stage":"READY"}],"sha":"f8c461c2c7c95a5f2f43e9622e7c198b34955bdd"},"iframe":{"embedSrc":"https://gradio-model3d.hf.space","src":"https://gradio-model3d.hf.space"},"secrets":[],"variables":[],"sse":{"status":{"url":"https://huggingface.co/api/spaces/gradio/model3D/events"},"liveMetrics":{"url":"https://huggingface.co/api/spaces/gradio/model3D/metrics"}},"linkedModels":[],"linkedDatasets":[{"author":"dylanebert","downloads":3557,"gated":false,"id":"dylanebert/3dgs","lastModified":"2024-03-22T19:15:52.000Z","datasetsServerInfo":{"viewer":"viewer","numRows":611,"libraries":["datasets","dask","mlcroissant"],"formats":["json"],"modalities":["3d","tabular","text"]},"private":false,"repoType":"dataset","likes":8,"isLikedByUser":false}],"linkedCollections":[],"sha":"f8c461c2c7c95a5f2f43e9622e7c198b34955bdd","hasBlockedOids":false,"region":"us","xetEnabled":false},"sessionUuid":"3GQpWe19yQUxrtIs0ZC3W"}">
|
117 |
-
|
118 |
-
<header class="bg-linear-to-t border-b border-gray-100 pt-4 xl:pt-0 from-gray-50-to-white via-white dark:via-gray-950"><div class="container relative flex flex-col xl:flex-row"><h1 class="flex flex-wrap items-center max-md:leading-tight gap-y-1 text-lg xl:flex-none"><a href="/spaces" class="group flex items-center"><svg class="sm:mr-1 false text-gray-400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M7.80914 18.7462V24.1907H13.2536V18.7462H7.80914Z" fill="#FF3270"></path><path d="M18.7458 18.7462V24.1907H24.1903V18.7462H18.7458Z" fill="#861FFF"></path><path d="M7.80914 7.80982V13.2543H13.2536V7.80982H7.80914Z" fill="#097EFF"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M4 6.41775C4 5.08246 5.08246 4 6.41775 4H14.6457C15.7626 4 16.7026 4.75724 16.9802 5.78629C18.1505 4.67902 19.7302 4 21.4685 4C25.0758 4 28.0003 6.92436 28.0003 10.5317C28.0003 12.27 27.3212 13.8497 26.2139 15.02C27.243 15.2977 28.0003 16.2376 28.0003 17.3545V25.5824C28.0003 26.9177 26.9177 28.0003 25.5824 28.0003H17.0635H14.9367H6.41775C5.08246 28.0003 4 26.9177 4 25.5824V15.1587V14.9367V6.41775ZM7.80952 7.80952V13.254H13.254V7.80952H7.80952ZM7.80952 24.1907V18.7462H13.254V24.1907H7.80952ZM18.7462 24.1907V18.7462H24.1907V24.1907H18.7462ZM18.7462 10.5317C18.7462 9.0283 19.9651 7.80952 21.4685 7.80952C22.9719 7.80952 24.1907 9.0283 24.1907 10.5317C24.1907 12.0352 22.9719 13.254 21.4685 13.254C19.9651 13.254 18.7462 12.0352 18.7462 10.5317Z" fill="black"></path><path d="M21.4681 7.80982C19.9647 7.80982 18.7458 9.02861 18.7458 10.5321C18.7458 12.0355 19.9647 13.2543 21.4681 13.2543C22.9715 13.2543 24.1903 12.0355 24.1903 10.5321C24.1903 9.02861 22.9715 7.80982 21.4681 7.80982Z" fill="#FFD702"></path></svg>
|
119 |
-
<span class="mr-2.5 font-semibold text-gray-400 group-hover:text-gray-500 max-sm:hidden">Spaces:</span></a>
|
120 |
-
<hr class="mx-1.5 h-2 translate-y-px rounded-sm border-r dark:border-gray-600 sm:hidden">
|
121 |
-
<div class="group flex flex-none items-center"><div class="relative mr-1 flex items-center">
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
<span class="inline-block "><span class="contents"><a href="/gradio" class="text-gray-400 hover:text-blue-600"><img alt="" class="size-3.5 rounded-sm flex-none" src="https://cdn-avatars.huggingface.co/v1/production/uploads/1654078732719-61d5c0530435582ab69f8f70.png" crossorigin="anonymous"></a></span>
|
126 |
-
</span></div>
|
127 |
-
|
128 |
-
|
129 |
-
<span class="inline-block "><span class="contents"><a href="/gradio" class="text-gray-400 hover:text-blue-600">gradio</a></span>
|
130 |
-
</span>
|
131 |
-
<div class="mx-0.5 text-gray-300">/</div></div>
|
132 |
-
|
133 |
-
<div class="max-w-full xl:flex xl:min-w-0 xl:flex-nowrap xl:items-center xl:gap-x-1"><a class="break-words font-mono font-semibold hover:text-blue-600 text-[1.07rem] xl:truncate" href="/spaces/gradio/model3D">model3D</a>
|
134 |
-
<button class="text-xs mr-3 focus:outline-hidden inline-flex cursor-pointer items-center text-sm mx-0.5 text-gray-600 " title="Copy space name to clipboard" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg>
|
135 |
-
</button></div>
|
136 |
-
<div class="inline-flex items-center overflow-hidden whitespace-nowrap rounded-md border bg-white text-sm leading-none text-gray-500 mr-2"><button class="relative flex items-center overflow-hidden from-red-50 to-transparent dark:from-red-900 px-1.5 py-1 hover:bg-linear-to-t focus:outline-hidden" title="Like"><svg class="left-1.5 absolute" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32" fill="currentColor"><path d="M22.45,6a5.47,5.47,0,0,1,3.91,1.64,5.7,5.7,0,0,1,0,8L16,26.13,5.64,15.64a5.7,5.7,0,0,1,0-8,5.48,5.48,0,0,1,7.82,0L16,10.24l2.53-2.58A5.44,5.44,0,0,1,22.45,6m0-2a7.47,7.47,0,0,0-5.34,2.24L16,7.36,14.89,6.24a7.49,7.49,0,0,0-10.68,0,7.72,7.72,0,0,0,0,10.82L16,29,27.79,17.06a7.72,7.72,0,0,0,0-10.82A7.49,7.49,0,0,0,22.45,4Z"></path></svg>
|
137 |
-
|
138 |
-
|
139 |
-
<span class="ml-4 pl-0.5 ">like</span></button>
|
140 |
-
<button class="focus:outline-hidden flex items-center border-l px-1.5 py-1 text-gray-400 hover:bg-gray-50 focus:bg-gray-100 dark:hover:bg-gray-900 dark:focus:bg-gray-800" title="See users who liked this repository">14</button></div>
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
<span class="inline-block "><span class="contents"><div class="cursor-pointer select-none overflow-hidden font-mono text-xs shrink-0 mr-2 flex items-center rounded-lg border leading-none dark:bg-gray-900
|
151 |
-
border-green-100
|
152 |
-
text-green-700 dark:text-green-500"><div class="inline-flex items-center px-2 py-[0.32rem] dark:bg-gray-900 border-green-100 bg-green-50 hover:bg-green-100/70 hover:text-green-800 dark:hover:text-green-400">
|
153 |
-
<div class="ml-0.5 mr-1.5 inline-block h-1.5 w-1.5 animate-pulse rounded-full bg-green-500"></div>
|
154 |
-
Running
|
155 |
-
</div>
|
156 |
-
</div></span>
|
157 |
-
</span>
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
<div class="sm:hidden"><div class="relative ">
|
166 |
-
<button class="btn px-1 py-1 text-sm translate-y-0 " type="button">
|
167 |
-
|
168 |
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="p-px" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><circle cx="16" cy="7" r="3" fill="currentColor"></circle><circle cx="16" cy="16" r="3" fill="currentColor"></circle><circle cx="16" cy="25" r="3" fill="currentColor"></circle></svg>
|
169 |
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" class="absolute right-[-0.25rem] bottom-[-0.25rem] rounded-xs bg-gray-50 p-px text-[0.85rem] text-gray-500 dark:bg-gray-925" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 12 12"><path fill="currentColor" d="M7.975 3.489a.438.438 0 0 1 0 .618L4.262 7.82a.416.416 0 0 1-.307.126.427.427 0 0 1-.311-.126.438.438 0 0 1 0-.618L7.357 3.49a.438.438 0 0 1 .618 0ZM6.427 8.132 4.88 9.675a2.17 2.17 0 0 1-3.09 0 2.188 2.188 0 0 1 0-3.09l1.542-1.548a.437.437 0 0 0-.618-.619L1.166 5.966a3.063 3.063 0 0 0 4.332 4.332L7.046 8.75a.438.438 0 0 0-.619-.618Zm4.026-7.121a3.063 3.063 0 0 0-4.332 0L4.573 2.559a.438.438 0 0 0 .618.618L6.74 1.635a2.171 2.171 0 0 1 3.09 0 2.188 2.188 0 0 1 0 3.09L8.287 6.273a.432.432 0 0 0 0 .618.421.421 0 0 0 .475.097.438.438 0 0 0 .143-.097l1.548-1.548a3.068 3.068 0 0 0 0-4.332Z"></path></svg>
|
170 |
-
|
171 |
-
</button>
|
172 |
-
|
173 |
-
|
174 |
-
</div></div>
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
</h1>
|
179 |
-
|
180 |
-
|
181 |
-
<div class="flex flex-col-reverse gap-x-2 sm:flex-row sm:items-center sm:justify-between xl:ml-auto"><div class="-mb-px flex h-12 items-center overflow-x-auto overflow-y-hidden sm:h-[3.25rem]">
|
182 |
-
<a class="tab-alternate" href="/spaces/gradio/model3D"><svg class="mr-1.5 text-gray-400 flex-none" style="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path class="uim-quaternary" d="M20.23 7.24L12 12L3.77 7.24a1.98 1.98 0 0 1 .7-.71L11 2.76c.62-.35 1.38-.35 2 0l6.53 3.77c.29.173.531.418.7.71z" opacity=".25" fill="currentColor"></path><path class="uim-tertiary" d="M12 12v9.5a2.09 2.09 0 0 1-.91-.21L4.5 17.48a2.003 2.003 0 0 1-1-1.73v-7.5a2.06 2.06 0 0 1 .27-1.01L12 12z" opacity=".5" fill="currentColor"></path><path class="uim-primary" d="M20.5 8.25v7.5a2.003 2.003 0 0 1-1 1.73l-6.62 3.82c-.275.13-.576.198-.88.2V12l8.23-4.76c.175.308.268.656.27 1.01z" fill="currentColor"></path></svg>
|
183 |
-
App
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
</a><a class="tab-alternate active" href="/spaces/gradio/model3D/tree/main"><svg class="mr-1.5 text-gray-400 flex-none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path class="uim-tertiary" d="M21 19h-8a1 1 0 0 1 0-2h8a1 1 0 0 1 0 2zm0-4h-8a1 1 0 0 1 0-2h8a1 1 0 0 1 0 2zm0-8h-8a1 1 0 0 1 0-2h8a1 1 0 0 1 0 2zm0 4h-8a1 1 0 0 1 0-2h8a1 1 0 0 1 0 2z" opacity=".5" fill="currentColor"></path><path class="uim-primary" d="M9 19a1 1 0 0 1-1-1V6a1 1 0 0 1 2 0v12a1 1 0 0 1-1 1zm-6-4.333a1 1 0 0 1-.64-1.769L3.438 12l-1.078-.898a1 1 0 0 1 1.28-1.538l2 1.667a1 1 0 0 1 0 1.538l-2 1.667a.999.999 0 0 1-.64.231z" fill="currentColor"></path></svg>
|
188 |
-
<span class="xl:hidden">Files</span>
|
189 |
-
<span class="hidden xl:inline">Files</span>
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
</a><a class="tab-alternate" href="/spaces/gradio/model3D/discussions"><svg class="mr-1.5 text-gray-400 flex-none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M20.6081 3C21.7684 3 22.8053 3.49196 23.5284 4.38415C23.9756 4.93678 24.4428 5.82749 24.4808 7.16133C24.9674 7.01707 25.4353 6.93643 25.8725 6.93643C26.9833 6.93643 27.9865 7.37587 28.696 8.17411C29.6075 9.19872 30.0124 10.4579 29.8361 11.7177C29.7523 12.3177 29.5581 12.8555 29.2678 13.3534C29.8798 13.8646 30.3306 14.5763 30.5485 15.4322C30.719 16.1032 30.8939 17.5006 29.9808 18.9403C30.0389 19.0342 30.0934 19.1319 30.1442 19.2318C30.6932 20.3074 30.7283 21.5229 30.2439 22.6548C29.5093 24.3704 27.6841 25.7219 24.1397 27.1727C21.9347 28.0753 19.9174 28.6523 19.8994 28.6575C16.9842 29.4379 14.3477 29.8345 12.0653 29.8345C7.87017 29.8345 4.8668 28.508 3.13831 25.8921C0.356375 21.6797 0.754104 17.8269 4.35369 14.1131C6.34591 12.058 7.67023 9.02782 7.94613 8.36275C8.50224 6.39343 9.97271 4.20438 12.4172 4.20438H12.4179C12.6236 4.20438 12.8314 4.2214 13.0364 4.25468C14.107 4.42854 15.0428 5.06476 15.7115 6.02205C16.4331 5.09583 17.134 4.359 17.7682 3.94323C18.7242 3.31737 19.6794 3 20.6081 3ZM20.6081 5.95917C20.2427 5.95917 19.7963 6.1197 19.3039 6.44225C17.7754 7.44319 14.8258 12.6772 13.7458 14.7131C13.3839 15.3952 12.7655 15.6837 12.2086 15.6837C11.1036 15.6837 10.2408 14.5497 12.1076 13.1085C14.9146 10.9402 13.9299 7.39584 12.5898 7.1776C12.5311 7.16799 12.4731 7.16355 12.4172 7.16355C11.1989 7.16355 10.6615 9.33114 10.6615 9.33114C10.6615 9.33114 9.0863 13.4148 6.38031 16.206C3.67434 18.998 3.5346 21.2388 5.50675 24.2246C6.85185 26.2606 9.42666 26.8753 12.0653 26.8753C14.8021 26.8753 17.6077 26.2139 19.1799 25.793C19.2574 25.7723 28.8193 22.984 27.6081 20.6107C27.4046 20.212 27.0693 20.0522 26.6471 20.0522C24.9416 20.0522 21.8393 22.6726 20.5057 22.6726C20.2076 22.6726 19.9976 22.5416 19.9116 22.222C19.3433 20.1173 28.552 19.2325 27.7758 16.1839C27.639 15.6445 27.2677 15.4256 26.746 15.4263C24.4923 15.4263 19.4358 19.5181 18.3759 19.5181C18.2949 19.5181 18.2368 19.4937 18.2053 19.4419C17.6743 18.557 17.9653 17.9394 21.7082 15.6009C25.4511 13.2617 28.0783 11.8545 26.5841 10.1752C26.4121 9.98141 26.1684 9.8956 25.8725 9.8956C23.6001 9.89634 18.2311 14.9403 18.2311 14.9403C18.2311 14.9403 16.7821 16.496 15.9057 16.496C15.7043 16.496 15.533 16.4139 15.4169 16.2112C14.7956 15.1296 21.1879 10.1286 21.5484 8.06535C21.7928 6.66715 21.3771 5.95917 20.6081 5.95917Z" fill="#FF9D00"></path><path d="M5.50686 24.2246C3.53472 21.2387 3.67446 18.9979 6.38043 16.206C9.08641 13.4147 10.6615 9.33111 10.6615 9.33111C10.6615 9.33111 11.2499 6.95933 12.59 7.17757C13.93 7.39581 14.9139 10.9401 12.1069 13.1084C9.29997 15.276 12.6659 16.7489 13.7459 14.713C14.8258 12.6772 17.7747 7.44316 19.304 6.44221C20.8326 5.44128 21.9089 6.00204 21.5484 8.06532C21.188 10.1286 14.795 15.1295 15.4171 16.2118C16.0391 17.2934 18.2312 14.9402 18.2312 14.9402C18.2312 14.9402 25.0907 8.49588 26.5842 10.1752C28.0776 11.8545 25.4512 13.2616 21.7082 15.6008C17.9646 17.9393 17.6744 18.557 18.2054 19.4418C18.7372 20.3266 26.9998 13.1351 27.7759 16.1838C28.5513 19.2324 19.3434 20.1173 19.9117 22.2219C20.48 24.3274 26.3979 18.2382 27.6082 20.6107C28.8193 22.9839 19.2574 25.7722 19.18 25.7929C16.0914 26.62 8.24723 28.3726 5.50686 24.2246Z" fill="#FFD21E"></path></svg>
|
194 |
-
Community
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
</a></div>
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
<div class="hidden sm:block mt-2 lg:mt-0"><div class="relative ">
|
203 |
-
<button class="btn px-1 py-1 text-base translate-y-px " type="button">
|
204 |
-
|
205 |
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="p-0.5" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><circle cx="16" cy="7" r="3" fill="currentColor"></circle><circle cx="16" cy="16" r="3" fill="currentColor"></circle><circle cx="16" cy="25" r="3" fill="currentColor"></circle></svg>
|
206 |
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" class="absolute right-[-0.18rem] bottom-[-0.18rem] rounded-xs bg-gray-50 p-px text-[0.85rem] text-gray-500 dark:bg-gray-925" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 12 12"><path fill="currentColor" d="M7.975 3.489a.438.438 0 0 1 0 .618L4.262 7.82a.416.416 0 0 1-.307.126.427.427 0 0 1-.311-.126.438.438 0 0 1 0-.618L7.357 3.49a.438.438 0 0 1 .618 0ZM6.427 8.132 4.88 9.675a2.17 2.17 0 0 1-3.09 0 2.188 2.188 0 0 1 0-3.09l1.542-1.548a.437.437 0 0 0-.618-.619L1.166 5.966a3.063 3.063 0 0 0 4.332 4.332L7.046 8.75a.438.438 0 0 0-.619-.618Zm4.026-7.121a3.063 3.063 0 0 0-4.332 0L4.573 2.559a.438.438 0 0 0 .618.618L6.74 1.635a2.171 2.171 0 0 1 3.09 0 2.188 2.188 0 0 1 0 3.09L8.287 6.273a.432.432 0 0 0 0 .618.421.421 0 0 0 .475.097.438.438 0 0 0 .143-.097l1.548-1.548a3.068 3.068 0 0 0 0-4.332Z"></path></svg>
|
207 |
-
|
208 |
-
</button>
|
209 |
-
|
210 |
-
|
211 |
-
</div></div>
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
</div></div></header>
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
<div class="spinner-overlay fixed inset-0 z-50 flex h-full w-full items-center justify-center overflow-y-auto bg-gray-500 text-white opacity-80 hidden"><svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" fill="none" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>
|
226 |
-
<span>Fetching metadata from the HF Docker repository...</span></div>
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
</div>
|
245 |
-
|
246 |
-
<div class="container relative flex flex-col md:grid md:space-y-0 w-full md:grid-cols-12 space-y-4 md:gap-6 mb-16"><section class="pt-8 border-gray-100 col-span-full"><div class="SVELTE_HYDRATER contents" data-target="ViewerHeader" data-props="{"context":{"repo":{"name":"gradio/model3D","type":"space"},"rev":"main","path":"files/Bunny.obj","subpaths":[{"dir":"files","href":"files"},{"dir":"Bunny.obj"}]},"refs":{"branches":[{"name":"main","ref":"refs/heads/main","targetCommit":"f8c461c2c7c95a5f2f43e9622e7c198b34955bdd"}],"tags":[],"converts":[]},"view":"blob"}"><header class="flex flex-wrap items-center justify-start pb-2 md:justify-end lg:flex-nowrap"><div class="grow max-md:flex max-md:w-full max-md:items-start max-md:justify-between"><div class="relative mr-4 flex min-w-0 basis-auto flex-wrap items-center md:grow md:basis-full lg:basis-auto lg:flex-nowrap"><div class="relative mr-3 mb-2">
|
247 |
-
<button class="text-sm md:text-base btn w-full cursor-pointer text-sm" type="button">
|
248 |
-
<svg class="mr-1.5 text-gray-700 dark:text-gray-400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" style="transform: rotate(360deg);"><path d="M13 14c-3.36 0-4.46 1.35-4.82 2.24C9.25 16.7 10 17.76 10 19a3 3 0 0 1-3 3a3 3 0 0 1-3-3c0-1.31.83-2.42 2-2.83V7.83A2.99 2.99 0 0 1 4 5a3 3 0 0 1 3-3a3 3 0 0 1 3 3c0 1.31-.83 2.42-2 2.83v5.29c.88-.65 2.16-1.12 4-1.12c2.67 0 3.56-1.34 3.85-2.23A3.006 3.006 0 0 1 14 7a3 3 0 0 1 3-3a3 3 0 0 1 3 3c0 1.34-.88 2.5-2.09 2.86C17.65 11.29 16.68 14 13 14m-6 4a1 1 0 0 0-1 1a1 1 0 0 0 1 1a1 1 0 0 0 1-1a1 1 0 0 0-1-1M7 4a1 1 0 0 0-1 1a1 1 0 0 0 1 1a1 1 0 0 0 1-1a1 1 0 0 0-1-1m10 2a1 1 0 0 0-1 1a1 1 0 0 0 1 1a1 1 0 0 0 1-1a1 1 0 0 0-1-1z" fill="currentColor"></path></svg>
|
249 |
-
main
|
250 |
-
<svg class="-mr-1 text-gray-500" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path d="M16.293 9.293L12 13.586L7.707 9.293l-1.414 1.414L12 16.414l5.707-5.707z" fill="currentColor"></path></svg></button>
|
251 |
-
|
252 |
-
|
253 |
-
</div>
|
254 |
-
<div class="relative mb-2 flex flex-wrap items-center"><a class="truncate text-gray-800 hover:underline" href="/spaces/gradio/model3D/tree/main">model3D</a>
|
255 |
-
<span class="mx-1 text-gray-300">/</span>
|
256 |
-
<a class="truncate hover:underline dark:text-gray-300" href="/spaces/gradio/model3D/tree/main/files">files
|
257 |
-
</a>
|
258 |
-
<span class="mx-1 text-gray-300">/</span><span class="dark:text-gray-300">Bunny.obj</span>
|
259 |
-
<button class="text-xs ml-2 focus:outline-hidden inline-flex cursor-pointer items-center text-sm mx-0.5 text-gray-600 " title="Copy path" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg>
|
260 |
-
</button></div></div>
|
261 |
-
</div>
|
262 |
-
|
263 |
-
</header></div>
|
264 |
-
<div class="SVELTE_HYDRATER contents" data-target="LastCommit" data-props="{"commitLast":{"date":"2022-09-16T03:09:22.000Z","subject":"Upload with huggingface_hub","authors":[{"_id":"60d38ae013f774189902f55e","avatar":"https://cdn-avatars.huggingface.co/v1/production/uploads/1624476448363-60d38ae013f774189902f55e.jpeg","isHf":true,"user":"aliabd"}],"commit":{"id":"460c7160324a7d29d7cc8dad72f5f05eb5eb7222","parentIds":["3f136382df6f46623d252f6458b6512244438d68"]},"title":"Upload with huggingface_hub"},"repo":{"name":"gradio/model3D","type":"space"}}"><div class="from-gray-100-to-white bg-linear-to-t flex flex-wrap items-baseline rounded-t-lg border border-b-0 px-3 py-2 dark:border-gray-800"><img class="mr-2.5 mt-0.5 h-4 w-4 self-center rounded-full" alt="aliabd's picture" src="https://cdn-avatars.huggingface.co/v1/production/uploads/1624476448363-60d38ae013f774189902f55e.jpeg">
|
265 |
-
<div class="mr-4 flex flex-none items-center truncate"><a class="hover:underline" href="/aliabd">aliabd
|
266 |
-
</a>
|
267 |
-
<span class="max-w-[175px] truncate border font-semibold leading-snug sm:max-w-xs rounded-md px-1.5 border-yellow-200 bg-yellow-600/10 text-yellow-500 dark:border-yellow-800/60 dark:bg-yellow-800/20 text-xs mt-0.5 ml-1.5" title="Member of the Hugging Face team">HF Staff</span>
|
268 |
-
</div>
|
269 |
-
<div class="mr-4 truncate font-mono text-sm text-gray-500 hover:prose-a:underline"><!-- HTML_TAG_START -->Upload with huggingface_hub<!-- HTML_TAG_END --></div>
|
270 |
-
<a class="rounded-sm border bg-gray-50 px-1.5 text-sm hover:underline dark:border-gray-800 dark:bg-gray-900" href="/spaces/gradio/model3D/commit/460c7160324a7d29d7cc8dad72f5f05eb5eb7222">460c716</a>
|
271 |
-
|
272 |
-
<time class="ml-auto hidden flex-none truncate pl-2 text-gray-500 dark:text-gray-400 lg:block" datetime="2022-09-16T03:09:22" title="Fri, 16 Sep 2022 03:09:22 GMT">over 2 years ago</time></div></div>
|
273 |
-
<div class="relative flex flex-wrap items-center border px-3 py-1.5 text-sm text-gray-800 dark:border-gray-800 dark:bg-gray-900 ">
|
274 |
-
<a class="my-1 mr-4 flex items-center hover:underline " href="/spaces/gradio/model3D/raw/main/files/Bunny.obj"><svg class="mr-1.5" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32" style="transform: rotate(360deg);"><path d="M31 16l-7 7l-1.41-1.41L28.17 16l-5.58-5.59L24 9l7 7z" fill="currentColor"></path><path d="M1 16l7-7l1.41 1.41L3.83 16l5.58 5.59L8 23l-7-7z" fill="currentColor"></path><path d="M12.419 25.484L17.639 6l1.932.518L14.35 26z" fill="currentColor"></path></svg>
|
275 |
-
raw
|
276 |
-
</a><div class="SVELTE_HYDRATER contents" data-target="CopyButton" data-props="{"value":"https://huggingface.co/spaces/gradio/model3D/resolve/main/files/Bunny.obj","style":"blank","label":"Copy download link","classNames":"my-1 mr-4 flex items-center no-underline hover:underline"}"><button class="my-1 mr-4 flex items-center no-underline hover:underline " title="Copy download link" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg>
|
277 |
-
<span class="ml-1.5 ">Copy download link</span></button></div><a class="my-1 mr-4 flex items-center hover:underline " href="/spaces/gradio/model3D/commits/main/files/Bunny.obj"><svg class="mr-1.5" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32" style="transform: rotate(360deg);"><path d="M16 4C9.383 4 4 9.383 4 16s5.383 12 12 12s12-5.383 12-12S22.617 4 16 4zm0 2c5.535 0 10 4.465 10 10s-4.465 10-10 10S6 21.535 6 16S10.465 6 16 6zm-1 2v9h7v-2h-5V8z" fill="currentColor"></path></svg>
|
278 |
-
history
|
279 |
-
</a><a class="my-1 mr-4 flex items-center hover:underline " href="/spaces/gradio/model3D/blame/main/files/Bunny.obj"><svg class="mr-1.5" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32" style="transform: rotate(360deg);"><path d="M16 2a14 14 0 1 0 14 14A14 14 0 0 0 16 2zm0 26a12 12 0 1 1 12-12a12 12 0 0 1-12 12z" fill="currentColor"></path><path d="M11.5 11a2.5 2.5 0 1 0 2.5 2.5a2.48 2.48 0 0 0-2.5-2.5z" fill="currentColor"></path><path d="M20.5 11a2.5 2.5 0 1 0 2.5 2.5a2.48 2.48 0 0 0-2.5-2.5z" fill="currentColor"></path></svg>
|
280 |
-
blame
|
281 |
-
</a><a class="my-1 mr-4 flex items-center hover:underline text-green-600 dark:text-green-500" href="/spaces/gradio/model3D/edit/main/files/Bunny.obj"><svg class="mr-1.5" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M2 26h28v2H2z" fill="currentColor"></path><path d="M25.4 9c.8-.8.8-2 0-2.8l-3.6-3.6c-.8-.8-2-.8-2.8 0l-15 15V24h6.4l15-15zm-5-5L24 7.6l-3 3L17.4 7l3-3zM6 22v-3.6l10-10l3.6 3.6l-10 10H6z" fill="currentColor"></path></svg>
|
282 |
-
contribute
|
283 |
-
</a><a class="my-1 mr-4 flex items-center hover:underline " href="/spaces/gradio/model3D/delete/main/files/Bunny.obj"><svg class="mr-1.5" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M12 12h2v12h-2z" fill="currentColor"></path><path d="M18 12h2v12h-2z" fill="currentColor"></path><path d="M4 6v2h2v20a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8h2V6zm4 22V8h16v20z" fill="currentColor"></path><path d="M12 2h8v2h-8z" fill="currentColor"></path></svg>
|
284 |
-
delete
|
285 |
-
</a>
|
286 |
-
|
287 |
-
<div class="mr-4 flex items-center"><div class="SVELTE_HYDRATER contents" data-target="ScanStatusBadge" data-props="{"classNames":"mr-2","scanStatus":{"status":"safe","protectAiScan":{"status":"unscanned"},"avScan":{"status":"safe"},"pickleImportScan":{"status":"unscanned","pickleImports":[]}},"repo":{"name":"gradio/model3D","type":"space"},"revision":"main","filePath":"files/Bunny.obj","openByDefault":false}"><div class="sm:relative mr-2"><button class="flex h-[1.125rem] select-none items-center gap-0.5 rounded border pl-0.5 pr-0.5 text-xs leading-tight text-gray-400 hover:cursor-pointer text-gray-400 hover:border-gray-200 hover:bg-gray-50 hover:text-gray-500 dark:border-gray-800 dark:hover:bg-gray-800 dark:hover:text-gray-200 "><svg class="flex-none" width="1em" height="1em" viewBox="0 0 22 28" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.3634 10.3639C15.8486 10.8491 15.8486 11.6357 15.3634 12.1209L10.9292 16.5551C10.6058 16.8785 10.0814 16.8785 9.7579 16.5551L7.03051 13.8277C6.54532 13.3425 6.54532 12.5558 7.03051 12.0707C7.51569 11.5855 8.30234 11.5855 8.78752 12.0707L9.7579 13.041C10.0814 13.3645 10.6058 13.3645 10.9292 13.041L13.6064 10.3639C14.0916 9.8787 14.8782 9.8787 15.3634 10.3639Z" fill="currentColor"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M10.6666 27.12C4.93329 25.28 0 19.2267 0 12.7867V6.52001C0 5.40001 0.693334 4.41334 1.73333 4.01334L9.73333 1.01334C10.3333 0.786673 11 0.786673 11.6 1.02667L19.6 4.02667C20.1083 4.21658 20.5465 4.55701 20.8562 5.00252C21.1659 5.44803 21.3324 5.97742 21.3333 6.52001V12.7867C21.3333 19.24 16.4 25.28 10.6666 27.12Z" fill="currentColor" fill-opacity="0.22"></path><path d="M10.0845 1.94967L10.0867 1.94881C10.4587 1.8083 10.8666 1.81036 11.2286 1.95515L11.2387 1.95919L11.2489 1.963L19.2489 4.963L19.25 4.96342C19.5677 5.08211 19.8416 5.29488 20.0351 5.57333C20.2285 5.85151 20.3326 6.18203 20.3333 6.52082C20.3333 6.52113 20.3333 6.52144 20.3333 6.52176L20.3333 12.7867C20.3333 18.6535 15.8922 24.2319 10.6666 26.0652C5.44153 24.2316 1 18.6409 1 12.7867V6.52001C1 5.82357 1.42893 5.20343 2.08883 4.94803L10.0845 1.94967Z" stroke="currentColor" stroke-opacity="0.30" stroke-width="2"></path></svg>
|
288 |
-
|
289 |
-
<span class="mr-0.5 max-sm:hidden">Safe</span></button>
|
290 |
-
|
291 |
-
</div></div>
|
292 |
-
</div>
|
293 |
-
|
294 |
-
<div class="flex items-center gap-x-3 dark:text-gray-300 sm:ml-auto"><div class="SVELTE_HYDRATER contents" data-target="LineWrapButton" data-props="{"classNames":"text-xs","lineSelectorClass":"blob-line"}">
|
295 |
-
|
296 |
-
<button class="text-xs focus:outline-hidden inline-flex cursor-pointer items-center justify-center text-sm mx-0.5 " type="button"><svg class="opacity-40" width="1em" height="1em" viewBox="0 0 12 11" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0.75 1.25H11.25M0.75 5H9C9.75 5 11.25 5.375 11.25 6.875C11.25 8.375 9.99975 8.75 9.375 8.75H6M6 8.75L7.5 7.25M6 8.75L7.5 10.25M0.75 8.75H3.75" stroke="currentColor" stroke-width="1.125" stroke-linecap="round" stroke-linejoin="round"></path></svg></button></div>
|
297 |
-
198 kB</div></div>
|
298 |
-
|
299 |
-
<div class="relative min-h-[100px] rounded-b-lg border border-t-0 leading-tight dark:border-gray-800 dark:bg-gray-925">
|
300 |
-
<div class="SVELTE_HYDRATER contents" data-target="OBJViewer" data-props="{"src":"/spaces/gradio/model3D/resolve/main/files/Bunny.obj","classNames":"h-96 w-full"}"><div class="relative h-96 w-full">
|
301 |
-
<div class="h-full w-full"></div></div></div></div></section></div></main>
|
302 |
-
|
303 |
-
</div>
|
304 |
-
|
305 |
-
<script>
|
306 |
-
import("\/front\/build\/kube-98954b7\/index.js");
|
307 |
-
window.moonSha = "kube-98954b7\/";
|
308 |
-
window.__hf_deferred = {};
|
309 |
-
</script>
|
310 |
-
|
311 |
-
<!-- Stripe -->
|
312 |
-
<script>
|
313 |
-
if (["hf.co", "huggingface.co"].includes(window.location.hostname)) {
|
314 |
-
const script = document.createElement("script");
|
315 |
-
script.src = "https://js.stripe.com/v3/";
|
316 |
-
script.async = true;
|
317 |
-
document.head.appendChild(script);
|
318 |
-
}
|
319 |
-
</script>
|
320 |
-
</body>
|
321 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
model.py
CHANGED
@@ -15,11 +15,19 @@ from diffusers import (
|
|
15 |
StableDiffusionControlNetPipeline,
|
16 |
StableDiffusionImg2ImgPipeline,
|
17 |
UniPCMultistepScheduler,
|
|
|
18 |
)
|
|
|
19 |
from torchvision import transforms
|
20 |
from cv_utils import resize_image
|
21 |
from preprocessor import Preprocessor
|
22 |
from settings import MAX_IMAGE_RESOLUTION, MAX_NUM_IMAGES
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
CONTROLNET_MODEL_IDS = {
|
25 |
# "Openpose": "lllyasviel/control_v11p_sd15_openpose",
|
@@ -154,6 +162,8 @@ class Model:
|
|
154 |
@torch.inference_mode()
|
155 |
def process_texnet(
|
156 |
self,
|
|
|
|
|
157 |
image: np.ndarray,
|
158 |
prompt: str,
|
159 |
additional_prompt: str,
|
@@ -179,7 +189,7 @@ class Model:
|
|
179 |
)
|
180 |
|
181 |
self.load_controlnet_weight("texnet")
|
182 |
-
|
183 |
prompt=self.get_prompt(prompt, additional_prompt),
|
184 |
negative_prompt=negative_prompt,
|
185 |
control_image=control_image,
|
@@ -194,8 +204,8 @@ class Model:
|
|
194 |
self.pipe = self.pipe_base
|
195 |
|
196 |
# refine
|
197 |
-
|
198 |
-
for result_coarse in
|
199 |
# clean up GPU cache
|
200 |
torch.cuda.empty_cache()
|
201 |
gc.collect()
|
@@ -215,12 +225,134 @@ class Model:
|
|
215 |
seed=seed,
|
216 |
)[0]
|
217 |
result_fine = PIL.Image.fromarray(np.where(mask, control_image, result_fine))
|
218 |
-
|
219 |
|
220 |
# restore the original pipe
|
221 |
self.pipe = self.pipe_backup
|
222 |
|
223 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
|
225 |
# @spaces.GPU #[uncomment to use ZeroGPU]
|
226 |
@torch.inference_mode()
|
|
|
15 |
StableDiffusionControlNetPipeline,
|
16 |
StableDiffusionImg2ImgPipeline,
|
17 |
UniPCMultistepScheduler,
|
18 |
+
DDIMScheduler, #rgb2x
|
19 |
)
|
20 |
+
import torchvision
|
21 |
from torchvision import transforms
|
22 |
from cv_utils import resize_image
|
23 |
from preprocessor import Preprocessor
|
24 |
from settings import MAX_IMAGE_RESOLUTION, MAX_NUM_IMAGES
|
25 |
+
from tqdm.auto import tqdm
|
26 |
+
import subprocess
|
27 |
+
|
28 |
+
from rgb2x.pipeline_rgb2x import StableDiffusionAOVMatEstPipeline
|
29 |
+
from app_texnet import image_to_temp_path
|
30 |
+
import os
|
31 |
|
32 |
CONTROLNET_MODEL_IDS = {
|
33 |
# "Openpose": "lllyasviel/control_v11p_sd15_openpose",
|
|
|
162 |
@torch.inference_mode()
|
163 |
def process_texnet(
|
164 |
self,
|
165 |
+
obj_name: str,
|
166 |
+
represented_image: np.ndarray | None, # not used
|
167 |
image: np.ndarray,
|
168 |
prompt: str,
|
169 |
additional_prompt: str,
|
|
|
189 |
)
|
190 |
|
191 |
self.load_controlnet_weight("texnet")
|
192 |
+
tex_coarse = self.run_pipe(
|
193 |
prompt=self.get_prompt(prompt, additional_prompt),
|
194 |
negative_prompt=negative_prompt,
|
195 |
control_image=control_image,
|
|
|
204 |
self.pipe = self.pipe_base
|
205 |
|
206 |
# refine
|
207 |
+
tex_fine = []
|
208 |
+
for result_coarse in tex_coarse:
|
209 |
# clean up GPU cache
|
210 |
torch.cuda.empty_cache()
|
211 |
gc.collect()
|
|
|
225 |
seed=seed,
|
226 |
)[0]
|
227 |
result_fine = PIL.Image.fromarray(np.where(mask, control_image, result_fine))
|
228 |
+
tex_fine.append(result_fine)
|
229 |
|
230 |
# restore the original pipe
|
231 |
self.pipe = self.pipe_backup
|
232 |
|
233 |
+
# use rgb2x for now for generating the texture
|
234 |
+
def rgb2x(
|
235 |
+
pipeline,
|
236 |
+
photo,
|
237 |
+
inference_step = 50,
|
238 |
+
num_samples = 1,
|
239 |
+
):
|
240 |
+
generator = torch.Generator(device="cuda").manual_seed(seed)
|
241 |
+
|
242 |
+
# Check if the width and height are multiples of 8. If not, crop it using torchvision.transforms.CenterCrop
|
243 |
+
old_height = photo.shape[1]
|
244 |
+
old_width = photo.shape[2]
|
245 |
+
new_height = old_height
|
246 |
+
new_width = old_width
|
247 |
+
radio = old_height / old_width
|
248 |
+
max_side = 1000
|
249 |
+
if old_height > old_width:
|
250 |
+
new_height = max_side
|
251 |
+
new_width = int(new_height / radio)
|
252 |
+
else:
|
253 |
+
new_width = max_side
|
254 |
+
new_height = int(new_width * radio)
|
255 |
+
|
256 |
+
if new_width % 8 != 0 or new_height % 8 != 0:
|
257 |
+
new_width = new_width // 8 * 8
|
258 |
+
new_height = new_height // 8 * 8
|
259 |
+
|
260 |
+
photo = torchvision.transforms.Resize((new_height, new_width))(photo)
|
261 |
+
|
262 |
+
required_aovs = ["albedo", "normal", "roughness", "metallic", "irradiance"]
|
263 |
+
prompts = {
|
264 |
+
"albedo": "Albedo (diffuse basecolor)",
|
265 |
+
"normal": "Camera-space Normal",
|
266 |
+
"roughness": "Roughness",
|
267 |
+
"metallic": "Metallicness",
|
268 |
+
"irradiance": "Irradiance (diffuse lighting)",
|
269 |
+
}
|
270 |
+
|
271 |
+
return_list = []
|
272 |
+
for i in tqdm(range(num_samples), desc="Running Pipeline", leave=False):
|
273 |
+
for aov_name in required_aovs:
|
274 |
+
prompt = prompts[aov_name]
|
275 |
+
generated_image = pipeline(
|
276 |
+
prompt=prompt,
|
277 |
+
photo=photo,
|
278 |
+
num_inference_steps=inference_step,
|
279 |
+
height=new_height,
|
280 |
+
width=new_width,
|
281 |
+
generator=generator,
|
282 |
+
required_aovs=[aov_name],
|
283 |
+
).images[0][0]
|
284 |
+
|
285 |
+
generated_image = torchvision.transforms.Resize(
|
286 |
+
(old_height, old_width)
|
287 |
+
)(generated_image)
|
288 |
+
|
289 |
+
# generated_image = (generated_image, f"Generated {aov_name} {i}")
|
290 |
+
# generated_image = (generated_image, f"{aov_name}")
|
291 |
+
return_list.append(generated_image)
|
292 |
+
|
293 |
+
return photo, return_list, prompts
|
294 |
+
|
295 |
+
# Load rgb2x pipeline
|
296 |
+
pipe = StableDiffusionAOVMatEstPipeline.from_pretrained(
|
297 |
+
"zheng95z/rgb-to-x",
|
298 |
+
torch_dtype=torch.float16,
|
299 |
+
# cache_dir=os.path.join(current_directory, "model_cache"),
|
300 |
+
).to(self.pipe.device)
|
301 |
+
pipe.scheduler = DDIMScheduler.from_config(
|
302 |
+
pipe.scheduler.config, rescale_betas_zero_snr=True, timestep_spacing="trailing"
|
303 |
+
)
|
304 |
+
pipe.set_progress_bar_config(disable=True)
|
305 |
+
pipe.to(self.pipe.device)
|
306 |
+
|
307 |
+
_, preds, prompts = rgb2x(pipe, torchvision.transforms.PILToTensor()(tex_fine[0]).to(self.pipe.device), inference_step=num_steps, num_samples=num_images)
|
308 |
+
|
309 |
+
base_color_path = image_to_temp_path(tex_fine[0].rotate(90), "base_color")
|
310 |
+
normal_map_path = image_to_temp_path(preds[0].rotate(90), "normal_map")
|
311 |
+
roughness_path = image_to_temp_path(preds[1].rotate(90), "roughness")
|
312 |
+
metallic_path = image_to_temp_path(preds[2].rotate(90), "metallic")
|
313 |
+
output_blend_path = os.path.join(os.getcwd(), "output", f"{obj_name}.blend") # replace with desired output path
|
314 |
+
os.makedirs(os.path.dirname(output_blend_path), exist_ok=True)
|
315 |
+
|
316 |
+
#
|
317 |
+
def run_blend_generation(
|
318 |
+
blender_path,
|
319 |
+
generate_script_path,
|
320 |
+
obj_path,
|
321 |
+
base_color_path,
|
322 |
+
normal_map_path,
|
323 |
+
roughness_path,
|
324 |
+
metallic_path,
|
325 |
+
output_blend
|
326 |
+
):
|
327 |
+
cmd = [
|
328 |
+
blender_path, "--background", "--python", generate_script_path, "--",
|
329 |
+
obj_path, base_color_path, normal_map_path, roughness_path, metallic_path, output_blend
|
330 |
+
]
|
331 |
+
subprocess.run(cmd, check=True)
|
332 |
+
|
333 |
+
# check if the blender_path exists, if not download
|
334 |
+
blender_path = '/tmp/blender-3.2.2-linux-x64/blender'
|
335 |
+
if not os.path.exists(blender_path):
|
336 |
+
print("Downloading Blender...")
|
337 |
+
subprocess.run(["wget", "https://download.blender.org/release/Blender3.2/blender-3.2.2-linux-x64.tar.xz", "-O", "/tmp/blender-3.2.2-linux-x64.tar.xz"], check=True)
|
338 |
+
subprocess.run(["tar", "-xf", "/tmp/blender-3.2.2-linux-x64.tar.xz", "-C", "/tmp"], check=True)
|
339 |
+
print("Blender downloaded and extracted.")
|
340 |
+
|
341 |
+
run_blend_generation(
|
342 |
+
blender_path=blender_path,
|
343 |
+
generate_script_path="rgb2x/generate_blend.py",
|
344 |
+
obj_path=f"examples/{obj_name}/mesh.obj", # replace with actual mesh path
|
345 |
+
base_color_path=base_color_path,
|
346 |
+
normal_map_path=normal_map_path,
|
347 |
+
roughness_path=roughness_path,
|
348 |
+
metallic_path=metallic_path,
|
349 |
+
output_blend=output_blend_path # replace with desired output path
|
350 |
+
)
|
351 |
+
|
352 |
+
# gallary
|
353 |
+
return [*tex_fine], [preds[1]], [preds[2]], [preds[3]], [output_blend_path]
|
354 |
+
# image
|
355 |
+
# return tex_fine[0], preds[1], preds[2], preds[3], output_blend_path
|
356 |
|
357 |
# @spaces.GPU #[uncomment to use ZeroGPU]
|
358 |
@torch.inference_mode()
|
rgb2x/generate_blend.py
ADDED
@@ -0,0 +1,142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import bpy
|
2 |
+
import sys
|
3 |
+
import os
|
4 |
+
|
5 |
+
def create_tex_node(nodes, img_path, label, color_space, location):
|
6 |
+
img = bpy.data.images.load(img_path)
|
7 |
+
tex = nodes.new(type='ShaderNodeTexImage')
|
8 |
+
tex.image = img
|
9 |
+
tex.label = label
|
10 |
+
tex.location = location
|
11 |
+
tex.image.colorspace_settings.name = color_space
|
12 |
+
return tex
|
13 |
+
|
14 |
+
def setup_environment_lighting(hdri_path):
|
15 |
+
if not bpy.data.worlds:
|
16 |
+
bpy.data.worlds.new(name="World")
|
17 |
+
if bpy.context.scene.world is None:
|
18 |
+
bpy.context.scene.world = bpy.data.worlds[0]
|
19 |
+
world = bpy.context.scene.world
|
20 |
+
|
21 |
+
world.use_nodes = True
|
22 |
+
nodes = world.node_tree.nodes
|
23 |
+
links = world.node_tree.links
|
24 |
+
nodes.clear()
|
25 |
+
|
26 |
+
env_tex = nodes.new(type="ShaderNodeTexEnvironment")
|
27 |
+
env_tex.image = bpy.data.images.load(hdri_path)
|
28 |
+
env_tex.location = (-300, 0)
|
29 |
+
|
30 |
+
bg = nodes.new(type="ShaderNodeBackground")
|
31 |
+
bg.location = (0, 0)
|
32 |
+
|
33 |
+
output = nodes.new(type="ShaderNodeOutputWorld")
|
34 |
+
output.location = (300, 0)
|
35 |
+
|
36 |
+
links.new(env_tex.outputs["Color"], bg.inputs["Color"])
|
37 |
+
links.new(bg.outputs["Background"], output.inputs["Surface"])
|
38 |
+
|
39 |
+
def setup_gpu_rendering():
|
40 |
+
bpy.context.scene.render.engine = 'CYCLES'
|
41 |
+
prefs = bpy.context.preferences
|
42 |
+
cprefs = prefs.addons['cycles'].preferences
|
43 |
+
|
44 |
+
# Choose backend depending on GPU type: 'CUDA', 'OPTIX', 'HIP', 'METAL'
|
45 |
+
cprefs.compute_device_type = 'CUDA'
|
46 |
+
bpy.context.scene.cycles.device = 'GPU'
|
47 |
+
|
48 |
+
def generate_blend(obj_path, base_color_path, normal_map_path, roughness_path, metallic_path, output_blend):
|
49 |
+
# Reset scene
|
50 |
+
bpy.ops.wm.read_factory_settings(use_empty=True)
|
51 |
+
|
52 |
+
# Import OBJ
|
53 |
+
bpy.ops.import_scene.obj(filepath=obj_path)
|
54 |
+
obj = bpy.context.selected_objects[0]
|
55 |
+
|
56 |
+
# Create material
|
57 |
+
mat = bpy.data.materials.new(name="BRDF_Material")
|
58 |
+
mat.use_nodes = True
|
59 |
+
nodes = mat.node_tree.nodes
|
60 |
+
links = mat.node_tree.links
|
61 |
+
nodes.clear()
|
62 |
+
|
63 |
+
output = nodes.new(type='ShaderNodeOutputMaterial')
|
64 |
+
output.location = (400, 0)
|
65 |
+
|
66 |
+
principled = nodes.new(type='ShaderNodeBsdfPrincipled')
|
67 |
+
principled.location = (100, 0)
|
68 |
+
links.new(principled.outputs['BSDF'], output.inputs['Surface'])
|
69 |
+
|
70 |
+
# Base Color
|
71 |
+
base_color = create_tex_node(nodes, base_color_path, "Base Color", 'sRGB', (-600, 200))
|
72 |
+
links.new(base_color.outputs['Color'], principled.inputs['Base Color'])
|
73 |
+
|
74 |
+
# Roughness
|
75 |
+
rough = create_tex_node(nodes, roughness_path, "Roughness", 'Non-Color', (-600, 0))
|
76 |
+
links.new(rough.outputs['Color'], principled.inputs['Roughness'])
|
77 |
+
|
78 |
+
# Metallic
|
79 |
+
metal = create_tex_node(nodes, metallic_path, "Metallic", 'Non-Color', (-600, -200))
|
80 |
+
links.new(metal.outputs['Color'], principled.inputs['Metallic'])
|
81 |
+
|
82 |
+
# Normal Map
|
83 |
+
normal_tex = create_tex_node(nodes, normal_map_path, "Normal Map", 'Non-Color', (-800, -400))
|
84 |
+
normal_map = nodes.new(type='ShaderNodeNormalMap')
|
85 |
+
normal_map.location = (-400, -400)
|
86 |
+
links.new(normal_tex.outputs['Color'], normal_map.inputs['Color'])
|
87 |
+
links.new(normal_map.outputs['Normal'], principled.inputs['Normal'])
|
88 |
+
|
89 |
+
# Assign material
|
90 |
+
if obj.data.materials:
|
91 |
+
obj.data.materials[0] = mat
|
92 |
+
else:
|
93 |
+
obj.data.materials.append(mat)
|
94 |
+
|
95 |
+
# Global Illumination using Blender's default forest HDRI
|
96 |
+
blender_data_path = bpy.utils.resource_path('LOCAL')
|
97 |
+
forest_hdri_path = os.path.join(blender_data_path, "datafiles", "studiolights", "world", "forest.exr")
|
98 |
+
print(f"Using HDRI: {forest_hdri_path}")
|
99 |
+
setup_environment_lighting(forest_hdri_path)
|
100 |
+
|
101 |
+
# GPU rendering setup
|
102 |
+
setup_gpu_rendering()
|
103 |
+
|
104 |
+
# Pack textures into .blend
|
105 |
+
bpy.ops.file.pack_all()
|
106 |
+
|
107 |
+
# Set the 3D View to Rendered mode and focus on object
|
108 |
+
for area in bpy.context.screen.areas:
|
109 |
+
if area.type == 'VIEW_3D':
|
110 |
+
for space in area.spaces:
|
111 |
+
if space.type == 'VIEW_3D':
|
112 |
+
space.shading.type = 'RENDERED' # Set viewport shading to Rendered
|
113 |
+
for region in area.regions:
|
114 |
+
if region.type == 'WINDOW':
|
115 |
+
override = {'area': area, 'region': region, 'scene': bpy.context.scene}
|
116 |
+
bpy.ops.view3d.view_all(override, center=True)
|
117 |
+
|
118 |
+
elif area.type == 'NODE_EDITOR':
|
119 |
+
for space in area.spaces:
|
120 |
+
if space.type == 'NODE_EDITOR':
|
121 |
+
space.tree_type = 'ShaderNodeTree' # Switch to Shader Editor
|
122 |
+
space.shader_type = 'OBJECT'
|
123 |
+
|
124 |
+
# Optional: Switch active workspace to Shading (if it exists)
|
125 |
+
for workspace in bpy.data.workspaces:
|
126 |
+
if workspace.name == 'Shading':
|
127 |
+
bpy.context.window.workspace = workspace
|
128 |
+
break
|
129 |
+
|
130 |
+
# Save the .blend file
|
131 |
+
bpy.ops.wm.save_as_mainfile(filepath=output_blend)
|
132 |
+
print(f"✅ Saved .blend file with BRDF, HDRI, GPU: {output_blend}")
|
133 |
+
|
134 |
+
if __name__ == "__main__":
|
135 |
+
argv = sys.argv
|
136 |
+
argv = argv[argv.index("--") + 1:] # Only use args after "--"
|
137 |
+
|
138 |
+
if len(argv) != 6:
|
139 |
+
print("Usage:\n blender --background --python generate_blend.py -- obj base_color normal roughness metallic output.blend")
|
140 |
+
sys.exit(1)
|
141 |
+
|
142 |
+
generate_blend(*argv)
|
rgb2x/gradio_demo_rgb2x.py
ADDED
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
|
3 |
+
os.environ["OPENCV_IO_ENABLE_OPENEXR"] = "1"
|
4 |
+
|
5 |
+
import gradio as gr
|
6 |
+
import torch
|
7 |
+
import torchvision
|
8 |
+
from diffusers import DDIMScheduler
|
9 |
+
from load_image import load_exr_image, load_ldr_image
|
10 |
+
from pipeline_rgb2x import StableDiffusionAOVMatEstPipeline
|
11 |
+
|
12 |
+
current_directory = os.path.dirname(os.path.abspath(__file__))
|
13 |
+
|
14 |
+
|
15 |
+
def get_rgb2x_demo():
|
16 |
+
# Load pipeline
|
17 |
+
pipe = StableDiffusionAOVMatEstPipeline.from_pretrained(
|
18 |
+
"zheng95z/rgb-to-x",
|
19 |
+
torch_dtype=torch.float16,
|
20 |
+
cache_dir=os.path.join(current_directory, "model_cache"),
|
21 |
+
).to("cuda")
|
22 |
+
pipe.scheduler = DDIMScheduler.from_config(
|
23 |
+
pipe.scheduler.config, rescale_betas_zero_snr=True, timestep_spacing="trailing"
|
24 |
+
)
|
25 |
+
pipe.set_progress_bar_config(disable=True)
|
26 |
+
pipe.to("cuda")
|
27 |
+
|
28 |
+
# Augmentation
|
29 |
+
def callback(
|
30 |
+
photo,
|
31 |
+
seed,
|
32 |
+
inference_step,
|
33 |
+
num_samples,
|
34 |
+
):
|
35 |
+
generator = torch.Generator(device="cuda").manual_seed(seed)
|
36 |
+
|
37 |
+
if photo.name.endswith(".exr"):
|
38 |
+
photo = load_exr_image(photo.name, tonemaping=True, clamp=True).to("cuda")
|
39 |
+
elif (
|
40 |
+
photo.name.endswith(".png")
|
41 |
+
or photo.name.endswith(".jpg")
|
42 |
+
or photo.name.endswith(".jpeg")
|
43 |
+
):
|
44 |
+
photo = load_ldr_image(photo.name, from_srgb=True).to("cuda")
|
45 |
+
|
46 |
+
# Check if the width and height are multiples of 8. If not, crop it using torchvision.transforms.CenterCrop
|
47 |
+
old_height = photo.shape[1]
|
48 |
+
old_width = photo.shape[2]
|
49 |
+
new_height = old_height
|
50 |
+
new_width = old_width
|
51 |
+
radio = old_height / old_width
|
52 |
+
max_side = 1000
|
53 |
+
if old_height > old_width:
|
54 |
+
new_height = max_side
|
55 |
+
new_width = int(new_height / radio)
|
56 |
+
else:
|
57 |
+
new_width = max_side
|
58 |
+
new_height = int(new_width * radio)
|
59 |
+
|
60 |
+
if new_width % 8 != 0 or new_height % 8 != 0:
|
61 |
+
new_width = new_width // 8 * 8
|
62 |
+
new_height = new_height // 8 * 8
|
63 |
+
|
64 |
+
photo = torchvision.transforms.Resize((new_height, new_width))(photo)
|
65 |
+
|
66 |
+
required_aovs = ["albedo", "normal", "roughness", "metallic", "irradiance"]
|
67 |
+
prompts = {
|
68 |
+
"albedo": "Albedo (diffuse basecolor)",
|
69 |
+
"normal": "Camera-space Normal",
|
70 |
+
"roughness": "Roughness",
|
71 |
+
"metallic": "Metallicness",
|
72 |
+
"irradiance": "Irradiance (diffuse lighting)",
|
73 |
+
}
|
74 |
+
|
75 |
+
return_list = []
|
76 |
+
for i in range(num_samples):
|
77 |
+
for aov_name in required_aovs:
|
78 |
+
prompt = prompts[aov_name]
|
79 |
+
generated_image = pipe(
|
80 |
+
prompt=prompt,
|
81 |
+
photo=photo,
|
82 |
+
num_inference_steps=inference_step,
|
83 |
+
height=new_height,
|
84 |
+
width=new_width,
|
85 |
+
generator=generator,
|
86 |
+
required_aovs=[aov_name],
|
87 |
+
).images[0][0]
|
88 |
+
|
89 |
+
generated_image = torchvision.transforms.Resize(
|
90 |
+
(old_height, old_width)
|
91 |
+
)(generated_image)
|
92 |
+
|
93 |
+
generated_image = (generated_image, f"Generated {aov_name} {i}")
|
94 |
+
return_list.append(generated_image)
|
95 |
+
|
96 |
+
return return_list
|
97 |
+
|
98 |
+
block = gr.Blocks()
|
99 |
+
with block:
|
100 |
+
with gr.Row():
|
101 |
+
gr.Markdown("## Model RGB -> X (Realistic image -> Intrinsic channels)")
|
102 |
+
with gr.Row():
|
103 |
+
# Input side
|
104 |
+
with gr.Column():
|
105 |
+
gr.Markdown("### Given Image")
|
106 |
+
photo = gr.File(label="Photo", file_types=[".exr", ".png", ".jpg"])
|
107 |
+
|
108 |
+
gr.Markdown("### Parameters")
|
109 |
+
run_button = gr.Button(value="Run")
|
110 |
+
with gr.Accordion("Advanced options", open=False):
|
111 |
+
seed = gr.Slider(
|
112 |
+
label="Seed",
|
113 |
+
minimum=-1,
|
114 |
+
maximum=2147483647,
|
115 |
+
step=1,
|
116 |
+
randomize=True,
|
117 |
+
)
|
118 |
+
inference_step = gr.Slider(
|
119 |
+
label="Inference Step",
|
120 |
+
minimum=1,
|
121 |
+
maximum=100,
|
122 |
+
step=1,
|
123 |
+
value=50,
|
124 |
+
)
|
125 |
+
num_samples = gr.Slider(
|
126 |
+
label="Samples",
|
127 |
+
minimum=1,
|
128 |
+
maximum=100,
|
129 |
+
step=1,
|
130 |
+
value=1,
|
131 |
+
)
|
132 |
+
|
133 |
+
# Output side
|
134 |
+
with gr.Column():
|
135 |
+
gr.Markdown("### Output Gallery")
|
136 |
+
result_gallery = gr.Gallery(
|
137 |
+
label="Output",
|
138 |
+
show_label=False,
|
139 |
+
elem_id="gallery",
|
140 |
+
columns=2,
|
141 |
+
)
|
142 |
+
|
143 |
+
inputs = [
|
144 |
+
photo,
|
145 |
+
seed,
|
146 |
+
inference_step,
|
147 |
+
num_samples,
|
148 |
+
]
|
149 |
+
run_button.click(fn=callback, inputs=inputs, outputs=result_gallery, queue=True)
|
150 |
+
|
151 |
+
return block
|
152 |
+
|
153 |
+
|
154 |
+
if __name__ == "__main__":
|
155 |
+
demo = get_rgb2x_demo()
|
156 |
+
demo.queue(max_size=1)
|
157 |
+
demo.launch()
|
rgb2x/load_image.py
ADDED
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
|
3 |
+
import cv2
|
4 |
+
import torch
|
5 |
+
|
6 |
+
os.environ["OPENCV_IO_ENABLE_OPENEXR"] = "1"
|
7 |
+
import numpy as np
|
8 |
+
|
9 |
+
|
10 |
+
def convert_rgb_2_XYZ(rgb):
|
11 |
+
# Reference: https://web.archive.org/web/20191027010220/http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
12 |
+
# rgb: (h, w, 3)
|
13 |
+
# XYZ: (h, w, 3)
|
14 |
+
XYZ = torch.ones_like(rgb)
|
15 |
+
XYZ[:, :, 0] = (
|
16 |
+
0.4124564 * rgb[:, :, 0] + 0.3575761 * rgb[:, :, 1] + 0.1804375 * rgb[:, :, 2]
|
17 |
+
)
|
18 |
+
XYZ[:, :, 1] = (
|
19 |
+
0.2126729 * rgb[:, :, 0] + 0.7151522 * rgb[:, :, 1] + 0.0721750 * rgb[:, :, 2]
|
20 |
+
)
|
21 |
+
XYZ[:, :, 2] = (
|
22 |
+
0.0193339 * rgb[:, :, 0] + 0.1191920 * rgb[:, :, 1] + 0.9503041 * rgb[:, :, 2]
|
23 |
+
)
|
24 |
+
return XYZ
|
25 |
+
|
26 |
+
|
27 |
+
def convert_XYZ_2_Yxy(XYZ):
|
28 |
+
# XYZ: (h, w, 3)
|
29 |
+
# Yxy: (h, w, 3)
|
30 |
+
Yxy = torch.ones_like(XYZ)
|
31 |
+
Yxy[:, :, 0] = XYZ[:, :, 1]
|
32 |
+
sum = torch.sum(XYZ, dim=2)
|
33 |
+
inv_sum = 1.0 / torch.clamp(sum, min=1e-4)
|
34 |
+
Yxy[:, :, 1] = XYZ[:, :, 0] * inv_sum
|
35 |
+
Yxy[:, :, 2] = XYZ[:, :, 1] * inv_sum
|
36 |
+
return Yxy
|
37 |
+
|
38 |
+
|
39 |
+
def convert_rgb_2_Yxy(rgb):
|
40 |
+
# rgb: (h, w, 3)
|
41 |
+
# Yxy: (h, w, 3)
|
42 |
+
return convert_XYZ_2_Yxy(convert_rgb_2_XYZ(rgb))
|
43 |
+
|
44 |
+
|
45 |
+
def convert_XYZ_2_rgb(XYZ):
|
46 |
+
# XYZ: (h, w, 3)
|
47 |
+
# rgb: (h, w, 3)
|
48 |
+
rgb = torch.ones_like(XYZ)
|
49 |
+
rgb[:, :, 0] = (
|
50 |
+
3.2404542 * XYZ[:, :, 0] - 1.5371385 * XYZ[:, :, 1] - 0.4985314 * XYZ[:, :, 2]
|
51 |
+
)
|
52 |
+
rgb[:, :, 1] = (
|
53 |
+
-0.9692660 * XYZ[:, :, 0] + 1.8760108 * XYZ[:, :, 1] + 0.0415560 * XYZ[:, :, 2]
|
54 |
+
)
|
55 |
+
rgb[:, :, 2] = (
|
56 |
+
0.0556434 * XYZ[:, :, 0] - 0.2040259 * XYZ[:, :, 1] + 1.0572252 * XYZ[:, :, 2]
|
57 |
+
)
|
58 |
+
return rgb
|
59 |
+
|
60 |
+
|
61 |
+
def convert_Yxy_2_XYZ(Yxy):
|
62 |
+
# Yxy: (h, w, 3)
|
63 |
+
# XYZ: (h, w, 3)
|
64 |
+
XYZ = torch.ones_like(Yxy)
|
65 |
+
XYZ[:, :, 0] = Yxy[:, :, 1] / torch.clamp(Yxy[:, :, 2], min=1e-6) * Yxy[:, :, 0]
|
66 |
+
XYZ[:, :, 1] = Yxy[:, :, 0]
|
67 |
+
XYZ[:, :, 2] = (
|
68 |
+
(1.0 - Yxy[:, :, 1] - Yxy[:, :, 2])
|
69 |
+
/ torch.clamp(Yxy[:, :, 2], min=1e-4)
|
70 |
+
* Yxy[:, :, 0]
|
71 |
+
)
|
72 |
+
return XYZ
|
73 |
+
|
74 |
+
|
75 |
+
def convert_Yxy_2_rgb(Yxy):
|
76 |
+
# Yxy: (h, w, 3)
|
77 |
+
# rgb: (h, w, 3)
|
78 |
+
return convert_XYZ_2_rgb(convert_Yxy_2_XYZ(Yxy))
|
79 |
+
|
80 |
+
|
81 |
+
def load_ldr_image(image_path, from_srgb=False, clamp=False, normalize=False):
|
82 |
+
# Load png or jpg image
|
83 |
+
image = cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_BGR2RGB)
|
84 |
+
image = torch.from_numpy(image.astype(np.float32) / 255.0) # (h, w, c)
|
85 |
+
image[~torch.isfinite(image)] = 0
|
86 |
+
if from_srgb:
|
87 |
+
# Convert from sRGB to linear RGB
|
88 |
+
image = image**2.2
|
89 |
+
if clamp:
|
90 |
+
image = torch.clamp(image, min=0.0, max=1.0)
|
91 |
+
if normalize:
|
92 |
+
# Normalize to [-1, 1]
|
93 |
+
image = image * 2.0 - 1.0
|
94 |
+
image = torch.nn.functional.normalize(image, dim=-1, eps=1e-6)
|
95 |
+
return image.permute(2, 0, 1) # returns (c, h, w)
|
96 |
+
|
97 |
+
|
98 |
+
def load_exr_image(image_path, tonemaping=False, clamp=False, normalize=False):
|
99 |
+
image = cv2.cvtColor(cv2.imread(image_path, -1), cv2.COLOR_BGR2RGB)
|
100 |
+
image = torch.from_numpy(image.astype("float32")) # (h, w, c)
|
101 |
+
image[~torch.isfinite(image)] = 0
|
102 |
+
if tonemaping:
|
103 |
+
# Exposure adjuestment
|
104 |
+
image_Yxy = convert_rgb_2_Yxy(image)
|
105 |
+
lum = (
|
106 |
+
image[:, :, 0:1] * 0.2125
|
107 |
+
+ image[:, :, 1:2] * 0.7154
|
108 |
+
+ image[:, :, 2:3] * 0.0721
|
109 |
+
)
|
110 |
+
lum = torch.log(torch.clamp(lum, min=1e-6))
|
111 |
+
lum_mean = torch.exp(torch.mean(lum))
|
112 |
+
lp = image_Yxy[:, :, 0:1] * 0.18 / torch.clamp(lum_mean, min=1e-6)
|
113 |
+
image_Yxy[:, :, 0:1] = lp
|
114 |
+
image = convert_Yxy_2_rgb(image_Yxy)
|
115 |
+
if clamp:
|
116 |
+
image = torch.clamp(image, min=0.0, max=1.0)
|
117 |
+
if normalize:
|
118 |
+
image = torch.nn.functional.normalize(image, dim=-1, eps=1e-6)
|
119 |
+
return image.permute(2, 0, 1) # returns (c, h, w)
|
rgb2x/pipeline_rgb2x.py
ADDED
@@ -0,0 +1,821 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import inspect
|
2 |
+
from dataclasses import dataclass
|
3 |
+
from typing import Callable, List, Optional, Union
|
4 |
+
|
5 |
+
import numpy as np
|
6 |
+
import PIL
|
7 |
+
import torch
|
8 |
+
from diffusers.configuration_utils import register_to_config
|
9 |
+
from diffusers.image_processor import VaeImageProcessor
|
10 |
+
from diffusers.loaders import (
|
11 |
+
LoraLoaderMixin,
|
12 |
+
TextualInversionLoaderMixin,
|
13 |
+
)
|
14 |
+
from diffusers.models import AutoencoderKL, UNet2DConditionModel
|
15 |
+
from diffusers.pipelines.pipeline_utils import DiffusionPipeline
|
16 |
+
from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion import (
|
17 |
+
rescale_noise_cfg,
|
18 |
+
)
|
19 |
+
from diffusers.schedulers import KarrasDiffusionSchedulers
|
20 |
+
from diffusers.utils import (
|
21 |
+
CONFIG_NAME,
|
22 |
+
BaseOutput,
|
23 |
+
deprecate,
|
24 |
+
logging,
|
25 |
+
)
|
26 |
+
from diffusers.utils.torch_utils import randn_tensor
|
27 |
+
from transformers import CLIPTextModel, CLIPTokenizer
|
28 |
+
|
29 |
+
logger = logging.get_logger(__name__)
|
30 |
+
|
31 |
+
|
32 |
+
class VaeImageProcrssorAOV(VaeImageProcessor):
|
33 |
+
"""
|
34 |
+
Image processor for VAE AOV.
|
35 |
+
|
36 |
+
Args:
|
37 |
+
do_resize (`bool`, *optional*, defaults to `True`):
|
38 |
+
Whether to downscale the image's (height, width) dimensions to multiples of `vae_scale_factor`.
|
39 |
+
vae_scale_factor (`int`, *optional*, defaults to `8`):
|
40 |
+
VAE scale factor. If `do_resize` is `True`, the image is automatically resized to multiples of this factor.
|
41 |
+
resample (`str`, *optional*, defaults to `lanczos`):
|
42 |
+
Resampling filter to use when resizing the image.
|
43 |
+
do_normalize (`bool`, *optional*, defaults to `True`):
|
44 |
+
Whether to normalize the image to [-1,1].
|
45 |
+
"""
|
46 |
+
|
47 |
+
config_name = CONFIG_NAME
|
48 |
+
|
49 |
+
@register_to_config
|
50 |
+
def __init__(
|
51 |
+
self,
|
52 |
+
do_resize: bool = True,
|
53 |
+
vae_scale_factor: int = 8,
|
54 |
+
resample: str = "lanczos",
|
55 |
+
do_normalize: bool = True,
|
56 |
+
):
|
57 |
+
super().__init__()
|
58 |
+
|
59 |
+
def postprocess(
|
60 |
+
self,
|
61 |
+
image: torch.FloatTensor,
|
62 |
+
output_type: str = "pil",
|
63 |
+
do_denormalize: Optional[List[bool]] = None,
|
64 |
+
do_gamma_correction: bool = True,
|
65 |
+
):
|
66 |
+
if not isinstance(image, torch.Tensor):
|
67 |
+
raise ValueError(
|
68 |
+
f"Input for postprocessing is in incorrect format: {type(image)}. We only support pytorch tensor"
|
69 |
+
)
|
70 |
+
if output_type not in ["latent", "pt", "np", "pil"]:
|
71 |
+
deprecation_message = (
|
72 |
+
f"the output_type {output_type} is outdated and has been set to `np`. Please make sure to set it to one of these instead: "
|
73 |
+
"`pil`, `np`, `pt`, `latent`"
|
74 |
+
)
|
75 |
+
deprecate(
|
76 |
+
"Unsupported output_type",
|
77 |
+
"1.0.0",
|
78 |
+
deprecation_message,
|
79 |
+
standard_warn=False,
|
80 |
+
)
|
81 |
+
output_type = "np"
|
82 |
+
|
83 |
+
if output_type == "latent":
|
84 |
+
return image
|
85 |
+
|
86 |
+
if do_denormalize is None:
|
87 |
+
do_denormalize = [self.config.do_normalize] * image.shape[0]
|
88 |
+
|
89 |
+
image = torch.stack(
|
90 |
+
[
|
91 |
+
self.denormalize(image[i]) if do_denormalize[i] else image[i]
|
92 |
+
for i in range(image.shape[0])
|
93 |
+
]
|
94 |
+
)
|
95 |
+
|
96 |
+
# Gamma correction
|
97 |
+
if do_gamma_correction:
|
98 |
+
image = torch.pow(image, 1.0 / 2.2)
|
99 |
+
|
100 |
+
if output_type == "pt":
|
101 |
+
return image
|
102 |
+
|
103 |
+
image = self.pt_to_numpy(image)
|
104 |
+
|
105 |
+
if output_type == "np":
|
106 |
+
return image
|
107 |
+
|
108 |
+
if output_type == "pil":
|
109 |
+
return self.numpy_to_pil(image)
|
110 |
+
|
111 |
+
def preprocess_normal(
|
112 |
+
self,
|
113 |
+
image: Union[torch.FloatTensor, PIL.Image.Image, np.ndarray],
|
114 |
+
height: Optional[int] = None,
|
115 |
+
width: Optional[int] = None,
|
116 |
+
) -> torch.Tensor:
|
117 |
+
image = torch.stack([image], axis=0)
|
118 |
+
return image
|
119 |
+
|
120 |
+
|
121 |
+
@dataclass
|
122 |
+
class StableDiffusionAOVPipelineOutput(BaseOutput):
|
123 |
+
"""
|
124 |
+
Output class for Stable Diffusion AOV pipelines.
|
125 |
+
|
126 |
+
Args:
|
127 |
+
images (`List[PIL.Image.Image]` or `np.ndarray`)
|
128 |
+
List of denoised PIL images of length `batch_size` or NumPy array of shape `(batch_size, height, width,
|
129 |
+
num_channels)`.
|
130 |
+
nsfw_content_detected (`List[bool]`)
|
131 |
+
List indicating whether the corresponding generated image contains "not-safe-for-work" (nsfw) content or
|
132 |
+
`None` if safety checking could not be performed.
|
133 |
+
"""
|
134 |
+
|
135 |
+
images: Union[List[PIL.Image.Image], np.ndarray]
|
136 |
+
|
137 |
+
|
138 |
+
class StableDiffusionAOVMatEstPipeline(
|
139 |
+
DiffusionPipeline, TextualInversionLoaderMixin, LoraLoaderMixin
|
140 |
+
):
|
141 |
+
r"""
|
142 |
+
Pipeline for AOVs.
|
143 |
+
|
144 |
+
This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods
|
145 |
+
implemented for all pipelines (downloading, saving, running on a particular device, etc.).
|
146 |
+
|
147 |
+
The pipeline also inherits the following loading methods:
|
148 |
+
- [`~loaders.TextualInversionLoaderMixin.load_textual_inversion`] for loading textual inversion embeddings
|
149 |
+
- [`~loaders.LoraLoaderMixin.load_lora_weights`] for loading LoRA weights
|
150 |
+
- [`~loaders.LoraLoaderMixin.save_lora_weights`] for saving LoRA weights
|
151 |
+
|
152 |
+
Args:
|
153 |
+
vae ([`AutoencoderKL`]):
|
154 |
+
Variational Auto-Encoder (VAE) model to encode and decode images to and from latent representations.
|
155 |
+
text_encoder ([`~transformers.CLIPTextModel`]):
|
156 |
+
Frozen text-encoder ([clip-vit-large-patch14](https://huggingface.co/openai/clip-vit-large-patch14)).
|
157 |
+
tokenizer ([`~transformers.CLIPTokenizer`]):
|
158 |
+
A `CLIPTokenizer` to tokenize text.
|
159 |
+
unet ([`UNet2DConditionModel`]):
|
160 |
+
A `UNet2DConditionModel` to denoise the encoded image latents.
|
161 |
+
scheduler ([`SchedulerMixin`]):
|
162 |
+
A scheduler to be used in combination with `unet` to denoise the encoded image latents. Can be one of
|
163 |
+
[`DDIMScheduler`], [`LMSDiscreteScheduler`], or [`PNDMScheduler`].
|
164 |
+
"""
|
165 |
+
|
166 |
+
def __init__(
|
167 |
+
self,
|
168 |
+
vae: AutoencoderKL,
|
169 |
+
text_encoder: CLIPTextModel,
|
170 |
+
tokenizer: CLIPTokenizer,
|
171 |
+
unet: UNet2DConditionModel,
|
172 |
+
scheduler: KarrasDiffusionSchedulers,
|
173 |
+
):
|
174 |
+
super().__init__()
|
175 |
+
|
176 |
+
self.register_modules(
|
177 |
+
vae=vae,
|
178 |
+
text_encoder=text_encoder,
|
179 |
+
tokenizer=tokenizer,
|
180 |
+
unet=unet,
|
181 |
+
scheduler=scheduler,
|
182 |
+
)
|
183 |
+
self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1)
|
184 |
+
self.image_processor = VaeImageProcrssorAOV(
|
185 |
+
vae_scale_factor=self.vae_scale_factor
|
186 |
+
)
|
187 |
+
self.register_to_config()
|
188 |
+
|
189 |
+
def _encode_prompt(
|
190 |
+
self,
|
191 |
+
prompt,
|
192 |
+
device,
|
193 |
+
num_images_per_prompt,
|
194 |
+
do_classifier_free_guidance,
|
195 |
+
negative_prompt=None,
|
196 |
+
prompt_embeds: Optional[torch.FloatTensor] = None,
|
197 |
+
negative_prompt_embeds: Optional[torch.FloatTensor] = None,
|
198 |
+
):
|
199 |
+
r"""
|
200 |
+
Encodes the prompt into text encoder hidden states.
|
201 |
+
|
202 |
+
Args:
|
203 |
+
prompt (`str` or `List[str]`, *optional*):
|
204 |
+
prompt to be encoded
|
205 |
+
device: (`torch.device`):
|
206 |
+
torch device
|
207 |
+
num_images_per_prompt (`int`):
|
208 |
+
number of images that should be generated per prompt
|
209 |
+
do_classifier_free_guidance (`bool`):
|
210 |
+
whether to use classifier free guidance or not
|
211 |
+
negative_ prompt (`str` or `List[str]`, *optional*):
|
212 |
+
The prompt or prompts not to guide the image generation. If not defined, one has to pass
|
213 |
+
`negative_prompt_embeds` instead. Ignored when not using guidance (i.e., ignored if `guidance_scale` is
|
214 |
+
less than `1`).
|
215 |
+
prompt_embeds (`torch.FloatTensor`, *optional*):
|
216 |
+
Pre-generated text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting. If not
|
217 |
+
provided, text embeddings will be generated from `prompt` input argument.
|
218 |
+
negative_prompt_embeds (`torch.FloatTensor`, *optional*):
|
219 |
+
Pre-generated negative text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt
|
220 |
+
weighting. If not provided, negative_prompt_embeds will be generated from `negative_prompt` input
|
221 |
+
argument.
|
222 |
+
"""
|
223 |
+
if prompt is not None and isinstance(prompt, str):
|
224 |
+
batch_size = 1
|
225 |
+
elif prompt is not None and isinstance(prompt, list):
|
226 |
+
batch_size = len(prompt)
|
227 |
+
else:
|
228 |
+
batch_size = prompt_embeds.shape[0]
|
229 |
+
|
230 |
+
if prompt_embeds is None:
|
231 |
+
# textual inversion: procecss multi-vector tokens if necessary
|
232 |
+
if isinstance(self, TextualInversionLoaderMixin):
|
233 |
+
prompt = self.maybe_convert_prompt(prompt, self.tokenizer)
|
234 |
+
|
235 |
+
text_inputs = self.tokenizer(
|
236 |
+
prompt,
|
237 |
+
padding="max_length",
|
238 |
+
max_length=self.tokenizer.model_max_length,
|
239 |
+
truncation=True,
|
240 |
+
return_tensors="pt",
|
241 |
+
)
|
242 |
+
text_input_ids = text_inputs.input_ids
|
243 |
+
untruncated_ids = self.tokenizer(
|
244 |
+
prompt, padding="longest", return_tensors="pt"
|
245 |
+
).input_ids
|
246 |
+
|
247 |
+
if untruncated_ids.shape[-1] >= text_input_ids.shape[
|
248 |
+
-1
|
249 |
+
] and not torch.equal(text_input_ids, untruncated_ids):
|
250 |
+
removed_text = self.tokenizer.batch_decode(
|
251 |
+
untruncated_ids[:, self.tokenizer.model_max_length - 1 : -1]
|
252 |
+
)
|
253 |
+
logger.warning(
|
254 |
+
"The following part of your input was truncated because CLIP can only handle sequences up to"
|
255 |
+
f" {self.tokenizer.model_max_length} tokens: {removed_text}"
|
256 |
+
)
|
257 |
+
|
258 |
+
if (
|
259 |
+
hasattr(self.text_encoder.config, "use_attention_mask")
|
260 |
+
and self.text_encoder.config.use_attention_mask
|
261 |
+
):
|
262 |
+
attention_mask = text_inputs.attention_mask.to(device)
|
263 |
+
else:
|
264 |
+
attention_mask = None
|
265 |
+
|
266 |
+
prompt_embeds = self.text_encoder(
|
267 |
+
text_input_ids.to(device),
|
268 |
+
attention_mask=attention_mask,
|
269 |
+
)
|
270 |
+
prompt_embeds = prompt_embeds[0]
|
271 |
+
|
272 |
+
prompt_embeds = prompt_embeds.to(dtype=self.text_encoder.dtype, device=device)
|
273 |
+
|
274 |
+
bs_embed, seq_len, _ = prompt_embeds.shape
|
275 |
+
# duplicate text embeddings for each generation per prompt, using mps friendly method
|
276 |
+
prompt_embeds = prompt_embeds.repeat(1, num_images_per_prompt, 1)
|
277 |
+
prompt_embeds = prompt_embeds.view(
|
278 |
+
bs_embed * num_images_per_prompt, seq_len, -1
|
279 |
+
)
|
280 |
+
|
281 |
+
# get unconditional embeddings for classifier free guidance
|
282 |
+
if do_classifier_free_guidance and negative_prompt_embeds is None:
|
283 |
+
uncond_tokens: List[str]
|
284 |
+
if negative_prompt is None:
|
285 |
+
uncond_tokens = [""] * batch_size
|
286 |
+
elif type(prompt) is not type(negative_prompt):
|
287 |
+
raise TypeError(
|
288 |
+
f"`negative_prompt` should be the same type to `prompt`, but got {type(negative_prompt)} !="
|
289 |
+
f" {type(prompt)}."
|
290 |
+
)
|
291 |
+
elif isinstance(negative_prompt, str):
|
292 |
+
uncond_tokens = [negative_prompt]
|
293 |
+
elif batch_size != len(negative_prompt):
|
294 |
+
raise ValueError(
|
295 |
+
f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:"
|
296 |
+
f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches"
|
297 |
+
" the batch size of `prompt`."
|
298 |
+
)
|
299 |
+
else:
|
300 |
+
uncond_tokens = negative_prompt
|
301 |
+
|
302 |
+
# textual inversion: procecss multi-vector tokens if necessary
|
303 |
+
if isinstance(self, TextualInversionLoaderMixin):
|
304 |
+
uncond_tokens = self.maybe_convert_prompt(uncond_tokens, self.tokenizer)
|
305 |
+
|
306 |
+
max_length = prompt_embeds.shape[1]
|
307 |
+
uncond_input = self.tokenizer(
|
308 |
+
uncond_tokens,
|
309 |
+
padding="max_length",
|
310 |
+
max_length=max_length,
|
311 |
+
truncation=True,
|
312 |
+
return_tensors="pt",
|
313 |
+
)
|
314 |
+
|
315 |
+
if (
|
316 |
+
hasattr(self.text_encoder.config, "use_attention_mask")
|
317 |
+
and self.text_encoder.config.use_attention_mask
|
318 |
+
):
|
319 |
+
attention_mask = uncond_input.attention_mask.to(device)
|
320 |
+
else:
|
321 |
+
attention_mask = None
|
322 |
+
|
323 |
+
negative_prompt_embeds = self.text_encoder(
|
324 |
+
uncond_input.input_ids.to(device),
|
325 |
+
attention_mask=attention_mask,
|
326 |
+
)
|
327 |
+
negative_prompt_embeds = negative_prompt_embeds[0]
|
328 |
+
|
329 |
+
if do_classifier_free_guidance:
|
330 |
+
# duplicate unconditional embeddings for each generation per prompt, using mps friendly method
|
331 |
+
seq_len = negative_prompt_embeds.shape[1]
|
332 |
+
|
333 |
+
negative_prompt_embeds = negative_prompt_embeds.to(
|
334 |
+
dtype=self.text_encoder.dtype, device=device
|
335 |
+
)
|
336 |
+
|
337 |
+
negative_prompt_embeds = negative_prompt_embeds.repeat(
|
338 |
+
1, num_images_per_prompt, 1
|
339 |
+
)
|
340 |
+
negative_prompt_embeds = negative_prompt_embeds.view(
|
341 |
+
batch_size * num_images_per_prompt, seq_len, -1
|
342 |
+
)
|
343 |
+
|
344 |
+
# For classifier free guidance, we need to do two forward passes.
|
345 |
+
# Here we concatenate the unconditional and text embeddings into a single batch
|
346 |
+
# to avoid doing two forward passes
|
347 |
+
# pix2pix has two negative embeddings, and unlike in other pipelines latents are ordered [prompt_embeds, negative_prompt_embeds, negative_prompt_embeds]
|
348 |
+
prompt_embeds = torch.cat(
|
349 |
+
[prompt_embeds, negative_prompt_embeds, negative_prompt_embeds]
|
350 |
+
)
|
351 |
+
|
352 |
+
return prompt_embeds
|
353 |
+
|
354 |
+
def prepare_extra_step_kwargs(self, generator, eta):
|
355 |
+
# prepare extra kwargs for the scheduler step, since not all schedulers have the same signature
|
356 |
+
# eta (η) is only used with the DDIMScheduler, it will be ignored for other schedulers.
|
357 |
+
# eta corresponds to η in DDIM paper: https://arxiv.org/abs/2010.02502
|
358 |
+
# and should be between [0, 1]
|
359 |
+
|
360 |
+
accepts_eta = "eta" in set(
|
361 |
+
inspect.signature(self.scheduler.step).parameters.keys()
|
362 |
+
)
|
363 |
+
extra_step_kwargs = {}
|
364 |
+
if accepts_eta:
|
365 |
+
extra_step_kwargs["eta"] = eta
|
366 |
+
|
367 |
+
# check if the scheduler accepts generator
|
368 |
+
accepts_generator = "generator" in set(
|
369 |
+
inspect.signature(self.scheduler.step).parameters.keys()
|
370 |
+
)
|
371 |
+
if accepts_generator:
|
372 |
+
extra_step_kwargs["generator"] = generator
|
373 |
+
return extra_step_kwargs
|
374 |
+
|
375 |
+
def check_inputs(
|
376 |
+
self,
|
377 |
+
prompt,
|
378 |
+
callback_steps,
|
379 |
+
negative_prompt=None,
|
380 |
+
prompt_embeds=None,
|
381 |
+
negative_prompt_embeds=None,
|
382 |
+
):
|
383 |
+
if (callback_steps is None) or (
|
384 |
+
callback_steps is not None
|
385 |
+
and (not isinstance(callback_steps, int) or callback_steps <= 0)
|
386 |
+
):
|
387 |
+
raise ValueError(
|
388 |
+
f"`callback_steps` has to be a positive integer but is {callback_steps} of type"
|
389 |
+
f" {type(callback_steps)}."
|
390 |
+
)
|
391 |
+
|
392 |
+
if prompt is not None and prompt_embeds is not None:
|
393 |
+
raise ValueError(
|
394 |
+
f"Cannot forward both `prompt`: {prompt} and `prompt_embeds`: {prompt_embeds}. Please make sure to"
|
395 |
+
" only forward one of the two."
|
396 |
+
)
|
397 |
+
elif prompt is None and prompt_embeds is None:
|
398 |
+
raise ValueError(
|
399 |
+
"Provide either `prompt` or `prompt_embeds`. Cannot leave both `prompt` and `prompt_embeds` undefined."
|
400 |
+
)
|
401 |
+
elif prompt is not None and (
|
402 |
+
not isinstance(prompt, str) and not isinstance(prompt, list)
|
403 |
+
):
|
404 |
+
raise ValueError(
|
405 |
+
f"`prompt` has to be of type `str` or `list` but is {type(prompt)}"
|
406 |
+
)
|
407 |
+
|
408 |
+
if negative_prompt is not None and negative_prompt_embeds is not None:
|
409 |
+
raise ValueError(
|
410 |
+
f"Cannot forward both `negative_prompt`: {negative_prompt} and `negative_prompt_embeds`:"
|
411 |
+
f" {negative_prompt_embeds}. Please make sure to only forward one of the two."
|
412 |
+
)
|
413 |
+
|
414 |
+
if prompt_embeds is not None and negative_prompt_embeds is not None:
|
415 |
+
if prompt_embeds.shape != negative_prompt_embeds.shape:
|
416 |
+
raise ValueError(
|
417 |
+
"`prompt_embeds` and `negative_prompt_embeds` must have the same shape when passed directly, but"
|
418 |
+
f" got: `prompt_embeds` {prompt_embeds.shape} != `negative_prompt_embeds`"
|
419 |
+
f" {negative_prompt_embeds.shape}."
|
420 |
+
)
|
421 |
+
|
422 |
+
def prepare_latents(
|
423 |
+
self,
|
424 |
+
batch_size,
|
425 |
+
num_channels_latents,
|
426 |
+
height,
|
427 |
+
width,
|
428 |
+
dtype,
|
429 |
+
device,
|
430 |
+
generator,
|
431 |
+
latents=None,
|
432 |
+
):
|
433 |
+
shape = (
|
434 |
+
batch_size,
|
435 |
+
num_channels_latents,
|
436 |
+
height // self.vae_scale_factor,
|
437 |
+
width // self.vae_scale_factor,
|
438 |
+
)
|
439 |
+
if isinstance(generator, list) and len(generator) != batch_size:
|
440 |
+
raise ValueError(
|
441 |
+
f"You have passed a list of generators of length {len(generator)}, but requested an effective batch"
|
442 |
+
f" size of {batch_size}. Make sure the batch size matches the length of the generators."
|
443 |
+
)
|
444 |
+
|
445 |
+
if latents is None:
|
446 |
+
latents = randn_tensor(
|
447 |
+
shape, generator=generator, device=device, dtype=dtype
|
448 |
+
)
|
449 |
+
else:
|
450 |
+
latents = latents.to(device)
|
451 |
+
|
452 |
+
# scale the initial noise by the standard deviation required by the scheduler
|
453 |
+
latents = latents * self.scheduler.init_noise_sigma
|
454 |
+
return latents
|
455 |
+
|
456 |
+
def prepare_image_latents(
|
457 |
+
self,
|
458 |
+
image,
|
459 |
+
batch_size,
|
460 |
+
num_images_per_prompt,
|
461 |
+
dtype,
|
462 |
+
device,
|
463 |
+
do_classifier_free_guidance,
|
464 |
+
generator=None,
|
465 |
+
):
|
466 |
+
if not isinstance(image, (torch.Tensor, PIL.Image.Image, list)):
|
467 |
+
raise ValueError(
|
468 |
+
f"`image` has to be of type `torch.Tensor`, `PIL.Image.Image` or list but is {type(image)}"
|
469 |
+
)
|
470 |
+
|
471 |
+
image = image.to(device=device, dtype=dtype)
|
472 |
+
|
473 |
+
batch_size = batch_size * num_images_per_prompt
|
474 |
+
|
475 |
+
if image.shape[1] == 4:
|
476 |
+
image_latents = image
|
477 |
+
else:
|
478 |
+
if isinstance(generator, list) and len(generator) != batch_size:
|
479 |
+
raise ValueError(
|
480 |
+
f"You have passed a list of generators of length {len(generator)}, but requested an effective batch"
|
481 |
+
f" size of {batch_size}. Make sure the batch size matches the length of the generators."
|
482 |
+
)
|
483 |
+
|
484 |
+
if isinstance(generator, list):
|
485 |
+
image_latents = [
|
486 |
+
self.vae.encode(image[i : i + 1]).latent_dist.mode()
|
487 |
+
for i in range(batch_size)
|
488 |
+
]
|
489 |
+
image_latents = torch.cat(image_latents, dim=0)
|
490 |
+
else:
|
491 |
+
image_latents = self.vae.encode(image).latent_dist.mode()
|
492 |
+
|
493 |
+
if (
|
494 |
+
batch_size > image_latents.shape[0]
|
495 |
+
and batch_size % image_latents.shape[0] == 0
|
496 |
+
):
|
497 |
+
# expand image_latents for batch_size
|
498 |
+
deprecation_message = (
|
499 |
+
f"You have passed {batch_size} text prompts (`prompt`), but only {image_latents.shape[0]} initial"
|
500 |
+
" images (`image`). Initial images are now duplicating to match the number of text prompts. Note"
|
501 |
+
" that this behavior is deprecated and will be removed in a version 1.0.0. Please make sure to update"
|
502 |
+
" your script to pass as many initial images as text prompts to suppress this warning."
|
503 |
+
)
|
504 |
+
deprecate(
|
505 |
+
"len(prompt) != len(image)",
|
506 |
+
"1.0.0",
|
507 |
+
deprecation_message,
|
508 |
+
standard_warn=False,
|
509 |
+
)
|
510 |
+
additional_image_per_prompt = batch_size // image_latents.shape[0]
|
511 |
+
image_latents = torch.cat(
|
512 |
+
[image_latents] * additional_image_per_prompt, dim=0
|
513 |
+
)
|
514 |
+
elif (
|
515 |
+
batch_size > image_latents.shape[0]
|
516 |
+
and batch_size % image_latents.shape[0] != 0
|
517 |
+
):
|
518 |
+
raise ValueError(
|
519 |
+
f"Cannot duplicate `image` of batch size {image_latents.shape[0]} to {batch_size} text prompts."
|
520 |
+
)
|
521 |
+
else:
|
522 |
+
image_latents = torch.cat([image_latents], dim=0)
|
523 |
+
|
524 |
+
if do_classifier_free_guidance:
|
525 |
+
uncond_image_latents = torch.zeros_like(image_latents)
|
526 |
+
image_latents = torch.cat(
|
527 |
+
[image_latents, image_latents, uncond_image_latents], dim=0
|
528 |
+
)
|
529 |
+
|
530 |
+
return image_latents
|
531 |
+
|
532 |
+
@torch.no_grad()
|
533 |
+
def __call__(
|
534 |
+
self,
|
535 |
+
prompt: Union[str, List[str]] = None,
|
536 |
+
photo: Union[
|
537 |
+
torch.FloatTensor,
|
538 |
+
PIL.Image.Image,
|
539 |
+
np.ndarray,
|
540 |
+
List[torch.FloatTensor],
|
541 |
+
List[PIL.Image.Image],
|
542 |
+
List[np.ndarray],
|
543 |
+
] = None,
|
544 |
+
height: Optional[int] = None,
|
545 |
+
width: Optional[int] = None,
|
546 |
+
num_inference_steps: int = 100,
|
547 |
+
required_aovs: List[str] = ["albedo"],
|
548 |
+
negative_prompt: Optional[Union[str, List[str]]] = None,
|
549 |
+
num_images_per_prompt: Optional[int] = 1,
|
550 |
+
use_default_scaling_factor: Optional[bool] = False,
|
551 |
+
guidance_scale: float = 0.0,
|
552 |
+
image_guidance_scale: float = 0.0,
|
553 |
+
guidance_rescale: float = 0.0,
|
554 |
+
eta: float = 0.0,
|
555 |
+
generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None,
|
556 |
+
latents: Optional[torch.FloatTensor] = None,
|
557 |
+
prompt_embeds: Optional[torch.FloatTensor] = None,
|
558 |
+
negative_prompt_embeds: Optional[torch.FloatTensor] = None,
|
559 |
+
output_type: Optional[str] = "pil",
|
560 |
+
return_dict: bool = True,
|
561 |
+
callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None,
|
562 |
+
callback_steps: int = 1,
|
563 |
+
):
|
564 |
+
r"""
|
565 |
+
The call function to the pipeline for generation.
|
566 |
+
|
567 |
+
Args:
|
568 |
+
prompt (`str` or `List[str]`, *optional*):
|
569 |
+
The prompt or prompts to guide image generation. If not defined, you need to pass `prompt_embeds`.
|
570 |
+
image (`torch.FloatTensor` `np.ndarray`, `PIL.Image.Image`, `List[torch.FloatTensor]`, `List[PIL.Image.Image]`, or `List[np.ndarray]`):
|
571 |
+
`Image` or tensor representing an image batch to be repainted according to `prompt`. Can also accept
|
572 |
+
image latents as `image`, but if passing latents directly it is not encoded again.
|
573 |
+
num_inference_steps (`int`, *optional*, defaults to 100):
|
574 |
+
The number of denoising steps. More denoising steps usually lead to a higher quality image at the
|
575 |
+
expense of slower inference.
|
576 |
+
guidance_scale (`float`, *optional*, defaults to 7.5):
|
577 |
+
A higher guidance scale value encourages the model to generate images closely linked to the text
|
578 |
+
`prompt` at the expense of lower image quality. Guidance scale is enabled when `guidance_scale > 1`.
|
579 |
+
image_guidance_scale (`float`, *optional*, defaults to 1.5):
|
580 |
+
Push the generated image towards the inital `image`. Image guidance scale is enabled by setting
|
581 |
+
`image_guidance_scale > 1`. Higher image guidance scale encourages generated images that are closely
|
582 |
+
linked to the source `image`, usually at the expense of lower image quality. This pipeline requires a
|
583 |
+
value of at least `1`.
|
584 |
+
negative_prompt (`str` or `List[str]`, *optional*):
|
585 |
+
The prompt or prompts to guide what to not include in image generation. If not defined, you need to
|
586 |
+
pass `negative_prompt_embeds` instead. Ignored when not using guidance (`guidance_scale < 1`).
|
587 |
+
num_images_per_prompt (`int`, *optional*, defaults to 1):
|
588 |
+
The number of images to generate per prompt.
|
589 |
+
eta (`float`, *optional*, defaults to 0.0):
|
590 |
+
Corresponds to parameter eta (η) from the [DDIM](https://arxiv.org/abs/2010.02502) paper. Only applies
|
591 |
+
to the [`~schedulers.DDIMScheduler`], and is ignored in other schedulers.
|
592 |
+
generator (`torch.Generator`, *optional*):
|
593 |
+
A [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make
|
594 |
+
generation deterministic.
|
595 |
+
latents (`torch.FloatTensor`, *optional*):
|
596 |
+
Pre-generated noisy latents sampled from a Gaussian distribution, to be used as inputs for image
|
597 |
+
generation. Can be used to tweak the same generation with different prompts. If not provided, a latents
|
598 |
+
tensor is generated by sampling using the supplied random `generator`.
|
599 |
+
prompt_embeds (`torch.FloatTensor`, *optional*):
|
600 |
+
Pre-generated text embeddings. Can be used to easily tweak text inputs (prompt weighting). If not
|
601 |
+
provided, text embeddings are generated from the `prompt` input argument.
|
602 |
+
negative_prompt_embeds (`torch.FloatTensor`, *optional*):
|
603 |
+
Pre-generated negative text embeddings. Can be used to easily tweak text inputs (prompt weighting). If
|
604 |
+
not provided, `negative_prompt_embeds` are generated from the `negative_prompt` input argument.
|
605 |
+
output_type (`str`, *optional*, defaults to `"pil"`):
|
606 |
+
The output format of the generated image. Choose between `PIL.Image` or `np.array`.
|
607 |
+
return_dict (`bool`, *optional*, defaults to `True`):
|
608 |
+
Whether or not to return a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] instead of a
|
609 |
+
plain tuple.
|
610 |
+
callback (`Callable`, *optional*):
|
611 |
+
A function that calls every `callback_steps` steps during inference. The function is called with the
|
612 |
+
following arguments: `callback(step: int, timestep: int, latents: torch.FloatTensor)`.
|
613 |
+
callback_steps (`int`, *optional*, defaults to 1):
|
614 |
+
The frequency at which the `callback` function is called. If not specified, the callback is called at
|
615 |
+
every step.
|
616 |
+
|
617 |
+
Examples:
|
618 |
+
|
619 |
+
```py
|
620 |
+
>>> import PIL
|
621 |
+
>>> import requests
|
622 |
+
>>> import torch
|
623 |
+
>>> from io import BytesIO
|
624 |
+
|
625 |
+
>>> from diffusers import StableDiffusionInstructPix2PixPipeline
|
626 |
+
|
627 |
+
|
628 |
+
>>> def download_image(url):
|
629 |
+
... response = requests.get(url)
|
630 |
+
... return PIL.Image.open(BytesIO(response.content)).convert("RGB")
|
631 |
+
|
632 |
+
|
633 |
+
>>> img_url = "https://huggingface.co/datasets/diffusers/diffusers-images-docs/resolve/main/mountain.png"
|
634 |
+
|
635 |
+
>>> image = download_image(img_url).resize((512, 512))
|
636 |
+
|
637 |
+
>>> pipe = StableDiffusionInstructPix2PixPipeline.from_pretrained(
|
638 |
+
... "timbrooks/instruct-pix2pix", torch_dtype=torch.float16
|
639 |
+
... )
|
640 |
+
>>> pipe = pipe.to("cuda")
|
641 |
+
|
642 |
+
>>> prompt = "make the mountains snowy"
|
643 |
+
>>> image = pipe(prompt=prompt, image=image).images[0]
|
644 |
+
```
|
645 |
+
|
646 |
+
Returns:
|
647 |
+
[`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`:
|
648 |
+
If `return_dict` is `True`, [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] is returned,
|
649 |
+
otherwise a `tuple` is returned where the first element is a list with the generated images and the
|
650 |
+
second element is a list of `bool`s indicating whether the corresponding generated image contains
|
651 |
+
"not-safe-for-work" (nsfw) content.
|
652 |
+
"""
|
653 |
+
# 0. Check inputs
|
654 |
+
self.check_inputs(
|
655 |
+
prompt,
|
656 |
+
callback_steps,
|
657 |
+
negative_prompt,
|
658 |
+
prompt_embeds,
|
659 |
+
negative_prompt_embeds,
|
660 |
+
)
|
661 |
+
|
662 |
+
# 1. Define call parameters
|
663 |
+
if prompt is not None and isinstance(prompt, str):
|
664 |
+
batch_size = 1
|
665 |
+
elif prompt is not None and isinstance(prompt, list):
|
666 |
+
batch_size = len(prompt)
|
667 |
+
else:
|
668 |
+
batch_size = prompt_embeds.shape[0]
|
669 |
+
|
670 |
+
device = self._execution_device
|
671 |
+
do_classifier_free_guidance = (
|
672 |
+
guidance_scale > 1.0 and image_guidance_scale >= 1.0
|
673 |
+
)
|
674 |
+
# check if scheduler is in sigmas space
|
675 |
+
scheduler_is_in_sigma_space = hasattr(self.scheduler, "sigmas")
|
676 |
+
|
677 |
+
# 2. Encode input prompt
|
678 |
+
prompt_embeds = self._encode_prompt(
|
679 |
+
prompt,
|
680 |
+
device,
|
681 |
+
num_images_per_prompt,
|
682 |
+
do_classifier_free_guidance,
|
683 |
+
negative_prompt,
|
684 |
+
prompt_embeds=prompt_embeds,
|
685 |
+
negative_prompt_embeds=negative_prompt_embeds,
|
686 |
+
)
|
687 |
+
|
688 |
+
# 3. Preprocess image
|
689 |
+
# Normalize image to [-1,1]
|
690 |
+
preprocessed_photo = self.image_processor.preprocess(photo)
|
691 |
+
|
692 |
+
# 4. set timesteps
|
693 |
+
self.scheduler.set_timesteps(num_inference_steps, device=device)
|
694 |
+
timesteps = self.scheduler.timesteps
|
695 |
+
|
696 |
+
# 5. Prepare Image latents
|
697 |
+
image_latents = self.prepare_image_latents(
|
698 |
+
preprocessed_photo,
|
699 |
+
batch_size,
|
700 |
+
num_images_per_prompt,
|
701 |
+
prompt_embeds.dtype,
|
702 |
+
device,
|
703 |
+
do_classifier_free_guidance,
|
704 |
+
generator,
|
705 |
+
)
|
706 |
+
image_latents = image_latents * self.vae.config.scaling_factor
|
707 |
+
|
708 |
+
height, width = image_latents.shape[-2:]
|
709 |
+
height = height * self.vae_scale_factor
|
710 |
+
width = width * self.vae_scale_factor
|
711 |
+
|
712 |
+
# 6. Prepare latent variables
|
713 |
+
num_channels_latents = self.unet.config.out_channels
|
714 |
+
latents = self.prepare_latents(
|
715 |
+
batch_size * num_images_per_prompt,
|
716 |
+
num_channels_latents,
|
717 |
+
height,
|
718 |
+
width,
|
719 |
+
prompt_embeds.dtype,
|
720 |
+
device,
|
721 |
+
generator,
|
722 |
+
latents,
|
723 |
+
)
|
724 |
+
|
725 |
+
# 7. Check that shapes of latents and image match the UNet channels
|
726 |
+
num_channels_image = image_latents.shape[1]
|
727 |
+
if num_channels_latents + num_channels_image != self.unet.config.in_channels:
|
728 |
+
raise ValueError(
|
729 |
+
f"Incorrect configuration settings! The config of `pipeline.unet`: {self.unet.config} expects"
|
730 |
+
f" {self.unet.config.in_channels} but received `num_channels_latents`: {num_channels_latents} +"
|
731 |
+
f" `num_channels_image`: {num_channels_image} "
|
732 |
+
f" = {num_channels_latents+num_channels_image}. Please verify the config of"
|
733 |
+
" `pipeline.unet` or your `image` input."
|
734 |
+
)
|
735 |
+
|
736 |
+
# 8. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline
|
737 |
+
extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta)
|
738 |
+
|
739 |
+
# 9. Denoising loop
|
740 |
+
num_warmup_steps = len(timesteps) - num_inference_steps * self.scheduler.order
|
741 |
+
with self.progress_bar(total=num_inference_steps) as progress_bar:
|
742 |
+
for i, t in enumerate(timesteps):
|
743 |
+
# Expand the latents if we are doing classifier free guidance.
|
744 |
+
# The latents are expanded 3 times because for pix2pix the guidance\
|
745 |
+
# is applied for both the text and the input image.
|
746 |
+
latent_model_input = (
|
747 |
+
torch.cat([latents] * 3) if do_classifier_free_guidance else latents
|
748 |
+
)
|
749 |
+
|
750 |
+
# concat latents, image_latents in the channel dimension
|
751 |
+
scaled_latent_model_input = self.scheduler.scale_model_input(
|
752 |
+
latent_model_input, t
|
753 |
+
)
|
754 |
+
scaled_latent_model_input = torch.cat(
|
755 |
+
[scaled_latent_model_input, image_latents], dim=1
|
756 |
+
)
|
757 |
+
|
758 |
+
# predict the noise residual
|
759 |
+
noise_pred = self.unet(
|
760 |
+
scaled_latent_model_input,
|
761 |
+
t,
|
762 |
+
encoder_hidden_states=prompt_embeds,
|
763 |
+
return_dict=False,
|
764 |
+
)[0]
|
765 |
+
|
766 |
+
# perform guidance
|
767 |
+
if do_classifier_free_guidance:
|
768 |
+
(
|
769 |
+
noise_pred_text,
|
770 |
+
noise_pred_image,
|
771 |
+
noise_pred_uncond,
|
772 |
+
) = noise_pred.chunk(3)
|
773 |
+
noise_pred = (
|
774 |
+
noise_pred_uncond
|
775 |
+
+ guidance_scale * (noise_pred_text - noise_pred_image)
|
776 |
+
+ image_guidance_scale * (noise_pred_image - noise_pred_uncond)
|
777 |
+
)
|
778 |
+
|
779 |
+
if do_classifier_free_guidance and guidance_rescale > 0.0:
|
780 |
+
# Based on 3.4. in https://arxiv.org/pdf/2305.08891.pdf
|
781 |
+
noise_pred = rescale_noise_cfg(
|
782 |
+
noise_pred, noise_pred_text, guidance_rescale=guidance_rescale
|
783 |
+
)
|
784 |
+
|
785 |
+
# compute the previous noisy sample x_t -> x_t-1
|
786 |
+
latents = self.scheduler.step(
|
787 |
+
noise_pred, t, latents, **extra_step_kwargs, return_dict=False
|
788 |
+
)[0]
|
789 |
+
|
790 |
+
# call the callback, if provided
|
791 |
+
if i == len(timesteps) - 1 or (
|
792 |
+
(i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0
|
793 |
+
):
|
794 |
+
progress_bar.update()
|
795 |
+
if callback is not None and i % callback_steps == 0:
|
796 |
+
callback(i, t, latents)
|
797 |
+
|
798 |
+
aov_latents = latents / self.vae.config.scaling_factor
|
799 |
+
aov = self.vae.decode(aov_latents, return_dict=False)[0]
|
800 |
+
do_denormalize = [True] * aov.shape[0]
|
801 |
+
aov_name = required_aovs[0]
|
802 |
+
if aov_name == "albedo" or aov_name == "irradiance":
|
803 |
+
do_gamma_correction = True
|
804 |
+
else:
|
805 |
+
do_gamma_correction = False
|
806 |
+
|
807 |
+
if aov_name == "roughness" or aov_name == "metallic":
|
808 |
+
aov = aov[:, 0:1].repeat(1, 3, 1, 1)
|
809 |
+
|
810 |
+
aov = self.image_processor.postprocess(
|
811 |
+
aov,
|
812 |
+
output_type=output_type,
|
813 |
+
do_denormalize=do_denormalize,
|
814 |
+
do_gamma_correction=do_gamma_correction,
|
815 |
+
)
|
816 |
+
aovs = [aov]
|
817 |
+
|
818 |
+
# Offload last model to CPU
|
819 |
+
if hasattr(self, "final_offload_hook") and self.final_offload_hook is not None:
|
820 |
+
self.final_offload_hook.offload()
|
821 |
+
return StableDiffusionAOVPipelineOutput(images=aovs)
|
settings.py
CHANGED
@@ -18,5 +18,5 @@ MAX_SEED = np.iinfo(np.int32).max
|
|
18 |
|
19 |
# setup CUDA
|
20 |
# disable the following when deployting to hugging face
|
21 |
-
|
22 |
-
|
|
|
18 |
|
19 |
# setup CUDA
|
20 |
# disable the following when deployting to hugging face
|
21 |
+
if os.getenv("CUDA_VISIBLE_DEVICES") is None:
|
22 |
+
os.environ["CUDA_VISIBLE_DEVICES"] = "7"
|