Инструменты пользователя

Инструменты сайта


truenas:application:llamacpp_moe_ssd

llama.cpp: большие MoE-модели с NVMe + RAM на TrueNAS (Docker, Custom App)

Введение

Инструкция описывает, как на сервере TrueNAS запустить большую MoE-модель (Qwen3.8-Flash-Next, 80–190 GB), которая не помещается целиком в RAM+VRAM: веса лежат на NVMe-накопителе, горячая часть держится в оперативной памяти и в кэше на видеокарте. Движок — llama.cpp (llama-server, OpenAI-совместимый API), запуск — Docker-приложение через веб-интерфейс TrueNAS.

Главное отличие от Strata на TrueNAS: llama.cpp работает на текущем драйвере NVIDIA 550 (проверено на сервере), обновлять TrueNAS не нужно, и модель не «закрепляет» RAM — память, занятая под веса, отдаётся другим приложениям по требованию.

Статус инструкции. На сервере проверено: образ llama.cpp запускается и видит GPU на драйвере 550.142, поддерживает архитектуру модели (qwen4exp) и нужные ключи. Сама модель на сервере ещё не запускалась, скорость не замерялась — такие места помечены (проверить).

Почему это работает

Qwen3.8-Flash-Next — модель Mixture-of-Experts (данные из заголовка GGUF):

Параметр Значение
Архитектура qwen4exp
Слоёв 48
Экспертов в слое 512, из них на каждый токен работают только 10
Контекст до 262 144 токенов

На каждый токен читается лишь малая часть весов (~2% экспертов). Поэтому:

  • общие веса (внимание, эмбеддинги) и KV-кэш — на GPU;
  • эксперты — в файле на NVMe, отображённом в память (mmap): Linux сам держит в RAM часто нужные страницы и дочитывает остальное с диска;
  • самые горячие эксперты — дополнительно в GPU-кэше (–moe-cache-mib).

Чем больше модель превышает свободную RAM, тем чаще чтения с NVMe и тем медленнее генерация — но запускается и работает.

Какие движки умеют NVMe + RAM и что подходит этому серверу

Движок Как использует SSD На этом сервере
llama.cpp (llama-server) mmap весов + эксперты MoE в RAM (–cpu-moe) + GPU-кэш экспертов (–moe-cache-mib); режим Direct I/O (-lm dio) работает сейчас (драйвер 550, проверено) — эта инструкция
Strata свой движок, часть экспертов в RAM, остальное с диска; на ПК — самый быстрый вариант только после обновления до TrueNAS 25.10.7+ (нужен драйвер 580), закрепляет RAM — отдельная инструкция
Ollama (уже стоит на сервере) внутри llama.cpp, mmap проще, но меньше контроля над выгрузкой экспертов; поддержка qwen4exp (проверить)
SGLang «SSD Expert Pack» эксперты на NVMe, Direct I/O, GPU-кэш; для гигантских моделей (DeepSeek-V4-Flash, Kimi-K3) (проверить) — вероятно, нужен более новый драйвер; см. блог LMSYS, 2026-08

Сервер

Параметр Значение
Система TrueNAS SCALE 25.04.2.6, драйвер NVIDIA 550.142
CPU Intel Core i5-14500 (6 P-ядер + 8 E-ядер, 20 потоков)
RAM 62 GB
GPU RTX 2000 Ada, 16 GB
NVMe пул appData — 2 × Samsung 990 PRO 4 TB, /mnt/appData

Проверка образа на сервере:

$ docker run --rm --gpus all ghcr.io/ggml-org/llama.cpp:server-cuda --version
version: 0.9.0-dev (build 12316, commit 5d4c8eeb2)
$ docker run --rm --gpus all ghcr.io/ggml-org/llama.cpp:server-cuda --list-devices
Available devices:
  CUDA0: NVIDIA RTX 2000 Ada Generation (16075 MiB, 4178 MiB free)

4178 MiB free — остальную видеопамять в этот момент держали другие приложения (см. «Шаг 1»). Образ (4.4 GB) уже скачан на сервер.

Шаг 1: Освободить видеокарту

На GPU сервера уже работают Ollama, Whisper, LibreTranslate, XTTS/VoxCPM — вместе ~12 из 16 GB. Для модели нужно хотя бы 8–10 GB свободных (общие веса + KV-кэш + кэш экспертов). На время работы остановите GPU-приложения: Apps → Installed → (приложение) → Stop. В первую очередь ollama — она держит загруженные модели в VRAM.

