Перейти к содержанию
Публикация AiManual

gemma4.c: как запустить современную LLM на CPU в 700 строках C

Разбираем gemma4.c, компактный C-рантайм для запуска Gemma 4 E2B на CPU. Объясняем токенизацию, prefill, decode, KV-кэш, int8-квантизацию, OpenMP и AVX-512 VNNI

Коротко

Что будет в материале

  1. 01

    Короткий ответ: что дает gemma4.c

  2. 02

    Что такое gemma4.c и чем этот подход отличается от обычного рантайма

  3. 03

    Как проходит инференс LLM внутри gemma4.c

  4. 04

    Почему запуск LLM на CPU стал возможен в такой компактной реализации

gemma4.c показывает, что запуск современной LLM на CPU не обязательно требует большого фреймворка. Проект помещает основные этапы инференса Gemma 4 E2B в один C-файл примерно на 700 строк и использует int8-квантизацию, OpenMP и AVX-512 VNNI.

На Ryzen 7 7700 разработчики указывают 639 ток/с при обработке входного контекста, или prefill, и 25,9 ток/с при последовательной генерации новых токенов. Эти показатели относятся к конкретной конфигурации и не гарантируют такую же скорость на любом процессоре.

Главная ценность gemma4.c связана с прозрачностью. В небольшом исходном файле видны токенизация, вычисления модели, KV-кэш и сэмплирование. Такой код помогает понять, что происходит между отправкой запроса и появлением следующего токена, тогда как полноразмерный рантайм обычно скрывает большую часть механики за слоями библиотек и универсальных интерфейсов.

Короткий ответ: что дает gemma4.c

Да, Gemma 4 E2B можно запускать на CPU через gemma4.c. Проект рассчитан на компактный инференс-рантайм на языке C и задействует три основных механизма ускорения:

  • int8-квантизацию, которая уменьшает разрядность представления данных;
  • OpenMP, распределяющий вычисления между потоками CPU;
  • AVX-512 VNNI, ускоряющий векторные операции над целочисленными данными.

Заявленный результат на Ryzen 7 7700 составляет 639 ток/с для prefill и 25,9 ток/с для decode. Первая цифра описывает обработку уже имеющегося контекста, вторая ближе к скорости, которую пользователь видит во время ответа модели.

gemma4.c подходит для изучения устройства трансформера, экспериментов с CPU-инференсом и проверки того, какие вычисления нужны для генерации текста. Для готового универсального приложения с широким набором форматов, режимов и интеграций лучше выбрать зрелый рантайм, например llama.cpp.

Что такое gemma4.c и чем этот подход отличается от обычного рантайма

gemma4.c - минималистичная реализация инференса Gemma 4 E2B на C. Ее исходный код собран в одном файле примерно на 700 строк. Внутри находятся основные этапы обработки запроса: подготовка входного текста, вычисление слоев модели, хранение состояния внимания и выбор следующего токена.

Компактность меняет способ изучения проекта. В большом рантайме логика может быть распределена между загрузчиком модели, тензорным движком, планировщиком, backend-ами CPU и системой управления памятью. В gemma4.c путь запроса прослеживается значительно проще: текст превращается в числа, числа проходят через вычисления трансформера, затем модель выдает оценки токенов, из которых выбирается продолжение.

У такого подхода есть четкая граница. Небольшой файл не претендует на полноту промышленного инструмента. В нем может не быть функций, форматов и аппаратных backend-ов, которые поддерживает llama.cpp. Поэтому gemma4.c разумно воспринимать как компактный учебный и экспериментальный рантайм, а не как универсальную замену всей экосистеме локальных LLM.

Как проходит инференс LLM внутри gemma4.c

Работу рантайма удобно представить как последовательность из нескольких этапов: входная строка, токены, обработка контекста, пошаговый decode, логиты и выбор следующего токена.

Токенизация: превращение текста в последовательность чисел

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

Полученная последовательность становится входом вычислительного графа. На этапе prefill рантайм обрабатывает уже имеющиеся токены контекста. При последующей генерации в последовательность добавляется новый токен, после чего модель вычисляет следующий шаг.

Конкретные особенности токенизатора Gemma 4 в исходных данных не описаны, поэтому для gemma4.c не следует приписывать ему определенную схему разбиения текста или специальные правила обработки Unicode.

Prefill и decode: два разных режима работы

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

Decode генерирует продолжение по одному токену. Каждый следующий шаг зависит от результата предыдущего: модель выбрала токен, добавила его к последовательности, вычислила новые оценки и повторила цикл. На этом этапе важны задержка одного шага и скорость последовательной генерации.

Именно поэтому показатели 639 ток/с и 25,9 ток/с нельзя воспринимать как две версии одной и той же скорости. Они измеряют разные участки работы LLM.

