| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| FROM python:3.10-slim-bookworm |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| ENV PYTHONDONTWRITEBYTECODE=1 \ |
| PYTHONUNBUFFERED=1 \ |
| PIP_NO_CACHE_DIR=1 \ |
| PIP_DISABLE_PIP_VERSION_CHECK=1 |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| ENV OMP_NUM_THREADS=2 \ |
| MKL_NUM_THREADS=2 \ |
| OPENBLAS_NUM_THREADS=2 \ |
| NUMEXPR_NUM_THREADS=2 \ |
| VECLIB_MAXIMUM_THREADS=2 |
|
|
|
|
| |
| |
| |
|
|
| WORKDIR /app |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| RUN apt-get update \ |
| && apt-get install -y --no-install-recommends \ |
| build-essential \ |
| python3-dev \ |
| ffmpeg \ |
| libsndfile1 \ |
| libsndfile1-dev \ |
| git \ |
| git-lfs \ |
| ca-certificates \ |
| curl \ |
| pkg-config \ |
| && git lfs install --system \ |
| && rm -rf /var/lib/apt/lists/* |
|
|
|
|
| # ---------------------------------------------------------------------------- |
| # 6. VERIFY NATIVE DEPENDENCIES DURING BUILD |
| # ---------------------------------------------------------------------------- |
| # |
| # This intentionally makes the Docker build fail early if ffmpeg/ffprobe are |
| # not available. |
| # |
| # ---------------------------------------------------------------------------- |
|
|
| RUN ffmpeg -version \ |
| && ffprobe -version \ |
| && git --version \ |
| && git-lfs --version |
|
|
|
|
| # ---------------------------------------------------------------------------- |
| # 7. CREATE PROJECT DIRECTORIES |
| # ---------------------------------------------------------------------------- |
| # |
| # The FastAPI service uses: |
| # |
| # src/input/<project_id>/ |
| # src/output/<project_id>/ |
| # |
| # Creating the roots here means the container starts with the expected |
| # filesystem contract. |
| # |
| # ---------------------------------------------------------------------------- |
|
|
| RUN mkdir -p \ |
| /app/src/input \ |
| /app/src/output \ |
| /app/models \ |
| /app/.cache \ |
| /app/tmp |
|
|
|
|
| # ---------------------------------------------------------------------------- |
| # 8. HUGGING FACE / MODEL CACHE LOCATIONS |
| # ---------------------------------------------------------------------------- |
| # |
| # Keep downloaded ML models in predictable locations. |
| # |
| # Hugging Face libraries commonly use HF_HOME. |
| # |
| # TORCH_HOME is also explicitly configured so Torch model/cache data does not |
| # end up scattered through the container filesystem. |
| # |
| # XDG_CACHE_HOME provides a predictable general cache root. |
| # |
| # ---------------------------------------------------------------------------- |
|
|
| ENV HF_HOME=/app/.cache/huggingface \ |
| HUGGINGFACE_HUB_CACHE=/app/.cache/huggingface/hub \ |
| TRANSFORMERS_CACHE=/app/.cache/huggingface/transformers \ |
| TORCH_HOME=/app/.cache/torch \ |
| XDG_CACHE_HOME=/app/.cache |
|
|
|
|
| # ---------------------------------------------------------------------------- |
| # 9. COPY REQUIREMENTS FIRST |
| # ---------------------------------------------------------------------------- |
| # |
| # Docker layer caching: |
| # |
| # If application source code changes but requirements do not, Docker can reuse |
| # the expensive dependency-installation layer. |
| # |
| # requirements_cpu.txt is your pipeline dependency file. |
| # requirements-fastapi.txt contains the API dependencies. |
| # |
| # ---------------------------------------------------------------------------- |
|
|
| COPY requirements_cpu.txt /app/requirements_cpu.txt |
|
|
|
|
| # ---------------------------------------------------------------------------- |
| # 10. UPGRADE PYTHON PACKAGING TOOLS |
| # ---------------------------------------------------------------------------- |
| # |
| # This follows your documented installation process: |
| # |
| # pip install --upgrade pip setuptools wheel |
| # |
| # ---------------------------------------------------------------------------- |
|
|
| RUN python -m pip install --upgrade \ |
| pip \ |
| setuptools \ |
| wheel |
|
|
|
|
| # ---------------------------------------------------------------------------- |
| # 11. INSTALL CPU PIPELINE DEPENDENCIES |
| # ---------------------------------------------------------------------------- |
| # |
| # IMPORTANT: |
| # |
| # Do NOT replace this with a hand-written package list if |
| # requirements_cpu.txt is the authoritative dependency file for the project. |
| # |
| # This guarantees that Docker uses exactly the dependency contract maintained |
| # by the project. |
| # |
| # ---------------------------------------------------------------------------- |
|
|
| RUN python -m pip install \ |
| --no-cache-dir \ |
| -r /app/requirements_cpu.txt |
|
|
|
|
|
|
| # ---------------------------------------------------------------------------- |
| # 13. COPY APPLICATION SOURCE |
| # ---------------------------------------------------------------------------- |
| # |
| # Copy the actual source only after dependencies. |
| # |
| # Expected structure: |
| # |
| # /app/ |
| # βββ main.py |
| # βββ requirements_cpu.txt |
| # βββ src/ |
| # βββ pipeline/ |
| # β βββ step_001_separate.py |
| # β βββ step_002_diarize.py |
| # β βββ step_003_segment.py |
| # β βββ step_004_transcribe.py |
| # β βββ step_005_original_subtitle.py |
| # βββ input/ |
| # βββ output/ |
| # |
| # ---------------------------------------------------------------------------- |
|
|
| COPY . /app |
|
|
|
|
| # ---------------------------------------------------------------------------- |
| # 14. RE-CREATE RUNTIME DIRECTORIES |
| # ---------------------------------------------------------------------------- |
| # |
| # COPY may overwrite the directory tree from the source repository. |
| # Therefore recreate the runtime directories after copying. |
| # |
| # ---------------------------------------------------------------------------- |
|
|
| RUN mkdir -p \ |
| /app/src/input \ |
| /app/src/output \ |
| /app/models \ |
| /app/.cache \ |
| /app/tmp |
|
|
|
|
| # ---------------------------------------------------------------------------- |
| # 15. PYTHON IMPORT / DEPENDENCY SANITY CHECK |
| # ---------------------------------------------------------------------------- |
| # |
| # This catches obvious dependency problems while building the image instead |
| # of discovering them only after deploying to Hugging Face Spaces. |
| # |
| # We intentionally don't execute any model inference here because that would |
| # make Docker builds extremely expensive. |
| # |
| # ---------------------------------------------------------------------------- |
|
|
| RUN python - <<'PY' |
| import sys |
|
|
| print("Python:", sys.version) |
|
|
| import fastapi |
| import pydantic |
| import httpx |
|
|
| print("FastAPI:", fastapi.__version__) |
| print("Pydantic:", pydantic.__version__) |
| print("HTTPX:", httpx.__version__) |
|
|
| try: |
| import torch |
| print("PyTorch:", torch.__version__) |
| print("CUDA available:", torch.cuda.is_available()) |
| except Exception as exc: |
| print("PyTorch import check failed:", exc) |
|
|
| try: |
| import faster_whisper |
| print("faster-whisper: import OK") |
| except Exception as exc: |
| print("faster-whisper import check failed:", exc) |
|
|
| print("Dependency sanity check completed.") |
| PY |
|
|
|
|
| # ---------------------------------------------------------------------------- |
| # 16. FFmpeg SANITY CHECK |
| # ---------------------------------------------------------------------------- |
|
|
| RUN ffmpeg -hide_banner -version >/dev/null \ |
| && ffprobe -hide_banner -version >/dev/null |
|
|
|
|
| # ---------------------------------------------------------------------------- |
| # 17. PYTHON PATH |
| # ---------------------------------------------------------------------------- |
| # |
| # Makes /app importable as the application root. |
| # |
| # This is particularly useful for: |
| # |
| # from src.pipeline.step_001_separate import ... |
| # |
| # ---------------------------------------------------------------------------- |
|
|
| ENV PYTHONPATH=/app |
|
|
|
|
| # ---------------------------------------------------------------------------- |
| # 18. HUGGING FACE SPACE PORT |
| # ---------------------------------------------------------------------------- |
| # |
| # Hugging Face Spaces expects the application to listen on port 7860. |
| # |
| # ---------------------------------------------------------------------------- |
|
|
| ENV PORT=7860 |
|
|
|
|
| # ---------------------------------------------------------------------------- |
| # 19. APPLICATION RUNTIME |
| # ---------------------------------------------------------------------------- |
| # |
| # IMPORTANT: |
| # |
| # Use ONE Uvicorn worker. |
| # |
| # Your pipeline deliberately limits heavy processing to one job at a time, |
| # and multiple Uvicorn workers would create separate Python processes/model |
| # instances. |
| # |
| # Therefore: |
| # |
| # --workers 1 |
| # |
| # is intentional. |
| # |
| # ---------------------------------------------------------------------------- |
|
|
| EXPOSE 7860 |
|
|
|
|
| # ---------------------------------------------------------------------------- |
| # 20. CONTAINER HEALTHCHECK |
| # ---------------------------------------------------------------------------- |
| # |
| # FastAPI exposes: |
| # |
| # GET /health |
| # |
| # Use it to verify that the web process is responding. |
| # |
| # ---------------------------------------------------------------------------- |
|
|
| HEALTHCHECK \ |
| --interval=30s \ |
| --timeout=10s \ |
| --start-period=120s \ |
| --retries=3 \ |
| CMD curl --fail http://127.0.0.1:7860/health || exit 1 |
|
|
|
|
| # ---------------------------------------------------------------------------- |
| # 21. START FASTAPI |
| # ---------------------------------------------------------------------------- |
| # |
| # exec form ensures Uvicorn receives signals correctly. |
| # |
| # $PORT is supplied by Hugging Face. |
| # |
| # ---------------------------------------------------------------------------- |
|
|
| CMD ["sh", "-c", "exec uvicorn main:app --host 0.0.0.0 --port ${PORT:-7860} --workers 1"] |