Перейти к содержанию
Публикация AiManual

RTX 5090 Laptop на Linux и Xid 8: почему llama.cpp вешает GPU и как помогает GGML_CUDA_DISABLE_GRAPHS=1

Зависания GPU с NVIDIA Xid 8 на RTX 5090 Laptop под Linux при запуске локальных LLM: почему llama.cpp спотыкается на CUDA graphs, как проверить это у себя, что

Коротко

Что будет в материале

  1. 01

    В чём проблема: Xid 8 на RTX 5090 Laptop при запуске локальных LLM

  2. 02

    Что такое NVIDIA Xid 8 и при чём тут CUDA graphs в llama.cpp

  3. 03

    Как воспроизвести зависание и проверить обходной путь GGML_CUDA_DISABLE_GRAPHS=1

  4. 04

    Чем платим за воркэраунд: что отключение CUDA graphs делает с производительностью

В чём проблема: Xid 8 на RTX 5090 Laptop при запуске локальных LLM

На Lenovo Legion с RTX 5090 Laptop (24 ГБ VRAM) под Linux Mint запуск локальных LLM приводит к зависанию GPU, и в логах NVIDIA появляется Xid 8. В трекере llama.cpp автор нашёл прямо релевантный issue: зависание при вычислении CUDA graphs и Xid 8 на RTX 5090 Laptop GPU под Linux (исходное сообщение с конфигурацией и симптомами).

Рабочее действие из этого issue: запускать llama.cpp с переменной окружения GGML_CUDA_DISABLE_GRAPHS=1. Она отключает CUDA graphs в бэкенде ggml, и зависания прекращаются. Цена известна заранее: производительность падает. Насколько именно, в источнике не сказано, поэтому цифры придётся снимать самому на своей модели и своём сценарии.

Исправления на момент публикации сообщения нет. Автор прямо пишет, что баг не чинят, а единственный обход замедляет работу. Всё сказанное ниже опирается на одно сообщение пользователя и упомянутый issue llama.cpp: независимого подтверждения, деталей от NVIDIA и сроков фикса в материалах нет.

Что такое NVIDIA Xid 8 и при чём тут CUDA graphs в llama.cpp

Xid - код, которым драйвер NVIDIA сообщает о сбое на стороне GPU. Сообщение уходит в лог ядра, поэтому его видно в dmesg и journalctl. Номер кода задаёт класс сбоя; в описанном случае Xid 8 появляется вместе с зависанием при работе с локальными LLM. Точное официальное толкование конкретного кода сверяйте с документацией NVIDIA под свою версию драйвера: в источнике такого разбора нет.

CUDA graphs - механизм CUDA, который позволяет один раз записать последовательность операций на GPU и дальше запускать её как единое целое. Экономия идёт на накладных расходах: каждый отдельный запуск ядра стоит времени CPU, а в инференсе LLM такие запуски идут сотнями на каждый токен. В llama.cpp графы применяются в CUDA-бэкенде ggml именно для этого. Как CUDA graph снимает часть накладных расходов при генерации, разбирали отдельно.

В описанном баге зависание происходит на этапе вычисления CUDA graphs. Отключение графов убирает этот этап из работы, и сбой перестаёт воспроизводиться.

Почему сбой в CUDA graphs выглядит как зависание, а не как ошибка приложения

Ошибка приложения выглядит как исключение или ненулевой код возврата. Сбой на уровне GPU выглядит иначе. Драйвер фиксирует проблему и пишет Xid, а процесс llama.cpp продолжает ждать операцию, которая уже не завершится: состояние устройства не определено, синхронизация не приходит. Снаружи это замерший вывод и загрузка без прогресса.

Практический вывод: искать причину нужно в логе ядра, а не в выводе llama.cpp. Оговорка по границам: это объяснение для описанного случая, а не универсальная трактовка любого Xid 8 на любой системе.

Как воспроизвести зависание и проверить обходной путь GGML_CUDA_DISABLE_GRAPHS=1

Проверка строится на сравнении двух запусков одного и того же сценария: с графами и без. Порядок:

  1. Запишите конфигурацию: Lenovo Legion, RTX 5090 Laptop с 24 ГБ VRAM, Linux Mint, ядро 7.1.13 с добавленными аудиодрайверами, драйвер NVIDIA 595.99.02. Без этой записи потом сложно понять, что именно изменилось.

  2. Запустите локальную LLM через llama.cpp с теми параметрами, на которых стабильно ловится зависание: та же модель, тот же квант, та же длина контекста.

  3. После зависания посмотрите лог ядра. Xid пишет драйвер NVIDIA, поэтому смотреть надо туда, а не в консоль приложения:

    dmesg | grep -i xid
    journalctl -k | grep -i xid
  4. Повторите тот же сценарий с отключёнными графами.

  5. Сравните поведение и скорость. Если без переменной зависание и Xid 8 возвращаются, а с ней нет, связь с CUDA graphs подтверждается.

Такая пара запусков проверяет воркэраунд, а не доказывает исправление причины.

Как выставить GGML_CUDA_DISABLE_GRAPHS=1 для llama.cpp

Это переменная окружения процесса llama.cpp, а не глобальная настройка системы. Проще всего экспортировать её в шелле перед запуском:

export GGML_CUDA_DISABLE_GRAPHS=1
./llama-cli -m путь/к/модели.gguf -p "тестовый запрос"

