Всё больше выходит больших MoE моделей с малым числом активных параметров. �� MoE совсем другой сценарий нагрузки и использования ресурсов нежели у Dense моделей, достаточно немного VRAM. Большие MoE модели устроит 1 GPU и много обычной RAM. О том, как устроены MoE и как ускорить работу одним параметром не меняя железо.

Немного про устройство MoE

MoE - это модели, где общее количество параметров больше числа активируемых для генерации нового токена. В отличии от сплошных Dense моделей, архитектура Mixture of Experts собирает модель из отдельных блоков называемых экспертами. Специально обученный блок роутер на каждом шагу выбирает к какому ограниченному числу экспертов будет направлен запрос на генерацию следующего, одного токена.

Стоит учесть, что это не буквальные эксперт, не эксперты в какой-то области, вроде математики или биологии, MoE эксперты это изолированные мини-подсети, которые научились работать в каком-то диапазоне значений лучше, чем соседние эксперты, и роутер, gating network, тоже обучаемая небольшая нейросеть, должен уметь выбирать к какой мини-подсети отправить конкретно этот запрос на этом слое.

Один проход модели для генерации 1 токена - это пройти по всем скрытым слоям. Слоёв в модели может быть как немного, например, 12 штук, так и очень много, доходя до 100 и более. Каждый слой это система из блоков внимания и блоков FFN, в MoE в каждом слое находится роутер, который на основе работы предыдущих слоев выберет следующего эксперта. MoE слои не обязаны идти друг за другом, они могут чередоваться с классическими слоями, всё зависит от архитектуры.

��а генерацию токена задействуется сразу несколько экспертов, которые будут миксоваться (то самое Mixture) по мере прохождения по слоям. На слой может быть выделено несколько экспертов.

Главное отличие Dense моделей от MoE в том, что из себя представляет FFN, блок который генерирует ответ. В Dense моделях это сплошной массивный блок, а в MoE этот блок заменен на группу маленьких FFN блоков, экспертов, каждый из которых представляет собой маленькую изолированную FFN сеть.

Из‑за такого урезания общего количества параметров на проход для одного слоя, суммарный объём модели большой, но несравним с Dense‑моделями такого же размера. При одинаковых условиях, сплошные модели будут качественнее из-за того, что FFN блок имеет больше параметров.

Другая проблема MoE в том, что сейчас нет эффективного алгоритма для изолирования экспертов друг от друга, и они могут "накладываться" друг на друга, дублируя обучение. И сам роутер может плохо подбирать экспертов или выбирать одних и тех же, что ещё сильнее снижает общее число рабочих параметров.

Почему ускорение работает для MoE

Например, GPT-OSS-120B, MoE-модель на каждом шагу активирует всего 4 эксперта из 128 доступных, и ещё часть общих тензоров, в итоге на генерацию 1 токена требуется в 24 раза меньше ресурсов, чем если бы это была сплошная модель.

Ускорение при комбинации CPU + GPU происходит за счёт того, что часть слоев выгружают на GPU, остается работает на CPU, и так как в сплошных моделях FFN блок сплошной, то видеокарта будет полезна при вычислении любой части такой сплошной сети.

В MoE сеть разряжена, и если сделать тоже самое, вынести целые слои на GPU, то внутри слоя будет задействована лишь небольшая часть блоков, и большая часть VRAM будет выступать просто как дорогое хранилище к которому лишь иногда обращаются.

Первые 2 слоя вынесены на GPU. На каждом слое выбрано по 2 эксперта из 128, много блоков простаивают занимая впустую VRAM
Первые 2 слоя вынесены на GPU. На каждом слое выбрано по 2 эксперта из 128, много блоков простаивают занимая впустую VRAM

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

Можно обратить внимание, что у слоя блок внимания общий для всего слоя. Если не трогать FFN блоки, а на GPU вынести только эти тензоры внимания, то полный проход нейросети будет задействовать видеокарту на каждом слое, что даст хорошее ускорение.

Теперь не целые слои, а только тензоры внимания всех слоев вынесены на GPU
Теперь не целые слои, а только тензоры внимания всех слоев вынесены на GPU

MoE бывают разные и некоторые ускоряются лучше

В зависимости от архитектуры MoE модели, часть слоев могут быть классическими Dense слоями, обычно их называют общими, а также часть экспертов могут быть общими. Такие общие слои и общие эксперты тоже могут быть вынесены на GPU, давая ещё больше ускорения.