nvidia-smi --query-gpu=memory.used,memory.total --format=csv

Остальные приложения (Nextcloud, Jellyfin и т.д.) можно не останавливать: память под веса модели — это кэш страниц Linux, он вытесняется, когда памяти не хватает. Чем больше свободной RAM, тем быстрее генерация.

Шаг 2: Датасет для моделей на NVMe

Datasets → appData → Add Dataset:

  • Name: llm-models
  • Dataset Preset: Generic
  • Advanced Options:
    • Record Size: 1M (большие файлы читаются крупными блоками)
    • Compression: OFF (GGUF почти не сжимается)
    • ATime: Off
  • Save.

Путь: /mnt/appData/llm-models. Места — с запасом под модели (на пуле ~3.3 TB свободно).

Кэш ZFS (ARC) и mmap. Файл модели, читаемый через mmap, на ZFS кэшируется дважды: в ARC и в кэше страниц Linux — RAM тратится впустую. Рекомендуется для этого датасета отключить кэширование данных в ARC (останутся только метаданные) — в System → Shell под root (sudo -i):

zfs set primarycache=metadata appData/llm-models
zfs get primarycache,recordsize,compression appData/llm-models

(проверить) влияние на скорость: сравните tokens/s до и после (см. «Шаг 7»). Вернуть: zfs set primarycache=all appData/llm-models.

Шаг 3: Выбор модели

Все варианты — Qwen3.8-Flash-Next в GGUF. «Свободно RAM» на сервере: ~30–38 GB при работающих приложениях, ~55 GB при остановленных. Что не поместилось в RAM — читается с NVMe.

Вариант Размер Где взять Ожидание на этом сервере (проверить)
UD-Q2_K_XL 80 GB unsloth/Qwen3.8-Flash-Next-GGUF быстрее всех, качество ниже
RVN IQ3_S 83 GB уже скачан на ПК: F:\projects\inst\qwen-iq3s (8 файлов) рекомендуется для начала — ничего не качать, только скопировать
UD-IQ3_XXS / UD-Q3_K_XL 84 / 90 GB Unsloth близко к IQ3_S
UD-IQ4_XS 94 GB Unsloth 4 бита, чуть больше чтений с диска
UD-Q4_K_XL 111 GB Unsloth лучше качество; заметная часть экспертов — с NVMe, медленнее
UD-Q5_K_XL … Q8_0 158–188 GB Unsloth запустится, но в основном с диска — медленно; имеет смысл после добавления RAM

Примечание про RVN IQ3_S. Этот же набор файлов не принял движок Strata (ему нужны служебные тензоры в BF16), а llama.cpp такие типы тензоров (IQ3_S, IQ4_NL) читает. Архитектура в файле — qwen4exp, её поддерживает текущий llama.cpp. (проверить запуск)

Шаг 4: Загрузить модель на сервер

Вариант А: скопировать RVN IQ3_S с ПК

  1. Shares → Windows (SMB) Shares → Add: Path /mnt/appData/llm-models, Name llm-models, Save (TrueNAS предложит включить службу SMB — согласиться). Доступ — вашему пользователю.
  2. На ПК (PowerShell):
    New-Item -ItemType Directory -Force \\TRUENAS\llm-models\qwen-rvn-iq3_s | Out-Null
    robocopy F:\projects\inst\qwen-iq3s \\TRUENAS\llm-models\qwen-rvn-iq3_s *.gguf /J /NP

    83 GB по гигабитной сети — ~15 минут.

Вариант Б: скачать с Hugging Face прямо на сервер

В System → Shell (или SSH) — одноразовый контейнер, который скачивает выбранный квант и удаляется:

docker run --rm -v /mnt/appData/llm-models:/models python:3.12-slim sh -c \
  "pip install -q -U huggingface_hub hf_xet && \
   hf download unsloth/Qwen3.8-Flash-Next-GGUF --include '*UD-Q4_K_XL*' --local-dir /models/unsloth-ud-q4_k_xl"
