🍣

whispercpp gemでRubyで音声書き起こし

に公開

whispercppという音声の自動書き起こしができるgemの紹介です。
https://github.com/ggml-org/whisper.cpp/tree/master/bindings/ruby

音声自動書き起こしのための機械学習モデル(+インターフェイス)に、OpenAIのWhisperがあります。Whisper.cppはそのWhisperのポーティングで、名前の通りC++で実装されています。whispercppは、そのC++実装のRubyバインディングです。

なので、大雑把にはWhisperでできることをRubyでもできる、という物です。

一度モデルをダウンロードすればローカルで動くので、API利用料やプライバシーを気にせず使うことができます。

一年ぐらい前に見付けて、ちょこちょこ機能追加などしています。

使い方

require "whisper"

whisper = Whisper::Context.new("base")
params = Whisper::Params.new()
whisper.transcribe("path/to/audio.wav", params) do |whole_text|
  puts whole_text
end

という感じで使います。
Whisper::Context.newに渡す引数がモデルの種類で、tiny, base, small, medium, large, turboなどがあり、大きくなるほどモデルサイズが大きく、精度が上がります(機械学習の常ですが、絶対ではないです……)。各モデルの詳細はWhisperのドキュメントを見てみてください。
最初の実行時に自動でダウンロードし(時間が掛かります)、二回目以降はダウンロードしたキャッシュを使用します。

使い方に戻って、時間情報が必要なときは、transcribeを呼び出した後でeach_segmentを使うと取得できます:

whisper
  .transcribe("path/to/audio.wav", params)
  .each_segment do |segment|
    line = "[%{st} --> %{ed}] %{text}" % {
      st: format_time(segment.start_time),
      ed: format_time(segment.end_time),
      text: segment.text
    }
    puts line
  end

使い道

ポッドキャスト

僕はポッドキャストの収録後、書き起こしを見ながら、どう編集しようかと考えています。
ポッドキャストによく出てくる単語なんかをプロンプトに渡してやるとそれらを使ってくれます。

# 大体"large-v3-turbo-q8_0"を使っています
whisper = Whisper::Context.new("large-v3-turbo-q8_0")
params = Whisper::Params.new(
  language: "ja",
  initial_prompt: "ここに。術後とか。を入れておく。"
)
whisper.transcribe("path/to/audio.wav", params)

macOSだとGPUが有効になるので、アクティビティモニターを見ながら「おお、RubyがGPUを有効活用している!」という感動を味わえます。

発表

夢として、リアルタイム書き起こしができるといいなあと思っています。
それができると、Rabbitみたいなプレゼンツールと統合して、資料の所に話したことを出したりできるようになります。

そのためにはマイクの音声を拾う必要があり、例えばGStreamer gemで拾うことが可能ですが、それをwhispercppに渡すところに課題があります。
whispercppにはMemoryViewでオーディオデータを取得する機能を実装してあるので、マイクの音声を渡す側を対応してやれば理論上実現できるはずです。GitHubにイシューをファイルしつつ実装を進めていますが、色々勉強しながらなのと、別件で忙しくなってて中々進まない……。


最近触っているgemの紹介でした。
Windows対応やCUDAの動作確認(コンパイルできる筈なのですが、環境が無くて未確認……)など、手伝ってくれる人、大歓迎です!

Discussion