KV-кэш LLM: зачем сохранять ключи и значения

В механизме внимания каждый обработанный токен связан с наборами key и value. При генерации следующего токена ранее вычисленные значения можно сохранить в KV-кэше и использовать повторно.

Без KV-кэша рантайму пришлось бы заново пересчитывать состояние всего контекста при каждом новом токене. Кэш сокращает эти повторные вычисления и делает autoregressive decode практичным на CPU.

Ускорение требует памяти. Чем длиннее контекст и чем больше слоев или голов внимания хранит модель, тем больше места занимает KV-кэш. Поэтому длина контекста влияет сразу на несколько параметров: время обработки, потребление памяти и скорость дальнейшей генерации.

Сэмплирование: как из выходов модели выбирается следующий токен

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

Сэмплирование превращает оценки в решение о продолжении. Выбранный токен добавляется к последовательности, его состояние учитывается в KV-кэше, и цикл повторяется. Конкретные стратегии и параметры сэмплирования gemma4.c в исходных данных не указаны, поэтому нельзя утверждать, использует ли проект определенную комбинацию temperature, top-k или top-p.

Почему запуск LLM на CPU стал возможен в такой компактной реализации

CPU-инференс упирается в объем данных, пропускную способность памяти и количество операций. gemma4.c сокращает нагрузку сразу по нескольким направлениям: хранит вычисляемые данные в int8, распределяет работу между потоками и использует векторные инструкции процессора.

int8-квантизация: меньше данных для вычислений

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

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

Компромисс связан с точностью представления. Квантизация может влиять на качество вычислений и ответов, но конкретные измерения потери качества для gemma4.c в доступных данных не приведены. Поэтому int8 здесь стоит оценивать как инженерный способ ускорить инференс, а не как гарантию полного совпадения с неквантизированной моделью.

OpenMP: распараллеливание на ядрах процессора

OpenMP позволяет распределять независимые части вычислений между потоками CPU. Для инференса это полезно при обработке матриц и других операций, которые можно выполнять параллельно.

Число потоков не превращается автоматически в такой же прирост производительности. На результат влияют количество физических ядер, настройки OpenMP, параметры компиляции, пропускная способность памяти и нагрузка на систему. Одинаковый бинарный файл может показывать разные цифры на двух процессорах с похожей частотой.

В сценарии с коротким запросом часть времени может уходить на служебные операции и синхронизацию потоков. При большом prefill параллелизм обычно получает больше работы, поэтому режим обработки контекста и decode реагируют на настройки многопоточности по-разному.

AVX-512 VNNI: аппаратное ускорение int8-операций

AVX-512 VNNI - набор векторных инструкций для процессоров с поддержкой соответствующего расширения. Он помогает ускорять операции над целочисленными данными, что хорошо сочетается с int8-квантизацией.

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

Производительность gemma4.c на Ryzen 7 7700

Для оценки проекта нужно разделять скорость обработки входа и скорость генерации. Первая показывает, как быстро рантайм переваривает уже известный контекст. Вторая описывает авторегрессионное создание новых токенов.

639 ток/с в prefill и 25,9 ток/с в decode

РежимПоказательЧто измеряется
Prefill639 ток/сОбработка входной последовательности
Decode25,9 ток/сПоследовательная генерация новых токенов

Показатель prefill выглядит значительно выше, потому что готовая последовательность обрабатывается плотнее и лучше загружает параллельные вычисления. Decode ограничен зависимостью между шагами: следующий токен нельзя полноценно вычислить до завершения предыдущего.

Обе цифры относятся к Gemma 4 E2B, запуску на Ryzen 7 7700 и описанной связке int8, OpenMP и AVX-512 VNNI. Без данных о длине контекста, числе потоков, настройках компилятора и других параметрах бенчмарк нельзя считать универсальным стандартом сравнения.

Что эти цифры говорят о практическом использовании

25,9 ток/с дает ориентир для комфортного локального диалога при совпадении аппаратных и программных условий. Пользователь получает несколько десятков новых токенов в секунду, но фактическое ощущение скорости зависит от длины ответа, задержки первого токена и интерфейса.

Значение 639 ток/с полезно при работе с уже существующим контекстом. Оно показывает, насколько быстро процессор может обработать входную последовательность в выбранном режиме. По одной этой цифре нельзя оценить время до первого токена, расход памяти или качество ответов модели.

На другом CPU результат может измениться из-за отсутствия AVX-512 VNNI, меньшего числа ядер, иной производительности памяти или отличающейся настройки OpenMP. Бенчмарк следует использовать как ориентир для конкретного класса систем, а не как обещание производительности.

gemma4.c и llama.cpp: компактность против полноты

gemma4.c и llama.cpp решают похожую задачу, но рассчитаны на разные сценарии использования.

