Зачем вообще смешивать NVIDIA и AMD в одном кластере?
Потому что у вас уже есть RTX 3090 (24GB), но на 104B модель её не хватает даже с квантованием Q4. Нужно ещё минимум 30-40GB. Покупать вторую 3090 дорого. RX 7900 XT с её 24GB GDDR6 стоит дешевле, но как заставить их работать вместе? CUDA с ROCm не дружат в одном процессе.
Это не простая конфигурация. Вы сэкономите деньги, но заплатите часами настройки. Если нужна стабильность — берите одинаковые карты. Если готовы к экспериментам — читайте дальше.
llama.cpp RPC решает проблему радикально: каждая карта работает в своём процессе со своим стеком драйверов. NVIDIA общается с CUDA, AMD с ROCm. А между ними — простой TCP.
Что у вас должно быть перед началом
- Два компьютера (или одна машина с двумя картами, но тогда изоляция через Docker)
- RTX 3090 с 24GB VRAM, драйверы NVIDIA 535+
- RX 7900 XT с 24GB VRAM, ROCm 6.1+
- Гигабитная сеть между машинами (кабель напрямую или через свитч)
- Модель Command R+ 104B в формате GGUF (Q4_K_M или Q5_K_M)
- Знание, где находится ваш терпение
Почему обычные методы не работают
Пытались запустить через vLLM или Text Generation Inference? Забудьте. Они требуют единого бэкенда. PyTorch с поддержкой и CUDA, и ROCm одновременно — это утопия. Даже если соберёте, стабильность будет нулевая.
llama.cpp RPC использует другую философию: каждый узел — самостоятельный сервер. Мастер отправляет запрос слоя 15 на узел A, получает результат, отправляет слой 16 на узел B. Сеть загружена минимально — только тензоры активаций между слоями.
1 Подготовка узла с NVIDIA (RTX 3090)
На машине с RTX 3090 всё просто. Собираем llama.cpp с поддержкой CUDA:
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
mkdir build && cd build
cmake .. -DLLAMA_CUDA=ON -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
Проверяем, что карта видна:
./server --help | grep cuda
# Должна быть строка с поддержкой CUDA
2 Подготовка узла с AMD (RX 7900 XT)
Здесь начинается боль. ROCm на RDNA3 — это отдельное приключение. Сначала ставим ROCm 6.1 (новее — лучше, но стабильнее 6.1).
Не используйте системные пакеты из репозитория Ubuntu/Debian. Они почти всегда устаревшие. Качайте официальные пакеты с сайта AMD.
После установки ROCm собираем llama.cpp с поддержкой HIP (AMD's CUDA):
cd llama.cpp
mkdir build-amd && cd build-amd
cmake .. -DLLAMA_HIP=ON -DCMAKE_BUILD_TYPE=Release -DAMDGPU_TARGETS=gfx1100
make -j$(nproc)
Ключевой момент: gfx1100 — это архитектура RX 7900 XT. Если укажете не ту, производительность упадёт в 10 раз.
3 Настройка сети между узлами
Статичные IP. Никакого DHCP. Настройте /etc/hosts или DNS, чтобы узлы видели друг друга по имени.
Проверяем сеть:
# На узле NVIDIA
ping amd-node.local
# На узле AMD
ping nvidia-node.local
Откройте порты 4242 и 4243 в фаерволе. Или просто отключите фаервол на время тестов (не в продакшене!).
4 Запуск RPC серверов
Сначала на узле AMD запускаем сервер, который будет обслуживать часть слоёв:
cd build-amd
./server -m /path/to/command-r-plus-104b.Q4_K_M.gguf \
--rpc-serve \
--host 0.0.0.0 \
--port 4242 \
--n-gpu-layers 40 \
--ctx-size 4096 \
--rpc-job-slot-count 1
Флаги важные:
--n-gpu-layers 40— сколько слоёв загружать на GPU. Для 104B модели и 24GB VRAM это максимум.--ctx-size 4096— ограничение контекста. Почему не 8192 или 32768? Об этом ниже.--rpc-job-slot-count 1— один параллельный запрос. Увеличивать только если уверены в сети.
Теперь на узле NVIDIA:
cd build
./server -m /path/to/command-r-plus-104b.Q4_K_M.gguf \
--rpc-serve \
--host 0.0.0.0 \
--port 4243 \
--n-gpu-layers 40 \
--ctx-size 4096 \
--rpc-job-slot-count 1
Обратите внимание — одна и та же модель на обоих узлах. Они загружают разные её части.
5 Запуск мастера, который всё координирует
На любом узле (или на третьем компьютере) запускаем:
./server -m /path/to/model.gguf \
--rpc \
--rpc-servers amd-node.local:4242,nvidia-node.local:4243 \
--ctx-size 4096 \
--parallel 1 \
--n-gpu-layers 80 \
--host 0.0.0.0 \
--port 8080
Магия в --n-gpu-layers 80. Мастер думает, что у него одна карта с 80 слоями в VRAM. На самом деле эти 80 слоёв распределены между двумя узлами.
Почему контекст ограничен 4096 токенами?
Самая болезненная часть mixed-vendor кластера. KV-cache (память под ключи и значения внимания) распределяется между узлами неравномерно.
На каждый слой в GPU нужно место под ключи и значения для каждого токена контекста. Формула простая: память_под_KV = 2 * слои * головы * размер_головы * контекст * точность.
Для Command R+ 104B с 80 слоями на GPU и контекстом 8192:
- На каждом узле по 40 слоёв
- Память под KV-cache: ~6GB на узел
- Плюс веса модели: ~23GB
- Итого: 29GB из 24GB доступных
Вот и всё. Не влезает. При 4096 контексте KV-cache занимает ~3GB, итого 26GB — уже на грани, но работает.
| Контекст | KV-cache на узел | Общая память | Влезает? |
|---|---|---|---|
| 2048 | ~1.5GB | ~24.5GB | ✅ Еле-еле |
| 4096 | ~3GB | ~26GB | ⚠️ С оверклоком памяти |
| 8192 | ~6GB | ~29GB | ❌ Нет |
Результаты: 12.3 токена в секунду — это много или мало?
На тестовом промпте "Explain quantum computing in simple terms" получаем:
- Первые 10 токенов: 1.2 сек (8.3 tps)
- Средняя скорость генерации: 12.3 tps
- Потребление памяти: 23.8/24GB на NVIDIA, 23.2/24GB на AMD
- Сетевая задержка между узлами: 0.3-0.8 мс
Для сравнения: одна RTX 4090 (24GB) с той же моделью в Q4 даёт 8-9 tps. Две RTX 3090 через NVLink — около 18 tps. Но NVLink требует одинаковых карт и специального моста.
12.3 tps за смешанную конфигурацию — хороший результат. Главное — модель работает.
Типичные ошибки и как их избежать
Ошибка: "CUDA error: out of memory" на узле NVIDIA, хотя на AMD всё хорошо
Память распределяется неравномерно. Решение: уменьшите --n-gpu-layers на проблемном узле. Или используйте --tensor-split для более точного распределения.
Ошибка: "HIP error: invalid device function" на AMD
Неправильный AMDGPU_TARGETS при компиляции. Для RX 7900 XT это gfx1100. Узнайте точную архитектуру:
rocminfo | grep "Name:"
Ошибка: медленная генерация (2-3 tps)
Скорее всего, сеть. Проверьте:
- Не используете Wi-Fi. Только кабель.
- ping между узлами должен показывать < 1ms
- Проверьте, не запущен ли торрент на одном из узлов
Ошибка: мастер падает при длинных ответах
Увеличьте --rpc-job-timeout на серверах. По умолчанию 60 секунд. Для длинных генераций ставьте 300 или больше.
А если добавить ещё карт?
Теоретически — да. На практике после третьего узла сложность растёт экспоненциально. Каждый новый узел добавляет задержку сети. Три узла дадут прирост на 30-40%, а не на 50%.
С четырьмя узлами вы будете больше времени бороться с настройкой, чем пользоваться моделью.
Итог: стоит ли игра свеч?
Стоит, если:
- Уже есть RTX 3090 и хочется больше VRAM без продажи почки
- Готовы потратить выходные на настройку
- Приемлем контекст 4096 токенов
Не стоит, если:
- Нужна стабильность 24/7
- Планируете часто менять модели
- Боитесь командной строки больше, чем пауков
Лично я после месяца использования mixed-кластера пришёл к выводу: технология RPC в llama.cpp — это прорыв. Она ломает монополию вендоров. Через год, когда инструменты станут удобнее, такие сборки станут обычным делом. А пока — вы первопроходец. Удачи.