Abed-gemma4-chat-api / Dockerfile
abedgemma's picture
Update Dockerfile
22a11e8 verified
Raw
History Blame Contribute Delete
12.3 kB
# ╔══════════════════════════════════════════════════════════════════════════╗
# β•‘ MYTHICAL UNIVERSAL SYSTEM β€” Dockerfile [v7.1] β•‘
# β•‘ [FIX-A] RAM thresholds β†’ 0 (auto-detect via cgroup, not hardcoded) β•‘
# β•‘ [FIX-D] THINKING_TIMEOUT=300s added β•‘
# β•‘ + all v7.0 fixes (PGO+ThinLTO, Ubuntu 22.04, whisper.cpp server) β•‘
# β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
# ─────────────────────────────────────────────────────────────────────────────
# STAGE 1: PGO INSTRUMENTATION BUILD
# ─────────────────────────────────────────────────────────────────────────────
FROM ubuntu:22.04 AS pgo-instrument
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
clang-15 lld-15 llvm-15 cmake make git \
python3 python3-pip \
libcurl4-openssl-dev ca-certificates curl \
&& ln -sf /usr/bin/clang-15 /usr/local/bin/clang \
&& ln -sf /usr/bin/clang++-15 /usr/local/bin/clang++ \
&& rm -rf /var/lib/apt/lists/*
# Download small profiling model (200MB, same transformer hot paths as Qwen3)
RUN pip3 install --no-cache-dir --break-system-packages huggingface_hub hf_transfer 2>/dev/null || \
pip3 install --no-cache-dir huggingface_hub hf_transfer && \
HF_HUB_ENABLE_HF_TRANSFER=1 python3 -c "\
from huggingface_hub import hf_hub_download; \
hf_hub_download( \
repo_id='bartowski/SmolLM2-360M-Instruct-GGUF', \
filename='SmolLM2-360M-Instruct-Q4_K_M.gguf', \
local_dir='/pgo_model' \
)"
WORKDIR /llama
RUN git clone --depth=1 https://github.com/ggml-org/llama.cpp .
# Instrumented build
RUN mkdir -p /pgo-data && \
cmake -B build-instr \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DGGML_AVX2=ON -DGGML_FMA=ON -DGGML_F16C=ON \
-DGGML_NATIVE=OFF \
-DBUILD_SHARED_LIBS=OFF \
-DLLAMA_CURL=ON \
-DCMAKE_C_FLAGS="-fprofile-generate=/pgo-data -O2 -march=x86-64-v3" \
-DCMAKE_CXX_FLAGS="-fprofile-generate=/pgo-data -O2 -march=x86-64-v3" \
-DCMAKE_EXE_LINKER_FLAGS="-fprofile-generate=/pgo-data" \
&& cmake --build build-instr --target llama-server -j$(nproc)
# Profile run β€” covers all real production use cases
RUN /llama/build-instr/bin/llama-server \
--model /pgo_model/SmolLM2-360M-Instruct-Q4_K_M.gguf \
--host 127.0.0.1 --port 18080 \
--ctx-size 2048 --threads 2 --parallel 1 \
--log-disable > /tmp/pgo.log 2>&1 & \
SERVER_PID=$! && \
for i in $(seq 1 30); do \
sleep 3; curl -sf http://127.0.0.1:18080/health >/dev/null 2>&1 && break; \
done && \
# Profile 1: Arabic text completion
curl -sf http://127.0.0.1:18080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"p","messages":[{"role":"system","content":"You are a universal AI assistant."},{"role":"user","content":"Ψ§Ψ΄Ψ±Ψ­ Ω…ΩΩ‡ΩˆΩ… Ψ§Ω„ΨͺΨΉΩ„Ω… Ψ§Ω„Ψ’Ω„ΩŠ Ψ¨Ψ·Ψ±ΩŠΩ‚Ψ© بسيطة Ω…ΨΉ Ψ£Ω…Ψ«Ω„Ψ© ΨΉΩ…Ω„ΩŠΨ©."}],"max_tokens":250}' >/dev/null 2>&1 || true && \
# Profile 2: English reasoning
curl -sf http://127.0.0.1:18080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"p","messages":[{"role":"user","content":"Explain the difference between supervised and unsupervised learning."}],"max_tokens":300}' >/dev/null 2>&1 || true && \
# Profile 3: Tool calling (MCP)
curl -sf http://127.0.0.1:18080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"p","messages":[{"role":"user","content":"Search for latest AI research papers."}],"max_tokens":100,"tools":[{"type":"function","function":{"name":"web_search","description":"Search the web","parameters":{"type":"object","properties":{"query":{"type":"string"}},"required":["query"]}}}],"tool_choice":"auto"}' >/dev/null 2>&1 || true && \
# Profile 4: Streaming
curl -sf http://127.0.0.1:18080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"p","messages":[{"role":"user","content":"Write a Python function to download files asynchronously."}],"max_tokens":200,"stream":true}' >/dev/null 2>&1 || true && \
# Profile 5: Code generation
curl -sf http://127.0.0.1:18080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"p","messages":[{"role":"user","content":"Write a complete React component for a chat interface."}],"max_tokens":400}' >/dev/null 2>&1 || true && \
# Repeated short requests (cache path)
for i in $(seq 1 8); do \
curl -sf http://127.0.0.1:18080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"p","messages":[{"role":"user","content":"Hello"}],"max_tokens":10}' >/dev/null 2>&1 || true; \
done && \
kill "${SERVER_PID}" && wait "${SERVER_PID}" 2>/dev/null || true && \
llvm-profdata-15 merge --output=/pgo-data/merged.profdata /pgo-data/ && \
echo "[PGO] Profile data ready: $(ls -lh /pgo-data/merged.profdata)"
# ─────────────────────────────────────────────────────────────────────────────
# STAGE 2: PGO + ThinLTO OPTIMISED llama-server
# ─────────────────────────────────────────────────────────────────────────────
FROM ubuntu:22.04 AS llama-builder
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
clang-15 lld-15 llvm-15 cmake make libcurl4-openssl-dev ca-certificates \
&& ln -sf /usr/bin/clang-15 /usr/local/bin/clang \
&& ln -sf /usr/bin/clang++-15 /usr/local/bin/clang++ \
&& rm -rf /var/lib/apt/lists/*
COPY --from=pgo-instrument /llama /llama
COPY --from=pgo-instrument /pgo-data /pgo-data
WORKDIR /llama
RUN cmake -B build-final \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DGGML_AVX2=ON -DGGML_FMA=ON -DGGML_F16C=ON \
-DGGML_NATIVE=OFF \
-DBUILD_SHARED_LIBS=OFF \
-DLLAMA_CURL=ON \
-DCMAKE_C_FLAGS="-fprofile-use=/pgo-data/merged.profdata \
-fprofile-correction -flto=thin \
-O3 -march=x86-64-v3 -DNDEBUG" \
-DCMAKE_CXX_FLAGS="-fprofile-use=/pgo-data/merged.profdata \
-fprofile-correction -flto=thin \
-O3 -march=x86-64-v3 -DNDEBUG" \
-DCMAKE_EXE_LINKER_FLAGS="-flto=thin -fuse-ld=lld-15" \
&& cmake --build build-final --target llama-server -j$(nproc) \
&& strip --strip-unneeded build-final/bin/llama-server \
&& echo "[llama-builder] Binary: $(du -sh build-final/bin/llama-server)"
# ─────────────────────────────────────────────────────────────────────────────
# STAGE 3: WHISPER.CPP SERVER
# Separate stage to avoid ggml version conflicts with llama.cpp
# ─────────────────────────────────────────────────────────────────────────────
FROM ubuntu:22.04 AS whisper-builder
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
clang-15 lld-15 cmake make git ca-certificates \
&& ln -sf /usr/bin/clang-15 /usr/local/bin/clang \
&& ln -sf /usr/bin/clang++-15 /usr/local/bin/clang++ \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /whisper
RUN git clone --depth=1 https://github.com/ggml-org/whisper.cpp .
RUN cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DGGML_AVX2=ON -DGGML_FMA=ON -DGGML_F16C=ON \
-DGGML_NATIVE=OFF \
-DWHISPER_BUILD_SERVER=ON \
-DWHISPER_NO_OPENVINO=ON \
-DCMAKE_C_FLAGS="-O3 -march=x86-64-v3 -DNDEBUG" \
-DCMAKE_CXX_FLAGS="-O3 -march=x86-64-v3 -DNDEBUG" \
&& cmake --build build --target whisper-server -j$(nproc) \
&& strip --strip-unneeded build/bin/whisper-server \
&& echo "[whisper-builder] Binary: $(du -sh build/bin/whisper-server)"
# ─────────────────────────────────────────────────────────────────────────────
# STAGE 4: RUNTIME β€” minimal, production-ready
# ─────────────────────────────────────────────────────────────────────────────
FROM python:3.11-slim AS runtime
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
ffmpeg \
libcurl4 \
libjemalloc2 \
curl tini ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Copy optimised binaries
COPY --from=llama-builder /llama/build-final/bin/llama-server /usr/local/bin/llama-server
COPY --from=whisper-builder /whisper/build/bin/whisper-server /usr/local/bin/whisper-server
RUN chmod +x /usr/local/bin/llama-server /usr/local/bin/whisper-server
# Python dependencies
RUN pip install --no-cache-dir \
"fastapi==0.115.12" \
"uvicorn[standard]==0.34.3" \
"uvloop==0.21.0" \
"httpx==0.28.1" \
"orjson==3.10.18" \
"psutil==7.0.0" \
"pillow==11.2.1" \
"pypdf==5.4.0" \
"beautifulsoup4==4.13.4" \
"youtube-transcript-api==0.6.3" \
"aiohttp==3.11.18" \
"huggingface_hub==0.31.4" \
"hf_transfer==0.1.9" \
"python-multipart==0.0.20"
WORKDIR /app
COPY app.py /app/app.py
COPY model_manager.py /app/model_manager.py
COPY startup.sh /app/startup.sh
RUN chmod +x /app/startup.sh
RUN mkdir -p /data/models /data/slot_cache /data/whisper /tmp/media /var/log /var/run
VOLUME ["/data"]
# ── Environment defaults ──────────────────────────────────────────────────────
ENV \
# Model selection managed by model_manager.py
MODEL_DIR="/data/models" \
SLOT_CACHE_DIR="/data/slot_cache" \
WHISPER_DIR="/data/whisper" \
WHISPER_MODEL_SIZE="base" \
# Server
LLAMA_HOST="127.0.0.1" LLAMA_PORT="8080" \
WHISPER_HOST="127.0.0.1" WHISPER_PORT="8081" \
API_HOST="0.0.0.0" API_PORT="7860" \
# Inference
CTX_SIZE="16384" \
MAX_NEW_TOKENS="2048" \
MAX_CTX_TOKENS="14000" \
# Safety β€” 0 = auto-detect container RAM via cgroup, then 82/90/95%
RAM_WARN_GB="0" RAM_REJECT_GB="0" RAM_FLUSH_GB="0" \
RAM_LIMIT_GB="14.0" \
REQUEST_TIMEOUT="90.0" THINKING_TIMEOUT="600.0" GENERATE_TIMEOUT="600.0" \
QUEUE_TIMEOUT="30.0" ENRICH_TIMEOUT="12.0" DOWNLOAD_TIMEOUT="30.0" \
# API
API_KEY="change-this-to-a-strong-secret" \
RATE_LIMIT_RPM="60" CACHE_TTL="60" \
# Media
IMAGE_MAX_PX="1120" VIDEO_MAX_FRAMES="8" MAX_FILE_MB="50" \
# HF
HF_HUB_ENABLE_HF_TRANSFER="1" \
PYTHONUNBUFFERED="1" PYTHONDONTWRITEBYTECODE="1"
EXPOSE 7860
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["/app/startup.sh"]