Files
style_code_lisad/REQUIREMENTS_GIN_STYLE.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

13 KiB
Raw Blame History

Требования к адаптации кода под gin-config стиль

Референсный проект: test_bb_uav


1. Структура директорий

Создать директорию для конфигурационных файлов:

depth_edges_annotate_worlduav/
├── in/
│   └── config_files/
│       ├── pipeline.gin        # Стадии пайплайна, пути, форматы вывода
│       ├── hardware.gin        # Профили GPU, batch size, FP16, workers
│       ├── models.gin          # Идентификаторы моделей, fallback-стратегии
│       ├── input.gin           # Размер изображений, нормализация, аугментации
│       └── segmentation.gin    # Текстовые промпты, параметры сегментации
├── src/
│   ├── conf/
│   │   ├── __init__.py
│   │   ├── pipeline_conf.py    # PipelineConfig (пути, стадии, resume, вывод)
│   │   ├── hardware_conf.py    # HardwareConfig (GPU, batch, FP16, workers)
│   │   ├── models_conf.py      # ModelsConfig (model IDs, fallback)
│   │   ├── input_conf.py       # InputConfig (размер, нормализация)
│   │   └── seg_conf.py         # SegConfig (промпты, параметры)
│   ├── augmentor/
│   │   ├── ...                 # Существующие модули (без изменения структуры)
│   └── augment_dataset.py      # Точка входа (адаптировать)

2. Паттерн конфигурационных классов

Каждый конфиг-класс следует единому шаблону из test_bb_uav:

import gin

@gin.configurable
class HardwareConfig:
    def __init__(self, profile_name='rtx4090', use_fp16=True,
                 batch_size=None, num_workers=4, reserve_gb=2.0):
        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

Правила:

  • Декоратор @gin.configurable только на классах (не на функциях)
  • Все параметры имеют значения по умолчанию в __init__
  • Класс хранит параметры как атрибуты экземпляра (self.param = param)
  • Не использовать dataclass совместно с gin — заменить dataclass на обычные классы
  • Допустима пост-обработка в __init__ (вычисление производных значений)

3. Загрузка конфигов

3.1 Центральный загрузчик (ПРОДАКШЕН)

Один файл src/conf/config_loader.py содержит единственную функцию, которая парсит все .gin файлы за один вызов:

def load_all_configs(path2cfg: str) -> dict[str, Any]:
    """Parse ALL .gin files at once and return all config objects."""
    gin.clear_config()  # ОБЯЗАТЕЛЬНО: сброс глобального состояния gin
    
    gin_files = sorted(Path(path2cfg).glob("*.gin"))
    gin.parse_config_files_and_bindings(
        config_files=[str(f) for f in gin_files],
        bindings=[],
    )
    
    return {
        "pipeline": PipelineConfig(),
        "hardware": HardwareConfig(),
        "models":   ModelsConfig(),
        "input":    InputConfig(),
        "seg":      SegConfig(),
    }

Правила:

  • gin.clear_config() обязателен перед каждой загрузкой — без него параметры от предыдущих вызовов накапливаются (gin имеет глобальное состояние)
  • Все .gin файлы парсятся одним вызовом gin.parse_config_files_and_bindings()
  • Конфиг-объекты создаются после полной загрузки всех .gin
  • В main() — один вызов load_all_configs(), не 5 отдельных get_*_cfg()

3.2 Индивидуальные загрузчики (ТОЛЬКО ДЛЯ ТЕСТИРОВАНИЯ)

Для unit-тестов и отладки — отдельные get_<name>_cfg() функции в том же файле:

def get_hardware_cfg(path2cfg: str) -> HardwareConfig:
    """Load ONLY hardware config (for isolated testing)."""
    gin.clear_config()  # Обязательно!
    gin.parse_config_file(f"{path2cfg}hardware.gin")
    return HardwareConfig()

Правила:

  • Имя функции: get_<name>_cfg(path2cfg: str) -> ConfigClass
  • Обязательно gin.clear_config() перед gin.parse_config_file()
  • Используются только в тестах и notebooks, не в main()

Референс: develop_style_prompt/config_loader_reference.py


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

Плоский формат ClassName.param = value:

# hardware.gin
HardwareConfig.profile_name = 'rtx4090'
HardwareConfig.use_fp16 = True
HardwareConfig.batch_size = 8
HardwareConfig.num_workers = 4
HardwareConfig.reserve_gb = 2.0

Правила:

  • Одна строка — один параметр
  • Комментарии через #
  • Строки в одинарных или двойных кавычках
  • Списки в квадратных скобках: [1, 2, 3]
  • Не использовать макросы, ссылки, gin.constant() или другие продвинутые фичи gin
  • Каждый .gin файл соответствует одному конфиг-классу

5. Точка входа (main)

