File size: 12,310 Bytes
a3577fb
e789f09
 
 
 
a3577fb
5b8300e
a3577fb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5b8300e
a3577fb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5b8300e
 
a3577fb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5b8300e
a3577fb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51528bc
 
a3577fb
 
 
 
 
 
5b8300e
a3577fb
 
a2ce8c8
a3577fb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e789f09
 
 
22a11e8
e789f09
a3577fb
 
 
 
 
 
 
 
5b8300e
a3577fb
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# ╔══════════════════════════════════════════════════════════════════════════╗
# β•‘  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"]