Container Compute Service (ACS) では、基盤となるハードウェアに関する深い知識や GPU インスタンスの管理は不要です。すべての構成はすぐに使用できます。ACS はデプロイが容易で、従量課金制です。LLM 推論サービスに適しており、推論コストを効率的に削減できます。このトピックでは、ACS で QwQ-32B モデルを使用してモデル推論サービスをデプロイし、Open WebUI を使用してサービスを表示する方法について説明します。
背景情報
QwQ-32B について
vLLM
Open WebUI
前提条件
Container Compute Service (ACS) を初めて使用する場合は、Alibaba Cloud アカウントを使用して ACS にデフォルトのロールを割り当てる必要があります。ACS にこれらのロールを割り当てた後にのみ、ACS は他のクラウドサービスのリソースを使用してクラスターを作成したり、ログファイルを保存したりできます。これらのクラウドサービスには、Elastic Compute Service (ECS)、Object Storage Service (OSS)、Apsara File Storage NAS (NAS)、Cloud Parallel File Storage (CPFS)、および Server Load Balancer (SLB) が含まれます。詳細については、「ACS を初めて使用する方向けのクイックスタート」をご参照ください。
Container Compute Service (ACS) を初めて使用する場合は、アカウントにデフォルトのロールを割り当てる必要があります。権限付与が完了した後にのみ、ACS は ECS、OSS、NAS、CPFS、SLB などの他のサービスを呼び出し、クラスターを作成し、ログを保存できます。詳細については、「ACS を初めて使用する方向けのクイックスタート」をご参照ください。
kubectl クライアントがクラスターに接続されています。詳細については、「クラスターの kubeconfig ファイルを取得し、kubectl を使用してクラスターに接続する」をご参照ください。
GPU インスタンスの仕様と推定コスト
GPU メモリは、推論フェーズでモデルパラメーターによって占有されます。使用量は、次の式に基づいて計算されます。
モデルには 320 億のパラメーターがあり、その精度のデータは 2 バイトです (デフォルトの 16 ビット浮動小数点数/バイトあたり 8 ビット)。
GPU メモリ = 32 x 109 x 2 バイト ≈ 59.6 GiB
モデルのロードに使用されるメモリに加えて、KV キャッシュのサイズと GPU 使用率も考慮する必要があります。通常、メモリの一定割合はバッファリング用に予約されています。したがって、推奨される仕様は、メモリ 80 GiB、vCPU 16 基、メモリ 128 GiB の GPU 1 基です。推奨仕様の表とGPU モデルと仕様も参照できます。ACS GPU インスタンスの課金の詳細については、「課金概要」をご参照ください。
ACS GPU インスタンスの仕様がACS ポッドの仕様調整ロジックに準拠していることを確認してください。
デフォルトでは、ACS ポッドは 30 GiB の無料 EphemeralStorage を提供します。この例で使用されている推論イメージinference-nv-pytorch:25.02-vllm0.7.2-sglang0.4.3.post2-pytorch2.5-cuda12.4-20250305-serverless のサイズは 9.5 GiB です。より多くのストレージ容量が必要な場合は、EphemeralStorage のサイズをカスタマイズします。詳細については、「EphemeralStorage を追加する」をご参照ください。
手順
チケットを送信すると、モデルファイルを取得し、サポートされている GPU モデルを表示することができます。
モデルファイル: QwQ-32B。モデルファイルのサイズは約 120 GiB です。通常、モデルファイルのダウンロードとアップロードには 2 ~ 3 時間かかります。チケットを送信して、モデルファイルを OSS バケットにコピーできます。
GPU モデル:
alibabacloud.com/gpu-model-series: <example-model>
ラベルの変数を、ACS でサポートされている実際の GPU モデルに置き換えます。詳細については、「ACS GPU ポッドの GPU モデルとドライバーバージョンを指定する」をご参照ください。高性能 RDMA ネットワーク: TCP/IP と比較して、高性能 RDMA はゼロコピーとカーネルバイパスを備えているため、ファイルコピーと頻繁なコンテキストスイッチオーバーを回避できます。RDMA は、レイテンシと CPU 使用率を削減し、スループットを向上させることができます。ACS では、
alibabacloud.com/hpn-type: "rdma"
ラベルを追加して RDMA を使用できます。RDMA をサポートするGPU モデルの詳細については、チケットを送信してください。
ステップ 1: モデルデータを準備する
LLM は、モデルファイルを保存するために大量のディスク容量を必要とします。NAS または OSS ボリュームを使用してモデルファイルを永続化することをお勧めします。次の例では、OSS ボリュームを使用して QwQ-32B モデルファイルを永続化します。
次のコマンドを実行して、QwQ-32B モデルをダウンロードします。
説明git-lfs プラグインがインストールされているかどうかを確認します。インストールされていない場合は、
yum install git-lfs
またはapt-get install git-lfs
を実行してインストールします。詳細については、「git-lfs をインストールする」をご参照ください。git lfs install GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/Qwen/QwQ-32B.git cd QwQ-32B git lfs pull
OSS ディレクトリを作成し、モデルファイルをディレクトリにアップロードします。
説明ossutil をインストールして使用するには、「ossutil をインストールする」をご参照ください。
ossutil mkdir oss://<your-bucket-name>/models/QwQ-32B ossutil cp -r ./QwQ-32B oss://<your-bucket-name>/models/QwQ-32B
PV と PVC を作成します。
llm-model
という名前の PV と、クラスター用の PVC を作成します。詳細については、「静的にプロビジョニングされた OSS ボリュームをマウントする」をご参照ください。コンソールを使用する
次の表に、PV の作成に使用される基本的なパラメーターを示します。
パラメーター
説明
PV タイプ
OSS
ボリューム名
llm-model
アクセス証明書
OSS バケットへのアクセスに使用される AccessKey ID と AccessKey シークレットを指定します。
バケット ID
前のステップで作成した OSS バケットを選択します。
OSS パス
モデルのパス (
/models/QwQ-32B
など) を選択します。次の表に、PVC の作成に使用される基本的なパラメーターを示します。
パラメーター
説明
PVC タイプ
OSS
ボリューム名
llm-model
割り当てモード
この例では、[既存のボリューム] が選択されています。
既存のボリューム
[既存のボリューム] をクリックし、作成した PV を選択します。
kubectl を使用する
次のコードブロックは、YAML テンプレートを示しています。
apiVersion: v1 kind: Secret metadata: name: oss-secret stringData: akId: <your-oss-ak> # OSS バケットへのアクセスに使用される AccessKey ID。 akSecret: <your-oss-sk> # OSS バケットへのアクセスに使用される AccessKey シークレット。 --- apiVersion: v1 kind: PersistentVolume metadata: name: llm-model labels: alicloud-pvname: llm-model spec: capacity: storage: 30Gi accessModes: - ReadOnlyMany persistentVolumeReclaimPolicy: Retain csi: driver: ossplugin.csi.alibabacloud.com volumeHandle: llm-model nodePublishSecretRef: name: oss-secret namespace: default volumeAttributes: bucket: <your-bucket-name> # OSS バケットの名前。 url: <your-bucket-endpoint> # エンドポイント (oss-cn-hangzhou-internal.aliyuncs.com など)。 otherOpts: "-o umask=022 -o max_stat_cache_size=0 -o allow_other" path: <your-model-path> # モデルパス (この例では /models/QwQ-32B/)。 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: llm-model spec: accessModes: - ReadOnlyMany resources: requests: storage: 30Gi selector: matchLabels: alicloud-pvname: llm-model
ステップ 2: モデルをデプロイする
次のコマンドを実行して、vLLM フレームワークを使用する QwQ-32B モデル推論サービスをデプロイします。
推論サービスは、OpenAI 互換の HTTP API を公開します。次のコードを実行して、モデルパラメーターファイルを特別なデータセットとして扱い、推論サービスを実行するコンテナーの指定されたパス (
/model/QwQ-32B
) にマウントします。--max_model_len
は、モデルで処理できるトークンの最大長を指定します。長さを増やすと、パフォーマンスが向上します。ただし、これにより GPU メモリの使用量も増加します。説明egslingjun-registry.cn-wulanchabu.cr.aliyuncs.com/egslingjun/{image:tag}
は、パブリックイメージのアドレスです。VPC を使用して AI コンテナイメージのプルを高速化することをお勧めします。kubectl apply -f- <<EOF apiVersion: apps/v1 kind: Deployment metadata: labels: app: qwq-32b alibabacloud.com/compute-class: gpu alibabacloud.com/gpu-model-series: <example-model> alibabacloud.com/hpn-type: "rdma" name: qwq-32b namespace: default spec: replicas: 1 selector: matchLabels: app: qwq-32b template: metadata: labels: app: qwq-32b alibabacloud.com/compute-class: gpu alibabacloud.com/gpu-model-series: <example-model> spec: volumes: - name: model persistentVolumeClaim: claimName: llm-model - name: dshm emptyDir: medium: Memory sizeLimit: 30Gi containers: - command: - sh - -c - vllm serve /models/QwQ-32B --port 8000 --trust-remote-code --served-model-name qwq-32b --max-model-len 32768 --gpu-memory-utilization 0.95 --enforce-eager image: egslingjun-registry.cn-wulanchabu.cr.aliyuncs.com/egslingjun/inference-nv-pytorch:25.02-vllm0.7.2-sglang0.4.3.post2-pytorch2.5-cuda12.4-20250305-serverless name: vllm ports: - containerPort: 8000 readinessProbe: tcpSocket: port: 8000 initialDelaySeconds: 30 periodSeconds: 30 resources: limits: nvidia.com/gpu: "1" cpu: "16" memory: 128G volumeMounts: - mountPath: /models/QwQ-32B name: model - mountPath: /dev/shm name: dshm --- apiVersion: v1 kind: Service metadata: name: qwq-32b-v1 spec: type: ClusterIP ports: - port: 8000 protocol: TCP targetPort: 8000 selector: app: qwq-32b EOF
ステップ 3: Open WebUI をデプロイする
次のコマンドを実行して、Open WebUI アプリケーションとサービスを作成します。
kubectl apply -f- << EOF apiVersion: apps/v1 kind: Deployment metadata: name: openwebui spec: replicas: 1 selector: matchLabels: app: openwebui template: metadata: labels: app: openwebui spec: containers: - env: - name: ENABLE_OPENAI_API value: "True" - name: ENABLE_OLLAMA_API value: "False" - name: OPENAI_API_BASE_URL value: http://qwq-32b-v1:8000/v1 - name: ENABLE_AUTOCOMPLETE_GENERATION value: "False" - name: ENABLE_TAGS_GENERATION value: "False" image: kube-ai-registry.cn-shanghai.cr.aliyuncs.com/kube-ai/open-webui:main name: openwebui ports: - containerPort: 8080 protocol: TCP volumeMounts: - mountPath: /app/backend/data name: data-volume volumes: - emptyDir: {} name: data-volume --- apiVersion: v1 kind: Service metadata: name: openwebui labels: app: openwebui spec: type: ClusterIP ports: - port: 8080 protocol: TCP targetPort: 8080 selector: app: openwebui EOF
ステップ 4: 推論サービスを検証する
kubectl port-forward
を実行して、ローカル環境と推論サービス間のポートフォワーディングを構成します。説明kubectl port-forward
を使用して設定されたポートフォワーディングは、本番環境では信頼性、安全性、または拡張性がありません。開発とデバッグのみを目的としています。本番環境でポートフォワーディングを設定するために、このコマンドを使用しないでください。ACK クラスターの本番で使用されるネットワーキングソリューションの詳細については、「Ingress 管理」をご参照ください。kubectl port-forward svc/openwebui 8080:8080
予期される結果:
Forwarding from 127.0.0.1:8080 -> 8080 Forwarding from [::1]:8080 -> 8080
http://localhost:8080
にアクセスし、Open WebUI にログインします。Open WebUI に初めてログインするときは、管理者ユーザー名とパスワードを入力する必要があります。プロンプトを入力します。次の図は、出力を示しています。
(オプション) ステップ 5: 推論サービスでストレステストを実行する
ストレステスト データセットをダウンロードするには、インターネットアクセスできることを確認してください。詳細については、「ACS クラスターのインターネットアクセスを有効にする」または「ポッドに独立した EIP をマウントする」をご参照ください。
詳細については、「クイックスタート: PHPを使用してBLOBをアップロード、ダウンロード、一覧表示する」をご参照ください。
kubectl apply -f- <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: vllm-benchmark labels: app: vllm-benchmark spec: replicas: 1 selector: matchLabels: app: vllm-benchmark template: metadata: labels: app: vllm-benchmark spec: volumes: - name: llm-model persistentVolumeClaim: claimName: llm-model containers: - name: vllm-benchmark image: kube-ai-registry.cn-shanghai.cr.aliyuncs.com/kube-ai/vllm-benchmark:v1 command: - "sh" - "-c" - "sleep inf" # 無限にスリープ volumeMounts: - mountPath: /models/QwQ-32B name: llm-model EOF
ベンチマーク ポッドにログインし、ストレステスト データセットをダウンロードします。
# ベンチマーク ポッドにログインするには、次のコマンドを実行します。 PODNAME=$(kubectl get po -o custom-columns=":metadata.name"|grep "vllm-benchmark") kubectl exec -it $PODNAME -- bash # ストレステスト データセットをダウンロードします。 pip3 install modelscope modelscope download --dataset gliang1001/ShareGPT_V3_unfiltered_cleaned_split ShareGPT_V3_unfiltered_cleaned_split.json --local_dir /root/
ストレステストを実行します。
# ストレステストを実行します。 input_length=4096,tp=4,output_lenght=512,concurrency=8,num_prompts=80 python3 /root/vllm/benchmarks/benchmark_serving.py \ --backend vllm \ --model /models/QwQ-32B \ --served-model-name qwq-32b \ --trust-remote-code \ --dataset-name random \ --dataset-path /root/ShareGPT_V3_unfiltered_cleaned_split.json \ --random-input-len 4096 \ --random-output-len 512 \ --random-range-ratio 1 \ --num-prompts 80 \ --max-concurrency 8 \ --host qwq-32b-v1 \ --port 8000 \ --endpoint /v1/completions \ --save-result \ 2>&1 | tee benchmark_serving.txt
予期される結果:
Starting initial single prompt test run... Initial test run completed. Starting main benchmark run... Traffic request rate: inf Burstiness factor: 1.0 (Poisson process) Maximum request concurrency: 8 100%|██████████| 80/80 [07:44<00:00, 5.81s/it] ============ Serving Benchmark Result ============ Successful requests: 80 Benchmark duration (s): 464.74 Total input tokens: 327680 Total generated tokens: 39554 Request throughput (req/s): 0.17 Output token throughput (tok/s): 85.11 Total Token throughput (tok/s): 790.18 ---------------Time to First Token---------------- Mean TTFT (ms): 10315.97 Median TTFT (ms): 12470.54 P99 TTFT (ms): 17580.34 -----Time per Output Token (excl. 1st token)------ Mean TPOT (ms): 71.03 Median TPOT (ms): 66.24 P99 TPOT (ms): 95.95 ---------------Inter-token Latency---------------- Mean ITL (ms): 71.02 Median ITL (ms): 58.12 P99 ITL (ms): 60.26 ==================================================
(Optional) Step 6: 環境をクリアする
推論サービスが不要になった場合は、速やかに環境を削除してください。
推論ワークロードとサービスを削除します。
kubectl delete deployment qwq-32b kubectl delete service qwq-32b-v1 kubectl delete deployment openwebui kubectl delete service openwebui kubectl delete deployment vllm-benchmark
PV と PVC を削除します。
kubectl delete pvc llm-model kubectl delete pv llm-model
期待される結果:
persistentvolumeclaim "llm-model" deleted persistentvolume "llm-model" deleted
参照資料
Container Compute Service (ACS) は Container Service for Kubernetes に統合されています。これにより、ACK Pro マネージドクラスター で ACS の GPU コンテナコンピューティング能力を使用することができます。
詳細については、以下のトピックをご参照ください。
ACS の AI コンテナイメージは、ACS クラスターの GPU アクセラレーションコンテナ専用です。このイメージのリリースノートの詳細については、「ACS AI コンテナイメージのリリースノート」をご参照ください。