前のドキュメントで説明した LLM リクエストルーティング機能に加えて、Alibaba Cloud Service Mesh(ASM)は、LLM シナリオにおける高度な可観測性要件を満たすために、可観測性機能をさらに強化しました。このトピックでは、ASM コンソールでアクセスログと監視メトリクスを使用して LLM リクエストを監視する方法について説明します。
トラフィック管理のための多様なオプションを提供するために、このトピックの手順は、トラフィックルーティング:ASM を使用して LLM トラフィックを効率的に管理する のすべての手順に基づいて準備されています。手順 1 と 手順 2 のみを実行した場合は、手順 2 のテストコマンドを実行して、観測可能データを取得するためのコマンドがこのトピックで説明されているものと同じかどうかを確認できます。
手順 1:アクセスログを使用して LLM リクエストを監視する
アクセスログを設定する
ASM は、LLM リクエストログのサポートを強化しました。カスタムアクセスログを設定して、リクエストログを表示できます。詳細な手順については、カスタムデータプレーンアクセスログ をご参照ください。
ASM コンソール にログインします。左側のナビゲーションペインで、 を選択します。
[メッシュ管理] ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションペインで、 を選択します。
グローバル [ログ設定] で、以下に示すように 3 つのフィールドを追加します。
テキストコンテンツは次のとおりです。
request_model FILTER_STATE(wasm.asm.llmproxy.request_model:PLAIN) // 現在のLLMリクエストで使用されるモデル request_prompt_tokens FILTER_STATE(wasm.asm.llmproxy.request_prompt_tokens:PLAIN) // 現在のリクエストの入力トークンの数 request_completion_tokens FILTER_STATE(wasm.asm.llmproxy.request_completion_tokens:PLAIN) // 現在のリクエストの出力トークンの数
これらのフィールドは次のとおりです。
request_model:現在の LLM リクエストで使用されるモデル。たとえば、qwen-turbo または qwen1.5-72b-chat。
request_prompt_tokens:現在のリクエストの入力トークンの数。
request_completion_tokens:現在のリクエストの出力トークンの数。
ほとんどの大規模モデルサービスプロバイダーは、通常、トークンの使用量に応じて課金します。これらのフィールドを使用すると、ユーザーはリクエスト中に消費されたトークンの数を確認し、使用中の特定のモデルを識別できます。
検証
ACK クラスタの kubeconfig ファイルを使用して、次の 2 つのコマンドを別々に実行します。
kubectl exec deployment/sleep -it -- curl --location 'http://dashscope.aliyuncs.com' \ --header 'Content-Type: application/json' \ --data '{ "messages": [ {"role": "user", "content": "Please introduce yourself."} // 自分を紹介してください。 ] }'
kubectl exec deployment/sleep -it -- curl --location 'http://dashscope.aliyuncs.com' \ --header 'Content-Type: application/json' \ --header 'user-type: subscriber' \ --data '{ "messages": [ {"role": "user", "content": "Please introduce yourself."} // 自分を紹介してください。 ] }'
次のコマンドを実行して、アクセスログを表示します。
kubectl logs deployments/sleep -c istio-proxy | tail -2
予期される出力:
{"bytes_received":"85","bytes_sent":"617","downstream_local_address":"47.93.xxx.xx:80","downstream_remote_address":"192.168.34.235:39066","duration":"7640","istio_policy_status":"-","method":"POST","path":"/compatible-mode/v1/chat/completions","protocol":"HTTP/1.1","request_id":"d0e17f66-f300-411a-8c32-xxxxxxxxxxxxx","requested_server_name":"-","response_code":"200","response_flags":"-","route_name":"-","start_time":"2024-07-12T03:20:03.993Z","trace_id":"-","upstream_cluster":"outbound|80||dashscope.aliyuncs.com","upstream_host":"47.93.xxx.xx:443","upstream_local_address":"192.168.34.235:38476","upstream_service_time":"7639","upstream_response_time":"7639","upstream_transport_failure_reason":"-","user_agent":"curl/8.8.0","x_forwarded_for":"-","authority_for":"dashscope.aliyuncs.com","request_model":"qwen1.5-72b-chat","request_prompt_tokens":"3","request_completion_tokens":"55"} {"bytes_received":"85","bytes_sent":"809","downstream_local_address":"47.93.xxx.xx:80","downstream_remote_address":"192.168.34.235:41090","duration":"2759","istio_policy_status":"-","method":"POST","path":"/compatible-mode/v1/chat/completions","protocol":"HTTP/1.1","request_id":"d89faada-6af3-4ac3-b4fd-xxxxxxxxxxxxx","requested_server_name":"-","response_code":"200","response_flags":"-","route_name":"vip-route","start_time":"2024-07-12T03:20:30.854Z","trace_id":"-","upstream_cluster":"outbound|80||dashscope.aliyuncs.com","upstream_host":"47.93.xxx.xx:443","upstream_local_address":"192.168.34.235:38476","upstream_service_time":"2759","upstream_response_time":"2759","upstream_transport_failure_reason":"-","user_agent":"curl/8.8.0","x_forwarded_for":"-","authority_for":"dashscope.aliyuncs.com","request_model":"qwen-turbo","request_prompt_tokens":"11","request_completion_tokens":"90"}
フォーマットおよび処理されたログは次のようになります。
{ "duration": "7640", "response_code": "200", "authority_for": "dashscope.aliyuncs.com", // アクセスされた実際の大規模モデルプロバイダー "request_model": "qwen1.5-72b-chat", // 現在のリクエストで使用されるモデル "request_prompt_tokens": "3", // 現在のリクエストの入力トークンの数 "request_completion_tokens": "55" // 現在のリクエストの出力トークンの数 }
{ "duration": "2759", "response_code": "200", "authority_for": "dashscope.aliyuncs.com", // アクセスされた実際の大規模モデルプロバイダー "request_model": "qwen-turbo", // 現在のリクエストで使用されるモデル "request_prompt_tokens": "11", // 現在のリクエストの入力トークンの数 "request_completion_tokens": "90" // 現在のリクエストの出力トークンの数 }
ASM は Alibaba Cloud Simple Log Service(SLS)とシームレスに統合されているため、アクセスログを介してリクエストレベルの LLM 呼び出しを監視できます。さらに、これらのログは直接収集および保存できます。アクセスログを有効にすると、カスタムアラートルールを作成し、詳細なログダッシュボードを設計できます。詳細については、データプレーンログ収集を有効にする をご参照ください。
手順 2:現在のワークロードで消費されたトークン数を表示するためのメトリクスを追加する
アクセスログは詳細なレコードを提供しますが、監視メトリクスはデータのより広いビューを提供します。ASM のメッシュプロキシは、ワークロードによって消費されたトークン数を監視メトリクスとして出力できるようになり、現在のワークロードのトークン使用量をリアルタイムで監視できるようになりました。
ASM は 2 つの新しいメトリクスを導入します。
asm_llm_proxy_prompt_tokens:入力トークンの数。
asm_llm_proxy_completion_tokens:出力トークンの数。
これらのメトリクスには、次のデフォルトディメンションが含まれています。
llmproxy_source_workload:リクエストを開始したワークロードの名前。
llmproxy_source_workload_namespace:リクエストを開始したサービスが存在する名前空間。
llmproxy_destination_service:宛先サービス。
llmproxy_model:現在のリクエストで使用されるモデル。
ワークロード設定を変更して新しいメトリクスを出力する
この手順では、デフォルトの名前空間にデプロイされた sleep を例として使用します。
ACK クラスタの kubeconfig ファイルを使用して、asm-llm-proxy-bootstrap-config.yaml という名前のファイルを作成します。
apiVersion: v1 kind: ConfigMap metadata: name: asm-llm-proxy-bootstrap-config data: custom_bootstrap.json: | "stats_config": { // 統計設定 "stats_tags":[ // 統計タグ { "tag_name": "llmproxy_source_workload", // ソースワークロード "regex": "(\\|llmproxy_source_workload=([^|]*))" }, { "tag_name": "llmproxy_source_workload_namespace", // ソースワークロードの名前空間 "regex": "(\\|llmproxy_source_workload_namespace=([^|]*))" }, { "tag_name": "llmproxy_destination_service", // 宛先サービス "regex": "(\\|llmproxy_destination_service=([^|]*))" }, { "tag_name": "llmproxy_model", // モデル "regex": "(\\|llmproxy_model=([^|]*))" } ] }
次のコマンドを実行して、asm-llm-proxy-bootstrap-config という名前の ConfigMap を作成します。
kubectl apply -f asm-llm-proxy-bootstrap-config.yaml
次のコマンドを使用して、pod にアノテーションを追加することで sleep を変更します。
kubectl patch deployment sleep -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/bootstrapOverride":"asm-llm-proxy-bootstrap-config"}}}}}'
検証
次のコマンドを使用してテストを実行します。
次のコマンドを実行して、sleep の Sidecar によって生成された Prometheus メトリクスを表示します。
kubectl exec deployments/sleep -it -c istio-proxy -- curl localhost:15090/stats/prometheus | grep llmproxy
予期される出力:
asm_llm_proxy_completion_tokens{llmproxy_source_workload="sleep",llmproxy_source_workload_namespace="default",llmproxy_destination_service="dashscope.aliyuncs.com",llmproxy_model="qwen1.5-72b-chat"} 72 asm_llm_proxy_completion_tokens{llmproxy_source_workload="sleep",llmproxy_source_workload_namespace="default",llmproxy_destination_service="dashscope.aliyuncs.com",llmproxy_model="qwen-turbo"} 85 asm_llm_proxy_prompt_tokens{llmproxy_source_workload="sleep",llmproxy_source_workload_namespace="default",llmproxy_destination_service="dashscope.aliyuncs.com",llmproxy_model="qwen1.5-72b-chat"} 3 asm_llm_proxy_prompt_tokens{llmproxy_source_workload="sleep",llmproxy_source_workload_namespace="default",llmproxy_destination_service="dashscope.aliyuncs.com",llmproxy_model="qwen-turbo"} 11
出力は、sidecar によって提供されるメトリクスとそれぞれのデフォルトディメンションを示しています。
ASM は ARMS サービスと統合され、設定された収集ルールを通じて Managed Service for Prometheus にメトリクスを収集できるようになりました。詳細な手順については、Managed Service for Prometheus にメトリクスを収集する をご参照ください。
手順 3:LLM 関連のディメンションを ASM ネイティブメトリクスに追加する
ASM はネイティブで、HTTP または TCP プロトコルを詳細に示すさまざまな メトリクス を提供します。これらのメトリクスには広範なディメンションが付属しており、ASM はこれらのメトリクスとディメンションを利用した堅牢な Prometheus ダッシュボードを開発しました。
ただし、これらのメトリクスには現在、LLM リクエストが含まれていません。この問題に対処するために、ASM は LLM リクエストのサポートを強化し、メトリクスディメンションをカスタマイズすることで既存のメトリクスに LLM リクエストを追加できるようにしました。
カスタムディメンションの設定:model
この例では、model ディメンションを REQUEST_COUNT メトリクスに追加します。
ASM コンソール にログインします。左側のナビゲーションペインで、 を選択します。
[メッシュ管理] ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションペインで、 を選択します。
[REQUEST_COUNT] を選択し、[ディメンションの編集] をクリックします。[カスタムディメンション] タブをクリックし、ディメンション名 に model を入力し、値 に
filter_state["wasm.asm.llmproxy.request_model"]
を入力します。
検証
次のコマンドを別々に実行してテストを実行します。
次のコマンドを実行して、sleep の Sidecar によって生成された Prometheus メトリクスを表示します。
kubectl exec deployments/sleep -it -c istio-proxy -- curl localhost:15090/stats/prometheus | grep llmproxy
予期される出力:
istio_requests_total{reporter="source",source_workload="sleep",source_canonical_service="sleep",source_canonical_revision="latest",source_workload_namespace="default",source_principal="unknown",source_app="sleep",source_version="",source_cluster="cce8d2c1d1e8d4abc8d5c180d160669cc",destination_workload="unknown",destination_workload_namespace="unknown",destination_principal="unknown",destination_app="unknown",destination_version="unknown",destination_service="dashscope.aliyuncs.com",destination_canonical_service="unknown",destination_canonical_revision="latest",destination_service_name="dashscope.aliyuncs.com",destination_service_namespace="unknown",destination_cluster="unknown",request_protocol="http",response_code="200",grpc_response_status="",response_flags="-",connection_security_policy="unknown",model="qwen1.5-72b-chat"} 1 istio_requests_total{reporter="source",source_workload="sleep",source_canonical_service="sleep",source_canonical_revision="latest",source_workload_namespace="default",source_principal="unknown",source_app="sleep",source_version="",source_cluster="cce8d2c1d1e8d4abc8d5c180d160669cc",destination_workload="unknown",destination_workload_namespace="unknown",destination_principal="unknown",destination_app="unknown",destination_version="unknown",destination_service="dashscope.aliyuncs.com",destination_canonical_service="unknown",destination_canonical_revision="latest",destination_service_name="dashscope.aliyuncs.com",destination_service_namespace="unknown",destination_cluster="unknown",request_protocol="http",response_code="200",grpc_response_status="",response_flags="-",connection_security_policy="unknown",model="qwen-turbo"} 1
model ディメンションが istio_requests_total メトリクスに正常に追加されました。
これらの監視メトリクスを使用すると、ARMS で分析ルールを設定して、より詳細な分析を行うことができます。たとえば、次のような分析が可能です。
特定のモデルへのリクエストの成功率。
特定のモデルまたはサービスプロバイダーの平均応答レイテンシ。
まとめ
トラフィックルーティング:ASM を使用して LLM トラフィックを効率的に管理する に基づいて、このトピックでは、LLM トラフィックの詳細な監視と全体的な監視の両方を行う方法について説明しました。クラスタ構成を少し調整するだけで、サービスメッシュ固有の多次元可観測性機能を利用できます。ASM はこれらの可観測性機能をさらに開発し、ますます包括的で適応性の高いソリューションを提供しています。