Skip to content
/ airelien.dev
Go back
Aurélien AMSELLEM

Lucebox sur Olares One — Épisode 4 : Le sous-module llama-server vous remet ça 1h plus tard

test_dflash compile, super. Mais pour servir en HTTP il me faut llama-server, qui se compile depuis le sous-module. Et le sous-module a sa propre invocation cmake — où j'ai oublié de remettre le -rpath-link. Et boom, rebelote 1h plus tard.

Épisode 3 — j’ai compris que LIBRARY_PATH ne résout pas les indirect dependencies, switché sur -Wl,-rpath-link, et test_dflash a fini par linker.

Sauf que test_dflash c’est un CLI minimaliste : il prend un prompt en input, sort des tokens en output. Pour avoir un endpoint OpenAI-compatible (que vous puissiez brancher Continue, Roo, votre client habituel), il me faut llama-server, qui vit dans Luce-Org/llama.cpp@luce-dflash (le fork llama.cpp embarqué comme submodule de Lucebox).

Donc une deuxième invocation cmake dans le Dockerfile :

WORKDIR /src/lucebox/dflash/deps/llama.cpp
RUN cmake -B build -S . \
    -DCMAKE_BUILD_TYPE=Release \
    -DGGML_CUDA=ON \
    -DCMAKE_CUDA_ARCHITECTURES="120" \
    -DLLAMA_BUILD_SERVER=ON \
    -DLLAMA_CURL=ON \
    && cmake --build build --target llama-server -j $(nproc)

Vous voyez l’erreur ? Moi non plus, sur le moment. J’ai relancé.

67 minutes plus tard

[100%] Linking CXX executable llama-server
/usr/bin/ld: ../../bin/libggml-cuda.so.0.9.11: undefined reference to `cuMemCreate'
/usr/bin/ld: ../../bin/libggml-cuda.so.0.9.11: undefined reference to `cuMemAddressReserve'
...

Mêmes 11 undefined references qu’à l’épisode 2. Sauf que cette fois j’ai juste oublié de passer -DCMAKE_EXE_LINKER_FLAGS=... et -DCMAKE_SHARED_LINKER_FLAGS=... à la deuxième invocation cmake. Le fix de l’épisode 3 était dans la cmake #1 (test_dflash), pas dans la cmake #2 (llama-server).

Erreur classique de Dockerfile : chaque RUN est un layer indépendant, et chaque cmake -B build -S . est une nouvelle config qui ne hérite de rien. Ce qui est local à un dossier reste local à ce dossier.

Faut copier-coller le fix dans la deuxième invocation :

WORKDIR /src/lucebox/dflash/deps/llama.cpp
RUN cmake -B build -S . \
    -DCMAKE_BUILD_TYPE=Release \
    -DGGML_CUDA=ON \
    -DCMAKE_CUDA_ARCHITECTURES="120" \
    -DLLAMA_BUILD_SERVER=ON \
    -DLLAMA_CURL=ON \
    -DCMAKE_EXE_LINKER_FLAGS="-Wl,-rpath-link,/usr/local/cuda/lib64/stubs" \
    -DCMAKE_SHARED_LINKER_FLAGS="-Wl,-rpath-link,/usr/local/cuda/lib64/stubs" \
    && cmake --build build --target llama-server -j $(nproc)

Et bien sûr, ajouter ces flags casse le cache du layer suivant — donc on retourne pour 2h de compile complet sur le sous-module. Cool cool cool.

Le 6e build

J’aurais dû compter mieux. Build #1 : 2h13 (cassé épisode 2). Build #2 : 2h (cassé épisode 3, même erreur). Build #3 : 56 min (test_dflash linké, mais le link de llama-server casse). Build #4 : 67 min (llama-server linké après fix). À peu près 6 heures cumulées de compile rien que pour les flags de link.

Cette fois ça passe. La structure finale du Dockerfile, c’est :

