Mark Stratmann
Running LLMs Background

Exécuter des LLM locaux sur le Framework Desktop (Max+ 395 - 128GB)

Exécutez des LLM locaux à l’aide de llama.cpp et d’Ollama avec des conteneurs Docker

Cet article décrit comment j’ai configuré mon PC de bureau Framework (Max+ 395 avec 128GB de mémoire unifiée) pour exécuter des LLM localement avec à la fois llama.cpp et Ollama via des conteneurs Docker.

Aperçu du matériel

Le Framework Desktop Max+ 395 est équipé du processeur AMD Ryzen AI Max 395 avec graphiques Radeon intégrés (Strix Halo), offrant :

  • 128GB de mémoire unifiée (partagée CPU/GPU)
  • Architecture AMD RDNA 3.5
  • Cible GPU gfx1151

https://frame.work/gb/en/desktop

Configuration de la mémoire GPU

Pour activer la totalité des 128GB de mémoire unifiée pour les charges de travail GPU, la configuration suivante est requise. Ces instructions synthétisent le guide Ubuntu de technigmaai-wiki avec la configuration de benchmark LLM de lhl/strix-halo-testing pour Fedora 43.

Configuration du BIOS

  1. Redémarrez et entrez dans le BIOS/UEFI
  2. Réglez Integrated Graphics/UMA Frame Buffer Size à 512MB
  3. Désactivez IOMMU

Configuration GRUB sur Fedora 43

Modifiez /etc/default/grub et ajustez la ligne GRUB_CMDLINE_LINUX_DEFAULT :

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash amd_iommu=off amdgpu.gttsize=131072 ttm.pages_limit=33554432"

Ensuite, mettez à jour GRUB et redémarrez :

sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot

Vérifier les paramètres mémoire

Après le redémarrage, vérifiez que les paramètres ont été appliqués :

cat /proc/cmdline
sudo dmesg | grep -i gtt
sudo dmesg | grep -i ttm

Cette configuration active environ 128GB de mémoire GTT pour les charges de travail GPU, ce qui est essentiel pour exécuter de grands modèles comme Qwen3-Coder-Next avec sa fenêtre de contexte de 256K.

Configuration alternative via module du noyau

Pour un contrôle plus granulaire, créez /etc/modprobe.d/amdgpu_llm_optimized.conf :

options amdgpu gttsize=120000
options ttm pages_limit=31457280
options ttm page_pool_size=15728640

Puis régénérez l’initramfs :

sudo dracut --force

Pourquoi Fedora 43 pour les LLM?

Alors que de nombreux guides ciblent Ubuntu, Fedora 43 offre plusieurs avantages pour les charges de travail LLM locales :

Noyau plus récent : Fedora 43 est livrée avec le noyau 6.18.4+, ce qui offre une meilleure prise en charge de ROCm 7.x et du GPU du Ryzen AI Max 395

Meilleure prise en charge de ROCm : Les améliorations du pilote AMDGPU dans les noyaux plus récents se traduisent par une meilleure gestion de la mémoire unifiée et une meilleure allocation de VRAM pour les charges de travail LLM

Fraîcheur des paquets : Le modèle de publication continue (rolling release) de Fedora fournit des versions plus récentes des dépendances clés, comme :

  • LLVM/Clang pour la compilation HIP
  • Pilotes Vulkan (Mesa RADV/AMDVLK)
  • CMake et les chaînes d’outils de compilation
  1. Considérations SELinux : Même si SELinux exige une configuration additionnelle (comme container_use_devices=1), il offre un meilleur isolement de sécurité pour les charges de travail LLM conteneurisées

Les principales sources qui ont guidé cette approche sont :

Conteneurs LLM basés sur Docker

J’ai créé des conteneurs Docker basés sur kyuz0/amd-strix-halo-toolboxes pour exécuter à la fois llama.cpp et Ollama.

Prérequis des conteneurs

Avant d’exécuter des conteneurs, activez SELinux pour autoriser l’accès des conteneurs aux périphériques GPU :

sudo setsebool container_use_devices=1

Il s’agit d’une configuration unique qui doit persister après les redémarrages :

sudo setsebool -P container_use_devices=1

Ollama avec Vulkan (fonctionne)

Le backend Vulkan fonctionne parfaitement avec Ollama sur Fedora 43.

