九州・福岡・東京ときどきIoT

21年間のはてなダイアリー&アメブロからの避難所

esp32s3でローカルでLLMを動かしたいー2

 

新しいプロジェクト esp32-llm についてです。こちらの移植手順について解説します。

まず、ご質問の「こちらのほうが簡単であると思うが?」という点についてですが、一見シンプルに見えますが、技術的なハードルは前回の xiaozhi-esp32 よりもむしろ高い可能性があります。

 

xiaozhi-esp32esp32-llm の違い

 

  xiaozhi-esp32 (前回) esp32-llm (今回)
処理方式 クラウドベース ローカル/オフライン
処理の流れ 録音 → クラウドAPI音声認識・対話 → クラウドAPI音声合成 → 再生 録音 → ESP32上で音声認識ESP32上でLLMが応答を生成 → 画面表示
主な技術 Web API連携 (HTTP, JSON) オンデバイスAI (機械学習モデルの実行)
開発環境 Arduino ESP-IDF (より専門的)
必須要件 インターネット常時接続 PSRAM付きの高性能なESP32-S3

xiaozhi-esp32はインターネット上のAIに処理を「丸投げ」するIoTクライアントでしたが、esp32-llmESP32-S3自体が小さな言語モデル(LLM)を動かして応答を生成する、非常に高度なエッジAIプロジェクトです。

結論として、APIキーの管理は不要になりますが、ハードウェア要件(特にPSRAM)と開発環境(ESP-IDF)のハードルが格段に上がります。


 

移植のための前提条件

 

このプロジェクトを進める前に、絶対に確認が必要な2つの前提条件があります。

  1. PSRAMの有無:

    お使いのESP32-S3開発ボードに**PSRAM (疑似SRAM)**が搭載されていますか? LLMのような巨大なモデルを動かすには、内蔵RAMだけでは全く足りず、外部PSRAMが必須です。もしPSRAMがなければ、このプロジェクトを動かすことはほぼ不可能です。

    (一般的なESP32-S3開発ボードには8MBや16MBのPSRAMが搭載されていることが多いです)

  2. ESP-IDF開発環境:

    このプロジェクトはArduinoではなく、ESP-IDF (Espressif IoT Development Framework) という、より専門的な開発環境を使用します。もし今までArduino IDEしか使ったことがなければ、まずESP-IDFの環境構築から始める必要があります。


 

移植の基本手順 (上記条件を満たしている場合)

 

esp32-llmは特定の開発ボード(ESP32-S3-BOXなど)を前提に作られているため、ご自身のカスタムハードウェアに合わせるには、ソースコードの設定ファイル(menuconfig)とドライバ部分の修正が必要です。

 

ステップ1: ESP-IDF環境のセットアップとプロジェクトの取得

 

  1. 上記のガイドに従い、ご自身のPCにESP-IDFのツールチェーンをインストールします。

  2. ターミナル(コマンドプロンプトPowerShell)を開き、プロジェクトをGitHubからクローン(ダウンロード)します。

    Bash
     
    git clone https://github.com/AIWintermuteAI/esp32-llm.git
    cd esp32-llm
    
  3. サブモジュール(プロジェクトが依存する他のリポジトリ)を更新します。

    Bash
     
    git submodule update --init --recursive
    

 

ステップ2: ハードウェア構成の設定 (menuconfig)

 

esp32-llmプロジェクトのディレクトリ内で、設定ツール menuconfig を起動します。

Bash
 
idf.py menuconfig

このツールで、お使いのハードウェアに合わせて設定を変更します。

  • マイク (INMP441) の設定:

    1. Component config ---> ESP Speech Recognition ---> Model configuration

      • ここで使用する音声認識モデル(WakeNet, MultiNetなど)を設定します。

    2. Component config ---> ESP ADF (Audio Development Framework) ---> ADF I2S Configuration (または同等の項目) を探します。

    3. I2Sのピン設定を以下のように変更します。

      • I2S_BCK_PIN: 40

      • I2S_LRCK_PIN: 38

      • I2S_DATA_IN_PIN: 39

  • ディスプレイの設定:

    menuconfig内に、ご自身のディスプレイ(ST7789)用の直接的な設定項目はない可能性が高いです。そのため、ここは一旦デフォルトのままにして、次のステップでソースコードを直接編集します。

