<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Esp32 on RockB</title><link>https://baeseokjae.github.io/tags/esp32/</link><description>Recent content in Esp32 on RockB</description><image><title>RockB</title><url>https://baeseokjae.github.io/images/og-default.png</url><link>https://baeseokjae.github.io/images/og-default.png</link></image><generator>Hugo</generator><language>en-us</language><lastBuildDate>Fri, 28 Aug 2026 10:01:32 +0000</lastBuildDate><atom:link href="https://baeseokjae.github.io/tags/esp32/index.xml" rel="self" type="application/rss+xml"/><item><title>Running LLM Commands on ESP32: Embedded AI Agent Hardware</title><link>https://baeseokjae.github.io/posts/esp32-llm-commands-embedded-2026/</link><pubDate>Fri, 28 Aug 2026 10:01:32 +0000</pubDate><guid>https://baeseokjae.github.io/posts/esp32-llm-commands-embedded-2026/</guid><description>Yes — you can run LLM commands on an ESP32. A 28.9M-parameter model runs on-device at ~10 tokens/sec, but real instruction-following needs a bigger chip or the cloud.</description><content:encoded><![CDATA[<p>Yes, you can run LLM commands on an ESP32. A 28.9M-parameter language model runs fully on-device on an ESP32-S3 at about 9.88 tokens per second, with 25M parameters stored in flash using Google&rsquo;s Per-Layer Embeddings. However, models this small cannot follow instructions, answer questions, or write code — so true command execution requires either a more capable chip like the ESP32-P4 or a cloud-assisted setup.</p>
<h2 id="why-run-an-llm-on-a-6-microcontroller">Why Run an LLM on a $6 Microcontroller</h2>
<p>The ESP32 family is the most popular microcontroller line in the maker and IoT world, and it costs as little as $6 to $10 per board. Running a language model on it means you get local, private, offline inference on hardware that costs less than a cup of coffee. There is no cloud bill, no network dependency, and no data leaving your device.</p>
<p>For command-style interaction — wake-word detection, simple voice replies, or recognizing a fixed set of commands — an on-device model is fast enough. The appeal is real: a 28.9M-parameter model on an ESP32-S3 produces output at 9.88 tokens/sec end-to-end, which is usable for short responses and command recognition. The tradeoff is that these models are trained on narrow datasets like TinyStories, so they are not general-purpose assistants.</p>
<p>The key insight from the community is that memory, not compute, is the binding constraint. An ESP32-S3 has only 512KB of SRAM, but it can be paired with up to 8MB of PSRAM and 16MB of flash. Getting a useful model to fit inside those limits is the entire engineering challenge.</p>
<h2 id="the-memory-problem--sram-psram-and-flash-on-esp32">The Memory Problem — SRAM, PSRAM, and Flash on ESP32</h2>
<p>To understand why running an LLM on an ESP32 is hard, you have to understand the three-tier memory layout. Each tier has a different speed and size, and a model must be distributed across all three.</p>
<ul>
<li><strong>SRAM (512KB on the S3):</strong> The fastest memory, used for activations and normalization weights. It is tiny, so only the most frequently accessed data lives here.</li>
<li><strong>PSRAM (up to 8MB on the S3, 32MB on the P4):</strong> Slower but much larger. This holds the core transformer weights and the head of the model.</li>
<li><strong>Flash (16MB on the S3):</strong> The slowest but largest tier. This is where the bulk of the embedding table lives, accessed via a flash lookup table.</li>
</ul>
<p>The slvDev/esp32-ai project demonstrates this layout in practice. It stores 25M parameters in a flash lookup table using Google&rsquo;s Per-Layer Embeddings, keeping activations and norm weights in SRAM, the core and head in PSRAM, and the 25M-parameter embedding table in flash. At inference time, the model samples only about 450 bytes per token from that flash table, which keeps the memory bandwidth manageable.</p>
<p>This three-tier approach is what makes a 14.9MB model at 4-bit quantization feasible on a board with just 512KB of SRAM. Without it, the model simply would not fit.</p>
<h2 id="per-layer-embeddings-how-289m-parameters-fit-in-flash">Per-Layer Embeddings: How 28.9M Parameters Fit in Flash</h2>
<p>The breakthrough that makes on-device ESP32 LLMs practical is Google&rsquo;s Per-Layer Embeddings technique. Instead of keeping a full embedding matrix in fast memory, the approach stores the embedding table in flash and samples only the rows needed for the current token.</p>
<p>In the esp32-ai project, the model has 28.9M total parameters, of which 25M live in the flash lookup table. At each token, the system reads roughly 450 bytes from flash rather than loading the entire table. This is the difference between a model that fits and one that overflows the memory budget.</p>
<p>The result is a 14.9MB model at 4-bit quantization that runs end-to-end at 9.88 tokens/sec. The project ships two example models: Barista, which answers questions about espresso, and TinyStories, which generates short stories. Both are trained on the TinyStories dataset, which is why they cannot answer general questions, follow instructions, write code, or recall facts.</p>
<p>This is the fundamental limitation to understand: the technique makes a small model fit, but it does not make the model smarter. The model is only as capable as its training data.</p>
<h2 id="choosing-a-chip--esp32-s3-vs-esp32-p4-for-ai">Choosing a Chip — ESP32-S3 vs ESP32-P4 for AI</h2>
<p>If you are serious about running LLM commands on embedded hardware, the chip you choose matters more than almost anything else. The two main candidates are the ESP32-S3 and the ESP32-P4.</p>
<table>
  <thead>
      <tr>
          <th>Feature</th>
          <th>ESP32-S3</th>
          <th>ESP32-P4</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>SRAM</td>
          <td>512KB</td>
          <td>Larger (with DIRAM)</td>
      </tr>
      <tr>
          <td>PSRAM</td>
          <td>Up to 8MB</td>
          <td>Up to 32MB</td>
      </tr>
      <tr>
          <td>Flash</td>
          <td>Up to 16MB</td>
          <td>Up to 16MB+</td>
      </tr>
      <tr>
          <td>Clock</td>
          <td>240MHz</td>
          <td>400MHz</td>
      </tr>
      <tr>
          <td>AI acceleration</td>
          <td>None (ESP-DSP SIMD)</td>
          <td>XespV (up to 30x speedup)</td>
      </tr>
      <tr>
          <td>Max model size</td>
          <td>~28.9M params (single board)</td>
          <td>~180.9M params</td>
      </tr>
      <tr>
          <td>Typical cost</td>
          <td>~$6-10</td>
          <td>~$6-10</td>
      </tr>
      <tr>
          <td>Agent capability</td>
          <td>Limited</td>
          <td>Early Instruct/Agent (unstable)</td>
      </tr>
  </tbody>
