whisper.cpp(Core ML版)、Remotion、機械音声でゆっくり動画風のものをを作りたい
ほぼ上記の記事で事足りるのですが、いくつか補足します。
とありますが、うまく行きませんでした。ANECompilerServiceがしばらく動作していて、あまりに長いので得て起きたら終わっていました。largeモデルで12時間くらいかかったようです。
モデルは
からダウンロードできます。ダウンロードしたモデルを指定して
./main -m models/ggml-base.bin -l ja -f ファイル名
whisper_init_from_file_no_state: loading model from 'models/ggml-base.bin'
whisper_model_load: loading model
whisper_model_load: n_vocab = 51865
whisper_model_load: n_audio_ctx = 1500
whisper_model_load: n_audio_state = 512
whisper_model_load: n_audio_head = 8
whisper_model_load: n_audio_layer = 6
whisper_model_load: n_text_ctx = 448
whisper_model_load: n_text_state = 512
whisper_model_load: n_text_head = 8
whisper_model_load: n_text_layer = 6
whisper_model_load: n_mels = 80
whisper_model_load: ftype = 1
whisper_model_load: type = 2
whisper_model_load: mem required = 310.00 MB (+ 6.00 MB per decoder)
whisper_model_load: adding 1608 extra tokens
whisper_model_load: model ctx = 140.60 MB
whisper_model_load: model size = 140.54 MB
whisper_init_state: kv self size = 5.25 MB
whisper_init_state: kv cross size = 17.58 MB
whisper_init_state: loading Core ML model from 'models/ggml-base-encoder.mlmodelc'
whisper_init_state: first run on a device may take a while ...
whisper_init_state: Core ML model loaded
system_info: n_threads = 4 / 8 | AVX = 0 | AVX2 = 0 | AVX512 = 0 | FMA = 0 | NEON = 1 | ARM_FMA = 1 | F16C = 0 | FP16_VA = 1 | WASM_SIMD = 0 | BLAS = 1 | SSE3 = 0 | VSX = 0 | COREML = 1 |
main: processing 'ファイル名' (176222891 samples, 11013.9 sec), 4 threads, 1 processors, lang = ja, task = transcribe, timestamps = 1 ...
[00:00:00.000 --> 00:00:02.000] ねー
[00:00:02.000 --> 00:00:17.880] 今日のご飯はカレーだったよ
[00:00:17.880 --> 00:00:23.200] やっぱりカレーだ
実行したらうまく動いたようです。ただ初回実行時にANECompilerServiceが動作し、スクリプトと同じことをするようで、
whisper_init_state: loading Core ML model from 'models/ggml-base-encoder.mlmodelc'
と出ていることから結局変換はされているようです。largeモデルはまた12時間かかるのかも知れません。
あとはChatGPTに
と指示したらオプション処理やエラー処理、usageの表示まできちんと書いてくれました。
#!/bin/bash
if [ $# -lt 3 ]; then
echo "Usage: $0 <input file> <model: base|large> <language: ja|en|...>"
exit 1
fi
input_file="$1"
model="$2"
language="$3"
if [ "$model" != "base" ] && [ "$model" != "large" ]; then
echo "Invalid model. Choose 'base' or 'large'."
exit 1
fi
random_name=$(mktemp -u tmp_audio_XXXXX).wav
ffmpeg -i "$input_file" -ar 16000 -ac 1 -c:a pcm_s16le "$random_name"
./main -m "models/ggml-$model.bin" -l "$language" -f "$random_name"
rm "$random_name"
このスクリプトを、例えばconvert_and_run.shという名前で保存し、実行権限を与えて実行できます。
chmod +x convert_and_run.sh
./convert_and_run.sh <input file> <model: base|large> <language: ja|en|...>
個人的なプランとして、英語のゆっくり動画みたいなものを作ってみようかと思っています。
日本語と英語では、文化の違いや好みを除けばおそらく英語のほうが20倍くらいは視聴されます。ゆっくり動画方式ならば別に英語の発音が汚くても問題ありません。ただしテーマは普通の英語話者でも作れるものを作っても仕方ないので、日本人ならではの何かを英語で発信することが重要かと考えています。
概要
原稿を日本語で書く
ChatGPTに適切なプロンプトを入れて英語の台本にする
Text-to-speechで流暢な英語の音声にする
Whisperでsrt形式に変換する
Remotionで字幕と音声を合成する
必要な素材を配置する
RemotionはReactのフレームワークでコーディングで動画を作れます。全自動で動画を作るよりも字幕だけSRTから自動で生成して、残りは動画編集ソフトで素材を配置するのがちょうどよいバランスだと思います。
機械音声はやや不自然かも知れませんが、滑舌はいいので、特にアナウンサーでも声優でもない人間が喋るよりはきれいにテキストに戻すことができます。テキストの原稿を一度音声にしてまたテキストに戻すのは無駄のようですが、字幕にする場合は音声に同期して表示することが重要ですから意味のあるステップだと思います。ただし機械音声が字幕ファイルを生成してくれるならこのステップは不要です。
Whisperの出力はタイムコードが付加されているので、音声と字幕のタイミングを合わせることができます。Remotionはコードで制御するのでSRTのような構造化された入力を一発で字幕に変換するのは得意です。Whiperは適切な長さで切ってくれる傾向にあるので、字幕としてちょうどいい長さの文章をタイムコード付きで得ることができます。