Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -10,6 +10,7 @@ from PIL import Image
|
|
10 |
import uuid
|
11 |
import time
|
12 |
import sys
|
|
|
13 |
|
14 |
# Set environment variables before anything else
|
15 |
os.environ['SHAPEE_NO_INTERACTIVE'] = '1'
|
@@ -118,12 +119,19 @@ def generate_3d():
|
|
118 |
prompt = data['prompt']
|
119 |
print(f"Received prompt: {prompt}")
|
120 |
|
121 |
-
# Set parameters for CPU performance (reduced steps)
|
122 |
batch_size = 1
|
123 |
guidance_scale = 15.0
|
124 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
# Generate latents with the text-to-3D model
|
126 |
-
print("Starting latent generation...")
|
127 |
latents = sample_latents(
|
128 |
batch_size=batch_size,
|
129 |
model=model,
|
@@ -134,13 +142,17 @@ def generate_3d():
|
|
134 |
clip_denoised=True,
|
135 |
use_fp16=False, # CPU doesn't support fp16
|
136 |
use_karras=True,
|
137 |
-
karras_steps=
|
138 |
sigma_min=1e-3,
|
139 |
sigma_max=160,
|
140 |
s_churn=0,
|
141 |
)
|
142 |
print("Latent generation complete!")
|
143 |
|
|
|
|
|
|
|
|
|
144 |
# Generate a unique filename
|
145 |
unique_id = str(uuid.uuid4())
|
146 |
filename = f"{output_dir}/{unique_id}"
|
@@ -148,9 +160,16 @@ def generate_3d():
|
|
148 |
# Convert latent to mesh
|
149 |
print("Decoding mesh...")
|
150 |
t0 = time.time()
|
|
|
|
|
151 |
mesh = decode_latent_mesh(xm, latents[0]).tri_mesh()
|
152 |
print(f"Mesh decoded in {time.time() - t0:.2f} seconds")
|
153 |
|
|
|
|
|
|
|
|
|
|
|
154 |
# Save as GLB
|
155 |
print("Saving as GLB...")
|
156 |
glb_path = f"{filename}.glb"
|
@@ -162,6 +181,10 @@ def generate_3d():
|
|
162 |
with open(obj_path, 'w') as f:
|
163 |
mesh.write_obj(f)
|
164 |
|
|
|
|
|
|
|
|
|
165 |
print("Files saved successfully!")
|
166 |
|
167 |
# Return paths to the generated files
|
@@ -188,7 +211,19 @@ def download_file(filename):
|
|
188 |
@app.route('/health', methods=['GET'])
|
189 |
def health_check():
|
190 |
"""Simple health check endpoint to verify the app is running"""
|
191 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
|
193 |
@app.route('/', methods=['GET'])
|
194 |
def home():
|
@@ -214,4 +249,6 @@ def home():
|
|
214 |
"""
|
215 |
|
216 |
if __name__ == '__main__':
|
|
|
|
|
217 |
app.run(host='0.0.0.0', port=7860, debug=True)
|
|
|
10 |
import uuid
|
11 |
import time
|
12 |
import sys
|
13 |
+
import gc # For explicit garbage collection
|
14 |
|
15 |
# Set environment variables before anything else
|
16 |
os.environ['SHAPEE_NO_INTERACTIVE'] = '1'
|
|
|
119 |
prompt = data['prompt']
|
120 |
print(f"Received prompt: {prompt}")
|
121 |
|
122 |
+
# Set parameters for CPU performance (reduced steps and other optimizations)
|
123 |
batch_size = 1
|
124 |
guidance_scale = 15.0
|
125 |
|
126 |
+
# *** OPTIMIZATION: Significantly reduce steps for low-memory environments ***
|
127 |
+
karras_steps = 16 # Reduced from 32 to 16 for better performance
|
128 |
+
|
129 |
+
# *** OPTIMIZATION: Run garbage collection before starting intensive task ***
|
130 |
+
gc.collect()
|
131 |
+
torch.cuda.empty_cache() if torch.cuda.is_available() else None
|
132 |
+
|
133 |
# Generate latents with the text-to-3D model
|
134 |
+
print("Starting latent generation with reduced steps...")
|
135 |
latents = sample_latents(
|
136 |
batch_size=batch_size,
|
137 |
model=model,
|
|
|
142 |
clip_denoised=True,
|
143 |
use_fp16=False, # CPU doesn't support fp16
|
144 |
use_karras=True,
|
145 |
+
karras_steps=karras_steps, # *** OPTIMIZATION: Reduced steps ***
|
146 |
sigma_min=1e-3,
|
147 |
sigma_max=160,
|
148 |
s_churn=0,
|
149 |
)
|
150 |
print("Latent generation complete!")
|
151 |
|
152 |
+
# *** OPTIMIZATION: Run garbage collection after intensive step ***
|
153 |
+
gc.collect()
|
154 |
+
torch.cuda.empty_cache() if torch.cuda.is_available() else None
|
155 |
+
|
156 |
# Generate a unique filename
|
157 |
unique_id = str(uuid.uuid4())
|
158 |
filename = f"{output_dir}/{unique_id}"
|
|
|
160 |
# Convert latent to mesh
|
161 |
print("Decoding mesh...")
|
162 |
t0 = time.time()
|
163 |
+
|
164 |
+
# *** OPTIMIZATION: Use simplified decoding for memory constraints ***
|
165 |
mesh = decode_latent_mesh(xm, latents[0]).tri_mesh()
|
166 |
print(f"Mesh decoded in {time.time() - t0:.2f} seconds")
|
167 |
|
168 |
+
# *** OPTIMIZATION: Clear latents from memory as they're no longer needed ***
|
169 |
+
del latents
|
170 |
+
gc.collect()
|
171 |
+
torch.cuda.empty_cache() if torch.cuda.is_available() else None
|
172 |
+
|
173 |
# Save as GLB
|
174 |
print("Saving as GLB...")
|
175 |
glb_path = f"{filename}.glb"
|
|
|
181 |
with open(obj_path, 'w') as f:
|
182 |
mesh.write_obj(f)
|
183 |
|
184 |
+
# *** OPTIMIZATION: Clear mesh from memory ***
|
185 |
+
del mesh
|
186 |
+
gc.collect()
|
187 |
+
|
188 |
print("Files saved successfully!")
|
189 |
|
190 |
# Return paths to the generated files
|
|
|
211 |
@app.route('/health', methods=['GET'])
|
212 |
def health_check():
|
213 |
"""Simple health check endpoint to verify the app is running"""
|
214 |
+
# Check available memory
|
215 |
+
try:
|
216 |
+
import psutil
|
217 |
+
memory_info = psutil.virtual_memory()
|
218 |
+
memory_usage = f"{memory_info.percent}% (Available: {memory_info.available / (1024**3):.2f} GB)"
|
219 |
+
except ImportError:
|
220 |
+
memory_usage = "psutil not installed"
|
221 |
+
|
222 |
+
return jsonify({
|
223 |
+
"status": "ok",
|
224 |
+
"message": "Service is running",
|
225 |
+
"memory_usage": memory_usage
|
226 |
+
})
|
227 |
|
228 |
@app.route('/', methods=['GET'])
|
229 |
def home():
|
|
|
249 |
"""
|
250 |
|
251 |
if __name__ == '__main__':
|
252 |
+
# Recommended to run with gunicorn for production with increased timeout:
|
253 |
+
# $ gunicorn app:app --bind 0.0.0.0:7860 --timeout 300 --workers 1
|
254 |
app.run(host='0.0.0.0', port=7860, debug=True)
|