Gladia、Deepgram、AssemblyAI、Speechmatics、Soniox、ElevenLabsをbot単位で選択。独自のAPIキー、独自のリージョン、プロバイダー固有のすべてのオプションを完全にパススルーできます。

AAmr El Shimy
··9 min read
6つの文字起こしプロバイダー、1つのAPI

音声認識プロバイダーの選択は、一度きりの決断ではありません。対象ドメインでの精度、1時間あたりの料金、対応言語、EUデータ保持条件でのDPA締結の可否、3人が同時に話した際の話者分離の精度など、あらゆる条件が変化し、すべての顧客に対して同じ答えが通用するわけではありません。

そこで、私たちは選択をやめました。bot単位でプロバイダーを選択でき、すでに取得済みの録音についても後から変更できます。

選択可能なプロバイダー

プロバイダーバッチライブ
gladia
deepgram
assemblyai
speechmatics
soniox
elevenlabs

ElevenLabsはストリーミング専用です。他の5つはバッチとライブの両方に対応しています。

バッチは多くの方が必要とする機能です。ミーティングが終了すると音声が送信され、webhook経由でスピーカーラベルと単語レベルのタイムスタンプ付きのトランスクリプトが返されます。ライブは、ミーティングの進行中にWebSocket経由でトランスクリプトのセグメントがリアルタイムに届くもので、その場で即座に反応する必要があるユースケースに適しています。

それぞれ独立して設定でき、高速なライブフィードと精度の高い最終トランスクリプトが必要な場合は、同一のbotで異なるプロバイダーを組み合わせて使用することもできます。

バッチ

{
  "meeting_url": "https://meet.google.com/abc-defg-hij",
  "bot_name": "Recording Bot",
  "transcription_enabled": true,
  "transcription_config": {
    "provider": "speechmatics",
    "region": "eu2",
    "api_key": null,
    "custom_params": null
  }
}

フィールドは4つです。providerを省略した場合、デフォルトは"gladia"になります。regionapi_keycustom_paramsはいずれもデフォルトがnullで、後述で説明します。

transcription_configtranscription_enabledがtrueの場合に必須で、falseの場合は無視されます。

1つのプロバイダーフィールドで、同じミーティング音声を6つの交換可能な文字起こしプロバイダーのいずれかにルーティング。それぞれ独自のリージョンとバッチ/ライブのサポートに対応しています

botが終了すると、transcription_providertranscription_idsがbotのレコードとwebhookのpayloadに返されます。GET /v2/bots/:bot_id/statusはプロバイダーから直接ポーリングされたライブのtranscription_statusを報告します。値はnot-applicablenot-startedqueuedprocessingdone、またはerrorのいずれかです。

リージョン固定

これらのプロバイダーの多くは複数のリージョンで稼働しており、多くのお客様にとってこれが最重要事項です。

プロバイダーバッチリージョンライブリージョン
gladiaグローバルエンドポイントのみus-westeu-west
deepgramglobaleuglobaleu
assemblyaiuseuuseu
speechmaticseu1eu2us1us2au1同上
sonioxuseujp同上
elevenlabsglobaluseuin

プロバイダーが対応していないリージョンを指定すると、後になって予期せぬ問題が発生するのではなく、bot作成時に許可されている値の一覧とともに400エラーが返されます。GladiaのバッチAPIはグローバル専用であるため、バッチ設定でregionprovider: "gladia"を指定するとリジェクトされます。なお、ライブAPIにはリージョンが存在します。

regionをnullのままにすると、適切なデフォルトが自動的に選択されます。DeepgramとAssemblyAIにはeu、Speechmaticsにはeu1、Sonioxにはusが使用されます。

音声データを特定の管轄区域外に出さない必要がある場合は、独自ストレージの持ち込みと組み合わせてご利用ください。プロバイダーはバケット上の署名付きURLから音声を取得するため、バケットの場所とプロバイダーのリージョンの両方が、音声データの実際の転送先を決定します。

