📞

電話の音声データをOpenAIのTTS (text-to-speech) modelで作成する

2024/09/09に公開

背景

Whisperによる電話の音声データの文字起こしを試してみたかったのですが、自由に使えそうな電話のデータは見つかりませんでした。
そこでOpenAIのTTS (text-to-speech) modelを活用して、電話の音声データを自分で作成することにしました。

手順

下記手順で音声データを作成しました。

  1. ChatGPTで電話の応対のやりとりを生成
  2. 生成したやりとりを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")

結果

想像以上に自然な会話を生成することができて大満足です。
適切な実データがなくとも、生成されたデータで問題なく検証できそうだと感じました。

参考資料

https://platform.openai.com/docs/guides/text-to-speech/quickstart

Discussion