Azure AI Foundry で Whisper モデルの API を Node-RED から試したメモです。
背景
2025/01/09 時点の情報で進めます。
- Azure AI Foundry から gpt-4o モデルを使ってみるメモ – 1ft-seabass.jp.MEMO
- Azure AI Foundry で作った gpt-4o モデルを API として Node-RED とやり取りするメモ – 1ft-seabass.jp.MEMO
先日こんな記事で Azure AI Foundry でモデル選んで API も使えることが分かったので Whisper モデルも使ってみます。
モデルを探す
モデル カタログ では whisper が使えることがわかります。
クリックしてみた詳細です。最後のトレーニング「使用できません」となって使えるのか心配になりますが、ちゃんと使えました。
左上のデプロイボタンをクリックします。
デプロイ確認画面です。
Azure AI Foundry から gpt-4o モデルを使ってみるメモ – 1ft-seabass.jp.MEMO で使ったプロジェクトをそのまま使います。
デプロイをクリックします。
すぐにデプロイ完了しました!
Node-RED の仕組み
現時点では OpenAI 社の API の構造と Azure AI Foundry の OpenAI の API は同じようなので、
を参考にしつつ、
まず Node-RED でこのようなフローを作り、 OpenAI 社の API での Whisper のほうで成功することを確認しました。
API 設定の change ノードでは、
サウンドデータ付与以外の部分で、ヘッダーや URL 、model などを設定しています。
サウンドデータ付与の change ノードでは、
このようにサウンドデータ付与を行っています。
inject ノードをクリックして動かすとこんなかんじです。
Whisper の詳細画面で Azure AI Foundry のほうの API のエンドポイントと API キーの情報を確保しつつ、
さきほどのフローをコピーして、Azure AI Foundry の設定をします。
API 設定の change ノードでは、OpenAI 社の API のヘッダー情報である Authorization ヘッダーを、Azure AI Foundry の OpenAI の API のヘッダー情報である api-key にしつつ Bearer はなくします。
動かしてみると何かがおかしい→翻訳だった
こんな感じで、文字お越しはされるものの、変な文字が混ざるときがあります。
英語が来る?何かがおかしい?
こういった issue をみていて「あ、これは文字起こしじゃなくて翻訳のほうが発動してる!」と気づきました。
ここに示されるエンドポイントのサンプルが translations になっちゃってるんですよね。気づきませんでした。
そのままコピペしてたので、
transcriptions に変更します。
こちらの API の仕様を参考にしてます。
うまくいった
にあわせて translations を transcriptions に変更したら翻訳っぽい挙動がなくなり、素直な自動言語認識の文字起こしになりました。
やった!
短時間にたたき続けてるとエラーが返ってくる学び
ちなみに、デフォルトでプロジェクトで使われる S0 tier を使ってると、短時間にたたき続けてるとエラーが返ってきます。
Requests to the Audio_Transcriptions Operation under Azure OpenAI API version 2024-06-01 have exceeded call rate limit of your current AIServices S0 pricing tier. Please retry after 5 seconds. Please contact Azure support service if you would like to further increase the default rate limit.
すこし間を置けばアクセスできるので安心してください。5 秒後リトライしてねと書いてありますね。
以下に JSON のフローも置いておきます。
[{"id":"22828b14f4fc87e9","type":"debug","z":"6c85d499b1c334b0","name":"debug 3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":800,"y":760,"wires":[]},{"id":"d826ed327d0b3135","type":"http request","z":"6c85d499b1c334b0","name":"","method":"POST","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":590,"y":760,"wires":[["22828b14f4fc87e9"]]},{"id":"d706cc46f00aeb7b","type":"change","z":"6c85d499b1c334b0","name":"multipart/form-data でのサウンドデータ付与","rules":[{"t":"set","p":"payload.file","pt":"msg","to":"{}","tot":"json"},{"t":"set","p":"payload.file.value","pt":"msg","to":"buffer","tot":"msg"},{"t":"set","p":"payload.file.options","pt":"msg","to":"{}","tot":"bin"},{"t":"set","p":"payload.file.options.filename","pt":"msg","to":"voice.wav","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":760,"wires":[["d826ed327d0b3135"]]},{"id":"6e0b9c1337c4e0a8","type":"change","z":"6c85d499b1c334b0","name":"API 設定","rules":[{"t":"set","p":"url","pt":"msg","to":"{url}","tot":"str"},{"t":"set","p":"payload","pt":"msg","to":"{}","tot":"json"},{"t":"set","p":"headers.api-key","pt":"msg","to":"{api-key}","tot":"str"},{"t":"set","p":"headers.Content-Type","pt":"msg","to":"multipart/form-data","tot":"str"},{"t":"set","p":"payload.model","pt":"msg","to":"whisper-1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":660,"wires":[["d706cc46f00aeb7b"]]},{"id":"4ee9ea2ea06f9b3c","type":"change","z":"6c85d499b1c334b0","name":"音データ msg.buffer 保管","rules":[{"t":"set","p":"buffer","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":590,"y":660,"wires":[["6e0b9c1337c4e0a8"]]},{"id":"41d40b4c8f81b66c","type":"file in","z":"6c85d499b1c334b0","name":"音データ読み込み","filename":"{path}","filenameType":"str","format":"","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":350,"y":660,"wires":[["4ee9ea2ea06f9b3c"]]},{"id":"b349cf79921725b7","type":"inject","z":"6c85d499b1c334b0","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":120,"y":660,"wires":[["41d40b4c8f81b66c"]]}]