Qwen3.8–27B на двух RTX 3060 ускорили с 9 до 40 токенов/с

Энтузиаст разогнал локальную Qwen3.8–27B Q4 на двух RTX 3060 12 ГБ с 9 до 39,6 токенов/с в реальной сессии OpenCode при контексте 128K. Ключевым изменением стал переход с распределения по слоям на тензорное распараллеливание в llama.cpp.

Главное
  • На старте Qwen3.8–27B Q4_K_M выдавала около 9–10 токенов/с на длинном контексте 120K
  • Переход с -sm layer на -sm tensor почти удвоил скорость decode на двух GPU без CUDA P2P
  • В контролируемом тесте с ~120K входных токенов получилось 28,16 токенов/с, в реальной сессии OpenCode — 39,6 токенов/с
Две видеокарты RTX 3060 12 ГБ в домашнем сервере на базе платы Z97 и процессора i7–4790
Фото: Хабр: Машинное обучение

Автор статьи на Хабре собрал домашний вычислительный блок для coding-агентов на базе старого ПК: Core i7–4790, 32 ГБ DDR3, материнская плата ASUS Sabertooth Z97 Mark 2 и две RTX 3060 по 12 ГБ. Цель — меньше зависеть от облачных лимитов Codex и Claude Code и не платить за дорогие тарифы. Суммарно в системе 24 ГБ VRAM, но без NVLink и CUDA P2P между картами.

На старте Qwen3.8–27B Q4_K_M от ggml-org работала, но на длинном контексте генерация опускалась до 9–10 токенов/с. На коротком запросе модель выдавала 16,6 токенов/с, на ~65K контекста — 11,35 токенов/с, на ~120K — 8,89 токенов/с. Автор хотел сохранить качественную 27B-модель и большой контекст, а не гнаться за скоростью ценой агрессивной квантизации.

Что дало ускорение

Самым крупным бесплатным ускорением стал переход от распределения модели по слоям к тензорному распараллеливанию: параметр -sm layer заменён на -sm tensor. В режиме layer разные группы слоёв лежат на разных GPU и данные проходят через них последовательно. В режиме tensor вычисления одного слоя делятся между двумя картами, после чего частичные результаты объединяются.

Несмотря на то что между картами PHB-топология, нет прямого CUDA P2P и GPU работают в режиме PCIe 8x, параллельная загрузка двух GPU оказалась выгоднее последовательного распределения по слоям. При autoregressive decode объём пересылаемых активаций сравнительно невелик относительно объёма весов, которые читаются на каждом токене, поэтому выигрыш от параллельной работы двух подсистем VRAM перекрыл накладные расходы меж-GPU обмена.

В контролируемом тесте с ~120K входных токенов получилось 28,16 токенов/с, а в реальной сессии OpenCode — 39,6 токенов/с в среднем по серверным логам. Автор отмечает, что не ставит знак равенства между локальной Qwen и Codex или Claude Code: у облачных моделей выше потолок на сложных многошаговых задачах. Но для большинства его сценариев локальной 27B-модели хватает с запасом.

Отдельный плюс — приватность: модель работает полностью на своём сервере, исходники, промпты и контекст не отправляются стороннему LLM-провайдеру. Это удобно для внутреннего кода, конфигураций и технических логов. Автор оговаривается, что это справедливо только если сама обвязка OpenCode, плагины и подключённые инструменты тоже не настроены отправлять данные наружу.

Для профиТехнические детали: архитектура, цифры, ссылки

Конфигурация теста:

  • CPU: Intel Core i7–4790
  • Материнская плата: ASUS Sabertooth Z97 Mark 2
  • RAM: 32 ГБ DDR3 1600MHz
  • GPU: 2 × NVIDIA GeForce RTX 3060 12 ГБ
  • Связь GPU: PHB, CUDA P2P read/write недоступен
  • ПО: Ubuntu, llama.cpp build 10991 (commit 930e2fa59), Docker tag server-cuda13-b10991

Исходная команда запуска:

docker run --rm --gpus all -p 8080:8080 -v «$HOME/models:/models:ro» ghcr.io/ggml-org/llama.cpp:server-cuda13-b10991 -m /models/Qwen3.8–27B-Q4_K_M.gguf -sm layer --fit on --fit-target 512 -c 131072 -np 1 -fa on -ctk q4_0 -ctv q4_0 --host 0.0.0.0 --port 8080

Ключевое изменение — замена -sm layer на -sm tensor. Модель: Qwen3.8–27B Q4_K_M от ggml-org, полный серверный контекст 131 072 токена, Flash Attention, Q4 KV-cache. Автор предупреждает: конфигурация может успешно стартовать с 128K KV-cache, а затем упасть с CUDA OOM при реальном заполнении (prefill).

Вопросы и ответы

Какое железо нужно для запуска Qwen3.8–27B локально?
В статье использовались две RTX 3060 по 12 ГБ (24 ГБ VRAM суммарно), Core i7–4790, 32 ГБ DDR3 и материнская плата ASUS Sabertooth Z97 Mark 2.
Почему tensor split быстрее layer split на двух GPU?
В режиме tensor вычисления одного слоя делятся между картами, и параллельная загрузка двух подсистем VRAM перекрывает накладные расходы меж-GPU обмена при autoregressive decode.
Какая скорость генерации получилась в итоге?
В контролируемом тесте с ~120K входных токенов — 28,16 токенов/с, в реальной сессии OpenCode — 39,6 токенов/с в среднем по серверным логам.