ESP32S3と16MBフラッシュでリアルタイム入力を受け取るオンデバイスLLMの作成
TuBrief 편집팀
2026년 8월 12일
0
Computing/Software원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
커뮤니티의 다른 글
댓글 (0)
Log in to leave a comment
아직 작성된 글이 없습니다
원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
Log in to leave a comment
아직 작성된 글이 없습니다
8ドルのESP32-S3ボードで2,890万パラメータの言語モデルを動かそうと決意すると、すぐに途方に暮れることになります。デモ映像ではスムーズに動くモデルが、自分が作ったハードウェア周辺機器と組み合わさると途端にフリーズしてしまうからです。SRAMはわずか512KBしかなく、文章を一つ変えるたびに15MBのパーティションを書き直さなければならないと、開発中についイライラしてしまいます。この制約を突破して実際にキーパッド入力を受け付けて動作するデバイスを作るには、メモリキャッシュと入出力バッファを最初から設計し直す必要があります。
テスト文を一つ変えるたびにボードを焼き直すようなやり方は、時間の無駄です。非同期UART割り込みとFreeRTOSセマフォを組み合わせれば、ボードを再起動する必要はありません。シリアルモニターやキーパッドで文章を入力するそばから、モデルが即座に理解します。
この構成を整えておけば、プロンプトの修正とテストにかかる時間を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) |
+------------------+ +-------------------+ +--------------------+
`
Google Gemma 3nの研究陣が提案したPer-Layer Embeddings (PLE)構造を使用すると、4ビットに圧縮した14.9MBのモデルを分割して配置できます。2,500万パラメータに達する埋め込みテーブルは16MBのSPIフラッシュに置き、Output Headの重み(310万パラメータ)とKVキャッシュは8MBのPSRAMに配置します。最も頻繁に使用される559KパラメータのDense Compute CoreとHot Activationバッファのみを512KBのSRAMに埋め込みます。
速度を秒間14トークン以上に引き上げる作業は、想像以上に手強いものです。
__attribute__((noinline))属性をしっかりと付与します。コンパイラが勝手にインライン化を進めてしまうと、I-RAMのキャッシュミスが発生し、演算時間が94.9msから155.2msにかえって悪化してしまいます。C言語でただ移植しただけでは、秒間0.57トークンという絶望的な速度になります。しかし、INT8ステージングとSRAMプリフェッチまで完了させると、秒間14.0トークンを超えてきます。
| 最適化段階 | トークンあたりの演算遅延時間 | 秒間トークン生成数 | 主な適用技術 |
|---|---|---|---|
| C純粋移植 (Baseline) | 1,757.2 ms | 0.57 tok/s | シングルコア、FP32演算 |
| PSRAM Head & スカラー最適化 | 193.9 ms | 4.61 tok/s | Output Head PSRAM配置 |
| デュアルコアFP32適用 | 139.4 ms | 6.22 tok/s | デュアルコアレイヤー分割演算 |
| INT8 Staging + SRAM最適化 | 94.9 ms | 9.88 tok/s | INT8量子化、noinline適用 |
| SRAMプリフェッチバッファ拡張 | ~71.4 ms | 14.0+ tok/s | 初期レイヤーSRAMプリフェッチ |
240MHzのクロックでデュアルコアを稼働させ続けると、消費電流が210mA (777mW)まで跳ね上がります。ボードが熱くなることは言うまでもなく、バッテリーが瞬く間に消耗してしまいます。esp_pm_configureコマンドを使用して、推論が行われていないときはクロックを40MHzに下げ、自動ライトスリープをかける必要があります。
esp_sleep_pd_config(ESP_PD_DOMAIN_VDDSDIO, ESP_PD_OPTION_ON)を実行します。スリープ状態に入ってもSPIフラッシュとRAMの電源は維持し、データが消えないようにする必要があります。3.7V 1000mAhのリチウムポリマーバッテリーで演算を続けさせると、4.7時間しか持ちません。しかし、ライトスリープ待機モードでは電流が0.24mA (0.88mW)まで急減します。待機時間が混ざり合う実際の使用環境では、平均電流が15〜30mAのレベルに維持され、バッテリーの駆動時間が3倍以上に延びます。