はじめに
こんにちは、GlobeeでCTOをやっています上赤です。
Globee Advent Calendar16日目の記事です。
今回はWhisperXを用いて、映画字幕へのタイムスタンプ付与を行った際の記録を残します。
発端
弊社が作っているサービスabceedでは、映画を使った英語学習を行うことが出来ます。
学習機能の中にはフレーズ単位でのシーク/リピート機能があり、これを実現するために、各フレーズの開始秒数/終了秒数を0.01秒単位で正確に付与する必要があります。
秒数付与は当初弊社オリジナルコンテンツチームが手動で行っていたのですが、作業効率化のため、エンジニアチーム側で何かサポートが出来ないかという話になってきました。
ちなみに、他にも映画字幕への語注作成についても記事を書いています。良かったら合わせてご覧ください。
こちら
問題の定義
入力: 映画の一部分のオーディオ(任意の形式)と字幕リスト
出力: 字幕リスト内の各文に対する開始時間
が定義です。
オーディオデータを使って下記のような字幕データに開始秒数/終了秒数を付与するというイメージですね。
また、映画は背景音や話し言葉の速度が含まれるため、声を検出するのが他のメディアより困難です。
それにより、単語を全て検出するのは難しいので、ある程度曖昧なマッチングを行う必要があります。
やったこと
データ変換
AIによる音声検出アルゴリズムは16kHz 16ビットの単一チャネルwavファイルで訓練されているため、変換が必要です。.mp3ファイルの場合はffmpeg、.wavファイルの場合はsoxを使用します。
ffmpeg -i "input.mp3" -vn -ac 1 -ar 16000 -acodec pcm_s16le -f wav 'output.wav'
sox "input.wav" -b 16 -r 16000 -c 1 "output.wav"
データ分割
同様に、AIアルゴリズムが30秒以下のセグメントしか処理できないため、事前に分割が必要です。会話が中断しないように、会話がないと思われるポイントでのみ、webrtcvadライブラリを用いて分割を行います。
WhisperXによる文字起こしとタイムスタンプ取得
文字起こしとタイムスタンプ取得にはWhisperXを利用します。
WhisperXは、METAのwav2vec2とOpenAIのWhisperの2つの音声認識技術が組み合わされており、正確な文字起こしとタイムスタンプの両方を得ることができます。
wav2vec2とWhisperには様々な訓練済みモデルがありますが、今回は
large-v2
+ facebook/wav2vec2-large-960h-lv60-self
の組み合わせで行いました。
単語レベルのマッピング
ここが一番面倒なところです。上で取得した単語単位のタイムスタンプを元に、字幕各行の開始秒数/終了秒数を作成します。
単語リストをスキャンし、字幕の行と一致する文字列のシーケンスを探す、というのが最もシンプルですが、それだけでは精度が低かったので、複数のロジックを組み合わせて結果を生成し、問題有りそうな箇所を修正していく、というような泥臭い方法で実現しました。
ロジックの中に、ChatGPTによる判定を挟んでみると精度が上がったのは面白かったです。
結果
最初はタイムスタンプ付与の精度が低かったのですが、改善を続けた結果、オリジナルコンテンツチームの作業時間を数十%削減することが出来ました!
自動付与はやはり完璧ではないので、自動付与されたタイムスタンプは初期値として使うだけにとどめ、人の耳で聞いて0.01秒単位で最終調整を行う必要があります。
将来的には自動付与されたタイムスタンプがほぼ修正の必要なくなるようにできれば良いなと思っています。引き続き改善中です。
まとめ
WhisperXを使うことで、映画字幕へのタイムスタンプ付与を自動化し、作業効率を改善することが出来ました!
今後も様々な領域で、業務改善をしていけたらと思います。
弊社では、現在アプリ/Web/サーバーエンジニア/PjMなど、ほぼすべての開発ポジションを募集中です!
ちょっとでも興味持った人は以下からカジュアル面談をご検討ください。色々お話します!
採用ページ