Почему ваша multi-GPU система тормозит, хотя должна летать
Вы поставили две RTX 4090 в материнку на x570, запустили llama.cpp с тензорным параллелизмом и... получили прирост в 1.2 раза вместо 2. А то и вовсе одну карту видите, а вторая простаивает. Знакомая история? Поздравляю, вы столкнулись с асимметричными PCI-E lanes - тихой болезнью multi-GPU систем, которая съедает до 50% производительности.
В теории, две карты должны делить нагрузку поровну. На практике, если одна карта сидит на PCI-E x16, а вторая на PCI-E x4 (или того хуже, на x1), то обмен данными между GPU превращается в узкое горлышко. И llama.cpp, который пытается распределить вычисления, упирается в медленный линк.
Хуже всего то, что система может работать без ошибок. Просто медленно. И вы будете месяцами думать, что проблема в драйверах, модели или коде. А дело в трех строчках конфигурации.
Эта статья - не про разгон или покупку нового железа. Это про то, как за 15 минут бесплатно получить то, что вы уже купили. Если у вас multi-GPU система и llama.cpp, читайте дальше.
1Снимите показания: какой слот какой скорости
Первым делом - понять, как ваша материнская плата распределяет PCI-E lanes. Особенно это актуально для плат на AMD x570, где второй PCI-E x16 слот часто работает на x4. Но и на Intel бывают сюрпризы.
Откройте терминал и выполните:
lspci -vv | grep -A 10 "VGA compatible controller"Вы увидите список ваших GPU. Обратите внимание на строку LnkSta. Например:
LnkSta: Speed 16GT/s, Width x16
LnkSta: Speed 8GT/s, Width x4Первый GPU работает на x16, второй на x4. Вот и причина тормозов. Если у вас больше двух карт, проверьте каждую.
Но lspci показывает теоретическую ширину. А что в реальности, под нагрузкой? Для этого переходим к шагу 2.
2Замерьте пульс под нагрузкой с nvtop
Установите nvtop - это htop для GPU. Он покажет не только загрузку, но и скорость передачи данных по PCI-E.
sudo apt install nvtop # для Ubuntu/Debian
# или
sudo dnf install nvtop # для FedoraЗапустите nvtop в одном терминале, а в другом запустите llama.cpp с multi-GPU. Смотрите на столбец "PCIe" - там будет отображаться текущая скорость передачи данных.
Если одна карта показывает высокую скорость (например, несколько ГБ/с), а вторая близка к нулю - значит, она не используется. Или если обе показывают, но одна на низкой скорости, то это узкое место.
nvtop не всегда точно отображает скорость на некоторых системах. Если сомневаетесь, используйте nvidia-smi dmon для мониторинга. Но nvtop дает более наглядную картину.
Теперь, когда диагноз ясен, переходим к лечению.
3Поймите, как llama.cpp выбирает GPU
По умолчанию llama.cpp использует все доступные GPU, начиная с нулевого. Но он не знает, что один слот быстрее другого. Он просто распределяет слои модели по очереди.
Если у вас асимметричные линки, то GPU на медленном слоте будет тормозить всю цепочку. Потому что данные для следующего слоя должны пройти через узкое горлышко.
Решение? Вручную указать, какие GPU использовать. И здесь на помощь приходит CUDA_VISIBLE_DEVICES.
4Отрежьте медленный GPU или поменяйте порядок
Переменная окружения CUDA_VISIBLE_DEVICES определяет, какие GPU видит CUDA. Индексы в ней начинаются с 0.
Допустим, у вас три GPU: GPU0 на x16, GPU1 на x4, GPU2 на x16. Вы хотите использовать только быстрые GPU0 и GPU2. Тогда:
export CUDA_VISIBLE_DEVICES=0,2Теперь llama.cpp увидит только два GPU, оба быстрых. И будет распределять нагрузку между ними.
А если вы хотите использовать все GPU, но поменять порядок, чтобы быстрые шли первыми? Нельзя. CUDA_VISIBLE_DEVICES только скрывает GPU, но не меняет их порядок. Однако вы можете физически переставить карты в слоты или настроить BIOS.
Как это сделать в запуске llama.cpp:
CUDA_VISIBLE_DEVICES=0,2 ./main -m model.gguf -ngl 100 --tensor-parallel 2Обратите внимание на флаг --tensor-parallel 2 - он указывает, сколько GPU использовать для тензорного параллелизма. Должно совпадать с количеством GPU в CUDA_VISIBLE_DEVICES.
Не путайте --tensor-parallel с --split-mode или --main-gpu. В llama.cpp 2026 года эти флаги могут измениться. Всегда проверяйте ./main --help для актуальной версии.