
Настройка AI-воркера распределенной сети llama.cpp на видеокартах AMD с Vulkan
На компьютере с видеокартами AMD с Vulkan (например, Radeon RX570 8GB) можно не обращать внимание на совместимость gcc с CUDA Runtime, задействуя самую новую версию компилятора.
Собираем llama.cpp на воркере (под управлением gentoo linux):
git clone https://github.com/ggml-org/llama.cpp && cd llama.cpp
cmake -B build -DGGML_VULKAN=ON -DCMAKE_BUILD_TYPE=Release -DGGML_RPC=ON -DCMAKE_C_FLAGS="-O3 -march=native -pipe" -DCMAKE_CXX_FLAGS="-O3 -march=native -pipe" && cmake --build build --config Release -j$(nproc)
-- The CXX compiler identification is GNU 15.3.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMAKE_BUILD_TYPE=Release
-- Found Git: /usr/bin/git (found version "2.54.0")
-- The ASM compiler identification is GNU
-- Found assembler: /usr/bin/cc
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- ccache found, compilation results will be cached. Disable with GGML_CCACHE=OFF.
-- CMAKE_SYSTEM_PROCESSOR: x86_64
-- GGML_SYSTEM_ARCH: x86
-- Found OpenMP_C: -fopenmp (found version "4.5")
-- Found OpenMP_CXX: -fopenmp (found version "4.5")
-- Found OpenMP: TRUE (found version "4.5")
-- Including CPU backend
-- x86 detected
-- Adding CPU backend variant ggml-cpu: -march=native
-- Using RPC backend
-- RDMA transport disabled
-- Including RPC backend
-- Found Vulkan: /usr/lib64/libvulkan.so (found version "1.4.341") found components: glslc glslangValidator
-- Vulkan found
-- GL_KHR_cooperative_matrix supported by glslc
-- GL_NV_cooperative_matrix2 supported by glslc
-- GL_NV_cooperative_matrix_decode_vector not supported by glslc
-- GL_EXT_integer_dot_product supported by glslc
-- GL_EXT_bfloat16 supported by glslc
-- Including Vulkan backend
-- ggml version: 0.15.3
-- ggml commit: 4fc4ec554
-- Found OpenSSL: /usr/lib64/libcrypto.so (found version "3.5.7")
-- Performing Test OPENSSL_VERSION_SUPPORTED
-- Performing Test OPENSSL_VERSION_SUPPORTED - Success
-- OpenSSL found: 3.5.7
-- Generating embedded license file for target: llama-app
-- Configuring done (3.8s)
-- Generating done (0.3s)
-- Build files have been written to: /home/intel88/Рабочий стол/llama.cpp/build
[ 0%] Building C object ggml/src/CMakeFiles/ggml-base.dir/ggml.c.o
[ 0%] Building CXX object vendor/cpp-httplib/CMakeFiles/cpp-httplib.dir/httplib.cpp.o
[ 0%] Creating directories for 'vulkan-shaders-gen'
[ 0%] Building CXX object common/CMakeFiles/llama-common-base.dir/build-info.cpp.o
[ 0%] No download step for 'vulkan-shaders-gen'
[ 0%] No update step for 'vulkan-shaders-gen'
[ 0%] No patch step for 'vulkan-shaders-gen'
[ 0%] Performing configure step for 'vulkan-shaders-gen'
-- The C compiler identification is GNU 15.3.0
-- The CXX compiler identification is GNU 15.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Enabling coopmat glslc support
-- Enabling coopmat2 glslc support
-- Enabling dot glslc support
-- Enabling bfloat16 glslc support
-- Configuring done (0.4s)
-- Generating done (0.0s)
-- Build files have been written to: /home/intel88/Рабочий стол/llama.cpp/build/ggml/src/ggml-vulkan/vulkan-shaders-gen-prefix/src/vulkan-shaders-gen-build
[ 0%] Performing build step for 'vulkan-shaders-gen'
[ 50%] Building CXX object CMakeFiles/vulkan-shaders-gen.dir/vulkan-shaders-gen.cpp.o
[ 0%] Linking CXX static library libllama-common-base.a
[ 0%] Built target llama-common-base
[ 0%] Building CXX object ggml/src/CMakeFiles/ggml-base.dir/ggml.cpp.o
…
[100%] Linking CXX executable ../../bin/llama-quantize
[100%] Built target test-export-graph-ops
[100%] Building CXX object tools/cli/CMakeFiles/llama-cli.dir/main.cpp.o
[100%] Linking CXX executable ../../bin/llama-cli
[100%] Built target llama-quantize
[100%] Building CXX object tools/server/CMakeFiles/llama-server.dir/main.cpp.o
[100%] Linking CXX executable ../../bin/llama-server
[100%] Built target llama-cli
[100%] Building CXX object tools/fit-params/CMakeFiles/llama-fit-params.dir/main.cpp.o
[100%] Built target llama-server
[100%] Building CXX object app/CMakeFiles/llama-app.dir/llama.cpp.o
[100%] Linking CXX executable ../../bin/llama-fit-params
[100%] Built target llama-fit-params
[100%] Building CXX object app/CMakeFiles/llama-app.dir/download.cpp.o
[100%] Building CXX object app/CMakeFiles/llama-app.dir/__/license.cpp.o
[100%] Linking CXX executable ../../bin/llama-diffusion-cli
[100%] Built target llama-diffusion-cli
[100%] Linking CXX executable ../bin/llama
[100%] Built target llama-app
[100%] Linking CXX executable ../bin/test-chat
[100%] Built target test-chat

