| # syntax=docker/dockerfile:1.6 | |
| # ============================================================================= | |
| # MiniCPM5-1B (Q8_0) GGUF chat server for Hugging Face Spaces. | |
| # Free CPU tier (2 vCPUs, 16 GB RAM). | |
| # | |
| # ARCHITECTURE: Multi-stage build (standard, no custom fork needed). | |
| # | |
| # MiniCPM5-1B uses the standard llama architecture + Q8_0 quantization, so | |
| # stock llama-cpp-python works fine β no turbo-tan fork required. This makes | |
| # the build simpler and faster (~10-15 min compile, cached by HF Spaces). | |
| # | |
| # Model: 1.07 GB on disk, 1B params, hybrid reasoning (enable_thinking), | |
| # long-context, tool-calling. Expected ~10-20 tok/s on 2 vCPUs. | |
| # ============================================================================= | |
| # ----------------------------------------------------------------------------- | |
| # Stage 1: Builder β compile llama-cpp-python wheel from source | |
| # ----------------------------------------------------------------------------- | |
| # Pin to Bookworm (Debian 12). Trixie (Debian 13) ships GCC 14 + glibc 2.41 | |
| # which has known compilation issues with llama.cpp. | |
| FROM python:3.10-slim-bookworm AS builder | |
| # Build tools + runtime deps needed to compile llama.cpp. | |
| # pkg-config : CMake's find_package(BLAS) needs it to locate OpenBLAS | |
| # libopenblas-dev: BLAS backend for the GGML BLAS path | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| build-essential \ | |
| cmake \ | |
| git \ | |
| pkg-config \ | |
| libopenblas-dev \ | |
| && rm -rf /var/lib/apt/lists/* | |
| RUN pip install --upgrade pip wheel setuptools | |
| # Compile llama-cpp-python with OpenBLAS acceleration. | |
| # CMAKE_ARGS : enable OpenBLAS, CPU-only (no CUDA) | |
| # CMAKE_BUILD_PARALLEL_LEVEL=2 : match the 2 vCPUs, avoid OOM during compile | |
| # LLAMA_CUBLAS=off : skip CUDA detection | |
| ENV CMAKE_ARGS="-DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS" \ | |
| LLAMA_CUBLAS=off \ | |
| CFLAGS="-O3" \ | |
| CXXFLAGS="-O3" \ | |
| CMAKE_BUILD_PARALLEL_LEVEL=2 | |
| # Build the wheel into /wheels. This downloads llama.cpp source + compiles. | |
| RUN pip wheel --no-cache-dir --no-deps \ | |
| --wheel-dir /wheels \ | |
| llama-cpp-python==0.3.32 | |
| # ----------------------------------------------------------------------------- | |
| # Stage 2: Runtime β slim image with pre-compiled wheel | |
| # ----------------------------------------------------------------------------- | |
| # Also pin to Bookworm so the runtime libc matches the builder's libc. | |
| FROM python:3.10-slim-bookworm | |
| # Runtime shared libraries: | |
| # libopenblas0 : BLAS runtime (wheel was compiled against libopenblas-dev) | |
| # libgomp1 : OpenMP runtime (threading) | |
| # ca-certificates / curl : HTTPS for hf_hub_download | |
| # tzdata : timezone data (UTC default) | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| libopenblas0 \ | |
| libgomp1 \ | |
| ca-certificates \ | |
| curl \ | |
| tzdata \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # Copy the compiled wheel from the builder stage and install it. | |
| COPY --from=builder /wheels/llama_cpp_python-*.whl /tmp/ | |
| # Python dependencies (versions audited 2026-07-06). | |
| # - llama-cpp-python==0.3.32 : June 2026 release. Compiled from source in | |
| # the builder stage. Standard llama.cpp β works | |
| # with MiniCPM5-1B (llama arch, Q8_0 quant). | |
| # - fastapi==0.115.6 : HTTP API framework | |
| # - uvicorn[standard]==0.34.0 : ASGI server (runs on port 7860) | |
| # - sse-starlette==2.1.3 : Server-Sent Events support for streaming | |
| # - huggingface_hub==1.22.0 : Current 1.x major (for hf_hub_download) | |
| # - tqdm==4.68.3 : Latest (progress bars) | |
| RUN pip install --upgrade pip && \ | |
| pip install /tmp/llama_cpp_python-*.whl && \ | |
| pip install \ | |
| fastapi==0.115.6 \ | |
| "uvicorn[standard]==0.34.0" \ | |
| sse-starlette==2.1.3 \ | |
| huggingface_hub==1.22.0 \ | |
| tqdm==4.68.3 && \ | |
| rm /tmp/llama_cpp_python-*.whl | |
| # Non-root user (Hugging Face Spaces requirement: UID 1000, name "user"). | |
| RUN useradd -m -u 1000 user | |
| WORKDIR /home/user/app | |
| COPY --chown=user:user app.py . | |
| USER user | |
| # HF cache must live inside the user's home directory so the non-root | |
| # process can write to it. On free-tier Spaces this is ephemeral β the | |
| # model is re-downloaded on every cold start. | |
| ENV HOME=/home/user \ | |
| PATH=/home/user/.local/bin:$PATH \ | |
| HF_HOME=/home/user/.cache/huggingface \ | |
| HF_HUB_CACHE=/home/user/.cache/huggingface/hub \ | |
| PYTHONUNBUFFERED=1 \ | |
| TZ=UTC | |
| EXPOSE 7860 | |
| CMD ["python", "app.py"] | |