はじめに
最近動画を編集する際に字幕を付けるのが大変に感じている
編集ソフトはShotcutを使っていてSpeech to Textという機能で自動字幕を付けられたが精度がいまいちだった
そこでDaVinci Resolveというより高機能な編集ソフトを使ってみた
DaVinci ResolveではAuto Subsというプラグインを用いて無料で自動字幕を付けられるそうだ
(有料版ならプラグイン無しで自動字幕機能が使えるらしい)
使ってみたが軽量なモデルでは精度がいまいちだった
精度の良いモデルを使うと長時間待つことになった
色々と調べてみるとローカル環境で自動字幕を付けられるモデルがあることを知った
それがWhisperである
Whisperは有名なChatGPTを開発しているOpenAI社が公開している音声認識モデルらしい
モデルとしての信頼もできると考え使ってみることにした
というわけで、今回はゼロからWhisperを使うまでの備忘録である
以下、自分のパソコンのスペック等
OS Windows 11
CPU Intel(R) Core(TM) i7-8565U CPU
RAM 16.0 GB
初期環境構築備忘録
自分はWindows上で開発をしたことが無いので、まずは必要なものをインストールする
Power Shellの最新版をインストール
Windows11では最初からPower Shellがインストールされているがバージョンが5である
最新版は7であるため、どうせならと思い最新版のインストールをした
プラスで、Power Shellをwingetでインストールしたほうが良いとのことでそうした
wingetがインストールされているか確認
winget
wingetでPower Shellをインストールできるか確認
winget search --id Microsoft.PowerShell --exact
wingetでPower Shellの最新版をインストール
winget ipowershellnstall --id Microsoft.PowerShell --source winget
Power Shell最新版がインストールされているか確認
$PSVersionTable
設定ファイルを開く
notepad $profile
以下の一文を記入するとPower Shellを起動したときに指定したフォルダで起動するらしい
# 初期位置を設定
Set-Location "C:\Users\<name>\<name>\"
あとは諸々設定をする(GUIの話は省略)
Oh My Poshを入れる
Power Shellをかっこよくしたほうが気分が上がるので、入れてみた
winget install JanDeDobbeleer.OhMyPosh --source winget --scope user --force
oh-my-posh font install meslo
mesloというのはよくわからないが、それがカッコいいらしいので素直に従った
(結果良い感じなのでオーライ)
VSCodeインストール
メモ帳でもよいが、どうせなら開発用のエディタ(VSCode)を入れてみた
winget install -h --id Microsoft.VisualStudioCode
VSCodeの起動
code .
extensionsからjapapeseと検索して日本語パックをインストール
Pythonインストール
winget install -e --id Python.Python.3.12 --source winget
バージョン確認(インストールできたか確認)
py --version
とりあえず3.12なら安定してそうな気がする
ffmpegをインストール
ffmpegは音声解析に必要らしい
winget install ffmpeg
ffmpeg -version
wingetですべてインストールできるのは便利だなという感想
これで必要なものを揃ったと思うので開発を始められそうである
Pythonの開発環境構築
とりあえず適当にフォルダを作成する
mkdir whisper
cd whisper
仮想環境を作る
py -m venv .venv
仮想環境を起動
.venv\Scripts\activate
一応、仮想環境の終了
deactivate
pipの準備
pip(Pythonのパッケージ管理システム)が入っているか確認
pip --version
とりあえずアップデートしておく
python -m pip install --upgrade pip
諸々準備
new-item README.md #プロジェクトの説明
new-item requirements.txt #必要なパッケージリスト
requirements.txtを用いて必要なパッケージを一括インストールできるらしい
pip install -r requirements.txt
Power Shellにはtouchコマンドが無いらしくnew-itemコマンドを使用した
notepad, codeコマンドでもよいだろう
README.mdに説明を書き留めて、わすれないように
以上で準備は完了
Faster-Whisperを使う
さっそくWhisperを使おうと思うが、色々と調べるとどうやらfaster-whisperというものがあるらしい
普通のWhisperよりも高速かつ軽量なようで、こちらを使うことにした
faster-whisperのインストール
pip install faster-whisper
VSCodeでPythonのスクリプトを書いていく
code src/script.py
このときVSCodeの拡張機能でPythonを入れておくとよい
tempフォルダにサンプルの音源を入れておく(test.m4a)
mkdir temp
とりあえずサンプルコードを拾ってきた
from faster_whisper import WhisperModel
model = WhisperModel("base", device="cpu") # 今回はCPUを使う
audio_path = "./temp/test.m4a" # サンプル音源
segments, info = model.transcribe(audio_path)
transcription = ''
for segment in segments:
transcription += str(segment.text) + '\n'
print(transcription)
実行
python src/script.py
結果、うまく使えた
初回ではモデルを使うにあたりHF_TOKENに関する警告が出てくるが、2回目以降は出てこない
他のモデルを使う場合、再び出てくる
解決するにはアカウントを作成してトークンを取得して設定するらしい
備考
faster-whisperのモデルは以下の通り
| モデル | パラメータ数 | 必要メモリ |
|---|---|---|
| tiny | 39M | 1GB |
| base | 74M | 1GB |
| small | 244M | 2GB |
| medium | 769M | 5GB |
| large | 1550M | 10GB |
largeモデルも必要メモリは満たしているが、普通のCPUで処理を行うと時間が掛かるらしいので現実的なモデルを選択する必要があるだろう(今回はbaseモデルを使用した)
GPUで処理すれば精度の高いモデルを使えるが、いかんせん高いので諦める
(GPUを使う場合、別に必要なパッケージなどがあるらしい)
SRT形式で出力したい
次に、SRT形式での出力を試みる
字幕として使いたいのでSRT形式が良いからである
from faster_whisper import WhisperModel
import datetime
model_size = "base"
model = WhisperModel(model_size, device="cpu")
audio_path = "./temp/test.m4a"
segments, info = model.transcribe(audio_path, language="ja")
output ="./temp/test.srt"
with open(output, "w", encoding="utf-8") as srt_file:
for i, segment in enumerate(segments, start=1):
start_seconds = datetime.timedelta(seconds=segment.start)
end_seconds = datetime.timedelta(seconds=segment.end)
start_time = str(start_seconds)[:11].replace('.', ',')
end_time = str(end_seconds)[:11].replace('.', ',')
srt_file.write(f"{i}\n")
srt_file.write(f"{start_time} --> {end_time}\n")
srt_file.write(f"{segment.text.strip()}\n\n")
print("srtファイル出力完了", output)
実行するとtempフォルダにtest.srtファイルが出力される
大問題!?本家Whisperにすることにした
この後色々と調べていくと、CPUで実行する場合faster-whisperよりも本家whisperのほうが処理速度が速いという記事を発見した
というわけで、faster-whisperを使う意味もないのでwhisperに戻します...トホホ
pip install openai-whisper
import whisper
from pathlib import Path
import argparse
import datetime
import time
# 処理時間の計測開始
start = time.perf_counter()
# 実行時に音源ファイルを指定する
parser = argparse.ArgumentParser()
parser.add_argument("audio_file")
args = parser.parse_args()
audio_path = Path(args.audio_file)
# whisperを用いて文字起こしをする
model_size = "base"
model = whisper.load_model(model_size, device="cpu")
result = model.transcribe(str(audio_path), fp16=False) #CPUではfp16=Falseでないと警告が出る
# SRT形式にして出力する
output = audio_path.with_suffix(".srt")
with open(output, "w", encoding="utf-8") as srt_file:
for i, segment in enumerate(result["segments"], start=1):
start_seconds = datetime.timedelta(seconds=segment["start"])
end_seconds = datetime.timedelta(seconds=segment["end"])
start_time = str(start_seconds)[:11].replace('.', ',')
end_time = str(end_seconds)[:11].replace('.', ',')
srt_file.write(f"{i}\n")
srt_file.write(f"{start_time} --> {end_time}\n")
srt_file.write(f"{segment["text"].strip()}\n\n")
# 処理時間の計測終了
end = time.perf_counter()
print("処理時間(秒数):", '{:.2f}'.format((end-start)))
print("SRTファイル出力:", output)
実行
python .\src\script.py .\temp\test.m4a
多少の変更点として
- 処理時間を計測した
- 実行時に音源ファイルを指定するようにした
WhisperでSRT形式出力
色々と調べていくとどうやらWhisperではSRT形式で出力する関数が用意されているらしい
import whisper
import os
from pathlib import Path
import argparse
from whisper.utils import get_writer
import time
# 処理時間の計測開始
start = time.perf_counter()
# 実行時に音源ファイルを指定する
parser = argparse.ArgumentParser()
parser.add_argument("audio_file")
args = parser.parse_args()
audio_path = Path(args.audio_file)
# whisperを用いて文字起こしをする
model_size = "base" # tiny/small/base/medium/large
model = whisper.load_model(model_size, device="cpu")
result = model.transcribe(str(audio_path), fp16=False, word_timestamps=True)
# SRT形式にして出力する
output = os.path.dirname(audio_path)
srt_writer = get_writer("srt", output)
word_options = {"max_line_width": 20, "max_line_count": 1}
srt_writer(result, audio_path, word_options)
# 処理時間の計測終了
end = time.perf_counter()
print("処理時間(秒数):", '{:.2f}'.format((end-start)))
print("SRTファイル出力:", audio_path.with_suffix(".srt"))
先ほどSRT形式にするために色々と頑張っていた部分を変更したら同様の結果になった
Whisperのほうが便利である
本家WhisperとFaster-Whisperの比較
10秒ほどの同じ音源ファイルをbaseモデルで実行して比較した結果
## 本家Whisper実行時の出力結果
処理時間(秒数): 3.79
SRTファイル出力: temp\test.srt
## Faster-Whisper実行時の出力結果
処理時間(秒数): 3.43
SRTファイル出力: temp\test.srt
あれ?本家Whisperのほうが早いと思ったが、faster-whisperのほうが早かった
テスト音源を10分ほどの長さのものに変更してみる
## 本家Whisper実行時の出力結果
処理時間(秒数): 107.76
SRTファイル出力: temp\test2.srt
## Faster-Whisper実行時の出力結果
処理時間(秒数): 153.32
SRTファイル出力: temp\test2.srt
最初は10秒ほどのテスト音源だったので本家Whisperが負けたが10分ほどの音源にすると本家Whisperの勝利だった
長い音源で実行するのであれば、本家Whisperのほうが早いのであろう
さいごに
以上、faster-whisperを用いて音声ファイルからSRT形式のファイルを出力するまでをやってみた
その後、本家Whisperで同様のプログラムを作成して比較した
精度も良いしモデルを選べばあまり時間もかからないので実用として問題なさそうである
今後もAIの進歩は著しいと思うので色々と追っていきたい