ls -la /mnt/appData/llm-models/unsloth-ud-q4_k_xl/*

Для другого кванта поменяйте UD-Q4_K_XL в обоих местах. Загрузка возобновляется при повторном запуске. (проверить точные имена папок в репозитории Unsloth)

В YAML («Шаг 6») указывается первый файл набора (…-00001-of-0000N.gguf), остальные части llama.cpp подхватит сам.

Шаг 5: API-ключ

openssl rand -hex 24

Ниже — <КЛЮЧ>. Без ключа сервер будет открыт всей сети.

Шаг 6: Custom App через веб-интерфейс

Apps → Discover Apps → ⋮ → Install via YAML:

  • Name: llama-qwen
  • Custom Config:
services:
  llama-qwen:
    image: ghcr.io/ggml-org/llama.cpp:server-cuda-b12316
    container_name: llama-qwen
    restart: unless-stopped
    ports:
      - "30081:8080"
    volumes:
      - /mnt/appData/llm-models:/models:ro
    command:
      - -m
      - /models/qwen-rvn-iq3_s/RVN-Qwen3.8-Flash-Next-IQ3_S-00001-of-00008.gguf
      - --alias
      - qwen3.8-flash-next
      - --host
      - 0.0.0.0
      - --port
      - "8080"
      - --api-key
      - "<КЛЮЧ>"
      - -c
      - "65536"
      - -ngl
      - "99"
      - --cpu-moe
      - --moe-cache-mib
      - "6144"
      - -fa
      - "on"
      - -ctk
      - q8_0
      - -ctv
      - q8_0
      - -t
      - "6"
      - --jinja
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

Что делает каждая строка:

Параметр Смысл
server-cuda-b12316 закреплённая версия llama.cpp (сборка 12316, CUDA 12 — работает на драйвере 550). Обновление — сменить номер сборки
30081:8080 снаружи порт 30081 (8080/8081 заняты, 30080 зарезервирован под Strata)
/models:ro датасет с моделями, только чтение
-m первый файл набора GGUF
–alias имя модели в API (/v1/models) — его указывают клиенты
-c 65536 контекст 64K (больше — больше VRAM под KV-кэш)
-ngl 99 все слои на GPU…
–cpu-moe …кроме экспертов: они остаются в RAM/mmap (а значит, на NVMe)
–moe-cache-mib 6144 6 GB видеопамяти — кэш самых используемых экспертов. Если VRAM мало — уменьшить; если свободно больше — увеличить
-fa on, -ctk/-ctv q8_0 Flash Attention и KV-кэш в 8 бит — меньше VRAM под контекст
-t 6 потоки CPU: по числу P-ядер i5-14500. (проверить) -t 12 и -t 14
–jinja шаблон чата из модели (нужен для вызова инструментов агентами)
deploy … nvidia доступ к GPU (как у ваших whisper и libretranslate)

Лимит памяти и memlock не нужны: в режиме mmap (по умолчанию) память под веса отдаётся системе по требованию.

Шаг 7: Запуск и проверка

Apps → Installed → llama-qwen → Logs. Нормальная загрузка выглядит так (суть строк): модель найдена, CUDA0 model buffer — часть на GPU, CPU_Mapped model buffer — эксперты отображены из файла, затем server is listening on http://0.0.0.0:8080. Загрузка — от десятков секунд до нескольких минут.

На сервере:

curl -s http://127.0.0.1:30081/health
curl -s http://127.0.0.1:30081/v1/models -H "Authorization: Bearer <КЛЮЧ>"

С ПК (PowerShell), с замером скорости — в ответе поле timings.predicted_per_second (токенов/с генерации):

'{"model":"qwen3.8-flash-next","messages":[{"role":"user","content":"Объясни кратко, чем list отличается от tuple в Python"}],"max_tokens":300}' | Out-File -Encoding utf8 req.json
curl.exe -s http://192.168.1.135:30081/v1/chat/completions -H "Authorization: Bearer <КЛЮЧ>" -H "Content-Type: application/json" --data-binary "@req.json"

Первые запросы будут медленными — эксперты ещё не в RAM и читаются с NVMe. После нескольких запросов «горячие» эксперты оседают в кэше, скорость растёт. Замеряйте 3–5 запросов подряд.

Шаг 8: Подстройка скорости

Меняйте по одному параметру (Apps → llama-qwen → Edit) и сравнивайте predicted_per_second:

  • –moe-cache-mib — больше кэша экспертов на GPU, если VRAM свободна (nvidia-smi). Обычно самый заметный эффект.
  • –n-cpu-moe N вместо –cpu-moe — эксперты первых N слоёв на CPU, остальных — целиком на GPU. Например –n-cpu-moe 44 — эксперты 4 последних слоёв в VRAM. Подбирать, пока хватает VRAM.
  • -t — 6 / 12 / 14 потоков; E-ядра иногда замедляют.
  • -c — меньше контекст → больше VRAM под эксперты.
  • Свободная RAM — остановка тяжёлых приложений даёт больше места под кэш страниц → меньше чтений с NVMe.
  • -lm dio (Direct I/O) — читать веса в обход кэша страниц. Обычно медленнее, имеет смысл только для экспериментов.

Активность диска: Reports → Disk (или zpool iostat -v appData 2 под root) — при «прогретом» кэше чтений с NVMe во время генерации должно быть мало.

Шаг 9: Подключение клиентов

Параметр Значение
Тип API OpenAI Compatible
Base URL http://192.168.1.135:30081/v1
Chat Completions http://192.168.1.135:30081/v1/chat/completions
API Key <КЛЮЧ>
Модель qwen3.8-flash-next (значение –alias)

Goose Desktop

Settings → Models → Add Custom Provider: Provider Type OpenAI Compatible, Display Name llama.cpp Server, API URL http://192.168.1.135:30081/v1/chat/completions, API Key <КЛЮЧ>, Available Models qwen3.8-flash-next, Streaming — вкл. Или файлом %APPDATA%\Block\goose\config\custom_providers\custom_llama_server.json:

{
  "name": "custom_llama_server",
  "engine": "openai",
  "display_name": "llama.cpp Server",
  "description": "llama.cpp on TrueNAS 192.168.1.135:30081",
  "api_key_env": "CUSTOM_LLAMA_SERVER_API_KEY",
  "base_url": "http://192.168.1.135:30081/v1/chat/completions",
  "models": [
    { "name": "qwen3.8-flash-next", "context_limit": 65536 }
  ],
  "headers": null,
  "timeout_seconds": 600,
  "supports_streaming": true,
  "requires_auth": true
}

Ключ — в Settings → Models у провайдера. Русский язык и MCP — как в инструкции для ПК.

Open WebUI (уже стоит на сервере)

Admin Panel → Settings → Connections → OpenAI API → URL http://192.168.1.135:30081/v1, Key <КЛЮЧ>.

Остальные клиенты (OpenCode, Claude Code, Python) — как на странице Strata на TrueNAS, с адресом http://192.168.1.135:30081/v1 и моделью qwen3.8-flash-next.

Несколько моделей / смена модели

  • Сменить модель — Edit → поменять путь в -m (и при желании –alias) → Save.
  • Не запускайте одновременно llama-qwen и strata (после обновления TrueNAS) — они делят одну видеокарту.
  • Удалить ненужную модель — удалить её папку в /mnt/appData/llm-models.

Безопасность

  • Порт 30081 открыт всей домашней сети — ключ обязателен. Не пробрасывайте порт на роутере в интернет; доступ извне — через VPN или nginx-proxy-manager с HTTPS.

Проблемы и решения

unknown model architecture: 'qwen4exp'

Слишком старая сборка llama.cpp. Используйте свежий тег server-cuda-bNNNNN (поддержка добавлена в 2026-08, PR #27742).

Нет GPU в логах / no CUDA devices

В YAML нет блока deploy … nvidia или видеокарту не видит Docker: на сервере docker run –rm –gpus all ghcr.io/ggml-org/llama.cpp:server-cuda-b12316 –list-devices.

CUDA out of memory при загрузке

Видеокарту держат другие приложения («Шаг 1») — либо уменьшите –moe-cache-mib и -c.

Очень медленно (меньше 1–2 токенов/с)

  • Кэш ещё не прогрет — сделайте несколько запросов.
  • Мало свободной RAM — остановите тяжёлые приложения; проверьте free -g (столбец available).
  • Модель слишком большая для RAM этого сервера — возьмите квант меньше.
  • Попробуйте primarycache=metadata («Шаг 2»).

Модель не найдена

Путь в -m — внутри контейнера (/models/…), а не /mnt/appData/…. Проверка: ls /mnt/appData/llm-models/<папка>.

Шпаргалка

docker logs -f llama-qwen
nvidia-smi
free -g
curl -s http://192.168.1.135:30081/v1/models -H "Authorization: Bearer <КЛЮЧ>"
Что Значение
Адрес API http://192.168.1.135:30081/v1
Модель (API) qwen3.8-flash-next
Модели на диске /mnt/appData/llm-models (NVMe)
Образ ghcr.io/ggml-org/llama.cpp:server-cuda-b12316
truenas/application/llamacpp_moe_ssd.txt · Последние изменения: 2026/11/12 18:15 — werwolf