Skip to content

How Expert Balance Works.ru

sikkatu edited this page Oct 17, 2026 · 2 revisions

Как работает балансировка экспертов

English | Русский | 中文

Проблема

Большая MoE-модель имеет сотни маршрутизируемых экспертов на слой. На 4 картах по 96 GB (384 GB суммарно, эффективно ~90 GB на карту после резерва) веса экспертов больших моделей не помещаются — а нужен ещё и запас под KV cache. При этом трафик касается лишь части экспертов.

Идея: горячие и холодные банки

  • Горячий банк (hot) — эксперты в памяти GPU. Нулевая стоимость передачи на токен.
  • Холодный банк (cold) — остальные, закреплены в RAM хоста, читаются по PCIe по требованию (UVA: GPU обращается к памяти хоста напрямую, без явного копирования).

На PCIe 4.0 (~25 ГБ/с эффективно на карту в этом классе хоста) холодный hit медленнее, но горячий набор покрывает подавляющее большинство маршрутизируемых токенов — поэтому средняя скорость остаётся высокой.

Как выбирается горячий набор

Один общий планировщик (patches/hotsplit_plan.py, только numpy, покрыт тестами):

  1. Гистограмма маршрутизации — счётчики частоты маршрутизации каждого эксперта (из balance.sh на выборке трафика — есть в рецептах DeepSeek/GLM; рецепт MiMo вместо этого несёт эталонный expert_hist_mix.json — переранжируйте под свой трафик через patches/hotsplit_rerank.py).
  2. Жадный горячий набор — эксперты сортируются по доле маршрутизации на байт (популярность ÷ размер), заполняется бюджет на rank HOTSPLIT_HOT_GIB.
  3. Валидация — NaN/отрицательные/несовпадающие счётчики — ошибка; переполнение бюджета — ошибка.
  4. Оракул — для малых случаев переборный планировщик подтверждает оптимальность жадного.

Планировщик байт-в-байт одинаков во всех четырёх рецептах (проверяется тестами).

Static и dynamic

  • Static (HOTSPLIT_DYNAMIC=0) — горячий набор фиксируется при загрузке по гистограмме.
  • Dynamic (HOTSPLIT_DYNAMIC=1, по умолчанию) — набор адаптируется во время работы: каждые HOTSPLIT_DYN_STEPS шагов движка живые счётчики маршрутизации оцениваются, и слабейшие горячие эксперты меняются на сильнейшие холодные (копии host→GPU на выделенном CUDA-потоке, публикуются через события — replay decode-графа никогда не видит полуприменённую перестановку).

Параметры обновлений валидируются на старте (мусорные значения вроде HOTSPLIT_DYN_STEPS=0 отказывают стартовать), повторные ошибки планировщика прерывают запуск, каждое обновление логирует строку hot/cold hit-rate — число, которое доказывает, что режим оправдывает себя.

Ручки

Параметр Значение По умолчанию
HOTSPLIT_HOT_GIB hot-бюджет на rank (GiB) пусто = объём GPU-резидентных байт стоковой расстановки (НЕ весь банк)
HOTSPLIT_DYNAMIC адаптация во время работы 1
HOTSPLIT_DYN_STEPS шаги между перестановками 2000
HOTSPLIT_DYN_MAX_SWAPS перестановок на слой за обновление 2
HOTSPLIT_DYN_MARGIN менять только если вход > margin × выход 1.25
HOTSPLIT_VRAM_RESERVE_GIB запас под CUDA graphs / KV cache 2
HOTSPLIT_NUMA_POLICY preferred / bind / off preferred

Почему цифрам здесь можно верить

Это железо: карты PCIe Gen 5, но слоты хоста — PCIe 4.0, память — DDR4. Все рецепты измеряют на наблюдаемой платформе (nvidia-smi, numastat), а не по спецификациям.

Clone this wiki locally