Dockerfile : ollama-vulkan/Dockerfile Docker Compose : ollama-vulkan/docker-compose.yml

# Ollama + Vulkan on Strix Halo (Fedora 43)
FROM registry.fedoraproject.org/fedora-minimal:43

# Base runtime deps + Vulkan userspace
RUN microdnf -y --nodocs --setopt=install_weak_deps=0 install \
      bash ca-certificates curl tar \
      libatomic libstdc++ libgcc \
      vulkan-loader vulkan-loader-devel vulkaninfo \
      mesa-vulkan-drivers radeontop \
      pciutils procps-ng wget gzip zstd \
  && microdnf clean all && rm -rf /var/cache/dnf/*

# Install AMDVLK (optional, can use Mesa RADV)
RUN curl -L -o /tmp/amdvlk-2025.Q2.1.x86_64.rpm \
    https://github.com/GPUOpen-Drivers/AMDVLK/releases/download/v-2025.Q2.1/amdvlk-2025.Q2.1.x86_64.rpm \
 && microdnf -y install /tmp/amdvlk-*.rpm \
 && rm -f /tmp/amdvlk-*.rpm

# Install Ollama (generic Linux build with Vulkan support)
RUN wget -P /tmp https://github.com/ollama/ollama/releases/download/v0.15.5-rc2/ollama-linux-amd64.tar.zst \
 && tar --zstd -C /usr -xf /tmp/ollama-linux-amd64.tar.zst \
 && rm -f /tmp/ollama-linux-amd64.tar.zst

RUN mkdir -p /root/.ollama

ENV OLLAMA_VULKAN=1 \
    GGML_VK_VISIBLE_DEVICES=0 \
    OLLAMA_HOST=0.0.0.0 \
    OLLAMA_ORIGINS="*"

EXPOSE 11434

CMD ["/usr/bin/ollama", "serve"]

Démarrer Ollama avec Vulkan :

# Build the image
docker build -t ollama-strix-vulkan -f ollama-vulkan/Dockerfile .

# Or using Docker Compose
cd ollama-vulkan
docker compose up -d

Accéder à Ollama :

ollama list
ollama pull qwen3-coder-next

Ollama avec ROCm (ne fonctionne pas - correction en attente)

L’implémentation ROCm d’Ollama ne fonctionne actuellement pas sur Fedora 43 avec ROCm 7.x. Le problème est suivi dans ROCm issue #5902.

Dockerfile : ollama-rocm/Dockerfile Docker Compose : ollama-rocm/docker-compose.yml

# Ollama + Vulkan on Strix Halo (Fedora 43)
FROM registry.fedoraproject.org/fedora:43

RUN dnf -y --nodocs --setopt=install_weak_deps=False install \
  make gcc cmake lld clang clang-devel compiler-rt libcurl-devel \
  radeontop git vim patch curl ninja-build tar xz aria2c wget zstd \
  && dnf clean all && rm -rf /var/cache/dnf/*


# find & fetch the latest Linux 7.x.x tarball (gfx1151)
WORKDIR /tmp
ARG ROCM_MAJOR_VER=7
ARG GFX=gfx1151
RUN set -euo pipefail; \
  BASE="https://therock-nightly-tarball.s3.amazonaws.com"; \
  PREFIX="therock-dist-linux-${GFX}-${ROCM_MAJOR_VER}"; \
  KEY="$(curl -s "${BASE}?list-type=2&prefix=${PREFIX}" \
  | tr '<' '\n' \
  | grep -o "therock-dist-linux-${GFX}-${ROCM_MAJOR_VER}\..*\.tar\.gz" \
  | sort -V | tail -n1)"; \
  echo "Latest tarball: ${KEY}"; \
  aria2c -x 16 -s 16 -j 16 --file-allocation=none "${BASE}/${KEY}" -o therock.tar.gz
RUN mkdir -p /opt/rocm-7.0 \
  && tar xzf therock.tar.gz -C /opt/rocm-7.0 --strip-components=1

ENV ROCM_PATH=/opt/rocm-7.0 \
  HIP_PLATFORM=amd \
  HIP_PATH=/opt/rocm-7.0 \
  HIP_CLANG_PATH=/opt/rocm-7.0/llvm/bin \
  HIP_INCLUDE_PATH=/opt/rocm-7.0/include \
  HIP_LIB_PATH=/opt/rocm-7.0/lib \
  HIP_DEVICE_LIB_PATH=/opt/rocm-7.0/lib/llvm/amdgcn/bitcode \
  PATH=/opt/rocm-7.0/bin:/opt/rocm-7.0/llvm/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
  LD_LIBRARY_PATH=/opt/rocm-7.0/lib:/opt/rocm-7.0/lib64:/opt/rocm-7.0/llvm/lib \
  LIBRARY_PATH=/opt/rocm-7.0/lib:/opt/rocm-7.0/lib64 \
  CPATH=/opt/rocm-7.0/include \
  PKG_CONFIG_PATH=/opt/rocm-7.0/lib/pkgconfig

RUN printf '%s\n' \
  'export ROCM_PATH=/opt/rocm-7.0' \
  'export HIP_PLATFORM=amd' \
  'export HIP_PATH=/opt/rocm-7.0' \
  'export HIP_CLANG_PATH=/opt/rocm-7.0/llvm/bin' \
  'export HIP_INCLUDE_PATH=/opt/rocm-7.0/include' \
  'export HIP_LIB_PATH=/opt/rocm-7.0/lib' \
  'export HIP_DEVICE_LIB_PATH=/opt/rocm-7.0/lib/llvm/amdgcn/bitcode' \
  'export PATH="$ROCM_PATH/bin:$HIP_CLANG_PATH:$PATH"' \
  'export LD_LIBRARY_PATH="$HIP_LIB_PATH:$ROCM_PATH/lib:$ROCM_PATH/lib64:$ROCM_PATH/llvm/lib"' \
  'export LIBRARY_PATH="$HIP_LIB_PATH:$ROCM_PATH/lib:$ROCM_PATH/lib64"' \
  'export CPATH="$HIP_INCLUDE_PATH"' \
  'export PKG_CONFIG_PATH="$ROCM_PATH/lib/pkgconfig"' \
  > /etc/profile.d/rocm.sh \
  && chmod +x /etc/profile.d/rocm.sh \
  && echo 'source /etc/profile.d/rocm.sh' >> /etc/bashrc

# Install the Ollama ROCm drivers (v0.15.2)
RUN wget -P /tmp https://github.com/ollama/ollama/releases/download/v0.15.5-rc3/ollama-linux-amd64-rocm.tar.zst \
 && tar -C /usr --use-compress-program=unzstd -xf /tmp/ollama-linux-amd64-rocm.tar.zst \
 && rm -f /tmp/ollama-linux-amd64-rocm.tar.zst

# Install ollama (v0.15.2)
RUN wget -P /tmp https://github.com/ollama/ollama/releases/download/v0.15.5-rc3/ollama-linux-amd64.tar.zst \
 && tar -C /usr --use-compress-program=unzstd -xf /tmp/ollama-linux-amd64.tar.zst \
 && rm -f /tmp/ollama-linux-amd64.tar.zst

# Make Ollama + ROCm shared libs visible to the runtime linker
RUN printf '%s\n' \
  /usr/lib/ollama \
  /opt/rocm-7.0/lib \
  > /etc/ld.so.conf.d/ollama-rocm.conf \
  && ldconfig

# Create /opt/rocm symlink that Ollama expects
RUN ln -sfn /opt/rocm-7.0 /opt/rocm

# Data directory
RUN mkdir -p /root/.ollama

# Expose Ollama API port
EXPOSE 11434

# profile
RUN printf '%s\n' \
  'export ROCBLAS_USE_HIPBLASLT=1' \
  > /etc/profile.d/rocm.sh && chmod +x /etc/profile.d/rocm.sh \
  && echo 'source /etc/profile.d/rocm.sh' >> /etc/bashrc

ENV OLLAMA_HOST=0.0.0.0 \
    OLLAMA_ORIGINS="*"

# Start the server
CMD ["/usr/bin/ollama", "serve"]

Le backend ROCm échoue avec des erreurs « out of memory » même lorsque le système signale ~111GB de VRAM disponible. Cela semble être une régression dans ROCm 7.2 qui affecte le calcul de mémoire d’Ollama.

Statut actuel : En attente d’une correction en amont de l’équipe AMD/ROCm.

llama.cpp avec Vulkan

Dockerfile : llamacpp/Dockerfile.llamacpp-strix-vulkan

# build stage
FROM registry.fedoraproject.org/fedora:43 AS builder

# deps
RUN dnf -y --nodocs --setopt=install_weak_deps=False install \
      git vim \
      make gcc cmake ninja-build lld clang clang-devel compiler-rt libcurl-devel \
      vulkan-loader-devel vulkaninfo mesa-vulkan-drivers \
      radeontop glslc \
    && dnf clean all && rm -rf /var/cache/dnf/*

# llama.cpp
WORKDIR /opt/llama.cpp
RUN git clone --recursive https://github.com/ggerganov/llama.cpp.git .

# build
RUN git clean -xdf \
 && git submodule update --recursive \
 && cmake -S . -B build -G Ninja \
      -DGGML_VULKAN=ON \
      -DCMAKE_BUILD_TYPE=Release \
      -DGGML_RPC=ON \
      -DCMAKE_INSTALL_PREFIX=/usr \
      -DLLAMA_BUILD_TESTS=OFF \
      -DLLAMA_BUILD_EXAMPLES=ON \
      -DLLAMA_BUILD_SERVER=ON \
 && cmake --build build --config Release \
 && cmake --install build --config Release

# libs
RUN find /opt/llama.cpp/build -type f -name 'lib*.so*' -exec cp {} /usr/lib64/ \; \
 && ldconfig


# runtime stage
FROM registry.fedoraproject.org/fedora-minimal:43

# runtime deps
RUN microdnf -y --nodocs --setopt=install_weak_deps=0 install \
      bash ca-certificates libatomic libstdc++ libgcc \
      vulkan-loader vulkan-loader-devel vulkaninfo mesa-vulkan-drivers radeontop \
  && microdnf clean all && rm -rf /var/cache/dnf/*

# copy
COPY --from=builder /usr/ /usr/
COPY --from=builder /usr/local/ /usr/local/
COPY --from=builder /opt/llama.cpp/build/bin/rpc-* /usr/local/bin/

# ld
RUN echo "/usr/local/lib"  > /etc/ld.so.conf.d/local.conf \
 && echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local.conf \
 && ldconfig \
 && cp -n /usr/local/lib/libllama*.so* /usr/lib64/ 2>/dev/null || true \
 && ldconfig

# shell
CMD ["/bin/bash"]

Le backend Vulkan pour llama.cpp est stable et bien éprouvé. Il offre des performances fiables pour toutes les tailles de modèles.

Entrée Docker Compose :

qwen-3-coder-vulkan:
  image: llamacpp-strix-vulkan
  container_name: llamacpp
  restart: unless-stopped
  devices:
    - /dev/dri:/dev/dri
  group_add:
    - "video"
  volumes:
    - /home/mark/running-llms/:/root/running-llms
  ports:
    - "8080:8080"
  security_opt:
    - seccomp=unconfined
  command: >
    bash -c "llama-server --alias Qwen3-Coder-30B -m /root/running-llms/hf-models/unsloth/Qwen3-Coder-30B-A3B-Instruct-1M-BF16/BF16/Qwen3-Coder-30B-A3B-Instruct-1M-BF16-00001-of-00002.gguf --ctx-size 262144 -fa 1 --no-mmap --host 0.0.0.0 --port 8080 --temp 0.7 --top-k 20 --min-p 0.01 --top-p 0.8 --repeat-penalty 1.05 --jinja -ngl 99 --threads -1"

llama.cpp avec ROCm (plus rapide - ~30% de gain de performance)

Dockerfile : llamacpp/Dockerfile.llamacpp-rocm

# build
FROM registry.fedoraproject.org/fedora:43 AS builder

RUN dnf -y --nodocs --setopt=install_weak_deps=False install \
  make gcc cmake lld clang clang-devel compiler-rt libcurl-devel \
  radeontop git vim patch curl ninja-build tar xz aria2c \
  && dnf clean all && rm -rf /var/cache/dnf/*

# find & fetch the latest Linux 7.x.x tarball (gfx1151)
WORKDIR /tmp
ARG ROCM_MAJOR_VER=7
ARG GFX=gfx1151
RUN set -euo pipefail; \
  BASE="https://therock-nightly-tarball.s3.amazonaws.com"; \
  PREFIX="therock-dist-linux-${GFX}-${ROCM_MAJOR_VER}"; \
  KEY="$(curl -s "${BASE}?list-type=2&prefix=${PREFIX}" \
  | tr '<' '\n' \
  | grep -o "therock-dist-linux-${GFX}-${ROCM_MAJOR_VER}\..*\.tar\.gz" \
  | sort -V | tail -n1)"; \
  echo "Latest tarball: ${KEY}"; \
  aria2c -x 16 -s 16 -j 16 --file-allocation=none "${BASE}/${KEY}" -o therock.tar.gz
RUN mkdir -p /opt/rocm-7.0 \
  && tar xzf therock.tar.gz -C /opt/rocm-7.0 --strip-components=1

ENV ROCM_PATH=/opt/rocm-7.0 \
  HIP_PLATFORM=amd \
  HIP_PATH=/opt/rocm-7.0 \
  HIP_CLANG_PATH=/opt/rocm-7.0/llvm/bin \
  HIP_INCLUDE_PATH=/opt/rocm-7.0/include \
  HIP_LIB_PATH=/opt/rocm-7.0/lib \
  HIP_DEVICE_LIB_PATH=/opt/rocm-7.0/lib/llvm/amdgcn/bitcode \
  PATH=/opt/rocm-7.0/bin:/opt/rocm-7.0/llvm/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
  LD_LIBRARY_PATH=/opt/rocm-7.0/lib:/opt/rocm-7.0/lib64:/opt/rocm-7.0/llvm/lib \
  LIBRARY_PATH=/opt/rocm-7.0/lib:/opt/rocm-7.0/lib64 \
  CPATH=/opt/rocm-7.0/include \
  PKG_CONFIG_PATH=/opt/rocm-7.0/lib/pkgconfig

RUN printf '%s\n' \
  'export ROCM_PATH=/opt/rocm-7.0' \
  'export HIP_PLATFORM=amd' \
  'export HIP_PATH=/opt/rocm-7.0' \
  'export HIP_CLANG_PATH=/opt/rocm-7.0/llvm/bin' \
  'export HIP_INCLUDE_PATH=/opt/rocm-7.0/include' \
  'export HIP_LIB_PATH=/opt/rocm-7.0/lib' \
  'export HIP_DEVICE_LIB_PATH=/opt/rocm-7.0/lib/llvm/amdgcn/bitcode' \
  'export PATH="$ROCM_PATH/bin:$HIP_CLANG_PATH:$PATH"' \
  'export LD_LIBRARY_PATH="$HIP_LIB_PATH:$ROCM_PATH/lib:$ROCM_PATH/lib64:$ROCM_PATH/llvm/lib"' \
  'export LIBRARY_PATH="$HIP_LIB_PATH:$ROCM_PATH/lib:$ROCM_PATH/lib64"' \
  'export CPATH="$HIP_INCLUDE_PATH"' \
  'export PKG_CONFIG_PATH="$ROCM_PATH/lib/pkgconfig"' \
  > /etc/profile.d/rocm.sh \
  && chmod +x /etc/profile.d/rocm.sh \
  && echo 'source /etc/profile.d/rocm.sh' >> /etc/bashrc

WORKDIR /opt/llama.cpp
RUN git clone --recursive https://github.com/ggerganov/llama.cpp.git . \
  && git clean -xdf \
  && git submodule update --recursive

RUN cmake -S . -B build \
  -DGGML_HIP=ON \
  -DAMDGPU_TARGETS=gfx1151 \
  -DCMAKE_BUILD_TYPE=Release \
  -DGGML_RPC=ON \
  -DLLAMA_HIP_UMA=ON \
  && cmake --build build --config Release -- -j$(nproc) \
  && cmake --install build --config Release

# keep bin; drop headers/docs/static libs (retain llama.cpp for rpc binaries)
RUN find /opt/rocm-7.0 -type f -name '*.a' -delete \
  && rm -rf /opt/rocm-7.0/include /opt/rocm-7.0/share \
  /opt/rocm-7.0/llvm/include /opt/rocm-7.0/llvm/share

# runtime
FROM registry.fedoraproject.org/fedora-minimal:43

RUN microdnf -y --nodocs --setopt=install_weak_deps=0 install \
  bash ca-certificates libatomic libstdc++ libgcc radeontop vim procps-ng \
  && microdnf clean all && rm -rf /var/cache/dnf/*

COPY --from=builder /opt/rocm-7.0 /opt/rocm-7.0
COPY --from=builder /usr/local/ /usr/local/
COPY --from=builder /opt/llama.cpp/build/bin/rpc-* /usr/local/bin/

# COPY gguf-vram-estimator.py /usr/local/bin/
# RUN chmod +x /usr/local/bin/gguf-vram-estimator.py

ENV ROCM_PATH=/opt/rocm-7.0 \
  HIP_PLATFORM=amd \
  HIP_PATH=/opt/rocm-7.0 \
  HIP_CLANG_PATH=/opt/rocm-7.0/llvm/bin \
  HIP_INCLUDE_PATH=/opt/rocm-7.0/include \
  HIP_LIB_PATH=/opt/rocm-7.0/lib \
  HIP_DEVICE_LIB_PATH=/opt/rocm-7.0/lib/llvm/amdgcn/bitcode \
  PATH=/opt/rocm-7.0/bin:/opt/rocm-7.0/llvm/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
  LD_LIBRARY_PATH=/opt/rocm-7.0/lib:/opt/rocm-7.0/lib64:/opt/rocm-7.0/llvm/lib \
  LIBRARY_PATH=/opt/rocm-7.0/lib:/opt/rocm-7.0/lib64 \
  CPATH=/opt/rocm-7.0/include \
  PKG_CONFIG_PATH=/opt/rocm-7.0/lib/pkgconfig

RUN printf '%s\n' \
  'export ROCM_PATH=/opt/rocm-7.0' \
  'export HIP_PLATFORM=amd' \
  'export HIP_PATH=/opt/rocm-7.0' \
  'export HIP_CLANG_PATH=/opt/rocm-7.0/llvm/bin' \
  'export HIP_INCLUDE_PATH=/opt/rocm-7.0/include' \
  'export HIP_LIB_PATH=/opt/rocm-7.0/lib' \
  'export HIP_DEVICE_LIB_PATH=/opt/rocm-7.0/lib/llvm/amdgcn/bitcode' \
  'export PATH="$ROCM_PATH/bin:$HIP_CLANG_PATH:$PATH"' \
  'export LD_LIBRARY_PATH="$HIP_LIB_PATH:$ROCM_PATH/lib:$ROCM_PATH/lib64:$ROCM_PATH/llvm/lib"' \
  'export LIBRARY_PATH="$HIP_LIB_PATH:$ROCM_PATH/lib:$ROCM_PATH/lib64"' \
  'export CPATH="$HIP_INCLUDE_PATH"' \
  'export PKG_CONFIG_PATH="$ROCM_PATH/lib/pkgconfig"' \
  > /etc/profile.d/rocm.sh \
  && chmod +x /etc/profile.d/rocm.sh \
  && echo 'source /etc/profile.d/rocm.sh' >> /etc/bashrc

# make /usr/local libs visible without touching env
RUN echo "/usr/local/lib"  > /etc/ld.so.conf.d/local.conf \
  && echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local.conf \
  && ldconfig

CMD ["/bin/bash"]

Le backend ROCm pour llama.cpp fournit environ 30% de meilleures performances que Vulkan. C’est parce que ROCm est la plateforme de calcul GPU native d’AMD, optimisée pour les charges de travail intensives en calcul comme l’inférence de LLM.

Entrée Docker Compose :

qwen-3-coder-rocm:
  image: llamacpp-rocm
  container_name: llamacpp
  restart: unless-stopped
  devices:
    - /dev/dri:/dev/dri
    - /dev/kfd:/dev/kfd
  group_add:
    - "video"
    - "render"
  volumes:
    - /home/mark/running-llms/:/root/running-llms
  ports:
    - "8080:8080"
  security_opt:
    - seccomp=unconfined
  command: >
    bash -c "llama-server --alias Qwen3-Coder-30B -m /root/running-llms/hf-models/unsloth/Qwen3-Coder-30B-A3B-Instruct-1M-BF16/BF16/Qwen3-Coder-30B-A3B-Instruct-1M-BF16-00001-of-00002.gguf --ctx-size 262144 -fa 1 --no-mmap --host 0.0.0.0 --port 8080 --temp 0.7 --top-k 20 --min-p 0.01 --top-p 0.8 --repeat-penalty 1.05 --jinja -ngl 99 --threads -1"

Exécution des modèles

Qwen3-Coder-Next (80B MoE)

C’est ici que le Framework Desktop se démarque vraiment. Je peux exécuter la version complète UD-Q8_K_XL de Qwen3-Coder-Next avec la fenêtre de contexte complète de 256K.

Liens :

Spécifications du modèle :

  • Architecture : 80B MoE (3B paramètres actifs)
  • Fenêtre de contexte : 262,144 jetons
  • Mémoire requise : ~93.4 GB pour UD-Q8_K_XL (8-bit)
  • Paramètres recommandés : temp=1.0, top_p=0.95, top_k=40, min_p=0.01

Configuration actuelle des modèles

Mon docker-compose.yml définit plusieurs services :

ServiceBackendModèleContexte
qwen-3-coder-next-rocmROCmQwen3-Coder-Next (UD-Q8_K_XL)262k
qwen-3-coder-next-vulkanVulkanQwen3-Coder-Next262k
qwen-3-next-rocmROCmQwen3-Next-80B-A3B-Thinking32k
gpt-oss-rocmROCmgpt-oss-120b-GGUF131k
glm-4.7VulkanGLM-4.716k

Commandes de lancement

Démarrer le service Ollama :

cd ollama-vulkan
docker compose up -d

Démarrer llama.cpp pour un modèle spécifique :

docker compose up -d qwen-3-coder-next-rocm

Arrêter tous les services :

docker compose down

Flux de travail agentiques et Claude Code

J’exécute des sessions Claude Code entièrement autonomes pendant de nombreuses heures avec cette configuration. Le Framework Desktop a rédigé la majorité de cet article au fil de ces sessions autonomes.

Configuration de Claude Code

export ANTHROPIC_AUTH_TOKEN=ollama
export ANTHROPIC_API_KEY=""
export ANTHROPIC_BASE_URL=http://your-framework-desktop-ip:11434

claude --model qwen3-coder-next

Remarque : Remplacez your-framework-desktop-ip par votre domaine ou adresse IP réelle.

Problèmes actuels

J’ai rencontré un problème avec Ollama dans des flux de travail agentiques - voir Ollama issue #13939. Claude Code tente parfois d’utiliser des noms de modèles qui ne sont pas disponibles localement, ce qui entraîne des délais d’attente.

Solution de contournement : Utiliser llama.cpp directement fournit des résultats plus fiables pour les flux de travail agentiques sur ma configuration. La stabilité et la constance sont nettement meilleures.

Pourquoi je suis emballé par cette configuration

Des « jetons » infinis gratuitement

Cette configuration me permet de « brûler » une quantité infinie de jetons LLM 24x7 gratuitement. Même si les modèles payants sont plus rapides, cette configuration permet :

  • Des expérimentations sans fin avec différents modèles et prompts
  • Des sessions d’agents autonomes de longue durée
  • Aucun coût par jeton à surveiller
  • Confidentialité totale des données et fonctionnement hors ligne

Caractéristiques de performance

  • Plus lent que les modèles payants : Oui, mais la différence est acceptable pour la plupart des tâches
  • Meilleur pour coder : Les modèles locaux excellent en complétion et en compréhension de code
  • Contexte illimité : La fenêtre de contexte de 256K sur Qwen3-Coder-Next change la donne

L’avenir

Cette configuration a été incroyablement productive. Je :

  • Exécute des sessions Claude Code entièrement autonomes pendant des heures
  • Expérimente différentes quantifications et architectures de modèles
  • Développe des flux de travail d’agents personnalisés qui tirent parti du GPU local

J’ajouterai bientôt un article sur ma configuration Claude Code et sur la façon dont je la paramètre pour fonctionner avec ces modèles locaux.

Attribution et remerciements

Cette configuration n’aurait pas été possible sans le travail incroyable de la communauté open source. Un énorme merci à :

  • kyuz0/amd-strix-halo-toolboxes - L’inspiration pour les conteneurs Docker, avec des images préconstruites pour les backends Vulkan et ROCm
  • technigmaai-wiki - Instructions complètes, étape par étape, pour la configuration de la mémoire GPU
  • lhl/strix-halo-testing - Configuration détaillée de benchmark LLM pour Strix Halo
  • Unsloth - Fournit d’excellents modèles optimisés GGUF
  • ROCm - La pile logicielle GPU ouverte
  • llama.cpp - L’incroyable travail de ggerganov et des contributeurs

Ces ressources représentent un effort important et incarnent l’avant-garde de l’inférence LLM locale sur matériel AMD.