В linux желательно установить ядро 7.1.2+, в котором исправлена масса ошибок и добавлена поддержка технологии

На момент написания статьи в gentoo ядро 7.1.2 находилось в тестовой ветке sys-kernel/gentoo-sources:

Устанавливаем sys-kernel/gentoo-sources-7.1.2 командами:
echo "sys-kernel/gentoo-sources ~amd64" | sudo tee -a /etc/portage/package.accept_keywords/kernel
sudo emerge --ask =sys-kernel/gentoo-sources-7.1.2
eselect kernel list
sudo eselect kernel set 2
sudo genkernel all --menuconfig
В открывшемся меню конфигурации ядра можно немного подшаманить, отключив неиспользуемую систему инициализации и другие ненужные функции.
После сборки проверяем/редактируем grub, например, так (для CPU Haswell, вывод изображения через Intel_HD4600, вычисления на двух AMD Radeon RX570 8GB в Vulkan-режиме):
GRUB_CMDLINE_LINUX="hugepagesz=1G hugepages=3 default_hugepagesz=1G amdgpu.ppfeaturemask=0xffffffff noresume nowatchdog nmi_watchdog=0 audit=0 page_alloc.shuffle=1 pci=pcie_bus_perf,realloc pcie_ports=native iommu=pt pcie_aspm=off msr.allow_writes=on mitigations=off spectre_v2=off spec_store_bypass_disable=off ssbd=off l1tf=off mds=off tsx_async_abort=off kvm.nx_huge_pages=off transparent_hugepage=madvise i915.enable_psr=0 raid=noautodetect plymouth.enable=0 ipv6.disable=1"
и выполняем
sudo grub-mkconfig -o /boot/grub/grub.cfg
Старое ядро (6.18.35) и оставшиеся от него символические ссылки можно удалить из папки boot командой:
sudo rm *6.18.35* && sudo rm *.old
Для оптимизации настроек системы для AI-вычислений по сети используем файл /etc/sysctl.d/99-custom.conf:
sudo nano /etc/sysctl.d/99-custom.conf
# Минимальный swappiness
vm.swappiness = 10
vm.vfs_cache_pressure = 50
# Сбалансированные лимиты дискового кэша под SATA SSD/HDD
vm.dirty_background_ratio = 5
vm.dirty_ratio = 15
# 512MB для contiguous аллокаций под 1G hugepages
vm.min_free_kbytes = 524288
# Shared Memory: shmmax поднят до ~30 ГБ (32212254720 байт)
# shmall = 32212254720 / 4096 (размер страницы) = 7864320
kernel.shmmax = 32212254720
kernel.shmall = 7864320
# --- Сеть (оптимизация под 10Gb)
net.core.somaxconn = 4096
net.core.netdev_max_backlog = 16384
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_rmem = 4096 131072 33554432
net.ipv4.tcp_wmem = 4096 131072 33554432
net.ipv4.tcp_timestamps = 1
# BBR congestion control и дисциплина очередей FQ
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
# --- специфично ---
# Увеличение лимита mmap для слоев нейросетей на AMD GPU
vm.max_map_count = 1048576
# Снижение OOM агрессивности
vm.oom_kill_allocating_task = 0
vm.panic_on_oom = 0
# Разрешить группе (обычно 1000) использовать Hugepages
vm.hugetlb_shm_group = 1000
# Разблокировка Magic SysRq (Alt+PrtScn+REISUB) для экстренной реанимации
kernel.sysrq = 1
Проверка настроек операционной системы:
- проверка пропускной способности и режима PCIe (флаги pci=pcie_bus_perf,realloc в grub):
sudo lspci -vvv -d 1002:* | grep -E "LnkCap:|LnkSta:"
LnkCap: Port #0, Speed 8GT/s, Width x16, ASPM L1, Exit Latency L1 <1us
LnkSta: Speed 8GT/s, Width x8 (downgraded)
LnkCap: Port #0, Speed 8GT/s, Width x16, ASPM L1, Exit Latency L1 <1us
LnkSta: Speed 8GT/s, Width x8 (downgraded)
LnkCap: Port #1, Speed 8GT/s, Width x16, ASPM L1, Exit Latency L1 <1us
LnkSta: Speed 8GT/s, Width x8 (downgraded)
LnkCap: Port #1, Speed 8GT/s, Width x16, ASPM L1, Exit Latency L1 <1us
LnkSta: Speed 8GT/s, Width x8 (downgraded)
- проверка сквозного режима IOMMU (iommu=pt), включается в BIOS (пункт Intel VT-d или Intel Virtualization Technology for Directed I/O):
dmesg | grep -i -E "iommu|dmar"
[ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-7.1.2-gentoo-x86_64 root=UUID=1ac6c721-7a21-4f69-b23e-aaea5354ae7b ro hugepagesz=1G hugepages=3 default_hugepagesz=1G amdgpu.ppfeaturemask=0xffffffff noresume nowatchdog nmi_watchdog=0 audit=0 page_alloc.shuffle=1 pci=pcie_bus_perf,realloc pcie_ports=native iommu=pt pcie_aspm=off msr.allow_writes=on mitigations=off spectre_v2=off spec_store_bypass_disable=off ssbd=off l1tf=off mds=off tsx_async_abort=off kvm.nx_huge_pages=off transparent_hugepage=madvise i915.enable_psr=0 raid=noautodetect plymouth.enable=0 ipv6.disable=1
[ 0.006733] ACPI: DMAR 0x000000009C282B08 0000B0 (v01 INTEL HSW 00000001 INTL 00000001)
[ 0.006744] ACPI: Reserving DMAR table memory at [mem 0x9c282b08-0x9c282bb7]
[ 0.016296] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-7.1.2-gentoo-x86_64 root=UUID=1ac6c721-7a21-4f69-b23e-aaea5354ae7b ro hugepagesz=1G hugepages=3 default_hugepagesz=1G amdgpu.ppfeaturemask=0xffffffff noresume nowatchdog nmi_watchdog=0 audit=0 page_alloc.shuffle=1 pci=pcie_bus_perf,realloc pcie_ports=native iommu=pt pcie_aspm=off msr.allow_writes=on mitigations=off spectre_v2=off spec_store_bypass_disable=off ssbd=off l1tf=off mds=off tsx_async_abort=off kvm.nx_huge_pages=off transparent_hugepage=madvise i915.enable_psr=0 raid=noautodetect plymouth.enable=0 ipv6.disable=1
[ 0.040866] DMAR: Host address width 39
[ 0.040868] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
[ 0.040873] DMAR: dmar0: reg_base_addr fed90000 ver 1:0 cap c0000020660462 ecap f0101a
[ 0.040877] DMAR: DRHD base: 0x000000fed91000 flags: 0x1
[ 0.040881] DMAR: dmar1: reg_base_addr fed91000 ver 1:0 cap d2008020660462 ecap f010da
[ 0.040884] DMAR: RMRR base: 0x0000009c102000 end: 0x0000009c10efff
[ 0.040887] DMAR: RMRR base: 0x0000009f800000 end: 0x000000af9fffff
[ 0.040889] DMAR-IR: IOAPIC id 2 under DRHD base 0xfed91000 IOMMU 1
[ 0.040892] DMAR-IR: HPET id 0 under DRHD base 0xfed91000
[ 0.040894] DMAR-IR: Queued invalidation will be enabled to support x2apic and Intr-remapping.
[ 0.041353] DMAR-IR: Enabled IRQ remapping in x2apic mode
[ 0.144432] iommu: Default domain type: Passthrough (set via kernel command line)
ACPI: DMAR … INTEL HSW свидетельствует, что материнская плата успешно передала ядру ACPI-таблицы CPU Haswell.
DMAR-IR: Enabled IRQ remapping in x2apic mode — обозначает, что включена аппаратная переадресация прерываний. Прерывания сети теперь обрабатываются аппаратно без задержек и микро-фризов процессора.
iommu: Default domain type: Passthrough — успешное применение режима сквозного проброса памяти iommu=pt. Благодрая этому обе видеокарты общаются с оперативной памятью напрямую на полной скорости шины, минуя виртуальные трансляции адресов IOMMU.
- проверка работы HMM (Heterogeneous Memory Management) для ядер linux 7.x, выполняем при запущенном инференсе, вывод появится когда памяти видеокарт будет не хватать, llama.cpp задействует ОЗУ:
dmesg | grep -i hmm
- проверка разблокировки Power Play (amdgpu.ppfeaturemask):
cat /sys/class/drm/card1/device/pp_od_clk_voltage
Команда выводит таблицу частот и напряжений, скорректированных программой lact:
0: 300MHz 750mV
1: 500MHz 760mV
2: 900MHz 850mV
3: 980MHz 860mV
4: 1000MHz 870mV
5: 1030MHz 880mV
6: 1060MHz 890mV
7: 1100MHz 900mV
OD_MCLK:
0: 300MHz 750mV
1: 1000MHz 780mV
2: 1850MHz 880mV
OD_RANGE:
SCLK: 300MHz 2000MHz
MCLK: 300MHz 2250MHz
VDDC: 750mV 1150mV
Для управления разгоном и вентиляторами видеокарт AMD в linux удобно применять программу LACT:

В gentoo lact можно установить командами:
sudo mkdir -p /etc/portage/package.accept_keywords
echo "sys-apps/lact ~amd64" | sudo tee -a /etc/portage/package.accept_keywords/lact
sudo emerge --ask sys-apps/lact
Для уменьшения нагрева нужно обязательно настроить вольтажи и частоты, активировав галочку «Показать все P-States»:

- проверка статуса Hugepages:
grep -i huge /proc/meminfo
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
FileHugePages: 167936 kB
HugePages_Total: 3
HugePages_Free: 3
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 1048576 kB
Hugetlb: 3145728 kB
Переносим файлы llama.cpp из директории build/bin в каталог, в котором нет кириллических букв и пробелов.
Запускаем инференс локально скриптом:
#!/bin/sh
# Снимаем лимиты на блокировку памяти в RAM (важно для mlock и hugepages)
ulimit -l unlimited || exit 1
# Принудительно задаем открытый Vulkan-драйвер от Mesa
export AMD_VULKAN_ICD=RADV
# Оптимизации RADV для вычислений
export RADV_PERFTEST=nogttspill
export RADV_DEBUG=nohiz
# Переходим в папку с llama.cpp
cd ~/llama_cpp
# Запуск локального сервера
exec ./llama-server \
-m ~/AI_Models/gemma4-coding-Q8_0.gguf \
--host 127.0.0.1 \
--port 8080 \
-c 15000 \
-ngl -1 \
-t 4 \
--jinja \
--mlock \
--webui \
-sm layer \
--device Vulkan0,Vulkan1
С указанными настройками (контекст 15000) две видеокарты AMD Radeon RX580 по 8GB успешно работают с AI-моделью gemma4-coding-Q8_0.gguf (11.8GB), скорость инференса 8.3 т/с:

Для включения машины в распределенную сеть создаем скрипт запуска ggml-rpc-server-worker.sh:
sudo mkdir /var/lib/llama_cpp/
sudo nano /var/lib/llama_cpp/ggml-rpc-server-worker.sh
Содержимое /var/lib/llama_cpp/ggml-rpc-server-worker.sh:
#!/bin/sh
export GGML_VK_VISIBLE_DEVICES=1,2
export AMD_VULKAN_ICD=RADV
export RADV_PERFTEST=nogttspill
export GGML_VK_FORCE_MAX_MEMORY=1
export RADV_DEBUG=nohiz
cd /var/lib/llama_cpp
exec ./ggml-rpc-server -H 0.0.0.0 -p 50052
Для безопасности распределенной сети запускаем воркер от изолированного системного пользователя llama, не имеющего прав root. При этом выдаем вашему текущему пользователю полные права на управление файлами в этой папке без использования sudo.
• Создаем рабочую директорию:
sudo mkdir -p /var/lib/llama_cpp
!!!Важно!!!
Для дальнейшей работы нужно скопировать скомпилированные файлы llama.cpp из подкаталога /build/bin/, а такде созданный ранее скрипт запуска ggml-rpc-server-worker.sh в каталог /var/lib/llama_cpp/
• Создаем системного пользователя llama и добавляем текущего пользователя в его группу:
sudo useradd -r -s /bin/false -G video,render -d /var/lib/llama_cpp llama
sudo gpasswd -a $USER llama
• Назначаем владельцем пользователя llama, но группу делаем общей:
sudo chown -R llama:llama /var/lib/llama_cpp
• Выставляем базовые Unix-права и принудительно открываем доступ текущему пользователю через списки ACL:
sudo chmod -R 775 /var/lib/llama_cpp
sudo setfacl -R -m u:$USER:rwx /var/lib/llama_cpp && sudo setfacl -R -d -m u:$USER:rwx /var/lib/llama_cpp
sudo chmod +x /var/lib/llama_cpp/ggml-rpc-server-worker.sh
• Обновляем сессию текущего терминала, чтобы права на запись вступили в силу:
newgrp llama
- создаем файл конфигурации службы openrc ggml-worker:
sudo nano /etc/conf.d/ggml-worker
- вносим туда текст:
# /etc/conf.d/ggml-worker
# Путь к исполняемому скрипту запуска
WORKER_SCRIPT="/var/lib/llama_cpp/ggml-rpc-server-worker.sh"
# Пользователь и группа для запуска
WORKER_USER="llama"
WORKER_GROUP="llama"
# Файл для логирования вывода (для отладки)
WORKER_LOG="/var/log/ggml-worker.log"
# Разрешаем процессу блокировать неограниченный объем памяти в RAM (замена ulimit -l)
rc_ulimit="-l unlimited"
- создаем управляющий скрипт системы инициализации OpenRC:
sudo nano /etc/init.d/ggml-worker
с текстом:
#!/sbin/openrc-run
# Описание службы для rc-status
description="LLAMA.cpp GGML RPC Server Worker"
# Зависимости службы
depend() {
# Сервер должен стартовать после инициализации сети и дисплейного менеджера
need net
after display-manager
}
start() {
ebegin "Starting GGML RPC Worker"
# Проверяем наличие скрипта
if [ ! -x "${WORKER_SCRIPT}" ]; then
eerror "Worker script ${WORKER_SCRIPT} not found or not executable!"
return 1
fi
# Обеспечиваем создание лог-файла с правильными правами
touch "${WORKER_LOG}"
chown "${WORKER_USER}:${WORKER_GROUP}" "${WORKER_LOG}"
# Запуск через start-stop-daemon
start-stop-daemon --start \
--background \
--make-pidfile \
--pidfile /run/ggml-worker.pid \
--user "${WORKER_USER}" \
--group "${WORKER_GROUP}" \
--stdout "${WORKER_LOG}" \
--stderr "${WORKER_LOG}" \
--exec "${WORKER_SCRIPT}"
eend $?
}
stop() {
ebegin "Stopping GGML RPC Worker"
start-stop-daemon --stop \
--pidfile /run/ggml-worker.pid
eend $?
}
- делаем скрипт исполняемым и добавляем его в уровень запуска default (после загрузки сети и графики):
sudo chmod +x /etc/init.d/ggml-worker
sudo rc-update add ggml-worker default
Управление службой ggml-worker осуществляем командами:
- запуск вручную:
sudo rc-service ggml-worker start
* Caching service dependencies ... [ ok ]
* Starting GGML RPC Worker ... [ ok ]
- остановка:
sudo rc-service ggml-worker stop
- просмотр логов вычислений нейросети:
tail -f /var/log/ggml-worker.log
ggml_vulkan: Found 2 Vulkan devices:
ggml_vulkan: 0 = AMD Radeon RX 570 Series (RADV POLARIS10) (radv) | uma: 0 | fp16: 0 | bf16: 0 | warp size: 64 | shared memory: 65536 | int dot: 0 | matrix cores: none
ggml_vulkan: 1 = AMD Radeon RX 570 Series (RADV POLARIS10) (radv) | uma: 0 | fp16: 0 | bf16: 0 | warp size: 64 | shared memory: 65536 | int dot: 0 | matrix cores: none
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
WARNING: Host ('0.0.0.0') is != '127.0.0.1'
Never expose the RPC server to an open network!
This is an experimental feature and is not secure!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- просмотр загрузки видеокарт в sys-process/nvtop (работает с AMD, NVIDIA, Intel и другими GPU) или подобной программе.

После применения описанных выше настроек служба ggml-worker будет запускаться в фоне автоматически. При этом вывод интерфейса XFCE на дисплей будет идти через встроенную графику Intel HD 4600, благодаря чему обе видеокарты AMD Radeon RX 570 8GB останутся полностью свободными и будут незаметно для пользователя принимать тензоры по сети от мастера.
На компьютере-мастере для управления используем скрипт, в котором узлы распределенной сети вычислений перечисляются через запятую, например, для lordx64_Qwable-v1-Q6_K_L.gguf (28.7GB):
./llama-server \
-m ~/AI_Models/Qwable-v1/lordx64_Qwable-v1-Q6_K_L.gguf \
--host 127.0.0.1 \
--port 8080 \
--rpc 192.168.2.41:50052,192.168.2.88:50052 \
-ngl -1 \
-b 512 \
-ub 512 \
-t 8 \
-tb 8 \
-sm layer \
-ctk q8_0 \
-ctv q8_0 \
-c 32768 \
-n -1 \
--no-mmap \
--rope-freq-scale 0.5 \
--yarn-orig-ctx 16384 \
--yarn-beta-fast 32 \
--yarn-beta-slow 1 \
--temp 0.2 \
--min-p 0.05 \
--flash-attn on
Инференс в локальной сети на трех компьютерах (1 — Nvidia Tesla V100, 2 — две Nvidia Ge Force GTX1070 по 8GB, 3 — две AMD Radeon RX 570 по 8GB), модель Qwable-v1-Q6_K_L.gguf, скорость инференса около 17 т/с:

Интересно отметить, что на второй машине стояла версия llama.cpp, собранная из исходников другого коммита на github (разница в сутки), что не помешало сети распределенных вычислений заработать.
При использовании только двух машин (1 — роутер 1Gbit по 8GB, соединение через роутер по каналу 1Gbit/s), скорость инференса упала до 6 т/с, что связано с переполнением памяти видеокарт AMD, работающих на Vulkan на такой большой модели с контекстом 32768:

Связка Tesla V100 и двух Nvidia GTX1070 при тех же условиях работала значительно лучше, выдавая около 14.6 т/с (подробнее в статье Запуск llama.cpp в распределенном режиме по локальной сети).
После уменьшения контекста до 15000 скорость инференса на двух машинах (Tesla V100 + две Radeon RX578) выросла до 7.9 т/с.
Главной целью создания кластера распределенных вычислений является увеличение доступного объема видеопамяти при сохранении приемлемой скорости инференса.

Multi-GPU майнинг-фермы с видеокартами, подключенными через райзеры PCI-Ex1 к плате с ограниченным числом линий PCI-E для этого не подходят из-за сильного ограничения пропускной способности шины PCI-E, задействующейся по полной программе при AI-вычислениях.

При использовании трех компьютеров с 5 видеокартами, четыре из которых работают в режиме PCI-Ex8 Gen3 и одна (Tesla V100) — по шине PCI-Ex16 Gen3 главным ограничением становиться скорость обмена по локальной сети. Тем не менее, быстродействие такого кластера значительно выше, чем если бы те же 5 карт стояло на одном компьютере, довольствуясь, в лучшем случае, подключением PCI-Ex4 Gen3.

Благодаря наличию 48GB VRAM можно использовать модели внушительного (для домашнего пользователя) размера, например, Qwen3.6-40B-Deck-Opus-NEO-CODE-HERE-2T-OT-HIGH-Q8_0.gguf (39.9GB) плюс модуль распознавания картинок mmproj-F16.gguf (0.9GB).

При использовании скрипта с контекстом в 32768 инференс производился с частичной выгрузкой в RAM. В логах загрузки llama.cpp были ошибки:
E ggml_backend_cuda_buffer_type_alloc_buffer: allocating 248.10 MiB on device 0: cudaMalloc failed: out of memory
E ggml_gallocr_reserve_n_impl: failed to allocate CUDA0 buffer of size 260149504)
не смотря на это, вычисления запустились, скорость AI-раздумий составила 2.4 т/с, что не так уж плохо для старого железа:

После уменьшения контекста до 15000 память немного разрузилась, скорость инференса модели размером более 40GB достигла 2.8 т/с. После отключения блока распознавания изображений и уменьшения контекста до 10000 скорость стала равной 3.2 токенам в секунду.

Заключение
Описанная в статье конфигурация распределенной сети вычислений на базе llama.cpp с использованием видеокарт AMD через Vulkan-драйвер позволяет эффективно решать задачу увеличения доступного объема видеопамяти для работы с крупными языковыми моделями.
Основные достижения:
1. Успешная интеграция разнородного оборудования
Практика показала, что в единую сеть можно объединять видеокарты разных производителей (NVIDIA и AMD) и даже разных поколений, что значительно расширяет возможности домашнего пользователя. Разница в версиях llama.cpp между узлами (в пределах нескольких дней) не критична для стабильной работы системы.
2. Приемлемая производительность
При оптимальной конфигурации (3 узла, 5 видеокарт, суммарно 48 ГБ VRAM) достигается скорость инференса 8–17 токенов в секунду, что достаточно для комфортной работы с моделями размером до 40 ГБ.
3. Безопасность и надежность
Изолированный пользователь, правильные права доступа, автоматический запуск через OpenRC и логирование обеспечивают стабильную работу системы в фоновом режиме.
Ключевые ограничения:
1. Скорость сети — главный фактор
Пропускная способность локальной сети определяет максимальную производительность кластера. При использовании соединения через роутер (1 Гбит/с) скорость падает до 6–8 т/с, что связано с задержками передачи тензоров между узлами.
2. Ограничения шины PCI-E
Видеокарты, работающие в режиме PCI-Ex8 Gen3, обеспечивают достаточную пропускную способность, но при подключении через райзеры или в режиме x4 производительность существенно снижается.
3. Управление памятью
При превышении доступного VRAM происходит выгрузка в оперативную память, что приводит к снижению скорости до 2–3 т/с. Оптимально подбирать размер контекста под доступные ресурсы.

