トピック

OpenAIの自動文字起こし「Whisper API」は1分1円以下! 簡単に使える?

OpenAIの文字起こし機能「Whisper API」を試してみた

何かと話題の対話型AIであるChatGPTだけれども、その開発元であるOpenAIが提供しているサービス・機能はChatGPT以外にもいくつかある。その1つが「Whisper」という音声データから文字起こししてくれる機能だ。

筆者の場合、たとえば取材のときに録音し、それを後で文字に起こすことがある。最近はGoogleのスマートフォン、Pixelシリーズの「レコーダー」アプリがもつ文字起こし機能をその場で使うことも増えてきたが、まだ完璧に文字起こししてくれるほどの精度には至っていない。しかしChatGPT(GPT-3.5やGPT-4)で驚異的なポテンシャルを見せつけているOpenAIの文字起こしサービスなら、さらなる高精度を期待できるのではないか。そう思って、試してみることにした。

わずか10行のプログラムで文字起こしが可能!?

「Whisper」はより正確に言うと、AIを構成するニューラルネットワークに付けられた音声認識モデルの名称で、OpenAIでは「Speech to text」機能として案内されているもの。現在は他のシステムからOpenAIのサーバーにアクセスして呼び出すAPIの形で提供されており、通称「Whisper API」と呼ばれている。対応言語は英語、日本語など数十言語に及ぶ。

Whisper APIのメリットは、精度がどうかは今は置いておくとして、なんといっても安価なことだ。料金は音声データ1分あたり、なんと0.006ドル。日本円にして1円にも満たない。もし60分の音声ファイルだったとしても、たったの60円。他の日本語対応の文字起こしサービスだと60分で2,000~3,000円かかるケースもあり、OpenAIのサービスはそれと比べて圧倒的に安価に文字起こしができてしまうのだ。ちょっとくらい精度が低くても、この料金なら許せそうではないか。

APIの利用料金表。Whisper APIは音声1分あたり0.006ドルと格安だ

ただし、提供方法がAPI(かつBeta版)ということで、この原稿を執筆している2023年4月現在、ChatGPTのようにWebブラウザーから個人ユーザーが容易にアクセスして結果を得られる実用的なツールは筆者が知る限りまだ存在しない、というのが弱点ではある(Whisper採用の法人向けサービスはいくつか登場してきている)。

「Hugging Face」というプラットフォームでWhisperを簡単に体験できるツールが公開されていたりもするが、利用には制限があったりする。実用レベルにするには、何らかのプログラム言語から呼び出すか、「Google Colab」などのクラウド上のプログラム実行環境を使うか、「Make」のようなローコード/ノーコードツールを駆使しなければならない。

「Hugging Face」でWhisperを簡単に体験できるツールもあるが、必ずしも実用的とは言えない

しかし、今回はWhisperがどれほどの認識精度を実現しているのか確かめるのが一番の目的。なので、とにかく筆者だけが使える形になればいい、ということにした。ローコード/ノーコードツールは、それ自体の学習コストもかかるし、場合によっては別途料金がかかることもある。そのため、OpenAIが公式にサポートし、サンプルコードも豊富なプログラム言語「Python」から呼び出すことにした。Pythonなら筆者もある程度コーディング経験があるのでやりやすい。

実は、PythonからのWhisper APIの呼び出しは、コーディングが必要とはいえ、それ自体の難易度はかなり低い。先ほど挙げたローコード/ノーコードツールを使うより手間はずっと少なかったりするのだ。環境面でのいろいろな前提はあるが、エラー対策や例外処理、汎用性なんかは考慮せず、とりあえず動くもの、ということであれば、下記の実質10行ほどのコードで実現できる。

--- transcribe.py ---

import os
import openai

# 入力する音声ファイル
fname = "output.mp3"
# APIキーが格納されたファイルへのパス
openai.api_key_path = 'apikey.txt'

audio_file = open(fname, "rb")
transcript = openai.Audio.transcribe("whisper-1", audio_file)
txt = transcript['text']
f = open(fname + ".txt", "w")
f.write(txt)
f.close()

