|
|
|
""" |
|
Post-install script for Hugging Face Spaces |
|
This script installs complex dependencies that need PyTorch to be available first |
|
""" |
|
|
|
import os |
|
import sys |
|
import subprocess |
|
import shutil |
|
from pathlib import Path |
|
|
|
|
|
PYTORCH_VERSION = None |
|
CUDA_VERSION = None |
|
|
|
def run_command(command, cwd=None, env=None): |
|
"""Run a shell command and return the result""" |
|
print(f"Running: {command}") |
|
result = subprocess.run(command, shell=True, cwd=cwd, capture_output=True, text=True, env=env) |
|
if result.returncode != 0: |
|
print(f"Error running command: {command}") |
|
print(f"Error output: {result.stderr}") |
|
return False |
|
print(f"Success: {command}") |
|
return True |
|
|
|
def check_pytorch_cuda(): |
|
"""Check if PyTorch is installed with correct CUDA version""" |
|
try: |
|
import torch |
|
print(f"PyTorch version: {torch.__version__}") |
|
print(f"CUDA available: {torch.cuda.is_available()}") |
|
if torch.cuda.is_available(): |
|
print(f"CUDA version: {torch.version.cuda}") |
|
print(f"cuDNN version: {torch.backends.cudnn.version()}") |
|
return True |
|
except Exception as e: |
|
print(f"Error checking PyTorch: {e}") |
|
return False |
|
|
|
def install_torch_sparse(): |
|
"""Install torch-sparse with compatible PyTorch version""" |
|
print("Installing torch-sparse...") |
|
|
|
|
|
try: |
|
import torch_sparse |
|
print("torch-sparse already installed") |
|
return True |
|
except ImportError: |
|
pass |
|
|
|
|
|
try: |
|
import torch |
|
print(f"Current PyTorch version: {torch.__version__}") |
|
|
|
|
|
if "+" in torch.__version__: |
|
pytorch_base = torch.__version__.split("+")[0] |
|
cuda_version = torch.__version__.split("+")[1] |
|
else: |
|
pytorch_base = torch.__version__ |
|
cuda_version = "cpu" |
|
|
|
print(f"PyTorch base version: {pytorch_base}, CUDA: {cuda_version}") |
|
|
|
|
|
global PYTORCH_VERSION, CUDA_VERSION |
|
|
|
if pytorch_base.startswith("2.7"): |
|
print("PyTorch 2.7.x detected - this is very recent and may not have compatible wheels") |
|
print("Attempting to work with current PyTorch version and disable problematic extensions...") |
|
|
|
|
|
PYTORCH_VERSION = pytorch_base |
|
CUDA_VERSION = cuda_version |
|
|
|
|
|
print("Disabling torch-sparse and torch-scatter due to ABI compatibility issues...") |
|
disable_torch_sparse() |
|
|
|
|
|
print("Installing torchvision for current PyTorch version...") |
|
if not run_command("pip install torchvision"): |
|
print("Warning: Failed to install torchvision") |
|
else: |
|
|
|
PYTORCH_VERSION = pytorch_base |
|
CUDA_VERSION = cuda_version |
|
|
|
except ImportError: |
|
print("PyTorch not found, installing default version...") |
|
if not run_command("pip install torch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 --index-url https://download.pytorch.org/whl/cu117"): |
|
return False |
|
PYTORCH_VERSION = "2.0.1" |
|
CUDA_VERSION = "cu117" |
|
|
|
|
|
print("Checking PyTorch installation...") |
|
check_pytorch_cuda() |
|
|
|
|
|
try: |
|
import torch |
|
if not torch.__version__.startswith("2.0.1") or "+cu117" not in torch.__version__: |
|
print(f"Warning: PyTorch version is still {torch.__version__}, expected 2.0.1+cu117") |
|
print("This may cause compatibility issues with torch-sparse and torch-scatter") |
|
except Exception as e: |
|
print(f"Error checking PyTorch version: {e}") |
|
|
|
|
|
print(f"Installing torch-sparse with PyTorch {PYTORCH_VERSION}...") |
|
|
|
|
|
wheel_url = f"https://data.pyg.org/whl/torch-{PYTORCH_VERSION}+{CUDA_VERSION}.html" |
|
print(f"Trying wheel URL: {wheel_url}") |
|
|
|
if run_command(f"pip install torch-sparse -f {wheel_url}"): |
|
print("Successfully installed torch-sparse") |
|
|
|
|
|
try: |
|
import torch_sparse |
|
print("torch-sparse import successful") |
|
except Exception as e: |
|
print(f"Warning: torch-sparse import failed: {e}") |
|
print("This may indicate a version compatibility issue") |
|
|
|
return True |
|
|
|
|
|
print("Trying alternative torch-sparse versions...") |
|
alternative_versions = [ |
|
f"https://data.pyg.org/whl/torch-{PYTORCH_VERSION}+{CUDA_VERSION}.html", |
|
f"https://data.pyg.org/whl/torch-{PYTORCH_VERSION}+cu118.html", |
|
f"https://data.pyg.org/whl/torch-{PYTORCH_VERSION}+cu117.html", |
|
f"https://data.pyg.org/whl/torch-{PYTORCH_VERSION}+cu116.html" |
|
] |
|
|
|
for url in alternative_versions: |
|
if url != wheel_url: |
|
print(f"Trying alternative URL: {url}") |
|
if run_command(f"pip install torch-sparse -f {url}"): |
|
print("Successfully installed torch-sparse with alternative version") |
|
return True |
|
|
|
|
|
print("Trying torch-sparse installation with --no-build-isolation...") |
|
if run_command(f"pip install torch-sparse -f {wheel_url} --no-build-isolation"): |
|
print("Successfully installed torch-sparse with --no-build-isolation") |
|
return True |
|
|
|
|
|
print("Trying torch-sparse installation from source...") |
|
if run_command("pip install torch-sparse --no-build-isolation"): |
|
print("Successfully installed torch-sparse from source") |
|
return True |
|
|
|
|
|
print("Trying torch-sparse installation with specific build flags...") |
|
env = os.environ.copy() |
|
env['TORCH_CUDA_ARCH_LIST'] = '6.0;6.1;7.0;7.5;8.0;8.6' |
|
env['FORCE_CUDA'] = '1' |
|
if run_command("pip install torch-sparse --no-build-isolation", env=env): |
|
print("Successfully installed torch-sparse with build flags") |
|
return True |
|
|
|
|
|
print("Trying torch-sparse installation from git...") |
|
if run_command("pip install git+https://github.com/rusty1s/pytorch_sparse.git --no-build-isolation"): |
|
print("Successfully installed torch-sparse from git") |
|
return True |
|
|
|
|
|
print("Failed to install torch-sparse, disabling it and using built-in PyTorch sparse operations") |
|
disable_torch_sparse() |
|
return True |
|
|
|
def disable_torch_sparse(): |
|
"""Disable torch-sparse in the code by modifying the configuration""" |
|
try: |
|
|
|
poisson_file = "NeuralJacobianFields/PoissonSystem.py" |
|
if os.path.exists(poisson_file): |
|
with open(poisson_file, 'r') as f: |
|
content = f.read() |
|
|
|
|
|
content = content.replace("USE_TORCH_SPARSE = True", "USE_TORCH_SPARSE = False") |
|
|
|
with open(poisson_file, 'w') as f: |
|
f.write(content) |
|
|
|
print("Disabled torch-sparse in NeuralJacobianFields/PoissonSystem.py") |
|
print("Will use built-in PyTorch sparse operations instead") |
|
except Exception as e: |
|
print(f"Warning: Could not disable torch-sparse: {e}") |
|
|
|
def install_torch_scatter(): |
|
"""Install torch-scatter with compatible PyTorch version""" |
|
print("Installing torch-scatter...") |
|
|
|
|
|
try: |
|
import torch_scatter |
|
print("torch-scatter already installed") |
|
return True |
|
except ImportError: |
|
pass |
|
|
|
|
|
print(f"Installing torch-scatter with PyTorch {PYTORCH_VERSION}...") |
|
|
|
|
|
wheel_url = f"https://data.pyg.org/whl/torch-{PYTORCH_VERSION}+{CUDA_VERSION}.html" |
|
print(f"Trying wheel URL: {wheel_url}") |
|
|
|
if run_command(f"pip install torch-scatter -f {wheel_url}"): |
|
print("Successfully installed torch-scatter") |
|
|
|
|
|
try: |
|
import torch_scatter |
|
print("torch-scatter import successful") |
|
except Exception as e: |
|
print(f"Warning: torch-scatter import failed: {e}") |
|
print("This may indicate a version compatibility issue") |
|
|
|
return True |
|
|
|
|
|
print("Trying alternative torch-scatter versions...") |
|
alternative_versions = [ |
|
f"https://data.pyg.org/whl/torch-{PYTORCH_VERSION}+{CUDA_VERSION}.html", |
|
f"https://data.pyg.org/whl/torch-{PYTORCH_VERSION}+cu118.html", |
|
f"https://data.pyg.org/whl/torch-{PYTORCH_VERSION}+cu117.html", |
|
f"https://data.pyg.org/whl/torch-{PYTORCH_VERSION}+cu116.html" |
|
] |
|
|
|
for url in alternative_versions: |
|
if url != wheel_url: |
|
print(f"Trying alternative URL: {url}") |
|
if run_command(f"pip install torch-scatter -f {url}"): |
|
print("Successfully installed torch-scatter with alternative version") |
|
return True |
|
|
|
|
|
print("Trying torch-scatter installation with --no-build-isolation...") |
|
if run_command(f"pip install torch-scatter -f {wheel_url} --no-build-isolation"): |
|
print("Successfully installed torch-scatter with --no-build-isolation") |
|
return True |
|
|
|
|
|
print("Trying torch-scatter installation from source...") |
|
if run_command("pip install torch-scatter --no-build-isolation"): |
|
print("Successfully installed torch-scatter from source") |
|
return True |
|
|
|
|
|
print("Trying torch-scatter installation with specific build flags...") |
|
env = os.environ.copy() |
|
env['TORCH_CUDA_ARCH_LIST'] = '6.0;6.1;7.0;7.5;8.0;8.6' |
|
env['FORCE_CUDA'] = '1' |
|
if run_command("pip install torch-scatter --no-build-isolation", env=env): |
|
print("Successfully installed torch-scatter with build flags") |
|
return True |
|
|
|
|
|
print("Trying torch-scatter installation from git...") |
|
if run_command("pip install git+https://github.com/rusty1s/pytorch_scatter.git --no-build-isolation"): |
|
print("Successfully installed torch-scatter from git") |
|
return True |
|
|
|
|
|
print("Failed to install torch-scatter, but this may not be critical for basic functionality") |
|
return True |
|
|
|
def install_nvdiffrast(): |
|
"""Install nvdiffrast""" |
|
print("Installing nvdiffrast...") |
|
|
|
|
|
try: |
|
import nvdiffrast |
|
print("nvdiffrast already installed") |
|
return True |
|
except ImportError: |
|
pass |
|
|
|
|
|
packages_dir = Path("packages") |
|
packages_dir.mkdir(exist_ok=True) |
|
|
|
|
|
if not (packages_dir / "nvdiffrast").exists(): |
|
if not run_command("git clone https://github.com/NVlabs/nvdiffrast.git", cwd=packages_dir): |
|
return False |
|
|
|
|
|
nvdiffrast_dir = packages_dir / "nvdiffrast" |
|
if not run_command("pip install .", cwd=nvdiffrast_dir): |
|
return False |
|
|
|
return True |
|
|
|
def install_pytorch3d(): |
|
"""Install PyTorch3D""" |
|
print("Installing PyTorch3D...") |
|
|
|
|
|
try: |
|
import pytorch3d |
|
print(f"PyTorch3D already installed: {pytorch3d.__version__}") |
|
return True |
|
except ImportError: |
|
pass |
|
|
|
|
|
print("Trying PyTorch3D installation from conda-forge...") |
|
if run_command("pip install pytorch3d --index-url https://pypi.anaconda.org/conda-forge/simple/"): |
|
print("Successfully installed PyTorch3D from conda-forge") |
|
return True |
|
|
|
|
|
if PYTORCH_VERSION and CUDA_VERSION: |
|
|
|
if CUDA_VERSION == "cu126": |
|
print("Trying PyTorch3D installation for CUDA 12.6...") |
|
if run_command("pip install pytorch3d -f https://dl.fbaipublicfiles.com/pytorch3d/packaging/wheels/py310_cu126_pyt271/download.html"): |
|
print("Successfully installed PyTorch3D for CUDA 12.6") |
|
return True |
|
|
|
elif CUDA_VERSION == "cu117": |
|
print("Trying PyTorch3D installation for CUDA 11.7...") |
|
if run_command("pip install pytorch3d -f https://dl.fbaipublicfiles.com/pytorch3d/packaging/wheels/py310_cu117_pyt201/download.html"): |
|
print("Successfully installed PyTorch3D for CUDA 11.7") |
|
return True |
|
|
|
|
|
print("Trying PyTorch3D source installation with system CUDA...") |
|
if install_pytorch3d_from_source(): |
|
return True |
|
|
|
|
|
print("Trying official PyTorch3D installation (CUDA 11.7)...") |
|
if run_command("pip install pytorch3d -f https://dl.fbaipublicfiles.com/pytorch3d/packaging/wheels/py310_cu117_pyt201/download.html"): |
|
print("Successfully installed PyTorch3D from official wheels") |
|
return True |
|
|
|
|
|
print("Trying PyTorch3D installation with specific version...") |
|
if run_command("pip install pytorch3d==0.7.4"): |
|
print("Successfully installed PyTorch3D 0.7.4") |
|
return True |
|
|
|
|
|
|
|
print(f"Determining PyTorch3D wheel URL for PyTorch {PYTORCH_VERSION}+{CUDA_VERSION}") |
|
|
|
|
|
specific_url = f"https://dl.fbaipublicfiles.com/pytorch3d/packaging/wheels/py310_{CUDA_VERSION}_pyt{PYTORCH_VERSION.replace('.', '')}/download.html" |
|
print(f"Trying specific wheel URL: {specific_url}") |
|
if run_command(f"pip install pytorch3d -f {specific_url}"): |
|
print(f"Successfully installed PyTorch3D with specific wheel URL") |
|
return True |
|
|
|
|
|
wheel_urls = [ |
|
"https://dl.fbaipublicfiles.com/pytorch3d/packaging/wheels/py310_cu126_pyt271/download.html", |
|
f"https://dl.fbaipublicfiles.com/pytorch3d/packaging/wheels/py310_{CUDA_VERSION}_pyt{PYTORCH_VERSION.replace('.', '')}/download.html", |
|
"https://dl.fbaipublicfiles.com/pytorch3d/packaging/wheels/py310_cu117_pyt201/download.html", |
|
"https://dl.fbaipublicfiles.com/pytorch3d/packaging/wheels/py39_cu117_pyt201/download.html", |
|
"https://dl.fbaipublicfiles.com/pytorch3d/packaging/wheels/py38_cu117_pyt201/download.html" |
|
] |
|
|
|
for i, url in enumerate(wheel_urls): |
|
print(f"Trying PyTorch3D wheel URL {i+1}...") |
|
if run_command(f"pip install pytorch3d -f {url}"): |
|
print(f"Successfully installed PyTorch3D from wheel URL {i+1}") |
|
return True |
|
|
|
|
|
print("Trying PyTorch3D source installation with build tools...") |
|
packages_dir = Path("packages") |
|
|
|
|
|
if not (packages_dir / "pytorch3d").exists(): |
|
if not run_command("git clone https://github.com/facebookresearch/pytorch3d.git", cwd=packages_dir): |
|
return False |
|
|
|
|
|
print("Installing build dependencies...") |
|
run_command("pip install wheel setuptools ninja") |
|
|
|
|
|
pytorch3d_dir = packages_dir / "pytorch3d" |
|
|
|
|
|
print("Trying PyTorch3D installation with build isolation disabled...") |
|
if run_command("pip install . --no-build-isolation", cwd=pytorch3d_dir): |
|
print("Successfully installed PyTorch3D from source") |
|
return True |
|
|
|
|
|
print("Trying PyTorch3D installation with environment variables...") |
|
env = os.environ.copy() |
|
env['FORCE_CUDA'] = '1' |
|
env['CUDA_HOME'] = '/usr/local/cuda-11.7' |
|
env['CUDA_VERSION'] = '11.7' |
|
|
|
if run_command("pip install . --no-build-isolation", cwd=pytorch3d_dir, env=env): |
|
print("Successfully installed PyTorch3D with environment variables") |
|
return True |
|
|
|
return False |
|
|
|
def install_pytorch3d_from_source(): |
|
"""Install PyTorch3D from source with system CUDA""" |
|
print("Installing PyTorch3D from source with system CUDA...") |
|
|
|
packages_dir = Path("packages") |
|
|
|
|
|
if not (packages_dir / "pytorch3d").exists(): |
|
if not run_command("git clone https://github.com/facebookresearch/pytorch3d.git", cwd=packages_dir): |
|
return False |
|
|
|
|
|
print("Installing build dependencies...") |
|
run_command("pip install wheel setuptools ninja") |
|
|
|
|
|
pytorch3d_dir = packages_dir / "pytorch3d" |
|
|
|
|
|
env = os.environ.copy() |
|
env['FORCE_CUDA'] = '1' |
|
env['CUDA_HOME'] = '/usr/local/cuda' |
|
env['CUDA_VERSION'] = '12.6' |
|
env['TORCH_CUDA_ARCH_LIST'] = '8.9' |
|
|
|
print("Building PyTorch3D with system CUDA...") |
|
if run_command("pip install . --no-build-isolation", cwd=pytorch3d_dir, env=env): |
|
print("Successfully installed PyTorch3D from source with system CUDA") |
|
return True |
|
|
|
return False |
|
|
|
def install_pytorch_dependencies(): |
|
"""Install PyTorch-related dependencies""" |
|
print("Installing PyTorch dependencies...") |
|
|
|
|
|
try: |
|
import torchvision |
|
import torchaudio |
|
print("PyTorch dependencies already installed") |
|
return True |
|
except ImportError: |
|
pass |
|
|
|
|
|
if not run_command("pip install torchvision"): |
|
print("Warning: Failed to install torchvision") |
|
return False |
|
|
|
|
|
if not run_command("pip install torchaudio"): |
|
print("Warning: Failed to install torchaudio") |
|
|
|
return True |
|
|
|
def install_fashion_clip(): |
|
"""Setup Fashion-CLIP""" |
|
print("Setting up Fashion-CLIP...") |
|
|
|
packages_dir = Path("packages") |
|
|
|
|
|
if not (packages_dir / "fashion-clip").exists(): |
|
if not run_command("git clone https://github.com/patrickjohncyh/fashion-clip.git", cwd=packages_dir): |
|
return False |
|
|
|
|
|
fashion_clip_dir = packages_dir / "fashion-clip" |
|
dependencies = ["appdirs", "boto3", "annoy", "validators", "transformers", "datasets"] |
|
|
|
for dep in dependencies: |
|
if not run_command(f"pip install {dep}", cwd=fashion_clip_dir): |
|
print(f"Warning: Failed to install {dep}") |
|
|
|
return True |
|
|
|
def main(): |
|
"""Main installation function""" |
|
print("Starting post-installation for Garment3DGen...") |
|
|
|
|
|
if not install_torch_sparse(): |
|
print("Failed to install torch-sparse") |
|
sys.exit(1) |
|
|
|
if not install_torch_scatter(): |
|
print("Failed to install torch-scatter") |
|
sys.exit(1) |
|
|
|
if not install_nvdiffrast(): |
|
print("Failed to install nvdiffrast") |
|
sys.exit(1) |
|
|
|
if not install_pytorch3d(): |
|
print("Failed to install PyTorch3D") |
|
sys.exit(1) |
|
|
|
if not install_fashion_clip(): |
|
print("Failed to install Fashion-CLIP") |
|
sys.exit(1) |
|
|
|
if not install_pytorch_dependencies(): |
|
print("Failed to install PyTorch dependencies") |
|
sys.exit(1) |
|
|
|
|
|
print("\n=== Final Verification ===") |
|
print("Checking all dependencies...") |
|
|
|
try: |
|
import torch |
|
print(f"β PyTorch {torch.__version__} - CUDA: {torch.cuda.is_available()}") |
|
|
|
|
|
if PYTORCH_VERSION and not torch.__version__.startswith(PYTORCH_VERSION): |
|
print(f"β Warning: PyTorch version {torch.__version__} may not be compatible with installed extensions") |
|
print(f"Expected version: {PYTORCH_VERSION}") |
|
|
|
|
|
try: |
|
import torch_sparse |
|
print("β torch-sparse") |
|
except ImportError: |
|
|
|
try: |
|
with open("NeuralJacobianFields/PoissonSystem.py", 'r') as f: |
|
content = f.read() |
|
if "USE_TORCH_SPARSE = False" in content: |
|
print("β torch-sparse (disabled, using built-in PyTorch sparse)") |
|
else: |
|
print("β torch-sparse (not available)") |
|
except: |
|
print("β torch-sparse (not available)") |
|
except Exception as e: |
|
|
|
try: |
|
with open("NeuralJacobianFields/PoissonSystem.py", 'r') as f: |
|
content = f.read() |
|
if "USE_TORCH_SPARSE = False" in content: |
|
print("β torch-sparse (disabled due to ABI issues, using built-in PyTorch sparse)") |
|
else: |
|
print(f"β torch-sparse import failed: {e}") |
|
except: |
|
print(f"β torch-sparse import failed: {e}") |
|
|
|
|
|
try: |
|
import torch_scatter |
|
print("β torch-scatter") |
|
except ImportError: |
|
print("β torch-scatter (not available, may not be critical)") |
|
except Exception as e: |
|
print(f"β torch-scatter import failed: {e} (may not be critical)") |
|
|
|
import nvdiffrast |
|
print("β nvdiffrast") |
|
|
|
import pytorch3d |
|
print("β PyTorch3D") |
|
|
|
print("\nPost-installation completed successfully!") |
|
print("All dependencies are now available.") |
|
|
|
except ImportError as e: |
|
print(f"β Import error: {e}") |
|
print("This may indicate a version compatibility issue between PyTorch and its extensions") |
|
sys.exit(1) |
|
except Exception as e: |
|
print(f"β Verification error: {e}") |
|
print("This may indicate a version compatibility issue between PyTorch and its extensions") |
|
sys.exit(1) |
|
|
|
if __name__ == "__main__": |
|
main() |