claude_refactor_v3: New train_gtauav.py, added entry point main.py, added utils

This commit is contained in:
pikaliov
2026-05-04 11:20:14 +03:00
parent 08d328db09
commit 89cb8ab0f7
10 changed files with 2299 additions and 505 deletions

2
src/utils/__init__.py Normal file
View File

@@ -0,0 +1,2 @@
"""Utilities: paths, seeding, IO."""

51
src/utils/io_utils.py Normal file
View File

@@ -0,0 +1,51 @@
"""IO helpers: atomic checkpoint saves, VRAM cleanup."""
from __future__ import annotations
import gc
import logging
import os
import tempfile
from pathlib import Path
from typing import Any
import torch
logger = logging.getLogger(__name__)
def atomic_save_torch(obj: Any, path: Path) -> None:
"""Save a PyTorch object atomically via temp file + os.replace.
On any failure (KeyboardInterrupt / SIGTERM included), the temp file
is removed. Makes --resume safe: a partial checkpoint never lands at
the destination path.
Args:
obj: Anything torch.save can handle.
path: Destination path. Parent directory is created if missing.
"""
path.parent.mkdir(parents=True, exist_ok=True)
fd, tmp = tempfile.mkstemp(suffix=".pt.tmp", dir=path.parent)
os.close(fd)
try:
torch.save(obj, tmp)
os.replace(tmp, path)
except BaseException:
if os.path.exists(tmp):
os.remove(tmp)
raise
def clear_vram() -> None:
"""Free VRAM and reset peak memory stats."""
gc.collect()
if torch.cuda.is_available():
torch.cuda.empty_cache()
torch.cuda.reset_peak_memory_stats()
allocated_gb = torch.cuda.memory_allocated() / 1e9
logger.info("VRAM cleared. Current usage: %.2f GB", allocated_gb)

32
src/utils/path_utils.py Normal file
View File

@@ -0,0 +1,32 @@
"""Project root resolution via marker files."""
from __future__ import annotations
from pathlib import Path
# Markers identifying the project root (per REQUIREMENTS_GIN_STYLE.md §5).
_MARKERS: tuple[str, ...] = ("pyproject.toml", ".git", "in")
def get_proj_dir() -> str:
"""Return absolute project root with trailing slash.
Walks up from this file's directory until finding pyproject.toml,
.git, or in/. Searches up to 10 levels.
Returns:
Project root path with trailing slash, e.g. '/home/user/caption-test/'.
Raises:
RuntimeError: If no marker found within 10 parent directories.
"""
current = Path(__file__).resolve().parent
for _ in range(10):
if any((current / m).exists() for m in _MARKERS):
return str(current) + "/"
current = current.parent
raise RuntimeError(
f"Project root not found. Looked for {_MARKERS} starting at "
f"{Path(__file__).resolve().parent}",
)

23
src/utils/seed_utils.py Normal file
View File

@@ -0,0 +1,23 @@
"""RNG seeding for reproducibility."""
from __future__ import annotations
import random
import numpy as np
import torch
def set_seed(seed: int = 42) -> None:
"""Fix all RNG seeds (Python random, NumPy, PyTorch CPU + all CUDA devices).
Args:
seed: Integer seed.
"""
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed_all(seed)