То же самое одной строкой, без экспорта:

GGML_CUDA_DISABLE_GRAPHS=1 ./llama-cli -m путь/к/модели.gguf -p "тестовый запрос"

Если llama.cpp запускается сервером или из скрипта, прописывайте переменную там же, где заданы остальные параметры запуска. В systemd-юните это строка Environment=GGML_CUDA_DISABLE_GRAPHS=1 в секции [Service]. Отдельных флагов командной строки для этого переключателя не нужно: хватает переменной окружения, и она действует только на запущенный процесс.

Как убедиться, что дело именно в CUDA graphs

Ключевой признак: воспроизводимость по переключателю. Сняли переменную, зависание и Xid 8 вернулись на том же сценарии; выставили обратно, работа пошла. Такой A/B-тест указывает на CUDA graphs, как в упомянутом issue.

Остальные причины он не исключает. При повторяющихся Xid 8 смотрите температуру и питание, версию драйвера, целостность файла модели и настройки оффлоада слоёв. В похожем разборе на другой модели показывали, как отделять проблему конфигурации llama.cpp от ограничений железа.

Чем платим за воркэраунд: что отключение CUDA graphs делает с производительностью

В источнике зафиксирован сам факт падения производительности, без чисел. Придумывать проценты смысла нет: на разных моделях и разных длинах контекста разница будет своей.

Механика потерь понятна из назначения графов. CUDA graphs экономят на накладных расходах при большом числе мелких операций. Отключение бьёт сильнее там, где этих операций много на единицу полезной работы:

  • генерация токенов по одному, где на каждый шаг приходится много коротких ядер;
  • небольшие модели и короткие промпты, где время на запуск ядер заметно на фоне самого вычисления;
  • сценарии с высоким tok/s, где оверхед успевает накопиться.

На длинном prefill с крупными матричными операциями относительные потери обычно меньше, но проверять надо на своём сценарии. Способ простой: одна модель, одинаковые параметры, прогрев и несколько прогонов с переменной и без. llama.cpp печатает тайминги генерации по завершении работы, по ним и сравнивайте. Разница между прогонами без прогрева легко превышает эффект от самого переключателя.

Вывод по цене: это компромисс, стабильность в обмен на скорость. Для интерактивной работы с моделями на 24 ГБ VRAM такой обмен обычно приемлем, для пакетных задач на скорость стоит посчитать заранее.

Ядро 7.1.13 и драйвер NVIDIA 595.99.02: почему конфигурация автора важна

Автор сообщения работает на ядре 7.1.13 с добавленными аудиодрайверами и на драйвере NVIDIA 595.99.02. Ядро 7.2 у него не запустилось: драйверы NVIDIA не завелись, и более новые версии драйвера тоже не заработали (детали конфигурации в исходном сообщении).

Отсюда два следствия. Первое: поведение бага и воркэраунда подтверждено только на этой связке, и переносить выводы на другие версии ядра и драйвера без проверки нельзя. Второе: версии из сообщения не стоит копировать как рецепт. У другой системы с другим железом и другим набором модулей совместимость может сложиться иначе, а откат на старую связку ядро-драйвер иногда стоит больше времени, чем экономит.

Статус исправления и что делать, пока фикса нет

На момент публикации сообщения исправления нет. Баг описан в issue llama.cpp, сроков никто не называет. Обещать скорый фикс не будем: в материалах нет ни версии с исправлением, ни подтверждения от NVIDIA.

Реалистичные варианты на это время:

  • работать с GGML_CUDA_DISABLE_GRAPHS=1 и принять падение скорости;
  • следить за issue llama.cpp и за обновлениями драйвера NVIDIA;
  • при экспериментах с новым ядром или драйвером заранее держать рабочий откат: старую версию ядра, пакет драйвера, снапшот системы;
  • для задач, где важна максимальная скорость, проверить альтернативный бэкенд или другую сборку, но только с замером на своём сценарии.

CUDA-путь llama.cpp меняется быстро: появляются новые оптимизации и pull request'ы, которые тоже влияют на стабильность и скорость. Пример такой работы, разреженный Flash Attention для Qwen4 на CUDA, разбирали отдельно. Перед обновлением сборки полезно смотреть, что именно поменялось в CUDA-бэкенде.

Воркэраунд не лечит причину. Он убирает этап, на котором происходит сбой, поэтому после обновления драйвера проблему стоит перепроверить: исчезла ли она без переменной.

Ограничения материала и что важно не перепутать

Сводка того, где заканчиваются факты:

  • основа - одно сообщение пользователя и упомянутый в нём issue llama.cpp; независимого подтверждения и деталей исправления нет;
  • падение производительности от воркэраунда подтверждено качественно, без цифр;
  • версии ядра 7.1.13 и драйвера 595.99.02 - конфигурация автора, а не рекомендация;
  • Xid 8 в других условиях может иметь другие причины, и этот разбор не универсальный рецепт для всех зависаний GPU на Linux.

Если у вас воспроизводится та же картина на RTX 5090 Laptop, самый быстрый шаг: прогнать сценарий дважды, с переменной и без, и записать результат в dmesg. Такая пара запусков даёт больше, чем любая теория о том, кто виноват: драйвер, ядро или конкретная сборка llama.cpp.

Подписаться на канал