diff --git a/AGENTS.md b/AGENTS.md index 81d37ce..bb68944 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -142,6 +142,7 @@ mlflow run . -P epochs=10 -P batch_size=256 -P lr=0.001 --entry-point gpu - `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` в скриптах, логирующих модели. +- **`python -m venv` падает на Linux (ensurepip)**: на Debian/Ubuntu без пакета `python3.13-venv` (или `python3-venv`) создание venv падает на шаге `ensurepip` (`non-zero exit status 1`). `setup_server.sh` ловит это и пробует fallback: `venv --without-pip` + bootstrap pip через `get-pip.py`. Альтернатива руками — `sudo apt-get install -y python3.13-venv python3.13-dev`. - **File-store как СЕРВЕРНЫЙ бэкенд в maintenance mode (MLflow 3.x)**: `mlflow server --backend-store-uri file://...` по умолчанию падает с `MlflowException ... filesystem tracking backend is in maintenance mode`. Официальный opt-out — `export MLFLOW_ALLOW_FILE_STORE=true` (уже выставлено в `start_ui.sh` перед file-блоком). Это касается ТОЛЬКО сервера; клиентский file store (как пишут скрипты в `./mlruns`) работает без opt-out. Альтернатива без opt-out — SQLite-бэкенд (закомментированный блок в `start_ui.sh`), но тогда скрипты должны логировать на сервер через `mlflow.set_tracking_uri('http://localhost:5555')`. - **`input_example` для `mlflow.pytorch.log_model` — только numpy**, не `torch.Tensor`: MLflow 3.x валидирует пример входа и падает с `MlflowException ... but got ''`. В `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+) — стороннее шумовое предупреждение, к проекту отношения не имеет; не подавляем (чтобы не прятать реальные предупреждения). diff --git a/setup_server.sh b/setup_server.sh index c4d2b3d..2c3e25f 100755 --- a/setup_server.sh +++ b/setup_server.sh @@ -20,6 +20,51 @@ esac ARCH="$(uname -m)" echo "📍 Платформа: $PLATFORM ($ARCH)" +# --- Выбор интерпретатора Python для создания venv --- +# Предпочитаем python3.13, при отсутствии — любой python3. +if command -v python3.13 &> /dev/null; then + PYBIN="python3.13" +elif command -v python3 &> /dev/null; then + PYBIN="python3" +else + echo "❌ python3 не найден в PATH" + exit 1 +fi +echo "🐍 Интерпретатор: $PYBIN ($($PYBIN --version 2>&1))" + +# --- Создание venv (с обработкой отсутствия ensurepip/venv-пакета) --- +create_venv() { + if [ -d ".venv" ]; then + echo " .venv уже существует — пропускаю создание" + return 0 + fi + if "$PYBIN" -m venv .venv; then + return 0 + fi + echo "⚠️ '$PYBIN -m venv .venv' не удался (частая причина — не установлен" + echo " пакет python3-venv / ensurepip в дистрибутиве)." + if [ "$PLATFORM" = "linux" ]; then + echo " Debian/Ubuntu: sudo apt-get install -y python3.13-venv python3.13-dev" + echo " (или python3-venv, если версия другая)" + echo " Fedora/RHEL: sudo dnf install -y python3-devel" + fi + echo " Пробую fallback: venv без pip + bootstrap через get-pip.py..." + if ! "$PYBIN" -m venv --without-pip .venv; then + echo "❌ Не удалось создать venv даже без pip. Установите python3-venv и повторите." + return 1 + fi + if ! curl -fsSL https://bootstrap.pypa.io/get-pip.py -o /tmp/get-pip.py; then + echo "❌ Не удалось скачать get-pip.py (нет сети?). Установите pip вручную." + return 1 + fi + if ! .venv/bin/python /tmp/get-pip.py; then + echo "❌ bootstrap pip через get-pip.py не удался." + return 1 + fi + rm -f /tmp/get-pip.py + return 0 +} + # ============================================ # macOS — установка без CUDA (есть MPS на Apple Silicon) # ============================================ @@ -37,19 +82,17 @@ if [ "$PLATFORM" = "macos" ]; then fi echo " Homebrew: $(brew --version | head -1)" - # --- Python через brew (если нет) --- - if ! command -v python@3.13 &> /dev/null; then + # --- Python через brew (если нет python3.13) --- + if ! command -v python3.13 &> /dev/null; then echo "📥 Устанавливаю python@3.13 через brew..." brew install python@3.13 + # brew ставит команду python3.13 fi - echo "🐍 Python: $(python3.13 --version)" # --- Создание venv --- echo "" echo "📦 Создание виртуального окружения venv..." - if [ ! -d ".venv" ]; then - python3.13 -m venv .venv - fi + create_venv || exit 1 source .venv/bin/activate echo " Активировано: $(which python)" @@ -71,7 +114,7 @@ if [ "$PLATFORM" = "macos" ]; then # --- Проверка PyTorch + устройства --- echo "" echo "✅ Проверка PyTorch..." - python@3.13 -c " + python -c " import torch, platform print(f'PyTorch: {torch.__version__}') print(f'MPS available: {torch.backends.mps.is_available()}') @@ -96,17 +139,14 @@ else echo "⚠️ nvidia-smi не найден — CUDA может быть не установлена" fi - # --- Проверка Python --- - echo "" - echo "🐍 Проверка Python..." - python3.13 --version - # --- Создание venv --- + echo "" + echo "🐍 Проверка Python..." + "$PYBIN" --version + echo "" echo "📦 Создание виртуального окружения venv..." - if [ ! -d ".venv" ]; then - python3.13 -m venv .venv - fi + create_venv || exit 1 source .venv/bin/activate echo " Активировано: $(which python)" @@ -128,7 +168,7 @@ else # --- Проверка PyTorch + CUDA --- echo "" echo "✅ Проверка PyTorch + CUDA..." - python3.13 -c " + python -c " import torch print(f'PyTorch: {torch.__version__}') print(f'CUDA available: {torch.cuda.is_available()}') @@ -143,7 +183,7 @@ fi # ============================================ echo "" echo "✅ Проверка MLflow..." -python3.13 -c "import mlflow; print(f'MLflow: {mlflow.__version__}')" +python -c "import mlflow; print(f'MLflow: {mlflow.__version__}')" echo "" echo "============================================"