Например, DeepSeek R1 и V3 имеют 3 общих слоя, а внутри MoE-слоев у них есть общие эксперты. Узнать это можно если посмотреть структуру тензоров слоев. Общие слои не имеют тензоров с именем exps (в данном случае это blk.0, blk.1, blk.2), и начиная с 4 слоя идут MoE-слои, там появляются эксперты, и среди них можно отделить, те которые имеют в имени shexp, это тензоры общих экспертов.

Структура слоев DeepSeek V3.1
Структура слоев DeepSeek V3.1

-cmoe или --cpu-moe для перераспределения тензоров

Для того, чтобы перенести всё кроме MoE-параметров (тензоры внимания, общие слои, общие эксперты) добавлен параметр --override-tensor, которым можно через regexp управлять какие тензоры куда направить.

В предыдущей статье я уже описывал как это работает, поэтому кому интересны детали, можете посмотреть их там: Запускаем настоящую DeepSeek R1 671B на игровом ПК и смотрим вменяемая ли она на огромном контексте (160к)

Для удобства, чтобы не заниматься регулярными выражениями, существует параметр --cpu-moe или -cmoe, который уже объединяет в себе всё перечисленные выше виды тензоров, которые нужно отделить от MoE-параметров.

Логика работы тут немного инвертирована. Сначала параметром -ngl 999 переносим полностью все слои на GPU, после этого добавляем -cmoe для переопределения MoE-параметров, чтобы они оставались на CPU.

-ncmoe или --n-cpu-moe N если есть лишняя VRAM

Тензоры внимания обычно занимают мало памяти, а общих слоев или экспертов может быть либо мало, либо не быть совсем, и -cmoe для GPT-OSS-120B займет всего 3 Гб VRAM. Остается много свободной памяти, которую можно пустить либо на контекст, либо заполнить её целыми слоями, на скольк�� хватит видеопамяти.

Чтобы управлять количеством слоев, которые пойдут на GPU в режиме cmoe, добавили ещё один параметр --n-cpu-moe N или-ncmoe N. Логика его работы такая - нужно указать сколько слоев отправятся на CPU, а остальные останутся на GPU.

Вместе с -ncmoe не нужно указывать -cmoe, так как у второго приоритет выше и ncmoe будет проигнорирован.

Для того, чтобы воспользоваться этим способом, нужно узнать сколько всего слоев у модели, это указывается либо в описании модели, либо при просмотре её структуры, либо просто при загрузке в llama.cpp. После этого в -ncmoe N выставить число равное количеству слоев, и по шагам уменьшать это значение в сторону 0. Какого-то удобного способа автоматизировать этот процесс пока нет.

Например, GPT-OSS-120B имеет 37 слоев.

Расход памяти у обычного -cmoe
Расход памяти у обычного -cmoe

И указав -ncmoe 30 видно, что количество занимаемой видеопамяти увеличилось.

Расход памяти при -ncmoe 30
Расход памяти при -ncmoe 30

Параметры -fa 1 и -ub 4096 -b 4096 и -ctk q8_0 -ctv q8_0

-fa 1 - кратно уменьшает расход памяти на контекст. Под fa скрыто несколько вариантов оптимизации, это может быть как flash attention, так и swa или mla, по умолчанию автоматически выбирается тот, который используется для модели изначально. В свежих llama.cpp этот параметр по умолчанию выставлен в 'auto', можно не указывать, но в другом софте этот параметр может быть выключен.

-ub 4096 -b 4096 - увеличить размеры батчей для ускорения обработки контекста. Это полезно, если у GPU много мощи и есть немного лишней видеопамяти. Можно выставить как больше, так и меньше.

-ctk q8_0 -ctv q8_0 - квантовать KV-кэш. Если мало памяти или нужно ещё больше контекста, то можно немного квантовать KV-кэш. KV-кэш это проекции контекста в представлении модели. По умолчанию работает в fp16, и чувствителен к квантованию, особенно V-проекция, поэтому не стоит опускать квантование ниже чем q8_0.

Запускаем GPT-OSS-120B

Самый распространенный способ запускать модели LLM локально, это либо через ollama, либо через LM Studio. Несмотря на то, что они сделаны на основе llama.cpp, они поддерживают не весь функционал, и там и там нет ncmoe, только в LM Studio есть галочка для cmoe. Поэтому запускать будем в llama.cpp.

Скачать gguf: https://huggingface.co/ggml-org/gpt-oss-120b-GGUF

