mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-11 17:26:57 +02:00
Image : le build CUDA était tué par l'OOM, pas en échec de compilation
Le premier build de l'image avec whisper CUDA a échoué après huit minutes sans écrire une seule ligne d'erreur : le journal s'arrête à 92 % de la compilation, puis « Complete job ». Un compilateur qui échoue dit pourquoi ; un compilateur tué ne dit rien. Ces 92 % étaient atteints en TREIZE secondes. Ce ne sont pas des compilations terminées, ce sont des nvcc lancés simultanément. « cmake --build -j » sans nombre autorise chez Make un parallélisme illimité. ggml-cuda compte environ 200 fichiers d'instanciation de gabarits et chaque nvcc réclame 1 à 2 Go : le runner (16 Go) mourait d'un OOM. L'étape CPU y survivait — peu de fichiers, compilation légère — ce qui a rendu le piège invisible jusqu'à l'arrivée de CUDA. - -j"$(nproc)" sur les deux étapes, et un test le vérifie désormais : cette faute est indétectable à la lecture et ne se manifeste qu'en CI. - Le runner libère dotnet, android et ghc avant de bâtir. L'empilement nvidia/cuda-devel + runtime CUDA + Chromium approche les 14 Go disponibles ; cette part-là reste une hypothèse, mais elle coûte une minute à écarter. - whisper-server CUDA est strippé : les symboles de débogage d'un binaire ggml-cuda pèsent plusieurs centaines de mégaoctets dans l'image finale. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3ewMAsXhkw9RY11kb9Dc9
This commit is contained in:
1 parent
f4969de9f7
commit
8e88a73d91
3 files changed
+34
-2
No files matched your search
@@ -16,6 +16,17 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# Depuis que l'image compile whisper.cpp avec CUDA, le build empile
|
||||||
|
# nvidia/cuda:*-devel (~6 Go), l'image runtime CUDA de llama.cpp (~4 Go)
|
||||||
|
# et Chromium/Playwright (~1 Go) — pour ~14 Go libres sur un runner neuf.
|
||||||
|
# Ces trois répertoires ne servent à rien ici et rendent une dizaine de
|
||||||
|
# gigaoctets en moins d'une minute.
|
||||||
|
- name: Libérer de l'espace disque
|
||||||
|
run: |
|
||||||
|
df -h /
|
||||||
|
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc
|
||||||
|
df -h /
|
||||||
|
|
||||||
- name: Setup Buildx
|
- name: Setup Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
|||||||
+10
-2
@@ -64,11 +64,18 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
RUN git clone --depth 1 https://github.com/ggml-org/whisper.cpp /w \
|
RUN git clone --depth 1 https://github.com/ggml-org/whisper.cpp /w \
|
||||||
&& cmake -S /w -B /w/build ${WHISPER_CMAKE_FLAGS} \
|
&& cmake -S /w -B /w/build ${WHISPER_CMAKE_FLAGS} \
|
||||||
&& cmake --build /w/build -j --target whisper-server
|
&& cmake --build /w/build -j"$(nproc)" --target whisper-server
|
||||||
|
|
||||||
# Version CUDA. La MAJEURE de CUDA doit correspondre à celle de l'image
|
# Version CUDA. La MAJEURE de CUDA doit correspondre à celle de l'image
|
||||||
# runtime : le binaire est lié dynamiquement à libcudart, fournie par
|
# runtime : le binaire est lié dynamiquement à libcudart, fournie par
|
||||||
# LLAMACPP_IMAGE et non par cette étape.
|
# LLAMACPP_IMAGE et non par cette étape.
|
||||||
|
#
|
||||||
|
# ⚠️ -j"$(nproc)" et JAMAIS -j nu. Avec Make, « -j » sans nombre autorise un
|
||||||
|
# parallélisme ILLIMITÉ. ggml-cuda compte ~200 fichiers d'instanciation de
|
||||||
|
# gabarits, et chaque nvcc réclame 1 à 2 Go : le runner GitHub (16 Go) était
|
||||||
|
# tué par l'OOM après avoir lancé 92 % des compilations en treize secondes,
|
||||||
|
# sans écrire la moindre ligne d'erreur. L'étape CPU y survivait — peu de
|
||||||
|
# fichiers, compilation légère — ce qui rendait le piège invisible jusqu'ici.
|
||||||
FROM nvidia/cuda:12.4.1-devel-ubuntu22.04 AS whisperbuild-cuda
|
FROM nvidia/cuda:12.4.1-devel-ubuntu22.04 AS whisperbuild-cuda
|
||||||
ARG WHISPER_CMAKE_FLAGS
|
ARG WHISPER_CMAKE_FLAGS
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
@@ -76,7 +83,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
RUN git clone --depth 1 https://github.com/ggml-org/whisper.cpp /w \
|
RUN git clone --depth 1 https://github.com/ggml-org/whisper.cpp /w \
|
||||||
&& cmake -S /w -B /w/build ${WHISPER_CMAKE_FLAGS} -DGGML_CUDA=ON \
|
&& cmake -S /w -B /w/build ${WHISPER_CMAKE_FLAGS} -DGGML_CUDA=ON \
|
||||||
&& cmake --build /w/build -j --target whisper-server
|
&& cmake --build /w/build -j"$(nproc)" --target whisper-server \
|
||||||
|
&& strip /w/build/bin/whisper-server
|
||||||
|
|
||||||
# ── Étape 2 : runtime sur l'image serveur CUDA officielle ───────────────
|
# ── Étape 2 : runtime sur l'image serveur CUDA officielle ───────────────
|
||||||
FROM ${LLAMACPP_IMAGE} AS runtime
|
FROM ${LLAMACPP_IMAGE} AS runtime
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package loki
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@@ -80,6 +81,18 @@ func TestDockerfileWhisperNonNatif(t *testing.T) {
|
|||||||
if !strings.Contains(txt, "whisper-server") {
|
if !strings.Contains(txt, "whisper-server") {
|
||||||
t.Errorf("étape %s : ne construit pas la cible whisper-server", nom)
|
t.Errorf("étape %s : ne construit pas la cible whisper-server", nom)
|
||||||
}
|
}
|
||||||
|
// « -j » nu autorise un parallélisme ILLIMITÉ chez Make. Sur l'étape
|
||||||
|
// CUDA (~200 nvcc à 1-2 Go pièce), le runner GitHub était tué par
|
||||||
|
// l'OOM sans écrire une ligne d'erreur. L'étape CPU y survivait, ce
|
||||||
|
// qui rendait le piège invisible.
|
||||||
|
for _, ligne := range strings.Split(txt, "\n") {
|
||||||
|
if !strings.Contains(ligne, "cmake --build") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if regexp.MustCompile(`-j(\s|$|\\)`).MatchString(ligne) {
|
||||||
|
t.Errorf("étape %s : « cmake --build -j » sans nombre — parallélisme illimité, le runner sera tué par l'OOM. Utiliser -j\"$(nproc)\".", nom)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user