File size: 6,388 Bytes
17cb954
6c099d4
d342157
 
6c099d4
 
a40099d
5c2cf00
a40099d
 
40399e0
aa58139
a40099d
aa58139
 
a40099d
aa58139
a40099d
 
 
aa58139
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a40099d
aa58139
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a40099d
aa58139
a40099d
aa58139
a40099d
aa58139
 
 
 
 
 
a40099d
 
aa58139
 
a40099d
 
 
 
6c099d4
a40099d
6c099d4
01c81d6
 
 
 
 
 
 
 
 
e117cef
 
 
 
 
 
 
 
 
 
01c81d6
6c099d4
a40099d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6c099d4
a40099d
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import spaces
import os
import sys
import subprocess
import gradio as gr

# ======= ВЫНОСИМ УСТАНОВКУ ДО ИНИЦИАЛИЗАЦИИ GPU =======

def _install_dependencies():
    """Устанавливает зависимости ЕДИНОРАЗОВО перед запуском GPU"""
    if not os.environ.get("DETECTRON2_INSTALLED"):
        print("🔧 Installing dependencies...")
        
        # 1. ОСНОВНЫЕ ЗАВИСИМОСТИ (без компиляции)
        print("📦 Installing core dependencies...")
        subprocess.check_call([
            sys.executable, "-m", "pip", "install",
            "mmcv>=1.4.0,<2.0.0", "cython", "shapely", "timm", "h5py", "scikit-image"
        ])
        
        # 2. pytorch3d - устанавливаем БЕЗ компиляции
        print("📦 Installing pytorch3d (no compilation)...")
        try:
            # Вариант 1: Предварительно собранные wheels
            subprocess.check_call([
                sys.executable, "-m", "pip", "install",
                "fvcore", "iopath", "ninja"
            ])
            
            # Скачиваем готовый wheel для pytorch3d
            subprocess.check_call([
                sys.executable, "-m", "pip", "install",
                "--find-links", "https://dl.fbaipublicfiles.com/pytorch3d/packaging/wheels/py310_cu118_pyt208/download.html",
                "pytorch3d==0.7.4"
            ])
        except:
            # Вариант 2: Упрощённая установка
            print("⚠️  Using simplified pytorch3d installation...")
            subprocess.check_call([
                sys.executable, "-m", "pip", "install",
                "git+https://github.com/facebookresearch/pytorch3d.git@stable",
                "--no-build-isolation", "--no-deps"
            ])
        
        # 3. Detectron2 - ТОЛЬКО установка, без компиляции
        print("📦 Installing detectron2...")
        try:
            # Если есть локальная копия, устанавливаем БЕЗ компиляции
            if os.path.exists("MaskClustering/third_party/detectron2"):
                print("📂 Found local detectron2, installing...")
                # Ключевое: устанавливаем без сборки C++/CUDA компонентов
                os.environ["FORCE_CUDA"] = "0"
                os.environ["BUILD_CPP_TESTS"] = "0"
                
                subprocess.check_call([
                    sys.executable, "-m", "pip", "install",
                    "-e", "MaskClustering/third_party/detectron2",
                    "--no-build-isolation"
                ], env={**os.environ, "FORCE_CUDA": "0"})
            else:
                # Устанавливаем готовую версию
                subprocess.check_call([
                    sys.executable, "-m", "pip", "install",
                    "detectron2==0.6", "--no-deps"
                ])
        except Exception as e:
            print(f"⚠️  Detectron2 installation warning: {e}")
        
        # 4. ВАЖНО: ПРОПУСКАЕМ ВСЮ КОМПИЛЯЦИЮ CUDA!
        print("⚠️  Skipping ALL CUDA compilation in ZeroGPU environment")
        print("ℹ️  MSDeformAttn and other CUDA ops will run in fallback CPU mode")
        
        # Создаём файл-заглушку для CUDA компонентов
        repo_root = os.path.dirname(os.path.abspath(__file__))
        cuda_ops_dir = os.path.join(repo_root, "MaskClustering/third_party/detectron2/projects/CropFormer/mask2former/modeling/pixel_decoder/ops")
        
        if os.path.exists(cuda_ops_dir):
            # Создаём простой __init__.py чтобы импорт не падал
            init_file = os.path.join(cuda_ops_dir, "__init__.py")
            with open(init_file, "w") as f:
                f.write("# CUDA ops disabled in ZeroGPU environment\n")
                f.write("print('CUDA ops running in CPU fallback mode')\n")
        
        os.environ["DETECTRON2_INSTALLED"] = "1"
        os.environ["FORCE_CUDA"] = "0"  # КРИТИЧЕСКИ ВАЖНО!
        print("✅ All dependencies installed (CUDA compilation SKIPPED)!")
        return True
    
    print("✅ Dependencies already installed.")
    return False

# ======= СНАЧАЛА УСТАНАВЛИВАЕМ ВСЁ =======

# Ключевые переменные окружения ДО импорта torch
os.environ["FORCE_CUDA"] = "0"
os.environ["CUDA_VISIBLE_DEVICES"] = ""
os.environ["GRADIO_ANALYTICS_ENABLED"] = "False"

# Фикс для асинхронной очереди Gradio
os.environ["GRADIO_QUEUE_ENABLED"] = "False"

@spaces.GPU()
def run_app():
    import mvp
    port = int(os.getenv("PORT", "7860"))
    mvp.demo.launch(
        server_name="0.0.0.0",
        server_port=port,
        show_error=True,
        share=False,
        show_api=False,
    )

if __name__ == "__main__":
    # Первый запуск: установка зависимостей
    if not os.environ.get("DETECTRON2_INSTALLED"):
        print("🚀 First run: installing dependencies...")
        _install_dependencies()
        print("🔄 Restarting application...")
        
        # Перезапускаем приложение
        os.execv(sys.executable, [sys.executable] + sys.argv)
    else:
        # Второй запуск: запускаем GPU-приложение
        print("🚀 Starting GPU application...")
        
        # Патч для gradio_client (оставляем как есть)
        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

        # ======= ТЕПЕРЬ GPU ИНИЦИАЛИЗИРУЕТСЯ ПРАВИЛЬНО =======
        
        # Запускаем приложение
        run_app()