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

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

raspberry pi で、STTしてLLMしてTTSしたい話し

STTしてLLMしてTTSしたい話し


「すべて Raspberry Pi 上でローカル完結」
以下の課題がポイントになります:

---

## 1. モデルサイズとPiの処理能力

* **Tanuki-8B** は 8B パラメータ級 → Pi 4/5 のCPUオンリーではほぼ無理です。
  GPUなし環境なら **量子化(Q4_K_Mなど)** 必須。
  Ollama は量子化済みモデルを扱えるので、Pi 5 (16GB RAM推奨) ならギリ動きます。
* Pi 4 (8GB) だと 3B〜4B クラスまでが現実的。
  → もし 8B にこだわるなら Pi 5 一択です。

---

## 2. 音声認識(STT)

* **Julius** → 軽量だが精度低め。
* **Whisper.cpp (tiny / baseモデル)** → Pi 上でも動作可能、精度高め。
  *完全ローカルならこちら推奨*。

---

## 3. 音声合成(TTS)

* **Edge-TTS** は実はクラウド利用前提なので「完全ローカル」にはなりません。
* ローカル完結なら:

  * **Open JTalk**(日本語対応)
  * **VOICEVOX Engine (ONNX版)** (Raspberry Pi 5 なら可)

  → 軽量なら **Open JTalk**、高品質なら **VOICEVOX**。

---

## 4. 構成例(全部ローカル版)

### ハード

* Raspberry Pi 5 (16GB) + USBマイク + スピーカー

### ソフト

* **Ollama** + 量子化 Tanuki-8B(Q4版)
* **Whisper.cpp**(STT)
* **Open JTalk**(TTS)
* Python スクリプトで統合

---

## 5. 制御フロー

```
マイク入力 → Whisper.cpp (STT)
    ↓
テキスト入力 → Ollama(Tanuki-8B, Q4版)
    ↓
返答テキスト → Open JTalk (TTS)
    ↓
スピーカー出力
```

---

## 6. Python 制御スケッチ(完全ローカル)

```python
import subprocess

def recognize_speech():
    # Whisper.cpp を使って録音→文字起こし
    subprocess.run(["arecord", "-d", "5", "-f", "cd", "input.wav"])
    result = subprocess.run(
        ["./whisper.cpp/main", "-m", "models/ggml-base.bin", "-f", "input.wav"],
        capture_output=True, text=True
    )
    return result.stdout.strip()

def query_ollama(prompt):
    result = subprocess.run(
        ["ollama", "run", "tanuki:8b"],
        input=prompt,
        text=True,
        capture_output=True
    )
    return result.stdout.strip()

def speak(text):
    subprocess.run(["open_jtalk",
        "-x", "/var/lib/mecab/dic/open-jtalk/naist-jdic",
        "-m", "htsvoice/mei_normal.htsvoice",
        "-ow", "out.wav"
    ], input=text, text=True)
    subprocess.run(["aplay", "out.wav"])

def main():
    print("話しかけてください...")
    user_input = recognize_speech()
    print("認識:", user_input)

    response = query_ollama(user_input)
    print("応答:", response)

    speak(response)

if __name__ == "__main__":
    main()
```

---

## まとめ

* **8Bモデル** → Pi 5 (16GB) + 量子化モデルでギリ動作
* **STT** → Whisper.cpp(精度&ローカルOK)
* **TTS** → Open JTalk(軽量&ローカル完結)

---

👉 そこで確認ですが、
ご利用予定の **Raspberry Pi のモデル(Pi 4 or Pi 5)とメモリ容量** はどれでしょうか?
それで「Tanuki-8B が動くか」「3Bや7Bに落とすか」の最適解が決まります。