bulatko commited on
Commit
8ff8722
Β·
1 Parent(s): f1a83d5

Deploy Zoo3D with Zero GPU support

Browse files
Files changed (5) hide show
  1. app.py +9 -1
  2. mvp.py +7 -3
  3. packages.txt +3 -6
  4. requirements.txt +3 -5
  5. verify_deployment.py +227 -0
app.py CHANGED
@@ -3,15 +3,23 @@ import sys
3
  import subprocess
4
 
5
  # Check if we're running on HF Spaces with Zero GPU
6
- IS_ZERO_GPU = os.environ.get("ZERO_GPU_MODE", "0") == "1" or os.environ.get("SPACES_ZERO_GPU", "0") == "1"
 
 
 
 
 
7
 
8
  # Try to import spaces for Zero GPU support
 
9
  try:
10
  import spaces
11
  HAS_SPACES = True
 
12
  except ImportError:
13
  HAS_SPACES = False
14
  spaces = None
 
15
 
16
  import gradio as gr
17
 
 
3
  import subprocess
4
 
5
  # Check if we're running on HF Spaces with Zero GPU
6
+ # HF Spaces sets SPACE_ID environment variable
7
+ IS_HF_SPACE = bool(os.environ.get("SPACE_ID"))
8
+ IS_ZERO_GPU = IS_HF_SPACE or os.environ.get("ZERO_GPU_MODE", "0") == "1" or os.environ.get("SPACES_ZERO_GPU", "0") == "1"
9
+
10
+ if IS_HF_SPACE:
11
+ print(f"πŸ€— Running on Hugging Face Space: {os.environ.get('SPACE_ID')}")
12
 
13
  # Try to import spaces for Zero GPU support
14
+ # Note: spaces is provided by HF Spaces environment, not from pip
15
  try:
16
  import spaces
17
  HAS_SPACES = True
18
+ print("βœ… Spaces module available - Zero GPU support enabled")
19
  except ImportError:
20
  HAS_SPACES = False
21
  spaces = None
22
+ print("ℹ️ Spaces module not available - running without Zero GPU")
23
 
24
  import gradio as gr
25
 
mvp.py CHANGED
@@ -26,16 +26,19 @@ import contextlib
26
  from huggingface_hub import hf_hub_download
27
 
28
  # Check if we're running on HF Spaces with Zero GPU
29
- IS_ZERO_GPU = os.environ.get("ZERO_GPU_MODE", "0") == "1" or os.environ.get("SPACES_ZERO_GPU", "0") == "1"
 
 
30
 
31
  # Try to import spaces for Zero GPU support
 
32
  try:
33
  import spaces
34
  HAS_SPACES = True
 
35
  except ImportError:
36
  HAS_SPACES = False
37
- spaces = None
38
- # Create dummy decorator if spaces not available
39
  class DummySpaces:
40
  @staticmethod
41
  def GPU(duration=60):
@@ -43,6 +46,7 @@ except ImportError:
43
  return func
44
  return decorator
45
  spaces = DummySpaces()
 
46
 
47
  # Import CropFormer runner for direct inference
48
  from exts import cropformer_runner
 
26
  from huggingface_hub import hf_hub_download
27
 
28
  # Check if we're running on HF Spaces with Zero GPU
29
+ # HF Spaces sets SPACE_ID environment variable
30
+ IS_HF_SPACE = bool(os.environ.get("SPACE_ID"))
31
+ IS_ZERO_GPU = IS_HF_SPACE or os.environ.get("ZERO_GPU_MODE", "0") == "1" or os.environ.get("SPACES_ZERO_GPU", "0") == "1"
32
 
33
  # Try to import spaces for Zero GPU support
34
+ # Note: spaces is provided by HF Spaces environment, not from pip
35
  try:
36
  import spaces
37
  HAS_SPACES = True
38
+ print("βœ… Spaces module available in mvp.py - Zero GPU decorators active")
39
  except ImportError:
40
  HAS_SPACES = False
41
+ # Create dummy decorator if spaces not available (for local testing)
 
42
  class DummySpaces:
43
  @staticmethod
44
  def GPU(duration=60):
 
46
  return func
47
  return decorator
48
  spaces = DummySpaces()
49
+ print("ℹ️ Using dummy spaces decorators (local mode)")
50
 
51
  # Import CropFormer runner for direct inference
52
  from exts import cropformer_runner
packages.txt CHANGED
@@ -1,9 +1,6 @@
1
- build-essential
2
- python3-dev
3
- git
4
- cmake
5
- make
6
- ninja-build
7
  ffmpeg
 
 
8
  libgl1
9
  libglib2.0-0
 
 
 
 
 
 
 
 
