AWS Lambda でOpenAI の Whisper API を 認識精度の改善も含めて試してみた

2023.10.19

はじめに

AWS LambdaでOpenAIのWhisper APIを試してみました。

OpenAIには音声データから文字起こししてくれる「Whisper」という音声認識モデルがあり、WhisperをAPIの形で呼び出すWhisper APIが存在します。日本語ももちろん対応してます。

今回は、AWS LambdaがS3バケットに保存された音声データを元にWhisper APIで文字起こしして、精度を確認してみたいと思います。

OpenAIアカウントAPIキーの発行

OpenAIアカウント作成後、APIキーの発行をします。 APIキーの発行は、アカウントの View API keys をクリックします。

Create new secret key をクリックすると、API keyが発行されますので、コピーしておきます。

S3バケット

拡張子がwavの音声ファイルをS3バケットに保存しました。

Whisper API は、デフォルトでは 25 MB 未満のファイルのみをサポートしてますので、20MB程度のサイズにしてます。

ちなみに、音声ファイル元は、以前「Contact Lens for Amazon Connect 入門」というタイトルでビデオセッションした動画のうち、最初の2分を音声ファイルに変換したものです。

Lambdaの作成

OpenAIはPython向けのライブラリを提供しています。このライブラリをインストールし、Lambda Layerにアップロードします。(直接zip形式でのアップロードも可能)

MacBook Pro M2の場合、以下のコマンドでライブラリをインストールし、Zip化することができます。

$ mkdir python
$ python3 -m pip install -t ./python openai
$ zip -r openai.zip ./python

Lambdaレイヤーでopenai.zipをアップロードします。

ランタイムPython 3.11を選択し、Lambda関数を作成します。

  • S3バケットにアクセスするため、LambdaのIAMロールには、AmazonS3FullAccessをアタッチします。
  • 環境変数では、キーはAPI_Key、値はAPIキーの値を入力
  • タイムアウトは、3秒から2分に変更
  • Lambdaレイヤーを追加

コードは下記の通りです。S3バケットとファイル名は、各々変えて下さい。

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

def lambda_handler(event, context):
    s3_client = boto3.client('s3') 
    bucket_name = 'S3バケット名'
    file_name = 'ファイル名'
    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)
    print('Transcript result:' + str(transcript["text"]))
    return str(transcript["text"])

実行してみた

先程のコードでLambdaを実行すると、実行時間は、約15秒でした。

20MBの音声ファイルをtmpディレクトリにダウンロードするのに5秒かかり、残りがWhisper APIのレスポンスでした。

実際の文字起こし内容↓

ーーーここからーーー

ディベロッパーズ IO 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 で電話をかけてきたお客様のことを 顧客と呼びます 電話対応したコールセンターの担当者のことを エージェントと呼びます そのエージェントの上司のことを スーパーエージェントと呼びます そして電話対応したその1件のことを コンタクトと呼びます 以上の用語をセッションでは

ーーーここまでーーー

漢字や英語が違和感なく文字起こしされており、精度が高い印象です。

ただし、3つほど気になった点があります。

  • 文中に句読点がない
  • 無関係のスペースが存在する。
  • 固有名詞の誤記
    • ディベロッパーズ IO → DevelopersIO
    • 平井裕治 → 平井裕二

コードを修正して、気になった点を改善します。

改善方法

固有名詞の誤記、誤ったスペースの挿入、および句読点の欠如については、Whisper APIの公式ドキュメントに記載されているように、次の2つの解決方法があります。

  1. プロンプトパラメーターを使用
  2. GPT-4による追加処理

1.プロンプトパラメーターを使用

1つ目は、Whisper APIのオプションのプロンプトパラメーターを使用する方法です。

この方法では、以下のようにpromptに修正の命令文を入力することで、おおよそ指示通りに修正を行ってくれます。

transcribe(filepath, prompt="命令文")

ただし、promptには最大で244トークンしか渡せませんので、注意しましょう。

promptパラメータを加えた下記のコードで試してみました。

コード (クリックすると展開します)
import openai
import os
import boto3
openai.api_key = os.environ['API_Key']