---------------------

「えっ、なんだ、めっちゃ簡単じゃん」と思うかもしれない。「プログラミングがわからなくてもサクッと試せそう」なんて思っちゃうかもしれない。これだけを見ればたしかにその通りだ。しかし、世の中そう甘くはないのである。「とりあえず動くものを」と考えて始めたWhisper APIによる文字起こしだが、その道のりにはいくつかのハードルが待ち受けている。

ChatGPTさんの力を借りれば、誰でもプログラムを作れるのか(作れない)

上記のコード、ものすごく単純ではあるけれど、実際のところ筆者がWeb検索し、OpenAIの公式ドキュメント(APIリファレンスなど)を読みつつ、さまざまな試行錯誤の末にたどり着いた内容だ。

いやいや、なんでそんな面倒なことをするの? オレたちにはChatGPTさんがついてる! 必要なコードとかをChatGPTさんに聞けば、APIを使った文字起こしツールも3分くらいでできちゃうんじゃないの!? とか思いたくなるのも、まあわかる。

よし、じゃあここでChatGPTさんに「Whisper APIを利用して、音声ファイル(mp3)からテキストファイルに変換するPythonのコードを提示してください」と聞いてみよう。ここで全部を引用するのは避けるが、下記画像のような内容が出力されるはずだ。

Whisper APIを使って文字起こしするPythonのコードを要求してみた

このコードをコマンドラインで実行してみるとどうなるか。たとえ必要なツール、環境設定などの前提を満たしていたとしても、エラーが表示されてプログラムは実行されないはずだ。

なんだかよくわからないが、エラーになって処理がストップした

なぜこうなったのか、原因や解決策を探るためにもう一度ChatGPTさんに聞いてみることにする。

えっ、ChatGPTさん!?

なんてこった! 「最新のドキュメントを読め」と言われてしまったではないか! たしかにこういったAPIを利用するにあたっては、どんなツール・プラットフォームでも、最新の情報を参照するのが鉄則ではある。なので、2021年9月までのことしか知らないChatGPTさんに頼るだけではツールはできあがらない。やっぱりこれまでと同じように地道にWeb検索し、公式ドキュメントを読み込み、試行錯誤していくのが結局のところ一番の近道なのだ。

Whisper APIを利用するために必要なもの

というわけで、まずはプログラムを実行できるよう、前提となる環境構築を行なう。Windows上で必要なものをざっと挙げると下記の通りだ。

・Pythonをインストールする
・Pythonのopenaiモジュールをインストールする
・OpenAIにアカウント登録する
・OpenAIに支払い方法(クレジットカード)を登録する
・OpenAIからAPIキーを取得する

ここで1つ1つの手順を細かく説明することは避けるが、わからないときはChatGPTさんではなく、普通にWeb検索して調べたり、公式ドキュメントを読んだ方がきっと早い。ネットでは、ChatGPTがあれば誰でも簡単にプログラムが作れる、みたいな雰囲気が漂っているが、筆者としては「プログラム言語のことを一切知らなくても大丈夫、とは口が裂けても言えないなあ」と思っている。

