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

279 lines
13 KiB
Markdown
Raw 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.
# Требования к адаптации кода под 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`:
```python
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 файлы за один вызов:
```python
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()` функции в том же файле:
```python
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`:
```gin
# 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` — использовать центральный загрузчик:
```python
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"],
)
```
```python
# Ищем 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`