"AWS Lambda でOpenAIのWhisper APIを試してみた"を読んで改善できないか試してみた

# はじめに

いままでOpenAI APIを試すときはローカル環境で実行していたので､以下の記事をもとにAWS LambdaでWhisper APIを試してみました｡
クラスメソッドさんの記事は､いつもとても参考になります｡

[AWS Lambda でOpenAI の Whisper API を 認識精度の改善も含めて試してみた](https://dev.classmethod.jp/articles/aws-lambda-openai-whisper-api/)

記事では､Whisper APIを使って音声ファイルから文字起こしを行った結果、気になった点として次のことが挙げられています。
- 句読点がない
- 余計なな空白が入る
- 固有名詞に誤記がある

GPT-4を使って文書を整形することで可読性が向上したものの､Lambdaの実行時間が長くなったとも書かれています｡そこで､GPT-3.5でも可読性の高い出力が得られないか試してみました｡
結果､Whisperのプロンプトを工夫することで､文字起こしの段階で可読性の高い文章を得ることができました｡

# 参考情報

https://dev.classmethod.jp/articles/aws-lambda-openai-whisper-api/

https://dev.classmethod.jp/articles/openai-whisper-api-amazon-transcribe/

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

https://qiita.com/revsystem/items/37aa4f066b63a3bb0379

# 前提条件

- 以下のリソースを作成･削除･変更できる権限をもつAWSユーザー
    - AWS Lambda
    - Amazon S3
- 使用するリージョン: us-east-1
- OpenAIのAPIキーが発行済み

# 環境構築

## AWS環境
元記事に､S3バケットの準備､Lambda関数の作成､レイヤーの追加などが詳しく書かれているのでここでは省略します｡
元記事ではLambda関数のIAMロールに`AmazonS3FullAccess`をアタッチしていますが､S3バケット内にあるファイルを読み込むだけなので､AWSポリシーテンプレートにある`Amazon S3 オブジェクトの読み取り専用アクセス権限`だけで良いと思います｡

## 音声データ
元記事では､[Contact Lens for Amazon Connect 入門](https://www.youtube.com/watch?v=tqJx-VJVUVc)の動画のうち､冒頭2分間を音声ファイルに変換したものが使用されています｡比較のため､同じデータを使用します｡

## コードの改善
openai.Audio.transcribe()に[文字起こしの品質を向上するプロンプト](https://platform.openai.com/docs/guides/speech-to-text/prompting)を指定しました｡コード内のTRANSCRIPT_PROMPTの箇所です｡`こんにちは。今日は、いいお天気ですね｡`や､`平井裕二さんが DevelopersIO で講演を行いました｡`のように句読点や固有名詞を含む簡単な文章をプロンプトにいれることで､文字起こしの品質が向上します｡

TRANSCRIPT_PROMPTの記述方法にも工夫が必要でした｡`平井裕二さんが DevelopersIO で講演を行いました｡`のようにDevelopersIOの前後に半角スペースが必要でした｡前後の半角スペースがない場合､文字起こしの結果が`ディベロッパーズ IO`となり､それをもとにした整形の結果は`Developers.IO`となりました｡元記事でopenai.Audio.transcribe()のプロンプトが意図したとおりに機能していなかったのはこの点が原因のようです｡

元記事では､GPT-4を使うことで､いくつかの単語が「」で囲われていました｡この点はChatCompletionのプロンプトを工夫することでGPT-3.5でも対応できました｡

また､元記事では最後から2行目で`str(transcript["text"])`を出力していますが､`corrected_text`を出力する箇所なのでそのように修正しました｡

コードを以下のようにしてみました｡

```python
import openai
import os
import boto3
openai.api_key = os.environ['API_Key']

system_prompt = """
文字起こしされた文章を整えてください｡必要の応じて､キーワードとなる単語を｢｣で囲ってください｡
"""

TRANSCRIPT_PROMPT = """
こんにちは。今日は、いいお天気ですね｡平井裕二さんが DevelopersIO で講演を行いました｡
"""

def generate_corrected_transcript(system_prompt, content):
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        temperature=0,
        messages=[
            {
                "role": "system",
                "content": system_prompt
            },
            {
                "role": "user",
                "content": content
            }
        ]
    )
    return response['choices'][0]['message']['content']

def lambda_handler(event, context):
    s3_client = boto3.client('s3') 
    bucket_name = 'net.rev-system.net.aws-lambda-openai-whisper-api'
    file_name = 'aws-lambda-openai-whisper-api.m4a'
    download_path = '/tmp/{}'.format(file_name)
    
    s3_client.download_file(bucket_name, file_name, download_path)

    with open(download_path, "rb") as audio_file:
        transcript = openai.Audio.transcribe("whisper-1", audio_file,language="ja", prompt=TRANSCRIPT_PROMPT)
    print('Transcript result:' + str(transcript["text"]))

    corrected_text = generate_corrected_transcript(system_prompt, str(transcript["text"]))
    print('Corrected text result:' + corrected_text)
    return corrected_text
```

### 文字起こしの結果
英語名詞の前後に半角スペースが残るものの文字起こしの時点で句読点が入り､TRANSCRIPT_PROMPTに指定した固有名詞も正しく反映されました｡

<details><summary>文字起こしの結果</summary>

> DevelopersIO 2023 今セッションでは Amazon Connect の機能の一つである Contact Lens for Amazon Connect 入門と題しまして、主に Amazon Connect を既に利用している方や Contact Lens for Amazon Connect について知りたい方向けの入門セッションとなります。 本セッションのスピーカーを務めさせていただきます。 AWS 事業本部コンサルティング部所属の平井裕二と申します。 本日はどうぞよろしくお願いいたします。 本セッションのアジェンダです。 まず、Amazon Connect について概要を解説し、Amazon Connect の機能の一つである Contact Lens for Amazon Connect の概要や機能、有効化の設定方法、導入するメリットについてご紹介いたします。 Amazon Connect とは、AWS が提供しているスケーラブルかつ信頼性の高い顧客窓口を 低コストでセルフサービスにて構築できるクラウド型コンタクトセンターサービスです。 Connect では、電話回線や電話番号の取得、チャット、通話録音、自動音声応答などの コンタクトセンターに必要な機能が提供されています。 また、インターネットに接続されたPCがあれば、どこからでもアクセス可能なため、 在宅勤務を含む柔軟な働き方を実現できます。 次に、Connect で使用する用語について先にご説明いたします。 Connect で電話をかけてきたお客様のことを顧客と呼びます。 電話対応したコールセンターの担当者のことをエージェントと呼びます。 そのエージェントの上司のことをスーパーエージェントと呼びます。 そして、電話対応したその一件のことをコンタクトと呼びます。 以上の用語をセッションでは度々使用します。
</details>

# 比較
以下のように､文字起こしの文字数が少ないため両モデルの出力に大きな違いはありませんでした｡

## gpt-3.5-turboによる整形の結果
`model="gpt-3.5-turbo"`を指定して実行した結果です｡実行時間は約20秒でした｡
文字起こしの結果をもとにいくつかの単語が｢｣で囲まれ､単語が言い換えられたり､文が整理されたりと､全体的に可読性が向上しました｡

<details><summary>gpt-3.5による整形の結果</summary>

> DevelopersIO 2023 今回のセッションでは、Amazon Connectの機能の一つである「Contact Lens for Amazon Connect」の入門についてお話しします。このセッションは、既にAmazon Connectを利用している方やContact Lens for Amazon Connectについて知りたい方を対象としています。私はAWS事業本部コンサルティング部所属の平井裕二と申します。よろしくお願いいたします。\n\nまず、アジェンダをご紹介します。最初に、Amazon Connectの概要について説明し、Contact Lens for Amazon Connectの概要や機能、有効化の設定方法、導入するメリットについてご紹介します。Amazon Connectは、AWSが提供しているクラウド型のコンタクトセンターサービスで、スケーラブルかつ信頼性の高い顧客窓口を低コストでセルフサービスにて構築することができます。Connectでは、電話回線や電話番号の取得、チャット、通話録音、自動音声応答など、コンタクトセンターに必要な機能が提供されています。また、インターネットに接続されたPCがあれば、どこからでもアクセス可能なため、在宅勤務を含む柔軟な働き方を実現できます。\n\n次に、Connectで使用する用語について説明します。電話をかけてきたお客様を「顧客」と呼びます。電話対応をするコールセンターの担当者を「エージェント」と呼びます。エージェントの上司を「スーパーエージェント」と呼びます。そして、電話対応した一件を「コンタクト」と呼びます。これらの用語はセッション中で頻繁に使用されます。
</details>

## gpt-4による整形の結果
`model="gpt-4"`を指定して実行した結果です｡実行時間は約40秒でした｡
gpt-3.5-turboの結果と比べ､さらにいくつかの単語が｢｣で囲まれました｡しかし､文章が短いこともあり､全体的にgpt-3.5-turboと大きな違いはみられませんでした｡

<details><summary>gpt-4による整形の結果</summary>

> 「DevelopersIO 2023」の今回のセッションでは、「Amazon Connect」の機能の一つ、「Contact Lens for Amazon Connect」の入門について解説します。このセッションは、主に「Amazon Connect」を既に利用している方や、「Contact Lens for Amazon Connect」について知りたい方向けの入門セッションとなります。スピーカーは、AWS事業本部コンサルティング部所属の平井裕二です。よろしくお願いいたします。\n\n本セッションのアジェンダは以下の通りです。まず、「Amazon Connect」についての概要を解説し、「Contact Lens for Amazon Connect」の概要や機能、有効化の設定方法、導入するメリットについてご紹介します。「Amazon Connect」は、AWSが提供しているスケーラブルで信頼性の高い顧客窓口を低コストでセルフサービスにて構築できるクラウド型コンタクトセンターサービスです。「Connect」では、電話回線や電話番号の取得、チャット、通話録音、自動音声応答などのコンタクトセンターに必要な機能が提供されています。また、インターネットに接続されたPCがあれば、どこからでもアクセス可能なため、在宅勤務を含む柔軟な働き方を実現できます。\n\n次に、「Connect」で使用する用語について説明します。「Connect」で電話をかけてきたお客様のことを「顧客」と呼びます。電話対応したコールセンターの担当者のことを「エージェント」と呼びます。そのエージェントの上司のことを「スーパーエージェント」と呼びます。そして、電話対応したその一件のことを「コンタクト」と呼びます。以上の用語をセッションでは度々使用します。
</details>

# 全文での比較
動画全体(14分22秒)の文字起こしとそれぞれのモデルでの比較を行いました｡全体の文字起こしの結果が約5,200文字となりgpt-3.5-turboのトークン上限数を超えるため､gpt-3.5-turbo-16kを使用しました｡テキスト量が多くなるため､Lambda関数のメモリ設定を256MBとしました｡

文字数が多くなると整形の結果に大きな違いが表れました｡これは､プロンプト指定した"文章を整える"をモデルがどう捉えるかの違いかもしれません｡

## gpt-3.5-turbo-16k
`model="gpt-3.5-turbo-16k"` を指定して実行したところ､実行時間は約140秒でした｡
結果の文字数が多いため省略しますが､約3,400文字となりました｡元々の目的である､文章を整えるという意味ではこちらの動作が期待値に近そうです｡

## gpt-4による整形の結果
`model="gpt-4"`を指定して実行した結果です｡実行時間は約90秒でした｡
2分の音声を扱ったときと分量があまり変化していませんが､動画の最後に触れられているワークショップについての記述があるため､全体を非常に小さくまとめたようです｡端折りすぎな感じがするので､ここはプロンプトを工夫して機能ごとに要点を整理するなど指示をだしたほうが良さそうです｡

<details><summary>gpt-4による全文整形の結果</summary>

> 本日のセッションでは、「DevelopersIO 2023」において、「Contact Lens for Amazon Connect」の入門と題し、主に「Amazon Connect」を既に利用している方や「Contact Lens for Amazon Connect」について知りたい方向けの入門セッションを行います。スピーカーは、AWS事業本部コンサルティング部所属の平井裕二です。\n\nまず、「Amazon Connect」について概要を解説し、「Contact Lens for Amazon Connect」の概要や機能、有効化の設定方法、導入するメリットについてご紹介します。「Amazon Connect」は、AWSが提供しているスケーラブルかつ信頼性の高い顧客窓口を低コストでセルフサービスにて構築できるクラウド型コンタクトセンターサービスです。\n\n次に、「Contact Lens for Amazon Connect」について解説します。「Contact Lens」は、「Amazon Connect」の機能の一つで、機械学習を利用したコンタクトセンターでの顧客とエージェント間の会話を分析するサービスです。顧客との会話を分析し、スーパーエージェントがエージェントに分析結果内容をフィードバックすることで、顧客対応の品質が向上し、顧客満足度の向上につなげることができます。\n\nまた、「Contact Lens」の設定方法は簡単に数クリックで有効化することが可能です。利用できる主な機能には、感情分析、エージェントのパフォーマンスの評価、コンタクト招待と分析、カスタム語彙、リアルタイムのアラートなどがあります。\n\n「Contact Lens」の導入により、顧客対応の品質が向上し、コンタクトセンターの目的の一つである顧客満足度の向上につなげることができます。最後に、「Contact Lens」が学べるワークショップをご紹介します。「Amazon Connect」の導入方法も記載されていますので、初めての方でも十分理解できる内容です。
</details>