2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Whisper × LM Studio × 音声読み上げ × JSON履歴保存でローカル音声対話システムを構築する

Posted at

🎙️ Whisper × LM Studio × 音声読み上げ × JSON履歴保存でローカル音声対話システムを構築する

はじめに

『まるでSFの世界』だと思っていたAIとの音声会話を、ご自宅のPCで実現しませんか?

面倒な設定や複雑なプログラミングは不要です。今回は、直感的なGUI操作だけでローカルLLM(大規模言語モデル)を動かせる**「LM Studio」**を活用し、テキスト入力ゼロで応答してくれるローカル音声対話システムを構築します。

このシステムがあれば、インターネット接続なしで、あなたの声だけでAIと自由に会話が楽しめます。

かつて憧れた、私だけの 『2001年宇宙の旅』のHAL 9000。本記事は、そのパーソナルAIアシスタント構築に向けた、記念すべきはじめの一歩となるでしょう。


目次

目的
1.使用技術・ツール
2.必要なライブラリのインストール
3.LM Studioの設定
4.音声入力
5.音声認識(Whisper)
6.LM Studioへの問い合わせ
7.音声読み上げ(pyttsx3)
8.履歴保存
9.統合スクリプト
10.補足
まとめ


🎯 目的

Whisperで音声認識した内容をLM Studioに渡して応答を生成し、それを音声で読み上げ、履歴としてJSON形式で保存する一連の処理をPythonで統合。ローカル環境で完結するAI音声対話システムの構築を目指します。


🧩 1.使用技術・ツール

  • 🐍 Python 3.10+
  • 🗣️ OpenAI Whisper(音声認識)
  • 🧠 LM Studio(ローカルLLM応答生成)
  • 🔊 pyttsx3(音声読み上げ)
  • 🎤 pyaudio(マイク入力)
  • 🧰 ffmpeg(Whisper用)

🛠️ 2.必要なライブラリのインストール

pip install openai-whisper pyttsx3 requests pyaudio

Whisperの動作には ffmpeg が必要です。以下の手順で公式サイトからダウンロード&インストールしてください:
🔗 ffmpegのインストール手順(公式サイト)

  1. https://ffmpeg.org/download.html にアクセス
  2. ダウンロードしたファイルを展開し、 実行ファイルのパスを環境変数に追加

🧠 3.LM Studioの設定

  • LM Studioを起動し、ローカルで動作するモデルを選択
  • 「開発者」タブからAPIサーバーを有効化
  • Reachable at: http://127.0.0.1:1234

🎤 4.音声入力(録音)

import pyaudio
import wave

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
RECORD_SECONDS = 8
FILENAME = "recorded.wav"

def record_audio():
    audio = pyaudio.PyAudio()
    stream = audio.open(format=FORMAT, channels=CHANNELS,
                        rate=RATE, input=True,
                        frames_per_buffer=CHUNK)
    print("🎙️ 録音開始…")
    frames = []
    for _ in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
        data = stream.read(CHUNK)
        frames.append(data)
    print("🛑 録音終了。保存中…")
    stream.stop_stream()
    stream.close()
    audio.terminate()

    wf = wave.open(FILENAME, 'wb')
    wf.setnchannels(CHANNELS)
    wf.setsampwidth(audio.get_sample_size(FORMAT))
    wf.setframerate(RATE)
    wf.writeframes(b''.join(frames))
    wf.close()

📝 5.音声認識(Whisper)

import whisper

def transcribe_audio():
    model = whisper.load_model("base")
    result = model.transcribe("recorded.wav", language="ja")
    print("📝 認識結果:", result["text"])
    return result["text"]

🤖 6.LM Studioへの問い合わせ

import requests

def send_to_lmstudio(text):
    url = "http://localhost:1234/v1/chat/completions"
    headers = {"Content-Type": "application/json"}
    payload = {
        "model": "local-model",
        "messages": [{"role": "user", "content": text}],
        "temperature": 0.7
    }
    response = requests.post(url, headers=headers, json=payload)
    reply = response.json()["choices"][0]["message"]["content"]
    print("🤖 LM Studioの応答:", reply)
    return reply

🔊 7.音声読み上げ(pyttsx3)

import pyttsx3

def speak(text):
    engine = pyttsx3.init()
    voices = engine.getProperty('voices')
    engine.setProperty('voice', voices[0].id)
    engine.setProperty('rate', 150)
    engine.setProperty('volume', 1.0)
    engine.say(text)
    engine.runAndWait()

🗂️ 8.履歴保存(JSON形式)

import json
import os
from datetime import datetime

def save_history_json(user_text, ai_reply):
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    entry = {
        "timestamp": timestamp,
        "user": user_text,
        "ai": ai_reply
    }

    filename = "chat_history.json"
    if os.path.exists(filename):
        with open(filename, "r", encoding="utf-8") as f:
            data = json.load(f)
    else:
        data = []

    data.append(entry)

    with open(filename, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)

🔁 9.統合スクリプト(連続対話モード)

def interactive_loop():
    print("🌀 対話モード開始。Ctrl+Cで終了します。")
    try:
        while True:
            record_audio()
            user_text = transcribe_audio()
            ai_reply = send_to_lmstudio(user_text)
            speak(ai_reply)
            save_history_json(user_text, ai_reply)
    except KeyboardInterrupt:
        print("\n👋 終了しました。")

def main():
    interactive_loop()

if __name__ == "__main__":
    main()

📦 10.補足

  • Whisper "base" モデルは "tiny" より精度が高く、日常会話の認識に適しています。
  • LM StudioのAPIは起動後に「API」タブから有効化してください。
  • pyttsx3の音声はOS依存。日本語音声がない場合は、別途インストールが必要です。

🚀 まとめ

このスクリプトにより、音声入力 → 音声認識 → 応答生成 → 音声読み上げ → JSON履歴保存までを、すべてローカル環境で完結できます。Whisperの精度とLM Studioの柔軟性を活かし、プライバシーを守りながら高品質な音声対話が可能です。

さらに、連続対話モードにより、実用的な音声インターフェースとしての運用も視野に入ります。今後は以下のような拡張も検討しています:

  • VOICEVOXやOpen JTalkによる自然な日本語音声合成
  • GUI化(TkinterやPyQtなど)
  • 履歴の可視化や検索機能の追加
  • モデル切り替えによるキャラクター性の導入

ローカル完結型の音声AIシステムを自分の手で構築することで、技術的な理解も深まり、応用の幅も広がります。ぜひ、あなた自身のスタイルに合わせてカスタマイズしてみてください。


2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?