設定が完了したら、Save -> Exit で終了します。

 

ステップ3: ディスプレイドライバのソースコード書き換え

 

ここが最も難しい部分です。プロジェクト内のディスプレイ描画を担当しているCファイル(例: main/board_init.ccomponents/display/display.c など)を探し出し、ESP32-S3-BOX用のドライバ初期化部分を、ご自身のST7789用ドライバを呼び出すコードに置き換える必要があります。

これはArduinoAdafruit_ST7789 ライブラリを直接使うのではなく、ESP-IDFのSPIドライバを使ってST7789を初期化するコードを書くことを意味します。以下に概念的なコードを示します。

修正対象のファイル (例: display.c など) の中で:

C
 
// 元のコード (ESP32-S3-BOX用など) をコメントアウトまたは削除
// ex: bsp_display_start();

// ★ここから、汎用SPIディスプレイ用の初期化コードを追加
#include "driver/spi_master.h"
#include "driver/gpio.h"

// TFTピン定義
#define TFT_CS    14
#define TFT_DC    47
#define TFT_RST   21
#define TFT_MOSI  45
#define TFT_SCLK  3
#define SPI_HOST  SPI2_HOST // 使用するSPIホスト

// ST7789を初期化する関数 (コマンド送信など) を自前で用意する必要がある
void st7789_init(spi_device_handle_t spi) {
    // リセット処理
    gpio_set_level(TFT_RST, 0);
    vTaskDelay(pdMS_TO_TICKS(100));
    gpio_set_level(TFT_RST, 1);
    vTaskDelay(pdMS_TO_TICKS(100));

    // ST7789の初期化コマンドシーケンスを送信...
    // ex: spi_master_write_cmd(...);
}

void display_init() {
    // SPIバスの初期化
    spi_bus_config_t buscfg = {
        .mosi_io_num = TFT_MOSI,
        .sclk_io_num = TFT_SCLK,
        .miso_io_num = -1, // MISOは使わない
        .quadwp_io_num = -1,
        .quadhd_io_num = -1,
        .max_transfer_sz = 320 * 240 * 2 + 8
    };
    spi_bus_initialize(SPI_HOST, &buscfg, SPI_DMA_CH_AUTO);

    // SPIデバイスの初期化
    spi_device_interface_config_t devcfg = {
        .clock_speed_hz = 40 * 1000 * 1000, // 40MHz
        .mode = 0,
        .spics_io_num = TFT_CS,
        .queue_size = 7,
        .pre_cb = NULL,
    };
    spi_device_handle_t spi;
    spi_bus_add_device(SPI_HOST, &devcfg, &spi);

    // GPIOピン(DC, RST)の初期化
    // ...

    // ST7789の初期化
    st7789_init(spi);
}

ご覧の通り、Arduinoライブラリのように簡単にはいかず、ESP-IDFの作法に則ったドライバレベルのコーディングが必要になります。

 

ステップ4: ビルドと書き込み

 

すべての設定と修正が完了したら、ターミナルからビルドと書き込みを行います。

Bash
 
# プロジェクトをビルド
idf.py build

# ボードに書き込み (COMポートはご自身の環境に合わせる)
idf.py -p COM5 flash

# 書き込みとシリアルモニタの起動
idf.py -p COM5 flash monitor

AI

まとめと推奨事項

 

  • 難易度: この移植は、Arduinoの手軽な開発とは異なり、組み込みLinuxに近いレベルの知識(ドライバ、メモリ管理、開発ツールチェーン)が要求される上級者向けのプロジェクトです。

  • PSRAMの確認: まずは、お使いのボードにPSRAMが搭載されているか、仕様を再確認してください。これがなければ始まりません。

  • 段階的アプローチ:

    1. まず、ESP-IDFの環境構築を完了させてください。

    2. 次に、esp32-llmではなく、ESP-IDFのサンプルプロジェクトの中から、ご自身のST7789ディスプレイをSPI接続で表示させる簡単なプログラムを動かすことを目標にしてください。LVGLグラフィックライブラリのサンプルなどが参考になります。

    3. それが成功して初めて、esp32-llmの移植に着手するのが現実的なステップとなります。

esp32-llmは非常に魅力的ですが、その分、要求されるスキルセットも高くなります。まずはESP-IDF環境に慣れることから始めてみてください。