Abhiroopvanaone commited on
Commit
09e65dd
Β·
verified Β·
1 Parent(s): 3de825a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -219
app.py CHANGED
@@ -9,12 +9,12 @@ import time
9
  # Global model storage
10
  models = {}
11
 
12
- @spaces.GPU # Zero GPU decorator - allocates GPU only when this function runs
13
  def load_glm_model(model_choice):
14
  """Load GLM model with Zero GPU allocation."""
15
  model_map = {
16
- "GLM-4.5V-FP8": "zai-org/GLM-4.5V-FP8",
17
  "GLM-4.5V-AWQ": "QuantTrio/GLM-4.5V-AWQ",
 
18
  "GLM-4.5V": "zai-org/GLM-4.5V"
19
  }
20
 
@@ -26,7 +26,6 @@ def load_glm_model(model_choice):
26
  try:
27
  print(f"πŸ”„ Loading {model_name} on Zero GPU...")
28
 
29
- # Load with Zero GPU optimization
30
  pipe = pipeline(
31
  "image-text-to-text",
32
  model=model_name,
@@ -37,55 +36,44 @@ def load_glm_model(model_choice):
37
 
38
  models[model_name] = pipe
39
  print(f"βœ… Successfully loaded {model_name}")
40
- return True, f"βœ… {model_choice} loaded successfully on Zero GPU"
41
 
42
  except Exception as e:
43
  error_msg = f"❌ Failed to load {model_choice}: {str(e)[:200]}"
44
  print(error_msg)
45
  return False, error_msg
46
 
47
- @spaces.GPU(duration=120) # Allocate GPU for up to 2 minutes for generation
48
  def generate_cadquery_code_gpu(image, model_choice, prompt_style):
49
  """Generate CADQuery code using Zero GPU allocation."""
50
 
51
  if image is None:
52
  return "❌ Please upload an image first."
53
 
54
- # Load model if needed
55
  success, message = load_glm_model(model_choice)
56
  if not success:
57
  return f"❌ {message}"
58
 
59
- # Create prompts
60
  prompts = {
61
  "Simple": "Generate CADQuery Python code for this 3D model:",
62
-
63
- "Detailed": """Analyze this 3D CAD model and generate Python CADQuery code to recreate it.
64
 
65
  Requirements:
66
  - Import cadquery as cq
67
  - Store result in 'result' variable
68
  - Use proper CADQuery syntax
69
- - Create complete runnable code
70
 
71
  Code:""",
72
-
73
  "Chain-of-Thought": """Analyze this 3D CAD model step by step:
74
 
75
  Step 1: Identify the basic geometry (box, cylinder, etc.)
76
- Step 2: Note any features (holes, fillets, chamfers, etc.)
77
- Step 3: Estimate dimensions and proportions
78
- Step 4: Generate clean CADQuery Python code
79
-
80
- Requirements:
81
- - Import cadquery as cq
82
- - Store final result in 'result' variable
83
- - Use realistic dimensions
84
 
85
  ```python
86
  import cadquery as cq
87
 
88
- # Generated CADQuery code:"""
89
  }
90
 
91
  prompt = prompts[prompt_style]
@@ -94,15 +82,14 @@ import cadquery as cq
94
  start_time = time.time()
95
 
96
  model_map = {
 
97
  "GLM-4.5V-FP8": "zai-org/GLM-4.5V-FP8",
98
- "GLM-4.5V-AWQ": "QuantTrio/GLM-4.5V-AWQ",
99
  "GLM-4.5V": "zai-org/GLM-4.5V"
100
  }
101
 
102
  model_name = model_map[model_choice]
103
  pipe = models[model_name]
104
 
105
- # Create the input for GLM
106
  messages = [
107
  {
108
  "role": "user",
@@ -113,21 +100,16 @@ import cadquery as cq
113
  }
114
  ]
115
 
116
- # Generate with the pipeline
117
  result = pipe(messages, max_new_tokens=512, temperature=0.7, do_sample=True)
118
 
119
- # Extract the generated text
120
  if isinstance(result, list) and len(result) > 0:
121
  generated_text = result[0].get("generated_text", str(result))
122
  else:
123
  generated_text = str(result)
124
 
125
  generation_time = time.time() - start_time
126
-
127
- # Extract clean code
128
  clean_code = extract_cadquery_code(generated_text)
129
 
130
- # Format output
131
  output = f"""## 🎯 Generated CADQuery Code
132
 
133
  ```python
@@ -137,50 +119,25 @@ import cadquery as cq
137
  ## πŸ“Š Generation Info
138
  - **Model**: {model_choice}
139
  - **Time**: {generation_time:.2f} seconds
140
- - **Prompt Style**: {prompt_style}
141
  - **Compute**: Zero GPU (A100)
142
 
143
- ## πŸ”§ Usage Instructions
144
- 1. Copy the code above
145
- 2. Install CADQuery: `pip install cadquery`
146
- 3. Run the code to generate your 3D model
147
- 4. Export to STL/STEP format if needed
148
-
149
- ## ⚠️ Note
150
- Generated using Zero GPU - GPU allocated only during generation for cost efficiency.
151
  """
152
 
153
  return output
154
 
155
  except Exception as e:
156
- error_trace = traceback.format_exc()
157
- return f"""❌ **Generation Failed**
158
-
159
- **Error**: {str(e)}
160
-
161
- **Model**: {model_choice}
162
-
163
- **Traceback**:
164
- ```
165
- {error_trace[:1000]}...
166
- ```
167
-
168
- Try a different model variant or simpler image."""
169
-
170
- def generate_cadquery_code(image, model_choice, prompt_style):
171
- """Wrapper function WITHOUT progress tracking to avoid Zero GPU conflicts."""
172
-
173
- # Simple status update instead of progress
174
- print(f"πŸš€ Starting generation with {model_choice}...")
175
- result = generate_cadquery_code_gpu(image, model_choice, prompt_style)
176
- print("βœ… Generation complete!")
177
- return result
178
 
179
  def extract_cadquery_code(generated_text: str) -> str:
180
  """Extract clean CADQuery code from generated text."""
181
  text = generated_text.strip()
182
 
183
- # Look for code blocks
184
  if "```python" in text:
185
  start = text.find("```python") + 9
186
  end = text.find("```", start)
@@ -188,21 +145,13 @@ def extract_cadquery_code(generated_text: str) -> str:
188
  code = text[start:end].strip()
189
  else:
190
  code = text[start:].strip()
191
- elif "```" in text:
192
- start = text.find("```") + 3
193
- end = text.find("```", start)
194
- if end > start:
195
- code = text[start:end].strip()
196
- else:
197
- code = text[start:].strip()
198
- elif "import cadquery" in text.lower() or "import cq" in text.lower():
199
- # Find import and take everything after
200
  lines = text.split('\n')
201
  code_lines = []
202
  started = False
203
 
204
  for line in lines:
205
- if "import cadquery" in line.lower() or "import cq" in line.lower():
206
  started = True
207
  if started:
208
  code_lines.append(line)
@@ -211,7 +160,6 @@ def extract_cadquery_code(generated_text: str) -> str:
211
  else:
212
  code = text
213
 
214
- # Basic cleanup
215
  lines = code.split('\n')
216
  cleaned_lines = []
217
 
@@ -222,11 +170,9 @@ def extract_cadquery_code(generated_text: str) -> str:
222
 
223
  final_code = '\n'.join(cleaned_lines)
224
 
225
- # Ensure basic structure
226
- if "import cadquery" not in final_code and "import cq" not in final_code:
227
  final_code = "import cadquery as cq\n\n" + final_code
228
 
229
- # Ensure result variable exists
230
  if "result" not in final_code and "=" in final_code:
231
  lines = final_code.split('\n')
232
  for i, line in enumerate(lines):
@@ -237,135 +183,60 @@ def extract_cadquery_code(generated_text: str) -> str:
237
 
238
  return final_code
239
 
240
- @spaces.GPU # Test model loading with Zero GPU
241
  def test_model_loading(model_choice):
242
- """Test loading a specific model on Zero GPU."""
243
  success, message = load_glm_model(model_choice)
244
- return f"## Zero GPU Test Result for {model_choice}\n\n{message}\n\n**Note**: GPU allocated only during this test."
245
-
246
- def get_system_info():
247
- """Get system information."""
248
- info_text = """## πŸ–₯️ Zero GPU Information
249
-
250
- - **Compute**: Serverless GPU allocation
251
- - **GPU Type**: A100 (allocated on demand)
252
- - **Billing**: Pay per second of GPU usage
253
- - **Benefits**: No idle costs, automatic scaling
254
-
255
- ## πŸ’° Cost Efficiency
256
- - GPU allocated only during generation
257
- - ~$0.50-2.00 per generation (estimated)
258
- - No cost when idle
259
- - Much cheaper than dedicated GPU instances
260
-
261
- ## ⚑ Performance
262
- - Cold start: 30-60 seconds (model loading)
263
- - Warm start: 10-30 seconds (model cached)
264
- - Generation: 15-45 seconds per image
265
-
266
- ## πŸ“‹ Current Status
267
- - Space running on CPU (free)
268
- - Zero GPU allocated automatically when needed
269
- - No ongoing GPU costs
270
- """
271
-
272
- return info_text
273
-
274
- # Simple status tracking without Gradio progress
275
- def show_status(message):
276
- """Simple status display."""
277
- return f"**Status**: {message}"
278
 
279
  def create_interface():
280
- """Create the Zero GPU optimized interface."""
281
 
282
- with gr.Blocks(title="GLM-4.5V CAD Generator (Zero GPU)", theme=gr.themes.Soft()) as demo:
283
  gr.Markdown("""
284
  # πŸ”§ GLM-4.5V CAD Generator (Zero GPU)
285
 
286
- Upload a 3D CAD model image and generate CADQuery Python code using GLM-4.5V models on **Zero GPU**!
287
 
288
- **Zero GPU Benefits:**
289
- - πŸš€ **A100 GPU** allocated on-demand
290
- - πŸ’° **Pay per use** - no idle costs
291
- - ⚑ **Automatic scaling** - no setup required
292
-
293
- **Available Models:**
294
- - **GLM-4.5V-FP8**: 8-bit quantized (recommended)
295
- - **GLM-4.5V-AWQ**: AWQ quantized (fastest startup)
296
- - **GLM-4.5V**: Full precision (best quality)
297
  """)
298
 
299
- with gr.Tab("πŸš€ CAD Generation"):
300
  with gr.Row():
301
  with gr.Column(scale=1):
302
- image_input = gr.Image(
303
- type="pil",
304
- label="Upload CAD Model Image",
305
- height=400
306
- )
307
 
308
  model_choice = gr.Dropdown(
309
- choices=["GLM-4.5V-FP8", "GLM-4.5V-AWQ", "GLM-4.5V"],
310
- value="GLM-4.5V-AWQ", # AWQ for fastest startup
311
- label="Select GLM Model Variant"
312
  )
313
 
314
  prompt_style = gr.Dropdown(
315
  choices=["Simple", "Detailed", "Chain-of-Thought"],
316
  value="Chain-of-Thought",
317
- label="Prompt Strategy"
318
  )
319
 
320
- generate_btn = gr.Button("πŸš€ Generate with Zero GPU", variant="primary", size="lg")
321
 
322
  with gr.Column(scale=2):
323
- # Status display
324
- status_display = gr.Markdown(value="**Status**: Ready to generate")
325
-
326
- output_text = gr.Markdown(
327
- label="Generated Code",
328
- value="Upload an image and click 'Generate' to allocate Zero GPU and start generation!"
329
- )
330
-
331
- # Note about Zero GPU
332
- gr.Markdown("""
333
- **⚑ Zero GPU Note**: GPU will be allocated automatically when you click generate.
334
- First generation may take 30-60 seconds due to model loading. Subsequent generations will be faster.
335
- """)
336
-
337
- # Update status on click
338
- def update_status_and_generate(image, model_choice, prompt_style):
339
- if image is None:
340
- return "**Status**: Please upload an image first", "❌ Please upload an image first."
341
-
342
- # Show generating status
343
- yield "**Status**: πŸ”„ Allocating Zero GPU and generating...", "πŸ”„ Generating CADQuery code..."
344
-
345
- # Call the actual generation
346
- result = generate_cadquery_code(image, model_choice, prompt_style)
347
-
348
- # Show completion status
349
- yield "**Status**: βœ… Generation complete!", result
350
 
351
  generate_btn.click(
352
- fn=update_status_and_generate,
353
  inputs=[image_input, model_choice, prompt_style],
354
- outputs=[status_display, output_text]
355
  )
356
 
357
- with gr.Tab("πŸ” Model Testing"):
358
- with gr.Row():
359
- with gr.Column():
360
- test_model_choice = gr.Dropdown(
361
- choices=["GLM-4.5V-FP8", "GLM-4.5V-AWQ", "GLM-4.5V"],
362
- value="GLM-4.5V-AWQ",
363
- label="Model to Test"
364
- )
365
- test_btn = gr.Button("πŸ§ͺ Test on Zero GPU", variant="secondary")
366
-
367
- with gr.Column():
368
- test_output = gr.Markdown(value="Click 'Test on Zero GPU' to verify model loading works.")
369
 
370
  test_btn.click(
371
  fn=test_model_loading,
@@ -373,61 +244,28 @@ def create_interface():
373
  outputs=test_output
374
  )
375
 
376
- with gr.Tab("βš™οΈ Zero GPU Info"):
377
- info_output = gr.Markdown()
378
-
379
- demo.load(fn=get_system_info, outputs=info_output)
380
-
381
- with gr.Tab("πŸ“– Help"):
382
  gr.Markdown("""
383
- ## 🎯 How Zero GPU Works
384
-
385
- 1. **Upload Image**: Standard image upload
386
- 2. **Click Generate**: Zero GPU automatically allocates A100 GPU
387
- 3. **Model Loading**: First time takes 30-60 seconds
388
- 4. **Generation**: 15-45 seconds for code generation
389
- 5. **GPU Release**: GPU automatically released after generation
390
-
391
- ## πŸ’° Cost Information
392
-
393
- - **No idle costs**: Pay only when generating
394
- - **Estimated cost**: $0.50-2.00 per generation
395
- - **GPU Type**: NVIDIA A100 (40GB VRAM)
396
- - **Billing**: Per second of actual GPU usage
397
-
398
- ## πŸš€ Performance Tips
399
-
400
- - **First generation**: Slower due to model download
401
- - **Subsequent generations**: Much faster (model cached)
402
- - **GLM-4.5V-AWQ**: Fastest startup time
403
- - **Simple images**: Process faster than complex ones
404
-
405
- ## πŸ”§ Generated Code Usage
406
-
407
- ```bash
408
- # Install CADQuery
409
- pip install cadquery
410
-
411
- # Run your generated code
412
- python your_cad_script.py
413
 
414
- # Export to STL
415
- cq.exporters.export(result, "model.stl")
416
- ```
 
417
 
418
- ## πŸ’‘ Best Practices
 
419
 
420
- - Start with **GLM-4.5V-AWQ** for testing
421
- - Use **Chain-of-Thought** prompts for best results
422
- - Upload clear, well-lit CAD images
423
- - Try simpler geometries first
424
  """)
425
 
426
  return demo
427
 
428
  if __name__ == "__main__":
429
- print("πŸš€ Starting GLM-4.5V CAD Generator with Zero GPU...")
430
- print("Zero GPU will be allocated automatically during generation.")
431
 
432
  demo = create_interface()
433
  demo.launch(
 
9
  # Global model storage
10
  models = {}
11
 
12
+ @spaces.GPU
13
  def load_glm_model(model_choice):
14
  """Load GLM model with Zero GPU allocation."""
15
  model_map = {
 
16
  "GLM-4.5V-AWQ": "QuantTrio/GLM-4.5V-AWQ",
17
+ "GLM-4.5V-FP8": "zai-org/GLM-4.5V-FP8",
18
  "GLM-4.5V": "zai-org/GLM-4.5V"
19
  }
20
 
 
26
  try:
27
  print(f"πŸ”„ Loading {model_name} on Zero GPU...")
28
 
 
29
  pipe = pipeline(
30
  "image-text-to-text",
31
  model=model_name,
 
36
 
37
  models[model_name] = pipe
38
  print(f"βœ… Successfully loaded {model_name}")
39
+ return True, f"βœ… {model_choice} loaded successfully"
40
 
41
  except Exception as e:
42
  error_msg = f"❌ Failed to load {model_choice}: {str(e)[:200]}"
43
  print(error_msg)
44
  return False, error_msg
45
 
46
+ @spaces.GPU(duration=120)
47
  def generate_cadquery_code_gpu(image, model_choice, prompt_style):
48
  """Generate CADQuery code using Zero GPU allocation."""
49
 
50
  if image is None:
51
  return "❌ Please upload an image first."
52
 
 
53
  success, message = load_glm_model(model_choice)
54
  if not success:
55
  return f"❌ {message}"
56
 
 
57
  prompts = {
58
  "Simple": "Generate CADQuery Python code for this 3D model:",
59
+ "Detailed": """Analyze this 3D CAD model and generate Python CADQuery code.
 
60
 
61
  Requirements:
62
  - Import cadquery as cq
63
  - Store result in 'result' variable
64
  - Use proper CADQuery syntax
 
65
 
66
  Code:""",
 
67
  "Chain-of-Thought": """Analyze this 3D CAD model step by step:
68
 
69
  Step 1: Identify the basic geometry (box, cylinder, etc.)
70
+ Step 2: Note any features (holes, fillets, etc.)
71
+ Step 3: Generate clean CADQuery Python code
 
 
 
 
 
 
72
 
73
  ```python
74
  import cadquery as cq
75
 
76
+ # Generated code:"""
77
  }
78
 
79
  prompt = prompts[prompt_style]
 
82
  start_time = time.time()
83
 
84
  model_map = {
85
+ "GLM-4.5V-AWQ": "QuantTrio/GLM-4.5V-AWQ",
86
  "GLM-4.5V-FP8": "zai-org/GLM-4.5V-FP8",
 
87
  "GLM-4.5V": "zai-org/GLM-4.5V"
88
  }
89
 
90
  model_name = model_map[model_choice]
91
  pipe = models[model_name]
92
 
 
93
  messages = [
94
  {
95
  "role": "user",
 
100
  }
101
  ]
102
 
 
103
  result = pipe(messages, max_new_tokens=512, temperature=0.7, do_sample=True)
104
 
 
105
  if isinstance(result, list) and len(result) > 0:
106
  generated_text = result[0].get("generated_text", str(result))
107
  else:
108
  generated_text = str(result)
109
 
110
  generation_time = time.time() - start_time
 
 
111
  clean_code = extract_cadquery_code(generated_text)
112
 
 
113
  output = f"""## 🎯 Generated CADQuery Code
114
 
115
  ```python
 
119
  ## πŸ“Š Generation Info
120
  - **Model**: {model_choice}
121
  - **Time**: {generation_time:.2f} seconds
122
+ - **Prompt**: {prompt_style}
123
  - **Compute**: Zero GPU (A100)
124
 
125
+ ## πŸ”§ Usage
126
+ ```bash
127
+ pip install cadquery
128
+ python your_script.py
129
+ ```
 
 
 
130
  """
131
 
132
  return output
133
 
134
  except Exception as e:
135
+ return f"❌ **Generation Failed**: {str(e)[:500]}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
 
137
  def extract_cadquery_code(generated_text: str) -> str:
138
  """Extract clean CADQuery code from generated text."""
139
  text = generated_text.strip()
140
 
 
141
  if "```python" in text:
142
  start = text.find("```python") + 9
143
  end = text.find("```", start)
 
145
  code = text[start:end].strip()
146
  else:
147
  code = text[start:].strip()
148
+ elif "import cadquery" in text.lower():
 
 
 
 
 
 
 
 
149
  lines = text.split('\n')
150
  code_lines = []
151
  started = False
152
 
153
  for line in lines:
154
+ if "import cadquery" in line.lower():
155
  started = True
156
  if started:
157
  code_lines.append(line)
 
160
  else:
161
  code = text
162
 
 
163
  lines = code.split('\n')
164
  cleaned_lines = []
165
 
 
170
 
171
  final_code = '\n'.join(cleaned_lines)
172
 
173
+ if "import cadquery" not in final_code:
 
174
  final_code = "import cadquery as cq\n\n" + final_code
175
 
 
176
  if "result" not in final_code and "=" in final_code:
177
  lines = final_code.split('\n')
178
  for i, line in enumerate(lines):
 
183
 
184
  return final_code
185
 
186
+ @spaces.GPU
187
  def test_model_loading(model_choice):
188
+ """Test loading a specific model."""
189
  success, message = load_glm_model(model_choice)
190
+ return f"## Test Result\n\n{message}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
 
192
  def create_interface():
193
+ """Create the Gradio interface."""
194
 
195
+ with gr.Blocks(title="GLM-4.5V CAD Generator", theme=gr.themes.Soft()) as demo:
196
  gr.Markdown("""
197
  # πŸ”§ GLM-4.5V CAD Generator (Zero GPU)
198
 
199
+ Upload a 3D CAD model image and generate CADQuery Python code!
200
 
201
+ **Models:** GLM-4.5V-AWQ (fastest) β€’ GLM-4.5V-FP8 (balanced) β€’ GLM-4.5V (best quality)
 
 
 
 
 
 
 
 
202
  """)
203
 
204
+ with gr.Tab("πŸš€ Generate"):
205
  with gr.Row():
206
  with gr.Column(scale=1):
207
+ image_input = gr.Image(type="pil", label="Upload CAD Image", height=400)
 
 
 
 
208
 
209
  model_choice = gr.Dropdown(
210
+ choices=["GLM-4.5V-AWQ", "GLM-4.5V-FP8", "GLM-4.5V"],
211
+ value="GLM-4.5V-AWQ",
212
+ label="Model"
213
  )
214
 
215
  prompt_style = gr.Dropdown(
216
  choices=["Simple", "Detailed", "Chain-of-Thought"],
217
  value="Chain-of-Thought",
218
+ label="Prompt Style"
219
  )
220
 
221
+ generate_btn = gr.Button("πŸš€ Generate", variant="primary")
222
 
223
  with gr.Column(scale=2):
224
+ output_text = gr.Markdown("Upload image and click Generate!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
 
226
  generate_btn.click(
227
+ fn=generate_cadquery_code_gpu, # Direct call - no wrapper
228
  inputs=[image_input, model_choice, prompt_style],
229
+ outputs=output_text
230
  )
231
 
232
+ with gr.Tab("πŸ§ͺ Test"):
233
+ test_model_choice = gr.Dropdown(
234
+ choices=["GLM-4.5V-AWQ", "GLM-4.5V-FP8", "GLM-4.5V"],
235
+ value="GLM-4.5V-AWQ",
236
+ label="Model to Test"
237
+ )
238
+ test_btn = gr.Button("Test Model")
239
+ test_output = gr.Markdown()
 
 
 
 
240
 
241
  test_btn.click(
242
  fn=test_model_loading,
 
244
  outputs=test_output
245
  )
246
 
247
+ with gr.Tab("ℹ️ Info"):
 
 
 
 
 
248
  gr.Markdown("""
249
+ ## Zero GPU Benefits
250
+ - **A100 GPU** allocated on-demand
251
+ - **Pay per use** - no idle costs
252
+ - **Automatic scaling**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
 
254
+ ## Usage Tips
255
+ - Clear CAD images work best
256
+ - GLM-4.5V-AWQ is fastest for testing
257
+ - Chain-of-Thought prompts give best results
258
 
259
+ ## Generated Code
260
+ Install CADQuery: `pip install cadquery`
261
 
262
+ Run your generated script to create 3D models!
 
 
 
263
  """)
264
 
265
  return demo
266
 
267
  if __name__ == "__main__":
268
+ print("πŸš€ GLM-4.5V CAD Generator with Zero GPU")
 
269
 
270
  demo = create_interface()
271
  demo.launch(