
10,390 文字

皆さん、こんにちは。リアルタイムAPIのブレイクアウトセッションへようこそ。私はAPIチームでリアルタイムAPIを担当しているエンジニアのマークです。そして私はカタで、デベロッパーエクスペリエンスチームの一員です。
数週間前、私たちはリアルタイムAPIのパブリックベータを発表しました。これにより初めて、単一のAPIで自然な低遅延の音声対話を実現したアプリケーションを構築することが可能になりました。2020年に最初のAPIをリリースした時は、テキストのみに限られていましたが、その後APIをマルチモーダル化し、音声の文字起こし、画像認識、テキスト音声変換をサポートするようになりました。
新しいリアルタイムAPIでは、さらに一歩進んで、これらの機能を単一のAPIに統合し、音声を直接理解できるモデルを実現しました。このリリース以降、開発者の皆さんは本当に印象的なものを作り出しています。アバターから音声によるウェブブラウジング、さらには音声によるペイントまで。また、企業も言語学習やヘルスコーチング、IDEでの音声制御など、自社アプリケーションでの音声体験にリアルタイムAPIを活用し始めています。
リアルタイムAPIをリリースする前は、音声対話を実現するには異なるモデルを組み合わせ、その周りに複雑なソリューションを構築する必要がありました。そのため、スムーズで自然な会話の流れを作り出すのは本当に困難でした。
リアルタイムAPIを使用しない場合、異なるモデルを組み合わせる必要があり、入力から最終出力までに複数のステップを考慮しなければなりません。まず、ユーザーの発話をキャプチャする必要があります。これには、話している時に押すボタンを用意するか、発話が終わったことを自動検出する必要があります。その後、音声を取得し、Whisperモデルを使用する文字起こしAPIなどで処理する必要があります。
次に、テキストが出力され、それをGPT-4などの言語モデルで処理して応答を生成します。最後のステップは音声の生成で、これには私たちのテキスト音声変換モデルなど、第三のモデルが必要です。
このフローの各ステップは前のステップの出力に依存しているため、全体的なプロセスが遅くなるだけでなく、自然な会話の中断に十分な速さで反応することができません。また、キャプチャされた音声は詳細やニュアンスを失ってしまいます。モデルに何かが「どのように聞こえるか」を伝えるようなもので、モデル自体が直接聞くわけではありません。これにより、自然で流動的な会話体験を構築することが非常に困難になっていました。
リアルタイムAPI以前は、GPT-4の機能の一部がまだAPIで利用できませんでした。最も注目すべきは、音声を直接理解し生成する能力です。これは、モデルが理解するためにその他のモダリティをテキストに変換する必要がないことを意味します。音声入力をテキストと同様に処理でき、最初にテキストを生成することなく直接音声を生成することもできます。
インタラクションを複数のステップに分割する必要がないため、はるかに低遅延でリアルタイムに処理することができます。実際、これはChat GPTの高度な音声モードを支えている同じモデル機能です。
デモを見てみましょう。
「今週末、天気が良さそうなので、外で何か楽しいことができないでしょうか?」
「ベイエリアを探索するのに絶好の機会ですね。ミュアウッズでハイキングを楽しんだり、ゴールデンゲートブリッジを望むクリシーフィールドでピクニックをしたり、ハイウェイ1号線をドライブして海岸線を探索したりできます。これらはいかがでしょうか?」
「素晴らしいですね。シーニックドライブのアイデアが気に入りました。どのルートを取ればいいですか?」
「ハイウェイ1号線は素晴らしい選択です。」
はい、Chat GPTの高度な音声モードは素晴らしい体験です。皆さんも試してみる機会があったと思います。現在、ヨーロッパ全域で利用可能です。さらに興味深いのは、リアルタイムAPIを使用することで、同じ機能にAPIからアクセスできるようになったことです。つまり、同じような体験を自分のアプリケーションで構築し、使用することができるのです。
数週間前、私たちはリアルタイムAPIをベータ版としてリリースしました。このAPIは、まさにこのような低遅延のマルチモーダル体験を自分のアプリケーションで実現できるように設計されています。ベータリリースは、単一のインターフェースで全てのモダリティをサポートするための重要な第一歩です。現在は音声、テキスト、ファンクションコーリングをサポートしており、将来的にはこのAPIにさらなる機能を追加していく予定です。
このセッションの残りの部分では、まず、リアルタイムAPI以前と以後で、このような音声体験を構築することがどのように変化したかのデモをお見せします。次に、ライブコーディングを行い、今日からどのように構築を始められるかをお見せします。最後に、リアルタイムAPIをアプリケーションに統合する方法のデモをお見せします。
では、リアルタイムAPI以前の音声アシスタントアプリの作り方を見てみましょう。カタのラップトップには、いくつかの異なるシステムを組み合わせて実装した小さな例があります。先ほど説明したように、音声の文字起こし、言語モデル、音声生成が必要です。これらには、OpenAIのWhisper、GPT-4、テキスト音声変換APIを使用できます。
「はい、私のラップトップには従来の方法で構築された音声アシスタントがあります。マークが説明したように、3つの異なるステップがあり、何かを質問すると、画面上で異なるステップが実行されているのが分かります。準備はできていますか?」
「はい」
「分かりました。メールの送信を取り消すにはどうすればいいですか?」
「テキストの応答を生成中です…音声を生成中です…これは少し不自然になってきましたが、メールの送信を取り消す必要がある場合、使用しているメールサービスによってプロセスが異なります。」
「はい、ありがとうございます。一般的な…」
「そこで止めておきましょう。遅すぎますが、ご理解いただけたと思います。これは機能しますが、重要なことを見逃しています。役に立つには応答が遅すぎました。カタ、そのメールはあまり刺激的ではなかったことを願います。」
では、今度はリアルタイムAPIで実装した同様のものを見てみましょう。
「はい、このボイスアシスタントのアップグレード版があります。今回は個別のステップはなく、すべてが同時に発生します。試してみて、違いを確認しましょう。」
「聞こえますか?」
「はい、はっきり聞こえます。今日はどのようにお手伝いできますか?」
「私はここDevDayで素晴らしいビルダーたちの群衆と一緒にいます。彼らに挨拶をして、私たちがどれだけ興奮しているかを伝えてください。」
「こんにちは、DevDayのビルダーの皆さん!皆さんとつながれることは素晴らしいです。このイベントの一部となれることに興奮していますし、皆さんが生み出す素晴らしいイノベーションを楽しみにしています。今日は一緒に魔法を起こしましょう!」
「聞こえましたね。実は私はパリから来て、ユーロスターで来たのですが、もう少しホームシックを感じています。今度はフランス語で挨拶をしてもらえませんか?」
「素晴らしい、ありがとうございます。そして比較のために、メールの送信を取り消す方法を教えてください。」
「メールの送信を取り消すには、メールサービスによって異なります。私はGmailを使用していますが、Gmailでは「送信取り消し」機能を使用してメールを取り消すことができます。」
「素晴らしい、ありがとうございます。」
[拍手]
これは大きな改善です。GPT-4のネイティブな音声機能を使用して、直接音声から音声へと変換しています。つまり、待つ必要がなく、通常のTTSと比べて音声がどれだけ表現豊かになっているかを聞くことができます。実際、リアルタイムAPIをリリースしてから数週間、私たちは音声をさらにダイナミックにすることに取り組んできました。
そこで本日、アプリケーションで使用できる5つの新しいアップグレードされた音声をリリースします。簡単な比較として、リリース時の音声と、現在利用可能な音声のいくつかを聞いてみましょう。
「人間の声は最も美しい楽器だが、演奏するのが最も難しい」とリヒャルト・シュトラウスは言いました。しかし、マヤ・アンジェロウによれば、「何を言うかではなく、どのように言うかが重要なのです」。言葉には信じられないほどの力があり、人々の心を高めることも、痛めつけることもできます。マーティン・ガースは言いました。そして、ジョージ6世が国民にリアルタイムで語りかけた時、「私は国内外のすべての家庭に、この言葉を送ります。それは、私が直接あなたの家を訪れてお話しできるかのように、一人一人に対して同じ深い感情を込めて語られています。」
もちろん、モデルは音声を直接理解するため、システムメッセージを使用してこれらの音声の感情やトーンを必要に応じて調整することができます。
「コードの仕組みを見ていきましょうか?」
「そうしましょう。」
リアルタイムAPIは、V1/realtimeという新しいエンドポイントを公開しています。アプリケーションはWebSocketで接続を維持し、サーバーとJSONフォーマットのメッセージを交換します。これらのメッセージには、テキスト、音声、ファンクションコールを含めることができます。WebSocketトランスポートにより、ステートフルな接続を維持できることが、ここでのリアルタイム性の鍵となります。
音声を含むユーザー入力をリアルタイムでリアルタイムAPIにストリーミングでき、モデルからの出力は生成されると同時にストリーミングで返されます。では、これがどのように機能するかをよりよく説明するためにいくつかのデモを見ていきましょう。
「はい、実際に何かを作ってみましょう。先ほど見たような簡単な例から始めてみてはどうでしょうか。マーク、実際にこれをどのように構築するか説明してもらえますか?」
「いいですね。」
「では小さく始めて、概念をより簡単に説明するために、ブラウザのWebSocket APIを使用してリアルタイムAPIに直接接続するフロントエンドのWebアプリケーションを構築していきます。ここに基本的なHTMLファイルがあり、ブラウザのオーディオAPIを扱うためのユーティリティをいくつか含めています。それ以外には、今はボタンがあるだけで、ヘルパーをいくつかセットアップしているだけです。」
Webページに移動してStartをクリックしても、まだコードを書いていないので当然何も起こりません。では、コードを書いていきましょう。
まず、リアルタイムAPIへの接続を開きます。新しいWebSocketを作成し、APIのURLを指定し、モデルも渡します。このカスタムヘッダーを使用してAPIキーを渡していることに注目してください。これは本番アプリケーションには適していませんが、APIをブラウザで直接ローカルに試験的に使用し始めるには最適です。これを念頭に置いて構築を始めてください。
WebSocket接続を作成したので、次はリアルタイムAPIからのメッセージを処理し始めます。onMessageハンドラーを定義し、APIから返されるメッセージはJSONなので、メッセージをJSONとしてパースします。メッセージにはそれぞれタイプがあり、この場合、私たちが関心があるのは、response.audio.deltaメッセージです。このメッセージは、モデルが音声で応答する際にサーバーから送り返されます。
メッセージタイプで分岐し、response.audio.deltaメッセージを受け取ったときは、音声をbase64デコードし、それをWaveStreamPlayerユーティリティクラスにパイプして、スピーカーから音声を再生します。ここで返される音声はPCM1 16、つまり24kHzのWAVEであることに注意してください。APIはG.711もサポートしているので、異なるコーデックの使用方法に興味がある場合は、ドキュメントを参照してください。
これでモデルから返される音声の処理が完了しました。次は、自分の音声を取得してリアルタイムAPIに送信する処理を行います。WebSocket接続のonOpenハンドラーを追加し、まずマイクを使って録音を開始します。ユーティリティクラスでコールバックを登録すると、マイクを通じて音声が入力されるたびに、その音声を取得してinput.audiobuffer.appendというメッセージにパッケージ化し、base64エンコードしてリアルタイムAPIに送信します。
モデルからの出力の処理と、自分の音声の送信の両方を処理したので、これで会話を始めるには十分なはずです。切り替えて試してみましょう。
「聞こえますか?」
「はい、はっきりと聞こえます。今日はどのようにお手伝いできますか?」
「今、観客の皆さんにデモをしているところなので、挨拶をしてもらえますか?」
「こんにちは、皆様。お会いできて光栄です。ご質問やお知りになりたいことがございましたら、お手伝いさせていただきます。」
「素晴らしい。」
数行のコードで音声から音声への変換アプリケーションが動作しましたが、APIのさらなる機能をお見せしましょう。デフォルトでは、リアルタイムAPIは新しいセッションを開始すると、私たちが話し終わると自動的に応答しますが、まだ中断を適切に処理していません。
リアルタイムAPIからの応答は実際にはリアルタイムよりも速く返ってきます。APIはできる限り早くモデルの応答を返し、私たちはその応答をバッファリングしてローカルで再生します。中断を自然に感じさせるためには、ユーザーが話し始めたときにモデルの出力をスピーカーでの再生を停止する必要があります。
リアルタイムAPIは音声が開始されたことを検知するためのイベントを送信してくれるので、それを使用してロジックを組み立てることができます。では、それを実装してみましょう。
今度は異なるメッセージタイプを処理します。このメッセージタイプはinput.audiobuffer.speech.startedと呼ばれ、サーバーがユーザーの発話開始を検知したときに送信されます。ユーザーが話し始めたら、現在再生中のモデル出力音声を中断します。ヘルパーはこのオフセットを返してくれます。このオフセットは既に再生された音声の長さで、これをAPIに送り返します。
これを行う理由は、モデルにちょうどどこで中断したかを正確に知らせるためです。リアルタイムで音声が送られてくるので、実際に話し始めたときにどこまで再生されていたかをモデルに知らせる必要があります。これを全て配線するには、もう少しメタデータが必要です。今からそれを追加します。
current_item_idとcontext_content_indexが必要で、これで中断を望み通りに機能させるために必要なものが揃いました。試してみましょう。
「聞こえますか?」
「はい、聞こえます。どのようにお手伝いできますか?」
「ロンドンで訪れるべき興味深い場所を5つ教えてください。」
「もちろんです。ロンドンには魅力的なスポットがたくさんあります。興味深い場所を5つご紹介しましょう。大英博物館は、膨大なアート・コレクションを…」
「それは興味深いですね。それはどこにありますか?」
「大英博物館はロンドンのブルームズベリー地区、グレート・ラッセル・ストリートにあります。トッテナム・コート・ロード駅やホルボーン駅から地下鉄で簡単にアクセスできます。」
モデルを中断して、それがどこにあるのか尋ねることができ、再生された音声の量に基づいて、大英博物館について尋ねていることをモデルは理解していたことがわかります。
このシンプルなデモでは、音声アシスタントをゼロから作成し、単一のファイルで音声と中断の基本的な処理を導入しました。APIを最もシンプルな形で示すために、バニラのフロントエンドJavaScriptを使用しましたが、もちろん本番アプリケーションをこのように構築することはありません。
では、この新しいAPIが実際のユースケースにどのように適合するか見てみましょう。カタ、説明してもらえますか?
「はい、もちろんです。実際に例を用意してあります。宇宙について学ぶための家庭教師アプリを作りたいと思います。私は宇宙は魅力的な分野だと思っているからです。ユーザーが宇宙について何でも質問できるようにしたいのですが、楽しいものにしたいと思います。シンプルなチャットインターフェースでもいいのですが、そこに何の面白みがあるでしょうか?2024年なので、もう少し没入感のあるものにできると思います。」
「そこで、このアプリケーションを用意しました。画面に表示されるまで少々お待ちください。これは太陽系の3Dビューです。これはフロントエンドだけで、バックエンドではマークが説明したようにリアルタイムAPIをセットアップしましたが、今回は実際のアプリケーションの一部として使用しています。試してみましょう。」
「太陽系で一番大きな惑星は何か教えてください。」
「もちろんです。太陽系で最も大きな惑星は木星です。他のすべての惑星を合わせた質量の2倍以上もあります。木星は巨人の中の巨人なのです。」
「素晴らしい。リアルタイムの対話が機能していて、これは学習にはより楽しい方法だと思いますが、もう少し対話的にできないか見てみましょう。」
「地球について知りたいのですが。」
「もちろんです。地球は太陽からの距離が3番目の惑星で、生命を支えることが知られている唯一の惑星です。多様な生態系、豊富な水、有害な太陽放射線から私たちを守る保護大気層を持っています。地球の特徴についてもっと知りたいですか?」
「そうですね、水がたくさんあるように見えますが、陸地と水の割合を教えてください。」
「はい、地球の表面の約71%が水で覆われており、残りの29%が陸地です。私たちの青い大理石は、まさにその名に恥じない姿です。円グラフでお見せしましょう。これが地球の表面の内訳です。」
「ありがとうございます。実は火星について質問があります。」
「赤い惑星・火星についてどんなことを知りたいですか?」
「火山がたくさんあると聞いたのですが、一番大きな火山について教えてください。」
「はい、火星にある、そして太陽系全体で最も大きな火山はオリンポス山です。高さは約13.6マイルで、エベレスト山の約3倍です。オリンポス山についてもっと情報が欲しいですか?」
「はい、3つの最も大きな火山とその高さを教えてください。」
「もちろんです。火星の3つの最大の火山は、1位がオリンポス・モンス(高さ13.6マイル、22キロメートル)、2位がアスクレウス・モンス(約11.3マイル、18.1キロメートル)、3位がアルシア・モンス(11.2マイル、18キロメートル)です。」
「ありがとうございます。新しいことを学べました。」
「素晴らしい。では、ここで何が起こったのか説明しましょう。リアルタイムで質問をして回答を得られただけでなく、画面上でもいくつかのインタラクションが起こっているのを見ました。特定の惑星について尋ねると、その惑星を近くで見るようにズームインし、データで答えられる質問をすると、画面上にグラフが表示されました。」
「これはどのように可能なのでしょうか?マークが説明したように、リアルタイムAPIはツールコールをサポートしています。私は実際にモデルが使用できるいくつかのツールを定義しました。特定の惑星について話すときに呼び出されるfocus_planetツールがあり、これは惑星名をパラメータとして取ります。また、display_dataツールもあります。アイデアとしては、データで答えられることについて、モデルが最も適切なチャートを選択し、タイトルと表示すべきデータポイントを決定するというものです。」
「これは既にツールコールのかなりクールな使い方です。アプリケーションでインタラクションをトリガーし、対話型アプリを作ることができます。しかし、時にはモデルにデータを送り返して、それを声に出して言わせる必要もあるかもしれません。それをどのように行うか見てみましょう。」
「ここにAPIコールがあり、これは国際宇宙ステーションの現在位置をリアルタイムで取得するエンドポイントを呼び出します。緯度と経度を返し、fetch_iss_positionという関数があり、これはそのエンドポイントを呼び出してレスポンスを取得します。また、show_issというツールを定義しており、このツールがモデルによってトリガーされると、fetch_iss_position関数を呼び出し、その位置をモデルに送り返します。実際に動作するところを見てみましょう。」
「地球に戻れますか?」
「もちろんです。私たちの故郷である地球に戻ってきました。何を探索したいですか?」
「現在のISSの位置を教えてください。」
「国際宇宙ステーション(ISS)は現在、南半球の上空、緯度マイナス35.6度、経度マイナス32.61度付近に位置しています。私たちの美しい惑星の周りを常に周回しています。他に何かお手伝いできることはありますか?」
「素晴らしい。実際、現在の位置をどのようにして知ることができるのですか?」
「私はリアルタイムデータにアクセスできるので、ISSが地球の周りを周回する際の現在位置を追跡することができます。この情報は頻繁に更新され、約90分ごとに惑星を周回するステーションの正確な位置を提供します。」
「素晴らしいですね。他に何かお手伝いできることはありますか?」
「はい、とても素晴らしいですね。これで、モデルにリアルタイムでデータを供給して、ユーザーとの会話で使用する方法がわかりました。」
「最後の質問です。冥王星を見せてもらえますか?」
「はい、聞いたところによると、もはや惑星ではないそうですね。」
「その通りです。冥王星は2006年に国際天文学連合によって準惑星に再分類されました。主な理由は、惑星としての基準をすべて満たしていなかったためで、特に軌道上の他の破片を一掃できていないことが挙げられます。とはいえ、冥王星は独自の特徴を持つ魅力的な天体であり続けています。他に何か知りたいことはありますか?」
「衛星があると聞きましたが、それらは何ですか?」
「ありがとうございます。」
モデルがここで行っているのを見てみると、show_moonsツールを呼び出し、冥王星の衛星を引数として渡しています。これは小さな配列ですが、大きな配列をパラメータとして持つ場合や、パラメータのリストが長い場合、ツールコールが完了する前にリアルタイムでストリーミングして表示したり、ユーザーに知らせたりすることができます。これは情報をリアルタイムで使用する非常に便利な方法です。
リアルタイムAPIを使って、音声で対話でき、ツールの使用のおかげで視覚的にも反応する没入型アプリを実際に構築しました。これがいくつかのアイデアになれば良いと思います。皆さんがどのようなものを作り出し、新しい魅力的なユーザー体験を生み出すために境界を押し広げていくのか、とても楽しみです。
リアルタイムAPIのデモをいくつか見ていただいたので、低遅延の音声対話アプリケーションに向けた新しい可能性を開くものだとご理解いただけたと思います。これはGPT-4のネイティブなマルチモーダル機能を活用する新しい方法であり、ファンクションコーリングのサポートにより、アプリケーションに深く統合することが可能です。
基調講演でお話ししたように、本日からリアルタイムAPIの使用コストを削減します。これは、テキストと音声入力に対してプロンプトキャッシングを実装したことで実現できました。つまり、キャッシュにヒットするテキスト入力のコストは50%削減され、チャット完了のテキストのみの入力に対するプロンプトキャッシングと同様に、キャッシュにヒットする音声入力のコストは80%削減されます。
典型的な15分の会話では、リリース時と比べて現在では30%のコスト削減が期待できます。新しいものを構築する場合でも、スケールアウトする場合でも、コストが重要な要素であることを私たちは理解しています。これを提供できることを大変嬉しく思います。
まだご覧になっていない方は、ぜひドキュメントと構築を始めるための追加リソースをチェックしてください。私たちはリアルタイムインタラクションの可能性に大変興奮しています。これはネイティブにマルチモーダルとなるように構築された新世代の製品の始まりに過ぎません。音声対話は最初のステップに過ぎませんが、将来的にはこのAPIで最先端モデルのネイティブな機能のロックを解除することを楽しみにしています。皆さんがこれを使って何を構築するのか、とても楽しみです。ありがとうございました。
コメント