⚠️

Twins : M5Stack AI Pyramidを買ったらメモリの壁が立ちはだかった

に公開

M5Stack AI Pyramid (4GB) 実機調査レポート

調査日:2026年3月5〜6日
調査者:キノセ + Claude

個人的に調べた程度のものなので、すべて参考程度のものだとご理解ください
アップデートにより翌日には別物になってるかもしれないので、都度確認しましょう
今の時代、AIが拾ってって、誤情報拡散しちゃうから注意文必須ですね・・

Proモデルが売り切れていたので仕方なく4GBモデルを買ったが、激しく後悔している記録
 Linuxのコマンドなんも知らんので、Claude任せで調べてもらったのを書き出してもらってます


基本情報

項目 内容
製品名 M5Stack AI Pyramid Computing Box 4GB
チップ Axera AX8850 SoC
CPU Octa-core ARM Cortex-A55 @ 1.7GHz
NPU 24 TOPS @ INT8
RAM 4GB LPDDR4x(システム2GB + NPU/Video 2GB)
ストレージ 32GB eMMC
OS Ubuntu 22.04 LTS (aarch64)
カーネル Linux 5.15.73
デバイスツリー compatible axera,ax650x
価格 $199
購入先 M5 STACK https://shop.m5stack.com/
スイッチサイエンス https://www.switch-science.com/

メモリ構成(重要)

dmesg出力: "Memory limited to 2048MB"
MemTotal: 1958104 kB(約1.9GB)

4GBのうち2GBがカーネル起動時に強制制限されてる?
残り2GBはNPU/ビデオエンジン専用でOSから見えない。
LLMが使えるのは実質2GBのみ


ネットワーク・接続情報

  • SSH接続:ssh root@<IPアドレス> 初期パスワード 123456
    (IPアドレスは本体の液晶に出る親切設計)
  • OpenAI互換APIサーバー:http://<IP>:8000/v1
  • LAN:eth0(有線)、eth1(有線)の2ポート
  • WiFi:内蔵なし

プリインストール構成

/opt/m5stack/bin/ に以下のサービスが起動時から動作:

サービス ポート 内容
llm_sys 10001 システム管理
llm_llm 内部 LLM推論エンジン
llm_asr 内部 音声認識(ASR)
llm_audio 内部 音声処理
llm_kws 内部 キーワードスポッティング
llm_melotts 内部 TTS
llm_openai_api 8000 OpenAI互換APIサーバー
tokenizer(python3) 8080(localhost) Qwen2.5トークナイザー

起動時からOpenAI互換APIがポート8000で動いている


デフォルトで動くモデル

モデル 用途
qwen2.5-0.5B-Int4-ax650 LLM
sense-voice-small-10s-ax650 音声認識
melotts-ja-jp-ax650 日本語TTS
melotts-en-default-ax650 英語TTS
melotts-zh-cn-ax650 中国語TTS
sherpa-onnx-streaming-zipformer-small-bilingual-zh-en 音声認識(別系統)

aptで追加できるモデル(M5Stack独自リポジトリ)

LLM系

モデル 動作確認 備考
qwen2.5-0.5B-Int4-ax650 デフォルト
qwen2.5-1.5B-Int4-ax650 他サービス停止が必要、応答約1分
qwen2.5-3B-Int4-ax650 未確認
qwen2.5-7B-Int4-ax650 メモリ不足(Required: 1919044KB)
deepseek-r1-1.5B-int4-ax650 未確認
deepseek-r1-7B-int4-ax650 未確認

VLM系

モデル 動作確認 備考
smolvlm-256M-ax650 カメラ画像理解OK、精度は低め
internvl3-1B-448-ax650 メモリ不足(Required: 1919044KB)
internvl2.5-1B-448-ax650 未確認
qwen3-vl-2b-int4-ax650 未確認

音声系

モデル 備考
whisper-tiny/base/small-ax650 NPUで高速動作の可能性
cosyvoice2-0.5B 音声クローニング対応

