Files
mlflow-practice/AGENTS.md
T
second_constantine d5c5bf3767 Recall везде + фиксы окружения
- recall_macro/recall_weighted во всех скриптах с метриками
  (train_simple, train_gpu, autolog_demo, hyperparam_sweep,
   grid_search_cv, load_and_predict, compare_runs)
- grid_search_cv: multi-metric scoring (accuracy + recall_macro)
- register_model: выбор лучшей модели по recall (--metric)
- MLflow warnings: name вместо artifact_path, сигнатура модели,
  numpy input_example для pytorch, подавление env-var INFO
- start_ui.sh: порт 5555 + file-store backend (фикс: UI не показывал
  эксперименты, т.к. скрипты писали в mlruns/, а сервер читал sqlite)
- setup_server.sh: развилка macOS/Linux + проверка MPS
- train_gpu: get_device CUDA→MPS→CPU, num_workers=0 на macOS
- AGENTS.md: гид для агента + саморегламент обновления
- README/CODE_WALKTHROUGH: выровнена нумерация уроков 8/9
- .gitignore: +.DS_Store
- удалён scripts/setup_git.sh
2026-07-20 22:28:23 +03:00

207 lines
14 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.
# AGENTS.md — гид для агента по проекту mlflow-practice
> Этот файл — ориентир для любого AI-агента (и человека), который будет
> работать с проектом. Читай его **первым** при входе в репозиторий.
---
## 🎯 Назначение проекта
Учебный проект для изучения **MLflow** на практике: от логирования
экспериментов до Model Registry и serving моделей. Девять последовательных
уроков, каждый — отдельный скрипт в `src/`. Поддерживает **GPU (RTX 3090, CUDA)**
и **macOS (Intel CPU / Apple Silicon MPS)**.
Не production-система. Цель — показать полный цикл MLOps на маленьких
встроенных датасетах (digits, wine, MNIST).
---
## 📁 Карта проекта
```
mlflow-practice/
├── AGENTS.md # ← этот файл (поддерживай актуальным!)
├── README.md # пользовательская документация (как запускать)
├── CODE_WALKTHROUGH.md # подробный разбор каждого файла с пояснениями
├── MLproject # MLflow Projects: entry points main/gpu/sweep
├── python_env.yaml # окружение для MLproject (python 3.10)
├── requirements.txt # pip-зависимости
├── setup_server.sh # установка окружения (РАЗВИЛКА macOS/Linux)
├── start_ui.sh # запуск MLflow Tracking Server (UI на :5555, file-store)
├── .gitignore
├── scripts/
│ └── setup_git.sh # настройка Git (HTTPS + токен)
├── src/ # ← весь код уроков здесь
│ ├── train_simple.py # Урок 1: sklearn + Tracking (ручное логирование)
│ ├── train_gpu.py # Урок 2: PyTorch CNN, CUDA→MPS→CPU
│ ├── register_model.py # Урок 3: Model Registry (версии, стадии)
│ ├── load_and_predict.py # Урок 4: загрузка модели + предсказание
│ ├── compare_runs.py # Урок 5: сравнение запусков через API
│ ├── autolog_demo.py # Урок 6: mlflow.autolog()
│ ├── hyperparam_sweep.py # Урок 7: перебор гиперпараметров вручную
│ ├── serve_model.py # Урок 8: REST API сервер модели (Flask)
│ └── grid_search_cv.py # Урок 9: GridSearchCV + autolog
├── data/ # датасеты (MNIST скачается автоматически)
├── artifacts/ # графики, отчёты (логируются в MLflow)
└── mlruns/ # локальный file store MLflow (в .gitignore)
```
---
## 🧩 Роль каждого файла (кратко)
| Файл | Что делает | Датасет | Фреймворк |
|---|---|---|---|
| `train_simple.py` | RandomForest, ручное логирование params/metrics/model/artifacts | digits | sklearn |
| `train_gpu.py` | CNN, логирование по эпохам, выбор устройства `get_device()` | MNIST | PyTorch |
| `register_model.py` | ищет лучший run по метрике, регистрирует модель, стадия Production | — | MLflow API |
| `load_and_predict.py` | грузит `models:/digits_rf_model/Production`, предсказывает | digits | MLflow |
| `compare_runs.py` | `MlflowClient.search_runs`, топ-N по метрике | — | MLflow API |
| `autolog_demo.py` | `mlflow.autolog()` для GradientBoosting | wine | sklearn |
| `hyperparam_sweep.py` | ручной перебор комбинаций, `--max-combos` | digits | sklearn |
| `serve_model.py` | Flask-сервер `/predict`, грузит модель из реестра | digits | Flask + MLflow |
| `grid_search_cv.py` | `GridSearchCV`, autolog залогит каждую попытку | digits | sklearn |
---
## 🖥️ Платформенная специфика
### Выбор устройства в `train_gpu.py`
Функция `get_device()` определяет устройство в порядке:
**CUDA → MPS (Apple Silicon) → CPU**. Тег MLflow `device_type` хранит выбор
(`cuda` / `mps` / `cpu`) — по нему удобно фильтровать запуски в UI.
### `num_workers` в DataLoader
На **macOS с MPS** многопроцессная загрузка нестабильна (fork + MPS),
поэтому `num_workers=0` на Darwin и `4` на Linux. `pin_memory=True`
только для CUDA. Логика — в `train_gpu.py` рядом с `DataLoader`.
### `setup_server.sh` — развивка по ОС
- `Darwin` → macOS: проверка Homebrew, `python@3.12` через brew, PyTorch
из PyPI (без CUDA), проверка `torch.backends.mps.is_available()`.
- `Linux` → GPU-сервер: `nvidia-smi`, PyTorch из
`--index-url https://download.pytorch.org/whl/cu121`, проверка VRAM.
При добавлении новой платформы — расширяй `case "$OS"` в начале скрипта.
---
## 🚀 Стандартные команды
```bash
# Окружение
bash setup_server.sh # установка (macOS или Linux)
source .venv/bin/activate
./start_ui.sh # MLflow UI → http://localhost:5555
# Уроки (в отдельном терминале, с активированным venv)
python src/train_simple.py --n-estimators 100 --max-depth 8
python src/train_gpu.py --epochs 5 --batch-size 128 --lr 0.001 # macOS/MPS
python src/register_model.py --experiment digits_classification
python src/load_and_predict.py
python src/compare_runs.py --experiment digits_classification --top 10
python src/autolog_demo.py
python src/hyperparam_sweep.py --max-combos 20
python src/serve_model.py --port 5001
python src/grid_search_cv.py
# Через MLflow Projects (изолированное окружение по MLproject)
mlflow run . -P n_estimators=100 -P max_depth=8
mlflow run . -P epochs=10 -P batch_size=256 -P lr=0.001 --entry-point gpu
```
---
## 🔧 Конвенции кода
- **Датасеты** — только встроенные (`load_digits`, `load_wine`, MNIST через
`torchvision`). Никаких внешних файлов в `data/`, кроме скачанного MNIST.
- **Логирование** — параметры/метрики/модель/артефакты. Графики сохраняются
в `artifacts/` и логируются через `mlflow.log_artifact`.
- **Имена экспериментов**: `digits_classification`, `mnist_cnn_gpu`,
`wine_autolog` и т.п. Модель в реестре — `digits_rf_model`.
- **`matplotlib.use("Agg")`** обязателен перед импортом pyplot — скрипты
работают без GUI (на сервере).
- **Python ≥ 3.10** (см. `python_env.yaml`). type hints опциональны.
- **CLI через `argparse`** — все скрипты с параметрами запускаются из CLI.
---
## ⚠️ Известные шероховатости / TODO
- ~~Нумерация уроков 8/9 расходилась между докстрингами и README/CODE_WALKTHROUGH~~ —
**исправлено**: канон `serve_model.py`=Урок 8 / `grid_search_cv.py`=Урок 9,
README.md и CODE_WALKTHROUGH.md выровнены под докстринги (порядок секций тоже).
- `requirements.txt` включает `torch`/`torchvision` из PyPI (CPU/MPS).
Для CUDA их нужно ставить отдельно через `--index-url .../whl/cu121`
(см. `setup_server.sh`, ветка Linux).
- **Порт MLflow UI = 5555** (не 5000): на macOS порт 5000 занят системным сервисом AirPlay Receiver (процесс `ControlCenter`), поэтому `start_ui.sh` использует 5555. На Linux можно вернуть 5000, но 5555 работает везде.
- **MLflow 3.x: `artifact_path` устарел** — во всех `log_model` используется `name=...` (был `artifact_path=...`). При обновлении/добавлении log_model не используй `artifact_path`.
- **Сигнатура модели**: `train_simple.py` логирует модель с явной `signature=` и `input_example=` (через `mlflow.models.signature.infer_signature`). Без этого MLflow пишет warning «Model logged without a signature and input example».
- `train_gpu.py` передаёт `input_example` → сигнатура авто-infer'ится.
- `autolog_demo.py` намеренно отключает сигнатуры (`log_model_signatures=False`) как демо опций autolog — там warning ожидаем.
- **INFO про переменные окружения** (`OPENAI_API_KEY` и т.п.) при логировании подавлено через `MLFLOW_RECORD_ENV_VARS_IN_MODEL_LOGGING=false` в скриптах, логирующих модели.
- **`input_example` для `mlflow.pytorch.log_model` — только numpy**, не `torch.Tensor`: MLflow 3.x валидирует пример входа и падает с `MlflowException ... but got '<class 'torch.Tensor'>'`. В `train_gpu.py` передаётся `np.random.rand(1,1,28,28).astype(np.float32)`. Аналогично для других flavor'ов — пример должен быть DataFrame/ndarray/dict/list/скаляр.
- **urllib3 `NotOpenSSLWarning`** на macOS (системный `ssl` собран с LibreSSL 2.8.3, urllib3 v2 просит OpenSSL 1.1.1+) — стороннее шумовое предупреждение, к проекту отношения не имеет; не подавляем (чтобы не прятать реальные предупреждения).
- **«Эксперимент не виден в UI» (главная причина)**: скрипты по умолчанию пишут в локальный file store `./mlruns`, а `start_ui.sh` раньше поднимал сервер на **SQLite** (`mlflow.db`) — два разных хранилища, UI ничего не показывал. Теперь `start_ui.sh` использует `--backend-store-uri file://${PWD}/mlruns`**то же хранилище, что и скрипты**, поэтому всё видно без настройки tracking URI. Альтернатива (SQLite-бэкенд) оставлена закомментированной в `start_ui.sh`; при её включении в скриптах нужно задать `mlflow.set_tracking_uri('http://localhost:5555')` (или `MLFLOW_TRACKING_URI`).
- `mlruns/`, `artifacts/*`, `data/MNIST/`, `mlflow.db` — в `.gitignore`,
в репозиторий не попадают.
---
## 🔄 Когда обновлять этот файл
**AGENTS.md — живой документ. Обновляй его при:**
1. **Добавлении/удалении файла в `src/`** — обнови карту проекта и таблицу ролей.
2. **Изменении платформенной логики** (новое устройство, новая ОС в
`setup_server.sh`, изменение `get_device()` или `num_workers`) — обнови
раздел «Платформенная специфика».
3. **Изменении имён экспериментов/моделей** в реестре — обнови «Конвенции».
4. **Изменении зависимостей или версии Python** (`requirements.txt`,
`python_env.yaml`) — проверь раздел команд и конвенции.
5. **Появлении новых entry points в `MLproject`** — добавь в карту и команды.
6. **Обнаружении gotcha/шероховатости** — занеси в «Известные шероховатости»,
чтобы следующий агент не наступал повторно.
Правило простое: **если ты что-то изменил в структуре/поведении проекта,
отрази это в AGENTS.md в том же коммите.** Если файл устарел относительно
кода — это баг, который нужно исправить.
---
## 📌 Шпаргалка по MLflow API (часто используемое в проекте)
```python
mlflow.set_experiment("name")
with mlflow.start_run(run_name="...") as run:
mlflow.log_param("k", v)
mlflow.log_metric("acc", 0.95, step=epoch)
mlflow.log_artifact("artifacts/curve.png")
mlflow.sklearn.log_model(model, "model") # sklearn flavor
mlflow.pytorch.log_model(model, "model") # pytorch flavor
mlflow.set_tag("device_type", "mps")
mlflow.autolog() # авто-логирование
# Model Registry
client = MlflowClient()
client.search_runs([experiment_id], order_by=["metrics.accuracy DESC"])
mlflow.register_model("runs:/<run_id>/model", "digits_rf_model")
client.transition_model_version_stage("digits_rf_model", version=1, stage="Production")
mlflow.pyfunc.load_model("models:/digits_rf_model/Production")
```
---
## 🧭 С чего начать новому агенту
1. Прочитай этот файл целиком.
2. Прочитай `README.md` (пользовательский взгляд) и `CODE_WALKTHROUGH.md`
(детальный разбор кода).
3. Прогони `bash setup_server.sh` на целевой платформе, чтобы понять
состояние окружения.
4. Перед правками проверь `git status` — в этом окружении `.git` может быть
read-only для агента (тогда коммит делает пользователь вручную).
5. Любое структурное изменение → коммит + правка AGENTS.md.