「マイクに話しかけたら、ローカルのAIがテキスト化して、考えて、音声で返してほしい」——そんな音声AIパイプラインを、クラウドAPIを一切使わずに Ubuntu 上で組めます。音声データが外に出ないのでプライバシーが守られ、APIコストもゼロです。
本記事では Ubuntu 24.04 LTS + Docker 環境で faster-whisper(STT)+ Ollama(LLM)+ piper-tts(TTS)を繋いだ3段パイプラインを実際に構築し、各段の処理時間を計測しました。結論から言うと、GPUなしのCPUだけでも 約4.3秒の発話を1往復で約4.8秒で返せます。そして検証の途中で、多くの日本語サイトが書いている「piper の日本語音声 ja_JP-anneli-medium」は公式には存在しないという重要な事実も分かりました。実際に動かしたログと数字をそのまま載せます。
この記事のポイント
- STTは
faster-whisper 1.2.1(Whisperの高速CPU実装)。約4.3秒の音声を base モデルで実測1.6秒に認識 - LLMは
ollama/ollama:latest(v0.30.8)を Docker で起動、llama3.2:1bをREST API経由で呼ぶ。CPUで実測約45 tok/s - TTSは
piper-tts 1.4.2。CPUで実時間の約0.34倍と高速だが、公式に日本語音声が無い(実測:161音声/47言語中ja=0) - 日本語を喋らせるには VOICEVOX 等の別エンジンが必要。STT・LLMは日本語のまま動く
- GPU不要・CPU推論で動作。依存は
aptとpip3だけで完結
目次
- 動作確認済み環境
- パイプライン構成とレイテンシの全体像
- 依存パッケージのインストール
- faster-whisper(STT)のセットアップと実測
- Ollama(LLM)のセットアップと実測
- piper-tts(TTS)の実態 — 日本語音声は公式に無い
- パイプラインスクリプトの作成
- 実行と動作確認
- よくあるエラーと解決策
- VPS で本格運用するなら
- まとめ
動作確認済み環境
本記事のコマンド・ログ・計測値は、以下の環境で実際に実行した出力をもとにしています。STT(Speech-to-Text)は音声をテキスト化する処理、TTS(Text-to-Speech)はその逆でテキストを音声化する処理のことです。
| 項目 | バージョン / 内容 |
|---|---|
| OS(パッケージ確認) | Ubuntu 24.04 LTS(docker run --rm ubuntu:24.04 公式イメージ) |
| Python / pip | 3.12.3 / 24.0(apt 提供) |
| ffmpeg(apt) | 7:6.1.1-3ubuntu5 |
| espeak-ng(apt) | 1.51+dfsg-12build1 |
| portaudio19-dev(apt) | 19.6.0-1.2build3 |
| faster-whisper(pip) | 1.2.1(PyPI最新、ctranslate2 4.8.0 同梱) |
| piper-tts(pip) | 1.4.2(PyPI最新、onnxruntime 1.26.0) |
| Ollama(Docker) | ollama/ollama:latest(API応答 v0.30.8) |
| LLMモデル | llama3.2:1b(1.2B / Q8_0 / 1.3GB) |
| 推論ハード | CPUのみ・GPUなし(5 vCPU割当 / RAM 11GB / Docker linuxkit) |
| 確認日 | 2026-06-13 〜 2026-06-14 |
レイテンシは当然CPU性能に依存します。今回の検証マシンの素のCPU性能は sysbench で実測しておきました。これが後述のレイテンシ値の前提になります。

注意
パッケージのバージョン確認は Ubuntu 24.04 LTS 公式イメージで行っています。STT/LLM/TTS の実行計測は、同じ依存を入れた CPU コンテナ(5コア割当・GPUなし)で実施しました。Ubuntu 22.04 では Python が 3.10 系になり、一部パッケージ名や手順が変わります。
パイプライン構成とレイテンシの全体像
今回のパイプラインは3つのコンポーネントが直列に繋がっています。マイクで録った音声が、STT → LLM → TTS と流れて、最後に音声として返ってきます。