Перспективы:
Данная архитектура особенно актуальна для:
— Локального развертывания крупных моделей без облачных сервисов
— Образовательных и исследовательских задач
— Корпоративных решений с требованиями к конфиденциальности данных
С развитием стандарта GGML RPC и улучшением программ, подобных llama.cpp, производительность таких систем будет продолжать расти, делая распределенные вычисления доступными для широкого круга пользователей.
P.S. Оптимизированный скрипт запуска увеличиил скорость инференса в модели gemma4-coding-Q8_0.gguf до 12.6 т/с (на 50%):
#!/bin/sh
# =============================================
# Оптимизированный запуск llama.cpp на AMD (RADV)
# =============================================
# Снимаем лимиты на блокировку памяти
ulimit -l unlimited || exit 1
# === Vulkan + RADV оптимизации ===
export AMD_VULKAN_ICD=RADV
export RADV_PERFTEST=nogttspill,nodisabled_shader_cache
export RADV_DEBUG=nohiz,nggc,nospill # для Polaris
export GGML_VK_FORCE_MAX_MEMORY=1
export GGML_VK_VISIBLE_DEVICES=1,2 # ← согласно vulkaninfo | grep deviceName
# Дополнительно (можно отключить, если не помогают)
export RADV_SHADER_CACHE_ENABLE=1
# export RADV_RRA=1 # для отладки
# Опционально: отключить некоторые фичи, если есть проблемы
# export RADV_PERFTEST=nogttspill,nodma
# Переходим в папку
cd ~/"Рабочий стол"/llama_cpp || exit 1
echo "🚀 Запуск llama-server с Vulkan (AMD)..."
# Запуск сервера
exec ./llama-server \
-m ~/AI_Models/gemma4-coding-Q8_0.gguf \
--host 127.0.0.1 \
--port 8080 \
-c 15000 \
-ngl -1 \
-t 4 -tb 4 \
--jinja \
--mlock \
--webui \
-sm layer \
--no-mmap \
--flash-attn auto \
--device Vulkan0,Vulkan1
Для повышения стабильности в grub дополнительно можно добавить параметры amdgpu.gpu_recovery=1 (восстановление при сбоях без перезагрузки) и amdgpu.dcdebugmask=0x10 (отключение функции энергосбереженияна нескольких картах) видеокарта реже сбрасывает частоты ядра дисплея, что снижает риск поймать аппаратный deadlock (ring gfx timeout или fence timeout) из-за конфликта подсистем питания):
GRUB_CMDLINE_LINUX="hugepagesz=1G hugepages=3 default_hugepagesz=1G amdgpu.ppfeaturemask=0xffffffff noresume nowatchdog nmi_watchdog=0 audit=0 page_alloc.shuffle=1 pci=pcie_bus_perf,realloc pcie_ports=native iommu=pt pcie_aspm=off msr.allow_writes=on mitigations=off spectre_v2=off spec_store_bypass_disable=off ssbd=off l1tf=off mds=off tsx_async_abort=off kvm.nx_huge_pages=off transparent_hugepage=madvise i915.enable_psr=0 raid=noautodetect plymouth.enable=0 ipv6.disable=1 amdgpu.gpu_recovery=1 amdgpu.dcdebugmask=0x10"
Для AI-кластера нужно внести изменения в файл /var/lib/llama_cpp/ggml-rpc-server-worker.sh:
#!/bin/sh
ulimit -l unlimited || exit 1
export AMD_VULKAN_ICD=RADV
export RADV_PERFTEST=nogttspill,nodisabled_shader_cache
export RADV_DEBUG=nohiz,nggc,nospill # для Polaris
export GGML_VK_FORCE_MAX_MEMORY=1
export GGML_VK_VISIBLE_DEVICES=1,2 # ← согласно vulkaninfo | grep deviceName
export RADV_SHADER_CACHE_ENABLE=1
cd /var/lib/llama_cpp
exec ./ggml-rpc-server -H 0.0.0.0 -p 50052
Скорость инференса в Qwab на двух компьютерах (Tesla V100 + 2 AMD Radeon Rx 570 8GB) после внесения изменений в ggml-rpc-server-worker.sh выросла незначительно — с 6 до 6.5 t/s, что, видимо, связано с сетевыми ограничениями.
Qwen3.6-40B-Deck-Opus-NEO-CODE-HERE-2T-OT-HIGH-Q8_0.gguf (39.9GB) без модуля распознавания картинок на трех машинах стал работать со скоростью 3.55 t/s (до улучшения скрипта ggml-rpc-server-worker.sh — 3.2).


