24
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Macで完全ローカル音声チャットAIを作ってみた - Qwen3-ASR + Ollamaでオフライン動作

24
Last updated at Posted at 2026-03-10

こんにちは。
AIソリューション事業部のAIおじさんです。
エンジニアではないのですが、AI好きのおじさんとして便利ツールを作ったりしています。

自分のPCに話しかけたら、AIが答えてくれる。しかもクラウドを一切使わず、完全に手元だけで動く。

これ、ロマンじゃないですか?

前回の記事でOllama + Qwen3を使ったローカルLLM環境を構築しました。記事の最後に「次は音声会話に挑戦したい」と書いたので、今回はその続編です。

Qwen3-ASR(音声認識)と Ollama(ローカルLLM)を組み合わせて、完全オフラインで動く音声チャットAIを作ってみました。Apple Silicon Mac で動かしているので、MチップのMacユーザーの参考になれば。

作りたいもの

最終的に目指しているのはこんな構成です。

┌─────────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   マイク     │────▶│  STT        │────▶│  LLM        │────▶│  TTS        │
│   入力      │     │ (Qwen3-ASR) │     │ (Ollama)    │     │ (Qwen3-TTS) │
└─────────────┘     └─────────────┘     └─────────────┘     └─────────────┘
                          │                   │                   │
                          ▼                   ▼                   ▼
                    テキスト変換         応答生成            音声再生

今回は STT(音声認識)→ LLM(応答生成) までを実装しました。TTSは次回以降で追加予定です。

STT(Speech-to-Text)とは

STTは「Speech-to-Text」の略で、音声をテキストに変換する技術です。日本語では「音声認識」とも呼ばれます。

身近な例だと:

  • iPhoneの音声入力
  • YouTubeの自動字幕
  • Alexaやスマートスピーカー

これらはすべてSTT技術を使っています。

クラウドSTT vs ローカルSTT

クラウドSTT ローカルSTT
Google Speech-to-Text, Whisper API Whisper.cpp, Qwen3-ASR
精度 高い モデルによる(最近は遜色ない)
速度 ネット依存 PC性能依存
プライバシー 音声データがサーバーに送られる 完全にローカルで完結
コスト 従量課金 無料(電気代のみ)

今回使う Qwen3-ASR は、ローカルで動作しながらも52言語に対応しており、日本語の認識精度も高いモデルです。

ローカルLLMとは

LLM(Large Language Model)は、ChatGPTのようにテキストで会話できるAIモデルのことです。

通常、ChatGPTやClaudeを使うにはインターネット経由でAPIを叩く必要がありますが、ローカルLLMは自分のPC上でモデルを動かします。

ローカルLLMのメリット

  • 完全オフライン: ネットなしで動く
  • プライバシー: 会話内容が外部に送信されない
  • 無料: API料金がかからない
  • カスタマイズ: ファインチューニングも自由

Ollamaとは

Ollamaは、ローカルLLMを簡単に動かすためのツールです。前回の記事でセットアップ方法を詳しく書きましたが、簡単におさらいすると:

# 公式サイトからダウンロード(Homebrew版はQwen3と相性問題あり)
curl -L -o /tmp/Ollama.zip "https://ollama.com/download/Ollama-darwin.zip"
unzip -o /tmp/Ollama.zip -d /tmp/
mv /tmp/Ollama.app /Applications/
open /Applications/Ollama.app

# モデルをダウンロードして実行
ollama run qwen3:4b-instruct

注意: Homebrew版のOllamaはQwen3でMetal周りのエラーが出ることがあります。公式版を使いましょう。

Ollamaが対応しているモデルは多数あり、今回は日本語性能が良い Qwen3 シリーズを使いました。qwen3:4b-instruct はThinking機能がないシンプル版で、即座に回答が返ってきます。

HuggingFaceとは

HuggingFaceは、AIモデルの「GitHub」のような存在です。

世界中の研究者や企業が作ったAIモデルが公開されていて、誰でも無料でダウンロードして使えます。今回使う Qwen3-ASR も HuggingFace で公開されています。

https://huggingface.co/Qwen/Qwen3-ASR-1.7B

モデルをダウンロードするには、Pythonライブラリ経由で自動取得するか、huggingface-cli を使います。今回は qwen-asr ライブラリが初回実行時に自動でダウンロードしてくれるので、特に意識する必要はありません。

使った技術

コンポーネント 使ったもの 特徴
音声認識(STT) Qwen3-ASR-1.7B 52言語対応、HuggingFaceで公開
対話生成(LLM) qwen3:4b-instruct (Ollama) 軽量で高速、日本語対応、即応答
実行環境 Apple Silicon (MPS) GPU活用で快適に動作

全部ローカルで完結するので、ネット環境がなくても動きます。

