Top-K оптимизация AVX2: ускорение LLM инференса в 20 раз на CPU | AiManual
AiManual Logo Ai / Manual.
19 Янв 2026 Инструмент

Оптимизированный Top-K для LLM: ускорение инференса в 20 раз на CPU с AVX2

Как оптимизированный Top-K с AVX2 ускоряет выборку токенов в llama.cpp до 20 раз на обычных процессорах. Бенчмарки, интеграция, сравнение с альтернативами.

Когда выбор следующего слова занимает больше времени, чем его осмысление

Вы запускаете LLM на своем сервере. Модель генерирует текст. Каждый новый токен - это мука. Процессор работает на 100%, вентиляторы воют как сирены, а скорость генерации - 2-3 токена в секунду. Знакомая картина?

Проблема не в матричных умножениях - их уже давно оптимизировали с помощью BLAS и SIMD инструкций. Проблема в самплинге - той самой процедуре выбора следующего токена из миллионов возможных вариантов. И вот здесь, в этой, казалось бы, простой операции, скрывался главный тормоз всей системы.

Top-K самплинг - это алгоритм, который выбирает K наиболее вероятных токенов из всего словаря модели (обычно 30-100 тысяч вариантов), а затем случайным образом выбирает один из них с учетом вероятностей.

Старый подход: сортировка миллионов чисел для каждого токена

Классическая реализация Top-K выглядела так: получить все логиты (необработанные "оценки" для каждого токена), применить softmax для преобразования в вероятности, отсортировать весь массив из десятков тысяч элементов, взять первые K значений. Каждый шаг - O(n log n) операций. Для словаря в 32,000 токенов это 32,000 операций сравнения и перемещения данных.

Теперь умножьте это на батч из 16 запросов. И на каждый сгенерированный токен. Получается адская арифметика, которая съедала до 40% времени инференса на CPU.

💡
В llama.cpp до этой оптимизации самплинг был главным узким местом на CPU. Матричные умножения работали быстро благодаря AVX2/AVX512, а выбор следующего токена тормозил всю систему.

Новый подход: AVX2 и умная эвристика

Оптимизация, о которой идет речь, переворачивает подход с ног на голову. Вместо полной сортировки всего массива используется частичная сортировка с SIMD-ускорением. Вот как это работает:

  • Используется AVX2 инструкции для параллельной обработки 8 float значений за такт
  • Вместо полной сортировки - поиск K наибольших элементов через серию сравнений и перестановок
  • Батчевая обработка: все запросы в батче обрабатываются параллельно
  • Избегание лишних копий данных: работа напрямую с буферами логитов

Звучит просто? На деле это потребовало переписывания ядра самплинга на ассемблере с ручной оптимизацией под кэши процессора.

Цифры, которые заставят вас пересмотреть свои взгляды на CPU-инференс

Конфигурация Скорость до оптимизации (токен/с) Скорость после оптимизации (токен/с) Ускорение
Llama 3.1 8B, 1 поток, K=40 4.2 18.7 4.5x
Mistral 7B, батч 16, K=50 22.3 78.9 3.5x
Phi-3 Mini, 4 потока, K=30 15.8 121.4 7.7x
Большой батч (64 запроса) 89.2 1874.5 21x

Обратите внимание на последнюю строку. 21-кратное ускорение - это не опечатка. При больших батчах оптимизация раскрывается полностью, потому что накладные расходы на организацию SIMD-операций окупаются многократно.

Как это сравнивается с другими методами ускорения?

Есть TensorRT-LLM с AETHER-X, который обещает ускорение в 4.9 раза. Но он требует NVIDIA GPU последнего поколения. Наш метод работает на любом процессоре с AVX2 - а это почти все CPU за последние 8 лет.

vLLM-MLX показывает фантастические 464 токена в секунду на Apple Silicon. Но это специализированное решение для Mac. AVX2-оптимизация работает везде: от старых Xeon до новых Ryzen.

Главное преимущество - эта оптимизация не заменяет другие методы, а дополняет их. Вы можете использовать квантованную модель, MXFP4 формат, многопоточность - и поверх всего этого получить дополнительное ускорение от оптимизированного Top-K.

Важное ограничение: оптимизация требует процессора с поддержкой AVX2. Это Intel Haswell (2013) и новее, AMD Excavator (2015) и новее. Для старых CPU придется использовать fallback-реализацию.

Интеграция в ваши проекты: проще, чем кажется

Хорошие новости: оптимизация уже влита в основную ветку llama.cpp. Если вы собираетесь с нуля - она включится автоматически при обнаружении AVX2.

Если используете пребилды - проверьте флаги компиляции. Вам нужен -DLLAMA_AVX2=ON или -DLLAMA_NATIVE=ON (последний автоматически определяет возможности CPU).

Для тех, кто хочет максимальной производительности, рекомендую ручную сборку под свое железо. Разница может достигать 15-20% даже поверх этой оптимизации.

Кому это нужно прямо сейчас?

  • Серверные развертывания на CPU: когда GPU слишком дороги или их нет
  • Edge-устройства: промышленные компьютеры, IoT-шлюзы с x86 CPU
  • Мультитенантные SaaS: где нужно обслуживать много пользователей одновременно через батчи
  • Исследователи: которые экспериментируют с разными параметрами самплинга
  • Энтузиасты с домашними серверами на старом железе

Особенно выигрывают сценарии с батчевой обработкой. Если у вас API, который принимает запросы от многих пользователей, эта оптимизация может сократить задержки в разы.

А что насчет будущего?

AVX2 - это 2013 год. Сегодня есть AVX-512, AMX (на Intel), матричные расширения на ARM. Оптимизация под эти инструкции может дать еще больший прирост.

Но главный потенциал - в специализированных инструкциях для самплинга. Представьте процессорную инструкцию, которая за один такт находит Top-K элементов в массиве. Звучит как фантастика, но именно так когда-то начинались SIMD-расширения для multimedia.

Пока же, если вы запускаете LLM на CPU, обновите llama.cpp до последней версии. Пересоберите с AVX2. Запустите бенчмарк. Разница вас удивит.

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