Pythonをインストールする(https://python.org/)
pip install openai (Pythonのopenaiモジュールをインストールする)
OpenAI APIのWebサイトにアクセスし、アカウント登録する
OpenAIに支払い方法(クレジットカード)を登録する
OpenAIからAPIキーを取得する

長い音声データがそのまま使えない? 助けてChatGPTさん!(助けてくれない)

必要なツールや情報は揃ったので、最初に挙げたPythonコードでさっそく文字起こしを……と思いたくなるが、その前に注意しておかなければならないことがある。それは、Whisper APIの仕様上、「一度に文字起こしできる音声データの長さは25分までに制限される」ということだ。これも公式ドキュメントに記載されている。

25分に満たない短い音声しか扱わないのであれば、気にする必要はない。けれども、長い会議の文字起こしが必要になることも当然想定されるわけで、その場合は複数の音声ファイルに分割した後、1つ1つWhisper APIに渡して処理する必要があるのだ。

「一度に文字起こしできる音声データの長さは25分までに制限される」ことから、長い音声ファイルは分割が必要。しかし、「前後の文脈を保つため、発言の途中で分割されないようにすることを推奨」している

しかもそうやって音声ファイルを分割する際には、公式ドキュメントによると「前後の文脈を保つため、発言の途中で分割されないようにすることを推奨」している。つまり、誰も発言していない無音部分で分割するのがベターということ。25分以内で、かつ無音部分で分割する。音声ファイルの編集ツールで手動分割するのもアリだが、やはり手間だ。ここもできれば自動化したい。よし、ChatGPTさんに相談だ!

無音を境に音声ファイルをイイ感じの長さで分割してくれるコードを1つ頼むよ、ChatGPTさん

自信満々に出力してきたPythonコード。pydubというものが必要との説明もあるので、インストールしたうえで実行してみる。さっきのエラーの例もあるからちょっと疑り深くなっているのだが、どうか。

「pip install pydub」コマンドでpydubをインストール
提示されたコードを実行すると、なぜか大量のファイルが出力された

処理完了までめちゃくちゃ時間がかかったうえに、大量のファイルが出力されてしまった。どうやら無音がある全ての箇所で分割してしまったようだ。質問の仕方が良くないのかもしれないが、いろいろ質問を変えても望む結果にならなかったので、結局筆者がファイルの分割位置を決定する処理部分に手を入れることに……。

最終的には、仕上がりのファイルサイズの余裕を見て、20分経過した直後に1秒以上の無音部分があればそこで分割する、ということにした。128kbpsのMP3ファイルだとだいたい20MB以内になるからだ。ただし、128kbpsで、かつ20分~25分の間に必ず無音があることが前提となるため、汎用性はあまりない。あと、処理速度を改善するべく、1ミリ秒単位で無音検知していたところは100ミリ秒に変えた(海外の掲示板で方法を調べた)。コードは下記。

--- audiosplit.py ---

from pydub import AudioSegment, silence

# 入力ファイル名
input_file = "input.mp3"
# 出力ファイル名のプレフィックス
output_prefix = "output"
# 1ファイルあたりの最大長さ(秒)
max_length = 1200
# 無音と判定するときの無音の長さ(ミリ秒)
min_silence_len=1000
# 無音と判定する音量の閾値
silence_thresh=-50

# 入力ファイルを読み込む
audio = AudioSegment.from_file(input_file)

# 無音部分を検出する(検出単位は100ミリ秒)
silences = silence.detect_silence(audio, min_silence_len, silence_thresh, 100)

# 分割するポイントを決定する
split_points = []
prev_time_start = 0
prev_time_end = 0
for i in range(len(silences)):
# 閾値以上の無音時間があるか
if silences[i][1]-silences[i][0] >= min_silence_len:
# 前回の分割ポイントからmax_length以内だったらスキップ
if silences[i][1]-prev_time_end < max_length*1000:
continue

# 前回の分割ポイントからmax_length以上なので、無音終了時間の100msec前で分割する
# (有音部分の直前直後で分割すると正しく音声が認識されない可能性がありそうなため)
if len(split_points) <= 1:
prev_time_start = 0
prev_time_end = min(silences[i][0]+100,len(audio))
else:
prev_time_start = prev_time_end+500
prev_time_end = min(silences[i][0]+100,len(audio))

# 分割ポイントを配列に格納
split_points.append(prev_time_start)
split_points.append(prev_time_end)

# 末尾も配列に格納
if split_points[-1] != len(audio):
split_points.append(prev_time_end+500)
split_points.append(len(audio))

# 分割位置の出力(確認用)
print(list(split_points))

# ファイルを分割する
for i in range(len(split_points)//2):
start = split_points[i*2]
end = split_points[i*2+1]
segment = audio[start:end]
# なんとなく後処理しやすいように3桁でゼロ埋め
output_file = f"{output_prefix}_{'{:03}'.format(i+1)}.mp3"
segment.export(output_file, format="mp3")
print("export:" + output_file)

---------------------

検証用なので、長い音声ファイルを処理するときは、いったん音声ファイルを「audiosplit.py」に食わせて分割した後、「transcribe.py」で1ファイルずつ音声認識を実行するという半自動なやり方となる。本格的にWhisper APIを活用することになったときには、1つのプログラムにまとめたうえでWebブラウザーから利用できるようにするなど、もう少し便利に扱える形にしたいところだ。

果たしてWhisperによる文字起こしの精度は!?

さあ、これでようやくWhisper APIの音声認識精度を検証する準備が整った。ここまでに1日半は費やした気がする。ChatGPTさんの意味不明な音声ファイル分割コードには本当に苦労させられた……。

と、それはともかく検証である。今回の検証にあたっては、PC WatchのYouTubeチャンネル「PAD」から、筆者が出演した部分の約1分間の音声をサンプルとして使用した。

【絶対にマネしてはいけない】中華な水槽PCケース「Y2鱼缸机箱」でPCを自作してみた

Whisper APIによる結果とは別に、手作業で文字起こししたものと、「Pixel 7 Pro(レコーダーアプリの文字起こし機能)」、日本語音声文字起こしサービスの「Rimo Voice」、文字起こしアプリ「UDトーク」の結果もそれぞれ比較のために用意した。

なお、Pixel 7 ProとUDトークについては、アプリが基本的にマイク入力のみ受け付ける仕組みとなっているため、スピーカーから出力した音声をスマートフォンのマイクで取り込むという方法でテストしている。そのため、音声ファイルを直接入力するWhisper APIやRimoと比較して音質面で若干不利な状況にあり、その分を差し引いて考えていただきたい。

実際の発言(手作業による文字起こし)

筆者:2つ目。
編集者:お、焼き魚。
筆者:もうなんか想像できるかもしれないですけども、このPCって、まあある意味熱源の塊なところもありますよね。
編集者:はい。
筆者:その上で生き物を飼うのって倫理的にどうなんですかっていう話もありますよね。
編集者:うーん、なるほど。はい。
筆者:PCが動いた時に、
編集者:はい。
筆者:負荷がかかると当然温度が上昇するし、負荷がかかってない時はまあ、下がる。
編集者:冷える。
筆者:ですよね。で、さらに冷却ファンなんかもあったりすると、その音が、
編集者:うん。
筆者:騒音として出てくる可能性もあると。それがお魚さんのストレスになってしまう可能性もありますよね。
編集者:まあ、もちろんコメントでもね、ヒーターは、っていうコメントもついてたりしますけど、そのね、水温を一定に保つためのヒーター機能はPC部分なんだよっていう解釈なのかもしれないんですけど。

Whisper API

2つ目 焼き魚 なんか想像できるかもしれないですけども このPCってある意味熱源の塊なところもありますよね その上で生き物を飼うのって倫理的にどうなんですかっていう話もありますよね PCが動いた時に負荷がかかると当然温度が上昇するし 負荷がかかってない時は冷えるなと さらに冷却ファンなんかもあったりするとその音が騒音として出る可能性もあると それがお魚さんのストレスになってしまう可能性もありますよね もちろんコメントでもヒーターはコメントもついてたりしますけど 水温を一定に保つためのヒーター機能はPC部分なんだよっていう解釈なのかもしれないんですけど

Pixel 7 Pro

2 つねを焼き魚。もうなんか想像できるかもしれないですけど。この PC ってまあある意味熱減のかたまりなところもありますよね。その上で生き物を買うのって倫理的にどうなんですか?っていう話もありますので。

はい。PC が動いた時にはい、負荷がかかると当然温度が上昇ですし。深くなるかな?下がるなんですよね?はい。で、さらに冷却ファンなんかもあったりするそ、その音がそうとしてて可能性もあるとそうですね。

なってしまう可能性もありますよね。まあ、もちろんコメントでもね。ヒーターはあって、あのーコメントもついていただきますけど、ただそのね水温も行ってみ保つためのヒーター機能は PC 部分なんだよっていう解釈なのかもしれないんですけど。

Rimo Voice

二つ目、焼き魚。もうなんか想像できるかもしれないですけれども、このPCってある意味熱源の塊なところもありますよね。その上で生き物を飼うのって、倫理的にどうなんですかっていう話もありますね。はい。PCが動いたときに、はい、負荷がかかると、当然温度が上昇するし、負荷変わって何か差が見えるはずなんですよね。

はい。さらに冷却ファンなんかもあったりするとその音がうん、騒音として出てくる可能性もある。それがお魚さんのストレスになってしまう可能性もありますよね。そうですねもちろん何かコメントでもね、ヒーターはコメントもついてたりしますけどね、水温を一定に保つためのヒーター機能はPC部分なんだよっていう解釈なのかもしれないんですけど。

UDトーク

二つ目を焼き魚、なんか想像できるかも知れないですけども、このPCってある意味熱源の塊なところもありますね。
その上で生き物を飼うのって倫理的にどうなんですかPCが、動いたときに、負荷がかかると当然温度が上昇。
関わってないかも。
ですよね。
さらに冷却ファンなんかもあったりするとその音が、騒音として出る可能性もある。
お魚さんのストレスになってしまう可能性も。
そう、もちろんがコメントでもね、聞いたわってコメントもついてたりしますけど、ただね、水温を一定に保つためのヒーター機能はPC部分なんだよ。
解釈なのかもしれないんですけど。

他ツールには便利な機能もある Whisper APIの利用ハードルの高さ

結果、日本語の認識精度としては、Whisper APIがかなり高いことがわかった。会話のなかであまり意味をなさない「はい」や「まあ」といった発言は意図的に取り除かれているのか、読みやすさという点でも優秀だ。唯一ネックとなるのは句読点がなく半角スペースで文章が区切られていること。文章を整える際には、語尾と思われる文字と半角スペースで検索し、一括置換するような作業が必要になるだろう。

他のツールの結果を見ると、Rimoも高精度で、しっかり句読点が入ったうえで段落分けまでしてくれている。料金は30秒22円(都度課金、音声ファイルの場合)でWhisper APIと比べてしまうと安価とは言えないが、実用性は高い。Pixel 7 ProやUDトークは、おそらくマイクからの音声入力ということで認識精度が低くなっているところもありそうだ。

ただ、Whisper API以外のこれらのツールは単に文字起こしするだけでなく、音声を聞きながら文章を再編集できたり、独自の辞書を追加して認識精度を高められたり、といった付加機能がある。ツールによって会話ジャンルの向き不向きもあるだろう。Whisper APIはたしかに高精度かもしれないが、使い勝手も含め総合的に考えると、まだ他のツールの方が活躍してくれる場面も少なくないと思われる。

とはいえ、1分あたり0.006ドルでこの精度は驚異的。OpenAIのサーバーに音声ファイルをアップロードすることになるため、機密情報保護の観点から安易な利用に対する懸念があることも覚えておきたいが、低コストで文字起こしの効率化を図りたいのなら、少し勉強してチャレンジしてみてもいいのではないだろうか。

日沼諭史

Web媒体記者、IT系広告代理店などを経て、フリーランスのライターとして執筆・編集業を営む。AV機器、モバイル機器、IoT機器のほか、オンラインサービス、エンタープライズ向けソリューション、オートバイを含むオートモーティブ分野から旅行まで、幅広いジャンルで活動中。著書に「できるGoProスタート→活用 完全ガイド」(インプレス)、「はじめての今さら聞けないGoPro入門」(秀和システム)、「今すぐ使えるかんたんPLUS+Androidアプリ 完全大事典」シリーズ(技術評論社)など。Footprint Technologies株式会社 代表取締役。