nikkie-ftnextの日記

イベントレポートや読書メモを発信

声をWhisper APIに聴かせて(音声ファイルもマイクから入力した音声も認識させよう)

はじめに

十分に発達した科学技術は、魔法と見分けがつかない。1 nikkieです。

Breaking news!!
ChatGPTとWhisperがWeb APIで提供開始されました!!
Whisper APIについてnikkieの視点(シオン・プロジェクトやSpeechRecognitionメンテナ視点)で触ってみてのログを残します。

目次

ChatGPTとWhisperがWeb APIで提供開始!

Whisper APIを触る (super easy!!)

マジでsuper easyすぎてヤバいです!

サンプルコードは提供開始のドキュメントにあります。
数行のコードでWhisper APIで文字起こしできちゃいます!

事前準備

OpenAIのアカウントが必要です。
ChatGPTを使っていたら、もうアカウントを持っています。

User settingsからAPI keyをgenerateします。
このキーは生成したときにしか表示されないので控えるのを忘れないように注意です2
Whisper APIをプログラムから利用するため、環境変数OPENAI_API_KEYに指定します。

export OPENAI_API_KEY=sk-your-secret-api-key

Whisper APIに送る音声ファイルを用意します。
macOSsayコマンドで作りました3sample.wav)。

curlでWhisper APIを呼び出す

めちゃめちゃ簡単です。

% curl https://api.openai.com/v1/audio/transcriptions \
      -H "Authorization: Bearer $OPENAI_API_KEY" \
      -H "Content-Type: multipart/form-data" \
      -F model="whisper-1" \
      -F file="@sample.wav"

{"text":"親譲りの無鉄砲で子供の時から損ばかりしている"}

PythonでWhisper APIを呼び出す

信じられないくらい簡単です。

  • Python 3.10.9
  • openai 0.27.0
    • pip install openaiで環境構築しました
>>> import openai
>>> with open("sample.wav", "rb") as audio_file:
...   transcript = openai.Audio.transcribe("whisper-1", audio_file)
>>> transcript["text"]
'親譲りの無鉄砲で子供の時から損ばかりしている'

open関数にwith文を使っているのは「リソースを開いたら確実に閉じたい」という好みです4

マイクから入力した音声もWhisperに認識させよう

SpeechRecognitionを使って実装できました!
声をPythonに聴かせて(マイクから入力した声をWhisperに、何度でも認識させよう) - nikkie-ftnextの日記で得た知見も使っています。

  • pip install git+https://github.com/Uberi/speech_recognition5
  • PyAudio 0.2.13

% python whisper_api.py
なにか話してください
音声を取得しました
十分に発達した科学技術は、魔法と見分けがつかない。

実装解説

マイクから取得した音声をWAV形式でインメモリストリームに持ちます(BytesIO)。

audio_data.name = "from_mic.wav"というコード(13行目)はopenaiライブラリを動かすためのハックです。
openai.Audio.transcribeメソッドは内部で第2引数fileのname属性6にアクセスしているんですよね(file.name)。
https://github.com/openai/openai-python/blob/v0.27.0/openai/api_resources/audio.py#L55

@classmethod
def transcribe(cls, model, file, ...):
    requestor, files, data = cls._prepare_request(file, file.name, model, **params)

組み込みのopen関数の返り値であればname属性を持つのですが(サンプルコードでは'sample.wav')、インメモリストリームは持ちません。
なので、インスタンスname属性を設定するというハックで対処しました。

file.nameが指すsample.wavのようなファイル名は、拡張子をWhisper APIが参照しているようです。
試行錯誤の中で以下のエラーを見て、「WAV形式のデータをhoge.wavのような名前で送ればよさそう」と閃きました。

openai.error.InvalidRequestError: Invalid file format. Supported formats: ['m4a', 'mp3', 'webm', 'mp4', 'mpga', 'wav', 'mpeg']

終わりに

Whisper API、ヤバいです!!
環境変数を設定して数行のコードで音声認識できました。
SpeechRecognitionの経験を活用して、マイクの音声も比較的簡単に認識できました!

趣味のシオン・プロジェクトの経験から、1年前は音声認識ってこんなに簡単じゃなかったんですよ。
ところがいまはWeb APIで超高性能な書き起こしが得られます!
こんなの魔法じゃん!! ヤバいって!

本当にヤバいA(P)Iが世に解き放たれちゃいましたね

P.S. SpeechRecognitionでサポートする実装、Work in progress!

サポートをお楽しみに〜7


  1. https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%A9%E3%83%BC%E3%82%AF%E3%81%AE%E4%B8%89%E6%B3%95%E5%89%87 より
  2. 忘れてもそんなにおおごとではないと思います。再生成しましょう!
  3. 声をPythonに聴かせて(前編:wavファイルだと書き起こせるのに、マイクの入力はいまいち!?) - nikkie-ftnextの日記(動作確認:sayコマンドでwavファイルを作る)
  4. ref: 5. ファイル操作とモジュール - Python Boot Camp Text ドキュメント
  5. こちらの記事でも書きましたが、最新はPyPIではなくリポジトリです(メンテナとして近々リリースがんばります)
  6. https://docs.python.org/ja/3/library/io.html#io.FileIO.name
  7. 「やるぞ」の気持ち!