Abhiroopvanaone commited on
Commit
54da26c
Β·
verified Β·
1 Parent(s): 1024e85

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +106 -255
app.py CHANGED
@@ -6,19 +6,21 @@ from PIL import Image
6
  import time
7
  import traceback
8
 
9
- # Global model storage
10
  models = {}
11
 
12
  @spaces.GPU(duration=300)
13
- def load_glm_model(model_choice):
14
- """Load GLM model on GPU."""
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
 
21
- model_name = model_map[model_choice]
 
 
22
 
23
  if model_name in models:
24
  return True, f"βœ… {model_choice} already loaded"
@@ -28,50 +30,28 @@ def load_glm_model(model_choice):
28
  "image-text-to-text",
29
  model=model_name,
30
  device_map="auto",
31
- torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
32
  trust_remote_code=True
33
  )
34
-
35
  models[model_name] = pipe
36
  return True, f"βœ… {model_choice} loaded successfully"
37
-
38
  except Exception as e:
39
- error_msg = f"❌ Failed to load {model_choice}: {str(e)[:200]}"
40
- return False, error_msg
41
 
42
  @spaces.GPU(duration=120)
43
- def generate_cadquery_code(image, model_choice, prompt_style):
44
- """Generate CADQuery code from image."""
45
-
46
  if image is None:
47
  return "❌ Please upload an image first."
48
 
 
 
 
 
 
 
 
49
  try:
50
- # Create prompt
51
- prompts = {
52
- "Simple": "Generate CADQuery Python code for this 3D model:",
53
- "Detailed": """Analyze this 3D CAD model and generate Python CADQuery code.
54
-
55
- Requirements:
56
- - Import cadquery as cq
57
- - Store result in 'result' variable
58
- - Use proper CADQuery syntax
59
-
60
- Code:""",
61
- "Chain-of-Thought": """Analyze this 3D CAD model step by step:
62
-
63
- Step 1: Identify the basic geometry (box, cylinder, etc.)
64
- Step 2: Note any features (holes, fillets, etc.)
65
- Step 3: Generate clean CADQuery Python code
66
-
67
- ```python
68
- import cadquery as cq
69
-
70
- # Generated code:"""
71
- }
72
-
73
- prompt = prompts[prompt_style]
74
-
75
  # Load model if needed
