На текущий момент qwen3.8-27b, без сомнений, лучшая модель для программирования, которую можно запускать на потребительских видеокартах. К сожалению, прямой путь - скачать модель с официального аккаунта qwen на huggingface -> запустить в своем любимом инференс-движке может не привести к хорошему результату, поэтому я решил написать эту статью.

План действий такой:

  1. Установить необходимые пакеты для сборки llamAmpere (https://github.com/JakeATX/llamAmpere) - это форк llama.cpp, оптимизированный для запуска на поколении графических адаптеров Ampere.

  2. Скомпилировать llamAmpere.

  3. Установить huggingface client.

  4. Скачать модель и отдельно исправленный chat template.

  5. Запустить инференс-движок с нашей моделью.

  6. Настроить агент (покажу на примере claude-code).

Подготовка зависимостей

Для начала нужна cuda. В README к llamAmpere указано, что они тестировали на cuda версии 12.4; у меня стоит 13.1, и тоже всё работает. Так что просто установите самый полный набор для разработки средствами вашего дистрибутива.

Далее нужны cmake и gcc не слишком высокой версии, крайне желательно не выше 14. В Fedora 44 нужно поставить дополнительно к системному gcc версии 16 пакеты gcc15 и gcc15-c++.

Фиксим заголовочный файл из cuda для gcc-15

Необходимо пропатчить файл /usr/local/cuda-13.1/targets/x86_64-linux/include/crt/math_functions.h. Вот патч: math_functions.patch

И еще текстом, на всякий случай:

--- math_functions.h.orig	2026-10-08 16:54:22.188939419 +0300
+++ math_functions.h	2026-10-08 16:25:45.772064018 +0300
@@ -626,7 +626,7 @@ extern __DEVICE_FUNCTIONS_DECL__ __devic
  *
  * \note_accuracy_double
  */
-extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ double                 rsqrt(double x);
+extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ double                 rsqrt(double x) noexcept(true);
 
 /**
  * \ingroup CUDA_MATH_SINGLE
@@ -650,7 +650,7 @@ extern __DEVICE_FUNCTIONS_DECL__ __devic
  *
  * \note_accuracy_single
  */
-extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ float                  rsqrtf(float x);
+extern __DEVICE_FUNCTIONS_DECL__ __device_builtin__ float                  rsqrtf(float x) noexcept(true);
 
 #if defined(__QNX__) && !defined(_LIBCPP_VERSION)
 namespace std {
@@ -6043,7 +6043,7 @@ inline __device__ void *__nv_aligned_dev
 
 #endif /* _WIN32 */
 
-__func__(double rsqrt(double a));
+__func__(double rsqrt(double a) noexcept(true));
 
 __func__(double rcbrt(double a));
 
@@ -6069,7 +6069,7 @@ __func__(double normcdf(double a));
 
 __func__(double erfcx(double a));
 
-__func__(float rsqrtf(float a));
+__func__(float rsqrtf(float a) noexcept(true));
 
 __func__(float rcbrtf(float a));
 

Сборка llamAmpere

Компилируем таким образом:

export NVCC_CCBIN='g++-15' # Только для fedora-44!
git clone https://github.com/JakeATX/llamAmpere.git
cd llamAmpere
cmake -S . -B build-sm86 -DCMAKE_BUILD_TYPE=Release -DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=86
cmake --build build-sm86 -j8 --target llama-server

Если всё прошло успешно то нужный исполняемый файл будет build-sm86/bin/llama-server.

Установка клиента huggingface

Ничего нестандартного тут не могу сказать, команда hf нам нужна только для того, чтобы скачать модель, можно ставить любым способом. Либо через pip:

pip install -U "huggingface_hub[cli]"

Либо через uv:

uv tool install huggingface_hub

Либо установочным скриптом:

curl -LsSf https://hf.co/cli/install.sh | sh

Далее для более высокой скорости скачивания нужно зарегистрироваться на huggingface, сделать там себе токен и записать его в переменную окружения:

export HF_TOKEN=XXXXXX

Скачиваем файлы

Для начала модель, она занимает 15 Гбайт:

hf download jakeatx/Qwen3.8-27B-ATX-IQ4_XS-M-GGUF  --local-dir $HOME/models/qwen3.8-27b-gguf/

С дефолтным chat_template из модели у меня claude-code не захотел работать, вот тут есть исправленные - https://huggingface.co/froggeric/Qwen-Fixed-Chat-Templates. Нам нужно скачать вот этот файл: https://huggingface.co/froggeric/Qwen-Fixed-Chat-Templates/resolve/main/chat_template.jinja

Запускаем

./build-sm86/bin/llama-server \
        --ctx-size 245760 \
        --batch-size 4096 \
        --ubatch-size 1024 \
        --threads 8 \
        --threads-batch 8 \
        --n-gpu-layers 99 \
        --flash-attn on \
        --cache-type-k turbo5 \
        --cache-type-v turbo4 \
        --parallel 1 \
        --jinja \
        --spec-type draft-mtp \
        --spec-draft-n-max 4 \
        --spec-draft-p-min 0 \
        --spec-draft-vocab-map auto \
        --model $HOME/models/qwen3.8-27b-gguf/Qwen3.8-27B-ATX-4-XS.gguf \
        --chat-template-file $HOME/models/chat_template.jinja \
        --host 0.0.0.0 \
        --port 8089 \
        --alias qwen3.8 \
        --reasoning-format deepseek

Если будете использовать только локально надо убрать параметр --host 0.0.0.0. Также можно немного поменять размер контекста, вместо 245760 поставить чуть больше, если изображение у вас выводится через отдельную видеокарту, либо чуть меньше, если хотите оставить больше видеопамяти для приложений. В указанном варианте потребляется 20834 Мбайт.

Настройка claude-code

Вот мой скрипт для запуска claude-code:

#!/bin/bash

CLAUDE_CODE_CONTEXT_LIMIT=245760 \
AI_LOG_ENDPOINT="" \
ANTHROPIC_BASE_URL="http://localhost:8089/" \
ANTHROPIC_AUTH_TOKEN="default" \
ANTHROPIC_CUSTOM_HEADERS="Plugin-Type: claude-code" \
API_TIMEOUT_MS=600000 \
ANTHROPIC_MODEL="qwen3.8" \
ANTHROPIC_SMALL_FAST_MODEL="qwen3.8" \
CLAUDE_CODE_SUBAGENT_MODEL="qwen3.8" \
ANTHROPIC_DEFAULT_SONNET_MODEL="qwen3.8" \
ANTHROPIC_DEFAULT_OPUS_MODEL="qwen3.8" \
ANTHROPIC_DEFAULT_HAIKU_MODEL="qwen3.8" \
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 \
CLAUDE_CODE_LOG_LEVEL=debug \
ENABLE_LSP_TOOL=1 \
command claude "$@"

Если что-то меняли в строке запуска llamAmpere, то тут надо поправить соответственно размер контекста, адрес сервера или имя модели.

Тестирование

Для проверки скорости использовал самописный скрипт, который проверяет скорость с коротким промптом в 35 токенов и с длинным в 100000 токенов. Вот этот скрипт.

Сравнил с оригинальной llama.cpp, в ней нет типов turbo5 и turbo4, так что для kv-кеша использовал q8_0 и q4_0.

Числа указаны в токенах/с, время изменялось с момента отправки запроса, e2e.

35 токенов

100K токенов

llamAmpere

68.8

58.9

llama.cpp

58.3

47.0

Полный отчет о тестировании

llamAmpere

Модель: qwen3.8 | runs=3 | max_tokens=2048 | temperature=0.0
Base URL: http://localhost:8089/v1
Long-промпт: ~100,480 токенов на запрос; на весь прогон (warmup + 3 runs) уйдёт ~401,920 входных токенов — учтите стоимость и лимит контекста модели.

=== Промпт: short (вход ~35 токенов, ~161 симв., max_tokens=2048) ===
  warmup (не учитывается)...
  # |   TTFT, с |  всего, с |  токены |  tok/s дек |  tok/s e2e
  1 |      2.72 |     20.40 |   1401 |       79.2 |       68.7
  2 |      2.63 |     20.34 |   1401 |       79.1 |       68.9
  3 |      2.63 |     20.39 |   1401 |       78.9 |       68.7
     среднее: TTFT 2.66 с | всего 20.37 с | декод 79.1 tok/s | e2e 68.8 tok/s
     медиана: TTFT 2.63 с | декод 79.1 tok/s

=== Промпт: long (вход ~100,480 токенов, ~512,089 симв., max_tokens=2048) ===
  warmup (не учитывается)...
  # |   TTFT, с |  всего, с |  токены |  tok/s дек |  tok/s e2e
  1 |      4.98 |     30.28 |   1784 |       70.5 |       58.9
  2 |      5.01 |     30.32 |   1784 |       70.5 |       58.8
  3 |      5.01 |     30.30 |   1784 |       70.5 |       58.9
     среднее: TTFT 5.00 с | всего 30.30 с | декод 70.5 tok/s | e2e 58.9 tok/s
     медиана: TTFT 5.01 с | декод 70.5 tok/s

Сравнение: TTFT short 2.66 с vs long 5.00 с (разница — цена префилла ~100,480 токенов контекста; после warmup сервер может кэшировать префикс, тогда TTFT повторных запусков занижен); декодирование: 79.1 vs 70.5 tok/s

llama.cpp

Модель: qwen3.8 | runs=3 | max_tokens=2048 | temperature=0.0
Base URL: http://localhost:8089/v1
Long-промпт: ~100,480 токенов на запрос; на весь прогон (warmup + 3 runs) уйдёт ~401,920 входных токенов — учтите стоимость и лимит контекста модели.

=== Промпт: short (вход ~35 токенов, ~161 симв., max_tokens=2048) ===
  warmup (не учитывается)...
  # |   TTFT, с |  всего, с |  токены |  tok/s дек |  tok/s e2e
  1 |      3.25 |     23.82 |   1392 |       67.7 |       58.4
  2 |      3.15 |     23.83 |   1392 |       67.3 |       58.4
  3 |      3.19 |     23.94 |   1392 |       67.1 |       58.2
     среднее: TTFT 3.20 с | всего 23.86 с | декод 67.4 tok/s | e2e 58.3 tok/s
     медиана: TTFT 3.19 с | декод 67.3 tok/s

=== Промпт: long (вход ~100,480 токенов, ~512,089 симв., max_tokens=2048) ===
  warmup (не учитывается)...
  # |   TTFT, с |  всего, с |  токены |  tok/s дек |  tok/s e2e
  1 |      6.63 |     40.29 |   1584 |       47.1 |       39.3
  2 |      6.65 |     40.32 |   1584 |       47.0 |       39.3
  3 |      6.67 |     40.38 |   1584 |       47.0 |       39.2
     среднее: TTFT 6.65 с | всего 40.33 с | декод 47.0 tok/s | e2e 39.3 tok/s
     медиана: TTFT 6.65 с | декод 47.0 tok/s

Сравнение: TTFT short 3.20 с vs long 6.65 с (разница — цена префилла ~100,480 токенов контекста; после warmup сервер может кэшировать префикс, тогда TTFT повторных запусков занижен); декодирование: 67.4 vs 47.0 tok/s

Итоги

В результате получаем полностью работающий claude-code, который вполне достойно анализирует и пишет код, вызывает инструменты и может работать в автономном режиме долгое время без каких-либо зависаний и ошибок. Да, он не такой умный, как Opus, но можно сначала сгенерировать план работы более умной моделью, а реализацию и отладку доверить этому джуну.

Комментарии (6)


  1. tplogin
    14.10.2026 08:46

    Не вижу смысла в таком контексте с таким квантом. Если только для тестов на скорость. Мой опыт показывает, что у этой модели 4-битные кванты очень часто зацикливаются, очень долго рассуждают.


    1. guryanov Автор
      14.10.2026 08:46

      Ну, конкретно эта конфигурация работает вполне достойно, час без зависаний в claude-code точно проработает


  1. netricks
    14.10.2026 08:46

    А с mtp сколько будет?


    1. guryanov Автор
      14.10.2026 08:46

      Так тут же включен MTP


      1. netricks
        14.10.2026 08:46

        Хм... Тогда измеренный рейт llama.cpp как-то низковат. Впрочем, это я по памяти. Может быть, что неверно помню


  1. evgkul
    14.10.2026 08:46

    Не хватает скорости prefill (сколько токенов в секунду нейронка читает), у llama.cpp по сравнению с другими движками (VLLM, TabbyAPI (сервер для нейронок в формате EXL3)) с этим не очень хорошо