Whisperは音声をテキストに変換するOpen AIのAIです。日本語にも対応している優秀なモデルなのですが…。
このAPIをつかおうとしたところ…以下のエラーが出る。
error_code=None error_message="Invalid file format. Supported formats: ['m4a', 'mp3', 'webm', 'mp4', 'mpga', 'wav', 'mpeg', 'ogg', 'oga', 'flac']" error_param=None error_type=invalid_request_error message='OpenAI API error received' stream_error=False
フォーマットは正しいはず、ファイル名は間違ってない、ファイルも破損していない。
ちなみに、データをtempfile使って、一時ファイルを生成している。
with tempfile.NamedTemporaryFile(delete=True, suffix=".wav") as temp_audio:
temp_audio.write(data)
temp_audio.flush()
transcript = openai.Audio.transcribe("whisper-1", temp_audio)
print(transcript["text"])
でも、これだとInvalid file formatが起きてしまいます。
実は、一時ファイル(temp_audio)の「読み書きのカーソル」をファイルの先頭に必要があるのです。
うまくいくコードはこちら。
with tempfile.NamedTemporaryFile(delete=True, suffix=".wav") as temp_audio:
temp_audio.write(data)
temp_audio.seek(0) # この行を追加
transcript = openai.Audio.transcribe("whisper-1", temp_audio)
print(transcript["text"])
さて、なぜこの「読み書きのカーソル」が問題となるのか、もう少し詳しく見てみましょう。
ファイルのカーソルとは、具体的にはファイル内での現在の位置を示すポインタのことを指します。これがファイルの最後に位置していると、ファイルの内容の読み取りや書き込みが期待する位置から始まらないため、意図しない動作が起こる可能性があります。
上記のコード例の場合、temp_audio.write(data)の操作後、カーソルはデータの最後、つまりファイルの終端に移動しています。そのため、openai.Audio.transcribeがファイルを読み込む際、内容が存在しない箇所から読み取りを開始してしまいます。これがInvalid file formatというエラーの原因となります。
temp_audio.seek(0)によってカーソルをファイルの先頭に戻すことで、openai.Audio.transcribeがファイルの正しい位置から読み取りを行い、期待した通りの動作となります。
このように、コーディング時にはファイルのカーソルの位置も考慮する必要があることが分かります。特にファイル操作を行う際には、このような細かいポイントがバグの原因となり得るため、注意深くコードを記述する必要があります。
結構、よくある話なので覚えておきましょう!