見出し画像

ChatGPTとペアプログラミングしながら、長時間の音声録音を、実務レベルで精度高く文字起こしする


OpenAIのWhisper APIsGoogle Colab、Pythonを活用して、長時間の動画や音源データの自動文字起こしの精度を上げる試みを続けています。(↓ これまでの記事)

その後、チーム内でプレゼンをしたり、周囲に宣伝して実績を増やしてみました。15件近く自動文字起こしを業務活用してみたところ、チーム内の負担が大幅に減り、業務効率を改善することができました。

それぞれニーズや課題が異なったので、共通点を機能に反映させることで更に精度があがりました。

その際、プログラム自体をAI生成しようと思い、ChatGPT3.5だけで開発する事にもチャレンジしてみました。開発したのは、Wisperだけではカバーしきれない専門用語の表記ゆれや、生成の精度が下がりがちな単語などの補完機能です。

Whisperで生成された書き起こしを、ChatGPTのAPIで整形して失敗する

前回の記事に書いた通り、Whisperでtranscribe関数をコールする際に、パラメーターにinitial_promptというヒントを与えることで、音声文字起こしが劇的に精密になりました。トーク内容を解釈しやすいように、適切な単語を羅列することで、精度に大きな差が出ると感じました。

その一方で、用語や単語の誤読や表記揺れの修正は手作業が続きました。これはWhisperの精度の問題というよりも、話者の話し方や滑舌、録音環境に大きく左右されます。いずれにせよ、人の手による置換が手間になっていました。

そこで、Whisperで生成された書き起こしテキストファイルに対して、ChatGPTで整形する処理を入れてみることにしました。

荒業ではありますが、音声文字起こしされたテキストファイルを読み込み、毎行ChatGPTのAPIをコールして、一行単位で校正するようにしました。

数行レベルではきれいに校正されるのですが、400行を超えたあたりでStackOverFlowが発生したり、Token数超過エラーが起きるようになりました。

APIError: Bad gateway.
InvalidRequestError: This model's maximum context length is 4097 tokens. However, your messages resulted in 10208 tokens. Please reduce the length of the messages.

Api error - Bad Gateway Error Code 502

StackOverFlowに関しては、更に荒業のようにPythonのsleep関数で数秒停止させると、ファイルの末尾まで整形処理が続きましたが、完了まで1時間以上かかるなどデメリットが大きく。

また、Token数超過エラーに関しては、毎回のリクエストでプロンプト文字数を200文字などかなり制限しているのですが、それでも全体の整形量が多くなると発生してしまいました。

そしてこれは気のせいかもしれませんが、午後から夕方にかけてGoogle Colabが重くなるため、パフォーマンスが著しく劣化する事が連日続きました。割り当てられるGPUの性能にもよると思いますが、自力での解決は難しく、この方法はあきらめました。

そこで、発想を少し変えて、人の手で置換する場合は、置換した記録を蓄積して、生成後にフィルターをかける事にしました。

ここからは、PythonでChatGPTを使って自動生成するようにしました。

ChatGPT × プログラミングで自動化のガイドライン

せっかくなので、プログラム自体も生成AIで自動化することにしました。基本的には、以下のガイドラインを自分なりのルールとして設けました。

  • ChatGPT3.5にプログラムを書いてもらい、自分はプログラムを書かない。

  • Google Colabを使用して、実行環境はColab内で完結させる。

  • プログラムの実行はCUIで、他人が使わない前提とした (まずは自分が楽をする目的)

これらの手順に従って試したところ、ペアプログラミング的な開発が楽しすぎて、思わず時間を忘れて開発に没頭しました。そして、ChatGPTとペアプログラミングする事の生産性の高さを実感できました。

WhisperのAPIを使って開発していた時は、サンプルコードの部分的なカスタマイズや、複数のライブラリを組み合わせて開発していました。

今回は新規で作成するので、ChatGPTに例えば「Pythonでユーザーからの入力を受け付けるプログラムを書いてください」というレベルから始めました。

Whisperの音声文字起こしを補完する機能の追加

結果的に、下記のような仕様のプログラムができあがりました。トータルで500行程度です。

  • YoutubeはURL、動画はMP4からMP3の音声ファイルを抽出

  • Whisperで音声文字起こしを行いテキストファイルに書き出す

  • (ここからChatGPT) データベースに格納している、過去の「誤字脱字正誤表テーブル」をロードし、音声文字起こしファイルに対して、自動で一括置換

  • 過去の「誤字脱字、専門用語の修正」を反映した内容に対して、追加で修正があれば、入力フォームから置換を続ける

  • 手入力の置換をデータベースに再格納

  • オプションで、置換したい単語が多い場合はCSVでとりこむ機能も追加

という感じです。これにより、人の手による置換をすればするほど、自動置換の精度が高くなります。Whisper自体のバージョンアップも今後期待できるので、長期的な運用をする事でその効果が望めると思われます。

運用してみると、自動生成 & 自動校正 & 手作業校正をする度に精度が上がっていくので、想像以上に快適でした。10件ほどやると、校正の時間が1/4に短縮されていることに気づきました。

