すべてのプロダクト
Search
ドキュメントセンター

Container Compute Service:ACS の GPU 計算能力を使用して QwQ-32B モデルからモデル推論サービスをデプロイする

最終更新日:May 15, 2025

Container Compute Service (ACS) では、基盤となるハードウェアに関する深い知識や GPU インスタンスの管理は不要です。すべての構成はすぐに使用できます。ACS はデプロイが容易で、従量課金制です。LLM 推論サービスに適しており、推論コストを効率的に削減できます。このトピックでは、ACS で QwQ-32B モデルを使用してモデル推論サービスをデプロイし、Open WebUI を使用してサービスを表示する方法について説明します。

背景情報

QwQ-32B について

Alibaba Cloud は、学習機能によって推論を大幅に強化できる QwQ-32B モデルを発表しました。QwQ-32B モデルは 320 億のパラメーターを備えています。そのパフォーマンスは、6,710 億のパラメーターを備えた DeepSeek-R1 フルバージョンに匹敵します。QwQ-32B の数学とコーディング (AIME 24/25 および livecodebench) のパフォーマンスと、いくつかの一般的なパフォーマンス指標は、DeepSeek-R1 フルバージョンのレベルに達し、Qwen2.5-32B に基づいて開発された DeepSeek-R1-Distill-Qwen-32B を上回っています。詳細については、「QwQ-32B」をご参照ください。

vLLM

vLLM は、高性能で使いやすい LLM 推論サービス フレームワークです。vLLM は、Qwen モデルを含む、最も一般的に使用される LLM をサポートしています。vLLM は、PagedAttention 最適化、連続バッチ処理、モデル量子化などのテクノロジーによって強化されており、LLM の推論効率を大幅に向上させます。 vLLM フレームワークの詳細については、「vLLM GitHub リポジトリ」をご参照ください。

Open WebUI

Open WebUI は、豊富な機能を備えた、拡張可能でユーザーフレンドリーなホスト型 AI プラットフォームです。オフラインで実行するように設計されています。Open WebUI は、Ollama などのさまざまな LLM フレームワークと、OpenAI と互換性のある API をサポートしています。RAG 用の組み込み推論エンジンが付属しており、強力な AI デプロイメント ソリューションを設計できます。

前提条件

  • 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 インスタンスの課金の詳細については、「課金概要」をご参照ください。

説明

手順

説明

チケットを送信すると、モデルファイルを取得し、サポートされている 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 モデルファイルを永続化します。

  1. 次のコマンドを実行して、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
  2. OSS ディレクトリを作成し、モデルファイルをディレクトリにアップロードします。

    説明

    ossutil をインストールして使用するには、「ossutil をインストールする」をご参照ください。

    ossutil mkdir oss://<your-bucket-name>/models/QwQ-32B
    ossutil cp -r ./QwQ-32B oss://<your-bucket-name>/models/QwQ-32B
  3. 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: モデルをデプロイする

  1. 次のコマンドを実行して、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 をデプロイする

  1. 次のコマンドを実行して、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: 推論サービスを検証する

  1. 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
  2. http://localhost:8080 にアクセスし、Open WebUI にログインします。

    Open WebUI に初めてログインするときは、管理者ユーザー名とパスワードを入力する必要があります。プロンプトを入力します。次の図は、出力を示しています。

    image

(オプション) ステップ 5: 推論サービスでストレステストを実行する

説明

ストレステスト データセットをダウンロードするには、インターネットアクセスできることを確認してください。詳細については、「ACS クラスターのインターネットアクセスを有効にする」または「ポッドに独立した EIP をマウントする」をご参照ください。

  1. 詳細については、「クイックスタート: 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
  2. ベンチマーク ポッドにログインし、ストレステスト データセットをダウンロードします。

    # ベンチマーク ポッドにログインするには、次のコマンドを実行します。
    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/
  3. ストレステストを実行します。

    # ストレステストを実行します。 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: 環境をクリアする

推論サービスが不要になった場合は、速やかに環境を削除してください。

  1. 推論ワークロードとサービスを削除します。

    kubectl delete deployment qwq-32b
    kubectl delete service qwq-32b-v1
    kubectl delete deployment openwebui
    kubectl delete service openwebui
    kubectl delete deployment vllm-benchmark
  2. PV と PVC を削除します。

    kubectl delete pvc llm-model
    kubectl delete pv llm-model

    期待される結果:

    persistentvolumeclaim "llm-model" deleted
    persistentvolume "llm-model" deleted

参照資料