Адаптировать augment_dataset.py — использовать центральный загрузчик:

from src.conf.config_loader import load_all_configs
from src.utils.utils_file_dir import get_proj_dir

def main() -> None:
    proj_dir = get_proj_dir()
    path2cfg = f"{proj_dir}in/config_files/"

    # ОДИН вызов загружает ВСЕ конфиги:
    configs = load_all_configs(path2cfg)

    # Явная передача в пайплайн:
    run_pipeline(
        configs["pipeline"],
        configs["hardware"],
        configs["models"],
        configs["input"],
        configs["seg"],
    )
# Ищем pyproject.toml или .git как корень проекта:
MARKERS = ("pyproject.toml", ".git", "in")

def get_proj_dir() -> str:
    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("Project root not found")

Правила:

  • Убрать argparse — все параметры из gin-файлов
  • Один вызов load_all_configs() вместо 5 отдельных get_*_cfg()
  • gin.clear_config() вызывается внутри load_all_configs() автоматически
  • Конфиг-объекты передаются явно через аргументы (не через глобальный gin)
  • Функция get_proj_dir() определяет корень проекта автоматически

6. Распределение параметров по конфиг-классам

PipelineConfig (pipeline.gin)

Параметр Тип По умолчанию Описание
input_root str Путь к входным данным
output_root str Путь для выходных данных
stages list ['depth', 'edges', 'segmentation'] Стадии пайплайна
save_npy bool True Сохранять .npy файлы
save_vis bool True Сохранять визуализации
save_concat bool True Сохранять 6-канальный результат
resume bool True Пропускать уже обработанные
subset str None Фильтр по подмножеству
source str None Фильтр по источнику (query/db)
log_level str 'INFO' Уровень логирования

HardwareConfig (hardware.gin)

Параметр Тип По умолчанию Описание
profile_name str 'rtx4090' Имя профиля GPU
use_fp16 bool True Использовать half precision
batch_size int None Размер батча (None = авто)
num_workers int 4 Число DataLoader workers
reserve_gb float 2.0 Резерв VRAM в ГБ

ModelsConfig (models.gin)

Параметр Тип По умолчанию Описание
depth_model_id str 'depth-anything/...' HuggingFace ID модели глубины
depth_fallback_id str '...' Fallback модель глубины
seg_model_id str '...' ID модели сегментации
seg_fallback_id str '...' Fallback модель сегментации
depth_model_size str 'Large' Размер модели глубины
seg_model_size str 'b5' Размер модели сегментации

InputConfig (input.gin)

Параметр Тип По умолчанию Описание
image_size int 256 Размер изображения
sobel_blur_ksize int 3 Ядро Sobel для edges
edge_normalize bool True Нормализация карты краев

SegConfig (segmentation.gin)

Параметр Тип По умолчанию Описание
prompts list [...] Текстовые промпты для OV-сегментации
threshold float 0.3 Порог сегментации

7. Миграция существующих модулей

Что удалить:

  • argparse из augment_dataset.py
  • @dataclass из AugmentConfig и HardwareProfile в config.py
  • Словарь PROFILES с хардкодом профилей (перенести в gin)
  • DEFAULT_GEO_PROMPTS из models.py (перенести в gin)

Что сохранить:

  • Структуру src/augmentor/ (dataset, inference, models, io_utils)
  • Логику fallback при загрузке моделей (но model ID из конфига)
  • Логику discover_images, AugmentDataset
  • Функции сохранения (save_depth, save_edges, save_segmentation)

Что адаптировать:

  • Все функции, принимающие AugmentConfig, должны принимать отдельные конфиг-объекты
  • Захардкоженные значения (model IDs, промпты, размер 256) — в gin-файлы
  • pipeline_256.py — удалить или адаптировать под новый стиль

8. Ограничения по использованию gin

Использовать минимальный набор возможностей gin:

  • Да: @gin.configurable, gin.parse_config_file()
  • Нет: gin.register(), gin.constant(), gin.query_parameter(), макросы, ссылки между конфигами
  • Значения конфигов можно менять в runtime после загрузки (config.param = new_value)

9. Порядок выполнения миграции

  1. Создать src/conf/ с конфиг-классами и функциями загрузки
  2. Создать in/config_files/ с .gin файлами
  3. Адаптировать augment_dataset.py — заменить argparse на gin-загрузку
  4. Адаптировать augmentor/models.py — model IDs из конфига
  5. Адаптировать augmentor/inference.py — параметры из конфига
  6. Адаптировать augmentor/dataset.py — принимать конфиг-объекты
  7. Удалить старый config.py (dataclass-версию)
  8. Проверить, что depth_edges_gen.py и depth_anything_v2_generate.py используют новые конфиги
  9. Удалить или адаптировать pipeline_256.py