76
  model_map = {
77
  "GLM-4.5V-AWQ": "QuantTrio/GLM-4.5V-AWQ",
@@ -81,12 +61,11 @@ import cadquery as cq
81
 
82
  model_name = model_map[model_choice]
83
 
84
- # Load model if not already loaded
85
  if model_name not in models:
86
  pipe = pipeline(
87
  "image-text-to-text",
88
  model=model_name,
89
- device_map="auto",
90
  torch_dtype=torch.float16,
91
  trust_remote_code=True
92
  )
@@ -95,37 +74,40 @@ import cadquery as cq
95
  pipe = models[model_name]
96
 
97
  # Generate
98
- start_time = time.time()
99
-
100
- messages = [
101
- {
102
- "role": "user",
103
- "content": [
104
- {"type": "image", "image": image},
105
- {"type": "text", "text": prompt}
106
- ]
107
- }
108
- ]
109
 
110
- result = pipe(messages, max_new_tokens=512, temperature=0.7, do_sample=True)
111
 
112
  if isinstance(result, list) and len(result) > 0:
113
  generated_text = result[0].get("generated_text", str(result))
114
  else:
115
  generated_text = str(result)
116
 
117
- generation_time = time.time() - start_time
118
- clean_code = extract_cadquery_code(generated_text)
 
 
 
 
 
119
 
120
- output = f"""## 🎯 Generated CADQuery Code
 
 
 
121
 
122
  ```python
123
- {clean_code}
124
  ```
125
 
126
- ## πŸ“Š Generation Info
127
  - **Model**: {model_choice}
128
- - **Time**: {generation_time:.2f} seconds
129
  - **Prompt**: {prompt_style}
130
  - **Device**: {"GPU" if torch.cuda.is_available() else "CPU"}
131
 
@@ -134,216 +116,85 @@ import cadquery as cq
134
  pip install cadquery
135
  python your_script.py
136
  ```
137
-
138
- ## ⚠️ Note
139
- Generated code may need manual adjustments for complex geometries.
140
  """
141
 
142
- return output
143
-
144
  except Exception as e:
145
- error_trace = traceback.format_exc()
146
- return f"""❌ **Generation Failed**
147
-
148
- **Error**: {str(e)}
149
-
150
- **Traceback**:
151
- ```
152
- {error_trace[:1000]}...
153
- ```
154
-
155
- Try a different model variant or check your image."""
156
-
157
- def extract_cadquery_code(generated_text: str) -> str:
158
- """Extract clean CADQuery code from generated text."""
159
- text = generated_text.strip()
160
-
161
- if "```python" in text:
162
- start = text.find("```python") + 9
163
- end = text.find("```", start)
164
- if end > start:
165
- code = text[start:end].strip()
166
- else:
167
- code = text[start:].strip()
168
- elif "import cadquery" in text.lower():
169
- lines = text.split('\n')
170
- code_lines = []
171
- started = False
172
-
173
- for line in lines:
174
- if "import cadquery" in line.lower():
175
- started = True
176
- if started:
177
- code_lines.append(line)
178
-
179
- code = '\n'.join(code_lines)
180
- else:
181
- code = text
182
-
183
- lines = code.split('\n')
184
- cleaned_lines = []
185
-
186
- for line in lines:
187
- line = line.strip()
188
- if line and not line.startswith('```'):
189
- cleaned_lines.append(line)
190
-
191
- final_code = '\n'.join(cleaned_lines)
192
-
193
- if "import cadquery" not in final_code:
194
- final_code = "import cadquery as cq\n\n" + final_code
195
-
196
- if "result" not in final_code and "=" in final_code:
197
- lines = final_code.split('\n')
198
- for i, line in enumerate(lines):
199
- if "=" in line and ("cq." in line or "Workplane" in line):
200
- lines[i] = f"result = {line.split('=', 1)[1].strip()}"
201
- break
202
- final_code = '\n'.join(lines)
203
-
204
- return final_code
205
 
206
- def test_model_loading(model_choice):
207
- """Test loading a specific model."""
208
- success, message = load_glm_model(model_choice)
209
  return f"## Test Result\n\n{message}"
210
 
211
- def get_system_info():
212
- """Get system information."""
213
- info = {
214
- "CUDA Available": torch.cuda.is_available(),
215
- "CUDA Device Count": torch.cuda.device_count() if torch.cuda.is_available() else 0,
216
- "PyTorch Version": torch.__version__,
217
- "Device": "GPU" if torch.cuda.is_available() else "CPU"
218
- }
219
-
220
- info_text = "## πŸ–₯️ System Information\n\n"
221
- for key, value in info.items():
222
- info_text += f"- **{key}**: {value}\n"
223
-
224
- return info_text
225
 
226
- def create_interface():
227
- """Create the Gradio interface."""
228
-
229
- with gr.Blocks(title="GLM-4.5V CAD Generator", theme=gr.themes.Soft()) as demo:
230
- gr.Markdown("""
231
- # πŸ”§ GLM-4.5V CAD Generator
232
-
233
- Upload a 3D CAD model image and generate CADQuery Python code using GLM-4.5V models!
234
-
235
- **Available Models:**
236
- - **GLM-4.5V-AWQ**: AWQ quantized (fastest startup)
237
- - **GLM-4.5V-FP8**: 8-bit quantized (balanced)
238
- - **GLM-4.5V**: Full precision (best quality)
239
- """)
240
-
241
- with gr.Tab("πŸš€ Generate"):
242
- with gr.Row():
243
- with gr.Column(scale=1):
244
- image_input = gr.Image(
245
- type="pil",
246
- label="Upload CAD Model Image",
247
- height=400
248
- )
249
-
250
- model_choice = gr.Dropdown(
251
- choices=["GLM-4.5V-AWQ", "GLM-4.5V-FP8", "GLM-4.5V"],
252
- value="GLM-4.5V-AWQ",
253
- label="Select Model"
254
- )
255
-
256
- prompt_style = gr.Dropdown(
257
- choices=["Simple", "Detailed", "Chain-of-Thought"],
258
- value="Chain-of-Thought",
259
- label="Prompt Style"
260
- )
261
-
262
- generate_btn = gr.Button("πŸš€ Generate CADQuery Code", variant="primary", size="lg")
263
-
264
- with gr.Column(scale=2):
265
- output_text = gr.Markdown(
266
- label="Generated Code",
267
- value="Upload an image and click 'Generate' to start!"
268
- )
269
-
270
- generate_btn.click(
271
- fn=generate_cadquery_code,
272
- inputs=[image_input, model_choice, prompt_style],
273
- outputs=output_text
274
- )
275
-
276
- with gr.Tab("πŸ§ͺ Test"):
277
- with gr.Row():
278
- with gr.Column():
279
- test_model_choice = gr.Dropdown(
280
- choices=["GLM-4.5V-AWQ", "GLM-4.5V-FP8", "GLM-4.5V"],
281
- value="GLM-4.5V-AWQ",
282
- label="Model to Test"
283
- )
284
- test_btn = gr.Button("πŸ§ͺ Test Model Loading", variant="secondary")
285
-
286
- with gr.Column():
287
- test_output = gr.Markdown(value="Click 'Test Model Loading' to check if models work.")
288
 
289
- test_btn.click(
290
- fn=test_model_loading,
291
- inputs=test_model_choice,
292
- outputs=test_output
293
- )
294
 
295
- with gr.Tab("βš™οΈ System"):
296
- info_output = gr.Markdown()
297
- refresh_btn = gr.Button("πŸ”„ Refresh System Info")
 
 
 
 
 
 
 
 
 
 
 
 
298
 
299
- demo.load(fn=get_system_info, outputs=info_output)
300
- refresh_btn.click(fn=get_system_info, outputs=info_output)
301
 
302
- with gr.Tab("πŸ“– Help"):
303
- gr.Markdown("""
304
- ## 🎯 How to Use
305
-
306
- 1. **Upload Image**: Clear 3D CAD model images work best
307
- 2. **Select Model**: GLM-4.5V-AWQ is fastest for testing
308
- 3. **Choose Prompt**: Chain-of-Thought usually gives best results
309
- 4. **Generate**: Click the button and wait for results
310
-
311
- ## πŸ’‘ Tips for Best Results
312
-
313
- - Use clear, well-lit CAD images
314
- - Simple geometric shapes work better than complex assemblies
315
- - Try different prompt styles if first attempt isn't satisfactory
316
-
317
- ## πŸ”§ Using Generated Code
318
-
319
- ```bash
320
- # Install CADQuery
321
- pip install cadquery
322
-
323
- # Run your generated code
324
- python your_cad_script.py
325
-
326
- # Export to STL
327
- cq.exporters.export(result, "model.stl")
328
- ```
329
-
330
- ## πŸ–₯️ Hardware Requirements
331
-
332
- - This app runs on GPU-enabled Hugging Face Spaces
333
- - First model load takes 5-10 minutes
334
- - Generation takes 15-45 seconds per image
335
- """)
336
 
337
- return demo
 
 
 
 
 
338
 
339
  if __name__ == "__main__":
340
  print("πŸš€ Starting GLM-4.5V CAD Generator...")
341
  print(f"CUDA available: {torch.cuda.is_available()}")
342
- print(f"PyTorch version: {torch.__version__}")
343
-
344
- demo = create_interface()
345
- demo.launch(
346
- server_name="0.0.0.0",
347
- server_port=7860,
348
- show_error=True
349
- )
 
6
  import time
7
  import traceback
8
 
9
+ # Global model storage for Zero GPU compatibility
10
  models = {}
11
 
12
  @spaces.GPU(duration=300)
13
+ def load_model_on_gpu(model_choice):
14
+ """Load GLM model on GPU - separated for clarity."""
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
 
21
+ model_name = model_map.get(model_choice)
22
+ if not model_name:
23
+ return False, f"Unknown model: {model_choice}"
24
 
25
  if model_name in models:
26
  return True, f"βœ… {model_choice} already loaded"
 
30
  "image-text-to-text",
31
  model=model_name,
32
  device_map="auto",
33
+ torch_dtype=torch.float16,
34
  trust_remote_code=True
35
  )
 
