이 글은 제가 Framework Desktop PC(Max+ 395, 128GB 통합 메모리)를 llama.cpp와 Ollama를 모두 사용해 Docker 컨테이너로 로컬 LLM을 실행할 수 있도록 어떻게 구성했는지 정리한 문서입니다.
하드웨어 개요
Framework Desktop Max+ 395는 통합 Radeon 그래픽(Strix Halo)이 포함된 AMD Ryzen AI Max 395 프로세서를 탑재하고 있으며, 주요 특징은 다음과 같습니다:
- 128GB 통합 메모리(CPU/GPU 공유)
- AMD RDNA 3.5 아키텍처
- gfx1151 GPU 타깃
https://frame.work/gb/en/desktop
GPU 메모리 구성
GPU 워크로드에서 128GB 통합 메모리를 전부 활용하려면 아래 구성이 필요합니다. 이 안내는 technigmaai-wiki의 Ubuntu 기반 가이드와 lhl/strix-halo-testing의 Fedora 43용 LLM 벤치마크 설정을 합쳐 정리한 것입니다(Fedora 43.).
BIOS 설정
- 재부팅 후 BIOS/UEFI 진입
- Integrated Graphics/UMA Frame Buffer Size를 512MB로 설정
- IOMMU 비활성화
Fedora 43 GRUB 구성
/etc/default/grub를 편집하고 GRUB_CMDLINE_LINUX_DEFAULT 라인을 수정합니다:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash amd_iommu=off amdgpu.gttsize=131072 ttm.pages_limit=33554432"
그다음 GRUB를 업데이트하고 재부팅합니다:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot
메모리 설정 확인
재부팅 후, 파라미터가 적용됐는지 확인합니다:
cat /proc/cmdline
sudo dmesg | grep -i gtt
sudo dmesg | grep -i ttm
이 구성은 GPU 워크로드에 대해 약 128GB의 GTT 메모리를 활성화하며, 256K 컨텍스트 윈도우를 가진 Qwen3-Coder-Next 같은 대형 모델을 구동하는 데 필수입니다.
대안: 커널 모듈 구성
더 세밀한 제어가 필요하면 /etc/modprobe.d/amdgpu_llm_optimized.conf를 생성합니다:
options amdgpu gttsize=120000
options ttm pages_limit=31457280
options ttm page_pool_size=15728640
그다음 initramfs를 재생성합니다:
sudo dracut --force
LLM에 Fedora 43을 쓰는 이유는?
많은 가이드는 Ubuntu를 대상으로 하지만, 로컬 LLM 워크로드 측면에서 Fedora 43은 몇 가지 장점이 있습니다:
더 최신 커널: Fedora 43은 커널 6.18.4+를 제공하며, ROCm 7.x와 Ryzen AI Max 395의 GPU에 대한 지원이 더 좋습니다
더 나은 ROCm 지원: 최신 커널에서의 AMDGPU 드라이버 개선은 통합 메모리 관리와 VRAM 할당을 더 잘 해주며, 이는 LLM 워크로드에 직접적인 이점으로 이어집니다
패키지 최신성: Fedora의 롤링 릴리스 모델 덕분에 다음과 같은 핵심 의존성들이 더 최신 버전으로 제공됩니다:
- HIP 컴파일을 위한 LLVM/Clang
- Vulkan 드라이버(Mesa RADV/AMDVLK)
- CMake 및 빌드 툴체인
- SELinux 고려사항: SELinux는 추가 설정(예:
container_use_devices=1)이 필요하지만, 컨테이너화된 LLM 워크로드에 대해 더 나은 보안 격리를 제공합니다
이 접근을 정리하는 데 참고한 핵심 소스는 다음과 같습니다:
Docker 기반 LLM 컨테이너
저는 kyuz0/amd-strix-halo-toolboxes를 기반으로 llama.cpp와 Ollama를 모두 실행할 수 있는 Docker 컨테이너를 만들었습니다.
컨테이너 사전 요구사항
컨테이너를 실행하기 전에, 컨테이너가 GPU 디바이스에 접근할 수 있도록 SELinux를 허용합니다:
sudo setsebool container_use_devices=1
이는 재부팅 후에도 유지되어야 하는 1회성 설정입니다:
sudo setsebool -P container_use_devices=1
Vulkan을 사용하는 Ollama (동작함)
Vulkan 백엔드는 Fedora 43에서 Ollama와 완벽하게 동작합니다(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"]
Vulkan으로 Ollama 실행:
# Build the image
docker build -t ollama-strix-vulkan -f ollama-vulkan/Dockerfile .
# Or using Docker Compose
cd ollama-vulkan
docker compose up -d
Ollama 접속:
ollama list
ollama pull qwen3-coder-next
ROCm을 사용하는 Ollama (동작하지 않음 - 수정 대기)
현재 Ollama의 ROCm 구현은 Fedora 43에서 ROCm 7.x와 함께 동작하지 않습니다. 이 이슈는 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"]
ROCm 백엔드는 시스템이 사용 가능한 VRAM을 ~111GB로 보고하더라도 "out of memory" 오류로 실패합니다. 이는 ROCm 7.2에서 Ollama의 메모리 계산에 영향을 주는 회귀(regression)로 보입니다.
현재 상태: AMD/ROCm 팀의 업스트림 수정 반영을 대기 중입니다.
Vulkan을 사용하는 llama.cpp
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"]
llama.cpp용 Vulkan 백엔드는 안정적이며 충분히 검증돼 있습니다. 모든 모델 크기에서 신뢰할 수 있는 성능을 제공합니다.
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"
ROCm을 사용하는 llama.cpp (더 빠름 - ~30% 성능 향상)
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"]
llama.cpp용 ROCm 백엔드는 Vulkan보다 약 30% 더 나은 성능을 제공합니다. 이는 ROCm이 AMD의 네이티브 GPU 컴퓨팅 플랫폼이며, LLM 추론처럼 연산 집약적인 워크로드에 최적화돼 있기 때문입니다.
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"
모델 실행
Qwen3-Coder-Next (80B MoE)
Framework Desktop이 진가를 발휘하는 부분입니다. 저는 256K 컨텍스트 윈도우 전체를 유지한 채로 Qwen3-Coder-Next의 UD-Q8_K_XL 전체 버전을 실행할 수 있습니다.
링크:
모델 사양:
- 아키텍처: 80B MoE(활성 파라미터 3B)
- 컨텍스트 윈도우: 262,144 토큰
- 필요 메모리: UD-Q8_K_XL(8-bit) 기준 ~93.4 GB
- 권장 설정: temp=1.0, top_p=0.95, top_k=40, min_p=0.01
현재 모델 구성
제 docker-compose.yml은 여러 서비스를 정의합니다:
| Service | Backend | Model | Context |
|---|---|---|---|
| qwen-3-coder-next-rocm | ROCm | Qwen3-Coder-Next (UD-Q8_K_XL) | 262k |
| qwen-3-coder-next-vulkan | Vulkan | Qwen3-Coder-Next | 262k |
| qwen-3-next-rocm | ROCm | Qwen3-Next-80B-A3B-Thinking | 32k |
| gpt-oss-rocm | ROCm | gpt-oss-120b-GGUF | 131k |
| glm-4.7 | Vulkan | GLM-4.7 | 16k |
실행 명령어
Ollama 서비스 시작:
cd ollama-vulkan
docker compose up -d
특정 모델에 대해 llama.cpp 시작:
docker compose up -d qwen-3-coder-next-rocm
모든 서비스 중지:
docker compose down
에이전트형 워크플로와 Claude Code
저는 이 구성에서 완전 자율 Claude Code 세션을 여러 시간 동안 실행해왔습니다. Framework Desktop은 이러한 자율 세션을 통해 이 글의 대부분을 작성했습니다.
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
참고: your-framework-desktop-ip를 실제 도메인 또는 IP 주소로 바꾸세요.
현재 이슈
에이전트형 워크플로에서 Ollama 관련 이슈 1건을 겪었습니다 - Ollama issue #13939을 참고하세요. Claude Code가 가끔 로컬에 없는 모델 이름을 사용하려고 시도하면서 타임아웃이 발생합니다.
우회 방법: 제 환경에서는 llama.cpp를 직접 사용하면 에이전트형 워크플로에서 더 신뢰할 수 있는 결과를 얻을 수 있었습니다. 안정성과 일관성이 체감될 정도로 더 좋습니다.
이 설정에 제가 왜 이렇게 만족하는가
무료로 무한 "토큰"
이 구성 덕분에 저는 LLM 토큰을 24x7 무료로 무한히 "태울" 수 있습니다. 유료 모델이 더 빠르긴 하지만, 이 설정은 다음을 가능하게 합니다:
- 다양한 모델과 프롬프트로 끝없는 실험
- 장시간 실행되는 자율 에이전트 세션
- 토큰당 비용 걱정 없음
- 완전한 데이터 프라이버시 및 오프라인 운영
성능 특성
- 유료 모델보다 느림: 맞지만, 대부분 작업에서 감당 가능한 수준입니다
- 코딩에 더 유리: 로컬 모델은 코드 완성과 이해에 강점을 보입니다
- 무제한 컨텍스트: Qwen3-Coder-Next의 256K 컨텍스트 윈도우는 게임 체인저입니다
미래
이 구성은 놀라울 정도로 생산적이었습니다. 저는 현재:
- 몇 시간씩 완전 자율 Claude Code 세션을 실행하고 있고
- 서로 다른 양자화(quantisation) 및 모델 아키텍처를 실험하고 있으며
- 로컬 GPU를 활용하는 커스텀 에이전트 워크플로를 개발 중입니다
곧 제 Claude Code 설정과, 이를 로컬 모델과 함께 동작하도록 어떻게 구성하는지에 대한 글도 추가할 예정입니다.
출처 및 감사
이 설정은 오픈소스 커뮤니티의 놀라운 작업 없이는 불가능했을 것입니다. 다음 프로젝트/리소스에 큰 감사를 전합니다:
- kyuz0/amd-strix-halo-toolboxes - Vulkan 및 ROCm 백엔드를 위한 사전 빌드 이미지를 포함해, Docker 컨테이너 구성에 영감을 준 프로젝트
- technigmaai-wiki - GPU 메모리 구성에 대한 포괄적인 단계별 안내
- lhl/strix-halo-testing - Strix Halo를 위한 상세한 LLM 벤치마킹 설정
- Unsloth - 훌륭한 GGUF 최적화 모델 제공
- ROCm - 오픈 GPU 소프트웨어 스택
- llama.cpp - ggerganov 및 기여자들의 놀라운 작업
이 리소스들은 상당한 노력의 산물이며, AMD 하드웨어에서의 로컬 LLM 추론 최전선을 보여줍니다.