Скачать llama.cpp: https://github.com/ggml-org/llama.cpp/releases

Для запуска:

  • llama-server - уже встроен удобный веб-клиент, который можно открыть в браузере, и автоматически запускается openai compatible api, чтобы в любом стороннем софте подключиться к этой модели.

  • llama-bench - утилита для бенчмарка скорости.

Чтобы модель грузилась сама, на сайте huggingface, где и хранятся все модели, нужно выбрать модель, нажать на Use this model и там найти llama.cpp, нажав на которую будет параметр -hf, который сам скачает выбранную модель и квант:

.\llama-server.exe -hf unsloth/gpt-oss-120b-GGUF:Q8_K_XL -fa 1 -cmoe -ngl 99 -c 8192 --jinja

Команда запуска, если модель уже скачана:

.\llama-server.exe -m "D:\models\gpt-oss-120b-mxfp4-00001-of-00003.gguf" -fa 1 -cmoe -ngl 99 -c 8192 --jinja

И оптимизированная под максимальную скорость PP и использование всей VRAM:

.\llama-server.exe -m "D:\models\gpt-oss-120b-mxfp4-00001-of-00003.gguf" -fa 1 -ncmoe 25 -ngl 99 -ub 4092 -b 4092 -c 65536 --jinja

Флаг --jinja - это флаг вшитого в GGUF шаблона чата, нужен не для всех моделей, но в данном случае в карточке модели указано, что нужно запускать с этим флагом. Это исправляет проблему не правильного отображения блока размышлений.

Чтобы не вбивать команду запуска каждый раз вручную, и чтобы быстро переключать модели, для удобства есть: https://github.com/mostlygeek/llama-swap

Замеры скорости до и после для GPT-OSS-120B

Через llama-bench прогоним 4 варианта:

  • GPU отключена, работа только на CPU (i7-14700, DDR5-4800)

  • обычный -ngl на сколько хватит памяти

  • -cmoe и -ngl 99

  • -ncmoe 23, для 22 уже не хватает видеопамяти

GPT-OSS-120B, tg - token generation, pp - prompt processing
GPT-OSS-120B, tg - token generation, pp - prompt processing

Размер контекста в llama-bench не большой, поэтому для реального использования расход памяти будет больше, примерно +2.5 Гб на 64к контекста или +1.25 Гб с KV квантованием.

Скорость, при том же расходе VRAM в ~23 Гб, выросла на 80%, почти в 2 раза, с 18.9 t/s до 34 t/s. При экономичном cmoe, расходуя всего 3 Гб VRAM, вместо 23 Гб, скорость всё равно выросла на 29%.

Немного упала скорость обработки контекста PP, но добавление -ub 4096 -b 4096 поднимает скорость с 300 t/s до 1600 t/s, но это зависит от мощности GPU:

Активные параметры MoE

Этот метод подойдет для любых MoE моделей, но эффективность будет разной, так как разные MoE модели сделаны с разной архитектурой, у них разное количество активных параметров, разное количество общих слоев и экспертов и т.д.

Например, модель Grok2 - это MoE модель, у которой самый маленький квант весит 80гб, что сравнимо с моделью GPT-OSS 120B по весу. Grok2 имеет 270B параметров, но при этом активных из них 115B, и даже с -cmoe нужно снизить параметр -ngl N, не получается выгрузить все 65 урезанных, без MoE-параметров, слоев, влезает только 42 и все 24 Гб видеопамяти забиты под завязку, не оставляя место под контекст.

Запуск Grok2 на том же ПК выдает всего 1.6 t/s, что лишь чуть-чуть быстрее запуска на CPU:

grok2, llama.cpp, 1.6 t/s
grok2, llama.cpp, 1.6 t/s

Для сравнения DeepSeek V3.1, модель общим числом параметров 671B, что в 2.5 раза больше Grok2, дает 7 t/s, так как активных параметров тут всего 37B, и ещё есть общие слоя и общие эксперты:

DeepSeek-V3.1-IQ2_KS, ik_llama.cpp, tg 7 t/s, pp 200 t/s
DeepSeek-V3.1-IQ2_KS, ik_llama.cpp, tg 7 t/s, pp 200 t/s

Другой пример с большим количеством общих слоев и экспертов это Llama-4-Maverick. Размер модели большой, 400B, имеет 17B активных параметров, но за счёт того, что тут много общих тензоров, её можно запустить на 23 t/s, что сопоставимо с GPT-OSS-120B, несмотря на то, что у Maverick в 3.4 раза больше активных параметров.