その他モジュール

パッケージ 内容
llm-yolo YOLOモジュール
llm-vlm VLMモジュール(smolvlm等に必要)
llm-camera カメラモジュール
llm-depth-anything 深度推定

動作確認済み機能

機能 結果 備考
SSH接続
OpenAI互換API ポート8000
qwen2.5-0.5B テキスト生成
qwen2.5-1.5B テキスト生成 他サービス停止要、約1分
qwen2.5-7B メモリ不足
smolvlm-256M テキスト応答
smolvlm-256M 画像理解 カメラ映像からシーン説明可能
internvl3-1B メモリ不足
USBカメラ認識 /dev/video0
fswebcam での撮影
日本語TTS起動 音声出力テストは未実施

WiFi接続について

カーネルヘッダー(linux-headers-5.15.73)がaptで入手不可のため、
ソースからのドライバビルドが不可能。

アダプタ チップ 結果
TP-Link Archer T3U Plus RTL8812BU/RTL8822BU ❌ ドライバなし
ELECOM WDC-433SU2M2 RTL8821AU ❌ ドライバなし

対策:イーサネットコンバータ(無線LAN子機)を使う
ピラミッド側はLANケーブル接続のみ、設定不要で確実。


実用上の制約まとめ

  • システムメモリが実質2GBのため1.5B超のモデルは動作困難
  • VLMとLLMの同時動作は不可
  • CPUはCortex-A55でラズパイ5(A76)より低性能
  • カーネルがカスタムビルドのためドライバ追加が困難
  • スワップなし

現実的な用途

向いていること

  • smolvlmによるカメラ映像の概況把握(シーン理解)
  • 日本語TTSによる音声出力
  • 音声認識(ASR)+キーワードスポッティング
  • OpenAI互換APIサーバーとしてLAN内で提供

向いていないこと

  • 7B以上のLLM推論
  • ラズパイのLLMオフロード先
    (4GBモデルはモデルサイズの制約が大きく、ラズパイ500のOllama(qwen3:1.7B動作中)と比較してモデル選択肢が少ない)
  • OpenCVとVLMの同時処理
  • WiFiアダプタの自由な追加

8GB Proモデルとの比較

4GB(今) 8GB Pro
価格 $199 $249
システムメモリ 2GB 4GB
NPU専用メモリ 2GB 4GB
qwen2.5-7B ✅ 見込み
internvl3-1B ✅ 見込み
VLM+LLM同時 ✅ 見込み
入手状況(2026/03時点) 在庫あり 売り切れ

今後の検証課題

  • ラズパイ500とのLAN直結・ブリッジ接続
  • smolvlmの実用速度測定(カメラ→応答まで何秒?)
  • TTSの実音声出力テスト
  • llm-yoloモジュールの動作確認
  • OpenCVのインストール可否確認
  • ラズパイ500(Ollama)との役割分担テスト

参考:APIの使い方

モデル一覧取得

curl http://<IP>:8000/v1/models

テキスト生成

curl http://<IP>:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen2.5-0.5B-Int4-ax650",
    "messages": [{"role": "user", "content": "こんにちは"}]
  }'

画像理解(Python)

import base64, json, urllib.request

with open("/tmp/cam.jpg", "rb") as f:
    img = base64.b64encode(f.read()).decode()

payload = json.dumps({
    "model": "smolvlm-256M-ax650",
    "messages": [{
        "role": "user",
        "content": [
            {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{img}"}},
            {"type": "text", "text": "What do you see?"}
        ]
    }]
}).encode()

req = urllib.request.Request(
    "http://localhost:8000/v1/chat/completions",
    data=payload,
    headers={"Content-Type": "application/json"}
)
res = urllib.request.urlopen(req)
print(json.loads(res.read())["choices"][0]["message"]["content"])

カメラ撮影

fswebcam -r 640x480 /tmp/cam.jpg

Discussion