Spaces:
Sleeping
Sleeping
File size: 8,704 Bytes
c02bf22 49d1739 af8fde2 890aef1 a4209fa c02bf22 49d1739 e053144 a4209fa c02bf22 e053144 a4209fa e053144 04532d1 c02bf22 e053144 c02bf22 e053144 c02bf22 e053144 c02bf22 38be658 a4209fa c02bf22 a4209fa c02bf22 a4209fa c02bf22 a4209fa c02bf22 a4209fa e053144 c02bf22 04532d1 c02bf22 04532d1 c02bf22 e053144 c02bf22 8037a7c e053144 8037a7c e053144 8037a7c e053144 af8fde2 e053144 c02bf22 04532d1 c02bf22 04532d1 e053144 c02bf22 890aef1 e053144 890aef1 c02bf22 e053144 c02bf22 e053144 c02bf22 e053144 c02bf22 a4209fa af8fde2 c02bf22 af8fde2 953ea94 e053144 953ea94 c02bf22 331812c |
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 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
#!/usr/bin/env python3
import gradio as gr
import subprocess
from pathlib import Path
import torch
import os
import logging
import sys
import spaces
# Logging konfigurieren
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
class InfinigenManager:
def __init__(self, base_dir="infinigen", output_dir="outputs", blender_version="4.3.2"):
"""Initialisiert den InfinigenManager mit Basisverzeichnis, Ausgabeverzeichnis und Blender-Version."""
self.base_dir = Path(base_dir)
self.output_dir = Path(output_dir)
self.blender_version = blender_version
self.blender_bin = None
self.blender_python = None
self.initialized = False
logger.info("Initialisiere InfinigenManager...")
self._initialize()
def _run_command(self, command, error_msg="Fehler bei Befehlsausführung", timeout=None):
"""Führt Befehle einheitlich aus und behandelt Fehler."""
try:
result = subprocess.run(
command,
shell=isinstance(command, str),
capture_output=True,
text=True,
check=True,
timeout=timeout
)
logger.debug(f"STDOUT: {result.stdout}")
return result
except subprocess.CalledProcessError as e:
logger.error(f"{error_msg}: {e.stderr}")
raise
except subprocess.TimeoutExpired as e:
logger.error(f"{error_msg} (Timeout): {e.stderr}")
raise
def _initialize(self):
"""Führt die zentrale Initialisierung durch."""
try:
self._setup_blender()
self._setup_infinigen()
self._check_cuda()
self.initialized = True
logger.info("Initialisierung erfolgreich abgeschlossen.")
except Exception as e:
logger.error(f"Initialisierung fehlgeschlagen: {e}")
self.initialized = False
def _setup_blender(self):
"""Richtet Blender und dessen Python-Interpreter ein."""
logger.info("Starte Blender-Setup...")
self.blender_bin = self._find_blender() or self._install_latest_blender()
self.blender_python = self._find_blender_python_with_grep()
if not self.blender_python:
raise RuntimeError("Blender Python-Interpreter nicht gefunden!")
logger.info(f"Blender Python gefunden: {self.blender_python}")
def _find_blender(self):
"""Sucht nach einer vorhandenen Blender-Installation."""
blender_paths = [
f"/home/user/blender-{self.blender_version}-linux-x64/blender",
"/usr/bin/blender"
]
for bin_path in blender_paths:
if os.path.exists(bin_path):
try:
version_result = self._run_command([bin_path, "-v"], "Kann Blender-Version nicht prüfen", timeout=10)
version = next((line.split()[1] for line in version_result.stdout.split("\n")
if "Blender" in line and "." in line), None)
logger.info(f"Vorhandene Blender-Version: {version or 'unbekannt'}")
if version and version >= self.blender_version:
return bin_path
except Exception as e:
logger.warning(f"Fehler bei Blender-Prüfung ({bin_path}): {e}")
return None
def _install_latest_blender(self):
"""Installiert Blender 4.3.2, falls nicht vorhanden."""
logger.info("Installiere Blender 4.3.2...")
url = "https://download.blender.org/release/Blender4.3/blender-4.3.2-linux-x64.tar.xz"
tar_path = "blender-4.3.2-linux-x64.tar.xz"
blender_dir = Path(f"/home/user/blender-{self.blender_version}-linux-x64")
self._run_command(f"wget -q {url}", "Fehler beim Herunterladen von Blender", timeout=60)
self._run_command(f"tar -xvf {tar_path} -C /home/user", "Fehler beim Entpacken von Blender", timeout=60)
os.remove(tar_path)
return blender_dir / "blender"
def _find_blender_python_with_grep(self):
"""Sucht den Blender-Python-Pfad mit find."""
base_path = Path(self.blender_bin).parent.parent
grep_cmd = f"find {base_path} -type f -path '*/python/bin/python3*' -executable"
try:
result = self._run_command(grep_cmd, "Fehler bei der Python-Suche mit find")
python_paths = result.stdout.strip().split("\n")
for path in python_paths:
if path:
version_result = self._run_command([path, "--version"], "Fehler bei Python-Version", timeout=5)
logger.info(f"Python-Version: {version_result.stdout.strip()}")
return path
logger.warning("Kein passender Python-Pfad in find-Ausgabe gefunden.")
return None
except Exception as e:
logger.error(f"Fehler bei der Suche nach Blender-Python: {e}")
return None
def _check_cuda(self):
"""Prüft die CUDA-Verfügbarkeit für GPU-Nutzung."""
cuda_available = torch.cuda.is_available()
logger.info(f"CUDA {'verfügbar' if cuda_available else 'nicht verfügbar'}: {torch.cuda.get_device_name(0) if cuda_available else 'N/A'}")
def _setup_infinigen(self):
"""Richtet Infinigen ein, falls nicht installiert."""
if not self.blender_python:
logger.error("Kann Infinigen nicht installieren: Blender Python fehlt.")
return
logger.info("Starte Infinigen-Setup...")
if not self.base_dir.exists():
self._run_command(f"git clone https://github.com/princeton-vl/infinigen.git {self.base_dir}",
"Fehler beim Klonen von Infinigen", timeout=30)
# Installiere Infinigen mit Abhängigkeiten
self._run_command([
self.blender_python, "-m", "pip", "install", "-e", f"{self.base_dir}[terrain,vis]", "--user"
], "Fehler bei der Installation von Infinigen", timeout=60)
# Überprüfe, ob das datagen-Modul verfügbar ist
if not self._is_datagen_available():
raise RuntimeError("Das 'datagen'-Modul von Infinigen ist nicht verfügbar. Überprüfe die Installation.")
def _is_datagen_available(self):
"""Prüft, ob das 'datagen'-Modul von Infinigen verfügbar ist."""
try:
self._run_command([self.blender_python, "-c", "import infinigen.datagen"], timeout=10)
return True
except Exception as e:
logger.error(f"Fehler beim Import von 'infinigen.datagen': {e}")
return False
@spaces.GPU
def generate_scene(self, seed, configs=None, pipeline_configs=None):
"""Generiert eine Szene mit Infinigen auf der GPU."""
if not self.initialized or not self.blender_python:
return "Fehler: Infinigen nicht initialisiert!"
logger.info(f"Generiere Szene mit Seed: {seed}")
self.output_dir.mkdir(exist_ok=True)
configs = configs or ["infinigen_examples/configs/desert.gin", "infinigen_examples/configs/simple.gin"]
pipeline_configs = pipeline_configs or [
"infinigen_examples/configs/local_16GB.gin",
"infinigen_examples/configs/monocular.gin",
"infinigen_examples/configs/blender_gt.gin"
]
command = [
self.blender_python, "-m", "infinigen.datagen.manage_jobs",
"--output_folder", str(self.output_dir),
"--num_scenes", "1",
"--specific_seed", str(int(seed)),
"--configs"
] + configs + ["--pipeline_configs"] + pipeline_configs
try:
self._run_command(command, "Fehler bei Szenengenerierung", timeout=300)
output_path = self.output_dir / "0000000000.png"
return str(output_path) if output_path.exists() else "Fehler: Bild nicht gefunden!"
except Exception as e:
return f"Fehler bei Szenengenerierung: {str(e)}"
# Manager initialisieren
logger.info("Starte Manager-Initialisierung...")
manager = InfinigenManager()
# Gradio-Oberfläche definieren
with gr.Blocks(title="Infinigen Demo") as demo:
gr.Markdown("## Infinigen Scene Generator")
seed_input = gr.Number(label="Seed", value=0, precision=0)
output_image = gr.Image(label="Generierte Szene")
generate_button = gr.Button("Szene generieren")
generate_button.click(fn=manager.generate_scene, inputs=[seed_input], outputs=[output_image])
logger.info("Starte Gradio-Oberfläche...")
demo.launch() |