migrate to uv + pyproject.toml
- root pyproject.toml replaces requirements.txt and requirements-worker.txt (worker = root + ffmpeg-python which root already had); test deps moved to [dependency-groups] dev - core/gpu/pyproject.toml replaces core/gpu/requirements.txt; uses [tool.uv.sources] to pin torch/torchvision and paddlepaddle-gpu to their CUDA index URLs, replacing the manual reinstall dance from old comments - Dockerfiles use uv sync --frozen against uv.lock for reproducible builds; PATH includes /app/.venv/bin so k8s manifests' bare uvicorn/celery commands resolve without wrapping in uv run - core/gpu/run.sh local mode now does uv sync + uv run python server.py; errors out cleanly if uv is missing
This commit is contained in:
@@ -8,8 +8,11 @@ RUN apt-get update && apt-get install -y \
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY requirements.txt .
|
ENV PATH="/app/.venv/bin:$PATH"
|
||||||
RUN uv pip install --system --no-cache -r requirements.txt
|
|
||||||
|
# uv.lock is generated on first build (dev box can't reach paddlepaddle's index)
|
||||||
|
COPY pyproject.toml ./
|
||||||
|
RUN uv sync --no-install-project --no-dev
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
|
|||||||
42
core/gpu/pyproject.toml
Normal file
42
core/gpu/pyproject.toml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
[project]
|
||||||
|
name = "mpr-gpu"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "MPR remote inference server (GPU)"
|
||||||
|
requires-python = ">=3.11"
|
||||||
|
dependencies = [
|
||||||
|
"fastapi>=0.109.0",
|
||||||
|
"uvicorn[standard]>=0.27.0",
|
||||||
|
"rapidfuzz>=3.0.0",
|
||||||
|
"Pillow>=10.0.0",
|
||||||
|
"redis>=5.0.0",
|
||||||
|
"ultralytics>=8.0.0",
|
||||||
|
"paddleocr>=3.0.0",
|
||||||
|
"paddlepaddle-gpu==3.0.0",
|
||||||
|
"transformers>=4.40.0,<5",
|
||||||
|
"accelerate>=0.27.0",
|
||||||
|
"torch",
|
||||||
|
"torchvision",
|
||||||
|
"opencv-python-headless>=4.8.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
# RTX 3080 / CUDA toolkit 12.8 — cu126 wheels are forward-compatible
|
||||||
|
# (no cu128 wheels yet on either index). Mixing PyPI torch with CUDA 12.8
|
||||||
|
# causes NCCL symbol errors, so the explicit index pins prevent uv from
|
||||||
|
# pulling torch transitively from PyPI via ultralytics.
|
||||||
|
[tool.uv.sources]
|
||||||
|
torch = { index = "pytorch-cu126" }
|
||||||
|
torchvision = { index = "pytorch-cu126" }
|
||||||
|
paddlepaddle-gpu = { index = "paddle-cu126" }
|
||||||
|
|
||||||
|
[[tool.uv.index]]
|
||||||
|
name = "pytorch-cu126"
|
||||||
|
url = "https://download.pytorch.org/whl/cu126"
|
||||||
|
explicit = true
|
||||||
|
|
||||||
|
[[tool.uv.index]]
|
||||||
|
name = "paddle-cu126"
|
||||||
|
url = "https://www.paddlepaddle.org.cn/packages/stable/cu126/"
|
||||||
|
explicit = true
|
||||||
|
|
||||||
|
[tool.uv]
|
||||||
|
package = false
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
fastapi>=0.109.0
|
|
||||||
uvicorn[standard]>=0.27.0
|
|
||||||
rapidfuzz>=3.0.0
|
|
||||||
Pillow>=10.0.0
|
|
||||||
redis>=5.0.0
|
|
||||||
|
|
||||||
# --- GPU-specific installs (mcrn: RTX 3080, CUDA toolkit 12.8) ---
|
|
||||||
#
|
|
||||||
# torch: must be installed from the PyTorch index, NOT from PyPI.
|
|
||||||
# cu126 is the closest build to CUDA 12.8 (no cu128 wheel yet; cu126 is forward-compatible).
|
|
||||||
# Install with:
|
|
||||||
# uv pip install --reinstall torch torchvision --index-url https://download.pytorch.org/whl/cu126
|
|
||||||
#
|
|
||||||
# ultralytics pulls torch as a dependency — reinstall torch after ultralytics to ensure
|
|
||||||
# the correct CUDA build. Mixing the PyPI torch with CUDA 12.8 causes NCCL symbol errors.
|
|
||||||
ultralytics>=8.0.0
|
|
||||||
|
|
||||||
# paddlepaddle-gpu: NOT available on PyPI. Install from PaddlePaddle's package index.
|
|
||||||
# cu126 build works on CUDA 12.8.
|
|
||||||
# Install with:
|
|
||||||
# uv pip install paddlepaddle-gpu==3.0.0 -i https://www.paddlepaddle.org.cn/packages/stable/cu126/
|
|
||||||
paddleocr>=3.0.0
|
|
||||||
|
|
||||||
# VLM (moondream2) — uses torch (already installed above)
|
|
||||||
# Pinned <5: transformers 5.x broke moondream2's custom model code
|
|
||||||
# (all_tied_weights_keys API change). Also needs accelerate for device_map.
|
|
||||||
transformers>=4.40.0,<5
|
|
||||||
accelerate>=0.27.0
|
|
||||||
|
|
||||||
# Preprocessing (phase 12)
|
|
||||||
opencv-python-headless>=4.8.0
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
# Run the inference server
|
# Run the inference server
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# ./run.sh # Local (pip install -r requirements.txt first)
|
# ./run.sh # Local: uv sync + run server.py (auto-installs/activates .venv)
|
||||||
# ./run.sh docker # Docker (CPU)
|
# ./run.sh docker # Docker (CPU)
|
||||||
# ./run.sh docker-gpu # Docker with GPU
|
# ./run.sh docker-gpu # Docker with GPU
|
||||||
# ./run.sh stop # Stop Docker container
|
# ./run.sh stop # Stop Docker container
|
||||||
@@ -26,7 +26,12 @@ fi
|
|||||||
|
|
||||||
case "${1:-local}" in
|
case "${1:-local}" in
|
||||||
local)
|
local)
|
||||||
python server.py
|
if ! command -v uv >/dev/null 2>&1; then
|
||||||
|
echo "uv not found. Install: curl -LsSf https://astral.sh/uv/install.sh | sh"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
uv sync
|
||||||
|
uv run python server.py
|
||||||
;;
|
;;
|
||||||
docker)
|
docker)
|
||||||
docker build -t mpr-inference .
|
docker build -t mpr-inference .
|
||||||
|
|||||||
@@ -6,8 +6,11 @@ RUN pip install --no-cache-dir uv
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY requirements.txt .
|
# Put the project venv on PATH so k8s/compose commands (uvicorn, etc.) resolve
|
||||||
RUN uv pip install --system --no-cache -r requirements.txt
|
ENV PATH="/app/.venv/bin:$PATH"
|
||||||
|
|
||||||
|
COPY pyproject.toml uv.lock ./
|
||||||
|
RUN uv sync --frozen --no-install-project --no-dev
|
||||||
|
|
||||||
# Copy code into image (k8s uses this, docker-compose volume-mounts over it)
|
# Copy code into image (k8s uses this, docker-compose volume-mounts over it)
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|||||||
@@ -8,10 +8,11 @@ RUN apt-get update && apt-get install -y \
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY requirements.txt requirements-worker.txt ./
|
ENV PATH="/app/.venv/bin:$PATH"
|
||||||
RUN uv pip install --system --no-cache -r requirements-worker.txt
|
|
||||||
|
COPY pyproject.toml uv.lock ./
|
||||||
|
RUN uv sync --frozen --no-install-project --no-dev
|
||||||
|
|
||||||
# Copy code into image (k8s uses this, docker-compose volume-mounts over it)
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
CMD ["celery", "-A", "admin.mpr", "worker", "--loglevel=info"]
|
CMD ["celery", "-A", "admin.mpr", "worker", "--loglevel=info"]
|
||||||
|
|||||||
42
pyproject.toml
Normal file
42
pyproject.toml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
[project]
|
||||||
|
name = "mpr"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "MPR — multi-pipeline runtime (api, admin, worker)"
|
||||||
|
requires-python = ">=3.11"
|
||||||
|
dependencies = [
|
||||||
|
"Django>=4.2,<5.0",
|
||||||
|
"django-environ>=0.11.2",
|
||||||
|
"fastapi>=0.109.0",
|
||||||
|
"uvicorn[standard]>=0.27.0",
|
||||||
|
"pydantic>=2.5.0",
|
||||||
|
"celery[redis]>=5.3.0",
|
||||||
|
"redis>=5.0.0",
|
||||||
|
"grpcio>=1.60.0",
|
||||||
|
"grpcio-tools>=1.60.0",
|
||||||
|
"boto3>=1.34.0",
|
||||||
|
"requests>=2.31.0",
|
||||||
|
"google-cloud-run>=0.10.0",
|
||||||
|
"strawberry-graphql[fastapi]>=0.311.0",
|
||||||
|
"langfuse>=2.0.0",
|
||||||
|
"anthropic>=0.40.0",
|
||||||
|
"sqlmodel>=0.0.14",
|
||||||
|
"psycopg2-binary>=2.9.9",
|
||||||
|
"opencv-python-headless>=4.8.0",
|
||||||
|
"numpy>=1.24.0",
|
||||||
|
"Pillow>=10.0.0",
|
||||||
|
"imagehash>=4.3.0",
|
||||||
|
"ffmpeg-python>=0.2.0",
|
||||||
|
"langgraph>=0.0.30",
|
||||||
|
"rapidfuzz>=3.0.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[dependency-groups]
|
||||||
|
dev = [
|
||||||
|
"pytest>=7.4.0",
|
||||||
|
"pytest-django>=4.7.0",
|
||||||
|
"pytest-asyncio>=0.23.0",
|
||||||
|
"httpx>=0.26.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.uv]
|
||||||
|
package = false
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
-r requirements.txt
|
|
||||||
ffmpeg-python>=0.2.0
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
# Django (admin viewer only — no app code depends on this)
|
|
||||||
Django>=4.2,<5.0
|
|
||||||
django-environ>=0.11.2
|
|
||||||
|
|
||||||
# FastAPI
|
|
||||||
fastapi>=0.109.0
|
|
||||||
uvicorn[standard]>=0.27.0
|
|
||||||
pydantic>=2.5.0
|
|
||||||
|
|
||||||
# Celery
|
|
||||||
celery[redis]>=5.3.0
|
|
||||||
redis>=5.0.0
|
|
||||||
|
|
||||||
# gRPC
|
|
||||||
grpcio>=1.60.0
|
|
||||||
grpcio-tools>=1.60.0
|
|
||||||
|
|
||||||
# AWS
|
|
||||||
boto3>=1.34.0
|
|
||||||
requests>=2.31.0
|
|
||||||
|
|
||||||
# GCP (optional — only needed when MPR_EXECUTOR=gcp)
|
|
||||||
google-cloud-run>=0.10.0
|
|
||||||
|
|
||||||
# GraphQL
|
|
||||||
strawberry-graphql[fastapi]>=0.311.0
|
|
||||||
|
|
||||||
# Observability
|
|
||||||
langfuse>=2.0.0
|
|
||||||
|
|
||||||
# Cloud LLM providers (only needed for cloud escalation stage)
|
|
||||||
anthropic>=0.40.0
|
|
||||||
|
|
||||||
# Database (SQLModel/SQLAlchemy + psycopg2)
|
|
||||||
sqlmodel>=0.0.14
|
|
||||||
psycopg2-binary>=2.9.9
|
|
||||||
|
|
||||||
# Detection pipeline orchestration
|
|
||||||
opencv-python-headless>=4.8.0
|
|
||||||
numpy>=1.24.0
|
|
||||||
Pillow>=10.0.0
|
|
||||||
imagehash>=4.3.0
|
|
||||||
ffmpeg-python>=0.2.0
|
|
||||||
langgraph>=0.0.30
|
|
||||||
rapidfuzz>=3.0.0
|
|
||||||
|
|
||||||
# Testing
|
|
||||||
pytest>=7.4.0
|
|
||||||
pytest-django>=4.7.0
|
|
||||||
pytest-asyncio>=0.23.0
|
|
||||||
httpx>=0.26.0
|
|
||||||
Reference in New Issue
Block a user