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

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


truenas:application:llamacpp_moe_ssd

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

— truenas:application:llamacpp_moe_ssd [2026/11/12 18:15] (текущий)
werwolf llama.cpp: MoE-модели с NVMe + RAM на TrueNAS (Custom App)
Строка 1: Строка 1:
 +====== 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.
 +
 +Главное отличие от [[:​truenas:​application:​strata_qwen_server|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 — [[:​truenas:​application:​strata_qwen_server|отдельная инструкция]] |
 +| **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''​ |
 +
 +Проверка образа на сервере:​
 +
 +<​code>​
 +$ 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)
 +</​code>​
 +
 +''​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.
 +
 +<code bash>
 +nvidia-smi --query-gpu=memory.used,​memory.total --format=csv
 +</​code>​
 +
 +Остальные приложения (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''​):​
 +
 +<code bash>
 +zfs set primarycache=metadata appData/​llm-models
 +zfs get primarycache,​recordsize,​compression appData/​llm-models
 +</​code>​
 +
 +**(проверить)** влияние на скорость:​ сравните ''​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 с ПК ====
 +
 +  - **Shares → Windows (SMB) Shares → Add**: Path ''/​mnt/​appData/​llm-models'',​ Name ''​llm-models'',​ Save (TrueNAS предложит включить службу SMB — согласиться). Доступ — вашему пользователю.
 +  - На ПК (PowerShell):<​code 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
 +</​code>​83 GB по гигабитной сети — ~15 минут.
 +
 +==== Вариант Б: скачать с Hugging Face прямо на сервер ====
 +
 +В **System → Shell** (или SSH) — одноразовый контейнер,​ который скачивает выбранный квант и удаляется:​
 +
 +<code bash>
 +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/​*
 +</​code>​
 +
 +Для другого кванта поменяйте ''​UD-Q4_K_XL''​ в обоих местах. Загрузка возобновляется при повторном запуске. **(проверить точные имена папок в репозитории Unsloth)**
 +
 +В YAML («Шаг 6») указывается **первый** файл набора (''​...-00001-of-0000N.gguf''​),​ остальные части llama.cpp подхватит сам.
 +
 +===== Шаг 5: API-ключ =====
 +
 +<code bash>
 +openssl rand -hex 24
 +</​code>​
 +
 +Ниже — ''<​КЛЮЧ>''​. Без ключа сервер будет открыт всей сети.
 +
 +===== Шаг 6: Custom App через веб-интерфейс =====
 +
 +**Apps → Discover Apps → ⋮ → Install via YAML**:
 +  * Name: ''​llama-qwen''​
 +  * Custom Config:
 +
 +<code yaml>
 +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]
 +</​code>​
 +
 +Что делает каждая строка:​
 +
 +^ Параметр ^ Смысл ^
 +| ''​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''​. Загрузка — от десятков секунд до нескольких минут.
 +
 +На сервере:​
 +
 +<code bash>
 +curl -s http://​127.0.0.1:​30081/​health
 +curl -s http://​127.0.0.1:​30081/​v1/​models -H "​Authorization:​ Bearer <​КЛЮЧ>"​
 +</​code>​
 +
 +С ПК (PowerShell),​ с замером скорости — в ответе поле ''​timings.predicted_per_second''​ (токенов/​с генерации):​
 +
 +<code powershell>​
 +'​{"​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"​
 +</​code>​
 +
 +**Первые запросы будут медленными** — эксперты ещё не в 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'':​
 +
 +<code 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
 +}
 +</​code>​
 +
 +Ключ — в Settings → Models у провайдера. Русский язык и MCP — как в [[:​truenas:​application:​strata_qwen_goose|инструкции для ПК]].
 +
 +==== Open WebUI (уже стоит на сервере) ====
 +
 +Admin Panel → Settings → Connections → OpenAI API → URL ''​http://​192.168.1.135:​30081/​v1'',​ Key ''<​КЛЮЧ>''​.
 +
 +Остальные клиенты (OpenCode, Claude Code, Python) — как на странице [[:​truenas:​application:​strata_qwen_server|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/<​папка>''​.
 +
 +===== Шпаргалка =====
 +
 +<code bash>
 +docker logs -f llama-qwen
 +nvidia-smi
 +free -g
 +curl -s http://​192.168.1.135:​30081/​v1/​models -H "​Authorization:​ Bearer <​КЛЮЧ>"​
 +</​code>​
 +
 +^ Что ^ Значение ^
 +| Адрес 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