2023.03.29

議事録作成の手間を解消?音声ファイルをChatGPTとWhisperで自動要約

はじめに

こんにちは。グループ研究開発本部 次世代システム研究室のT.D.Qです。

議事録作成に手間がかかるため、コア業務に集中できないと感じている方は多いでしょう。このような方におすすめなのがAIを活用した議事録の自動作成です。今回のブログでは、OpenAI社が開発したChatGPT APIWhisperを使った音声ファイルの要約システムの構築を紹介したいと思います。

1.やりたいこと

  • 目的: 音声ファイルの要約を自動化すること
  • 使用する技術: OpenAIのChatGPTとWhisper
  • 実現手段:
    • Dockerで音声自動要約専用サーバーを構築
    • Flaskを利用して音声ファイルを処理するAPIを作成
    • Whisperで音声ファイルをテキストに変換
    • ChatGPT APIで要約を生成
    • 要約テキストをユーザーに返却

    2.環境構築

    2-1.Whisperサーバー構築

    Whisperとは、OpenAIが開発している汎用的な音声認識モデルです。
    インターネット上から収集した68万時間におよぶ音声データで学習され、音声翻訳や言語識別だけでなく、多言語音声認識を行うことができるマルチタスクモデルでもあるモデルになります。Whisperの日本語の単語誤り率は6.4%であり、他の言語と比較しても高い精度で文字起こしが可能だと言えます。

    今回はDocker環境を使うので以下のDockerfileを実装しました。
    FROM python:3.10-slim
    
    WORKDIR /python-docker
    
    COPY requirements.txt requirements.txt
    RUN apt-get update && apt-get install git -y
    RUN pip3 install --upgrade pip
    RUN pip3 install -r requirements.txt
    RUN pip3 install "git+https://github.com/openai/whisper.git"
    RUN pip3 install --upgrade openai
    RUN apt-get install -y ffmpeg
    
    COPY . .
    
    EXPOSE 5000
    
    CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]
    
    音声自動要約専用サーバーは、Python 3.10-slimベースのDockerイメージを使用し、requirements.txtで指定されたPythonパッケージをインストールします。WhisperとOpenAIのPythonパッケージをインストールし、FlaskフレームワークでAPIを実装します。APIをポート5000で実行するように指定しています。また、音声・動画の変換、再生、録画などを行うためffmpegもインストールしておきます。requirements.txtに以下の内容で準備します。
    autopep8==1.6.0
    certifi==2021.10.8
    charset-normalizer==2.0.7
    click==8.0.3
    et-xmlfile==1.1.0
    Flask==2.0.2
    idna==3.3
    itsdangerous==2.0.1
    Jinja2==3.0.2
    MarkupSafe==2.0.1
    numpy==1.21.3
    openai==0.19.0
    openpyxl==3.0.9
    pandas==1.3.4
    pandas-stubs==1.2.0.35
    pycodestyle==2.8.0
    python-dateutil==2.8.2
    python-dotenv==1.0.0
    pytz==2021.3
    requests==2.26.0
    six==1.16.0
    toml==0.10.2
    tqdm==4.62.3
    urllib3==1.26.7
    Werkzeug==2.0.2
    

    2-2.ChatGPT API向けの設定

    2023年3月2日(米国時間では1日)、OpenAIChatGPTAPIが公開されました。
    プログラムからChatGPTを使うため、APIキーを発行してもらわなければなりませんので、OpenAIにログインし、右上のアイコンからView API Keyをクリックします。APIのページにいけるので、そこから新しいシークレットキーをcreateします。作成されたsecret keyはメモしておきましょう。
    OpenAIから取得したAPIキーを.envファイルを設定しますしょう。
    LASK_APP=app
    FLASK_ENV=development
    
    # Once you add your API key below, make sure to not share it with anyone! The API key should remain private.
    OPENAI_API_KEY=sk-jxxxxxxxxx
    

    2-3.音声自動要約アプリの実装

    さて、APIサーバーのエントリースクリプト(app.py)を実装しましょう。
    このソースコードは、Flaskフレームワークを使用してWebアプリケーションを構築し、Whisper及びChatGPT APIを使用して音声ファイルを自動要約します。
    「/summary」エンドポイントにPOSTリクエストを送信すると、音声ファイルを受け取り、Whisperを使用してテキストに変換し、OpenAI APIを使用して自動要約を作成し、JSON形式で結果を返します。
    中身は以下の通りです。
    from flask import Flask, abort, request
    from tempfile import NamedTemporaryFile
    import os
    import whisper
    import openai
    import torch
    
    # NVIDIA GPUが利用可能かどうかを確認
    torch.cuda.is_available()
    DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
    
    # Whisperモデルをロードする
    model = whisper.load_model("medium", device=DEVICE)
    
    # OpenAPI APIキーを設定する
    openai.api_key = os.getenv("OPENAI_API_KEY")
    
    app = Flask(__name__)
    
    
    @app.route("/")
    def welcome():
        return "Welcome to my Blog Post about ChatGPT and Whisper!"
    
    
    @app.route('/summary', methods=['POST'])
    def handler():
        if not request.files:
            # ユーザーがファイルを渡さなかった場合は、400 (Bad Request) エラーを返す
            abort(400)
    
        results = []
    
        # ユーザーが渡したすべてのファイルに対してループする
        for filename, handle in request.files.items():
            # 一時ファイルを作成する.
            temp = NamedTemporaryFile()
            # ユーザーがアップロードしたファイルを一時ファイルに書きこむ
            handle.save(temp)
            # Whisperモデルで音声の一時ファイルからテキストを取得する
            result = model.transcribe(temp.name)
    
            # Sテキストを要約する
            summary_result = summary_text(result['text'])
            # 結果オブジェクトを作成する
            results.append({
                'transcript': result['text'],
                'language': result['language'],
                'summary': summary_result,
            })
    
        # JSON形式で結果を返却する
        return {'results': results}
    
    def summary_text(transcribed_text):
        if len(transcribed_text) == 0:
            return ""
        print(generate_prompt(transcribed_text))
    
        try:
            response = openai.Completion.create(
                model="text-davinci-003",
                max_tokens=1024,
                stop=None,
                prompt=generate_prompt(transcribed_text),
                temperature=0.7,
            )
            print(response)
    
            return response.choices[0].text
        except Exception as e:
            print(e)
            return ""
    
    def generate_prompt(transcribed_text):
        return """以下の文章は日本語におかしいなところを修正してください。修正した文章を説明不要で箇条書き文章のみに簡潔に答えてください:
        {}""".format(transcribed_text)
    
    
    summary_text関数は、テキストを受け取り、OpenAI APIを使用して自動要約を作成します。 関数のパラメータは以下のとおりです。
  • model:使用する言語モデルの種類を指定する(ここでは”text-davinci-003″を使用)
  • max_tokens:生成される文章の最大トークン数を指定する(ここでは1024を指定)
  • stop:生成される文章の停止語を指定する(ここでは指定せずNoneとしている)
  • prompt:生成される文章のプロンプトとなる文章を指定する(ここではtranscribed_textを引数として渡してgenerate_prompt()で作成)
  • temperature:文章生成のランダム性を調整するパラメータ。0に近いほど一意な文章が生成されやすく、1に近いほど一般的な文章が生成されやすくなる。0から1の値を指定する(ここでは0.7を指定)。
  • このChatGPTのAPI仕様が公開されているので興味の方はご参照ください。

    2-4.アプリケーションサーバを起動

    早速、dockerコマンドで音声自動要約サーバーのImageをビルドしましょう。Dockerfileが存在するディレクトリに移動し、以下のコマンドを実施しましょう。
     docker build -t audio-summary-api . 
    
    大量の依存関係を解決するために必要なパッケージをインストールしたり、GPUカード対応のためサイズの大きいファイルのダウンロードが発生するのでビルド時間が10分以上になります。

    Docker Imageをビルドできたら次のコマンドでAPIサーバを立ち上がりましょう。
    docker run -p 5000:5000 audio-summary-api
    
    ここまでは音声自動要約サーバーの準備ができました。

    3.実験結果と評価

    3-1.自動要約された音声ファイル

    早速、音声自動要約APIを検証しましょう。次のcurlコマンドを使用してこのAPIを検証できます。
    curl -F "file=@/path/to/file" http://localhost:5000/summary
    
    結果として、JSONオブジェクトに以下の項目が含まれるはずです。
  • language: Whisperが音声ファイルから認識したテキストの言語
  • transcript: Whisperが音声ファイルから認識したテキストの本文
  • summary: ChatGPTが要約したテキスト
  • 今回は、次世代システム研究室の新卒メンバー1年目後のインタビュー動画から音声を抽出して構築したシステムでテキストに要約したいと思います。yt-dlpなどPythonのライブラリを使用して音声抽出が可能ですが、今回のブログでは対象外としました。

    3-2.要約結果

    ChatGPT APIの出力を安定するまでモデルを切り替えたり、Promptの内容をチューニングしたりする必要がありますしたのでソースコードに記載したPromptのように対応しましたが、
    ChatGPTのInputとなるWhisperのOutputをチューニングが大事ですね。ちなみに、Whisperモデルは以下の9種類がありますが、今回は日本語を対応する多言語モデルのみ使います。
    Size Parameters English-only model Multilingual model Required VRAM Relative speed
    tiny 39 M tiny.en tiny ~1 GB ~32x
    base 74 M base.en base ~1 GB ~16x
    small 244 M small.en small ~2 GB ~6x
    medium 769 M medium.en medium ~5 GB ~2x
    large 1550 M N/A large ~10 GB 1x
    各Whisperモデルを検証するため、app.pyにてwhisper.load_modelにモデル名を指定しましょう。
    # Load the Whisper model:
    model = whisper.load_model("base", device=DEVICE)
    
    音声ファイルを指定して、自動要約APIを実行しましょう。APIの実行には、私自身がよくPostmanを使っているので、今回もPostmanで検証を行いたいと思います。

    使えませんね。。ベースモデルだとWhisperのOutputとなるtranscriptが非常に精度が低いため、音声からテキストに変換した結果は全く使えませんでした。。
    Whisperベースモデルの検証結果に加えて、上位のモデルも含めた検証結果を確認したいと思います。そのため、ソースコードにてWhisperモデルをmediumに設定して検証してみましょう。
    # Whisperモデルをロードする
    model = whisper.load_model("medium", device=DEVICE)
    
    見事、mediumモデルを使うとtranscriptの内容がかなり改善されたため、ChatGPTによる要約結果であるsummaryも大幅に改善されました。厳密に言えば、この要約文章はまだ改善の余地があると思いますが、意味はかなり明確になりました。

    今回の検証結果は以下のテーブルでまとめました。
            
    Whisper model モデルサイズ 音声ファイルサイズ 初回サーバ起動時間 自動要約時間 精度
    tiny 72.1MB 950Kb 40秒 15秒 非常に低い
    base 139MB 950Kb 1分38秒 17~20秒 非常に低い
    small 461MB 950Kb 4分19秒 28秒 低い
    medium 1.42GB 950Kb 14分08秒 1分24秒 良い
    large 2.87GB 950Kb 起動不可(リソース不足) 使えない
    検証結果からみるとWhisperモデルは、モデルサイズが大きくなるほど高い精度が得られます。特に、最近large-v2モデルも公開されているようですので、さらなる精度を期待できますね。今回の検証は、Whisperのmediumモデルからは良さそうな精度を得ましたが、Macbook ProのPCではその以上の精度を期待するlargeモデルが正常に実行できないことは少し残念でした。また、モデルサイズの大きさや処理速度に大きく影響を与える問題を発見しました。モデルの初回ダウンロードのためサーバの立ち上がる時間が長い場合があるため、リアルタイム対応は複雑な対応になるかもしれませんが、短期間で音声認識にはGPUカードを搭載する高スペックなサーバーを検討するか有料版のWhisper APIおよびChatGPT APIの利用を検討したほうがよさそうです。最近、OpenAIの有料版APIの導入により、1時間のミーティングをわずか3分で議事録を作成できるようになった記事が公開されましたので。

    ChatGPT API (GPT-4)とWhisper APIの利用費用

    今回のブログでは、Whisperの実行環境を自分で構築し、ChatGPT APIのtext-davinci-003モデルを使用して無料で音声自動要約システムを構築しました。しかし、より高性能なAPIであるGPT-4やWhisper APIを使用する場合は、以下の価格表に記載されている料金が必要となります。この価格表はOpenAIが正式に公開しているページに記載しているのでご参照くだだい。
    今回の検証音声ファイルの長さが30秒程度、生成したトークンが1000以内なので、GPT-4およびWhisper API(large-V2 モデル)を使うと1回の要約は$0.036(3/29現在のドル円は1$=131.5円で換算すると4.8円)になるかと思います。
       
    モデル トークンタイプ 価格
    GPT-4 プロンプトトークン 1000あたり$0.03
    サンプルトークン 1000あたり$0.06
    GPT-4-0314 プロンプトトークン 1000あたり$0.03
    サンプルトークン 1000あたり$0.06
    GPT-4-32K プロンプトトークン 1000あたり$0.06
    サンプルトークン 1000あたり$0.12
    GPT-4-32K-0314 プロンプトトークン 1000あたり$0.06
    サンプルトークン 1000あたり$0.12
    Whisper large-V2 モデル 1分あたり0.006ドル

    まとめ

    いかがでしょうか?このブログでは、OpenAIが開発したChatGPT APIとWhisperを活用して、音声ファイルの自動要約方法を紹介しました。Whisperを使うことで、多言語の音声ファイルを文字起こしし、その後ChatGPTを使って、インタビューや議事録などのテキスト文章を簡単かつ迅速に要約することができます。
    ただし、Whisperの実験情報からわかるように、低いスペックなマシンではモデルサイズやサーバー立ち上がる時間、自動要約時間などの課題が残されています。特に、大規模な音声ファイルを短期間で処理するためには、有料版のAPIを使うか、もしくはGPUカード搭載サーバーでの実行が必要であると思います。
    今後は、この自動要約の機能をさらに便利なGUIに加えて、Slackなどのコラボレーションツールに組み込んで、議事録の作成作業を一層自動化することが期待できるのではないでしょうか?

    宣伝

    次世代システム研究室では、最新のテクノロジーを調査・検証しながらインターネットのいろんなアプリケーションの開発を行うアーキテクトを募集しています。募集職種一覧 からご応募をお待ちしています。

    • Twitter
    • Facebook
    • はてなブックマークに追加

    グループ研究開発本部の最新情報をTwitterで配信中です。ぜひフォローください。

     
    • AI研究開発室
    • 大阪研究開発グループ

    関連記事