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)
163 lines
12 KiB
Markdown
163 lines
12 KiB
Markdown
Отличная инициатива. Переход от `argparse` и `dataclass` к `gin-config` в научно-исследовательских проектах по глубокому обучению — это мощный шаг, который сильно упрощает управление гиперпараметрами и версионирование экспериментов.
|
||
|
||
Ваш подход в `REQUIREMENTS_GIN_STYLE.md`, где вы используете `gin` для конфигурации классов, но **явно передаете объекты конфигов** (избегая глобального состояния `gin`), — это лучшая практика, которая решает главную проблему этого фреймворка.
|
||
|
||
Ниже представлены разработанный **SKILL (набор правил)**, **Prompt-шаблон** для ИИ, а также **сравнение конфигураций** с финальными рекомендациями.
|
||
|
||
---
|
||
|
||
### 1. SKILL: Стандарт написания кода для DL/CV исследований (Cross-View Geo-Localization)
|
||
|
||
Этот свод правил объединяет ваши базовые требования со спецификой задачи кросс-вью геолокализации и выбранным стилем `gin-config`.
|
||
|
||
**Общие требования к Python-коду:**
|
||
|
||
- **Версии:** Python 3.10+, PyTorch 2.x.
|
||
|
||
- **Импорты:** Обязательно `from __future__ import annotations` первой строкой в каждом файле.
|
||
|
||
- **Язык:** Весь код, переменные и комментарии строго на **английском языке**.
|
||
|
||
- **Типизация (Type Hints):** Строгая типизация для всех аргументов функций и возвращаемых значений (`-> None`, `-> torch.Tensor` и т.д.).
|
||
|
||
- **Документация:** Docstrings в формате **Google-style** для всех публичных классов и функций.
|
||
|
||
|
||
**Архитектура и управление ресурсами (CV/DL специфика):**
|
||
|
||
- **Воспроизводимость:** Обязательная фиксация seed (`torch.manual_seed`, `np.random.seed`) в главном скрипте.
|
||
|
||
- **Управление VRAM:** Из-за ограничений в 24 GB VRAM (RTX 4090) модели должны загружаться последовательно (`sequential model loading`). После использования модель выгружается из памяти (`del model`, `gc.collect()`, `torch.cuda.empty_cache()`).
|
||
|
||
- **Отказоустойчивость:** Запись файлов (например, `.npy`) должна быть атомарной (сохранение во временный файл `tmp` с последующим `os.replace`), чтобы пайплайн мог безопасно возобновить работу (`--resume`) после сбоя.
|
||
|
||
- **Разделение логики:** Строгое разделение на `dataset` (загрузка данных), `models` (инициализация), `inference` (прогон батчей) и `io_utils` (сохранение).
|
||
|
||
|
||
**Конфигурация (Gin-Config Style):**
|
||
|
||
- **Инкапсуляция:** Конфигурация осуществляется через классы, декорированные `@gin.configurable`. Запрещено использовать `dataclass` совместно с gin.
|
||
|
||
- **Инициализация:** Все параметры должны иметь значения по умолчанию в методе `__init__` класса.
|
||
|
||
- **Формат .gin:** Плоский формат файлов (одна строка — один параметр `ClassName.param = value`). Запрещены сложные конструкции gin (макросы, ссылки, `gin.constant()`).
|
||
|
||
- **Логика загрузки:** Использование паттерна функций-загрузчиков `get_<name>_cfg(path2cfg)`, которые вызывают `gin.parse_config_file()` и возвращают экземпляр конфигурационного класса.
|
||
|
||
- **Явная передача:** Объекты конфигурации передаются в функции пайплайна явно через аргументы, использование глобального состояния gin для получения параметров внутри функций запрещено.
|
||
|
||
|
||
---
|
||
|
||
### 2. Prompt-шаблон для генерации кода (System Prompt)
|
||
|
||
Вы можете использовать этот промпт для постановки задач нейросети (например, при рефакторинге старого кода или написании новых модулей).
|
||
|
||
Markdown
|
||
|
||
```
|
||
You are an expert Machine Learning Engineer and Python Developer specializing in Computer Vision and Deep Learning (specifically Cross-View Geo-Localization).
|
||
Your task is to write, refactor, or review Python code according to the strict guidelines defined below.
|
||
|
||
### THE SKILL (Coding Standards)
|
||
|
||
1. **Environment & Language**:
|
||
- Target Python 3.10+ and PyTorch 2.x.
|
||
- Start all files with `from __future__ import annotations`.
|
||
- All code, variable names, and comments MUST be in English.
|
||
|
||
2. **Typing & Documentation**:
|
||
- Use strict type hints for all function arguments and return types.
|
||
- Use Google-style docstrings for all classes and functions.
|
||
|
||
3. **Configuration (Gin-Config Strict Pattern)**:
|
||
- Use `gin-config` for managing hyperparameters. Do NOT use `argparse` or `dataclass`.
|
||
- Apply `@gin.configurable` ONLY to classes, not functions.
|
||
- Provide default values for all parameters inside the class `__init__` method. Store parameters as instance attributes (`self.param = param`).
|
||
- Define dedicated loader functions named `get_<name>_cfg(path2cfg)` that call `gin.parse_config_file(gin_file)` and return the instantiated class object.
|
||
- Configuration objects must be passed explicitly as arguments to functions/pipelines. Never rely on global gin state inside execution logic.
|
||
|
||
4. **Deep Learning / CV Best Practices**:
|
||
- **VRAM Management**: Models must be explicitly loaded and unloaded (`del model`, `torch.cuda.empty_cache()`) when doing sequential multi-model processing to fit within 24GB VRAM limits.
|
||
- **Reproducibility**: Ensure deterministic behavior (e.g., set seeds using `torch.manual_seed`, `np.random.seed`).
|
||
- **Fault Tolerance**: Use atomic file writes (save to `.tmp` then `os.replace`) to allow safe resumption of interrupted pipelines.
|
||
|
||
### Task Description:
|
||
[INSERT YOUR SPECIFIC TASK HERE. Example: Refactor the provided `augment_dataset.py` script to remove argparse and integrate the Gin-Config Strict Pattern described above using the 5 config classes.]
|
||
```
|
||
|
||
---
|
||
|
||
### 3. Примеры конфигов и сравнение подходов
|
||
|
||
Для вашей задачи (автоматическое аннотирование датасета генераторами) нам нужно конфигурировать пути, параметры железа, идентификаторы моделей и настройки аугментации.
|
||
|
||
#### Вариант А: Обычный `argparse` + `dataclass` (То, что у вас было)
|
||
|
||
- **Плюсы:** Не требует сторонних библиотек, отлично подходит для простых скриптов.
|
||
|
||
- **Минусы:** Когда параметров становится больше 15-20 (как у вас в 5 классах), командная строка превращается в хаос (`python script.py --depth-model xyz --use-fp16 --batch-size 8 ...`). Сложно отслеживать, с какими параметрами был запущен эксперимент неделю назад.
|
||
|
||
|
||
#### Вариант Б: YAML + Hydra / OmegaConf
|
||
|
||
YAML
|
||
|
||
```
|
||
# hardware.yaml
|
||
profile_name: rtx4090
|
||
use_fp16: true
|
||
batch_size: 8
|
||
num_workers: 4
|
||
reserve_gb: 2.0
|
||
```
|
||
|
||
- **Плюсы:** Иерархическая структура, легко читается, де-факто стандарт индустрии для многих фреймворков.
|
||
|
||
- **Минусы:** Требует написания шаблонного кода для парсинга (чтение файла, конвертация словаря в `dataclass`). Если использовать Hydra, то она "захватывает" архитектуру приложения (требует декоратора `@hydra.main`), что усложняет дебаг.
|
||
|
||
|
||
#### Вариант В: Ваш плоский `gin-config` стиль
|
||
|
||
Code snippet
|
||
|
||
```
|
||
# hardware.gin
|
||
HardwareConfig.profile_name = 'rtx4090'
|
||
HardwareConfig.use_fp16 = True
|
||
HardwareConfig.batch_size = 8
|
||
HardwareConfig.num_workers = 4
|
||
HardwareConfig.reserve_gb = 2.0
|
||
```
|
||
|
||
Python
|
||
|
||
```
|
||
# Загрузка
|
||
@gin.configurable
|
||
class HardwareConfig:
|
||
def __init__(self, profile_name='rtx4090', ...): ...
|
||
|
||
def get_hardware_cfg(path2cfg):
|
||
gin.parse_config_file(f"{path2cfg}hardware.gin")
|
||
return HardwareConfig()
|
||
```
|
||
|
||
- **Плюсы:** * **Нулевой бойлерплейт при парсинге:** Вы просто парсите файл, и gin автоматически подставляет значения в параметры `__init__` класса.
|
||
|
||
- **Легкость логирования:** Сохранить весь конфиг эксперимента можно вызвав `gin.config_str()`.
|
||
|
||
- **Защита от опечаток:** Если вы напишете в конфиге `HardwarConfig.batch = 8`, `gin` упадет с ошибкой еще до запуска тяжелых вычислений, потому что такого аргумента нет.
|
||
|
||
- **Минусы:**
|
||
|
||
- Не поддерживает вложенные иерархии (сложно группировать очень сложные структуры, но для ваших 5 конфигов это не критично).
|
||
|
||
- Многие используют `gin` как антипаттерн "глобального состояния" (когда функции по всему коду неявно тянут параметры из эфира).
|
||
|
||
|
||
### 📝 Финальная рекомендация
|
||
|
||
**Строго придерживайтесь вашего `REQUIREMENTS_GIN_STYLE.md`.** Вы выбрали идеальный компромисс: вы используете `gin-config` для того, в чем он силен (красивая и лаконичная привязка параметров текстового файла к аргументам класса без парсеров словарей), но при этом **запрещаете его главную слабость** — неявное глобальное состояние. Загрузив параметры в объект конфигурации (например, `hardware_conf = get_hardware_cfg(...)`), вы дальше передаете его в пайплайн явно. Это делает код тестируемым, читаемым и идеально подходящим для глубокого обучения.
|
||
|
||
Подсказать ли вам, как должен выглядеть итоговый рефакторинг `augment_dataset.py` с применением этих правил? |