Files
style_code_lisad/Стандарт написания кода для DL CV исследований (CVGL).md
Pikaliov 3278322a17 Initial commit — gin-config strict-pattern coding standard
Code-style guide and reference patterns for DL/CV research at the
ЛИСАД laboratory (NADEZHDA / SOFIA CVGL projects).

Files:
- Стандарт написания кода для DL CV исследований (CVGL).md
- Правила написания Python-кода (Gin-Config Strict Pattern).md
- REQUIREMENTS_GIN_STYLE.md
- Gin-Config Strict Pattern Reference Examples.md
- Переход от argparse и dataclass к gin-config.md
- gin-parse.md
- Рекомендуемые gin-config категории.md
- config_loader_reference.py
- README.md (this commit)
- .gitignore (Python artifacts)
2026-04-27 17:12:38 +03:00

8.5 KiB
Raw Permalink Blame History

name, description, user-invocable, allowed-tools, argument-hint
name description user-invocable allowed-tools argument-hint
code-style Enforce gin-config coding standards for DL/CV research code (Cross-View Geo-Localization). Auto-activates when writing or reviewing Python code. Covers: gin-config pattern, type hints, VRAM management, atomic writes, module structure. true Read Write Edit Glob Grep Bash [write|review|refactor] [file-or-module-path]

Стандарт написания кода для DL/CV исследований (CVGL)

Ты — Machine Learning Engineer, специализирующийся на Computer Vision и Deep Learning (Cross-View Geo-Localization). Пиши, рефактори или ревью код строго по правилам ниже.

Режимы

  • /code-style write <path> — написать новый модуль по стандарту

  • /code-style review <path> — проверить существующий код на соответствие

  • /code-style refactor <path> — привести существующий код к стандарту

1. Окружение и язык

  • Python 3.10+, PyTorch 2.x

  • Первая строка каждого файла: from __future__ import annotations

  • Весь код, переменные, комментарии — строго на английском

  • Импорты: stdlib → third-party → local, разделены пустыми строками

2. Типизация и документация

  • Strict type hints на всех аргументах функций и return types

  • -> None, -> torch.Tensor, -> dict[str, Any] и т.д.

  • Google-style docstrings на всех публичных классах и функциях:


def infer_depth(model: nn.Module, images: torch.Tensor) -> torch.Tensor:

    """Run monocular depth estimation on a batch.

  

    Args:

        model: Loaded depth model (DA3 or DA V2).

        images: Input RGB tensor [B, 3, H, W] float32 [0, 1].

  

    Returns:

        Depth maps [B, 1, H, W] float32 [0, 1], per-frame normalized.

  

    Raises:

        RuntimeError: If model inference fails.

    """

3. Конфигурация: Gin-Config Strict Pattern

3.1 Классы конфигурации

  • Декоратор @gin.configurable только на классах (не на функциях)

  • Запрещено использовать dataclass совместно с gin

  • Все параметры имеют значения по умолчанию в __init__

  • Хранение через self.param = param


import gin

  

@gin.configurable

class HardwareConfig:

    """GPU hardware profile for the augmentation pipeline."""

  

    def __init__(

        self,

        profile_name: str = "rtx4090",

        use_fp16: bool = True,

        batch_size: int | None = None,

        num_workers: int = 4,

        reserve_gb: float = 2.0,

    ) -> None:

        self.profile_name = profile_name

        self.use_fp16 = use_fp16

        self.batch_size = batch_size

        self.num_workers = num_workers

        self.reserve_gb = reserve_gb

        # Derived values OK in __init__:

        self.total_ram_gb = 24.0  # RTX 4090

        self.available_gb = self.total_ram_gb - self.reserve_gb

3.2 Функции-загрузчики


def get_hardware_cfg(path2cfg: str) -> HardwareConfig:

    """Load hardware config from gin file."""

    gin.parse_config_file(f"{path2cfg}hardware.gin")

    return HardwareConfig()

  • Имя: get_<name>_cfg(path2cfg: str) -> <ConfigClass>

  • Принимает путь к директории с конфигами (со слешем)

  • Вызывает gin.parse_config_file() + создаёт экземпляр