また、単語集ができるので、これは学習データとしても利用できるのではという気になりました。SRT形式でタイムコードも記録できるので、間違えた用語と正しい用語の対比にも活用できると思います。

汎用的なAI生成文字起こしツールみたいのが今後も出てくると思いますが、手軽に自分たちの仕事やチームに特化した機能を実現できたのは良かったなと思いました。

悩まないChatGPTとのペアプログラミングする楽しさ

ChatGPTはProを利用していますが、今回は3.5を使いました。ChatGPT4でなくても性能的に十分でした。

ChatGPTが提案するプログラムをただコピペして実行するのではなく、内容をよく読んで、不明な箇所は、「どういう意図で書いたのか?何をしているのか?」を質問するように心掛けました。意図した動作をしない場合は、現象やエラーメッセージを貼り付けて、一緒に考えるようにしました。

ここで驚いたのは、AIは悩む時間がないということです。ペアプログラミングをしていると相手が悩む、自分も悩むことがあります。どうしようか?と考えたりする時間が多いですが、AIはその悩む時間が一切なく、合っているか間違っているかは別として、別の解をノーウェイトで提案してきます。

秒でTry & Errorを繰り返すことができるので、間違っていたとしても、その手数の多さから、正解に近づく時間が圧倒的に短く感じました。ゲームで例えるならステージ間のロード時間がなくなったような感じです。

また、仕様の変更にも文句を言わずに、即座に対応してくれるのも頼もしかったです。最初はCSVに書き出してデータを蓄積していましたが、CRUDが必要だと思い、途中からSQLiteに変更しました。その際も、現在のCSVの仕様から、SQLiteに変える仕様にするコードを、プログラム全体の改変ベースで提示してくれました。

また、置換テーブルに重複して用語を登録した場合の対応も、SQLのDistinct文など、泥臭い構文で集約して書き直してくれます。「SQLをそう書けば良いんだけど、クエリと処理書くのめんどうだなー」という処理を、瞬時に提案してくれるので、とても助かります。(↓SQL文は簡略化しています)

# 重複項目を削除したレコードを取得
cursor.execute("SELECT DISTINCT input_1, input_2 FROM replacements")
distinct_records = cursor.fetchall()

自分はコードは書かず、仕様も細かくプロンプトに書かない

ChatGPTに依頼したプロンプトは数行程度のかなり抽象的な内容にしていました。ネットで見る事例の中でたまに、役割や指示を、かなり具体的に長文で依頼する例も見かけますが、細かい仕様を自然言語でプロンプトに書くなら、自分でプログラムを書いたほうが早いと思い、そのアプローチはとりませんでした。

例えば「レコードの中で、2列目の値が重複した行がある場合は、最新行のみ残して、重複を削除したい」みたいな、かなりざっくりとした仕様を与え、提案されたプログラムを一緒にレビューする感じにしました。

「抽象的な仕様は伝えるけど、実装の裁量権は任せます。成果物は一緒にレビューしましょう」みたいな感覚は、若手の新人と一緒にソフトウェア開発しているような感じがしました。

リファクタリングは任せなかった

逆に、ChatGPTが提案してくるリファクタリングしたコードは、自分が理解できなくなることや、読むコストがかかるので、採用しませんでした。ChatGPTが提案するリファクタリング案は、素晴らしく簡潔な関数で、驚くばかりです。

Pythonはそもそも書き方が属人化しない言語なので、その提案を受けるのがベストだと思いますが、自分の中での可読性を重視しました。と言っても、ここではまだ悩んでいます。

逆に、変数や定数の整理が必要で、無駄に参照している変数が多かったため、自分で消して検証を行うなどは、ChatGPTに任せず自分でプログラミングしました。

プログラミング的な脳の疲労

コードはほとんど書いていませんが、集中してプログラムを書いた感覚になりました。何より、プログラミングしている時の楽しさと同じ楽しさを感じて、めちゃくちゃ楽しかったです。AIに限らず「ペアプログラミングは良いぞ!」という上級者の方の声があるのは納得です。

ペアプログラミングは1つの仕事にプログラマを2名あてる関係で、工数や生産性の点で課題がありましたが、ChatGPTなどを使うことでその課題が解決すると思います。

今後は、Whisperのsmallやlargeのように、プログラムを生成する際の、スキルレベルが異なるものが出てくると、よりプログラマにとって学びが深く面白いのでは?と思いました。

今後の音声文字起こし

今回は、「音声文字起こし」の後に、人の手による置換のオペレーションを蓄積して、音声文字起こしを補完する機能について説明しました。このため、生成AIとは関係がありません。

今後は、過去に書いた記事のタイトルや見出しを学習し、PVが高かった記事を参照しながら、見出しの提案をする「アーカイブ情報をベースにした提案」などに取り組んでいきたいと思います。

この記事が参加している募集

ライターの仕事

AIとやってみた

この記事が気に入ったらサポートをしてみませんか?