36
  models[model_name] = pipe
37
  return True, f"βœ… {model_choice} loaded successfully"
 
38
  except Exception as e:
39
+ return False, f"❌ Failed to load {model_choice}: {str(e)[:200]}"
 
40
 
41
  @spaces.GPU(duration=120)
42
+ def generate_code(image, model_choice, prompt_style):
43
+ """Generate CADQuery code - main GPU function."""
 
44
  if image is None:
45
  return "❌ Please upload an image first."
46
 
47
+ # Create prompts
48
+ prompts = {
49
+ "Simple": "Generate CADQuery Python code for this 3D model:",
50
+ "Detailed": "Analyze this 3D CAD model and generate Python CADQuery code.\n\nRequirements:\n- Import cadquery as cq\n- Store result in 'result' variable\n- Use proper CADQuery syntax\n\nCode:",
51
+ "Chain-of-Thought": "Analyze this 3D CAD model step by step:\n\nStep 1: Identify the basic geometry\nStep 2: Note any features\nStep 3: Generate clean CADQuery Python code\n\n```python\nimport cadquery as cq\n\n# Generated code:"
52
+ }
53
+
54
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  # Load model if needed
56
  model_map = {
57
  "GLM-4.5V-AWQ": "QuantTrio/GLM-4.5V-AWQ",
 
61
 
62
  model_name = model_map[model_choice]
63
 
 
64
  if model_name not in models:
65
  pipe = pipeline(
66
  "image-text-to-text",
67
  model=model_name,
68
+ device_map="auto",
69
  torch_dtype=torch.float16,
70
  trust_remote_code=True
71
  )
 
74
  pipe = models[model_name]
75
 
76
  # Generate
77
+ messages = [{
78
+ "role": "user",
79
+ "content": [
80
+ {"type": "image", "image": image},
81
+ {"type": "text", "text": prompts[prompt_style]}
82
+ ]
83
+ }]
 
 
 
 
84
 
85
+ result = pipe(messages, max_new_tokens=512, temperature=0.7)
86
 
87
  if isinstance(result, list) and len(result) > 0:
88
  generated_text = result[0].get("generated_text", str(result))
89
  else:
90
  generated_text = str(result)
91
 
92
+ # Simple code extraction
93
+ code = generated_text.strip()
94
+ if "```python" in code:
95
+ start = code.find("```python") + 9
96
+ end = code.find("```", start)
97
+ if end > start:
98
+ code = code[start:end].strip()
99
 
100
+ if "import cadquery" not in code:
101
+ code = "import cadquery as cq\n\n" + code
102
+
103
+ return f"""## 🎯 Generated CADQuery Code
104
 
105
  ```python
106
+ {code}
107
  ```
108
 
109
+ ## πŸ“Š Info
110
  - **Model**: {model_choice}
 
111
  - **Prompt**: {prompt_style}
112
  - **Device**: {"GPU" if torch.cuda.is_available() else "CPU"}
113
 
 
116
  pip install cadquery
117
  python your_script.py
118
  ```
 
 
 
119
  """
120
 
 
 
121
  except Exception as e:
122
+ return f"❌ **Generation Failed**: {str(e)[:500]}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
+ def test_model(model_choice):
125
+ """Test model loading."""
126
+ success, message = load_model_on_gpu(model_choice)
127
  return f"## Test Result\n\n{message}"
128
 
129
+ def system_info():
130
+ """Get system info."""
131
+ info = f"""## πŸ–₯️ System Information
 
 
 
 
 
 
 
 
 
 
 
132
 
133
+ - **CUDA Available**: {torch.cuda.is_available()}
134
+ - **CUDA Devices**: {torch.cuda.device_count() if torch.cuda.is_available() else 0}
135
+ - **PyTorch Version**: {torch.__version__}
136
+ - **Device**: {"GPU" if torch.cuda.is_available() else "CPU"}
137
+ """
138
+ return info
139
+
140
+ # Create interface
141
+ with gr.Blocks(title="GLM-4.5V CAD Generator", theme=gr.themes.Soft()) as demo:
142
+ gr.Markdown("""
143
+ # πŸ”§ GLM-4.5V CAD Generator
144
+
145
+ Generate CADQuery Python code from 3D CAD model images using GLM-4.5V models!
146
+
147
+ **Models**: GLM-4.5V-AWQ (fastest) | GLM-4.5V-FP8 (balanced) | GLM-4.5V (best quality)
148
+ """)
149
+
150
+ with gr.Tab("πŸš€ Generate"):
151
+ with gr.Row():
152
+ with gr.Column():
153
+ image_input = gr.Image(type="pil", label="Upload CAD Model Image")
154
+ model_choice = gr.Dropdown(
155
+ choices=["GLM-4.5V-AWQ", "GLM-4.5V-FP8", "GLM-4.5V"],
156
+ value="GLM-4.5V-AWQ",
157
+ label="Select Model"
158
+ )
159
+ prompt_style = gr.Dropdown(
160
+ choices=["Simple", "Detailed", "Chain-of-Thought"],
161
+ value="Chain-of-Thought",
162
+ label="Prompt Style"
163
+ )
164
+ generate_btn = gr.Button("πŸš€ Generate CADQuery Code", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
 
166
+ with gr.Column():
167
+ output = gr.Markdown("Upload an image and click Generate!")
 
 
 
168
 
169
+ generate_btn.click(
170
+ fn=generate_code,
171
+ inputs=[image_input, model_choice, prompt_style],
172
+ outputs=output
173
+ )
174
+
175
+ with gr.Tab("πŸ§ͺ Test"):
176
+ with gr.Row():
177
+ with gr.Column():
178
+ test_model_choice = gr.Dropdown(
179
+ choices=["GLM-4.5V-AWQ", "GLM-4.5V-FP8", "GLM-4.5V"],
180
+ value="GLM-4.5V-AWQ",
181
+ label="Model to Test"
182
+ )
183
+ test_btn = gr.Button("πŸ§ͺ Test Model")
184
 
185
+ with gr.Column():
186
+ test_output = gr.Markdown("Click Test Model to check loading.")
187
 
188
+ test_btn.click(fn=test_model, inputs=test_model_choice, outputs=test_output)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
 
190
+ with gr.Tab("βš™οΈ System"):
191
+ info_display = gr.Markdown()
192
+ refresh_btn = gr.Button("πŸ”„ Refresh")
193
+
194
+ demo.load(fn=system_info, outputs=info_display)
195
+ refresh_btn.click(fn=system_info, outputs=info_display)
196
 
197
  if __name__ == "__main__":
198
  print("πŸš€ Starting GLM-4.5V CAD Generator...")
199
  print(f"CUDA available: {torch.cuda.is_available()}")
200
+ demo.launch(share=True, show_error=True)