system_prompt = """
あなたの仕事は、文字起こしされた文章を整えることです。
必要に応じて句読点を追加してください。
必要に応じて、無意味なスペースは削除してください。
ディベロッパーズ・アイオーは、DevelopersIOに変換してください。
ひらいゆうじという人名は、平井裕二に変換してください。
"""

def lambda_handler(event, context):
    s3_client = boto3.client('s3') 
    bucket_name = 'S3バケット名'
    file_name = 'ファイル名'
    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, prompt=system_prompt)
    print('Transcript result:' + str(transcript["text"]))
    return str(transcript["text"])

実行時間は15秒程度でした。

実際の文字起こし内容↓

ーーーここからーーー

"ディベロッパーズ・アイオー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が提供しているスケーラブルかつ 信頼性の高い顧客窓口を低コストで セルフサービスにて構築できる クラウド型コンタクトセンターサービスです。 コネクトでは、電話回線や電話番号の取得、 チャット、通話録音、自動音声応答などの コンタクトセンターに必要な機能が提供されています。 また、インターネットに接続されたPCがあれば どこからでもアクセス可能なため、 在宅勤務を含む柔軟な働き方を実現できます。 次に、コネクトで使用する用語について 先にご説明いたします。 コネクトで電話をかけてきたお客様のことを 顧客と呼びます。 電話対応したコールセンターの担当者のことを エージェントと呼びます。 そのエージェントの上司のことを スーパーエージェントと呼びます。 そして、電話対応したその一件のことを コンタクトと呼びます。 以上の用語セッションでは"

ーーーここまでーーー

句読点が追加され、一部スペースが削除されました。また、固有名詞は、平井裕二に変換されました。

ただし、無関係なスペースが一部あったり、ディベロッパーズ・アイオーは正式名称に変換されませんでした。

2. GPT-4による追加処理

2つ目の改善方法は、GPT-4(もしくは GPT-3.5)による追加処理です。

Whisper APIで文字起こした内容に対して、GPT-4で文章を整える処理を追加します。

GPT-4のプロンプトでは、句読点の挿入、不必要なスペースの削除、および固有名詞の適切な変換を指示します。

実際に実行したコードは下記の通りです。

コード (クリックすると展開します)
import openai
import os
import boto3
openai.api_key = os.environ['API_Key']

system_prompt = """
あなたの仕事は、文字起こしされた文章を整えることです。
必要に応じて句読点を追加してください。
必要に応じて、無意味なスペースは削除してください。
ディベロッパーズ・アイオーは、DevelopersIOに変換してください。
ひらいゆうじという人名は、平井裕二に変換してください。
"""

def generate_corrected_transcript(system_prompt, content):
    response = openai.ChatCompletion.create(
        model="gpt-4",
        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 = 'S3バケット名'
    file_name = 'ファイル名'
    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)
    print('Transcript result:' + str(transcript["text"]))

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

実行時間は、50~60秒程度と長くなりました。

実際の文字起こし内容↓

ーーーここからーーー

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

ーーーここまでーーー

文章に合わせて句読点や無関係なスペースの削除だけでなく、段落(\n\n)や、かっこ(「」)も追加されており、1. プロンプトパラメーターを使用と比較すると、こちらの方法の方が読みやすいです。。

また、音声ファイルでは、最後以上の用語セッションではで終わっていますが、ChatGPT-4によって、以上の用語をセッションでは使用します。と補完されています。

固有名詞も変換されてますね。

プロンプトでは、ディベロッパーズ・アイオーは、DevelopersIOに変換してください。と記載しましたが、ディベロッパーズ IOという文字起こしでも内容でもDevelopersIOに変換されました。

最後に

今回は、AWS LambdaでWhisper APIの使用感と精度を確認しました。

Whisper APIだけでも十分な精度を示しますが、GPT-4による追加処理を行うことにより、さらなる可読性の向上を確認できました。

ただし、GPT-4を使用することで実行時間が増加するという課題があります。しかし、AIの性能向上に伴い、この問題も将来的に解消されることが予想されます。

参考