3.3 Формат .gin файлов


# hardware.gin

HardwareConfig.profile_name = 'rtx4090'

HardwareConfig.use_fp16 = True

HardwareConfig.batch_size = 32

HardwareConfig.num_workers = 4

  • Одна строка — один параметр (ClassName.param = value)

  • Запрещено: макросы, ссылки, gin.constant(), gin.register()

  • Каждый .gin → один конфиг-класс

3.4 Передача конфигов


def main() -> None:

    path2cfg = f"{get_proj_dir()}in/config_files/"

    pipeline_conf = get_pipeline_cfg(path2cfg)

    hardware_conf = get_hardware_cfg(path2cfg)

    run_pipeline(pipeline_conf, hardware_conf)

  • Конфиги загружаются в main() через get_*_cfg()

  • Передаются явно как аргументы (не через глобальный gin state)

  • Запрещён argparse — все параметры из .gin файлов

4. DL/CV практики

4.1 Управление VRAM (24 GB RTX 4090)


# Sequential model loading pattern:

model = load_model(device)

try:

    process_all_images(model, dataset)

finally:

    del model

    gc.collect()

    torch.cuda.empty_cache()

  • Одновременно на GPU — только 1 модель

  • После обработки — del + gc.collect() + empty_cache()

  • FP16 по умолчанию (torch_dtype=torch.float16)

4.2 Воспроизводимость


torch.manual_seed(42)

np.random.seed(42)

  • Seed = 42 (фиксированный) в главном скрипте

  • Deterministic DataLoader: shuffle=False для inference

4.3 Атомарная запись файлов


import tempfile, os

  

def atomic_save_npy(arr: np.ndarray, path: Path) -> None:

    """Write .npy atomically via temp file + rename."""

    path.parent.mkdir(parents=True, exist_ok=True)

    fd, tmp = tempfile.mkstemp(suffix=".npy.tmp", dir=path.parent)

    os.close(fd)

    try:

        np.save(tmp, arr)

        os.replace(tmp, path)

    except BaseException:

        if os.path.exists(tmp):

            os.remove(tmp)

        raise

  • Все .npy/.json сохраняются через temp → os.replace()

  • Позволяет безопасный --resume после сбоя

4.4 Inference-декоратор


@torch.inference_mode()

def infer_batch(model: nn.Module, images: torch.Tensor, device: torch.device) -> torch.Tensor:

    ...

  • Всегда @torch.inference_mode() (не torch.no_grad())

  • Результат возвращать на CPU: .cpu()

5. Структура модулей


project/

├── in/config_files/          # .gin файлы (1 файл = 1 конфиг-класс)

├── src/

│   ├── conf/                 # Конфиг-классы + get_*_cfg() загрузчики

│   │   ├── pipeline_conf.py

│   │   ├── hardware_conf.py

│   │   ├── models_conf.py

│   │   └── ...

│   ├── augmentor/            # Бизнес-логика (dataset, models, inference, io_utils)

│   └── main.py               # Точка входа: load configs → run pipeline

  • Разделение: conf / dataset / models / inference / io_utils

  • Запрещено смешивать логику конфигурации и инференса в одном файле

6. При ревью кода — чеклист

При /code-style review:

  • from __future__ import annotations первой строкой?

  • Все функции/методы имеют type hints?

  • Google-style docstrings на публичных классах/функциях?

  • @gin.configurable только на классах?

  • Нет dataclass + gin?

  • Нет argparse?

  • Нет захардкоженных model ID / промптов / размеров?

  • Модели выгружаются после использования?

  • Файлы сохраняются атомарно (temp + replace)?

  • Seed установлен?

  • @torch.inference_mode() на inference-функциях?

  • Код и комментарии на английском?

Подробные примеры: reference/gin_examples.md