TuBrief
Subscribed Channels
Videos
Community

Создание локальной LLM с реальным вводом на ESP32S3 и 16MB Flash

TuBrief Editorial
August 12, 2026
0
Computing/Software

Written with AI assistance from the source video. The video is the authority.

Русский한국어中文العربيةEspañolDeutschEnglishFrançaisहिन्दीPortuguêsBahasa Indonesia日本語

Related Video

Этот микроконтроллер за 8 долларов запускает языковую модель локально!8:14

Этот микроконтроллер за 8 долларов запускает языковую модель локально!

Better Stack

More from the community

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

September 13, 2026

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

September 13, 2026

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

September 13, 2026

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

September 13, 2026

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

September 12, 2026

Apple Won the AI Race

September 12, 2026

Comments (0)

Log in to leave a comment

No posts yet

© 2026 . All rights reserved.

TuBrief
Subscribed Channels
Videos
Community
Log in

Создание локальной LLM с реальным вводом на ESP32S3 и 16MB Flash

Если вы решите запустить языковую модель с 28,9 миллионами параметров на плате ESP32-S3 за 8 долларов, вы быстро столкнетесь с тупиком. Модель, которая отлично работает на презентационных видео, внезапно зависает при соприкосновении с вашими аппаратными периферийными устройствами. SRAM составляет всего 512 КБ, а необходимость прошивать новый раздел размером 15 МБ при каждом изменении предложения быстро начинает раздражать. Чтобы преодолеть эти ограничения и создать устройство, которое работает с реальным вводом с клавиатуры, вам придется полностью перепроектировать кэширование памяти и буферы ввода-вывода с нуля.

Внедрение промптов через Serial без необходимости полной перепрошивки

Перепрошивка платы каждый раз ради изменения одного тестового предложения — пустая трата времени. Связав асинхронные прерывания UART и семафоры FreeRTOS, вы избавитесь от необходимости перезагружать плату. Модель будет мгновенно обрабатывать предложения по мере их ввода через Serial-монитор или клавиатуру.

  1. Назначьте пины GPIO 16/17 порту UART_NUM_2, установите порог аппаратного FIFO в 120 байт и включите прерывание по приему.
  2. Создайте кольцевой буфер на 2048 байт во встроенной SRAM. Это предотвратит переполнение данных и сбои во время выполнения инференса.
  3. Подключите потоковый парсер, определяющий символы переноса строки, и мгновенно конвертируйте входной текст в массив ID токенов с помощью библиотеки токенизатора BTK1 размером 43 056 байт.
  4. Установите двойной семафор xPromptSemaphore. Когда задача приема завершит запись токенов и вызовет xSemaphoreGive, ожидающая задача инференса получит блокировку памяти через xSemaphoreTake и запустит вычисления.

Такая конфигурация сокращает время на доработку и тестирование промптов более чем на 80%.

`
+------------------+ +-------------------+ +--------------------+
| External UART | ---> | HW FIFO Buffer | ---> | SW Ring Buffer |
| (Keypad/Monitor) | | (120 Bytes) | | (2048 Bytes) |
+------------------+ +-------------------+ +--------------------+
|
v
+------------------+ +-------------------+ +--------------------+
| LLM Forward Pass | <--- | xPromptSemaphore | <--- | BTK1 Tokenizer |
| (Inference Task) | | (Binary Lock) | | (43,056 B Library) |
+------------------+ +-------------------+ +--------------------+

`

Достижение скорости в 14 токенов с помощью послойного распределения эмбеддингов и кэширования в SRAM

Использование архитектуры Per-Layer Embeddings (PLE), предложенной исследователями Google Gemma 3n, позволяет разделить и разместить 4-битную модель размером 14,9 МБ. Таблица эмбеддингов объемом 25 миллионов параметров размещается во флеш-памяти SPI емкостью 16 МБ, а веса Output Head (3,1 миллиона параметров) и кэш KV помещаются в PSRAM емкостью 8 МБ. Самое часто используемое плотное вычислительное ядро (Dense Compute Core) на 559 КБ параметров и буфер HotActivation сохраняются прямо в SRAM на 512 КБ.

Поднять скорость до 14 токенов в секунду и выше оказалось сложнее, чем предполагалось.

  1. Добавьте атрибут __attribute__((noinline)) к функции вычислений matvec_i8_range. Если компилятор выполнит инлайнинг автоматически, возникнут промахи кэша I-RAM, и время вычислений не ускорится, а упадет с 94,9 мс до 155.2 мс.
  2. Разделите операции ple_model_proj и qkv между двумя ядрами Dual Xtensa LX7 процессора ESP32-S3. Нужная скорость достигается только при одновременной работе обоих ядер.
  3. Расширьте буфер предвыборки (prefetch), который заранее загружает данные эмбеддингов начальных слоев в свободную память SRAM, чтобы преодолеть узкое место флеш-памяти.

Простой перенос кода на язык C дает удручающую скорость в 0,57 токена в секунду. Однако после применения квантования INT8 и предвыборки в SRAM скорость превышает 14,0 токенов в секунду.

Этап оптимизации Задержка вычислений на токен Генерация токенов в секунду Основные применяемые технологии
Чистый порт на C (Baseline) 1757,2 мс 0,57 tok/s Один корок, вычисления FP32
PSRAM Head и скалярная оптимизация 193,9 мс 4,61 tok/s Размещение Output Head в PSRAM
Применение двухъядерного FP32 139,4 мс 6,22 tok/s Двухъядерные вычисления послойного разделения
INT8 Staging + оптимизация SRAM 94,9 мс 9.88 tok/s Квантование INT8, применение noinline
Расширение буфера предвыборки SRAM ~71,4 мс 14,0+ tok/s Предвыборка начальных слоев в SRAM

Управление током потребления на уровне 210 мА с помощью Light Sleep

При непрерывной работе двух ядер на частоте 240 МГц потребляемый ток взмывает до 210 мА (777 мВт). Помимо того, что плата сильно нагревается, батарея разряжается в мгновение ока. Команда esp_pm_configure должна использоваться для снижения частоты до 40 МГц и включения автоматического режима легкого сна (Light Sleep) в периоды отсутствия инференса.

  1. В структуре esp_pm_config_esp32s3_t установите max_freq_mhz на 240, min_freq_mhz на 40 и включите light_sleep_enable.
  2. Выполните команду esp_sleep_pd_config(ESP_PD_DOMAIN_VDDSDIO, ESP_PD_OPTION_ON). Питание флеш-памяти SPI и RAM должно сохраняться даже в состоянии сна, иначе данные будут потеряны.
  3. Используйте uart_set_wakeup_threshold и esp_sleep_enable_uart_wakeup, чтобы настроить прерывание пробуждения, которое выведет CPU из спящего режима в момент поступления сигнала по последовательному порту.

При непрерывных вычислениях от литий-полимерного аккумулятора 3,7 В емкостью 1000 мАч устройство проработает всего 4,7 часа. Однако в режиме ожидания Light Sleep ток падает до 0,24 мА (0,88 мВт). В реальных сценариях использования с чередованием периодов ожидания средний ток удерживается на уровне 15–30 мА, что увеличивает время автономной работы более чем в 3 раза.