Для запуска Maverick не нужно много VRAM, но чтобы получить такую скорость понадобиться много RAM, так как даже Q3 квант потребует 180 Гб.

Llama-4-Maverick-17B-128E, 23 t/s
Llama-4-Maverick-17B-128E, 23 t/s

И пример модели, которая не имеет ни общих слоев, ни общих экспертов - это Qwen3-235B-A22B. Модель не очень большая, всего 235B, и активных параметров 22B не сильно больше чем у Maverick, но из-за архитектуры модель выдает всего 6.4 t/s.

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

Qwen3-235B-A22B-Thinking-2507, 6.4 t/s
Qwen3-235B-A22B-Thinking-2507, 6.4 t/s

Список MoE моделей

Примерный список актуальных моделей, который возможно запустить локально. Обычно через xB-AxB указывается количество общих параметров и активных параметров, но не все модели выносят это в название.

Есть как и те, что пойдут даже на CPU и будут выдавать не плохо качество, например, Qwen3-30B-A3B-2507 или Qwen3-Next-80B-A3B, так как активных параметров всего 3B, так и те, которым для запуска потребуется не меньше 256 Гб, вроде Kimi K2.

GLM-4.5-Air по требуемым ресурсам на уровне GPT-OSS-120B, но GLM часто показывает себя лучше, особенно на контексте выше 32к. И уже анонсировали выход GLM-4.6-Air.

Некоторые модели совсем свежие, поэтому поддержки в llama.cpp нет, но над этим работают, постоянно добавляя поддержку новых архитектур. На днях, например, добавили поддержку Qwen3 VL моделей, которые представлены в диапазоне от 2B до 235B.

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

Заключение

Переход к MoE позволяет изменить требование с VRAM на RAM и открывает возможности для запуска крупных LLM даже на видеокартах с 8 Гб, чего раньше не хватало даже для запуска Gemma3 27B. Конечно, чем больше VRAM, тем больше ускорение, но теперь даже 1 видеокарта способна расширить возможности для локального использования.

Запускать эти LLM можно в том числе и на AMD, так как llama.cpp поддерживает работу на Windows через Vulkan для всех или ROCm для поддерживаемых видеокарт.

MoE начинает находить применение не только в LLM, но и в других типах нейросетей. Например, Wan2.2 первыми перешли на MoE для генерации видео, что позволяет генерировать ролики кинематографического качество на домашнем ПК в 720p за приемлемое время.

Если же у вас совсем мало и VRAM, и RAM, а какую-то, не совсем уж глупую, модель попробовать локально хочется, попробуйте Qwen3-4B-Instruct-2507. Для своего размера в 2.5 Гб (в кванте UD-Q4_K_XL) модель показывает себя вполне достойно.

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


  1. sssevasss
    01.11.2025 11:03

    Для VR где разрешение может достигать 4K на глаз как раз лучше больше VRAM иметь)


    1. VBDUnit
      01.11.2025 11:03

      Даже без VR на больших разрешениях типа 11520×2160 или 23040×4320 нужно много VRAM, иначе в играх будет 1 fps. А ещё можно рендерить в 3D пакетах всякое 16K на GPU и тут тоже будет нужно много VRAM.

      Но тут речь про LLM, а не графику. У меня OSS 120b выдает 11–16 токенов в секунду в зависимости от настроек, при этом карта забита под 0 и ничего другого в неё уже не влезет.

      А описанный в статье способ, фактически, позволяет если не ускорить, то хотя бы одновременно загрузить дополнительно несколько моделей и переключаться между ними, не делая полной выгрузки и повторной загрузки. Например, комбинировать OSS120b с каким‑нибудь VLLM и SDXL.


  1. Snownoch
    01.11.2025 11:03

    вот же спасибо добрый человек. утащил в сохраненное


  1. edyapd
    01.11.2025 11:03

    Из тех, которые пробовал, меня больше всего, по соотношению скорость-качество, устраивает gpt-oss-120b. На моём компьютере выдаёт 12 т/с при пустом контексте и при заполнении контектса до 32к - около 6 т/с. DeepSeek V3.1 работает, но скорость не более 1.5 т/с. Если качество не сильно нужно, то использую gpt-oss-20b, даёт до 40 т/с на пустом и около 12 т/с при 32к контексте.

    Но я использую ik-llama.

    Tesla P40, Xeon 2698 v3, RAM DDR4-2133 192GB