LM Studio: спекулятивное декодирование ответов LLM

Недавно в LM Studio (софт для запуска нейронок локально) зарелизилась интересная фича: speculative decoding, которая по обещаниями авторов дает прирост скорости от 1.3 до чуть ли не 2x. Выглядит слишком хорошо, что бы быть правдой.

Кратко: все не так радужно и зависит от железа и звезд на небе.

Как работает спекулятивное декодирование в общих чертах:

  1. Малая модель (Draft model) быстро генерирует несколько будущих токенов, основываясь на текущем контексте.
  2. Большая модель (Target model) затем проверяет предложенные токены.
  3. Если большая модель согласна с догадками (или большинством из них) — эти токены принимаются сразу, что экономит вычисления.
  4. Если не согласна — возвращается к нормальному "шаг за шагом" декодингу для корректного токена.

В этой схеме есть два ограничения: обе модели должны быть одной и той же архитектуры (если большая модель - Llama, то и маленькая должна быть тоже Llama) и кроме того, должны быть тренированы на примерно одном датасете. Почему? Очень просто - чем ближе модели друг к другу, тем больше вероятность одинаковых ответов и тогда маленькая модель сможет эффективно предсказывать ответ большой. Если же модели далеки друг от друга как по архитектуре, так и по набору данных, то маленькая модель просто не сможет успешно предсказывать ответы большой.

LM Studio рекомендует мне Llama 3.2 3B как draft-модель, но она у меня уже скачана
LM Studio рекомендует мне Llama 3.2 3B как draft-модель, но она у меня уже скачана

Железо для тестов:

ПК: Ryzen 9 7900X3D + 64Гб DDR5 + NVIDIA RTX 4070 Ti. VRAM: 12 Гб

MacBook Pro 13" M1: 16Гб оперативной памяти LPDDR4 и 8 ядер GPU. VRAM: 12 ГБ.

Mac Studio M1 Ultra: 64Гб оперативной памяти LPDDR5 и 48 ядер GPU. VRAM: 52 Гб

Что показали тесты в реальности:

Для тестирования я использовал модели в форматах GGUF и MLX (только для Mac), фиксированный seed и лимит на кол-во генерируемых токенов (300) что бы долго не ждать.

Модели: Qwen2.5 14B (Q4), Qwen2.5 7B (Q8 и Q4), QwQ 32B (Q4), Llama 3.3 70B (Q3), Llama 3.1 8B (Q8 и Q4)

Draft-модели: Qwen2.5 0.5B (Q8 и Q4), QwQ 0.5B (Q8 и Q4), Llama 3.2 1B (Q8 и Q4), Llama 3.2 3B (Q8), Llama 3.2 8B (Q4).

Я брал примеры запросов из статьи на сайте программы и придумывал свои.

Если кратко: спекулятивное декодирование дает прирост далеко не всегда, более того - иногда скорость генерирования ответа наоборот сильно падает.

Чуть подробней:

На слабом железе (старый макбук M1) прирост заметен, но не в 2 раза, хорошо если хотя бы +30%.

На мощном железе (M1 Ultra) модели работают и так неплохо, но при этом почти всегда спекулятивное декодирование только замедляет работу, причем сильно: от -30 до -80% скорости. Довольно странный результат, скорее всего какие-то проблемы в самом коде.

На классическом железе (gpu от NVIDIA) спекулятивное декодирование чаще дает прирост производительности, но и тут можно нарваться на запрос, который будет обрабатываться медленней.

А потом я решил отдельно простестировать запросы на кодинг: написать какой-то простой алгоритм или функцию на питоне, и вот тут внезапно ситуация резко улучшилась, причем на любом железе. И маки и rtx4070ti показали прирост от 80 до 140% в большинстве придуманных мной тестов. При этом я не использовал специализированные модели для кодинга. Интересный результат. Код писать легче?

Какая получается картина:

запросы на точные факты (например: "В каком году взорвалась ЧАЭС? Назови только год") получают заметный буст скорости от спекулятивного декодирования

запросы на кодинг (python) - тоже чаще всего заметный прирост скорости, однако есть подозрение, что если запросить что-то слишком сложное, то результат станет противоположным

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

Я не стал прикладывать сами результаты тестов, поскольку там много букв и цифр, мало кому интересных.

Стоит ли использовать эту фичу?

Все зависит от железа, размеров основной модели и задач.

Для кодинга - скорее да, чем нет.

Для общего ускорения ответов LLM - только если у вас классическое железо (NVIDIA) и памяти хватит на две модели (по-сути, это норм только для xx90 видеокарт)

Дополнительно: маленькую draft-модель лучше брать с квантованием не меньшее Q8 (ну может Q6 в крайнем случае, если уже в память не лезет) и размером от 0.5B до 4B, более сжатые модели сильно хуже предсказывают токены и весь смысл теряется. Если основная модель размером от 70B, то ей в пару лучше ставить draft-модель размером 7-8B, но не 0.5-1B.

Если у вас мак - не используйте llama.cpp, только mlx, почему-то llama.cpp на маках всегда показывает самые плохие результаты в спекулятивном декодировании, да и вообще рантайм mlx всегда быстрее.

1
Начать дискуссию