大型言語モデル(LLMs)は、日常的なアプリから高度なツールに至るまで、どこにでもあります。それらを使用することは簡単です。しかし、あなたが自分のモデルを実行する必要がある場合はどうですか? あなたが細かく調整しているか、プライバシーに敏感なデータに取り組んでいるかどうかは、複雑さが増加しています。この投稿では、私たちは私たちの独自のLLM推測システムを構築する際に学んだことを共有します。私たちは、ストレージとデプロイのモデルをカバーし、サービスアーキテクチャを設計し、ルーティング、ストリーミング、およびマイクロサービスの管理などの現実的な問題を解決します。プロセスには課題が含まれていますが、最終的には、私たちは信頼できるシステムを構築し、共有価値のあるレッス 導入 LLMsは、チャットボットやワークフローエージェントからスマートオートメーションツールに至るまで、幅広いアプリケーションをパワーアップしています。 多くのプロジェクトは、例えば、外部プロバイダーに依存しています。 , あるいは ほとんどの使用の場合には十分ですが、特定のアプリケーションでは、すぐに問題になります。 プロバイダーがダウンロードする場合はどうですか? 遅延、価格、またはオープタイムの完全な制御が必要な場合はどうですか? 最も重要なことは、プライバシーを大切にし、ユーザーデータを第三者に送信する余裕がない場合はどうですか? オープン 双子 アントロピー オープン 双子 アントロピー そこで、自己ホスティングが不可欠になります。事前訓練されたモデルを提供することで、コントロール、セキュリティ、およびモデルを特定のビジネスニーズに合わせてカスタマイズする能力が提供されます。そのようなシステムを構築するには、大きなチームや膨大なリソースを必要としません。 謙虚な予算、小さなチーム、わずかなノードで構築しました。 この制約は私たちの建築決定に影響を与え、実用性と効率性に焦点を当てる必要があります。 次のセクションでは、直面した課題、実施されたソリューション、そしてその途中で学んだレッスンを説明します。 総合概要 これらは、システムの背骨を形成するコアコンポーネントです。 Formats and Encoding. A shared language across services is essential. That means consistent request/response formats, generating parameter schemes, dialog history structures, and serialization that works everywhere — from frontend to backend to model runner. それは、一貫したリクエスト/応答形式、生成パラメータスケジュール、対話履歴構造、およびフォントエンドからバックエンドまで、あらゆる場所で機能するシリアリゼーションを意味します。 ストリーミングとルーティング. 複数のモデル、リクエストタイプ、ホストの優先順位を扱うには、慎重なルーティング決定が必要です. 入力ユーザーのリクエストがシステムを通じてどのようにルーティングされるか - 初期入力点から適切なワーカーノードまで - および応答がどのように再ストリーミングされるかを説明します。 モデルストレージと展開. モデルはどこに存在し、どのように生産使用のために準備されていますか? 私たちは、モデルの信頼性を確保することを含む実行する主要なテストについて議論します。 観察性. 物事が機能していることをどのように知っていますか? 私たちは、どのようなメトリクスを追跡し、失敗をどのように監視し、システムの健康と信頼性を確保するために使用する探査機を示します。 スケジュールとデータの暗号化 Choosing the right schema for data transfer is crucial. A shared format across services simplifies integration, reduces errors, and improves adaptability. We aimed to design the system to work seamlessly with both self-hosted models and external providers — without exposing differences to the user. Why Schema Design Matters LLMデータ交換のための普遍的な基準はありません. 多くのプロバイダは、 , while others - like または — introduce subtle but important differences. Many of these providers offer OpenAI-compatible SDKs that retain the same schema, though often with limitations or reduced feature sets (e.g., で、 (その他のプロジェクトなど) これらの変異をOpenAIに対応したインターフェイスに包装することによって統一することを目指しています。 オープン クラウド 双子 AnthropicのOpenAI対応SDK Gemini’s OpenAI compatibility layer OpenRouter オープン クラウド 双子 AnthropicのOpenAI対応SDK GeminiのOpenAI互換性レイヤー OpenRouter Sticking to a single predefined provider’s schema has its benefits: きちんとテストされ、安定した API を取得します。 既存のSDKやツールに頼ることができます。 しかし、実際の欠点もあります: それは、複数のプロバイダーをサポートすることを困難にし、ベンダーロックインを作成します。 これは、ビジネスニーズやデータサイエンスチームの要件に必要なカスタマイズされた機能でスケジュールを拡張する柔軟性を制限します。 あなたは、あなたのコントロール外の変化や削減に暴露されます。 これらのシステムはしばしば、繊細なコントロールを制限する遺産制限を伴う。 To address this, we chose to define our — 私たちのニーズを中心に設計されたスケジュール、その後必要に応じてさまざまな外部フォーマットにマッピングすることができます。 own internal data model 内部スケジュールデザイン 課題に対処する前に、問題を定義し、解決策に対する期待を述べましょう。 Easy conversion to formats required by external providers and in reverse. ビジネスとデータサイエンスのチームに特有の機能の完全なサポート。 計画を容易に拡張し、将来の要件を満たすようにします。 私たちは、プロバイダがメッセージ、パラメータ、および出力をどのように構造するかを理解するために、主要なLLMスケジュールをレビューすることから始めました。 ほとんどのシステムで共通している、以下を含む: core domain entities メッセージ(例えば、速やかに、歴史) 生成パラメータ(たとえば、温度、top_p、beam_search) いくつかのパラメーターを特定し、例えば、 で、 あるいは プロバイダの内部構成およびビジネス論理に特有のものとして、これらの要素はコアLLMドメインの外にあり、共有スケジュールの一部ではありません。代わりに、それらはオプションの拡張として扱われます。機能が広く採用され、またはより広範な相互運用性のために必要になると、私たちはそれをコアスケジュールに統合することを評価します。 service_tier usage_metadata reasoning_mode 高いレベルで、私たちの入力スケジュールは、これらの重要なコンポーネントで構成されています: モデル:ルーティングキーとして使用され、ルーティング識別子として機能し、システムがリクエストを適切なワーカーノードにリダイレクトすることを可能にします。 Generation Parameters - Core model settings (e.g. temperature, top_p, max_tokens) メッセージ — 会話履歴と迅速なパイロード。 ツール - モデルが使用するツールの定義。 これは、以下に示す図で示すものである。 デザインの構造と意図を示していますが、実装の詳細は単純性のために省略されています。 ピアノみたいな ピアノみたいな class ChatCompletionRequest(BaseModel): model: str # Routing key to select the appropriate model or service messages: list[Message] # Prompt and dialogue history generation_parameters: GenerationParameters # Core generation settings tools: list[Tool] # Optional tool defenitions class GenerationParameters(BaseModel): temperature: float top_p: float max_tokens: int beam_search: BeamSearchParams # Optional, non-core fields specific to certain providers provider_extensions: dict[str, Any] = {} ... # Other parameters We deliberately moved generation parameters into a separate nested field instead of placing them at the root level. この設計選択は、それらを根のレベルに置く代わりに、別々の巣立ったフィールドに移しました。 パラメータ(たとえば、温度、トップP、モデル設定)および エコシステム内の多くのチームは、これらの常数を外部構成システムに格納し、この分離を実用的かつ必要とする。 常時 変数 呼ばれる追加フィールドを追加します。 内 内 これらのパラメータは、さまざまなLLMプロバイダーによって大きく異なり、これらの分野の検証と解釈は —the component that knows how to communicate with a specific model provider. Thus, we avoid unnecessary pass-through coupling caused by redundant data validation across multiple services. provider_extensions GenerationParameters delegated to the final module that handles model inference 後ろ向きの互換性を確保するために、新しい出力スケジュール機能が導入されます。 これらのフィールドは機能フラッグとして機能する — ユーザーはそれらを特定の行動にオプトするように設定する必要があります. このアプローチは、コアスケジュールを安定的に維持し、増加的な進化を可能にします. たとえば、推論の痕跡は、応答フィールドがリクエストに設定されている場合にのみ出力に含まれます。 explicit, optional fields これらのスケジュールは、共有されたPythonライブラリで維持され、サービス間で一貫したリクエストと応答の処理を確保するために使用されます。 第三者プロバイダーとの協力 私たちは、独自のプラットフォームをどのように構築したかを説明し始めました - なぜ外部プロバイダ間の互換性に悩むのでしょうか? 内部インフラストラクチャに依存しているにもかかわらず、外部モデルが役割を果たすいくつかのシナリオがあります。 データサイエンスチームによるプロトタイプ作成と実験のための合成データ生成。 where some proprietary models perform better out of the box. General-purpose tasks プライバシー、遅延、またはインフラストラクチャの制御が少なくなる非敏感な使用事例。 外部プロバイダーとのコミュニケーションの全体的な流れは、次のようにまとめられます。 このプロセスには以下のステップが含まれます。 プロバイダとのコミュニケーションを担当する特別LLMゲートウェイサービスは、当社のスケジュール形式でユーザーの要求を受け取ります。 The request is converted into the provider-specific format, including any . provide_extensions 外部プロバイダーはリクエストを処理し、応答を返します。 LLMゲートウェイサービスは応答を受け取り、標準化された応答スケジュールにそれをマップします。 これは、いくつかの個々のマイクロサービスを抽象化する高レベルのスケジュールです。特定のコンポーネントとストリーミング応答形式に関する詳細は、次のセクションで説明されます。 ストリーミング形式 LLMの応答は、トークンごとに増加的に生成され、その後、トークンごとに合計されます。 ユーザーの視点から、ブラウザ、モバイルアプリケーション、または端末を通じて、体験は残らなければなりません。 そのためには、サポートする交通機関が必要です。 . chunks fluid and responsive low-latency, real-time streaming これを達成するための2つの主な選択肢があります: WebSockets:クライアントとサーバー間の継続的な2方向の相互作用を可能にする完全ダプレックス通信チャンネル。 Server-Sent Events(SSE):リアルタイムのアップデートに広く使用される、HTTPベースの単方向ストリーミングプロトコル。 WebSockets WebSockets サーバー送信イベント(SSE) サーバー送信イベント(SSE) なぜ、WebSocketsを上回るのか 両方とも実現可能な場合、 — particularly for OpenAI-compatible APIs and similar systems. This is due to several practical advantages: SSE is the more commonly used solution for standard LLM inference シンプル: SSE は標準 HTTP を上回っており、特別なアップグレードや交渉は必要ありません。 互換性:追加のライブラリなしですべての主要なブラウザでネイティブで動作します。 Unidirectional Flow:ほとんどのLLM応答はサーバーからクライアントにのみ流れ、SSEの設計と一致しています。 : SSE plays well with standard HTTP infrastructure, including reverse proxies. Proxy-Friendliness アップグレードまたは交渉 これらの利点から、 . SSE is typically chosen for text-only, prompt-response streaming use cases However, some emerging use cases require richer, low-latency, bidirectional communication — such as real-time transcription or speech-to-speech interactions. addresses these needs using これらのプロトコルは、継続的な多様な入力と出力により適しています。 OpenAI’s Realtime API WebSockets OpenAIのリアルタイムAPI 私たちのシステムは、単に We stick with そのシンプルさ、互換性、そして私たちのストリーミングモデルとの調和のために。 text-based interactions SSE Response Stream Content 同 輸送層として選択された、次のステップは、 ストリーミングに含めるデータ 効果的なストリーミングには、単なる原文以上のものが必要で、十分なストリーミングを提供する必要があります。 ユーザインターフェイスや自動化ツールなどの下流消費者をサポートするため、ストリームには以下の情報が含まれる必要があります。 SSE what structure, metadata, and context Header-Level Metadata. リクエスト ID などの基本的な識別情報。 Real Content Chunks. The core output — the tokens or strings generated by the model — is delivered incrementally as sequences (n) are streamed back, chunk-by-chunk. Each generation can consist of multiple sequences (e.g., n=2, n=4) .These sequences are generated independently and streamed in parallel, each broken into its own set of incremental chunks. コアの出力 — モデルによって生成されたトークンまたはストリーミング — シェア(n)がストリーミングされるように増加します。 使用およびトークンレベルのメタデータ これには、生成されたトークンの数、タイミングデータ、およびログプロブや推論トラックなどのオプションの診断が含まれます。これらは、請求、デバッグ、またはモデル評価のために使用することができます。 After defining the structure of the streamed response, we also considered several non-functional requirements essential for reliability and future evolution. 私たちのストリームデザインは、以下のようになることを意図しています。 構造化 - コンテンツタイプとイベント境界線を明確に区別する。 拡張可能 - 既存のクライアントを破ることなくオプションメタデータを持ち込むことができます。 強力 - 誤り、遅延、または部分的なデータに対応します。 多くのアプリケーションにおいて、例えば、 または 複数のシーケンス(完結)が、単一世代リクエストの一部として並行して生成される。 side-by-side comparison diverse sampling The most comprehensive format for streaming responses is defined in the 仕様によると、単一世代のチュンクには、複数のセクションが含まれることがあります。 アレイ: OpenAI API reference choices OpenAI API 参照 選択 アレイ チャットを完了するオプションのリスト. Can contain more than one element if n is greater than 1. Can also be empty for the last chunk. もし n が 1 より大きい場合、1 つ以上の要素を含むことができます。 choices array チャットを完了するオプションのリスト. Can contain more than one element if n is greater than 1. Can also be empty for the last chunk. もし n が 1 より大きい場合、1 つ以上の要素を含むことができます。 Although, in practice, individual chunks usually contain only a single delta, the format allows for multiple sequence updates per chunk. It’s important to account for this, as future updates might make broader use of this capability. Notably, even the この構造を支えるように設計されています。 Python SDK Python SDK 潜在的な機能の幅広い範囲との互換性を確保するために、同じ構造に従うことを選択しました. The chart below illustrates an example from our implementation, where a single generation consists of three sequences, streamed in six pieces over time: This chunk marks the beginning of the entire generation. It doesn’t contain any actual content but includes shared metadata, such as the generation ID, timestamp, and role (e.g., assistant, etc.). Chunk 1 — Generation Start. Two sequences begin streaming in parallel. Each is tagged with a unique identifier to distinguish it from others. Chunk 2 — Sequence Start (Green & Purple). Chunk 3 — Sequence Start (Blue) & Sequence Delta. The third sequence starts (blue), while the first two sequences (green and purple) stream incremental content via delta events. セクションスタート(ブルー)とセクションデルタ。 The green and blue sequences continue streaming deltas. The purple sequence finishes — this includes a structured finish_reason (like stop, length, etc.). Chunk 4 — Midstream Updates & Finish (Purple). Both the green and blue sequences complete. Each sequence’s lifecycle is now fully enclosed between its respective start and finish markers. Chunk 5 — Remaining Sequence Finishes. This chunk closes the generation and may include global usage statistics, final token counts, latency info, or other diagnostics. Chunk 6 — Generation Finish. As you see, to make the stream robust and easier to parse, we opted to ゼロチェック、EOF、またはマジック・トークンなどの暗示的なメカニズムに依存するのではなく、この構造化されたアプローチは、下流の解析を簡素化し、特に複数の完成が並行してストリーミングされている環境では、開発およびランタイム検査中にデバッグビリティとエラー隔離も向上します。 explicitly signal Start and Finish events for both the overall generation and each individual sequence また、追加の紹介をいたします。 エラーに関する構造化された情報を持ち込むブロック エラー - 誤ったリクエストや認証の問題など - は、標準の HTTP 応答コードを介して直接表面化できます。 , we have two options: either abruptly terminate the HTTP stream or emit a well-formed SSE error event. We chose the latter. Abruptly closing the connection makes it hard for clients to distinguish between network issues and actual model/service failures. By using a dedicated error chunk, we enable more reliable detection and propagation of issues during streaming. Error during the generation process バックエンドサービスとリクエストフロー At the center of the system is a single entrypoint: . 認証、使用追跡、割引の執行、リクエスト形式化、指定されたモデルに基づくルーティングなどの基本的な問題に対処します。ゲートウェイは多くの責任を負っているように見えますが、それぞれのタスクは意図的にシンプルでモジュール化されています。外部プロバイダーにとっては、リクエストをAPIに適応させ、応答を統一された形式に戻します。 自社ホストモデルでは、リクエストは独自の統一されたスケジュールを使用して内部システムに直接ルーティングされます。このデザインは、一貫したインターフェイスを介して外部モデルと内部モデルの両方のシームレスなサポートを可能にします。 LLM-Gateway Self-Hostedモデル As mentioned earlier, エンドユーザーへのストリーミング反応に適していますが、実用的な選択肢ではありません。 リクエストが到着すると、モデル推測のための適切なワーカーノードにルーティングされ、結果はストリーミングされ、いくつかのシステムはチェーン化されたHTTPプロキシとヘッダーベースのルーティングを使用してこれを処理しますが、私たちの経験では、このアプローチは、論理が複雑化するにつれて管理し、進化するのが難しくなります。 Server-Sent Events (SSE) internal backend communication Our internal infrastructure needs to support: Priority-aware スケジュール - リクエストには異なる緊急性レベル(例えば、インタラクティブ対バッチ)があり、優先順位の高いタスクを最初に処理する必要があります。 ハードウェア意識のルーティング - 特定のノードは、より高性能のGPUで実行され、優先されるべきであり、他のノードは過流容量として機能します。 Model-specific dispatching — 各ワーカーは、ハードウェアの互換性とリソースの制約に基づいて、モデルのサブセットのみをサポートするように構成されています。 これらの要件を満たすために、我々はA to decouple task routing from result delivery. This design provides better flexibility and resilience under varying load and routing conditions. We use この目的のために、他のブローカーもあなたの遅延、通過量、および操作の好みに応じて実行可能であるかもしれませんが RabbitMQは、その成熟度と私たちの既存のツールとの調和を考慮して、自然に適合しました。 message broker ウサギ ウサギ ウサギ では、このシステムが実際にどのように実装されているかを詳しく見ていきましょう。 我々 使用 , allowing us to route requests based on model compatibility and node capabilities. The process is as follows: dedicated queues per model The LLM-Gateway service (represented as the user) initiates an HTTP request to trigger a text generation task. starts a new to manage this request. Client Sends Request. Scheduler service Request Handler The request is handled by the , which selects the appropriate queue (marked in green on the image) based on the requested model and appends the message to it. Task Routing via Scheduler service. Scheduler Worker Pick Up Task. A suitable Inference Worker (only one worker is shown for simplicity, but there are many) subscribed to the queue picks up the task and starts processing. この worker は、選択したモデルをローカルで実行します。 Streaming the Response. The worker streams the response chunk-by-chunk into the Response Queue, to which the Scheduler replica handling the request is subscribed. 作業員は、リクエストを処理するスケジュラーのレプリカにサブスクリプトされているResponse Queueに、リクエストの一部ずつストリーミングします。 The Scheduler listens to the reply queue and receives the response chunks as they arrive. Receiving Response Chunks. The chunks are converted to SSE format and streamed to the client. SSE Streaming. To handle , we avoid overwhelming the message broker: メッセージブローカーを圧倒する: large payloads 大規模な入力または出力データをタスクに直接埋め込むのではなく、外部のS3対応ストアにアップロードします。 リファレンス(URL またはリソース ID など)はタスクメタデータに含まれており、必要に応じて実際のコンテンツを取得します。 Applying the Design with RabbitMQ When it comes to , each 普通のRabbitMQ 単一のモデルタイプを扱うことに専念します。 利用することで達成できるもの この設定では、より高い優先順位値のメッセージがより低い優先順位値より前に配信され、処理されます。 , where messages should be directed to the most performant available nodes first, can help. Consumers with higher priority receive messages as long as they are active; lower-priority consumers only receive messages when the higher-priority ones are blocked or unavailable. routing and publishing messages Request Queue 尾 priority-aware scheduling メッセージ優先順位 hardware-aware routing 消費者優先事項 尾 メッセージ優先順位 消費者優先事項 If message loss is unacceptable, the following must be in place: Publisher は、ブローカーがメッセージを受け取って保存したことを確認します。 and so data survives restarts. Durable queues persistent messages これらはまた、RabbitMQ 4.0 以降の簡素化されたメッセージおよび消費者優先順位をサポートします。 出版社 確認 出版社 確認 Quorum queues クォーラム RabbitMQ 4.0 からの簡素化されたメッセージと消費者優先順位 これまでのところ、タスクがどのように公開されているかをカバーしましたが、 handled? The first step is to understand how work in RabbitMQ. The broker supports a concept called 単一の接続に縛られており、その接続が閉じると自動的に削除されます。 streamed response temporary queues EXCLUSIVE CHOES EXCLUSIVE CHOES exclusive queues We create しかし、これは課題をもたらします:各サービスのレプリカには1つのRabbitMQ列がありますが、それは処理しなければなりません。 . one exclusive queue per Scheduler service replica many requests in parallel これに対処するために、我々はRabbitMQの列をAとして扱う。 , routing responses to the correct Scheduler replica. Each user request is assigned a すべての答えに含まれており、内部の 追加を維持いたします。 with short-lived in-memory queues — one per active request. Incoming chunks are matched to these queues based on the identifier and forwarded accordingly. These in-memory queues are discarded once the request completes, while the RabbitMQ queue persists for the lifetime of the service replica. transport layer unique identifier Scheduler in-memory routing layer スケジュール的には次のように見えます。 Scheduler 内の中央ディスパイヤーは、それぞれ専用のマネージャーによって管理される適切なメモリの列にブロックを送信します。 INFERENCE 効率的なLLM推論のためのいくつかの成熟したフレームワークがあります。 and これらのシステムは、 リアルタイムで応答トークンを生成し、しばしば連続バッチングやGPUメモリ最適化などの機能を使用します。 as the core inference engine, with a few custom modifications: VLLM スレッグ process multiple sequences in parallel vLLM VLLM VLLM スレッグ スレッグ — to better suit our generation logic and support structured constraints. Custom beam search implementation 構造化された出力スケジュールのサポート - モデルがビジネス特有のフォーマットに合致する出力を返すことを可能にします。 経験を通じて、私たちは小さなライブラリのアップデートでさえ、 — whether in output quality, determinism, or concurrency behavior. Because of this, we’ve established a robust testing pipeline: significantly alter model behavior ストレステストは、共通の問題、メモリ漏洩、または安定回帰を明らかにする。 to ensure consistent outputs for fixed seeds and parameter sets. Determinism testing Parameter grid testing to cover a wide range of generation settings, without going overboard. パラメータグリッドテストは、生産設定の幅広い範囲をカバーし、乗り越えることなく行います。 ストレージと展開 現代のほとんどのシステムは、 — クラウド内または Kubernetes (K8s) 内で、このセットアップは典型的なバックエンド サービスでうまく機能しますが、周囲の課題を導入します。 LLMモデルは、 , and baking model weighs directly into Docker images — quickly becomes problematic:ドッカー画像に直接重みを加え、すぐに問題になる: containerized environments model weight storage tens or even hundreds of gigabytes in size 遅いビルド - 複数の段階のビルドとキャッシュでさえ、ビルド段階の間に大きなモデルファイルを転送することは、CI時間を劇的に増やすことができます。 遅い展開 - 各展開には大量の画像を引っ張る必要があり、数分間かかることがあり、中断や遅延を引き起こす可能性があります。 リソース効率の低下:Docker レジストリや Kubernetes ノードは非常に大きな画像を処理するのに最適化されていないため、ストレージの使用量や帯域幅の圧力が膨らみます。 To solve this, we separate Docker 画像のライフサイクルから。当社のモデルは、 , and picked just before inference service startup. To improve startup time and avoid redundant downloads, we also use 各ノードのモデル重量をキャッシュする。 model storage external S3-compatible object storage 現地永続体積(PVC) local persistent volumes (PVCs) 現地永続体積(PVC) Observability A system like this — built on 要求する 規模で信頼性とパフォーマンスを確保するために。 streaming, message queues, and real-time token generation robust observability In addition to standard service-level metrics (CPU, memory, error rates, etc.), we found it essential to monitor the following: 列の深さ、メッセージのバックログ、および消費者の数 - 待機メッセージの数、現在の列のサイズ、およびアクティブな消費者の数を監視すると、タスク配布のボトルネックや従業員利用の不均衡を検出できます。 Token/chunk throughput - 1秒あたり生成されるトークンの数または応答ブランクを追跡することは、遅延または通過回帰を特定するのに役立ちます。 Distributed Tracking - リクエストがどこに失敗するか、またはコンポーネント(ゲートウェイ、ブローカー、従業員など)に停滞しているかを特定する。 推定エンジンの健康チェック - 推定プロセスが稀な条件下(例えば、悪い入力または極端なパラメータ値)で崩壊する可能性があるため、活性度と準備の積極的な監視が重要です。 分散トラッキング Distributed tracing さらなる改善 当社のシステムは生産準備が整っているものの、依然として重要な課題と最適化の機会があります。 Using a to boost inference performance. distributed KV-cache 出力がもはや必要ないときにコンピュータを保存するためのリクエストのキャンセルをサポートします。 データサイエンスチームのためのシンプルなモデル配信パイプラインを作成します。 結論 信頼性があり、プロバイダー独立のLLMサービスシステムを構築することは最初は複雑に見えるかもしれませんが、車輪を再発明する必要はありません。SSE経由でストリーミング、メッセージブローカー経由でタスク配布、vLLMのようなランタイムで処理された推論は、明確な目的を果たし、既存の、よくサポートされているツールに基づいています。 次の投稿では、分散型KVキャッシング、複数のモデルを複製する取り扱い、ML指向のチームに適した展開ワークフローなどのより高度なトピックについて説明します。 著者 トッキー , Stanislav Shimovolos スタニスラフ・シモボロス スタニスラフ・シモボロス トッキー , マクシム・アファナシエフ マクシム・アファナシエフ マクシム・アファナシエフ 認定 Tochkaで行われた仕事 Dmitry Kryukov Dmitry Kryukov ドミトリー・クリウコフ