1
  ffmpeg
2
+ libsm6
3
+ libxext6
4
  libgl1
5
  libglib2.0-0
6
+ libgomp1
requirements.txt CHANGED
@@ -1,8 +1,6 @@
1
- # HF Spaces support (optional)
2
- spaces>=0.19.0
3
-
4
- torch==2.3.1
5
- torchvision==0.18.1
6
  numpy==1.26.1
7
  Pillow
8
  huggingface_hub
 
1
+ # PyTorch - using version compatible with Zero GPU
2
+ torch==2.2.0
3
+ torchvision==0.17.0
 
 
4
  numpy==1.26.1
5
  Pillow
6
  huggingface_hub
verify_deployment.py ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Verification script to check if the project is ready for Zero GPU deployment
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ import re
9
+
10
+ def check_file_exists(filepath, required=True):
11
+ """Check if a file exists"""
12
+ exists = os.path.exists(filepath)
13
+ status = "βœ…" if exists else ("❌" if required else "⚠️")
14
+ print(f"{status} {filepath}: {'Found' if exists else 'Missing'}")
15
+ return exists
16
+
17
+ def check_pytorch_version():
18
+ """Check PyTorch version in requirements.txt"""
19
+ print("\nπŸ“¦ Checking PyTorch version...")
20
+
21
+ with open("requirements.txt", "r") as f:
22
+ content = f.read()
23
+
24
+ # Look for torch version
25
+ torch_match = re.search(r"torch==(\d+\.\d+\.\d+)", content)
26
+ if torch_match:
27
+ version = torch_match.group(1)
28
+ if version == "2.2.0":
29
+ print(f"βœ… PyTorch version {version} is compatible with Zero GPU")
30
+ return True
31
+ else:
32
+ print(f"❌ PyTorch version {version} may not be compatible with Zero GPU")
33
+ print(" Recommended: torch==2.2.0")
34
+ return False
35
+ else:
36
+ print("❌ PyTorch version not found in requirements.txt")
37
+ return False
38
+
39
+ def check_spaces_not_in_requirements():
40
+ """Check that spaces is NOT in requirements.txt"""
41
+ print("\nπŸ“¦ Checking spaces library...")
42
+
43
+ with open("requirements.txt", "r") as f:
44
+ content = f.read()
45
+
46
+ if "spaces" in content:
47
+ print("❌ 'spaces' found in requirements.txt - should be removed!")
48
+ print(" HF Spaces provides this automatically")
49
+ return False
50
+ else:
51
+ print("βœ… 'spaces' correctly not in requirements.txt")
52
+ return True
53
+
54
+ def check_gpu_decorators():
55
+ """Check for @spaces.GPU decorators"""
56
+ print("\n🎯 Checking GPU decorators...")
57
+
58
+ files_to_check = ["mvp.py"]
59
+ decorator_pattern = r"@spaces\.GPU"
60
+
61
+ for filepath in files_to_check:
62
+ if not os.path.exists(filepath):
63
+ print(f"⚠️ {filepath} not found")
64
+ continue
65
+
66
+ with open(filepath, "r") as f:
67
+ content = f.read()
68
+
69
+ decorators = re.findall(decorator_pattern, content)
70
+ if decorators:
71
+ print(f"βœ… {filepath}: Found {len(decorators)} @spaces.GPU decorators")
72
+
73
+ # Check specific functions
74
+ functions = ["run_model", "reconstruct", "detect_objects"]
75
+ for func in functions:
76
+ # Check if function has decorator
77
+ pattern = rf"@spaces\.GPU.*?\ndef {func}\("
78
+ if re.search(pattern, content, re.DOTALL):
79
+ print(f" βœ… {func}() has GPU decorator")
80
+ else:
81
+ print(f" ⚠️ {func}() might be missing GPU decorator")
82
+ else:
83
+ print(f"❌ {filepath}: No GPU decorators found")
84
+ return False
85
+
86
+ return True
87
+
88
+ def check_model_manager():
89
+ """Check for ModelManager implementation"""
90
+ print("\nπŸ”§ Checking ModelManager...")
91
+
92
+ with open("mvp.py", "r") as f:
93
+ content = f.read()
94
+
95
+ if "class ModelManager" in content:
96
+ print("βœ… ModelManager class found")
97
+
98
+ # Check for key methods
99
+ methods = ["get_vggt_model", "get_metric3d_model", "get_clip_model", "clear_cache"]
100
+ for method in methods:
101
+ if f"def {method}" in content:
102
+ print(f" βœ… {method}() method found")
103
+ else:
104
+ print(f" ❌ {method}() method missing")
105
+
106
+ # Check for global instance
107
+ if "model_manager = ModelManager()" in content:
108
+ print(" βœ… Global model_manager instance created")
109
+ else:
110
+ print(" ⚠️ Global model_manager instance not found")
111
+
112
+ return True
113
+ else:
114
+ print("❌ ModelManager class not found")
115
+ return False
116
+
117
+ def check_environment_variables():
118
+ """Check for Zero GPU environment variable handling"""
119
+ print("\n🌍 Checking environment variable handling...")
120
+
121
+ files = ["app.py", "mvp.py"]
122
+
123
+ for filepath in files:
124
+ with open(filepath, "r") as f:
125
+ content = f.read()
126
+
127
+ checks = {
128
+ "IS_HF_SPACE": "HF Space detection",
129
+ "IS_ZERO_GPU": "Zero GPU mode detection",
130
+ "MAX_IMAGES": "Image limit configuration",
131
+ "BATCH_SIZE": "Batch size configuration",
132
+ }
133
+
134
+ print(f"\n {filepath}:")
135
+ for var, description in checks.items():
136
+ if var in content:
137
+ print(f" βœ… {var}: {description}")
138
+ else:
139
+ print(f" ⚠️ {var}: {description} not found")
140
+
141
+ def check_readme_header():
142
+ """Check README header for HF Spaces"""
143
+ print("\nπŸ“„ Checking README configuration...")
144
+
145
+ if os.path.exists("README_HF.md"):
146
+ with open("README_HF.md", "r") as f:
147
+ content = f.read()
148
+
149
+ if content.startswith("---"):
150
+ # Extract YAML header
151
+ header_end = content.find("---", 3)
152
+ if header_end > 0:
153
+ header = content[3:header_end]
154
+
155
+ required_fields = {
156
+ "title:": "Title field",
157
+ "emoji:": "Emoji field",
158
+ "sdk: gradio": "Gradio SDK",
159
+ "app_file: app.py": "App file specification",
160
+ }
161
+
162
+ print("βœ… README_HF.md has YAML header")
163
+ for field, description in required_fields.items():
164
+ if field in header:
165
+ print(f" βœ… {description}")
166
+ else:
167
+ print(f" ❌ {description} missing")
168
+ else:
169
+ print("❌ README_HF.md YAML header not properly closed")
170
+ else:
171
+ print("❌ README_HF.md missing YAML header")
172
+ else:
173
+ print("❌ README_HF.md not found")
174
+
175
+ def main():
176
+ """Run all verification checks"""
177
+ print("=" * 60)
178
+ print("πŸ” Zoo3D Zero GPU Deployment Verification")
179
+ print("=" * 60)
180
+
181
+ # Check critical files
182
+ print("\nπŸ“ Checking required files...")
183
+ check_file_exists("app.py")
184
+ check_file_exists("mvp.py")
185
+ check_file_exists("requirements.txt")
186
+ check_file_exists("packages.txt")
187
+ check_file_exists("README_HF.md")
188
+ check_file_exists("ZERO_GPU_README.md", required=False)
189
+ check_file_exists("test_zero_gpu.py", required=False)
190
+
191
+ # Check configurations
192
+ pytorch_ok = check_pytorch_version()
193
+ spaces_ok = check_spaces_not_in_requirements()
194
+ decorators_ok = check_gpu_decorators()
195
+ model_manager_ok = check_model_manager()
196
+ check_environment_variables()
197
+ check_readme_header()
198
+
199
+ # Summary
200
+ print("\n" + "=" * 60)
201
+ print("πŸ“Š Summary")
202
+ print("=" * 60)
203
+
204
+ critical_checks = [pytorch_ok, spaces_ok, decorators_ok, model_manager_ok]
205
+
206
+ if all(critical_checks):
207
+ print("βœ… Project is ready for Zero GPU deployment!")
208
+ print("\nNext steps:")
209
+ print("1. Copy README_HF.md to README.md when deploying")
210
+ print("2. Push to Hugging Face Spaces with Zero GPU hardware")
211
+ print("3. Monitor logs for any runtime issues")
212
+ return 0
213
+ else:
214
+ print("❌ Some issues need to be fixed before deployment")
215
+ print("\nCritical issues to resolve:")
216
+ if not pytorch_ok:
217
+ print("- Update PyTorch to version 2.2.0")
218
+ if not spaces_ok:
219
+ print("- Remove 'spaces' from requirements.txt")
220
+ if not decorators_ok:
221
+ print("- Add @spaces.GPU decorators to GPU functions")
222
+ if not model_manager_ok:
223
+ print("- Implement ModelManager for lazy loading")
224
+ return 1
225
+
226
+ if __name__ == "__main__":
227
+ sys.exit(main())