BaseChange / setup_colab.py
Vedant Jigarbhai Mehta
Fix VRAM attribute name for PyTorch compatibility
a05c98a
Raw
History Blame Contribute Delete
10.3 kB
"""Google Colab setup script for the change-detection project.
Replaces the manual "Colab Setup Cell" with a single importable function.
Handles Drive mounting, GPU verification, dependency installation, directory
creation, and prints a status summary with checkmarks.
Usage (in a Colab notebook cell):
!python setup_colab.py
# Or import and call directly:
from setup_colab import setup
paths = setup()
"""
import importlib
import logging
import subprocess
import sys
from pathlib import Path
from typing import Dict, List, Optional, Tuple
logger = logging.getLogger(__name__)
# Packages that must be importable for the project to work.
_REQUIRED_PACKAGES: List[Tuple[str, str]] = [
("torch", "torch"),
("torchvision", "torchvision"),
("segmentation_models_pytorch", "segmentation-models-pytorch"),
("timm", "timm"),
("einops", "einops"),
("albumentations", "albumentations"),
("cv2", "opencv-python-headless"),
("sklearn", "scikit-learn"),
("matplotlib", "matplotlib"),
("yaml", "PyYAML"),
("tqdm", "tqdm"),
("tensorboard", "tensorboard"),
("gradio", "gradio"),
]
# ---------------------------------------------------------------------------
# Environment checks
# ---------------------------------------------------------------------------
def is_colab() -> bool:
"""Detect whether the code is running inside Google Colab.
Returns:
``True`` if the ``google.colab`` package is importable.
"""
try:
import google.colab # noqa: F401
return True
except ImportError:
return False
def mount_drive() -> bool:
"""Mount Google Drive at ``/content/drive``.
Skips gracefully when not running in Colab or when already mounted.
Returns:
``True`` if Drive is mounted (or was already), ``False`` otherwise.
"""
if not is_colab():
logger.info(" Not running in Colab — Drive mount skipped.")
return False
if Path("/content/drive/MyDrive").exists():
logger.info(" Google Drive already mounted.")
return True
from google.colab import drive
drive.mount("/content/drive")
logger.info(" Google Drive mounted successfully.")
return True
def check_gpu() -> Tuple[Optional[str], Optional[str], Optional[float]]:
"""Check GPU availability and return device information.
Returns:
Tuple of ``(gpu_name, gpu_type, vram_gb)``.
All ``None`` if no GPU is available.
"""
import torch
if not torch.cuda.is_available():
return None, None, None
gpu_name = torch.cuda.get_device_name(0)
props = torch.cuda.get_device_properties(0)
vram_gb = getattr(props, "total_memory", getattr(props, "total_mem", 0)) / 1e9
name_upper = gpu_name.upper()
if "T4" in name_upper:
gpu_type = "T4"
elif "V100" in name_upper:
gpu_type = "V100"
else:
gpu_type = "other"
return gpu_name, gpu_type, vram_gb
# ---------------------------------------------------------------------------
# Dependencies
# ---------------------------------------------------------------------------
def install_requirements() -> bool:
"""Install project dependencies from ``requirements.txt``.
Returns:
``True`` if installation succeeded, ``False`` if the file is missing.
"""
req_path = Path("requirements.txt")
if not req_path.exists():
logger.warning(" requirements.txt not found in %s", Path.cwd())
return False
logger.info(" Installing from requirements.txt ...")
subprocess.check_call(
[sys.executable, "-m", "pip", "install", "-q", "-r", str(req_path)],
stdout=subprocess.DEVNULL,
)
return True
def verify_packages() -> Dict[str, bool]:
"""Check that all required packages are importable.
Returns:
Dict mapping import name → ``True`` if importable.
"""
results: Dict[str, bool] = {}
for import_name, _ in _REQUIRED_PACKAGES:
try:
importlib.import_module(import_name)
results[import_name] = True
except ImportError:
results[import_name] = False
return results
# ---------------------------------------------------------------------------
# Directory creation
# ---------------------------------------------------------------------------
def create_drive_dirs(
drive_root: str = "/content/drive/MyDrive/change-detection",
) -> Dict[str, Path]:
"""Create all project directories on Google Drive.
Args:
drive_root: Root directory on Drive for this project.
Returns:
Dict mapping logical name → ``Path`` for each directory.
"""
dirs = {
"root": Path(drive_root),
"checkpoints": Path(drive_root) / "checkpoints",
"logs": Path(drive_root) / "logs",
"outputs": Path(drive_root) / "outputs",
"processed_data": Path(drive_root) / "processed_data",
}
for name, path in dirs.items():
path.mkdir(parents=True, exist_ok=True)
return dirs
# ---------------------------------------------------------------------------
# Status summary
# ---------------------------------------------------------------------------
def _tick(ok: bool) -> str:
"""Return a checkmark or cross for console display.
Args:
ok: Whether the check passed.
Returns:
``'[OK]'`` or ``'[FAIL]'``.
"""
return "[OK]" if ok else "[FAIL]"
def print_summary(
colab: bool,
drive_mounted: bool,
gpu_name: Optional[str],
gpu_type: Optional[str],
vram_gb: Optional[float],
deps_ok: bool,
pkg_results: Dict[str, bool],
dirs: Dict[str, Path],
) -> None:
"""Print a formatted status summary to the console.
Args:
colab: Whether running in Colab.
drive_mounted: Whether Drive is mounted.
gpu_name: GPU device name (or ``None``).
gpu_type: Detected GPU type string.
vram_gb: VRAM in gigabytes.
deps_ok: Whether pip install succeeded.
pkg_results: Per-package import check results.
dirs: Created directory paths.
"""
border = "=" * 60
logger.info(border)
logger.info(" SETUP STATUS SUMMARY")
logger.info(border)
# Environment
logger.info(" %-30s %s", "Running in Colab", _tick(colab))
logger.info(" %-30s %s", "Google Drive mounted", _tick(drive_mounted))
# GPU
if gpu_name is not None:
logger.info(" %-30s %s", "GPU detected", _tick(True))
logger.info(" %-30s %s", " Device", gpu_name)
logger.info(" %-30s %s", " Type (for batch sizing)", gpu_type)
logger.info(" %-30s %.1f GB", " VRAM", vram_gb)
else:
logger.info(" %-30s %s", "GPU detected", _tick(False))
logger.info(" %-30s", " WARNING: CPU only — training will be slow")
# Dependencies
logger.info(" %-30s %s", "Dependencies installed", _tick(deps_ok))
all_ok = all(pkg_results.values())
logger.info(" %-30s %s", "All packages importable", _tick(all_ok))
if not all_ok:
for name, ok in pkg_results.items():
if not ok:
logger.info(" MISSING: %s", name)
# Directories
logger.info(" %-30s %s", "Drive directories created", _tick(bool(dirs)))
for name, path in dirs.items():
logger.info(" %-26s %s", name, path)
logger.info(border)
if all_ok and gpu_name is not None:
logger.info(" All checks passed. Ready to train!")
elif all_ok:
logger.info(" Dependencies OK but no GPU. Consider changing runtime.")
else:
logger.info(" Some checks failed. Review the output above.")
logger.info(border)
# ---------------------------------------------------------------------------
# Main setup function
# ---------------------------------------------------------------------------
def setup(
drive_root: str = "/content/drive/MyDrive/change-detection",
install_deps: bool = True,
) -> Dict[str, Path]:
"""Run the full Colab setup sequence.
Steps:
1. Mount Google Drive (if in Colab)
2. Check GPU type and VRAM
3. Install pip dependencies
4. Verify all packages are importable
5. Create Drive directories
6. Print status summary
Args:
drive_root: Root directory on Google Drive for persistent storage.
install_deps: Whether to run ``pip install -r requirements.txt``.
Returns:
Dict of project directory paths.
"""
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
logger.info("=" * 60)
logger.info(" Military Base Change Detection — Colab Setup")
logger.info("=" * 60)
# 1. Google Drive
logger.info("[1/5] Google Drive")
colab = is_colab()
drive_mounted = mount_drive()
# 2. GPU
logger.info("[2/5] GPU Check")
gpu_name, gpu_type, vram_gb = check_gpu()
if gpu_name:
logger.info(" GPU: %s (%s) — %.1f GB VRAM", gpu_name, gpu_type, vram_gb)
else:
logger.warning(" No GPU detected.")
# 3. Install dependencies
logger.info("[3/5] Dependencies")
deps_ok = False
if install_deps:
deps_ok = install_requirements()
logger.info(" pip install: %s", _tick(deps_ok))
else:
logger.info(" Skipped (install_deps=False).")
# 4. Verify imports
logger.info("[4/5] Package Verification")
pkg_results = verify_packages()
ok_count = sum(pkg_results.values())
logger.info(" %d/%d packages importable", ok_count, len(pkg_results))
# 5. Create directories
logger.info("[5/5] Drive Directories")
dirs: Dict[str, Path] = {}
if drive_mounted or not colab:
dirs = create_drive_dirs(drive_root)
logger.info(" Created %d directories under %s", len(dirs), drive_root)
else:
logger.warning(" Drive not mounted — skipping directory creation.")
# Summary
print_summary(
colab=colab,
drive_mounted=drive_mounted,
gpu_name=gpu_name,
gpu_type=gpu_type,
vram_gb=vram_gb,
deps_ok=deps_ok,
pkg_results=pkg_results,
dirs=dirs,
)
return dirs
if __name__ == "__main__":
setup()