独自キーの持ち込み

api_keyを渡すと、当社のアカウントではなく、そのプロバイダーにおけるお客様のアカウントを使用します。

{
  "transcription_config": {
    "provider": "deepgram",
    "region": "eu",
    "api_key": "your-deepgram-key"
  }
}

キーはAES-256-GCMで暗号化してから保存され、botへの転送中も暗号化されたままです。botは使用時点で復号します。botのデータを削除すると、保存されたキーは上書きされます。

使用する理由は2つあります。1つ目はコストです。当社のキーでの文字起こしは1時間あたり0.25トークン、お客様のキーでは0.05トークンで請求されます。2つ目は、お客様自身のアカウントでのみ利用できる機能があることです。たとえば、トレーニング済みのカスタム語彙や、当社では対応していない契約条件などが該当します。

BYOKはPay as You Goを含むすべてのプランで利用可能です。transcription_configにプロバイダーのAPIキーを渡すだけで、プランのアップグレードは不要です。

プロバイダーオプションの直接パススルー

私たちは意図的に正規化されたオプション層を構築しませんでした。各プロバイダーには他のプロバイダーにはない独自の機能があり、共通の最小公倍数に平坦化すると、そのプロバイダーを選んだ理由が失われてしまいます。

custom_paramsは、記述した内容をほぼそのままプロバイダーに渡します。

{
  "transcription_config": {
    "provider": "speechmatics",
    "region": "eu2",
    "custom_params": {
      "transcription_config": {
        "language": "en",
        "diarization": "speaker",
        "operating_point": "enhanced"
      }
    }
  }
}

ドット記法も使用できます。構築しやすい場合はこちらをご利用ください。

{ "custom_params": { "diarization_config.min_speakers": 2 } }

ライブ設定では、バリデーション前にアンフラット化されます。そのため、プロバイダーが実際に受け取る形状に対してバリデーションが行われます。バッチ設定では、フラットキーが記述どおりにバリデーションされ、送信時に後からアンフラット化されます。

ライブ設定では、pipelineによって設定され、送信するとリジェクトされるフィールドが4つあります。encodingsample_ratebit_depthchannelsです。サンプルレートは特に重要で、ミーティング音声からプロバイダーごとにネゴシエーションされるため、上書きするとストリームが壊れます。代わりにstreaming_config.audio_frequencyを使用してください。

話者分離はデフォルトでオンになっています。これは、オフにするとスピーカーラベルのないテキストの塊になるためであり、また少なくとも1つのプロバイダーでは明示的に要求しない限り、発話が一切返されない場合があるためです。custom_paramsに明示的な値を指定するとそちらが優先されます。

注意点:バッチとライブでは形状が異なります

これは半日を無駄にしがちなポイントなので、明確に述べておきます。同じプロバイダーであっても、ライブAPIとバッチAPIでは受け付けるパラメーターの形状が異なります。

Gladiaが最もわかりやすい例です。バッチでは翻訳設定をトップレベルで指定します。ライブではrealtime_processingの下にネストする必要があります。

{
  "streaming_config": {
    "mode": "transcription",
    "output_url": "wss://your-app.example.com/transcripts",
    "audio_frequency": 24000,
    "transcription": {
      "provider": "gladia",
      "region": "eu-west",
      "api_key": "your-gladia-key",
      "custom_params": {
        "language_config": { "languages": ["ru"] },
        "realtime_processing": {
          "translation": true,
          "translation_config": { "target_languages": ["en"] }
        }
      }
    }
  }
}

ライブパラメーターはstrictモードでバリデーションされます。ライブセッションAPIは未知のキーを即座にリジェクトするため、ミーティング中に失敗するよりもbot作成時に失敗させた方が適切だからです。1階層下に属するキーを送信した場合、エラーメッセージで正しい位置が示されます。

