Learn efficient methods for transcribing meeting recordings and creating minutes using AI technologies like OpenAI’s Whisper, the new o1 model, Python, and FFmpeg.
相模原市で IoT 設計を受託しているファームロジックスです。
最近、あるお客様からの依頼で、ミーティング録音の文字起こし(いわゆるテープ起こし)と、そこからの議事録作成をさせて頂きました。私の専門外の議事ということもあり、手作業ではとても無理でしたので、機械学習(AI)技術を最大限に活用しました。
1時間の音声で 50円程度から可能
まず最初に、テープ起こしの費用について御興味の方が多いでしょう。既に ChatGPT Plus のサービスを利用している場合には、後述の Whisper と OpenAI o1 を利用することで、かなり質の高いテープ起こしが 1時間の音声あたり 0.36 米ドル(現在のレートで 50円程度)から可能です。
この費用は概ね Whisper というクラウドサービスによるもので、ChatGPT の o1 モデルは、現在 Plus サービスで 1週間あたり 50メッセージまで追加費用なしで利用できます。
音声テキスト変換(Speech-to-Text)
AI による音声テキスト変換技術には以前から興味があったのですが、なかなか実践する機会がありませんでした。今回はじめて取り組んでみたところ、AI の進化に驚きつつも、実際の議事録起こし作業ではさまざまな問題に直面することが分かりました。私自身の備忘録としてもさることながら、ブログを御覧頂いている皆様の少しでもお役に立てればと思い、今回の作業から得たノウハウを共有させて頂こうと思います。
ちなみに結論から申しますと、つい最近リリースされた OpenAI(ChatGPT)の最新モデル「o1」を使うのがもっとも効率的だと分かりましたが、実は作業を始めた段階では o1 が未リリースで(o1-preview は存在した)、また、o1 がそのような用途(議事録作成)に適しているとは予想していなかったため、まずは OpenAI Whisper だけを使うことにしました。
録音データの準備
最初に必要なのは、議事録の録音を電子ファイルとして用意することです。
私が所有している IC レコーダは、オリンパス社の Voice-Trek DM-20 という非常に古いモデルですが、当時の製品によくあるように、高品質な設計と耐久性で、まだまだ十分に使用できます。この IC レコーダにも USB 接続機能はありますが、録音形式は当時一般的だったWMA(Windows Media Audio)形式となっています。今なら、普通は AAC(.m4a)といったところでしょうか。
私は当初、この WMA 形式の音声を AAC および MP3(お客様向け)に変換しました。後で分かったのは、OpenAI 社のクラウド Whisper サービス(後述)を利用するには、アップロードファイルのサイズ制限があることです。その点を考慮して、高音質を保ちつつファイルサイズを最小限に抑えるには、現在では拡張子 .webm の WebM 形式(コンテナ形式)を使った Opus 符号化(エンコーディング)が良さそうです。
Opus 符号化を直接使用して拡張子 .opus で音声ファイルを作成しても、後から WebM コンテナ形式(拡張子 .webm)に変換するのは容易なので、まずは .opus 形式で作業しようと思います。変換には、フリーソフトウェアの FFmpeg を使用することにします。いろいろと試行錯誤したのですが、Voice-Trek DM-20 の WMA 形式ファイルに録音された音声(スピーチ)を確実に変換するには、次のようなコマンドが良さそうです。(macOS や Linux ではそのまま実行できます。Windows でも、Windows Subsystem for Linux (WSL) や Git Bash、Cygwin で対応できます。)
ffmpeg -i input.wma -f s16le -ar 16000 -ac 1 - | ffmpeg -f s16le -ar 16000 -ac 1 -i - -c:a libopus -b:a 32k -application voip -vbr on -y output.opus
このコマンドのパイプラインは冗長ですが、このようにすると、変換時にタイムスタンプに関する警告を避けられます。もともとの音声ファイルの周波数特性が 7kHz 以下だそうなので、サンプリングレートは 16kHz とします。Opus のビットレートは 32kbps もあれば十分でしょう。-application voip -vbr on
を指定して、音声(スピーチ)に最適化し、可変レート符号化も明示的に指定しておきます。
ファイルの編集
IC レコーダなどから録音したファイルには、通常、冒頭や末尾に余計な音声(司会者の声やノイズ等)が含まれています。後で音声文字変換をする際に邪魔になりますし、変換時間も増え、またクラウドサービスを利用する場合には利用料金やアップロードサイズ制限もありますので、できるだけ余計な音声は削除しておくのが得策です。
音声ファイルの編集にはいろいろなソフトがありますが、私は以前から使い慣れている Audacity を使いました。Audacity は 2021年頃、ある企業に買収されたときにゴタゴタがありましたが、現在は解決しているようです。(参考: Wikipedia)
Audacity の使い方は、ネット上にいろいろとチュートリアルがあると思いますので、そちらを参考にしてください。音声ファイルの保存には、上記同様、私は以下のように保存(export)しました。これ以外の設定はデフォルトです。
- Format: Opus
- Channels: Mono
- Sample Rate: 16000 Hz
- Bit Rate: 32 kbps
- VBR Mode: On
- Optimize for: Speech
OpenAI Whisper による文字起こし
さて、早速文字起こしです。おそらく、世の中には有償のソフトですとか、クラウドサービスが多くあると思うのですが、私は、以前に一度だけ試したことのある OpenAI Whisper のローカル PC 実行版を、まずは使ってみることにしました。
ローカル PC での Whisper(無料)
Whisper のソフトウェア(ローカル PC 実行版)は、以下から無料でダウンロードできます。
インストール方法はドキュメントを御参考ください。
テキストへの変換は、簡単なやり方としては次のようにして実行します。
whisper --initial_prompt 'Please keep punctuation.' input.opus
--initial_prompt
による指定 Please keep punctuation.(句読点を残してください)ですが、このような指定をしないと、変換結果に句読点が出力されないことがあります。
もう少し正確な変換をしたい場合は、プロンプトを使って音声ファイル中に現れる専門用語などを指定すると良いようです。(詳細はこちらを御覧ください。) ただし実際には、Whisper のプロンプト長には厳しい制限があり、思ったほどの効果は得られないことが後で分かりました。
whisper --initial_prompt 'Please keep punctuation. 用語: DSP 音声信号処理(おんせいしんごうしょり) 機械学習(きかいがくしゅう)' input.opus
ちなみに私は当初、専門用語の指定はしませんでした。理由は、私の専門外の議事が録音された内容であり、用語の指定が難しかったからです。後にクラウド版の Whisper を使うことになった時には、お客様から専門用語のリストを頂くことができました。
このように Whisper を実行すると、次のようなファイルが出力されます。
- input.srt
- input.tsv
- input.vtt
YouTube に投稿するビデオなどにキャプションを付けるのに便利なフォーマットも含まれるようですが、私は単純で読みやすい input.vtt を利用しました。
OpenAI 社のクラウドサービス
上記の「ローカル PC」による変換は無料で手軽なのですが、残念ながら、変換結果には満足できませんでした。その後、Hugging Face の openai/whisper-large-v3(下記)も試してみたのですが、メモリとディスクをかなり使用すること、そしてなにより GPU を利用しないと動作が極めて遅いこともあり、こちらも諦めました。
最終的に、以前にアカウントを作ったことのある OpenAI 社のクラウドサービスに落ち着きました。このクラウドサービス(モデル名: whisper-1)は有料($0.006/分)で、たとえば 1時間の音声だと現在の為替レートで 50円ほどかかります。しかし、品質はかなり満足できるものであり、話者から少し離れて録音した、声が小さめの音声データでも、十分に利用できるテキストが得られます。
一つ注意点として、このクラウドサービスでは .opus 形式の音声はそのまま利用できません。(アップロードできません。)そのため、例えば FFmpeg であれば、次のようにして予め WebM コンテナ形式に変換しておきます。
ffmpeg -i input.opus -c:a copy -f webm output.webm
ただの形式変換であり、再符号化(再エンコード)は伴わないので、変換はすぐに終わります。なお、アップロードするファイルのサイズは 25Mバイト以下である必要があります。
Whisper のクラウドサービスには ChatGPT のようなウェブインターフェイスはないので、API を直接呼び出す必要があります。Python という言語でプログラムを書きます。こんな感じのコードになるでしょうか。(動かすには.env
ファイルに API キー OPENAI_API_KEY
の設定が必要です。)
import json import warnings from dotenv import load_dotenv from openai import OpenAI # Whisperプロンプトの定義 WHISPER_PROMPT = """ 用語: DSP 音声信号処理(おんせいしんごうしょり) 機械学習(きかいがくしゅう) """ load_dotenv() client = OpenAI() audio_file = open("input.webm", "rb") transcription = client.audio.transcriptions.create( model="whisper-1", file=audio_file, response_format="verbose_json", prompt=WHISPER_PROMPT, timestamp_granularities=["segment"], ) # JSONをそのまま保存 def save_json(transcription, filename): warnings.filterwarnings("ignore", category=UserWarning) data = transcription.to_dict() with open(filename, "w", encoding="utf-8") as json_file: json.dump(data, json_file, ensure_ascii=False, indent=4) print(transcription) save_json(transcription, "output.json")
実際には、次のようなテキスト形式で保存するようにすると、お客様への提示や、後述の ChatGPT 処理が容易になるでしょう。(左端の数字は、[分:秒] という形式のタイムスタンプです。後で元の音声ファイルと付き合わせるときに便利です。)
[000:00] 皆様、本日はお集まり頂きましてありがとうございます。 [000:06] 今日は、ファームロジックスの業務内容と最近の取り組みについて説明させて頂きたいと思います。 ... [029:30] 本日はありがとうございました。
OpenAI 社のクラウド版 Whisper は、さすがに商用版(有償)ということもあり、GitHub 版や Hugging Face のモデル(ソフト)よりも認識(変換)精度が高いようです。
誤認識との闘い
いま、クラウド版 Whisper の認識精度は優秀だと述べたばかりですが、確かに一般の用語ばかり現れる音声であれば十分な品質だと思うのですが、専門用語が多い音声ファイルであったり、また、話者が早口である、または、声が小さいといった場合には、出力されるテキストに誤変換(誤認識)が多くなってきます。
特に、先ほど Whisper ではプロンプトを指定することで用語の誤認識を防ぐことができると書きましたが、前述したこちらの説明ページにあるように、プロンプト長は 224トークンに制限されており、期待したほどの効果は得られません。
今回はお客様から頂いた音声ファイルであり、内容をそのまま引用することはできないのですが、少し雰囲気をお伝えしてみましょう。こんな感じです。
- 誤: ファームロジックスから帰りました、横山でございます
- 正: ファームロジックスから参りました、横山でございます
- 誤: スタッフ企業
- 正: スタートアップ企業
- 誤: 品数の良い
- 正: 品質の良い
- 誤: 書庫にある広大な資料
- 正: 書庫にある膨大な資料
以下のように、思わず吹き出してしまいそうな誤変換もあります。
- 誤: 生徒ハンバーガー
- 正: 製造販売業
誤変換の中には、誰が見ても明らかなものもあれば、文脈が分からないと人間でも聞き間違いそうなものもあります。
余談ですが、最初に変換後のテキストを見てから音声を聞くと、「確かにそのように聞こえてしまう」ものもあり、思わず「空耳アワー」という昔のテレビ番組コーナーを思い出してしまいました。
実はこの結果を基に、ChatGPT(GPT-4o)に(本記事の後半で示したような)説明資料の作成をさせました。専門分野でない私には、ある程度意味のありそうな資料が得られたと思ったのですが、お客様に示したところ、苦笑されてしまいました。(使えるレベルではなかった、ということ。)
作戦 1: そのまま ChatGPT に任せる
このままでは、文字起こしテキストをお客様に渡す訳にはいきませんので、対策を考えます。
先ほどの説明ページの下の方のセクション(Improving reliability)を見ると、次のように書かれています。
Post-processing with GPT-4
The second method involves a post-processing step using GPT-4 or GPT-3.5-Turbo.
どういうことかと言いますと、Whisper だけに頼るのではなく、同社の生成言語モデル GPT で後処理をしてください、ということです。Whisper とは異なり、GPT ならば API を使わずとも、ChatGPT ウェブサービスで GPT を利用することができます。早速やってみましょう。
ところで、この文字起こしテキストをいきなり渡しても、ChatGPT にはテキスト文章の背景(専門分野)や専門用語が分からないでしょう。どうしたら良いでしょう?
私が最初に試みた方法は(おそらく皆さんもお考えになるでしょうが)、チャットの最初に、お客様から拝借した、会議のアジェンダ(議事日程、プログラム)などのテキストファイル、あるいは PDF ファイルを与える、という方法です。さらに、先ほど説明したように、お客様から AI が聞き間違えそうな専門用語集を頂ければ、もっと良いでしょう。
私は ChatGPT の一般的なモデル GPT-4o を使って、上記のようにチャットの書き出しをした後、続けて文字起こしテキストを「一度に」与えてみました。
しかし、この方法はダメでした。確かに、議事の冒頭のテキストについては、ある程度正確に誤認識を識別して修正してくれるのですが、議事が進むにつれて、テキストが滅茶滅茶になってしまうのです。いわゆる「妄想」(hallucination)と呼ばれる現象でしょうか。生成言語モデルが抱える本質的な制限である、コンテキストウィンドウの大きさ(小ささ)が影響しているかも知れません。
この方法は、諦めることにしました。
作戦 2: OpenAI 社の GPT API サービスを利用する
先ほど、OpenAI 社の API サービスで Whisper を使用する方法を説明しましたが、同社のサービスでは、ChatGPT のベースとなっている生成言語モデル GPT についても API が利用できます。
いったい何をするのでしょうか?
私のアイデアは、こういうものでした。つまり、文字起こしのテキストをまとめて与えるからいけないのであって、1行ずつ与えてみたらどうだろう、というものです。ChatGPT のインターフェイスを使っても良いのですが、手作業で 1行ずつ入力するのは大変です。
そのために、Whisper と同様に Python で API 呼び出しのプログラムを作成します。以下のようなイメージです。(テキストにはわざと書き間違いを含めています。)
from dotenv import load_dotenv from openai import OpenAI # 環境変数のロード load_dotenv() client = OpenAI() # チャット履歴の初期化 chat_history = [ { "role": "system", "content": "あなたは Whisper による書き起こしに対して、Whisper の誤変換を修正するスタッフです。与えられた入力文を修正し、行末尾に [誤変換1 -> 修正済1, 誤変換1 -> 修正済2] のように加えてください。", }, { "role": "user", "content": "[000:00] 皆様、本日はお改まり頂きましてありがとうございます。", }, ] # 初回の応答取得 response = client.chat.completions.create( model="gpt-4o", messages=chat_history, ) # 応答を履歴に追加 assistant_reply = response.choices[0].message.content print(assistant_reply) chat_history.append({"role": "assistant", "content": assistant_reply}) # 次のメッセージの追加 chat_history.append( { "role": "user", "content": "[000:06] 今日は、ファームロジックスの豪雨内容と最近の取り組みについて設営させて頂きたいと思います。", } ) # 2回目の応答取得 response = client.chat.completions.create( model="gpt-4o", messages=chat_history, ) # 応答の出力 assistant_reply = response.choices[0].message.content print(assistant_reply) # 以下、続く
私が実行すると、以下のような出力になりました。
[000:00] 皆様、本日はお集まり頂きましてありがとうございます。[お改まり -> お集まり] [000:06] 今日は、ファームロジックスの業務内容と最近の取り組みについて説明させて 頂きたいと思います。[豪雨内容 -> 業務内容, 設営 -> 説明]
実際に利用するときは、先ほどと同様に、議事のアジェンダですとか、用語のリストなどを冒頭で与えます。また、AI がテキストのどのような部分を変更したかについても、GPT に回答して貰います。今回はお客様依頼で作成したプログラムですので、詳細は割愛させて頂きます。
ところで、上記のプログラムをそのまま使いますと、chat_history
がどんどん大きくなり、つまりトークン数が大きくなり、プログラムの動作がどんどん遅くなるだけでなく、API の使用料金が無視できなくなってきます。これはどのように対策したら良いでしょうか。
作戦 3: GPT に定期的に用語リストを作成させる
私が考えた方法は、入力テキスト(議事)を数行与える度に、GPT に今まで現れた誤変換と正しい用語の対照リストを作成させ、過去の chat_history
の古い部分を置き換える、という方法です。
恐らく、この方法は機能します。ただし、実際には試していません。
作戦 4: ChatGPT を使って、最初に用語の対照リストを作らせる
このアイデアを思いついたときは、思わず膝を叩きました。(自画自賛)
どのようなアイデアか説明いたします。作戦 1 で示したように、文字起こしテキストを一度に渡してしまうと修正版のテキストを正しく生成してくれない(最初の方は良いが、後のほうが滅茶滅茶になる)のですが、テキストを一度に渡したとしても、「誤変換と正しい用語の対照リスト」を作成して貰うことはできるのではないでしょうか。
さらにもしかすると、その対照リストは以後の作業にとって極めて重要なので、GPT-4o モデルでなく、現在プレビュー中である o1-preview モデルにやらせてみたらどうなのでしょう!? (ChatGPT Plus サービスを利用していれば、o1-preview モデルは一定回数まで追加費用なしで利用できます。)
対照リストが一度完成したら、後は上記の Python プログラムを修正して、chat_history
をどんどん長くすることなく、毎回、対照リストと新しい 1行だけを渡すようにすれば、動作は軽快になり、API 使用料金も最小限に抑えられるはずです。
青天の霹靂 OpenAI o1(オーワン)登場
このアイデアを思いついたので、私は早速 PC に向かいました。ウェブブラウザで ChatGPT のインターフェイスを開きます。
そのときです。なんと、以前からプレビュー中だった o1-preview から「preview」が外れて、「o1」モデルがリリースされているではないですか!!(12月9日現在)
まあ、それは良いことです。それはそれとして、私は早速、上記のアイデアを試してみることにしました。o1 モデルに、議事の開催通知、アジェンダを与えたのち、Whisper が生成した誤変換だらけの文字起こしテキストを与え、次のように指示しました。
私: Whisper で文字起こししたテキストを示します。誤認識が多いです。誤認識と思われる用語と、本来の用語(本来、こういう発言だっただろうという用語)の対照リストを作ってください。
するとどうでしょう。以下のような回答が得られました。
OpenAI o1: 以下に、Whisperが誤認識したと思われる用語と、その本来の正しい用語の一例を対照表としてまとめます。
(※全てを網羅できない可能性がありますが、文脈から推定できる代表的な誤認識箇所を示します。)
対照リストは表形式で出力され、各カラムには
- 誤認識用語
- 正しい用語(推定)
だけでなく、なんと
- 備考
まで明記されていました。お客様から頂いた資料に基づくものなので、ここで示すことができないのが残念なのですが、おそらく専門分野のお客様が見ても納得するような、詳細な対照リストが得られたのです。
結論: Whisper + o1 で解決
ここまで来ると、その結果に感激する一方で、私は嫌な予感がしました。モデル o1 の能力は、私の期待を超えるものなのではないだろうか? GPT-4o ではできなかったテキストの一括処理を、o1 ならば処理できたりするのではないだろうか? 昨日までの私の作業(と API 利用料金)はもしかして無駄になったのではないだろうか?
o1 モデルに続けて依頼します。
私: それを元に、先ほどのテキストを1行ずつ全て修正してください。以下のように、末尾に [] で囲って修正点を明記してください。
(略)
o1 モデルは長考に入りました。最初の 2回はエラーになってしまいました。不安な気持ちで Re-generate(回答の再生成)ボタンをクリックします。
するとどうでしょう? GPT-4o のときとは異なり、文字起こしの先頭から末尾まで、きちんと修正テキストを作ってくれたではないですか。昨日までの私の苦労はいったいなんだったのでしょうか!? 生成モデル(AI)の進化の恐ろしさを痛感しました。
まとめます。
先ほど述べたように、OpenAI 社のモデル o1 は正式にリリースされ、ChatGPT Plus のユーザーであれば一定回数まで追加費用なしで利用可能です。具体的には、週あたり 50メッセージまで利用できます。
今回の私の作業では、モデル o1 に以下のような 3回のメッセージを送ることで、Whisper による誤認識だらけの 30分程度のテキスト(およそ 30キロバイト)から、かなり品質の良いテキストに変換することができました。
計算上は、現在の o1 の利用制限を考慮したとしても、1週間あたり 8時間程度(50 ÷ 3 × 30 ÷ 60)のテープ起こしが 可能となります。8時間のテープ起こしに必要な費用は、Whisper の費用(400円強)と、ほかに ChatGPT Plus の費用(月額 3,300円程度)です。普段から ChatGPT Plus を利用されている方であれば、かなりリーズナブルと言えるのではないでしょうか。
以下に、今回 o1 モデルに与えた指示を示しますので、御参考ください。
今回 o1 に与えた指示(プロンプト)
- まずは、以下の資料を確認してください。
# 資料 1
(お客様提供の資料なので略)
# 資料 2
(お客様提供の資料なので略) - 次に、Whisper で文字起こししたテキストを示します。誤認識が多いです。誤認識と思われる用語と、本来の用語(本来、こういう発言だっただろうという用語)の対照リストを作ってください。
# 例
お改まり -> お集まり
豪雨内容 -> 業務内容
設営 -> 説明
# Whisier で文字起こししたテキスト(誤認識が多い)
[000:00] 皆様、本日はお改まり頂きましてありがとうございます。
(お客様提供の資料なので以下略) - それを元に、先ほどのテキストを1行ずつ全て修正してください。以下のように、末尾に [] で囲って修正点を明記してください。
# 例
[000:00] 皆様、本日はお集まり頂きましてありがとうございます。[お改まり -> お集まり]
もしかして、ちゃんとした説明資料も作れる!?
ここまで来ると、期待が膨らむ…というよりは、説明資料も作らせてみよう、という欲望が出てきます。o1 モデルに頼んでみましょう。
先ほどの o1 セッションに続けても良かったのですが、新しいセッション(スレッド)を開きました。そのため、再度、背景から説明し直します。
私: これから、ある会議の文字起こし(テープ起こし)から、その議事内容の説明資料を作りたいと思います。以下に、会議の開催通知、議事日程(プログラム)、文字起こしの際に誤りを修正した用語一覧、OpenAI Whisper によるトランスクリプト(誤字修正済み)を示します。 トランスクリプトは、議事日程のうち「(略)」のものです。 依頼内容ですが、まず最初に、作成する「説明資料」の章立て(セクション構成)を提案してください。
(略)
するとどうでしょう。極めて綿密な章立てをしてくれるではないでしょうか。(上述の理由により、ここで示すことができないのが残念です。)
続けて依頼します。(o1 モデルは現在、週あたり 50メッセージという利用制限があるので、慎重にチャットします。)
私: 良いと思います。それでは、実際に説明資料を作成してください。なお、各セクションの内容が短くなりすぎる場合には、必要ならばセクション構成はもう少し粗くても良いと思います。その際は、章立てを変更して良いです。
感激(別名、唖然)の幕引き
得られた説明資料は、私の想像を超えるものでした。もしかすると、専門分野のお客様が見たら「まだまだですね。ChatGPT の妄想が多いですね」と言われそうですが、門外漢の私の目には十分な内容で、議事の内容が理解できるほどの品質に感じられました。
冒頭で示したように、誤変換だらけの文字起こしテキストから生成させた説明資料(失敗作)に比べると、格段の向上ではないかと思います。
今日はここまでといたします。
お問い合わせはお気軽に!
繰り返しになりますが、今回は、お客様からの依頼に基づく内容なので詳細な結果を示すことができず、申し訳ございません。しかし、同様の御依頼がありましたら対応可能でございますので、お気軽にお問い合わせください。あくまでも機械学習(AI)による生成ですので、全てのお客様に御満足頂けるかどうかは分かりませんが、喜んで作業させて頂きます。