環境構築

1. Miniforgeをインストール

Python環境の管理には Miniforge(conda)を使いました。

brew install --cask miniforge
conda init zsh
# ターミナルを再起動

2. Python環境を作成

conda create -n voice-ai python=3.12 -y
conda activate voice-ai

3. 必要なライブラリをインストール

# PyTorch(Apple Silicon用)
pip install torch torchvision torchaudio

# Qwen3-ASR と Ollama クライアント
pip install -U qwen-asr ollama

# 音声入出力用
pip install sounddevice soundfile

4. Ollamaのセットアップ

前回の記事でセットアップ済みの場合はスキップしてOK。まだの場合は公式版をインストールします。

# 公式版をダウンロード&インストール
curl -L -o /tmp/Ollama.zip "https://ollama.com/download/Ollama-darwin.zip"
unzip -o /tmp/Ollama.zip -d /tmp/
mv /tmp/Ollama.app /Applications/
open /Applications/Ollama.app

# モデルをダウンロード
ollama pull qwen3:4b-instruct

これだけで準備完了です。STTモデル(約3.4GB)は初回実行時にHuggingFaceから自動ダウンロードされます。

実装したもの

プロジェクト構造

local_llm_dev/
├── src/
│   ├── stt.py          # 音声認識エンジン
│   ├── llm.py          # LLMラッパー(ストリーミング対応)
│   └── pipeline.py     # STT→LLM統合パイプライン
└── examples/
    ├── record_and_transcribe.py  # 録音→認識
    └── voice_chat.py             # 音声チャット

STTエンジン

src/stt.py では、Qwen3-ASRをラップした STTEngine クラスを実装。Apple Silicon の場合は自動で MPS(Metal Performance Shaders)を使うようにしています。

from src.stt import STTEngine

with STTEngine() as engine:
    result = engine.transcribe("audio.wav", language="Japanese")
    print(result["text"])

ポイントは dtype の自動変換。MPS は bfloat16 に対応していないので、自動で float16 に変換しています。

「こんんいちは。お元気ですか」と話しかけてみました。

スクリーンショット 2026-01-30 22.45.16.png

ちゃんと音声認識してテキストに変換されています。

LLMエンジン

src/llm.py では Ollama を使った LLMEngine クラスを実装。会話履歴の管理とストリーミング出力に対応しています。

from src.llm import LLMEngine

llm = LLMEngine(model="qwen3:4b-instruct")

# 通常の応答
response = llm.chat("こんにちは!")
print(response)

# ストリーミング
for chunk in llm.chat_stream("今日の天気は?"):
    print(chunk, end="", flush=True)

パイプライン

src/pipeline.py で STT と LLM を繋いで、一連の流れを実現しています。

マイク入力 → 録音 → STT → テキスト → LLM → 応答

動かしてみた

音声チャットを起動

conda activate voice-ai
python examples/voice_chat.py --stream

実際の動作

🎤 録音: 5秒
📝 認識結果: こんにちは。お元気ですか。今何をしています。
🤖 LLM応答: こんにちは!お元気です。今、日本語でお手伝いしています。

5秒制限をつけているため、いま何をしています「か?」の前に切れてしまいました。

スクリーンショット 2026-01-30 22.51.00.png

ちゃんと日本語を認識して、自然な返答が返ってきました。

自分のPCに話しかけて、ローカルで動いているAIが答えてくれる。この体験、なかなか感動します。

テキストモードでデバッグ

マイクなしで試したい場合はテキストモードも用意しています。

python examples/voice_chat.py --text-mode

技術的なポイント

Apple Silicon での動作

  • デバイス: MPS(Metal Performance Shaders)を使用
  • dtype: bfloat16 → float16 に自動変換(MPS非対応のため)
  • メモリ: Unified Memory なので VRAM を気にしなくていい

モデルサイズ

  • Qwen3-ASR-1.7B: 約3.4GB(HuggingFaceから初回ダウンロード)
  • qwen3:4b-instruct: 約2.5GB(Ollama経由)

16GB メモリの Mac なら余裕で動きます。

まとめ

前回構築した Ollama + Qwen3 環境に、Qwen3-ASR を追加して音声入力に対応させました。Apple Silicon Mac 上で完全ローカルな音声チャットAIが動いています。

正直、実用性だけで言えばChatGPTのアプリで音声会話すればいい話です。でも、自分のマシンだけで完結する音声AIを動かすというロマン。これが楽しいんですよね。

今後やりたいこと:

  • TTS(Qwen3-TTS)を追加して音声で応答させる
  • リアルタイム認識の改善
  • より自然な会話フロー

完全ローカルでの音声AIは、思ったより手軽に始められます。興味のある方はぜひ試してみてください。

参考

24
17
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
24
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?