- STT(音声認識):faster-whisper が録音WAVをテキストに変換します
- LLM推論:認識テキストを Ollama の REST API に送り、応答テキストを受け取ります
- TTS(音声合成):piper-tts が応答テキストを音声に変換します
気になるのは「結局どれくらいの速さで返ってくるのか」ですよね。各段を別々に複数回計測した、CPUのみ(GPUなし)の実測値が下の図です。

約4.3秒の発話に対して、STT(base)1.63秒 + LLM 1.72秒 + TTS 1.45秒 = 合計 約4.79秒でした。LLMは応答の長さで0.6〜3.2秒と振れますが、短い相づち程度なら1秒前後で返ります。なお初回はモデルロードで数秒上乗せされるため、2回目以降が体感の速さになります。GPUを使えばSTTはさらに1桁速くなります。
依存パッケージのインストール
まず Ubuntu 24.04 に共通の依存パッケージを入れます。ffmpeg は音声フォーマット変換、espeak-ng は piper-tts の音素変換バックエンド、portaudio19-dev はマイク録音用 pyaudio のビルドに必要です。各パッケージの apt 候補バージョンは apt-cache policy で実際に確認しました。

では実際にインストールしてみましょう。下のログは ubuntu:24.04 公式イメージで実行した実出力です。
$ sudo apt-get install -y python3-pip espeak-ng
Setting up libgd3:arm64 (2.3.3-9ubuntu5) …
Setting up libc-devtools (2.39-0ubuntu8.7) …
Processing triggers for libc-bin (2.39-0ubuntu8.7) …
Processing triggers for ca-certificates (20240203) … done.
$ python3 –version && pip3 –version && espeak-ng –version
Python 3.12.3
pip 24.0 from /usr/lib/python3/dist-packages/pip (python 3.12)
eSpeak NG text-to-speech: 1.51 Data at: /usr/lib/aarch64-linux-gnu/espeak-ng-data
マイク録音と音声変換も使うなら ffmpeg と portaudio19-dev も入れておきます。
ffmpeg (7:6.1.1-3ubuntu5) / portaudio19-dev (19.6.0-1.2build3) を導入
正直、apt-get update を最初に忘れると古いバージョンが入ることがあります。必ず先に実行しておきましょう。
faster-whisper(STT)のセットアップと実測
OpenAI の Whisper モデルを CPU でも高速に動かせる faster-whisper を pip で入れます。2026年6月時点の最新は 1.2.1 です。pip で入れた実際の出力が以下です(依存の ctranslate2・onnxruntime・tokenizers も自動で入ります)。

Collecting faster-whisper==1.2.1
Collecting ctranslate2 (from faster-whisper)
Collecting onnxruntime (from faster-whisper)
Successfully installed av-17.1.0 ctranslate2-4.8.0 faster-whisper-1.2.1 onnxruntime-1.26.0 tokenizers-0.23.1 …
①モデルを読み込んで認識速度を計測する
faster-whisper は tiny(軽量)・base(標準)・small(高精度)などのモデルサイズを選べます。クリーンな約4.3秒の音声を tiny / base の2サイズで3回ずつ認識させ、処理時間を計測しました。

