驚き!これは、最近まとめた AI for Web Devs シリーズのボーナス ブログ投稿です。まだこのシリーズを読んでいない方は、ぜひ読んでみてください
この投稿では、既存のプロジェクト アーキテクチャと、アプリケーション開発者とエンド ユーザーの両方のためにそれを改善する方法について説明します。
いくつかの一般的な概念について説明し、例では特定の Akamai 製品を使用します。
既存のアプリケーションは非常に基本的なものです。ユーザーが 2 人の対戦相手を提出すると、アプリケーションは、AI が生成した、戦いでどちらが勝つかという応答をストリーミングで返します。
アーキテクチャもシンプルです。
クライアントはサーバーにリクエストを送信します。
サーバーはプロンプトを構築し、そのプロンプトを OpenAI に転送します。
OpenAI はストリーミング応答をサーバーに返します。
サーバーは必要な調整を行って、ストリーミング応答をクライアントに転送します。
Akamai のクラウド コンピューティング サービスを利用していました (以前は
🤵 は高級レストランのサーバーのように見え、👁️🗨️ は「目」、つまり AI です。笑
技術的にはこれで問題なく動作しますが、特にユーザーが重複したリクエストを行った場合に問題がいくつかあります。応答をサーバーに保存し、固有のリクエストに対してのみ OpenAI にアクセスする方が、より速く、よりコスト効率が高い可能性があります。
これは、すべてのリクエストが非決定的である必要はない (同じ入力が異なる出力を生成する) ことを前提としています。同じ入力が同じ出力を生成しても問題ないと仮定しましょう。結局のところ、戦いでどちらが勝つかという予測はおそらく変わらないでしょう。
OpenAI からの応答を保存したい場合、2 つの対戦相手を使用して迅速かつ簡単に検索できる、ある種のデータベースに応答を保存するのが現実的な場所です。こうすることで、リクエストが行われたときに、最初にデータベースをチェックできます。
クライアントはサーバーにリクエストを送信します。
サーバーは、ユーザーの入力と一致するデータベース内の既存のエントリを確認します。
以前のレコードが存在する場合、サーバーはそのデータで応答し、リクエストは完了します。次の手順はスキップしてください。
そうでない場合、サーバーは前のフローのステップ 3 に従います。
応答を閉じる前に、サーバーは OpenAI の結果をデータベースに保存します。
点線はオプションのリクエストを表しており、💽 はハードディスクのように見えます。
この設定では、重複したリクエストはデータベースによって処理されます。 OpenAI リクエストの一部をオプションにすることで、ユーザーが経験する遅延の量を削減できる可能性があり、さらに API リクエストの数を減らすことでコストを節約できます。
特にサーバーとデータベースが同じリージョンに存在する場合、これは良いスタートです。 OpenAI のサーバーにアクセスするよりも応答時間が大幅に短縮されます。
ただし、アプリケーションの人気が高まるにつれて、世界中からユーザーを獲得し始める可能性があります。データベースの検索が高速になるのは素晴らしいことですが、飛行時間による遅延がボトルネックになっている場合はどうなるのでしょうか?
私たちは、物事をユーザーに近づけることで、この懸念に対処できます。
「エッジ」という用語にまだ慣れていない方は、この部分が混乱するかもしれませんが、簡単に説明してみます。エッジとは、可能な限りユーザーに近いコンテンツを指します。人によっては、それは IoT デバイスや携帯電話の塔を意味するかもしれませんが、Web の場合、標準的な例は次のとおりです。
詳細は省きますが、CDN は、ネットワーク内の最も近いノードからのユーザー要求に応答できる、グローバルに分散されたコンピューターのネットワークです (
エッジ コンピューティングを使用すると、多くのバックエンド ロジックをユーザーのすぐ近くに移動でき、コンピューティングにとどまりません。ほとんどのエッジ コンピューティング プロバイダーは、同じエッジ ノード内にある種の最終的に整合性のあるキーと値のストアも提供します。
それは私たちのアプリケーションにどのような影響を与えるでしょうか?
クライアントはリクエストをバックエンドに送信します。
エッジ コンピューティング ネットワークは、リクエストを最も近いエッジ ノードにルーティングします。
エッジ ノードは、ユーザーの入力に一致するキー/値ストア内の既存のエントリを確認します。
以前のレコードが存在する場合、エッジ ノードはそのデータで応答し、リクエストは完了します。次の手順はスキップしてください。
そうでない場合、エッジ ノードはリクエストをオリジン サーバーに転送し、オリジン サーバーはそのリクエストを OpenAI に渡して、ヤッダ ヤッダ ヤッダとします。
応答を閉じる前に、サーバーは OpenAI の結果をエッジ キー/値ストアに保存します。
エッジ ノードは青いボックスで、エッジがあるため 🔪 で表されます。EdgeWorker は 🧑🏭 で表される Akamai のエッジ コンピューティング製品であり、EdgeKV は 🔑🤑🏪 で表される Akamai の Key-Value ストアです。エッジ ボックスは、物理的な距離を表すために、クラウド内のオリジン サーバーよりもクライアントに近くなります。
オリジンサーバーはここでは必ずしも必要ではないかもしれませんが、存在する可能性の方が高いと思います。データ、コンピューティング、ロジック フローの点で、これは以前のアーキテクチャとほとんど同じです。主な違いは、以前に保存された結果がユーザーのすぐ近くに存在し、ほぼ即座に返せることです。
(注: データはエッジでキャッシュされていますが、応答は依然として動的に構築されます。動的応答が必要ない場合は、オリジン サーバーの前で CDN を使用し、正しい HTTP ヘッダーを次のように設定する方が簡単かもしれません。応答をキャッシュします。ここには多くのニュアンスがあるので、もっと言いたいことはありますが…まあ、疲れているのであまり言いたくありません。ご質問がございましたら、お気軽にお問い合わせください。)
さあ、料理中です!重複したリクエストはほぼ即座に応答され、不要な API リクエストも節約されます。
これでテキスト応答のアーキテクチャが整理されましたが、AI によって生成された画像もあります。
今日最後に検討するのは画像です。画像を扱う場合は、配送と保管について考慮する必要があります。 OpenAI の人々は独自のソリューションを持っていると思いますが、セキュリティ、コンプライアンス、または信頼性の理由からインフラストラクチャ全体を所有したいと考えている組織もあります。 OpenAI を使用する代わりに、独自の画像生成サービスを実行する場合もあります。
現在のワークフローでは、ユーザーは最終的に OpenAI に到達するリクエストを作成します。 OpenAI は画像を生成しますが、それを返しません。代わりに、OpenAI のインフラストラクチャでホストされている画像の URL を含む JSON 応答を返します。
この応答では、URL を使用して<img>
タグをページに追加できます。これにより、実際の画像に対する別のリクエストが開始されます。
独自のインフラストラクチャでイメージをホストしたい場合は、それを保存する場所が必要です。イメージをオリジン サーバーのディスクに書き込むこともできますが、ディスク容量がすぐに使い果たされてしまい、サーバーをアップグレードする必要があり、コストがかかる可能性があります。
これでストレージの問題は解決しましたが、オブジェクト ストレージ バケットは通常、単一のリージョンにデプロイされます。これは、データベースにテキストを保存する際に発生した問題を反映しています。 1 つのリージョンがユーザーから遠く離れている場合があり、これにより大幅な遅延が発生する可能性があります。
すでにエッジを導入しているため、静的アセットのみに CDN 機能を追加するのは非常に簡単です (率直に言って、すべてのサイトに CDN が必要です)。構成が完了すると、CDN は最初のリクエストでオブジェクト ストレージから画像を取得し、同じリージョン内の訪問者からの今後のリクエストに備えてキャッシュします。
画像のフローは次のようになります。
クライアントは、対戦相手に基づいて画像を生成するリクエストを送信します。
エッジ コンピューティングは、そのリクエストの画像データが既に存在するかどうかを確認します。存在する場合は、URL を返します。
画像は URL とともにページに追加され、ブラウザーは画像を要求します。
画像が以前に CDN にキャッシュされていた場合、ブラウザーはその画像をほぼ即座に読み込みます。これで流れは終わりです。
イメージが以前にキャッシュされていない場合、CDN はオブジェクト ストレージの場所からイメージをプルし、今後のリクエストに備えてそのコピーをキャッシュし、イメージをクライアントに返します。これは流れのもう一つの終端です。
画像データがエッジの Key-Value ストアにない場合、画像を生成するリクエストはサーバーに送られ、OpenAI に送られ、OpenAI が画像を生成して URL 情報を返します。サーバーは、イメージをオブジェクト ストレージ バケットに保存するタスクを開始し、イメージ データをエッジ キー/値ストアに保存し、イメージ データをエッジ コンピューティングに返します。
新しいイメージ データを使用して、クライアントは新しいリクエストを作成するイメージを作成し、上記のステップ 5 から続行します。
コンテンツ配信ネットワークは配送トラック (🚚) とネットワーク信号 (📶) で示され、オブジェクト ストレージは箱の中の靴下 (🧦📦)、またはストレージ内のオブジェクトで示されます。これらは明らかだと思うので、このキャプションはおそらく必要ありませんが、私は自分の絵文字ゲームを誇りに思っているため、検証が必要です。楽しませてくれてありがとう。続ける。
この最後のアーキテクチャは、確かにもう少し複雑ですが、アプリケーションが深刻なトラフィックを処理する場合は、検討する価値があります。
右に!これらすべての変更を適切に実施し、固有のリクエストに対して AI が生成したテキストと画像を作成し、重複したリクエストに対してエッジからキャッシュされたコンテンツを提供します。その結果、応答時間が短縮され、ユーザー エクスペリエンスが大幅に向上します (さらに、API 呼び出しが減ります)。
これらのアーキテクチャ図は、意図的にさまざまなデータベース、エッジ コンピューティング、オブジェクト ストレージ、CDN プロバイダーに適用できるようにしました。私は自分のコンテンツが広く適用されることを望んでいます。ただし、エッジの統合は単なるパフォーマンス以上のものであることに言及する価値があります。有効にできる非常に優れたセキュリティ機能もたくさんあります。
たとえば、Akamai のネットワークでは、次のようなものにアクセスできます。
それでは、今のところ、読んでいただいたことに大きな「ありがとう」を言いたいと思います。何かを学べたことを願っています。いつものように、コメント、質問、懸念事項などがございましたら、いつでもお気軽にお問い合わせください。
読んでいただきありがとうございます。この記事が気に入って、私をサポートしたい場合は、そのための最良の方法は次のとおりです。
最初に公開されたのは