QAエンジニアが音声合成の差分を自動検知する仕組みを導入したはなし
こんにちは。電話AI SaaS IVRyのQAエンジニアの関( @IvryQa )です。
アドベントカレンダーの3日目を担当します。
IVRyの自動応答機能では、Text-to-Speech(TTS)という音声合成を使用しています。ユーザーは設定画面から自由に読み上げ内容を設定することができ、実際の音声も確認することができます。
しかし、TTSのバージョンアップデートによって、同じテキストでも読み上げ方が変化することがあります。
例えば、文章中の改行は空白として読み上げられていたものが、突如消えてしまい違和感のある音声になっていたり、文章自体は変更していないのに読み上げのイントネーションが変わってしまうなどの事象がありました。
このような予期せぬ変更は、IVRyをご利用いただいていユーザーだけではなく、実際にIVRyに電話をかけてくるエンドユーザーの体験にも直接影響を及ぼす重要な要素だと考えています。
これまでは、一定の頻度で自動応答を設定し、実際に電話をかけて確認する作業を定期的に行っていましたが、手動での確認には限界があり、より効率的な品質保証の仕組みが必要だと感じていました。
そこで、私たちはこれらの想定していない変化を自動で検知する仕組みを導入しました。
本記事では、その取り組みについてご紹介していきます。
変更を見逃さないことの重要性
IVRyのような音声対話システムにおいて、音声の品質はとても重要な要素だと考えます。
特に、IVRyに電話をかけるエンドユーザーにとって、想定していない箇所での空白の欠如は聞き取りづらさが生まれ、不自然なイントネーションは違和感を与えてしまうと思います。
例えば、下記のような音声をお聴きください。
◼︎ 空白あり
◼︎ 空白なし
聴き比べていただくと、空白なしの音声ファイルでは、文章が続けて読み上げられ不自然で、聞き取りづらいことがわかります。
IVRyで設定した内容が予期せず変更されてしまうと、サービスを利用するユーザーだけでなく、IVRyに電話をかけてくるエンドユーザーの体験にも直接的な影響を与える重要な要素だと考えています。
差分検知の仕組み
大枠の流れは下記になります。
- IVRyの設定画面にて、再生するテキストを入力し、音声ファイルを作成し、ダウンロードします。
- マスター音声ファイルとダウンロードした音声ファイルの2つのファイルを比較し、以下の観点で差分を検知しています。
- 波形の比較による音声パターンの分析
- MFCCによる音質・イントネーションの評価
- 再生時間の比較
- 評価結果をSlackへ通知します。
使用技術
※ 以下のライブラリを活用しています。
-
librosa[1]
- 主に音声波形の分析と処理、波形データの取得で利用
-
python_speech_features(MFCC)[2]
- イントネーションや音質の変化を検出する目的で利用
- Matplotlib
- 波形とMFCCの可視化
- NumPy
- 波形の差分計算
- MFCCの距離計算
※ 人間の音声知覚に基づいた音声特性の分析を行うことができる。
具体的な実装例
◼︎ 波形分析
2つの音声波形の時間を揃えた上で、それぞれの振幅の差を平均して計算します。この振幅差が、設定した閾値(0.1)を超えると「波形に明らかな違い」と判定します。
# 音声ファイルを読み込む
y1, sr1 = librosa.load(audio_file1, sr=None)
y2, sr2 = librosa.load(audio_file2, sr=None)
# 音声の長さを取得
duration1 = librosa.get_duration(y=y1, sr=sr1)
duration2 = librosa.get_duration(y=y2, sr=sr2)
# 両ファイルの波形長を揃える
min_len = min(len(y1), len(y2))
y1_trimmed = y1[:min_len]
y2_trimmed = y2[:min_len]
# 波形の差分を計算
waveform_diff = np.mean(np.abs(y1_trimmed - y2_trimmed))
# 評価結果を返す
if waveform_diff > 0.1:
return f"波形に明らかな違いがあります(差分: {waveform_diff:.4f})。"
else:
return f"波形は類似しています(差分: {waveform_diff:.4f})。"
◼︎ MFCC分析
音声波形を時間で揃えたあと、MFCCを抽出して、2つの音声のMFCCの差分を計算しています。
# 波形を揃えてからMFCCを抽出
mfcc1 = mfcc(y1_trimmed, sr1)
mfcc2 = mfcc(y2_trimmed, sr2)
# MFCCの差分を計算
mfcc_dist = float(np.sum(np.abs(mfcc1 - mfcc2)))
# 評価結果を返す
if mfcc_dist > 10000:
evaluation.append("音質やイントネーションに違いがあります。")
else:
return f"音質やイントネーションは類似しています(MFCC差分: {mfcc_dist:.4f})。"
差分の評価のポイント
- 波形比較による音声パターンの違いがあるか
- MFCCによる音質・イントネーションの変化があるか
- 再生時間の差異があるか
検知できる変更パターン
◼︎ 空白の欠如
▼ Slack通知
▼ 波形
◼︎ イントネーションの変化
▼ Slack通知
▼ 波形
※ 差分なしのパターンは、下記のようなSlack通知がきます。
導入効果
音声差分の自動検知を導入したことで、大きく2つの効果が得られました。
1つ目は、確認作業の時間短縮です。これまで手動で30分ほど掛かっていた確認作業が、わずか1〜2分で完了できるようになりました。
2つ目は、定期的なモニタリングの実現です。人による確認では、どうしても他の優先タスクとの兼ね合いで後手に回ってしまうことがありました。しかし、自動化により決まったタイミングで確実にチェックを実行できるようになり、継続的な品質監視が可能になりました。
この仕組みにより、より安定的で効率的な品質保証ができているのは大きな成果だと感じています。
改善ポイント
現状の仕組みには、改善の余地があります。一つは、環境の課題です。現在は設定画面からダウンロードした音声ファイルを比較していますが、実際のエンドユーザーにより近い体験を検証するには、実際の電話環境での検証が必要だと考えています。
ただし、通信環境によるノイズの混入や音質の変化が発生することで誤検知が増える可能性があり、ここが一つの課題と感じています。また、評価の精度に関する課題もあります。
現状の閾値設定は、0に近い数値で行っていますが、微妙な差異でも検知してしまうことがあるので、ここは、一つ目の課題とセットで検討していく必要があると考えています。
細かいですが、可視化された波形やMFCCのグラフの見やすさも改善の余地があると考えます。より直感的に差分を把握できるような表示の工夫も検討していきたいと考えています。
まとめ
今回は、音声合成の差分を自動検知する仕組みについて紹介しました。
この仕組みは、音楽活動の経験が長い社内のエンジニアの音響や技術の知見を活かすことで、実現することができました。
今後も継続的な改善を重ね、一定の品質を安心して利用してもらえるよう取り組んでいきたいです。また、音声品質の定量評価基準としても活用できるのではないかと考えています。
他にも、Webアプリケーションのテストだけでなく、音声認識や電話自動応答システムの自動化といった新しい分野にも積極的に取り組んでいきたいと考えています。
ぜひ、興味を持っていただけた方は、お声がけください!
-
librosaは、librosa development teamによって開発され、ISCライセンスのもと提供されています。本記事では、その一部を活用しています。 ↩︎
-
MFCC(Mel-Frequency Cepstral Coefficients:メル周波数ケプストラム係数)は、人間の聴覚特性に基づいた音声分析手法です。 ↩︎
Discussion