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)
8.5 KiB
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