Критерийgemma4.cllama.cpp
Размер и прозрачностьОдин C-файл примерно на 700 строк, проще проследить путь вычисленийКрупный проект с большим числом компонентов и backend-ов
Учебная ценностьВысокая, основные этапы инференса находятся рядомТребует больше времени на изучение архитектуры
Прикладная полнотаМинималистичный набор возможностейБолее широкий набор функций для локального запуска
Аппаратные вариантыФокус на выбранном CPU-путиРазвитая поддержка разных конфигураций и ускорителей
Основной сценарийИзучение и экспериментыРегулярное использование локальных LLM

llama.cpp логичнее выбирать, когда нужны готовые прикладные возможности, совместимость и более зрелая экосистема. На его фоне gemma4.c ценен как короткий исходный материал, где проще увидеть устройство токенизации, вычислений, KV-кэша и генерации.

Для сравнения с другими CPU-only подходами полезен разбор Project Zero. Это другой проект на чистом C, поэтому его показатели и архитектурные решения нельзя напрямую смешивать с результатами gemma4.c, но оба материала помогают оценить интерес к компактным CPU-рантаймам.

Кому подойдет запуск LLM на CPU через gemma4.c

  • Разработчикам C и C++. Проект дает небольшой объем исходного кода для изучения работы тензорных вычислений, токенизации и цикла генерации.
  • Исследователям устройства трансформеров. В одном файле проще связать теорию внимания, KV-кэш и получение логитов с работающим инференсом.
  • Энтузиастам локальных LLM. gemma4.c позволяет экспериментировать с запуском Gemma 4 E2B на собственном CPU без обязательного GPU.
  • Владельцам совместимого железа. Ryzen 7 7700 показывает, что при поддержке нужных инструкций и корректной настройке CPU может выдавать пригодную для диалога скорость decode.
  • Начинающим специалистам по ML-инфраструктуре. Компактный рантайм помогает разобраться, какие части скрываются за привычной командой запуска модели.

Пользователю, которому нужен универсальный чат-инструмент, сервер API, широкий выбор моделей или разные аппаратные backend-ы, вероятно, важнее полнота llama.cpp. Критерий выбора здесь простой: gemma4.c нужен для понимания и экспериментов, llama.cpp - для более широкого прикладного использования.

Если интересует сама модель Gemma 4 и ее место среди локальных LLM, полезно сопоставить этот материал с разбором Gemma 4 и Qwen3.6-MoE. Аппаратные требования и поведение конкретной модели зависят от ее архитектуры, квантования и выбранного рантайма.

Ограничения и итоговая оценка проекта

Сильные стороны gemma4.c очевидны:

  • один C-файл примерно на 700 строк;
  • запуск Gemma 4 E2B на CPU;
  • понятный полный цикл от токенизации до выбора токена;
  • int8-квантизация для снижения нагрузки на память и вычисления;
  • OpenMP для работы с несколькими потоками;
  • AVX-512 VNNI для ускорения целочисленных операций;
  • заявленные 639 ток/с в prefill и 25,9 ток/с в decode на Ryzen 7 7700.

Ограничения связаны с тем же минимализмом. Возможности могут быть уже, чем у llama.cpp, а результаты зависят от процессора, поддержки инструкций, параметров OpenMP, сборки и конкретной модели. В доступных данных нет сведений о потреблении памяти, задержке первого токена, качестве ответов после int8-квантизации и поддерживаемых форматах файлов.

gemma4.c стоит изучать, если цель - понять механику CPU-инференса и получить компактную основу для экспериментов. Для повседневного локального использования с большим набором моделей и настроек практичнее смотреть в сторону зрелых универсальных рантаймов.

Часто задаваемые вопросы о gemma4.c

Можно ли запустить Gemma 4 E2B без GPU?

Да. gemma4.c описан как CPU-реализация инференса Gemma 4 E2B. Проект использует int8-квантизацию, OpenMP и AVX-512 VNNI. Скорость зависит от процессора и параметров запуска.

Что такое KV-кэш LLM и зачем он нужен?

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

Почему prefill быстрее генерации?

Prefill обрабатывает уже известный контекст более плотным параллельным вычислением. Decode создает токены последовательно, и каждый следующий шаг зависит от результата предыдущего. Поэтому 639 ток/с для prefill и 25,9 ток/с для генерации описывают разные режимы работы.

Чем gemma4.c отличается от llama.cpp?

gemma4.c проще читать и использовать для изучения основных этапов инференса, поскольку код собран в одном небольшом файле. llama.cpp ориентирован на более широкий набор прикладных возможностей, моделей и конфигураций. Выбор зависит от задачи: обучение и эксперименты или универсальный локальный рантайм.

Подписаться на канал