</table>
<p>The ESP32-P4 is a major upgrade for AI workloads. It supports up to 32MB of PSRAM, runs at 400MHz, and includes XespV hardware acceleration that delivers up to 30x speedup on certain operations. The p-for-llm project runs a 180.9M-parameter model on the P4 at about 9 tokens/sec using a PLE-MoE-W1.58A8 architecture that mixes ternary, Q8, and FP16 storage totaling roughly 44MiB across flash and PSRAM.</p>
<p>The P4 also has early Instruct (ChatML) and Agent capabilities, though they are still unstable. If your goal is a real embedded AI agent that can follow commands, the P4 is the more promising path. The S3 is cheaper and more widely available, but it is limited to the smallest models.</p>
<h2 id="setting-up-the-toolchain-esp-idf-fetch_modelsh-deploysh">Setting Up the Toolchain (ESP-IDF, fetch_model.sh, deploy.sh)</h2>
<p>Getting a model onto an ESP32 requires the ESP-IDF toolchain and a two-step workflow. The esp32-ai project provides a clean template you can follow.</p>
<p>First, install the ESP-IDF development environment. This is the standard Espressif toolchain for building and flashing firmware. Once it is set up, the workflow is:</p>
<ol>
<li><strong>fetch_model.sh</strong> — downloads the model and verifies its integrity. This ensures you have the correct weights before you try to flash them.</li>
<li><strong>deploy.sh</strong> — compiles the firmware and flashes it to the board.</li>
</ol>
<p>The model weights are transferred to the board over USB at startup in some setups, which keeps the flash footprint small. If you add an SD card, the P4 can run fully offline without needing to re-transfer weights on every boot.</p>
<p>For the S3, the AIWintermuteAI/esp32-llm project shows the optimization path: dual-core math, ESP-DSP SIMD dot products, a 240MHz CPU with 80MHz PSRAM overclock, and a larger instruction cache. These optimizations pushed a 260K-parameter model to 19.13 tokens/sec. Even a small model needs about 1MB of RAM, so choose a board with PSRAM and flash headroom.</p>
<h2 id="building-a-command-ready-on-device-model">Building a Command-Ready On-Device Model</h2>
<p>If you want an on-device model that can actually respond to commands, you need to think about what &ldquo;command&rdquo; means at this scale. A model trained on TinyStories cannot follow instructions, so you cannot just ask it to do things.</p>
<p>The realistic approach is to build a model that recognizes a fixed vocabulary of commands and produces short, predictable responses. This works well for voice replies and command recognition, where the output space is small and well-defined. The 9-20 tokens/sec throughput is fine for these use cases.</p>
<p>For a command-ready model, you would train or fine-tune on a dataset that matches your specific commands, then quantize to 4-bit or W1.58 to fit the memory budget. The quantization choice matters: 4-bit is the sweet spot for the S3, while the P4&rsquo;s W1.58A8 mixed-precision approach packs more parameters into the same footprint.</p>
<p>The key expectation to set: at this scale, the model is a command recognizer and short-response generator, not a general assistant. It can tell you the weather if you hard-code the logic, but it cannot reason about the world.</p>
<h2 id="going-further--multi-board-distributed-inference-and-kv-caches">Going Further — Multi-Board Distributed Inference and KV Caches</h2>
<p>When a single board&rsquo;s flash is not enough, you can split the model across multiple boards. The wladimiravila/esp32s3-distributed-ai project runs a 56M-parameter LLM across three ESP32-S3 boards communicating over ESP-NOW.</p>
<p>The architecture uses a technique called Split-PLE, where the 50.3M-parameter embedding table is split across boards A and B so each fits in 16MB of flash. Board C hosts the WiFi and a web server, streaming generated text to a browser via Server-Sent Events (SSE). Board B keeps a 1.5MB KV cache in PSRAM (256 positions) so the transformer can attend to the full sequence.</p>
<p>This distributed approach shows how to scale past a single board&rsquo;s limits, but it adds real complexity. You now have to manage inter-board communication, synchronization, and the latency of ESP-NOW. It is a research-grade solution, not something you would deploy casually.</p>
<p>The KV cache is the other scaling lever. By keeping the key-value cache in PSRAM, the model can attend to longer sequences without recomputing. This is essential for anything beyond the shortest responses.</p>
<h2 id="when-to-offload--cloud-assisted-voice-and-agent-commands">When to Offload — Cloud-Assisted Voice and Agent Commands</h2>
<p>If you need real agent behavior — instruction following, factual answers, code generation — a fully on-device SLM will not cut it. The honest answer is that command execution at this level requires either a bigger chip or a cloud model.</p>
<p>The cloud-assisted path is well established. The ElatoAI project runs realtime voice AI on ESP32 backed by Cloudflare Durable Objects and Workers AI, using Deepgram for speech-to-text and text-to-speech. It supports 100+ voice models and secure WebSockets for conversations lasting more than 20 minutes. This is the &ldquo;agent&rdquo; path for command-style interaction: the ESP32 handles audio capture and playback, while the heavy lifting happens in the cloud.</p>
<p>The alternative is a local model on a more powerful device. The local-ai-toys project supports local LLMs and TTS (Qwen, Mistral) via MLX on ESP32 devices, bridging the gap between fully-on-device and fully-cloud.</p>
<p>The decision comes down to your constraints. If privacy, offline operation, and cost are paramount, accept the limits of an on-device SLM. If you need real intelligence, offload to the cloud and use the ESP32 as a smart peripheral.</p>
<h2 id="practical-limits-and-what-an-embedded-slm-can-and-cant-do">Practical Limits and What an Embedded SLM Can and Can&rsquo;t Do</h2>
<p>It is worth being explicit about the limits, because the marketing around &ldquo;AI on microcontrollers&rdquo; often oversells what is possible.</p>
<p><strong>What an embedded SLM can do:</strong></p>
<ul>
<li>Generate short, predictable responses at 9-20 tokens/sec</li>
<li>Recognize a fixed vocabulary of commands</li>
<li>Produce voice replies and simple text output</li>
<li>Run fully offline and privately on a $6 board</li>
</ul>
<p><strong>What an embedded SLM cannot do:</strong></p>
<ul>
<li>Follow arbitrary instructions</li>
<li>Answer factual questions</li>
<li>Write or debug code</li>
<li>Recall knowledge beyond its narrow training data</li>
<li>Maintain long, coherent conversations without a KV cache</li>
</ul>
<p>The 28.9M-parameter model on the S3 is trained on TinyStories, so it generates stories but cannot answer questions. The 180.9M-parameter model on the P4 has early Instruct and Agent capabilities, but they are unstable. The 260K-parameter tinyllamas model is a proof of concept that the authors themselves describe as &ldquo;not very useful&rdquo; for real tasks.</p>
<p>Set your expectations accordingly. An embedded SLM is a command recognizer and short-response generator, not a general assistant.</p>
<h2 id="conclusion--building-a-real-embedded-ai-agent">Conclusion — Building a Real Embedded AI Agent</h2>
<p>Running LLM commands on an ESP32 is genuinely possible, and the ecosystem is maturing fast. The ESP32-S3 can run a 28.9M-parameter model on-device at ~10 tokens/sec using Per-Layer Embeddings and a three-tier memory layout. The ESP32-P4 pushes this to 180.9M parameters with hardware acceleration and early agent capabilities.</p>
<p>The path to a real embedded AI agent depends on your definition of &ldquo;agent.&rdquo; For fixed command recognition and short voice replies, a fully on-device SLM on an S3 or P4 is enough. For true instruction-following and reasoning, you need either a distributed multi-board setup or a cloud-assisted architecture where the ESP32 handles the interface and the cloud handles the intelligence.</p>
<p>Start with the esp32-ai workflow: install ESP-IDF, run fetch_model.sh and deploy.sh, and get a model flashing on a board with PSRAM and flash headroom. Then decide whether your commands fit in a small on-device model or whether you need to offload. Either way, the hardware is cheap, the tools are open source, and the field is moving quickly.</p>
<h2 id="faq">FAQ</h2>
<p><strong>Can you run an LLM on an ESP32?</strong>
Yes. An ESP32-S3 can run a 28.9M-parameter language model fully on-device at about 9.88 tokens/sec, and an ESP32-P4 can run a 180.9M-parameter model at about 9 tokens/sec.</p>
<p><strong>What is the best ESP32 for running LLM commands?</strong>
The ESP32-P4 is the best choice for AI because it supports up to 32MB of PSRAM, runs at 400MHz, and has XespV hardware acceleration with up to 30x speedup. The ESP32-S3 is cheaper but limited to the smallest models.</p>
<p><strong>How do you fit a language model into an ESP32&rsquo;s limited memory?</strong>
By using a three-tier memory layout: activations and norm weights in SRAM, core and head weights in PSRAM, and the embedding table in flash. Google&rsquo;s Per-Layer Embeddings technique stores 25M parameters in flash and samples only ~450 bytes per token.</p>
<p><strong>Can an ESP32 LLM follow instructions or answer questions?</strong>
Not reliably. Models trained on narrow datasets like TinyStories cannot follow instructions, answer questions, write code, or recall facts. Real instruction-following requires a bigger chip or a cloud model.</p>
<p><strong>What is the difference between on-device and cloud-assisted ESP32 AI?</strong>
On-device AI runs a small model locally for privacy and offline operation, but it is limited to simple commands. Cloud-assisted AI uses the ESP32 for audio and interface while a cloud model (like Cloudflare Workers AI) handles the intelligence, enabling real agent behavior.</p>
]]></content:encoded></item></channel></rss>