Files
Pikaliov 98e98f591c Add code-style skill (gin-config strict pattern)
- code-style/SKILL.md — skill spec for the LISAD code-style enforcement
- code-style/reference/gin_examples.md — gin-config canonical examples

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 10:33:43 +03:00

221 lines
8.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: code-style
description: "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."
user-invocable: true
allowed-tools: Read Write Edit Glob Grep Bash
argument-hint: "[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** на всех публичных классах и функциях:
```python
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`
```python
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 Функции-загрузчики
```python
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 файлов
```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 Передача конфигов
```python
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)
```python
# 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 Воспроизводимость
```python
torch.manual_seed(42)
np.random.seed(42)
```
- Seed = 42 (фиксированный) в главном скрипте
- Deterministic DataLoader: `shuffle=False` для inference
### 4.3 Атомарная запись файлов
```python
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-декоратор
```python
@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](reference/gin_examples.md)