Add opencl support for llamacpp
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env bash
|
||||
###############################################################################
|
||||
# build-mesa.sh
|
||||
#
|
||||
# Builda Mesa dal repository ufficiale upstream (gitlab.freedesktop.org),
|
||||
# che su main contiene gia' il fix subgroup per Freedreno (commit
|
||||
# 185c89084ab7 "freedreno/a6xx: Expose subgroup ops", non ancora presente in
|
||||
# alcuna release stabile 26.1.x). Produce pacchetti .deb pronti da
|
||||
# installare, salvati in ./deb/
|
||||
#
|
||||
# Nessun fork necessario: il fix e' gia' su main upstream.
|
||||
#
|
||||
# Uso:
|
||||
# ./build-mesa.sh # clona main upstream in /tmp e builda
|
||||
# ./build-mesa.sh /path/gia/clonato # usa un checkout gia' esistente
|
||||
# ./build-mesa.sh <url-alternativo> # clona un repo/fork diverso, se serve
|
||||
###############################################################################
|
||||
set -euo pipefail
|
||||
|
||||
echo "=== Installazione dipendenze di build (primo step) ==="
|
||||
sudo apt-get update
|
||||
sudo apt-get build-dep -y mesa || {
|
||||
echo "build-dep su pacchetto 'mesa' fallito o non disponibile, installo un set minimo esplicito."
|
||||
sudo apt-get install -y \
|
||||
git meson ninja-build pkg-config python3-mako python3-pip \
|
||||
libdrm-dev libx11-dev libxext-dev libxfixes-dev libxcb1-dev \
|
||||
libxcb-glx0-dev libxxf86vm-dev libxrandr-dev libwayland-dev \
|
||||
wayland-protocols llvm-dev clang libclc-dev spirv-tools \
|
||||
libspirv-tools-dev rustc cargo libelf-dev libzstd-dev \
|
||||
libexpat1-dev bindgen cbindgen dpkg-dev debhelper devscripts
|
||||
}
|
||||
echo
|
||||
|
||||
UPSTREAM_URL="https://gitlab.freedesktop.org/mesa/mesa.git"
|
||||
ARG="${1:-}"
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
DEB_OUT_DIR="${SCRIPT_DIR}/deb"
|
||||
|
||||
# Determina se l'argomento e' un path esistente o un URL alternativo da clonare
|
||||
if [ -n "${ARG}" ] && [ -d "${ARG}/.git" ]; then
|
||||
MESA_SRC="${ARG}"
|
||||
echo "=== Uso checkout gia' esistente: ${MESA_SRC} ==="
|
||||
elif [ -n "${ARG}" ]; then
|
||||
# argomento passato ma non e' una dir .git valida: trattalo come URL alternativo
|
||||
CLONE_URL="${ARG}"
|
||||
else
|
||||
CLONE_URL="${UPSTREAM_URL}"
|
||||
fi
|
||||
|
||||
if [ -z "${MESA_SRC:-}" ]; then
|
||||
CLONE_DIR="/tmp/mesa-$(date +%Y%m%d-%H%M%S)"
|
||||
echo "=== Clono ${CLONE_URL} in ${CLONE_DIR} ==="
|
||||
git clone "${CLONE_URL}" "${CLONE_DIR}"
|
||||
MESA_SRC="${CLONE_DIR}"
|
||||
fi
|
||||
|
||||
BUILD_DIR="${MESA_SRC}/build-deb"
|
||||
LOG_FILE="/tmp/build-mesa-$(date +%Y%m%d-%H%M%S).log"
|
||||
|
||||
echo "=== build-mesa.sh ==="
|
||||
echo "Sorgente Mesa: ${MESA_SRC}"
|
||||
echo "Output .deb: ${DEB_OUT_DIR}"
|
||||
echo "Build dir: ${BUILD_DIR}"
|
||||
echo "Log: ${LOG_FILE}"
|
||||
echo
|
||||
|
||||
echo "=== Verifica commit fix subgroup presente ==="
|
||||
mkdir -p "${DEB_OUT_DIR}"
|
||||
cd "${MESA_SRC}"
|
||||
if git log --oneline | grep -q "185c89084ab7\|Expose subgroup ops"; then
|
||||
echo "OK: commit fix subgroup trovato nella history."
|
||||
else
|
||||
echo "ATTENZIONE: non trovo il commit atteso nella history di questo checkout." >&2
|
||||
echo "Verifica di essere sul branch/commit giusto prima di continuare." >&2
|
||||
read -p "Continuare comunque? [y/N] " -n 1 -r
|
||||
echo
|
||||
[[ $REPLY =~ ^[Yy]$ ]] || exit 1
|
||||
fi
|
||||
echo
|
||||
|
||||
echo "=== Build Mesa (meson/ninja) ==="
|
||||
rm -rf "${BUILD_DIR}"
|
||||
meson setup "${BUILD_DIR}" "${MESA_SRC}" \
|
||||
-Dprefix=/usr \
|
||||
-Dgallium-drivers=freedreno \
|
||||
-Dvulkan-drivers= \
|
||||
-Dgallium-rusticl=true \
|
||||
-Dgallium-rusticl-enable-drivers=freedreno \
|
||||
-Dopencl-spirv=true \
|
||||
-Dbuildtype=release \
|
||||
2>&1 | tee -a "${LOG_FILE}"
|
||||
|
||||
ninja -C "${BUILD_DIR}" 2>&1 | tee -a "${LOG_FILE}"
|
||||
echo
|
||||
|
||||
echo "=== Packaging .deb ==="
|
||||
# Se il repo ha tooling Debian (cartella debian/), usalo.
|
||||
if [ -d "${MESA_SRC}/debian" ]; then
|
||||
echo "Trovata cartella debian/, uso dpkg-buildpackage."
|
||||
cd "${MESA_SRC}"
|
||||
dpkg-buildpackage -us -uc -b 2>&1 | tee -a "${LOG_FILE}"
|
||||
# dpkg-buildpackage mette i risultati nella dir padre di MESA_SRC
|
||||
find "$(dirname "${MESA_SRC}")" -maxdepth 1 -name "*.deb" -newer "${LOG_FILE}" \
|
||||
-exec cp -v {} "${DEB_OUT_DIR}/" \;
|
||||
else
|
||||
echo "Nessuna cartella debian/ trovata: creo un pacchetto .deb minimale"
|
||||
echo "con i soli file installati dalla build (DESTDIR + fpm/dpkg-deb)."
|
||||
|
||||
DESTDIR="${BUILD_DIR}/install-root"
|
||||
rm -rf "${DESTDIR}"
|
||||
DESTDIR="${DESTDIR}" ninja -C "${BUILD_DIR}" install 2>&1 | tee -a "${LOG_FILE}"
|
||||
|
||||
PKG_ROOT="${BUILD_DIR}/deb-pkg"
|
||||
PKG_NAME="mesa-freedreno-subgroups"
|
||||
PKG_VERSION="26.2.0-devel+subgroups1"
|
||||
PKG_ARCH="arm64"
|
||||
PKG_DIR="${PKG_ROOT}/${PKG_NAME}_${PKG_VERSION}_${PKG_ARCH}"
|
||||
|
||||
rm -rf "${PKG_ROOT}"
|
||||
mkdir -p "${PKG_DIR}/DEBIAN"
|
||||
cp -a "${DESTDIR}/usr" "${PKG_DIR}/"
|
||||
|
||||
cat > "${PKG_DIR}/DEBIAN/control" << EOF
|
||||
Package: ${PKG_NAME}
|
||||
Version: ${PKG_VERSION}
|
||||
Section: libs
|
||||
Priority: optional
|
||||
Architecture: ${PKG_ARCH}
|
||||
Maintainer: local-build
|
||||
Description: Mesa build from local fork with Freedreno subgroup support
|
||||
Build locale da fork Mesa (commit 185c89084ab7 "freedreno/a6xx: Expose
|
||||
subgroup ops", non ancora presente in alcuna release stabile 26.1.x,
|
||||
disponibile solo su trunk verso 26.2).
|
||||
.
|
||||
Sostituisce i file installati da mesa-libgallium / mesa-opencl-icd
|
||||
di Debian con la build patchata. Da usare solo per test.
|
||||
EOF
|
||||
|
||||
cat > "${PKG_DIR}/DEBIAN/README-patch.md" << 'EOF'
|
||||
# Nota sulla patch inclusa
|
||||
|
||||
Commit: 185c89084ab7 "freedreno/a6xx: Expose subgroup ops"
|
||||
Autore: upstream Mesa (author date 2026-02-11, committer/merge date 2026-05-18)
|
||||
Motivo assenza in Debian: il branch stabile 26.1 e' stato diramato da main il
|
||||
2026-04-14 (tag mesa-26.1.0 il 2026-05-06), quindi questo fix e' arrivato su
|
||||
main DOPO la diramazione. Essendo una feature (non un bugfix), non verra'
|
||||
backportato al branch 26.1.x per policy standard di Mesa. Il fix esiste solo
|
||||
su trunk, verso la futura 26.2.
|
||||
|
||||
Verificato (vedi indagine precedente):
|
||||
- Nessuna dipendenza da ioctl/kernel driver msm: i campi
|
||||
shader_subgroup_supported_features / max_subgroups / subgroup_sizes sono
|
||||
popolati da tabelle statiche compilate (freedreno_devices.py).
|
||||
- Nessuna condizione che esclude a690 (FD690 e' CHIP.A6XX).
|
||||
- Nessun commit successivo modifica subgroup/ballot/shuffle in freedreno tra
|
||||
questo fix e HEAD: e' completo e autosufficiente, non un WIP parziale.
|
||||
|
||||
Questo pacchetto installa i file prodotti da una build meson/ninja pulita
|
||||
di questo checkout, con gallium-drivers=freedreno e rusticl abilitato per
|
||||
freedreno. Non tocca Vulkan/Turnip.
|
||||
EOF
|
||||
|
||||
dpkg-deb --build --root-owner-group "${PKG_DIR}" "${DEB_OUT_DIR}/${PKG_NAME}_${PKG_VERSION}_${PKG_ARCH}.deb"
|
||||
fi
|
||||
echo
|
||||
|
||||
echo "=== Contenuto pacchetto/i .deb prodotti ==="
|
||||
for deb in "${DEB_OUT_DIR}"/*.deb; do
|
||||
[ -e "${deb}" ] || continue
|
||||
echo "--- ${deb} ---"
|
||||
dpkg -c "${deb}"
|
||||
echo
|
||||
done
|
||||
|
||||
echo "=== Fatto ==="
|
||||
echo "Pacchetti .deb disponibili in: ${DEB_OUT_DIR}"
|
||||
echo "Log completo: ${LOG_FILE}"
|
||||
@@ -0,0 +1,96 @@
|
||||
### LLaMACpp Builder Container with OpenCL for Qualcomm Adreno GPUs
|
||||
### Build from source with GGML_OPENCL=ON since no official Linux OpenCL release exists
|
||||
###
|
||||
### BUILD: podman build -t llamacpp:opencl-arm64 -f llamacpp-opencl.Containerfile .
|
||||
### Export: podman save -o /home/badstorm/llamacpp-opencl-arm64.tar localhost/llamacpp:opencl-arm64
|
||||
FROM debian:13-slim
|
||||
USER root
|
||||
EXPOSE 8090
|
||||
|
||||
# Copia il/i pacchetto/i .deb con la Mesa patchata (fix subgroup Freedreno,
|
||||
# commit 185c89084ab7, non presente in alcuna release Debian/backports).
|
||||
# Generati da build-mesa.sh nella sottocartella ./deb accanto a questo file.
|
||||
COPY deb/*.deb /tmp/mesa-deb/
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y curl tar grep sed git ffmpeg nano python3-pip python3 python3-wheel \
|
||||
ocl-icd-libopencl1 \
|
||||
# Installa la Mesa patchata locale (fornisce mesa-opencl-icd / mesa-libgallium
|
||||
# equivalenti, con il fix subgroup). Se il .deb ha dipendenze non risolte,
|
||||
# il secondo apt-get -f install le completa dai repo standard.
|
||||
&& (dpkg -i /tmp/mesa-deb/*.deb || true) \
|
||||
&& apt-get install -y -f \
|
||||
&& rm -rf /tmp/mesa-deb \
|
||||
&& pip install --break-system-packages --upgrade setuptools \
|
||||
&& pip install --break-system-packages -U "huggingface_hub[cli]" \
|
||||
&& if [ -f requirements.txt ]; then pip install --break-system-packages -r requirements.txt; fi \
|
||||
&& apt autoremove -y \
|
||||
&& apt clean -y \
|
||||
&& rm -rf /tmp/* /var/tmp/* \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& find /var/cache/apt/archives /var/lib/apt/lists -not -name lock -type f -delete \
|
||||
&& find /var/cache -type f -delete
|
||||
|
||||
WORKDIR /build
|
||||
RUN git clone --depth 1 https://github.com/ggml-org/llama.cpp
|
||||
|
||||
# --- PATCH: riconosci device Rusticl/Freedreno (es. "FD690") come Adreno ---
|
||||
# Il backend OpenCL controlla dev_ctx->device_name cercando le stringhe
|
||||
# "Adreno" o "Qualcomm" (vedi ggml_opencl_is_device_supported in
|
||||
# ggml/src/ggml-opencl/ggml-opencl.cpp). Il driver Mesa/Rusticl riporta pero'
|
||||
# il device come "FD690" (Freedreno + numero modello), non "Adreno 690", quindi
|
||||
# il controllo fallisce e il device viene scartato con "unsupported GPU".
|
||||
# Questa patch resta necessaria SEMPRE, indipendentemente dalla versione Mesa,
|
||||
# perche' riguarda solo il nome con cui Rusticl si presenta, non le capability
|
||||
# del device. Aggiungiamo il pattern "FD6" (copre la serie Adreno 6xx via
|
||||
# Freedreno) alla condizione che marca il device come GPU_FAMILY::ADRENO.
|
||||
#
|
||||
# NOTA: la patch precedente che bypassava il controllo "does not support
|
||||
# subgroups" NON e' piu' necessaria ne' presente qui: con la Mesa patchata
|
||||
# (vedi deb/ - fix upstream "freedreno/a6xx: Expose subgroup ops") il device
|
||||
# dichiara realmente cl_khr_subgroups, quindi il controllo originale del
|
||||
# codice passa senza bisogno di bypass. Se in futuro si torna a una Mesa
|
||||
# senza quel fix, il controllo tornera' a scartare il device correttamente
|
||||
# (comportamento voluto: meglio un fallback esplicito che un bypass silente).
|
||||
RUN cd llama.cpp \
|
||||
&& grep -n 'strstr(dev_ctx->device_name.c_str(), "Adreno")' ggml/src/ggml-opencl/ggml-opencl.cpp \
|
||||
&& sed -i \
|
||||
's/strstr(dev_ctx->device_name.c_str(), "Adreno") ||/strstr(dev_ctx->device_name.c_str(), "Adreno") ||\n strstr(dev_ctx->device_name.c_str(), "FD6") ||/' \
|
||||
ggml/src/ggml-opencl/ggml-opencl.cpp \
|
||||
&& grep -n -A5 'strstr(dev_ctx->device_name.c_str(), "Adreno")' ggml/src/ggml-opencl/ggml-opencl.cpp
|
||||
|
||||
RUN cd llama.cpp \
|
||||
&& mkdir build && cd build \
|
||||
&& cmake .. -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DGGML_OPENCL=ON \
|
||||
-DGGML_OPENCL_EMBED_KERNELS=ON \
|
||||
-DGGML_OPENCL_USE_ADRENO_KERNELS=ON \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
&& cmake --build . --config Release -j$(nproc)
|
||||
|
||||
# Copy the built binaries and libraries into /app, matching the layout the runtime expects
|
||||
RUN mkdir -p /app \
|
||||
&& find /build/llama.cpp/build/bin -maxdepth 1 -type f -exec cp {} /app/ \; \
|
||||
&& find /build/llama.cpp/build -maxdepth 3 -iname "*.so*" -exec cp -P {} /app/ \; \
|
||||
&& chmod +x /app/llama-server \
|
||||
&& rm -rf /build
|
||||
|
||||
WORKDIR /app
|
||||
ENV PATH=/app:$PATH
|
||||
ENV LD_LIBRARY_PATH=/app:$LD_LIBRARY_PATH
|
||||
ENV HF_HUB_ENABLE_HF_TRANSFER=1
|
||||
ENV LLAMA_ARG_HOST=0.0.0.0
|
||||
ENV LLAMA_ARG_PORT=8090
|
||||
ENV LLAMA_ARG_HF_REPO=unsloth/Qwen3.5-35B-A3B-GGUF:Q2_K_XL
|
||||
ENV LLAMA_ARG_NO_MMAP=true
|
||||
ENV LLAMA_ARG_CTX_SIZE=128000
|
||||
# Adreno-specific: make sure Rusticl/OpenCL device is picked correctly
|
||||
ENV GGML_OPENCL_PLATFORM=0
|
||||
ENV GGML_OPENCL_DEVICE=0
|
||||
# NECESSARIA: senza questa, Rusticl carica la piattaforma OpenCL ma con 0
|
||||
# device (il driver Freedreno non viene attivato). Con questa variabile
|
||||
# clinfo/ggml_opencl vedono correttamente il device Adreno (es. FD690).
|
||||
ENV RUSTICL_ENABLE=freedreno
|
||||
ENTRYPOINT ["/app/llama-server"]
|
||||
CMD ["--no-warmup"]
|
||||
Viittaa uudesa ongelmassa
Block a user