このトピックでは、DataCache を使用して DeepSeek-R1 シリーズモデルを Elastic Container Instance にデプロイする方法について説明します。また、カスタムメトリックに基づいてポッドのスケーリングを実装するために Horizontal Pod Autoscaler (HPA) を構成する方法についても説明します。この例では、DeepSeek-R1-Distill-Qwen-7B を使用します。
DeepSeek のデプロイに Elastic Container Instance を使用する理由
Elastic Container Instance は O&M が不要で、柔軟にデプロイでき、弾力性があり費用対効果の高いビジネスの構築に役立ちます。詳細については、「利点」をご参照ください。
Elastic Container Instance は DataCache と ImageCache を使用して、イメージのプルとモデルのダウンロードにかかる時間を節約し、ネットワークリソースの消費を削減し、システム効率を向上させます。
説明コンテナ化された大規模モデル推論サービスのデプロイには、コンテナの作成と起動、イメージのプル、モデルファイルのダウンロード、モデルのロードと起動という段階が含まれます。大規模モデル推論サービスのイメージとモデルはサイズが大きいため、イメージとモデルのプルには長時間の時間と大量のネットワークトラフィックが必要です。たとえば、vLLM イメージのサイズは約 16.5 GB で、DeepSeek-R1-Distill-Qwen-7B モデルのサイズは約 14 GB です。Elastic Container Instance は、DataCache と ImageCache を使用して、イメージのプルとモデルのダウンロードにかかる時間を節約します。
前提条件
DataCache カスタムリソース定義 (CRD) がクラスターにデプロイされています。詳細については、「DataCache CRD のデプロイ」をご参照ください。
クラスターが存在する仮想プライベートクラウド (VPC) がインターネット NAT ゲートウェイに関連付けられています。VPC 内のリソースまたは VPC 内の vSwitch に接続されているリソースがインターネットにアクセスできるように、インターネット NAT ゲートウェイ用に SNAT エントリが構成されています。
説明VPC がインターネット NAT ゲートウェイに関連付けられていない場合は、DataCache を作成してアプリケーションをデプロイするときに、VPC に Elastic IP アドレス (EIP) を関連付ける必要があります。このようにして、インターネットからデータをプルできます。
ARMS Prometheus コンポーネント (ack-arms-prometheus) がクラスターにインストールされています。詳細については、「Managed Service for Prometheus の使用」をご参照ください。
ack-alibaba-cloud-metrics-adapter コンポーネントがクラスターにデプロイされています。
ack-Alibaba-cloud-metrics-adapter をデプロイするには、Container Service for Kubernetes (ACK) コンソールにログインします。左側のナビゲーションウィンドウで、 を選択します。マーケットプレイスページで、ack-alibaba-cloud-metrics-adapter を見つけてデプロイします。
KServe がクラスターにデプロイされています。
KServe は Kubernetes ベースの機械学習モデルサービスフレームワークです。KServe を使用すると、Kubernetes CRD を使用して、トレーニング済みの 1 つ以上のモデルをモデルサービスランタイムにデプロイできます。詳細については、「ack-kserve のインストール」をご参照ください。
ランタイム環境を準備する
DeepSeek モデルごとに、ランタイム環境の要件が異なります。このトピックでは、DeepSeek-R1-Distill-Qwen-7B モデルを使用します。
推奨仕様
Elastic Container Instance ベースのポッドの作成に使用する GPU アクセラレーション Elastic Compute Service (ECS) インスタンスファミリは、次の条件を満たしている必要があります。ポッドの作成に使用できる GPU アクセラレーション ECS インスタンスファミリの詳細については、「サポートされているインスタンスファミリ」をご参照ください。
CPU: 厳密な制限なし
メモリサイズ: 16 GiB 以上
GPU の数: 1 以上
GPU メモリのサイズ: 20 GB 以上。たとえば、A10 GPU は要件を満たしています。GPU メモリサイズが 20 GB 未満の場合、メモリ不足 (OOM) エラーが発生する可能性があります。
ソフトウェア要件
大規模モデルのデプロイは、多数のライブラリと構成に依存します。vLLM は主流の大規模モデル推論エンジンであり、このトピックでは推論サービスのデプロイに使用されます。Elastic Container Instance はパブリックコンテナイメージを提供します。パブリックコンテナイメージを直接使用するか、パブリックコンテナイメージに基づいて二次開発を行うことができます。イメージアドレスは
registry.cn-hangzhou.aliyuncs.com/eci_open/vllm-openai:v0.7.2
です。イメージサイズは約 16.5 GB です。
ステップ 1: DataCache を作成する
DeepSeek を初めてデプロイするときは、モデルデータをプルする必要がないように、事前に DataCache を作成する必要があります。これにより、DeepSeek のデプロイが高速化されます。
Hugging Face にアクセスして、モデルの ID を取得します。
このトピックでは、DeepSeek-R1-Distill-Qwen-7B のメインバージョンを使用します。Hugging Face でモデルを見つけ、モデル詳細ページの上部にあるモデルの ID をコピーします。
DataCache の YAML 構成ファイルを記述します。次に、YAML ファイルを使用して DataCache を作成し、DeepSeek-R1-Distill-Qwen-7B モデルデータをプルして DataCache に保存します。
kubectl create -f datacache-test.yaml
datacache-test.yaml という名前の DataCache YAML 構成ファイルの例。
apiVersion: eci.aliyun.com/v1alpha1 kind: DataCache metadata: name: deepseek-r1-distill-qwen-7b spec: bucket: test path: /model/deepseek-r1-distill-qwen-7b dataSource: type: URL options: repoSource: HuggingFace/Model # データソースが Hugging Face であるモデルを指定します。 repoId: deepseek-ai/DeepSeek-R1-Distill-Qwen-7B # モデルの ID を指定します。 revision: main # モデルのバージョンを指定します。 netConfig: securityGroupId: sg-bp1*********** vSwitchId: vsw-bp1uo************ # SNAT エントリが構成されている vSwitch を指定します。 # モデルのインターネットアクセスを有効にするために vSwitch に SNAT エントリが構成されていない場合は、Elastic IP アドレス (EIP) を作成して vSwitch に関連付ける必要があります。 eipCreateParam: bandwidth: 5 # EIP 帯域幅
DataCache のステータスをクエリします。
kubectl get edc
モデルデータがダウンロードされ、DataCache のステータスが Available になると、DataCache を使用できるようになります。Alibaba Cloud は DeepSeek-R1 シリーズモデルのホットロード機能を提供しており、これにより DataCache が数秒で作成されます。
NAME AGE DATACACHEID STATUS PROGRESS BUCKET PATH deepseek-r1-distill-qwen-7b 40s edc-uf6btsb4q5j4b9ue**** Available 100% test /model/deepseek-r1-distill-qwen-7b
ステップ 2: ack-alibaba-cloud-metrics-adapter のルールを構成する
カスタムメトリックベースの自動スケーリングは、ack-alibaba-cloud-metrics-adapter コンポーネントと ACK が提供する Kubernetes HPA メカニズムに基づいて実装されます。次の表に、HPA でサポートされている GPU メトリックを示します。詳細については、「GPU メトリックに基づく自動スケーリングの有効化」をご参照ください。
メトリック | 説明 | 単位 |
DCGM_FI_DEV_GPU_UTIL | GPU カードの使用率。このメトリックは、排他モードでスケジュールされている GPU でのみ使用できます。 | % |
DCGM_FI_DEV_FB_USED | GPU カードの使用済みメモリ。このメトリックは、排他モードでスケジュールされている GPU でのみ使用できます。 | MiB |
DCGM_CUSTOM_PROCESS_SM_UTIL | ポッドの GPU 使用率。 | % |
DCGM_CUSTOM_PROCESS_MEM_USED | ポッドに割り当てられている GPU メモリの使用量。 | MiB |
ACK コンソール にログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。[クラスター] ページで、クラスターの名前をクリックします。
クラスター管理ページの左側のナビゲーションウィンドウで、
を選択します。[Helm] ページで、ack-alibaba-cloud-metrics-adapter の [アクション] 列の [更新] をクリックします。
custom
フィールドに次のrules
を追加します。
ステップ 3: スケーラブルな DeepSeek モデル推論サービスをデプロイする
DeepSeek アプリケーションの YAML 構成ファイルを記述し、YAML ファイルに基づいてアプリケーションをデプロイします。
kubectl create -f deepseek-r1-7b-kserve.yaml
次のサンプルコードは、deepseek-r1-7b-kserve.yaml ファイルの内容を示しています。ファイルの説明:
ポッドは GPU アクセラレーション ECS インスタンスタイプに基づいており、DeepSeek-R1-Distill-Qwen-7B モデルがマウントされています。
InferenceService のプレディクターは、vLLM を含むイメージを使用します。コンテナが起動されると、コンテナは
vllm serve /deepseek-r1-7b --tensor-parallel-size 1 --max-model-len 24384 --enforce-eager
を実行して OpenAI-Compatible Server を起動します。スケーリングは、ポッドの GPU 使用率を示す DCGM_CUSTOM_PROCESS_SM_UTIL メトリックに基づいて予測されます。平均 GPU 使用率が 50% に達すると、HPA は自動的にポッドをスケールアウトします。ポッドの合計最大数は、
maxReplicas
の値を超えることはできません。
apiVersion: serving.kserve.io/v1beta1 kind: InferenceService metadata: name: deepseek-r1-7b-kserve labels: alibabacloud.com/eci: "true" annotations: serving.kserve.io/autoscalerClass: external k8s.aliyun.com/eci-use-specs: ecs.gn7i-c16g1.4xlarge,ecs.gn7i-c32g1.8xlarge # GPU アクセラレーション ECS インスタンスタイプを指定します。ポッドの作成成功率を高めるために、複数の ECS インスタンスタイプを指定できます。 k8s.aliyun.com/eci-extra-ephemeral-storage: "20Gi" # ポッドの起動は大きなフレームワークに依存するため、追加の一時記憶領域を指定します。追加の一時記憶領域に対して課金されます。 k8s.aliyun.com/eci-data-cache-bucket: "test" # DataCache を格納するバケットを指定します。 # より高速なロード速度が必要な場合は、AutoPL ディスクを使用できます。 k8s.aliyun.com/eci-data-cache-provisionedIops: "15000" # 拡張 SSD (ESSD) AutoPL ディスクにプロビジョニングされる IOPS を指定します。 k8s.aliyun.com/eci-data-cache-burstingEnabled: "true" # アプリケーションの起動を高速化するために、ESSD AutoPL ディスクのパフォーマンスバースト機能を有効にします。 spec: predictor: containers: - name: vllm command: - /bin/sh args: - -c - vllm serve /deepseek-r1-7b --port 8080 --tensor-parallel-size 1 --max-model-len 24384 --enforce-eager image: registry-vpc.cn-hangzhou.aliyuncs.com/eci_open/vllm-openai:v0.7.2 resources: limits: cpu: "16" memory: "60Gi" nvidia.com/gpu: "1" requests: cpu: "16" memory: "60Gi" nvidia.com/gpu: "1" volumeMounts: - mountPath: /deepseek-r1-7b # モデルのパスを指定します。 name: llm-model volumes: - name: llm-model hostPath: path: /model/deepseek-r1-distill-qwen-7b # DataCache のマウントパスを指定します。 --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: deepseek-r1-7b-kserve-predictor namespace: default spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: deepseek-r1-7b-kserve-predictor metrics: - pods: metric: name: DCGM_CUSTOM_PROCESS_SM_UTIL # 監視するメトリックの名前を指定します。 target: type: Utilization # ターゲット値のタイプ (使用率または生の値など) を定義します。 averageValue: '50' # メトリックのターゲット平均値を設定します。 type: Pods minReplicas: 1 # Running 状態のポッドの最小数を指定します。 maxReplicas: 100 # ポッドの最大許容数を指定します。
予期される出力:
inferenceservice.serving.kserve.io/deepseek-r1-7b-kserve created horizontalpodautoscaler.autoscaling/deepseek-r1-7b-kserve-predictor created
アプリケーションがデプロイされているかどうかを確認します。
kubectl get pods --selector=app=isvc.deepseek-r1-7b-kserve-predictor
予期される出力:
NAME READY STATUS RESTARTS AGE deepseek-r1-7b-kserve-predictor-6785df7b7f-r7kjx 1/1 Running 0 116s
ステップ 4: モデルの推論効果をテストする
DeepSeek 推論アプリケーションで使用される Server Load Balancer (SLB) インスタンスの IP アドレスとホスト名を取得し、IP アドレスとホスト名を変数として設定します。
NGINX_INGRESS_IP=$(kubectl -n kube-system get svc nginx-ingress-lb -ojsonpath='{.status.loadBalancer.ingress[0].ip}') SERVICE_HOSTNAME=$(kubectl get inferenceservice deepseek-r1-7b-kserve -o jsonpath='{.status.url}' | cut -d "/" -f 3)
DeepSeek モデル推論サービスをテストします。
DeepSeek モデル推論サービスにリクエストを送信します。例:
curl POST http://$NGINX_INGRESS_IP:80/v1/chat/completions \ -H "Host: $SERVICE_HOSTNAME" \ -H "Content-Type: application/json" \ -d '{ "model": "/deepseek-r1-7b", "messages": [ { "role": "user", "content": "Briefly describe containers in one sentence" } ], "temperature": 0.6, "max_tokens": 3000 }' \ --verbose
予期される出力:
{"id":"chatcmpl-56e6ff393d999571ce6ead1b72f9302d","object":"chat.completion","created":1739340308,"model":"/deepseek-r1-7b","choices":[{"index":0,"message":{"role":"assistant","reasoning_content":null,"content":"<think>\n 1 文でコンテナについて簡単に説明する必要があります。コンテナとは何ですか? プログラミング、特に Docker では、コンテナはアプリケーションを独立して実行できる隔離された環境のようです。コンテナ化により、開発とデプロイが容易になりますよね? したがって、コンテナは、アプリケーションを依存関係から分離できる軽量のランタイムであり、開発とデプロイのプロセスをより効率的にする必要があります。そうですか? したがって、コンテナの 1 文の紹介では、コンテナの分離、軽量、独立動作の機能について説明する必要があります。クラウドネイティブサービスやマイクロサービスアーキテクチャなどのコンテナ化テクノロジーのアプリケーションシナリオについても言及される場合があります。さて、これらのアイデアを 1 つの文にまとめる必要があります。\n</think>\n\nコンテナは、アプリケーションを独立して実行できる隔離されたランタイム環境であり、軽量で効率的なリソース管理を提供し、クラウドネイティブサービスとマイクロサービスアーキテクチャをサポートします。","tool_calls":[]},"logprobs":null,"finish_reason":"stop","stop_reason":null}],"usage":{"prompt_tokens":8,"total_tokens":168,"completion_tokens":160,"prompt_tokens_details":null},"prompt_logprobs":null}
<think></think>
内のコンテンツは、モデルが最終的な回答を生成する前の思考プロセスまたは推論ステップを表します。これらのマーカーは最終出力の一部ではなく、モデルが回答を生成する前の自己プロンプトまたは論理推論の記録です。抽出された最終回答:
コンテナは、アプリケーションを独立して実行できる隔離されたランタイム環境であり、軽量で効率的なリソース管理を提供し、クラウドネイティブサービスとマイクロサービスアーキテクチャをサポートします。
メトリック値がスケーリングしきい値を超えたときに HPA がポッドをスケールアウトするかどうかをテストします。
次のコマンドを実行して、クラスター内のポッドの数をクエリします。
kubectl get pods --selector=app=isvc.deepseek-r1-7b-kserve-predictor
次の出力は、クラスターに 1 つのポッドが含まれていることを示しています。
NAME READY STATUS RESTARTS AGE deepseek-r1-7b-kserve-predictor-6785df7b7f-r7kjx 1/1 Running 0 6m54s
次のコマンドを実行して、HPA のステータスをクエリします。
kubectl get hpa
予期される出力:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE deepseek-r1-7b-kserve-predictor Deployment/deepseek-r1-7b-kserve-predictor 9/50 1 100 1 8m
hey を使用してストレステストを実行します。
hey の詳細については、「hey」をご参照ください。
hey -z 2m -c 20 -m POST -host $SERVICE_HOSTNAME -H "Content-Type: application/json" -d '{"model": "/deepseek-r1-7b", "messages": [{"role": "user", "content": "hello world!"}], "max_tokens": 512, "temperature": 0.7, "top_p": 0.9, "seed": 10}' http://$NGINX_INGRESS_IP:80/v1/chat/completions
クラスター内のポッドの数をクエリして、HPA がポッドをスケールアウトしたかどうかを確認します。
kubectl get pods --selector=app=isvc.deepseek-r1-7b-kserve-predictor
次の出力は、HPA がポッドをスケールアウトしたことを示しています。
NAME READY STATUS RESTARTS AGE deepseek-r1-7b-kserve-predictor-6785df7b7f-r7kjx 1/1 Running 0 8m5s deepseek-r1-7b-kserve-predictor-6785df7b7f-6l2kj 1/1 Running 0 104s deepseek-r1-7b-kserve-predictor-6785df7b7f-3q5dz 1/1 Running 0 104s
次のコマンドを実行して、HPA のステータスをクエリします。
kubecl get hpa
予期される出力:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE deepseek-r1-7b-kserve-predictor Deployment/deepseek-r1-7b-kserve-predictor 5/50 1 100 3 10m