このトピックでは、Kubernetes クラスタにデプロイされた LLM 推論サービスの負荷分散とトラフィック管理を強化するためにサービスメッシュ(ASM)を使用する方法について説明します。 LLM 推論トラフィックとワークロードの固有の特性により、従来の負荷分散方式では不十分な場合があります。このトピックでは、パフォーマンスを向上させ、推論トラフィックを把握するために、vLLM 推論サービスのサービスプールとルーティングを定義する手順を説明します。
ヒントを読む
始める前に、以下について理解していることを確認してください。
ACS クラスタ内で GPU コンピューティング機能を利用するには、詳細な手順については、「ACS GPU アクセラレーション ポッドの GPU モデルとドライババージョンを指定する ACS クラスタ内で GPU コンピューティング機能を利用するには」を参照してください。
ACK クラスタで GPU ノードプールを作成して使用する方法、または ACS コンピューティングパワーを利用する方法については、詳細な手順については、「GPU ノードプールを作成する」または「ACK Pro クラスタで ACS のコンピューティングパワーを使用する」を参照してください。
このトピックを読むことで、以下について学ぶことができます。
これらのスタックは、新しいリリースで定期的に更新されます。独自のカスタム ランタイム スタックを作成することもできます。
従来の方法を使用してクラスター内の LLM 推論サービスを管理する際の課題。
ASM を使用してクラスター内の LLM 推論サービスを管理するための概念と実践的なステップ。
背景
大規模言語モデル (LLM)
大規模言語モデル (LLM) は、数十億のパラメーターを持つニューラルネットワークベースの言語モデルであり、GPT、Qwen、Llama などが代表的な例です。これらのモデルは、Webテキスト、専門文献、コードなど、多様で大規模な事前トレーニング データセットでトレーニングされ、主に補完や対話などのテキスト生成タスクに使用されます。
LLM を活用してアプリケーションを構築するには、次の方法があります。
OpenAI、Alibaba Cloud Model Studio、Moonshot などのプラットフォームから外部 LLM API サービスを利用する。
vLLM などのオープンソースまたは独自のモデルとフレームワークを使用して独自の LLM 推論サービスを構築し、Kubernetes クラスターにデプロイする。このアプローチは、推論サービスの制御や LLM 推論機能の高いカスタマイズが必要なシナリオに適しています。
vLLM
vLLM は、LLM 推論サービスを効率的かつユーザーフレンドリーに構築するために設計されたフレームワークです。 Qwen を含むさまざまな大規模言語モデルをサポートし、PagedAttention、動的バッチ推論 (Continuous Batching)、モデル量子化などの手法によって LLM 推論効率を最適化します。
背景
ASM はクラスター内の LLM 推論サービストラフィックの管理を容易にします。LLM 推論サービスをデプロイする際、InferencePool と InferenceModel のカスタムリソース定義 (CRD) を通じて、サービスを提供するワークロードとモデル名を宣言できます。その後、ASM は LLM 推論バックエンドを対象とする LLM 推論サービスに対して、負荷分散、トラフィックルーティング、および可観測性を提供します。
現在、vLLM に基づく LLM 推論サービスのみがサポートされています。
従来の負荷分散従来の負荷分散アルゴリズムは、HTTP リクエストをさまざまなワークロードに均等に分散します。ただし、LLM 推論サービスでは、各リクエストがバックエンドに課す負荷は予測できません。 推論プロセスは、プリフィルとデコードの 2 つのフェーズで構成されます。
| LLM 負荷分散ASM は、LLM バックエンド向けに調整された負荷分散アルゴリズムを提供します。これは、多次元メトリックを使用して推論サーバーの内部状態を評価し、複数のサーバーにワークロードを分散します。主なメトリックは次のとおりです。
このアプローチは、推論サービス全体で一貫した GPU 負荷を確保し、LLM リクエストの最初のトークンの応答レイテンシ (ttft) を削減し、スループットを向上させることで、従来のアルゴリズムよりも優れたパフォーマンスを発揮します。 |
従来の可観測性LLM 推論サービスは通常、OpenAI のリクエスト API 形式を使用して対話します。モデル名や最大トークン数など、ほとんどのリクエストメタデータはリクエスト本文にあります。リクエストヘッダーとパスに基づく従来のルーティング機能と可観測性機能は、リクエスト本文を解析しないため、リクエストモデル名またはトークン数に基づくトラフィック割り当てまたは観測に対応できません。 | 推論トラフィックの可観測性ASM は、リクエストのアクセスログと監視メトリックにおける LLM 推論機能を強化します。
|
前提条件
GPU ノードプールを持つ ACK マネージドクラスターを作成したか、GPU 計算能力を持つ推奨ゾーンで ACS クラスターを選択したことを確認します。詳細については、「ACK マネージドクラスターの作成」および「ACS クラスターを作成する」をご参照ください。
ACK マネージドクラスターに ACK Virtual Node コンポーネントをインストールして、ACS GPU 計算機能を利用できます。詳細については、「ACK での ACS GPU 計算能力」をご参照ください。
v1.24 以降の ASM インスタンスにクラスターが追加されています。詳細については、「ASM インスタンスにクラスターを追加する」をご参照ください。
イングレスゲートウェイが作成され、ポート 8080 で HTTP サービスが有効になっています。詳細については、「イングレスゲートウェイを作成する」をご参照ください。
(オプション) Sidecar がデフォルトの名前空間に挿入されています。詳細については、「Sidecar プロキシの自動挿入を有効にする」をご参照ください。
説明可観測性の実際の操作を確認する必要がない場合は、Sidecar の挿入をスキップできます。
ベストプラクティス
次の例は、vLLM に基づいて Llama2 large モデルをデプロイすることで、ASM を使用してクラスタ内の LLM 推論サービストラフィックを管理する方法を示しています。
手順 1:サンプル推論サービスをデプロイする
提供されたコンテンツを使用して、vllm-service.yaml という名前のファイルを作成します。
説明このトピックで説明されているイメージには、16 GiB を超えるビデオメモリを搭載した GPU が必要です。 16 GiB のビデオメモリを搭載した T4 カードタイプでは、このアプリケーションを起動するための十分なリソースが提供されません。 ACK クラスタには A10 カードタイプ、ACS クラスタには第 8 世代 GPU B を使用することをお勧めします。モデルの詳細については、submit a ticket を送信して、サポートを受けてください。
LLM イメージのサイズが大きいため、ACR に事前に保存し、プルに内部ネットワークアドレスを使用することをお勧めします。パブリックネットワークから直接プルすると、クラスタ EIP 帯域幅の構成によっては、待機時間が長くなる可能性があります。
ACS クラスタ
apiVersion: v1 kind: Service metadata: name: vllm-llama2-7b-pool spec: selector: app: vllm-llama2-7b-pool ports: - protocol: TCP port: 8000 targetPort: 8000 type: ClusterIP --- apiVersion: v1 kind: ConfigMap metadata: name: chat-template data: llama-2-chat.jinja: | {% if messages[0]['role'] == 'system' %} {% set system_message = '<<SYS>>\n' + messages[0]['content'] | trim + '\n<</SYS>>\n\n' %} // メッセージがシステムメッセージの場合、システムメッセージ変数を設定します {% set messages = messages[1:] %} // システムメッセージをメッセージリストから削除します {% else %} {% set system_message = '' %} // メッセージがシステムメッセージでない場合、システムメッセージ変数を空に設定します {% endif %} {% for message in messages %} // メッセージリストを反復処理します {% if (message['role'] == 'user') != (loop.index0 % 2 == 0) %} // ユーザーとアシスタントのロールが交互になっていることを確認します {{ raise_exception('Conversation roles must alternate user/assistant/user/assistant/...') }} // ロールが交互になっていない場合は、例外を発生させます {% endif %} {% if loop.index0 == 0 %} // 最初のメッセージの場合 {% set content = system_message + message['content'] %} // システムメッセージをコンテンツに追加します {% else %} {% set content = message['content'] %} // それ以外の場合は、メッセージコンテンツをコンテンツに設定します {% endif %} {% if message['role'] == 'user' %} // メッセージがユーザーメッセージの場合 {{ bos_token + '[INST] ' + content | trim + ' [/INST]' }} // BOS トークンと [INST] タグを追加します {% elif message['role'] == 'assistant' %} // メッセージがアシスタントメッセージの場合 {{ ' ' + content | trim + ' ' + eos_token }} // EOS トークンを追加します {% endif %} {% endfor %} --- apiVersion: apps/v1 kind: Deployment metadata: name: vllm-llama2-7b-pool namespace: default spec: replicas: 3 selector: matchLabels: app: vllm-llama2-7b-pool template: metadata: annotations: prometheus.io/path: /metrics prometheus.io/port: '8000' prometheus.io/scrape: 'true' labels: app: vllm-llama2-7b-pool alibabacloud.com/compute-class: gpu # GPU 計算能力を指定します alibabacloud.com/compute-qos: default alibabacloud.com/gpu-model-series: "example-model" # GPU モデルを example-model として指定します。実際の状況に応じて入力してください。 spec: containers: - name: lora image: "registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/llama2-with-lora:v0.2" imagePullPolicy: IfNotPresent command: ["python3", "-m", "vllm.entrypoints.openai.api_server"] args: - "--model" - "/model/llama2" - "--tensor-parallel-size" - "1" - "--port" - "8000" - '--gpu_memory_utilization' - '0.8' - "--enable-lora" - "--max-loras" - "4" - "--max-cpu-loras" - "12" - "--lora-modules" - 'sql-lora=/adapters/yard1/llama-2-7b-sql-lora-test_0' - 'sql-lora-1=/adapters/yard1/llama-2-7b-sql-lora-test_1' - 'sql-lora-2=/adapters/yard1/llama-2-7b-sql-lora-test_2' - 'sql-lora-3=/adapters/yard1/llama-2-7b-sql-lora-test_3' - 'sql-lora-4=/adapters/yard1/llama-2-7b-sql-lora-test_4' - 'tweet-summary=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_0' - 'tweet-summary-1=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_1' - 'tweet-summary-2=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_2' - 'tweet-summary-3=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_3' - 'tweet-summary-4=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_4' - '--chat-template' - '/etc/vllm/llama-2-chat.jinja' env: - name: PORT value: "8000" ports: - containerPort: 8000 name: http protocol: TCP livenessProbe: // liveness プローブの設定 failureThreshold: 2400 httpGet: path: /health port: http scheme: HTTP initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 readinessProbe: // readiness プローブの設定 failureThreshold: 6000 httpGet: path: /health port: http scheme: HTTP initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: // リソース制限とリクエストの設定 limits: cpu: 16 memory: 64Gi nvidia.com/gpu: 1 requests: cpu: 8 memory: 30Gi nvidia.com/gpu: 1 volumeMounts: // ボリュームマウントの設定 - mountPath: /data name: data - mountPath: /dev/shm name: shm - mountPath: /etc/vllm name: chat-template restartPolicy: Always schedulerName: default-scheduler terminationGracePeriodSeconds: 30 volumes: // ボリュームの設定 - name: data emptyDir: {} - name: shm emptyDir: medium: Memory - name: chat-template configMap: name: chat-templateACK クラスタ
apiVersion: v1 kind: Service metadata: name: vllm-llama2-7b-pool spec: selector: app: vllm-llama2-7b-pool ports: - protocol: TCP port: 8000 targetPort: 8000 type: ClusterIP --- apiVersion: v1 kind: ConfigMap metadata: name: chat-template data: llama-2-chat.jinja: | {% if messages[0]['role'] == 'system' %} {% set system_message = '<<SYS>>\n' + messages[0]['content'] | trim + '\n<</SYS>>\n\n' %} // メッセージがシステムメッセージの場合、システムメッセージ変数を設定します {% set messages = messages[1:] %} // システムメッセージをメッセージリストから削除します {% else %} {% set system_message = '' %} // メッセージがシステムメッセージでない場合、システムメッセージ変数を空に設定します {% endif %} {% for message in messages %} // メッセージリストを反復処理します {% if (message['role'] == 'user') != (loop.index0 % 2 == 0) %} // ユーザーとアシスタントのロールが交互になっていることを確認します {{ raise_exception('Conversation roles must alternate user/assistant/user/assistant/...') }} // ロールが交互になっていない場合は、例外を発生させます {% endif %} {% if loop.index0 == 0 %} // 最初のメッセージの場合 {% set content = system_message + message['content'] %} // システムメッセージをコンテンツに追加します {% else %} {% set content = message['content'] %} // それ以外の場合は、メッセージコンテンツをコンテンツに設定します {% endif %} {% if message['role'] == 'user' %} // メッセージがユーザーメッセージの場合 {{ bos_token + '[INST] ' + content | trim + ' [/INST]' }} // BOS トークンと [INST] タグを追加します {% elif message['role'] == 'assistant' %} // メッセージがアシスタントメッセージの場合 {{ ' ' + content | trim + ' ' + eos_token }} // EOS トークンを追加します {% endif %} {% endfor %} --- apiVersion: apps/v1 kind: Deployment metadata: name: vllm-llama2-7b-pool namespace: default spec: replicas: 3 selector: matchLabels: app: vllm-llama2-7b-pool template: metadata: annotations: prometheus.io/path: /metrics prometheus.io/port: '8000' prometheus.io/scrape: 'true' labels: app: vllm-llama2-7b-pool spec: containers: - name: lora image: "registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/llama2-with-lora:v0.2" imagePullPolicy: IfNotPresent command: ["python3", "-m", "vllm.entrypoints.openai.api_server"] args: - "--model" - "/model/llama2" - "--tensor-parallel-size" - "1" - "--port" - "8000" - '--gpu_memory_utilization' - '0.8' - "--enable-lora" - "--max-loras" - "4" - "--max-cpu-loras" - "12" - "--lora-modules" - 'sql-lora=/adapters/yard1/llama-2-7b-sql-lora-test_0' - 'sql-lora-1=/adapters/yard1/llama-2-7b-sql-lora-test_1' - 'sql-lora-2=/adapters/yard1/llama-2-7b-sql-lora-test_2' - 'sql-lora-3=/adapters/yard1/llama-2-7b-sql-lora-test_3' - 'sql-lora-4=/adapters/yard1/llama-2-7b-sql-lora-test_4' - 'tweet-summary=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_0' - 'tweet-summary-1=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_1' - 'tweet-summary-2=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_2' - 'tweet-summary-3=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_3' - 'tweet-summary-4=/adapters/vineetsharma/qlora-adapter-Llama-2-7b-hf-TweetSumm_4' - '--chat-template' - '/etc/vllm/llama-2-chat.jinja' env: - name: PORT value: "8000" ports: - containerPort: 8000 name: http protocol: TCP livenessProbe: // liveness プローブの設定 failureThreshold: 2400 httpGet: path: /health port: http scheme: HTTP initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 readinessProbe: // readiness プローブの設定 failureThreshold: 6000 httpGet: path: /health port: http scheme: HTTP initialDelaySeconds: 5 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: // リソース制限とリクエストの設定 limits: nvidia.com/gpu: 1 requests: nvidia.com/gpu: 1 volumeMounts: // ボリュームマウントの設定 - mountPath: /data name: data - mountPath: /dev/shm name: shm - mountPath: /etc/vllm name: chat-template restartPolicy: Always schedulerName: default-scheduler terminationGracePeriodSeconds: 30 volumes: // ボリュームの設定 - name: data emptyDir: {} - name: shm emptyDir: medium: Memory - name: chat-template configMap: name: chat-templateデータプレーン上のクラスタの kubeconfig ファイルを使用して、LLM 推論サービスをデプロイします。
kubectl apply -f vllm-service.yaml
手順 2:ASM ゲートウェイルールを構成する
ASM ゲートウェイでポート 8080 のリスニングを有効にするゲートウェイルールをデプロイします。
次の内容で gateway.yaml という名前のファイルを作成します。
apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: llm-inference-gateway namespace: default spec: selector: istio: ingressgateway servers: - hosts: - '*' port: name: http-service number: 8080 protocol: HTTPゲートウェイルールを作成します。
kubectl apply -f gateway.yaml
手順 3:LLM 推論サービスのルーティングと負荷分散を構成する
従来の負荷分散と LLM 負荷分散のパフォーマンスを比較するには、「(オプション) 可観測性ダッシュボードを使用して従来の負荷分散とパフォーマンスを比較する」の手順を完了してから、さらに操作を進めてください。
ASM の kubeconfig ファイルを使用して、LLM 推論サービスのルーティングを有効にします。
kubectl patch asmmeshconfig default --type=merge --patch='{"spec":{"gatewayAPIInferenceExtension":{"enabled":true}}}'InferencePool リソースをデプロイします。
InferencePool リソースは、ラベルセレクターを使用して、クラスタ内の一連の LLM 推論サービスのワークロードを定義します。 ASM は、作成された InferencePool に基づいて vLLM 負荷分散を適用します。
次の内容で inferencepool.yaml という名前のファイルを作成します。
apiVersion: inference.networking.x-k8s.io/v1alpha1 kind: InferencePool metadata: name: vllm-llama2-7b-pool spec: targetPortNumber: 8000 selector: app: vllm-llama2-7b-pool次の表は、いくつかの設定項目について説明しています。
設定項目
説明
.spec.targetPortNumber
推論サービスを提供する Pod によって公開されるポート。
.spec.selector
推論サービスを提供する Pod ラベル。ラベルキーは app でなければならず、値は対応するサービス名でなければなりません。
データプレーン上のクラスタの kubeconfig ファイルを使用して、InferencePool リソースを作成します。
kubectl apply -f inferencepool.yaml
InferenceModel リソースをデプロイします。
InferenceModel は、InferencePool リソース内の特定のモデルのトラフィック分散ポリシーを指定します。
次の内容を使用して inferencemodel.yaml という名前のファイルを作成します。
apiVersion: inference.networking.x-k8s.io/v1alpha1 kind: InferenceModel metadata: name: inferencemodel-sample spec: modelName: tweet-summary poolRef: group: inference.networking.x-k8s.io kind: InferencePool name: vllm-llama2-7b-pool targetModels: - name: tweet-summary weight: 100次の表は、いくつかの設定項目について説明しています。
設定項目
説明
.spec.modelName
リクエスト内の model パラメーターと照合するために使用されます。
.spec.targetModels
トラフィックルーティングルールを構成します。上記の例では、リクエストヘッダーに model: tweet-summary が含まれるトラフィックは 100%、tweet-summary モデルを実行している Pod に送信されます。
InferenceModel リソースを作成します。
kubectl apply -f inferencemodel.yaml
LLMRoute リソースを作成します。
InferencePool リソースを参照することで、ポート 8080 で受信したすべてのリクエストをサンプル LLM 推論サービスに転送するようにゲートウェイのルーティングルールを設定します。
次の内容で llmroute.yaml という名前のファイルを作成します。
apiVersion: istio.alibabacloud.com/v1 kind: LLMRoute metadata: name: test-llm-route spec: gateways: - llm-inference-gateway host: test.com rules: - backendRefs: - backendRef: group: inference.networking.x-k8s.io kind: InferencePool name: vllm-llama2-7b-poolLLMRoute リソースをデプロイします。
kubectl apply -f llmroute.yaml
手順 4:確認する
次のコマンドを複数回実行してテストを実行します。
curl -H "host: test.com" ${ASM Gateway IP}:8080/v1/completions -H 'Content-Type: application/json' -d '{
"model": "tweet-summary",
"prompt": "Write as if you were a critic: San Francisco",
"max_tokens": 100,
"temperature": 0
}' -v予期される出力:
{"id":"cmpl-2fc9a351-d866-422b-b561-874a30843a6b","object":"text_completion","created":1736933141,"model":"tweet-summary","choices":[{"index":0,"text":", I'm a newbie to this forum. Write a summary of the article.\nWrite a summary of the article.\nWrite a summary of the article. Write a summary of the article. Write a summary of the article. Write a summary of the article. Write a summary of the article. Write a summary of the article. Write a summary of the article. Write a summary of the article. Write a summary of the article. Write a summary","logprobs":null,"finish_reason":"length","stop_reason":null,"prompt_logprobs":null}],"usage":{"prompt_tokens":2,"total_tokens":102,"completion_tokens":100,"prompt_tokens_details":null}}(オプション) 手順 5:LLM サービスの可観測性メトリックとダッシュボードを構成する
InferencePool リソースと InferenceMode リソースを使用してクラスタ内の LLM 推論サービスを宣言し、ルーティングポリシーを設定した後、ログとモニタリングメトリックを通じて LLM 推論サービスの可観測性を表示できます。
ASM コンソールで LLM トラフィック可観測性機能を有効にして、モニタリングメトリックを収集します。
追加のログフィールド、メトリック、およびメトリックディメンションを組み込むことで、LLM 推論リクエストの可観測性を向上させます。詳細な構成手順については、「トラフィック観測:ASM を使用した LLM トラフィックの効率的な管理」をご参照ください。
構成が完了すると、
modelディメンションが ASM モニタリングメトリックに組み込まれます。これらのメトリックは、可観測性モニタリングフレームワーク内で Prometheus を使用するか、サービスメッシュモニタリング用にセルフホスト型 Prometheus を統合することで収集できます。ASM は、すべての要求の入力トークン数を表す
asm_llm_proxy_prompt_tokensと出力トークン数を表すasm_llm_proxy_completion_tokensという 2 つの新しいメトリックを導入しています。これらのメトリックは、Prometheus に次のルールを追加することで組み込むことができます。詳細については、「その他の Prometheus サービスディスカバリ構成」をご参照ください。scrape_configs: - job_name: asm-envoy-stats-llm // ジョブ名 scrape_interval: 30s // スクレイピング間隔 scrape_timeout: 30s // スクレイピングタイムアウト metrics_path: /stats/prometheus // メトリックパス scheme: http // スキーム kubernetes_sd_configs: - role: pod // Kubernetes サービスディスカバリのロール relabel_configs: - source_labels: - __meta_kubernetes_pod_container_port_name action: keep regex: .*-envoy-prom - source_labels: - __address__ - __meta_kubernetes_pod_annotation_prometheus_io_port action: replace regex: ([^:]+)(?::\d+)?;(\d+) replacement: $1:15090 target_label: __address__ - action: labelmap regex: __meta_kubernetes_pod_label_(.+) - source_labels: - __meta_kubernetes_namespace action: replace target_label: namespace - source_labels: - __meta_kubernetes_pod_name action: replace target_label: pod_name metric_relabel_configs: - action: keep source_labels: - __name__ regex: asm_llm_.*
vLLM サービスのモニタリングメトリックを収集します。
LLM 推論リクエストのモニタリングメトリックには、主に外部 LLM 推論リクエストのスループットが含まれます。 vLLM サービス pod に Prometheus コレクターのアノテーションを追加して、vLLM サービスによって公開されたメトリックを収集し、その内部状態を監視します。
... annotations: prometheus.io/path: /metrics # メトリックが公開される HTTP パス。 prometheus.io/port: "8000" # メトリックが公開されるポート。vLLM サーバーのリスニングポートです。 prometheus.io/scrape: "true" # 現在の pod のメトリックをスクレイピングするかどうか。 ...Prometheus のデフォルトのサービスディスカバリメカニズムを使用して、vLLM サービスに関連するメトリックを取得します。詳細な手順については、「デフォルトのサービスディスカバリ」をご参照ください。
vLLM サービスからの主要なメトリックは、vLLM ワークロードの内部状態に関する洞察を提供します。
メトリック名
説明
vllm:gpu_cache_usage_perc
vLLM の GPU キャッシュ使用率です。vLLM が起動すると、KV キャッシュのために可能な限り多くの GPU ビデオメモリを事前に占有します。 vLLM サーバーの場合、キャッシュ使用率が低いほど、GPU が新しいリクエストにリソースを割り当てるためのスペースが増えます。
vllm: リクエストキュー時間 (秒) の合計
待機状態キューでの所要時間です。LLM 推論リクエストが vLLM サーバーに到着した後、すぐに処理されずに、vLLM スケジューラがプリフィルとデコードをスケジュールするのを待つ必要がある場合があります。
vllm:num_requests_running
vllm:num_requests_waiting
vllm:num_requests_swapped
推論を実行中、待機中、およびメモリにスワップされたリクエストの数です。 vLLM サービスの現在のリクエスト負荷を評価するために使用できます。
vllm:avg_generation_throughput_toks_per_s
vllm:avg_prompt_throughput_toks_per_s
プリフィルステージで消費され、デコードステージで生成される 1 秒あたりのトークン数。
vllm: トークン初回受信時間 (秒) バケット
リクエストが vLLM サービスに送信されてから最初のトークンが応答されるまでの待機時間レベル。 このメトリックは通常、クライアントがリクエストコンテンツを出力してから最初の応答を取得するまでにかかる時間を表し、LLM ユーザーエクスペリエンスに影響を与える重要なメトリックです。
Grafana ダッシュボードをデプロイして、LLM 推論サービスの可観測性を視覚化します。
vLLM でデプロイされた LLM 推論サービスを Grafana ダッシュボードで監視します。
開始するには、次の手順に従います。
vLLM モニタリング メトリックを使用して、LLM 推論サービスのワークロードの内部状態を評価します。
Grafana コンソールでデータソース (Prometheus インスタンス) を作成できます。ASM とvLLM の監視メトリクスが Prometheus インスタンスによって収集されていることを確認してください。
LLM 推論サービスの可観測性ダッシュボードを作成するには、以下に提供される内容を Grafana にインポートしてください。
次のようなダッシュボードが表示されます。

(オプション) 可観測性ダッシュボードを使用して従来の負荷分散とパフォーマンスを比較する
可観測性ダッシュボードを使用すると、LLM 推論サービスの負荷分散のパフォーマンスと、キャッシュ使用率、リクエスト キュー時間、トークン スループット、ttft などのメトリックを含む従来の負荷分散アルゴリズムを直接比較できます。
次のコマンドを実行して、サンプル LLM 推論サービスにルーティングと従来の負荷分散を提供する仮想サービスを作成します。
kubectl apply -f- <<EOF apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: llm-vs namespace: default spec: gateways: - default/llm-inference-gateway hosts: - '*' http: - name: any-host route: - destination: host: vllm-llama2-7b-pool.default.svc.cluster.local port: number: 8000 EOFllmperf ツールを使用して、LLM 推論サービスのストレステストを実行します。
Grafana ダッシュボードを使用して、2 つのルーティングと負荷分散ポリシーを分析します。
この比較は、LLM 推論サービスの負荷分散が、より優れたレイテンシ、スループット、およびキャッシュ使用率を提供することを示しています。