'translation' is not a top-level field of the gladia live API —
did you mean 'realtime_processing.translation'?
(the live API shape differs from batch)

バッチとライブの両パラメーターは、bot作成時に各プロバイダー固有のスキーマに対してチェックされます。そのため、タイプミスは1時間後の文字起こし失敗ではなく、即座に400として返されます。ただし、厳密さには2つの注意点があります。バッチパースは寛容なため、未知のバッチキーはバリデーションを通過し、プロバイダーに転送されます。未知のキーをリジェクトするのはライブのみです。また、ElevenLabsのライブパラメーターは、チェック対象となる公開スキーマが存在しないため、バリデーションなしにパススルーされます。

ライブ出力

mode: "transcription"を使用すると、プロバイダーセッションを開き、ミーティング音声を供給し、イベントをJSONとしてoutput_urlに転送します。

{
  "event": "transcript.segment",
  "bot_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "text": "so the migration lands Thursday",
    "isFinal": true,
    "utteranceStart": 12.44,
    "utteranceEnd": 14.91,
    "confidence": 0.97,
    "speaker": { "name": "Alice", "id": 1 },
    "words": []
  }
}

また、使用されたプロバイダーのsession.started、要求した場合のtranslation、そしてerrorも含まれます。中継機器によるアイドル状態のソケット切断を防ぐため、30秒ごとにpingを送信します。

1つの制約があります。当社のプラットフォームキーでのライブセッションは、現在Gladiaのみを含む管理されたプロバイダーセットに限定されています。ライブ文字起こしに他のプロバイダーを使用する場合はBYOKキーが必要であり、ミーティング開始時ではなくbot作成時にFST_ERR_STREAMING_TRANSCRIPTION_KEY_UNAVAILABLEとしてリジェクトされます。

考えを変えたい場合

POST /v2/bots/:bot_id/retranscribe
{
  "transcription": {
    "provider": "assemblyai",
    "region": "eu",
    "api_key": "your-assemblyai-key"
  }
}

保存された音声が別のプロバイダーに再送信され、botの設定が更新されます。これにより、デモ音声ではなくご自身のミーティングで2つのベンダーをA/Bテストしたり、失敗した文字起こしをリカバリしたりすることができます。

botのデータを削除すると、?delete_from_provider=true(デフォルト)を使用してプロバイダーからもトランスクリプトが削除されます。独自キーを提供した場合はそのキーが使用されます。

プロバイダーに障害が発生した場合

送信に失敗した場合は、5秒後と15秒後に2回リトライされ、合計3回試行されます。リトライによって解決する可能性がある場合のみ対象となります。具体的には、rate limit、5xx、接続・ポーリングタイムアウト、ネットワークレベルの障害、およびプロバイダーがジョブIDを含まないbodyで2xxを返した場合です。認証エラー、無効な入力、サポートされていない操作は、2回目も同様に失敗するためリトライされません。

各リトライでは、再送信前にcallbackのシークレットが更新されます。これにより、実際の競合状態を防ぎます。プロバイダーがジョブを受け付けたが、そのレスポンスが当社側でタイムアウトした場合、そのcallbackは既に存在しないシークレットに対して届くためリジェクトされます。これにより、リトライされたジョブと競合して1つのチャンクに対して2つのトランスクリプトが生成される事態を回避できます。

**第2のプロバイダーへの自動フェイルオーバーはありません。**これは、インシデント中に発覚するより、明確に伝えておく方が良いと判断しています。選択したプロバイダーがリトライ後も失敗した場合、botはfailedTRANSCRIPTION_FAILEDとともに終了しますが、録画と音声アーティファクトはすべて保持されています。リカバリはretranscribeの呼び出しで行い、必要であれば別のプロバイダーを指定できます。プロバイダーを暗黙的に切り替えることは、同意していない管轄区域へのトランスクリプト送信や、同意していない料金の発生を意味するため、この判断はお客様に委ねています。

関連情報

関連ブログtranscription