Qwen3.8-27B на двух Tesla V100: настройка, 160k контекста и 100 ток/с для кодинга
Локальная Qwen3.8-27B на двух Tesla V100 SXM2 16GB через llama.cpp даёт 160 тыс. токенов контекста, около 100 ток/с генерации кода и 1136 ток/с обработки промпта. Ниже — сборка llama.cpp под Volta (sm_70) с CUDA 12.9 и драйвером 580, деление модели на две видеокарты (tensor split), MTP-спекуляция, выбор KV-кэша и распознавание изображений на CPU. Все цифры измерены на живом сервере.
Результаты: Tesla V100 против Tesla M40
До V100 на том же сервере стояли две Tesla M40 12GB. После замены контекст вырос с 96 до 160 тыс. токенов, генерация ускорилась в 3–5 раз, а обработка промпта — в 9 раз (квант модели тот же, UD-Q4_K_M).
Модель обслуживает агента для программирования. Для агента важны три вещи: длинный контекст (история сессии с кодом легко занимает 60–100 тыс. токенов), быстрая обработка промпта (её платим при каждом сбросе кэша) и скорость генерации.
2× M40 12GB | 2× V100 16GB | Разница | |
Контекст, токенов | 98 304 | 163 840 | ×1,7 |
Генерация, короткий контекст, ток/с | 20–22 | код ~101, JSON ~119, текст ~64 | ×3–5 |
Генерация на полном контексте, ток/с | — | 45–52 | |
Обработка промпта ~5 тыс. токенов, ток/с | 125 | 1136 | ×9,1 |
Среднее заполнение всего контекста, ток/с | — | 580 | |
Изображения | нет | да, кодирование на CPU |
Дальше по шагам: железо, сборка, запуск, подбор параметров, температура, изображения и эксплуатация. В конце — что попробовали и отбросили.
Конфигурация сервера с двумя Tesla V100
Стенд — двухсокетный сервер на Xeon E5-2680 v4 (2×14 ядер, 56 потоков) с 125 GB RAM. Карты стоят в слотах разных сокетов, обе на PCIe Gen3 x16.
Параметр | Значение |
GPU | 2× Tesla V100-SXM2-16GB (10de:1db1) |
Слоты | 0000:02:00.0 (NUMA0) и 0000:81:00.0 (NUMA1) |
Связь между картами | через QPI между сокетами (P2P типа SYS), NVLink нет |
Лимит мощности / макс. частота SM | 300 Вт / 1530 МГц |
Драйвер | 580.178.04, CUDA 12.9 |
ECC | включён |
ECC оставили включённым. На M40 с GDDR5 ECC съедает часть памяти, и там его выключение давало контекст. У V100 память HBM2, и ECC объёма не занимает: 16384 MiB доступны и с ним. Выигрыша от выключения нет, а защита от ошибок памяти на старых картах полезна.
Сборка llama.cpp для Tesla V100: sm_70 и CUDA 12.9
Исходники те же: llama.cpp на коммите 620d2225, CUDA 12.9 — последняя версия, которая ещё собирает под sm_70 (nvcc предупреждает, что поддержку уберут).
Архитектура — CMAKE_CUDA_ARCHITECTURES=70-real: только машинный код для sm_70, без PTX. Сборка быстрее, бинарники меньше.
Драйвер и CUDA. Стоит драйвер 580.178.04: ветка R580 — последняя с поддержкой Volta. Его ставят с --dkms --kernel-module-type=proprietary: открытые модули, которые R580 выбирает по умолчанию, работают только с Turing и новее. CUDA 12.9 взята из redist-архивов: nvcc, cudart, cccl и cuBLAS 12.9.1.4 без статических библиотек, всего 1,2 GB.
Запуск llama-server на двух GPU: tensor split
Модель делится поровну между картами в режиме tensor split: каждая держит половину каждого слоя, и обе считают одновременно. На M40 мы сравнивали его с делением по слоям, и там tensor выиграл; на V100 оставили его же, даже несмотря на обмен через QPI.
Итоговая команда, которую собирает лаунчер (важные флаги):
CUDA_DEVICE_ORDER=PCI_BUS_ID CUDA_VISIBLE_DEVICES=0,1 llama-server \
--model Qwen3.8-27B-UD-Q4_K_M.gguf --ctx-size 163840 --gpu-layers 99 \
--split-mode tensor --tensor-split 1,1 \
--batch-size 1024 --ubatch-size 1024 --flash-attn on \
--cache-type-k f16 --cache-type-v f16 \
--spec-type draft-mtp --spec-draft-n-max 4 --spec-draft-p-min 0.0 \
--threads 10 --threads-batch 20 --jinja \
--mmproj mmproj-F16.gguf --no-mmproj-offload --image-max-tokens 1024 \
--cache-ram 40960 --slot-save-path slot-cache \
--host 127.0.0.1 --port 8080 --parallel 1 --alias qwen3.8-27b
MTP-спекуляция (draft-mtp) использует встроенные в Qwen3.8 головы предсказания нескольких токенов — отдельная модель-черновик не нужна. На коде принимается ~80% черновика, на JSON ~98%, на обычном тексте ~40%.
--cache-ram 40960 — 40 GB оперативки под кэш промптов: повторный запрос с тем же началом не пересчитывается.
--slot-save-path позволяет сохранить KV-кэш сессии на диск перед перезапуском и вернуть после.
Сервер слушает только localhost.
Лаунчер — Python-скрипт с чтением флагов из переменных окружения (QWEN_CTX, QWEN_KV, QWEN_UB, QWEN_DRAFT, QWEN_MMPROJ). Перед запуском он без GPU проверяет слоты PCI, версию драйвера и файлы рантайма (каталог рантайма задаёт QWEN_RUNTIME); всё найденное пишет в JSON-отчёт со списком препятствий. Над ним тонкая обёртка v100_start.sh с профилем по умолчанию; любой параметр переопределяется переменной.
Оптимизация: MTP, KV-кэш и размер контекста
Лучший профиль — 160k контекста, KV-кэш в f16, ubatch 1024 и черновик MTP длиной 4. Всё подбирали прогонами на живом сервере: короткие задачи (код, JSON, текст), генерация после промпта в 99 тыс. токенов и полное заполнение контекста с «иглой» — словом в середине, которое модель должна найти.
Длина черновика MTP. Чем предсказуемее текст, тем длиннее выгодный черновик: JSON растёт до 5, код выходит на плато к 4, обычный текст лучше всего при 2. Агент в основном пишет код и вызовы инструментов, поэтому взяли 4. Длина 5 ещё и добавляет памяти: на 256k пик дошёл до 16 088 из 16 384 MiB.
Замеры на стенде · профиль 256k, KV q8_0, ubatch 1024 · среднее двух запросов на тип
KV-кэш: f16 быстрее q8_0. На V100 квантованный KV-кэш экономит память, но тормозит генерацию на длинном контексте. Генерация кода после промпта в 99 тыс. токенов, ток/с:
Черновик MTP | KV q8_0 | KV f16 |
2 | 55,3 | 63,2 |
4 | 61,0 | 69,7 |
f16 вместе с черновиком 4 дали +26% к исходной комбинации. Цена — контекст: в f16 влезает 160k, в q8_0 — 256k.
160k или 256k. Оба профиля проверены полным заполнением, игла найдена в обоих.
Профиль | Средняя обработка промпта, ток/с | Генерация на полном контексте, ток/с | Пик памяти на карту, MiB |
160k, KV f16, черновик 4 | 580 | 45–50 | 15 234 |
256k, KV q8_0, черновик 2 | 437 | 27 | 15 868 |
256k вдвое медленнее на конце контекста, а агент до него редко доходит: сжатие истории срабатывает раньше. По умолчанию стоит 160k, а 256k включается одной строкой: QWEN_KV=q8_0 QWEN_DRAFT=2 sh v100_start.sh 262144.
ubatch 1024. Вдвое больше исходных 512: промпт считается крупнее. 2048 на 256k не помещается даже при запуске (нехватка памяти CUDA).
Температура и частоты Tesla V100 под нагрузкой
Под постоянной нагрузкой (короткие задачи и заполнение 32 и 160 тыс. токенов) обе карты держат полную частоту SM 1530 МГц. Температура в среднем 74 и 78 °C, максимум 77 и 81 °C, мощность около 233 Вт на карту.
Пороги V100 SXM2: 83 °C — верхняя граница рабочей температуры, с 87 °C карта сама снижает частоты, на 90 °C выключается.
Распознавание изображений: mmproj на CPU
Модель понимает картинки без потери контекста и скорости текста: визуальный модуль работает на процессоре. До этого сервер запускался с --no-mmproj, и на скриншот отвечал ошибкой 500 «image input is not supported».
Модуль — mmproj-F16.gguf (885 MiB, проектор qwen3vl_merger) из того же репозитория и ревизии, что и модель. Версия F16, а не BF16: у V100 нет аппаратной поддержки BF16.
На GPU модуль не влезал. При 160k с KV f16 в пике на карте свободно ~1,1 GB, а модулю нужны ещё и буферы под картинку. Вариантов было два: снизить контекст до 128k или кодировать картинки на CPU (--no-mmproj-offload). Выбрали CPU и ограничили картинку 1024 токенами (--image-max-tokens), чтобы большой скриншот не кодировался минутами.
Замер | Результат |
Картинка 640×480 | 335 токенов, ~5 с |
Картинка 1920×1080 | 1043 токена, ~19 с |
Повтор той же картинки | промпт берётся из кэша, заново считаются 4 токена |
Память GPU в простое после картинок | 15 248 MiB (было 14 830) |
Пик на полном заполнении 160k | 15 250 MiB (было 15 234) |
Скорость текста | без изменений |
На тестовой картинке модель верно назвала фигуры и цвета и дословно переписала кириллический текст. Перенести модуль на GPU можно переменной QWEN_MMPROJ=gpu, с контекстом 128k.
Что не подошло и выводы
Вариант | Почему нет |
Квант Q5_K_M вместо Q4_K_M | 18,4 GiB вместо 15,3 GiB: +1,5 GiB на карту, пришлось бы урезать контекст до ~112k или перейти на KV q8_0; не пробовали |
ubatch 2048 на 256k | нехватка памяти CUDA уже при запуске |
Черновик MTP 5 на 256k | пик 16 088 из 16 384 MiB — слишком близко к пределу |
Модуль изображений на GPU | только ценой контекста 128k; оставили на CPU |
Отключение ECC | на HBM2 памяти не добавляет |
Больше всего дали KV-кэш в f16 и черновик MTP длиной 4: +26% к генерации на длинном контексте по сравнению с исходными q8_0 и черновиком 2.
Частые вопросы
Сколько видеопамяти нужно для Qwen3.8-27B?
Квант UD-Q4_K_M весит 15,3 GiB, поэтому в одну карту на 16 GB вместе с контекстом он не помещается. На двух V100 по 16 GB с контекстом 160k и KV-кэшем f16 пик — 15 234 MiB на карту.
Какой драйвер NVIDIA и какая CUDA нужны для Tesla V100?
Драйвер из ветки R580, например 580.178.04: это последняя ветка с поддержкой Volta. Ставить нужно проприетарные модули ядра: открытые работают только с Turing и новее. Собирать llama.cpp — CUDA 12.9, последней версией с компиляцией под sm_70.
Какая скорость у Qwen3.8-27B на двух V100?
На коротком контексте около 101 ток/с на коде, 119 на JSON и 64 на обычном тексте. После заполнения всех 160k — 45–52 ток/с. Промпт в 5 тыс. токенов считается со скоростью 1136 ток/с, весь контекст — в среднем 580 ток/с.
Нужен ли NVLink для двух V100?
Нет. В нашем сервере карты стоят в слотах разных сокетов и обмениваются через QPI, а все цифры статьи получены именно так, в режиме tensor split.
Какой KV-кэш выбрать на V100: f16 или q8_0?
f16, если хватает 160k контекста: после промпта в 99 тыс. токенов он даёт 69,7 ток/с против 61,0 у q8_0. q8_0 нужен для 256k: в f16 такой контекст не помещается.
Какую длину черновика MTP поставить?
Для кода — 4: дальше скорость не растёт. JSON ускоряется до длины 5, а обычный текст быстрее всего при 2.
Можно ли получить 256k контекста?
Да, с KV-кэшем q8_0 и черновиком MTP 2: пик 15 868 MiB на карту. Но в конце контекста генерация падает до 27 ток/с, примерно вдвое ниже, чем у профиля 160k.
Как добавить распознавание изображений без потери контекста?
Запускать модуль mmproj-F16.gguf на процессоре флагом --no-mmproj-offload и ограничить картинку через --image-max-tokens 1024. Картинка 640×480 обрабатывается за ~5 с, 1920×1080 — за ~19 с, контекст и скорость текста не меняются.
Нужно ли отключать ECC на V100?
Нет. Память HBM2 не тратит объём на ECC, 16 384 MiB доступны и с ним, а защита от ошибок памяти на старых картах полезна.
Почему mmproj в F16, а не в BF16?
У Tesla V100 нет аппаратной поддержки BF16, а F16 она считает нативно.
Комментарии
Загрузка комментариев…