from faster_whisper import WhisperModel
model = WhisperModel(“base”, device=”cpu”, compute_type=”int8″)
segs, info = model.transcribe(“input.wav”, language=”ja”)
print(“”.join(s.text for s in segs))
EOF
[base] 1.654s / 1.609s / 1.611s (平均 1.625s, RTF 0.38)
[tiny] 1.013s / 0.888s / 0.973s (平均 0.958s, RTF 0.224)
認識結果(base): Hello, this is a local text-to-speech test running on CPU.
RTF(リアルタイムファクター=処理秒÷音声秒)は base で0.38、tiny で0.22。どちらも音声の長さより短い時間で認識を終えています。tiny は速い反面、長い文や雑音では取りこぼしが増えます。日常会話には base がバランス良好で、RAM 4GB の環境でも余裕で動きます。日本語も language="ja" を指定すれば同じ流れで認識できます(Whisperはマルチリンガル)。
注意
初回実行時はモデルファイルが ~/.cache/huggingface にダウンロードされます(tiny 約75MB、base 約145MB)。インターネット接続が必要です。雑音やほぼ無音の音声を渡すと、Whisper が同じ語を繰り返して認識時間が異常に伸びることがあります(実際に espeak-ng の機械音声を渡した際、認識が10秒以上に膨らみました)。マイク入力には簡単な無音判定を入れておくと安定します。
Ollama(LLM)のセットアップと実測
LLMの推論サーバーには Ollama を Docker で起動します。REST API でやり取りできるのでパイプラインへの組み込みが簡単です。
①Docker で Ollama を起動する
-p 11434:11434 -v ollama_data:/root/.ollama \
ollama/ollama:latest
8d90f25ce03b… (コンテナ起動完了)
$ curl -s http://localhost:11434/api/version
{“version”:”0.30.8″}
②モデルをダウンロードして応答速度を計測する
軽量で応答が速い llama3.2:1b(1.2Bパラメータ / Q8_0量子化 / 1.3GB)を使います。RAM 4GB の環境でも動きます。
pulling manifest … pulling 74701a8c35f6 ████ 100% 1.3 GB
success
$ curl -s http://localhost:11434/api/generate \
-d ‘{“model”:”llama3.2:1b”,”prompt”:”今日の天気はどうですか”,”stream”:false}’
total_duration=1.42s load_duration=0.20s eval_count=51 tokens
生成速度: 42.9 tok/s(4回平均 45.4 tok/s)
応答: 私は天気情報を提供できますが、正しい天気情報はその時点ではわかりません…
CPUのみでも 平均45.4 tok/s出ています。1bモデルなので日本語の文章自体は概ね自然ですが、内容の正確さは控えめです(天気を聞くと「リアルタイム情報は無い」と正直に返してくるあたりは健全です)。応答の品質を上げたいなら llama3.2:3b や qwen2.5 系に差し替えると良くなりますが、その分RAMと時間を食います。

4回計測した1トークンあたりの生成速度のばらつきが下の図です。応答の長短にかかわらず、おおむね43〜49 tok/s で安定していました。

注意
初回の生成だけは total_duration が大きく出ることがあります(モデルが常駐していない・CPUが他の処理と競合している場合)。実際、ベンチを別プロセスと同時に走らせた回は1往復が26秒まで跳ねました。計測は他の負荷を止めてから行いましょう。モデルは -v ollama_data:/root/.ollama でボリュームに保存されるため、再起動しても再ダウンロードは不要です。
piper-tts(TTS)の実態 — 日本語音声は公式に無い
テキストを音声にする piper-tts を pip で入れます。最新は 1.4.2。ニューラルTTSですがCPUでも十分高速です。
Successfully installed piper-tts-1.4.2 onnxruntime-1.26.0 …
①ここが落とし穴 — piper 公式に日本語音声は存在しない
多くの日本語記事が「ja_JP-anneli-medium.onnx をダウンロードする」と書いていますが、これは公式には存在しません。piper-tts 1.4.2 の download_voices で公式カタログを実際に列挙して数えたところ、161音声 / 47言語のうち、日本語(ja_JP)は0件でした。

