AI и DIY,  Статьи

Настройка 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).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *