📞
電話の音声データをOpenAIのTTS (text-to-speech) modelで作成する
背景
Whisperによる電話の音声データの文字起こしを試してみたかったのですが、自由に使えそうな電話のデータは見つかりませんでした。
そこでOpenAIのTTS (text-to-speech) modelを活用して、電話の音声データを自分で作成することにしました。
手順
下記手順で音声データを作成しました。
- ChatGPTで電話の応対のやりとりを生成
- 生成したやりとりをOpenAIのTTS (text-to-speech) modelで音声化
ChatGPTで電話の応対のやりとりを生成
下記プロンプトで会話の履歴を生成してもらいました
あなたは、Tokoroteenという文房具を販売しているECサイトのヘルプデスクで働いているオペレーターの佐藤さんです。
ヘルプデスクに着信する問い合わせの中で、「返品・交換」カテゴリに属する問い合わせの、電話の書き起こしスクリプトを[# 出力]に沿って教えて
# 出力
|role|script|
|--|--|
|operator|(コミュニケータの発話内容)|
|customer|(コミュニケータの発話内容)|
生成結果は下記のとおりです。これをconversation.csv
として保存しました。
role | script |
---|---|
operator | 佐藤でございます。Tokoroteenカスタマーサポートにお電話いただき、ありがとうございます。本日はどのようなご用件でしょうか? |
customer | こんにちは、先日購入した万年筆が壊れていたので、返品か交換をお願いしたいです。 |
operator | 大変申し訳ございません。商品が壊れていたということで、ご不便をおかけしました。まずはご注文内容を確認させていただきますので、お名前とご注文時の生年月日をお伺いできますでしょうか? |
customer | 名前は山田太郎、1990年5月1日です。 |
operator | ありがとうございます。少々お待ちください…ご注文の確認が取れました。壊れていたとのことですが、具体的にどのような状態でしたでしょうか? |
customer | 到着したときにペン先が折れていて、インクも漏れていました。 |
operator | それは大変申し訳ございません。新品交換か、返品対応のどちらかをお選びいただけますが、どちらをご希望されますか? |
customer | 交換をお願いしたいです。 |
operator | 承知いたしました。それでは、新品の万年筆と交換させていただきます。まず、壊れた商品をご返送いただき、その後交換品を発送いたします。返品用のラベルをメールでお送りいたしますので、商品を元の箱に戻し、ラベルを貼っていただき、最寄りの配送業者にお渡しください。 |
customer | わかりました。 |
operator | 交換品は返品商品を確認後、3~5営業日以内に発送いたします。返品が確認され次第、追ってメールでご連絡いたしますのでご安心ください。その他ご不明な点はございますでしょうか? |
customer | 特にありません。ありがとうございました。 |
operator | こちらこそ、迅速に対応させていただきますので、ご迷惑をおかけして申し訳ございませんでした。何かございましたらいつでもご連絡くださいませ。失礼いたします。 |
生成したやりとりをOpenAIのTTSで音声化
conversation.csv
を読み込み、音声化します。声のオプションとして、alloy, echo, fable, onyx, nova, shimmer
の6名を選ぶことができ、今回はオペレーターをalloy
、顧客をonyx
とすることにしました。
一行ずつ音源を生成し、最後にそれらを結合することで一つの音声ファイルとしました。
import pandas as pd
from openai import OpenAI
from pydub import AudioSegment
from pathlib import Path
# OpenAIクライアントの初期化
client = OpenAI()
# CSVファイルを読み込む
csv_file_path = "conversation.csv"
df = pd.read_csv(csv_file_path)
# 音声ファイルの保存先
output_dir = Path("audio_files")
output_dir.mkdir(exist_ok=True)
# 各行ごとに音声を生成
audio_files = []
for index, row in df.iterrows():
role = row["role"]
text = row["text"]
# 音声を選択
if role == "operator":
voice = "alloy"
elif role == "customer":
voice = "onyx"
else:
continue
# 音声を生成
response = client.audio.speech.create(
model="tts-1",
voice=voice,
input=text,
)
# 音声ファイルを保存
speech_file_path = output_dir / f"speech_{index}.mp3"
response.stream_to_file(speech_file_path)
audio_files.append(speech_file_path)
# 音声ファイルを結合
combined = AudioSegment.empty()
for audio_file in audio_files:
segment = AudioSegment.from_mp3(audio_file)
combined += segment
# 最終的なMP3ファイルとして保存
final_output_path = "conversation.mp3"
combined.export(final_output_path, format="mp3")
結果
想像以上に自然な会話を生成することができて大満足です。
適切な実データがなくとも、生成されたデータで問題なく検証できそうだと感じました。
参考資料
Discussion