目的
Cloudflare Workers AI で Whisper Large V3 Turbo モデルが Beta
になっています。
whisper-large-v3-turbo
は whisper-large-v3
の finetuned
モデルで、多少の品質を犠牲にしながらも高速に動くモデルです。
Whisper large-v3-turbo is a finetuned version of a pruned Whisper large-v3. In other words, it's the exact same model, except that the number of decoding layers have reduced from 32 to 4. As a result, the model is way faster, at the expense of a minor quality degradation.
例えば、以下のような電話やミーティングの audio
ファイルから WebVTT
形式の字幕ファイルを出力できます。
その後、場合によっては文字起こしデータから、要約や次のアクションの提示を事後処理として、さらに他の AI モデルを使って実行させるようなフローを実現できます。
参考: audio
ファイルの抽出
ミーティング録画から audio
ファイルを抽出するには以下の ffmpeg
コマンドを使います。
ffmpeg -i ./cf-video.mp4 -vn ./cf-video.mp3
Workers AI デプロイ
以下の Workers コードを使用します。
以下のコマンドでデプロイできます。
export URL='https://github.com/kyouheicf/hello-whisper.git'
git clone $URL && cd $(basename $_ .git)
npx wrangler deploy
使い方
以下のように URL の path
パラメータとして audio
ファイルの URL を記述すると、字幕データが返ってきます。
curl https://hello-whisper.xxx.workers.dev/https://example.com/cf-video.mp3 | jq
{
"input": {
"audio": []
},
"response": {
"transcription_info": {
"language": "ja",
"language_probability": 1,
"duration": 30.046625,
"duration_after_vad": 30.046625
},
"segments": [
{
"start": 2.539999999999999,
"end": 5.66,
"text": "ミノシロ金3億円?そんな大金あるわけないだろ!",
"temperature": 0,
"avg_logprob": -0.2854399464649861,
"compression_ratio": 1.62,
"no_speech_prob": 0,
"words": [
{
"start": 2.539999999999999,
"end": 2.82,
"word": "ミ"
},
{
"start": 2.82,
"end": 2.96,
"word": "ノ"
},
...
{
"start": 5.54,
"end": 5.66,
"word": "ろ!"
}
],
"word_count": 1
},
...
{
"start": 25.62,
"end": 29.46,
"text": "サイバーセキュリティが、あなたの安心を守る。クラウドフレア。",
"temperature": 0,
"avg_logprob": -0.2854399464649861,
"compression_ratio": 1.62,
"no_speech_prob": 0,
"words": [
{
"start": 25.62,
"end": 25.9,
"word": "サ"
},
...
{
"start": 29.34,
"end": 29.46,
"word": "ア。"
}
],
"word_count": 1
}
],
"vtt": "WEBVTT\n\n00:02.540 --> 00:02.820\nミ\n\n00:02.820 --> 00:02.960\nノ\n\n00:02.960 --> 00:03.080\nシ\n\n00:03.080 --> 00:03.160\nロ\n\n00:03.160 --> 00:03.300\n金\n\n00:03.300 --> 00:03.520\n3\n\n00:03.520 --> 00:03.740\n億\n\n00:03.740 --> 00:03.880\n円?\n\n00:04.400 --> 00:04.680\nそんな\n\n00:04.680 --> 00:04.820\n大\n\n00:04.820 --> 00:04.960\n金\n\n00:04.960 --> 00:05.140\nある\n\n00:05.140 --> 00:05.220\nわ\n\n00:05.220 --> 00:05.320\nけ\n\n00:05.320 --> 00:05.400\nない\n\n00:05.400 --> 00:05.540\nだ\n\n00:05.540 --> 00:05.660\nろ!\n\n00:05.840 --> 00:06.000\nえっ?\n\n00:06.640 --> 00:06.880\nも\n\n00:06.880 --> 00:07.060\nしか\n\n00:07.060 --> 00:07.300\nして。\n\n00:07.580 --> 00:07.860\nサ\n\n00:07.860 --> 00:07.940\nイ\n\n00:07.940 --> 00:08.040\nバ\n\n00:08.040 --> 00:08.120\nー\n\n00:08.120 --> 00:08.280\n攻\n\n00:08.280 --> 00:08.480\n撃?\n\n00:08.880 --> 00:09.160\nまず\n\n00:09.160 --> 00:09.300\nい\n\n00:09.300 --> 00:09.420\nな、\n\n00:09.500 --> 00:09.720\nそれ。\n\n00:10.140 --> 00:10.300\nガ\n\n00:10.300 --> 00:10.380\nン\n\n00:10.380 --> 00:10.460\nサ\n\n00:10.460 --> 00:10.560\nム\n\n00:10.560 --> 00:10.680\nウ\n\n00:10.680 --> 00:10.700\nェ\n\n00:10.700 --> 00:10.700\nア\n\n00:10.700 --> 00:10.880\n攻\n\n00:10.880 --> 00:11.020\n撃\n\n00:11.020 --> 00:11.160\nさ\n\n00:11.160 --> 00:11.300\nれた。\n\n00:11.620 --> 00:11.900\n本当\n\n00:11.900 --> 00:12.080\nに?\n\n00:12.180 --> 00:12.340\nや\n\n00:12.340 --> 00:12.420\nば\n\n00:12.420 --> 00:12.520\nく\n\n00:12.520 --> 00:12.640\nない?\n\n00:12.780 --> 00:12.940\nデ\n\n00:12.940 --> 00:13.040\nー\n\n00:13.040 --> 00:13.120\nタ、\n\n00:13.360 --> 00:13.440\nロ\n\n00:13.440 --> 00:13.540\nック\n\n00:13.540 --> 00:13.680\nさ\n\n00:13.680 --> 00:13.740\nれ\n\n00:13.740 --> 00:13.860\nちゃ\n\n00:13.860 --> 00:13.960\nう。\n\n00:14.000 --> 00:14.140\n今、\n\n00:14.280 --> 00:14.300\n来\n\n00:14.300 --> 00:14.420\nて\n\n00:14.420 --> 00:14.480\nる\n\n00:14.480 --> 00:14.580\nんだ\n\n00:14.580 --> 00:14.640\nよ、\n\n00:14.720 --> 00:14.780\nもう\n\n00:14.780 --> 00:14.960\n俺。\n\n00:16.740 --> 00:17.020\n大丈夫?\n\n00:17.680 --> 00:17.880\nん?\n\n00:19.400 --> 00:19.540\nん?\n\n00:20.700 --> 00:20.980\nああ、\n\n00:20.980 --> 00:21.260\n大丈夫。\n\n00:21.640 --> 00:21.840\nク\n\n00:21.840 --> 00:21.900\nラ\n\n00:21.900 --> 00:22.000\nウ\n\n00:22.000 --> 00:22.060\nド\n\n00:22.060 --> 00:22.200\nフ\n\n00:22.200 --> 00:22.240\nレ\n\n00:22.240 --> 00:22.280\nア\n\n00:22.280 --> 00:22.420\nが\n\n00:22.420 --> 00:22.660\n守\n\n00:22.660 --> 00:22.800\nって\n\n00:22.800 --> 00:22.900\nく\n\n00:22.900 --> 00:23.000\nれて\n\n00:23.000 --> 00:23.140\nる\n\n00:23.140 --> 00:23.320\nから。\n\n00:23.500 --> 00:23.700\n正\n\n00:23.700 --> 00:24.000\n解\n\n00:24.000 --> 00:24.140\nだ\n\n00:24.140 --> 00:24.360\nよ!\n\n00:24.680 --> 00:24.880\n一\n\n00:24.880 --> 00:24.980\n緒\n\n00:24.980 --> 00:25.080\nに\n\n00:25.080 --> 00:25.180\n見\n\n00:25.180 --> 00:25.260\nる?\n\n00:25.620 --> 00:25.900\nサ\n\n00:25.900 --> 00:25.960\nイ\n\n00:25.960 --> 00:26.040\nバ\n\n00:26.040 --> 00:26.120\nー\n\n00:26.120 --> 00:26.220\nセ\n\n00:26.220 --> 00:26.280\nキ\n\n00:26.280 --> 00:26.360\nュ\n\n00:26.360 --> 00:26.380\nリ\n\n00:26.380 --> 00:26.480\nテ\n\n00:26.480 --> 00:26.500\nィ\n\n00:26.500 --> 00:26.680\nが、\n\n00:26.800 --> 00:27.180\nあ\n\n00:27.180 --> 00:27.300\nなた\n\n00:27.300 --> 00:27.440\nの\n\n00:27.440 --> 00:27.580\n安\n\n00:27.580 --> 00:27.800\n心\n\n00:27.800 --> 00:27.920\nを\n\n00:27.920 --> 00:28.120\n守\n\n00:28.120 --> 00:28.300\nる。\n\n00:28.660 --> 00:28.940\nク\n\n00:28.940 --> 00:28.980\nラ\n\n00:28.980 --> 00:29.060\nウ\n\n00:29.060 --> 00:29.120\nド\n\n00:29.120 --> 00:29.260\nフ\n\n00:29.260 --> 00:29.340\nレ\n\n00:29.340 --> 00:29.460\nア。\n\n",
"text": "ミノシロ金3億円?そんな大金あるわけないだろ! えっ?もしかして。 サイバー攻撃? まずいな、それ。 ガンサムウェア攻撃された。 本当に?やばくない? データ、ロックされちゃう。 今、来てるんだよ、もう俺。 大丈夫? ん? ん? ああ、大丈夫。クラウドフレアが守ってくれてるから。 正解だよ! 一緒に見る? サイバーセキュリティが、あなたの安心を守る。クラウドフレア。",
"word_count": 15,
"segment_vtt": "WEBVTT\n\n00:00:02.540 --> 00:00:05.660\nミノシロ金3億円?そんな大金あるわけないだろ!\n\n00:00:05.840 --> 00:00:07.300\nえっ?もしかして。\n\n00:00:07.580 --> 00:00:08.480\nサイバー攻撃?\n\n00:00:08.880 --> 00:00:09.720\nまずいな、それ。\n\n00:00:10.140 --> 00:00:11.300\nガンサムウェア攻撃された。\n\n00:00:11.620 --> 00:00:12.640\n本当に?やばくない?\n\n00:00:12.780 --> 00:00:13.960\nデータ、ロックされちゃう。\n\n00:00:14.000 --> 00:00:14.960\n今、来てるんだよ、もう俺。\n\n00:00:16.740 --> 00:00:17.020\n大丈夫?\n\n00:00:17.680 --> 00:00:17.880\nん?\n\n00:00:19.400 --> 00:00:19.540\nん?\n\n00:00:20.700 --> 00:00:23.320\nああ、大丈夫。クラウドフレアが守ってくれてるから。\n\n00:00:23.500 --> 00:00:24.360\n正解だよ!\n\n00:00:24.680 --> 00:00:25.260\n一緒に見る?\n\n00:00:25.620 --> 00:00:29.460\nサイバーセキュリティが、あなたの安心を守る。クラウドフレア。\n\n"
}
}
WebVTT
形式の字幕ファイル保存
上記の vtt
フィールドを使うと、日本語の場合、1文字ずつ分かれた出力となってしまい、字幕ファイルとしての使い勝手が悪いです。
そこで segments.text
を変換した segment_vtt
フィールドとして WebVTT
形式の字幕ファイルを出力するようにアレンジしています。
字幕ファイルとして保存する場合は、以下のコマンドを実行します。
curl https://hello-whisper.xxx.workers.dev/https://example.com/cf-video.mp3 \
| jq -r .response.segment_vtt > cf-video.vtt
WEBVTT
00:00:02.540 --> 00:00:05.660
ミノシロ金3億円?そんな大金あるわけないだろ!
00:00:05.840 --> 00:00:07.300
えっ?もしかして。
00:00:07.580 --> 00:00:08.480
サイバー攻撃?
00:00:08.880 --> 00:00:09.720
まずいな、それ。
00:00:10.140 --> 00:00:11.300
ガンサムウェア攻撃された。
00:00:11.620 --> 00:00:12.640
本当に?やばくない?
00:00:12.780 --> 00:00:13.960
データ、ロックされちゃう。
00:00:14.000 --> 00:00:14.960
今、来てるんだよ、もう俺。
00:00:16.740 --> 00:00:17.020
大丈夫?
00:00:17.680 --> 00:00:17.880
ん?
00:00:19.400 --> 00:00:19.540
ん?
00:00:20.700 --> 00:00:23.320
ああ、大丈夫。クラウドフレアが守ってくれてるから。
00:00:23.500 --> 00:00:24.360
正解だよ!
00:00:24.680 --> 00:00:25.260
一緒に見る?
00:00:25.620 --> 00:00:29.460
サイバーセキュリティが、あなたの安心を守る。クラウドフレア。
字幕付きの動画や音声として再生するには、以下の記事にあるように VLC media player
を使った方法があります。
Content-Length 7.5 MB 制限を回避する
いろいろな audio
ファイルを調査する中で、以下のエラーが出ることがありました。
Error: 3006: Request is too large
Content-Length
レスポンスヘッダが 75000 bytes
を超えると、エラーが出るような挙動を確認しました。
audio
ファイルがサイズ超過している場合、以下のようなコマンドでビットレートを調整することでサイズを縮小する、もしくはファイルを分割することを検討してください。
# ビットレートを調整
ffmpeg -i cf-pitch.mp3 -b:a 32k cf-pitch-32k.mp3
# ffmpeg -i cf-pitch.mp3 -b:a 48k cf-pitch-48k.mp3
# ffmpeg -i cf-pitch.mp3 -b:a 64k cf-pitch-64k.mp3
# ffmpeg -i cf-pitch.mp3 -b:a 72k cf-pitch-72k.mp3
# ffmpeg -i cf-pitch.mp3 -b:a 96k cf-pitch-96k.mp3
# ffmpeg -i cf-pitch.mp3 -b:a 112k cf-pitch-112k.mp3
# ffmpeg -i cf-pitch.mp3 -b:a 128k cf-pitch-128k.mp3
# ffmpeg -i cf-pitch.mp3 -b:a 160k cf-pitch-160k.mp3
# ffmpeg -i cf-pitch.mp3 -b:a 192k cf-pitch-192k.mp3
# ffmpeg -i cf-pitch.mp3 -b:a 256k cf-pitch-256k.mp3
# ffmpeg -i cf-pitch.mp3 -b:a 320k cf-pitch-320k.mp3
# 圧縮率の高いファイル形式に変更
ffmpeg -i audio.mp3 -vn -map_metadata -1 -ac 1 -c:a libopus -b:a 12k -application voip audio.ogg
# 時間を 50 分で切る
ffmpeg -i audio.mp3 -b:a 16k -t 00:50:00 audio-16k-50m.mp3
タイムアウトによる推論時間制限を回避する
Whisper による推論時間が約 2 分を超えると、以下のエラーが出ることがありました。
Error: 3007: Request timeout
audio
ファイルの長さで言うと、約 50 分になります。
この場合、Cloudflare Workers AI による製品改善を期待する、もしくはファイルを分割することを検討してください。
ファイル分割に関して、segment
の途中にならないような文脈をとらえた chunking
についてはいくつか事前処理に使えるツールがあるようです。
initial_prompt
による日本語認識改善
プロンプト(initial_prompt
パラメータ)を使用すると、Whisper が生成するトランスクリプトの品質を向上させられる可能性があります。
ただし、改善できる度合いはある程度限られていると考えたほうが良さそうです。
プロンプト内では、専門用語を羅列する単語帳のような使い方が紹介されています。
You can use a prompt to improve the quality of the transcripts generated by the Whisper API. The model tries to match the style of the prompt, so it's more likely to use capitalization and punctuation if the prompt does too. However, the current prompting system is more limited than our other language models and provides limited control over the generated audio.
...
Because it wasn't trained with instruction-following techniques, Whisper operates more like a base GPT model. Keep in mind that Whisper only considers the first 224 tokens of the prompt.
Whisperのコンテキストのサイズは448です。これは、入力用と出力用のトークンの合計数であり、Whisperの実装では入力用には半分の224トークンまでに制約されています。そのため、未知語の数が多くなってきた場合は、prompt以外の方法を検討する必要があります。
例えば、日本語の文章をうまく理解させるために、「やさしい日本語」にあるような文章を initial_prompt
パラメータに入れることで多少の日本語認識改善が見られました。
日本語の文字起こしの場合、initial_prompt
パラメータには英単語等が含まれていない方が認識率が高かったです。
+ // やさしい日本語のサンプル文章
+ initial_prompt: '1 日の PM 2.5 の量が、 70 μg / m^2 を超えたときは、外に出ることをできるだけ少なくしましょう。そして、外での長い時間の激しい運動はできるだけ少なくしましょう。病気(呼吸器や循環器)の人、小さな子ども、お年寄りの方は、体調に気をつけましょう。',
まとめ
Cloudflare Workers AI では、すぐに AI を使い始めることができます。
これも Cloudflare の拠点に GPU が配備され、最寄りの拠点で推論をおこなえるインフラが整っているからです。
Workers の使いやすさに加えて、さまざまなコンポーネントを Bindings
で追加するだけで連携できる点も魅力です。
@cf/openai/whisper-large-v3-turbo
で日本語の文字起こしもそれなりに使えることがわかったので、事後処理に他の AI モデルを組み合わせる等、アイデアが膨らむところです。
これからも Cloudflare Workers AI の成長を見守っていきましょう。