import os import sys import subprocess import gradio as gr def _launch(): # Check if we need to install detectron2 and dependencies (first run only) if not os.environ.get("DETECTRON2_INSTALLED"): print("🔧 Installing CropFormer dependencies...") try: # Install CropFormer/Mask2Former dependencies subprocess.check_call([ sys.executable, "-m", "pip", "install", "mmcv>=1.4.0,<2.0.0", "cython", "shapely", "timm", "h5py", "scikit-image" ]) subprocess.check_call([ sys.executable, "-m", "pip", "install", "--no-build-isolation", "git+https://github.com/facebookresearch/pytorch3d.git" ]) print("✅ CropFormer dependencies installed!") print("🔧 Installing detectron2 from vendored source...") subprocess.check_call([ sys.executable, "-m", "pip", "install", "--no-build-isolation", "-e", "MaskClustering/third_party/detectron2" ]) print("✅ detectron2 installed successfully!") # Compile CropFormer components repo_root = os.path.dirname(os.path.abspath(__file__)) cropformer_root = os.path.join(repo_root, "MaskClustering/third_party/detectron2/projects/CropFormer") # 1. Compile entity_api PythonAPI print("🔧 Compiling entity_api PythonAPI...") entity_api_dir = os.path.join(cropformer_root, "entity_api/PythonAPI") if os.path.exists(entity_api_dir): try: subprocess.check_call(["make"], cwd=entity_api_dir, shell=True) print("✅ entity_api compiled successfully!") except subprocess.CalledProcessError as e: print(f"⚠️ entity_api compilation failed (non-critical): {e}") else: print(f"⚠️ entity_api directory not found: {entity_api_dir}") # 2. Compile MSDeformAttn CUDA ops print("🔧 Compiling MSDeformAttn CUDA operators...") ops_dir = os.path.join(cropformer_root, "mask2former/modeling/pixel_decoder/ops") if os.path.exists(ops_dir): try: # Try with CUDA first subprocess.check_call(["sh", "make.sh"], cwd=ops_dir) print("✅ MSDeformAttn ops compiled successfully!") except subprocess.CalledProcessError as e: print(f"⚠️ CUDA compilation failed, trying CPU-only mode: {e}") try: # Fallback to CPU-only build subprocess.check_call( ["python", "setup.py", "build", "install"], cwd=ops_dir, env={**os.environ, "FORCE_CUDA": "0"} ) print("✅ MSDeformAttn ops compiled (CPU mode)!") except subprocess.CalledProcessError as e2: print(f"⚠️ MSDeformAttn compilation failed (non-critical): {e2}") else: print(f"⚠️ MSDeformAttn ops directory not found: {ops_dir}") print("🔄 Restarting to load detectron2...") # Set environment variable to avoid reinstalling on restart os.environ["DETECTRON2_INSTALLED"] = "1" # Restart the script os.execv(sys.executable, [sys.executable] + sys.argv) except subprocess.CalledProcessError as e: print(f"❌ Failed to install dependencies: {e}") raise else: # Second run: verify imports work print("🔍 Verifying detectron2 and mmcv imports...") try: import detectron2 import mmcv print(f"✅ detectron2 available (version: {getattr(detectron2, '__version__', 'unknown')})") print(f"✅ mmcv available (version: {getattr(mmcv, '__version__', 'unknown')})") except ImportError as e: print(f"❌ Required module cannot be imported: {e}") print(f" sys.path: {sys.path}") raise # HF Spaces/Gradio sometimes calls /api_info regardless of `show_api=False`. # Some gradio_client versions crash when JSON schema uses boolean `additionalProperties`. # Patch defensively to avoid bringing down the whole app. try: import gradio_client.utils as _gcu if hasattr(_gcu, "_json_schema_to_python_type"): _orig = _gcu._json_schema_to_python_type def _json_schema_to_python_type_patched(schema, defs=None): if isinstance(schema, bool): return "Any" return _orig(schema, defs) _gcu._json_schema_to_python_type = _json_schema_to_python_type_patched except Exception: pass # HF Spaces expects the app to listen on 0.0.0.0:7860 (PORT may be provided). import mvp port = int(os.getenv("PORT", "7860")) # `mvp` defines `demo` (gr.Blocks). We launch it here instead of inside `mvp.py`. mvp.demo.queue(max_size=20).launch( server_name="0.0.0.0", server_port=port, show_error=True, share=False, show_api=False, ) if __name__ == "__main__": _launch()