こんにちは!ABEJA でソフトウェアエンジニアを務めている宇留嶋です。2025 年 3 月に OpenAI が発表した次世代音声モデル群は、従来の Whisper を凌ぐ高精度な音声認識と、話し方まで指示できる音声合成をAPI で提供し、音声対話向けの LLM API として大きな注目を浴びました。 同 API の音声出力機能では、ストリーミングに対応した 高品質プリセットボイスが利用できるほか、外部で生成した音声ファイルを入力として与えることも可能です。 そこで今回は、このAPI を “音声品質の審査員”として活用 し、OpenAI GPT-4o mini TTS、Google Cloud Text‑to‑Speech、Amazon Polly、ElevenLabsなど主要な TTS サービスが生成した日本語音声をスコアリングしました。モデルには自然さ、聞き取りやすさ、抑揚といった複数観点で 評価を指示し、出力を定量データとして比較しています。 本来、人手による聴取試験はコストと時間がかさみます。また機械的に評価しようとしても、様々な指標を算出するには追加モデルや参照音声が必要で、実装・計算コストが意外に高い のが現状です。 実務でも TTS を使う機会が増え、「どのサービスが本当に“人間らしい”音声を出せるのかを客観的に測りたい」という疑問から始まった試みです。本記事では評価セットアップ、プロンプト設計、スコア評価、そして OpenAI モデルに評価を任せるメリット・限界までを紹介し、最後に筆者の所感をまとめます。 まず、今回比較対象とした主要なTTSサービスを挙げます。それぞれ日本語テキストの読み上げに対応したサービスです: 今回は上記4サービスに、同一の日本語テキストを読み上げてもらい音声の聞き取りやすさや自然さを比較します。なお、各サービスとも日本語かつ女性の音声を使用しました。 比較にあたり、以下のような方法で評価を行いました: OpenAI API(text + speech to text)による自動評価 2で得た 合成音声ファイルを input_audio として Chat Completions エンドポイント に送り、同時に評価用プロンプトを渡します。モデルは音声を解析し、各観点のスコアとコメントをテキストで返します。返却 JSON からスコアを抽出し、サービスごとの評価表を作成します。 比較項目: 最終的に、以下の観点で各サービスを比較しました: それでは、各サービスで実際に音声を生成した実装コードと、結果の比較を見ていきましょう。 それぞれのサービスでテキスト読み上げを行うコードの概要を示します。 OpenAIのPython SDKを使ってテキストを音声合成します。声質は女性音声 googleが提供するPython SDKを使って言語コード AWSのPollyではBoto3クライアントから ElevenLabsに関してはwebアプリケーション内にて、音声合成させました。 modelは 各音声サービスの評価はOpenAI API(gpt-4o-mini-audio-preview)を使い自動評価させました。 以下のプロンプトで各指標を評価しています。 評価結果は以下となりました。 自然さとノイズ抑制では AWS Pollyが一歩先行していると評価されました。 表現力は OpenAI Alloyが僅かにトップとなり明瞭さでは Google TTSが最高点という結果です。 筆者の聴感と一致している部分としては、OpenAI Alloyの抑揚表現の豊かさや Google TTSの聞き取りやすさは実際にも強みとして感じられました。 一方で、体感ではやや機械的に聞こえる AWS Pollyが「自然さ」で高評価を得るなど、評価指標と実際の印象が食い違うケースも見受けられ、指標設計の難しさが垣間見えます。 今回の実験でLLMに音声評価させるというアプローチを試すことができました。 LLMの音声品質評価は迅速で低コスト、多面評価可能というメリットがあると思います。 一方で、まだ人間の感性を完全に代替する段階には至っておらず、微妙な感情表現の機微 や 言語的背景知識が絡むニュアンスなどには十分課題があると思っています。 LLM が音声を理解し定量評価まで行える時代は、音声 UX にとって大きな転機になると思います。 今後もOpenAIの音声系APIの進化がとても楽しみです。 ABEJAは、テクノロジーの社会実装に取り組んでいます。 技術はもちろん、技術をどのようにして社会やビジネスに組み込んでいくかを考えるのが好きな方は、下記採用ページからエントリーください! (新卒の方やインターンシップのエントリーもお待ちしております!)
はじめに
比較対象のTTSサービス
実験の方法
実装
各サービスで音声合成
1. OpenAI(gpt-4o-mini-tts)
alloy
を指定しました。from pathlib import Path
from openai import OpenAI
client = OpenAI()
speech_file_path = Path(__file__).parent / "speech.mp3"
text = "2025年に入り、生成AI技術はますます進歩しています。..."
with client.audio.speech.with_streaming_response.create(
model="gpt-4o-mini-tts",
voice="alloy",
input=text,
) as response:
response.stream_to_file(speech_file_path)
2. Google Cloud Text-to-Speech
ja-JP
の女性音声ja-JP-Chirp3-HD-Leda
を指定しました。from google.cloud import texttospeech
client = texttospeech.TextToSpeechClient()
synthesis_input = texttospeech.SynthesisInput(text="こんにちは")
voice = texttospeech.VoiceSelectionParams(
language_code="ja-JP",
name="ja-JP-Chirp3-HD-Leda"
)
audio_config = texttospeech.AudioConfig(
audio_encoding=texttospeech.AudioEncoding.MP3
)
response = client.synthesize_speech(
input=synthesis_input,
voice=voice,
audio_config=audio_config
)
with open("output.mp3", "wb") as out:
out.write(response.audio_content)
print('Audio content written to "output.mp3"')
3. Amazon Polly
SynthesizeSpeech
APIを呼び出し、日本語の女性音声Mizuki
を指定して音声合成しました。import boto3
client = boto3.client('polly')
text = "2025年に入り、生成AI技術はますます進歩しています。..."
response = client.synthesize_speech(
OutputFormat='mp3',
SampleRate='8000',
Text=text,
TextType='text',
VoiceId='Mizuki',
)
b = response['AudioStream'].read()
with open('test.mp3', "wb") as f:
f.write(b)
5. ElevenLabs
Eleven Multilingual v2
を使い、Voiceは日本語、女性のMorioki
を使いました。音声合成の自動評価
def evaluateone(client: AzureOpenAI, audio: pathlib.Path, script: str) -> str:
"""
音声ファイル `audio` とその台本 `script` を Azure OpenAI に渡し,
8 指標を 1〜100 点で採点し,詳細コメントを付けて JSON で返す。
さらに「総評」として平均点と総括コメントを生成させる。
"""
prompt = (
"あなたは音声品質の専門家です。以下 8 項目について 1〜100 点で採点し、"
"各項目ごとに 50〜100 字程度の詳細コメントを付けてください。\n"
"最後に「総評」として、8 項目の平均点 (average_score) と総括コメントを出力してください。\n\n"
"【評価指標と採点基準】\n"
"■ 自然さ(Naturalness)\n"
" 90–100: 完璧に人間同等 / 70–89: ほぼ自然 / 40–69: 機械的箇所あり / 10–39: 不自然 / 0–9: 非常に不自然\n"
"■ 表現力(Expressiveness)\n"
" 情緒・抑揚・強弱の豊かさを定量化。単調さが目立つほど減点。\n"
"■ 明瞭さ(Intelligibility)\n"
" 誤発音や滑舌、SNR を考慮。WER 10% 以下なら 80 点以上。\n"
"■ 音質(Sound Quality)\n"
" 周波数帯域、歪み、クリッピング、SNR を総合評価。\n"
"■ ノイズ(Noise Level)\n"
" バックグラウンドノイズ・電気的ノイズ・録音環境ノイズを考慮。\n"
"■ プロソディ(韻律)\n"
" F0 変動、リズム、ポーズ配置、アクセントパターンの自然さ。\n"
"■ 話者性(Speaker Identity)\n"
" 声質一貫性評価。\n"
"■ 主観的印象(Overall Impression)\n"
" 聴取負荷、感情伝達、好感度など総合主観評価。\n\n"
"【出力フォーマット】\n"
"{\n"
" \"自然さ\": {\"score\": 92, \"comment\": \"…\"},\n"
" \"表現力\": {\"score\": 85, \"comment\": \"…\"},\n"
" \"明瞭さ\": {\"score\": 97, \"comment\": \"…\"},\n"
" \"音質\": {\"score\": 88, \"comment\": \"…\"},\n"
" \"ノイズ\": {\"score\": 94, \"comment\": \"…\"},\n"
" \"プロソディ\": {\"score\": 90, \"comment\": \"…\"},\n"
" \"話者性\": {\"score\": 83, \"comment\": \"…\"},\n"
" \"主観的印象\": {\"score\": 91, \"comment\": \"…\"},\n"
" \"総評\": {\"average_score\": 90, \"comment\": \"全体的に…\"}\n"
"}\n"
"※ JSON 以外の出力は不要です。\n\n"
"【原稿】\n" + script
)
messages = [
{"role": "system", "content": prompt},
{
"role": "user",
"content": [
{"type": "text", "text": "以下の朗読音声を評価してください。"},
{
"type": "input_audio",
"input_audio": {
"data": b64_audio(audio),
"format": audio_format(audio),
},
},
],
},
]
resp = client.chat.completions.create(
model=DEPLOYMENT,
messages=messages,
modalities=["text", "audio"],
audio={"voice": "alloy", "format": "wav"},
)
msg = resp.choices[0].message
return (msg.audio.transcript if msg.audio else msg.content).strip()
評価結果
サービス
平均スコア
自然さ
表現力
明瞭さ
音質
ノイズ
プロソディ
話者性
主観的印象
AWS Polly “Mizuki”
91.3
93.7
86.7
96.3
89.7
96.3
90.3
86.0
91.7
OpenAI “Alloy”
90.2
92.3
87.0
95.3
89.0
93.3
90.0
84.7
90.0
Google TTS “Chirp3‑HD‑Leda”
89.6
91.0
85.3
97.0
87.7
91.7
89.3
84.7
90.3
ElevenLabs “Morioki”
89.0
89.7
83.3
95.3
89.0
91.7
88.0
85.0
90.0
まとめ
We Are Hiring!