>100 Views
March 15, 26
スライド概要
なごあずのイベントで登壇した資料です。2026/03/14(土)15:30 〜 17:30
https://75az.connpass.com/event/383389/
愛知 / SE / Azure / AzPoC部
gpt-realtime-1.5 モデルで スタックチャン 2026/03/14 なごあず #75 しろくま Hiroki, Nomura
プロフィール しろくま 愛知県在住のエンジニアです。 技術関係のブログを書いたり、登壇したりしています。 所属 AzPoC部 #AzPoC なごあず #75azu Solution Architect AI Engineer Developer Administrator Network Engineer
今日話すこと 組み込み開発初心者ですが、gpt-realtime-1.5 を使って M5Stack CoreS3 をスタックチャンにしておしゃべりできるようにしました!! 組み込みやIoTをやったことがない、ど初心者です。お手柔らかに優しいお気持ちでお聞きください… 1. スタックチャンって何? & 使った技術 2. システム全体のアーキテクチャ 3. ハマったポイントと解決策 4. 中継サーバ & ツール呼び出し
スタックチャンってナニ?
https://protopedia.net/prototype/2345 https://protopedia.net/prototype/4052
https://protopedia.net/prototype/5496
あたしの子は、アタマダケ
きっかけは。。。 Maki-san https://x.com/yuma_prog
スタックチャンとは? 「コミュニケーションロボットを、あなたの 手に」 M5Stackベースの手乗りサイズロボット 作者: Shinya Ishikawa さん かわいい顔の表示と表情変化 視線制御・音声出力・サーボ制御 カスタムアプリ開発が可能 Apache 2.0 の完全オープンソース!! ハード設計・3Dデータ・ファームウェア全公開 コミュニティ GitHub 1,300+ Stars / 148 Forks Discordコミュニティあり Xのスタックチャンアカウントは、スタックチャンに関して 投稿すると捕捉していいねくれます
今回の実装で何ができるようになった? スタックチャン + gpt-realtime-1.5 で実現したこと 今回の実装で実現したこと: 話しかけるだけで リアルタイム応答 AIが感情判断して表情が 自動変化 ボタン操作不要! 自然な対話 リップシンクで口の動きも 同期
アーキテクチャ
システムアーキテクチャ CoreS3 Node.js Azure OpenAI (ファームウェア) (中継サーバ) (Realtime API) ●マイク入力 ●PCM16→base64 ●音声認識 (STT) ●スピーカー出力 ●バックプレッシャー ●応答生成 (LLM) ●アバター表示 ●リップシンク WebSocket (LAN内) ●ツール呼び出し Azureだったら、 AppServiceとか ContainerAppsとかへ WebSocket (wss://Azure) ●音声合成 (TTS) ●VAD
なぜ中継サーバを介すのか? CoreS3から直接Azure OpenAIに接続しない5つの理由 1 2 3 4 5 TLS接続の計算負荷 TLSハンドシェイクはESP32系には重く不安定。Node.jsで安定した暗号化接続を確保 音声エンコード変換 PCM16→base64変換を中継サーバが担当。CoreS3はraw PCMの送受信に集中できる バックプレッシャー制御 Azureの応答速度とCoreS3の処理速度のギャップをバッファリングで吸収 ツール呼び出し処理 Function CallingのJSON解析・外部API連携をNode.jsで処理し結果だけ返す APIキーの安全管理 ファームウェアへのキー埋め込みは漏洩リスク。サーバ側で秘匿管理
M5Stack CoreS3を使いました。
M5Stack CoreS3 ってどんなデバイス? 主要スペック ●プロセッサ:ESP32-S3 デュアルコア( 240MHz) この小さなデバイスに ●マイク:ES7210 デュアルマイク マイク・スピーカー・ ディスプレイ・Wi-Fi が ●スピーカー:AW88298(1W) 全部入ってる ●メモリ:Flash 16MB / PSRAM 8MB ●ディスプレイ:2.0" IPS(320×240)タ ッチ ●通信:Wi-Fi 2.4GHz / USB-C → 顔つきで対話させるのによさげ
CoreS3 の中身をもう少し詳しく 音声対話で重要なオーディオ周りの構成 オーディオ構成 その他のモジュール マイク(ES7210) ディスプレイ デュアルマイク → ノイズに強い 2.0" IPS (320×240) サンプルレート: 16kHz / 16bit → アバター表情の表示に使用 スピーカー(AW88298) Wi-Fi(ESP32-S3) 1W出力のクラスDアンプ内蔵 2.4GHz 802.11 b/g/n サンプルレート: 48kHz / 16bit → WebSocketで中継サーバに接続 ※ 同じI2Sバスを共有(後述) PSRAM 8MB → リングバッファの確保に活用
開発環境セットアップ 組み込み初心者でもこれだけ揃えればOK! 必要なツール ●VSCode + PlatformIO拡張 ●C++ 拡張機能 ●Node.js 18+ ●Azureサブスクリプション セットアップ手順 ① Azure PortalでOpenAIリソース作成 East US 2 or Sweden Central ② Azure AI Foundryでモデルデプロイ gpt-realtime-1.5 を選択 ③ ファームウェア書き込み config.h → Build → Upload ④ 中継サーバ起動 npm install → .env設定 → npm run dev
gpt-realtime-1.5って?
従来モデルとRealtimeモデルの違い 従来は3ステップ必要だった処理が、Realtimeモデルでは1ステップに!! 従来方式(STT → LLM → TTS) 音声 入力 STT 音声認識 テキスト LLM 推論 → 変換のたびにレイテンシが発生。感情・抑揚が失われ る テキスト TTS 音声合成 音声 出力 → 低レイテンシ。抑揚・感情もそのまま伝わる Realtimeモデル(Speech-to-Speech) 音声入力 gpt-realtime-1.5 音声 → 音声を直接処理! 音声出力
gpt-realtime-1.5 って何がすごいの? Azure OpenAI の最新リアルタイム音声対話モデル テキストではなく「音声で直接」やりとりできる!! 音声推論 文字起こし精度 指示追従 +5% +10% +7% 前世代比で改善 前世代比で改善 前世代比で改善
中継サーバ & ツール呼び出し
中継サーバの構成(TypeScript / Node.js) CoreS3とAzureのプロトコル差を吸収する中継役 DeviceServer(ポート8080) AzureRealtimeClient ●CoreS3からのWebSocket接続管理 ●Azure APIへの常時接続管理 ●PCM16バイナリ → base64 変換 ●session.updated の待機 ●JSONコマンド転送(表情・口パク) ●自動再接続(5秒間隔)
ツール呼び出しで表情を自動制御!! AIが会話の文脈から感情を判断して、自律的にアバターの表情を変える 1 2 3 4 5 ユーザーと 会話 AIが 感情判断 set_expression ツール呼出 中継サーバ が実行 CoreS3の 表情変更! 表情パターン: happy / sad / angry / sleepy / neutral ※プロンプトで感情判断ルールを指定
VAD(Voice Activity Detection) サーバサイドVADで「ボタン操作なし」の自然な対話を実現!! session.update の turn_detection で設定 500ms無音 → サーバが発話終了と判定 → 応答生成開始 従来の音声対話 ① ボタンを押して話す ② ボタンを離す ③ 応答を待つ 今回(VAD) ① ただ話しかけるだけ! ② AIが自動で聞き取り ③ すぐ応答が返ってくる
学んだこと・まとめ WebSocketリアルタイムストリーミング 双方向常時接続でのデータフロー管理を学んだ ESP32のオーディオ制約 I2Sバス排他制御とメモリ管理の大切さ プロデューサー / コンシューマーパターン リングバッファとバックプレッシャーの実装 AIツール呼び出し AIが自律的にハードウェアを制御する仕組み リアルタイムペース調整 速度の不整合が起こる問題と解決方法 組み込み初心者でも最新AIモデルと組み合わせれば面白いものが作れる!!
ハマったポイントと解決策
ハマり① I2Sバス排他制御 問題 解決策 マイクとスピーカーが同じI2Sバスを共有 → 同時に使えない!切替ミスで音が壊れ る 状態マシンで排他制御を実装 「停止 → 開始」の順序を厳密に管理 状態遷移フロー IDLE MIC ACTIVE MIC STOP SPK START SPK ACTIVE IDLE
ハマり② 音声データが速すぎる!! AIは再生速度より速く音声を生成する(1秒分が0.3秒で到着) → バッファオーバーフロー & WebSocketバッファも溢れる 解決① 1.5MBリングバッファ 解決② バックプレッシャー制御 PSRAMに約32秒分を確保 書込位置と読出位置を独立管理 → 速度不整合を吸収! 1024バイトずつ分割してキュー管理 前チャンク送信完了後に次を送信 → setImmediate() で実装
製造業でも生成AI活用したい! 名古屋LLM MeetUp#11 3/19(木) @なごのキャンパス
Thank you !