FROM nvidia/cuda:13.0.0-devel-ubuntu22.04 AS builder

ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
    git build-essential cmake ninja-build pkg-config \
    libcurl4-openssl-dev ca-certificates python3-pip python3-dev \
    && rm -rf /var/lib/apt/lists/*

# Fix #1 : stub libcuda.so.1 au link
ENV LIBRARY_PATH="/usr/local/cuda/lib64/stubs:${LIBRARY_PATH}"
RUN ln -sf /usr/local/cuda/lib64/stubs/libcuda.so \
           /usr/local/cuda/lib64/stubs/libcuda.so.1

WORKDIR /src
RUN git clone --depth 1 --recurse-submodules \
    https://github.com/Luce-Org/lucebox-hub /src/lucebox

# Fix #2 + #3 : rpath-link partout, dans les deux invocations cmake
WORKDIR /src/lucebox/dflash
RUN cmake -B build -S . \
    -DCMAKE_BUILD_TYPE=Release \
    -DGGML_CUDA=ON \
    -DCMAKE_CUDA_ARCHITECTURES="120" \
    -DCMAKE_EXE_LINKER_FLAGS="-Wl,-rpath-link,/usr/local/cuda/lib64/stubs" \
    -DCMAKE_SHARED_LINKER_FLAGS="-Wl,-rpath-link,/usr/local/cuda/lib64/stubs" \
    && cmake --build build --target test_dflash -j $(nproc)

WORKDIR /src/lucebox/dflash/deps/llama.cpp
RUN cmake -B build -S . \
    -DCMAKE_BUILD_TYPE=Release \
    -DGGML_CUDA=ON \
    -DCMAKE_CUDA_ARCHITECTURES="120" \
    -DLLAMA_BUILD_SERVER=ON -DLLAMA_CURL=ON \
    -DCMAKE_EXE_LINKER_FLAGS="-Wl,-rpath-link,/usr/local/cuda/lib64/stubs" \
    -DCMAKE_SHARED_LINKER_FLAGS="-Wl,-rpath-link,/usr/local/cuda/lib64/stubs" \
    && cmake --build build --target llama-server -j $(nproc)

Et le push final :

==> Pushing aamsellem/lucebox-qwen36-blackwell:1.0.0
...
==> Done. Image: docker.io/aamsellem/lucebox-qwen36-blackwell:1.0.0

🎉 Image publique sur Docker Hub. Ça compile. Ça link. Ça push. Tout va bien.

Maintenant je package un chart Helm pour Olares, j’ajoute le download du modèle (unsloth/Qwen3.6-27B-Q4_K_M.gguf + drafter z-lab/Qwen3.6-27B-DFlash), je deploy. Le pod boot, télécharge les ~20 Go de modèles, démarre llama-server. ggml détecte la GPU :

ggml_cuda_init: found 1 CUDA devices (Total VRAM: 24463 MiB):
  Device 0: NVIDIA GeForce RTX 5090 Laptop GPU, compute capability 12.0,
            VMM: yes, VRAM: 24463 MiB

Et puis…

[HAMI-core ERROR (...)]: Illegal device id: -644371744

Le pod meurt. CrashLoopBackOff. On recommence, le -644371744 devient -39296272, puis 1816936528. Random.

Je n’ai aucune idée de ce qui se passe.

Épisode 5 — le runtime nous claque la porte, à très vite !


Disclosure — Tous les benchmarks de ce post tournent sur mon propre Olares One. Si le contenu vous a été utile et que vous envisagez d’en acheter un, commander via ce lien de parrainage vous donne 400 $ de réduction (3 599 $ au lieu de 3 999 $) et me rapporte 200 $. Je le mentionne par transparence — et oui, accessoirement, ça aide à faire vivre le blog (hébergement, domaine, et le temps que je passe à écrire ici). Lien valable jusqu’à fin juin 2026 environ.

Share this post on:

Commentaires