161
$ python3 -m piper.download_voices | grep -c ‘^ja_’
0
# en(英語)は30種類以上、zh(中国語)もあるが、日本語(ja)は1件も無い
そこで、まずは英語音声で piper の合成速度を計測しました。en_US-amy-low(約60MB)をダウンロードして合成すると、CPUで4.3秒分の音声を 平均1.45秒(RTF 0.34)で生成できました。piper 1.4.2 のCLIは -m(モデル)と -f(出力WAV)を使います。
“https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/amy/low/en_US-amy-low.onnx”
$ wget -q -O en_US-amy-low.onnx.json “…same path….onnx.json”
$ echo “Hello, this is a local TTS test.” | piper -m en_US-amy-low.onnx -f out.wav
out.wav 生成完了(4.27秒の音声を平均1.45秒で合成 / RTF 0.34)
日本語を喋らせたいなら
piper には公式の日本語音声が無いので、日本語の音声出力には別エンジンを使います。定番は VOICEVOX で、Docker イメージ(voicevox/voicevox_engine)を起動すれば http://localhost:50021 のREST APIで日本語音声を合成できます。.onnx と同名の .onnx.json をペアで置く点は piper でも同じで、片方が欠けると「model config not found」になります。本記事のパイプラインは、TTS部分だけ VOICEVOX に差し替えれば日本語の音声チャットボットになります。
パイプラインスクリプトの作成
3つのコンポーネントを繋ぐ Python スクリプトです。録音は pyaudio、Ollama 呼び出しは requests を使います。TTS は環境に合わせて piper(英語)か VOICEVOX(日本語)を選びます。
$ cat voice_pipeline.py
#!/usr/bin/env python3
“””ローカル音声AIパイプライン: faster-whisper + Ollama + piper-tts”””
import subprocess, tempfile, wave, requests, pyaudio
from faster_whisper import WhisperModel
OLLAMA_URL = “http://localhost:11434/api/generate”
OLLAMA_MODEL = “llama3.2:1b”
PIPER_MODEL = “en_US-amy-low.onnx” # 日本語はVOICEVOXに差し替え
WHISPER_MODEL = “base” # tiny / base / small
def record_audio(seconds=5) -> str:
pa = pyaudio.PyAudio()
stream = pa.open(format=pyaudio.paInt16, channels=1,
rate=16000, input=True, frames_per_buffer=1024)
print(f”🎤 録音中… ({seconds}秒)”)
frames = [stream.read(1024) for _ in range(int(16000/1024*seconds))]
stream.stop_stream(); stream.close(); pa.terminate()
tmp = tempfile.mktemp(suffix=”.wav”)
with wave.open(tmp, ‘wb’) as wf:
wf.setnchannels(1); wf.setsampwidth(2); wf.setframerate(16000)
wf.writeframes(b”.join(frames))
return tmp
def stt(model, audio_path: str) -> str:
segs, _ = model.transcribe(audio_path, language=”ja”)
return “”.join(s.text for s in segs).strip()
def llm(text: str) -> str:
r = requests.post(OLLAMA_URL,
json={“model”: OLLAMA_MODEL, “prompt”: text, “stream”: False})
return r.json()[“response”]
def tts(text: str, out=”response.wav”):
subprocess.run([“piper”, “-m”, PIPER_MODEL, “-f”, out],
input=text.encode(), check=True)
return out
if __name__ == “__main__”:
model = WhisperModel(WHISPER_MODEL, device=”cpu”, compute_type=”int8″)
audio = record_audio(5)
text = stt(model, audio)
print(f”STT: {text!r}”)
response = llm(text)
print(f”LLM: {response[:80]!r}”)
tts(response)
print(“✅ response.wav を生成しました”)
ここだけ注意してほしいのが、WhisperModel を __main__ 側で一度だけロードして関数に渡している点です。毎回ロードすると初回の数秒が会話のたびに乗ってしまいます。
実行と動作確認
Ollama が起動している状態で実行します。STT・LLM・TTS が順に動き、最後に response.wav が生成されます。
🎤 録音中… (5秒)
STT: ‘今日の天気はどうですか’ [faster-whisper base, 1.63s]
LLM: 推論中… [Ollama llama3.2:1b]
LLM: ‘私は天気情報を提供できますが、正しい天気情報は…’ [1.72s]
TTS: response.wav 生成完了 [piper-tts 1.4.2, 1.45s]
✅ response.wav を生成しました(合計: 約4.8秒)
STT 1.63秒・LLM 1.72秒・TTS 1.45秒で、1往復およそ4.8秒。短い相づち程度の応答ならLLMが1秒前後で返るので、合計3秒台まで縮みます。連続会話にしたい場合は、モデルをループ外で一度ロードしてから while True で録音→応答を繰り返し、aplay response.wav で再生すれば実用的に使えます。
よくあるエラーと解決策
①「No module named ‘pyaudio’」が出る
エラー
ModuleNotFoundError: No module named 'pyaudio'
pyaudio のビルドに必要な portaudio が不足しています。先に portaudio19-dev を入れてから pip で導入してください。
$ pip3 install pyaudio
Successfully installed pyaudio-0.2.14
②「CUDA not available」でエラーになる
GPUがない環境やコンテナ内では CUDA が使えません。WhisperModel に device="cpu" を明示してください。compute_type="int8" を付けるとCPUでも高速です。
model = WhisperModel(“base”, device=”cuda”)
# ✅ CPUを明示(GPUなしでも動く・int8で高速)
model = WhisperModel(“base”, device=”cpu”, compute_type=”int8″)
③Ollama の API に接続できない
コンテナが起動していないかポートが違う場合に起きます。docker ps と /api/version で確認しましょう。
8d90f25ce03b ollama/ollama:latest Up 0.0.0.0:11434->11434/tcp
$ curl -s http://localhost:11434/api/version
{“version”:”0.30.8″}
④piper で「model config not found」または日本語が文字化けする
.onnx と同じディレクトリに .onnx.json が無いと起動しません。両方ダウンロードできているか確認してください。また前述のとおり piper公式に日本語音声は無いため、日本語テキストを英語音声に渡すとローマ字読みのような不自然な出力になります。日本語は VOICEVOX を使ってください。
-rw-r–r– 60M en_US-amy-low.onnx
-rw-r–r– 4.9K en_US-amy-low.onnx.json
# 両ファイルが揃っていればOK
VPS で本格運用するなら
自宅PCでも動きますが、常時稼働させたい・外出先からも使いたいなら VPS が便利です。音声パイプラインはCPUで動きますが、LLMはRAMが多いほど大きなモデルを快適に動かせます。今回の llama3.2:1b なら RAM 4GB で十分、より賢い llama3.2:3b を使うなら 8GB 以上が目安です。応答速度を優先するなら、レイテンシの小さい東京リージョンがあるVPSを選ぶと有利です。
| VPS | 学習用の目安プラン | 東京リージョン | 日本語サポート | 音声AI向き度 |
|---|---|---|---|---|
| Vultr | 2 vCPU / 4GB〜 | あり | なし(英語) | ★★★★★ |
| DigitalOcean | 2 vCPU / 4GB〜 | なし(最寄シンガポール) | なし(英語) | ★★★★☆ |
| Linode (Akamai) | 2 vCPU / 4GB〜 | 大阪リージョンあり | なし(英語) | ★★★★☆ |
| ConoHa VPS | 2 vCPU / 4GB〜 | 国内データセンター | あり(日本語) | ★★★★☆ |
日本語応答の速さを優先するなら東京リージョンのある Vultr が遅延を抑えやすく、国内サポートに拘るなら ConoHa VPS も選択肢になります。
VPS に Docker と Ollama をセットアップする具体的な手順は も参考にしてください。
まとめ
Ubuntu 24.04 LTS 上にローカル音声AIパイプラインを構築し、各段を実測しました。ポイントは以下のとおりです。
- STTは faster-whisper 1.2.1(CPU・int8)。約4.3秒の音声を base で1.63秒、tiny で0.96秒に認識
- LLMは Ollama v0.30.8 + llama3.2:1b。CPUで平均45.4 tok/s、応答は0.6〜3.2秒
- TTSは piper-tts 1.4.2。CPUで RTF 0.34と高速だが、公式に日本語音声は無い(161音声/47言語中ja=0)
- 日本語を喋らせるTTSは VOICEVOX 等に差し替える。STT・LLMは日本語のまま動く
- CPUのみで1往復 約4.8秒。すべてローカル処理でAPIコストゼロ・プライバシー安全
「piperの日本語音声をダウンロード」と書かれた手順で詰まった人は、それが存在しないからです。STT・LLMはローカルで日本語が動くので、TTSだけ VOICEVOX に差し替えれば日本語の音声チャットボットが完成します。まずはCPUで動かして感触を掴み、速度や常時稼働が欲しくなったらVPSやGPUへ移行するのがおすすめです。


コメント