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

Container Service for Kubernetes:KServe で Fluid を使用したモデルの高速化

最終更新日:Mar 26, 2026

大規模言語モデル (LLM) は、数十ギガバイトに達することもあり、Object Storage Service (OSS) からモデルファイルを取得する際に、コールドスタートが遅くなったり、再起動のレイテンシーが高くなったりする原因となります。Fluid は、JindoRuntime を使用してクラスターノード上にモデルファイルをローカルにキャッシュすることで、この問題を解決します。最初の読み込み後、推論サービスは OSS からモデルファイルを取得する代わりに、ローカルの JindoFS メモリキャッシュから読み込むため、その後の再起動が大幅に高速化されます。このトピックでは、Qwen-7B-Chat-Int8 モデルに対して Fluid ベースのキャッシュを設定し、NVIDIA V100 GPU 上の vLLM をバックエンドとする KServe 推論サービスとしてデプロイする方法を説明します。

前提条件

開始する前に、以下をご確認ください:

  • ContainerOS を実行していない、Kubernetes 1.22 以降を実行する ACK Pro マネージドクラスター。ノード数は 3 つ以上で、各ノードに 3 GB 以上の空きメモリが必要です。詳細は、「ACK Pro マネージドクラスターの作成」をご参照ください。

  • クラウドネイティブ AI スイートがインストールされ、ack-fluid コンポーネントがデプロイされていること。詳細は、「クラウドネイティブ AI スイートのデプロイ」をご参照ください。

  • Arena 0.9.15 以降がインストールされていること。詳細は、「Arena クライアントの設定」をご参照ください。

  • ack-kserve コンポーネントがインストールされていること。詳細は、「ack-kserve のインストール」をご参照ください。

  • OSS が有効化されていること。詳細は、「OSS の有効化」をご参照ください。

仕組み

Fluid は、連携して動作する 2 つの Kubernetes カスタムリソースを導入しています:

  • Dataset — 公開するリモートストレージパスを宣言します。このケースでは、モデルファイルを含む OSS バケットのパスです。

  • JindoRuntime — JindoFS クラスターを起動し、データセットのコンテンツをクラスターノードのメモリにキャッシュします。これにより、後続の読み取りは OSS からではなく、ローカルから提供されます。

KServe 推論サービスがデータセットをマウントすると、vLLM サーバーは起動のたびに OSS からモデルファイルを取得するのではなく、ローカルの JindoFS キャッシュから読み取ります。

ステップ 1: モデルデータの準備と OSS へのアップロード

Qwen-7B-Chat-Int8 モデルのダウンロード

  1. Git と Large File Support (LFS) プラグインをインストールします:

    sudo yum install git
    sudo yum install git-lfs
  2. ModelScope から Qwen-7B-Chat-Int8 リポジトリをクローンします。クローン中は LFS のダウンロードをスキップします:

    GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/qwen/Qwen-7B-Chat-Int8.git
  3. クローンしたディレクトリに移動し、LFS で管理されているモデルファイルを取得します:

    cd Qwen-7B-Chat-Int8
    git lfs pull

モデルの OSS へのアップロード

  1. OSS コンソールにログインし、OSS バケット名を記録します。 バケットを作成するには、「バケットの作成」をご参照ください。

  2. ossutil のインストールと設定を行います。詳細については、「ossutil のインストール」をご参照ください。

  3. バケット内にディレクトリを作成し、モデルファイルをアップロードします:

    ossutil mkdir oss://<your-bucket-name>/Qwen-7B-Chat-Int8
    ossutil cp -r ./Qwen-7B-Chat-Int8 oss://<your-bucket-name>/Qwen-7B-Chat-Int8

ステップ 2: Dataset と JindoRuntime の作成

OSS 認証情報用の Secret の作成

OSS バケットへのアクセスに使用する AccessKey ペアを格納するための Kubernetes Secret を作成します:

kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: oss-secret
stringData:
  fs.oss.accessKeyId: <your-access-key-id>
  fs.oss.accessKeySecret: <your-access-key-secret>
EOF

<your-access-key-id><your-access-key-secret> を実際の認証情報に置き換えてください。AccessKey ペアを取得するには、「AccessKey ペアの取得」をご参照ください。

期待される出力:

secret/oss-secret created

Dataset と JindoRuntime の作成

次の内容で resource.yaml という名前のファイルを作成します。設定の詳細については、「JindoFS を使用した OSS へのアクセス高速化」をご参照ください。

apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: qwen-7b-chat-int8
spec:
  mounts:
    - mountPoint: oss://<oss_bucket>/Qwen-7b-chat-Int8  # 実際の OSS パスに置き換えてください
      options:
        fs.oss.endpoint: <oss_endpoint>                  # OSS バケットのエンドポイントに置き換えてください
      name: models
      path: "/"
      encryptOptions:
        - name: fs.oss.accessKeyId
          valueFrom:
            secretKeyRef:
              name: oss-secret
              key: fs.oss.accessKeyId
        - name: fs.oss.accessKeySecret
          valueFrom:
            secretKeyRef:
              name: oss-secret
              key: fs.oss.accessKeySecret
---
apiVersion: data.fluid.io/v1alpha1
kind: JindoRuntime
metadata:
  name: qwen-7b-chat-int8  # Dataset 名と一致させる必要があります
spec:
  replicas: 3
  tieredstore:
    levels:
      - mediumtype: MEM       # メモリにキャッシュ
        volumeType: emptyDir
        path: /dev/shm
        quota: 3Gi            # レプリカごとのキャッシュ容量
        high: "0.95"
        low: "0.7"
  fuse:
    resources:
      requests:
        memory: 2Gi
    properties:
      fs.oss.download.thread.concurrency: "200"
      fs.oss.read.buffer.size: "8388608"
      fs.oss.read.readahead.max.buffer.count: "200"
      fs.oss.read.sequence.ambiguity.range: "2147483647"

設定を適用します:

kubectl apply -f resource.yaml

期待される出力:

dataset.data.fluid.io/qwen-7b-chat-int8 created
jindoruntime.data.fluid.io/qwen-7b-chat-int8 created

ステップ 3: vLLM 推論サービスのデプロイ

vLLM を使用して、Qwen-7B-Chat-Int8 モデルを KServe 推論サービスとしてデプロイします。--data フラグは Fluid データセットをコンテナにマウントするため、モデルは JindoFS キャッシュから読み取られます。

arena serve kserve \
    --name=qwen-fluid \
    --image=kube-ai-registry.cn-shanghai.cr.aliyuncs.com/kube-ai/vllm:0.4.1 \
    --gpus=1 \
    --cpu=4 \
    --memory=12Gi \
    --data="qwen-7b-chat-int8:/mnt/models/Qwen-7B-Chat-Int8" \
    "python3 -m vllm.entrypoints.openai.api_server --port 8080 --trust-remote-code --served-model-name qwen --model /mnt/models/Qwen-7B-Chat-Int8 --gpu-memory-utilization 0.95 --quantization gptq --max-model-len=6144"

期待される出力:

inferenceservice.serving.kserve.io/qwen-fluid created
INFO[0002] The Job qwen-fluid has been submitted successfully
INFO[0002] You can run `arena serve get qwen-fluid --type kserve -n default` to check the job status

ステップ 4: 高速化結果の検証

データセットのキャッシュステータスの確認

kubectl get dataset qwen-7b-chat-int8

期待される出力:

NAME                UFS TOTAL SIZE   CACHED     CACHE CAPACITY   CACHED PERCENTAGE   PHASE   AGE
qwen-7b-chat-int8   17.01GiB         10.46MiB   18.00GiB         0.1%                Bound   23h

PHASE: Bound ステータスは、データセットがバインドされており、JindoRuntime がアクティブであることを確認します。推論サービスがモデルファイルを読み取るにつれて、キャッシュ済み割合が増加します。

サーバー起動時間の確認

次のコマンドを実行して、サーバーが Ready になるまでにかかる時間を測定します:

# 推論サービスの Pod 名を取得
POD_NAME=$(kubectl get po | grep qwen-fluid | awk -F " " '{print $1}')
# サーバーが Ready になるまでにかかった時間を確認
kubectl logs $POD_NAME | grep -i "server ready takes"

期待される出力:

server ready takes 25.875763 s

Fluid キャッシュを有効にすると、モデルファイルは再起動時に OSS から取得される代わりにローカルメモリから提供されるため、起動時間が短縮されます。実際の高速化の度合いは、データセットのサイズ、ノードのメモリ、ネットワーク条件によって異なります。

キャッシュされたアクセス時間とキャッシュされていないアクセス時間を比較したベンチマークデータについては、「JindoFS を使用した OSS へのアクセス高速化」の「ステップ 3: アプリケーションを作成してデータアクセラレーションをテストする」セクションをご参照ください。

トラブルシューティング

JindoRuntime が Ready にならない

現象: resource.yaml を適用した後、データセットが Bound 以外のフェーズのままになります。

原因: メモリ不足により、JindoRuntime のワーカーが保留状態になっている可能性があります。各レプリカは、3 GiB のキャッシュメモリと、Fuse サイドカー用に 2 GiB をリクエストします。

解決策: JindoRuntime のイベントを確認します:

kubectl describe jindoruntime qwen-7b-chat-int8

ノードの空きメモリが不足している場合は、tieredstorequota を減らすか、より多くの使用可能なメモリを持つノードを追加してください。

OSS アクセスエラー

現象: データセットにエラーが表示されるか、JindoRuntime の Pod がアクセス拒否を報告します。

原因: oss-secret Secret 内の AccessKey ID または AccessKey Secret が正しくないか、AccessKey に OSS バケットに対する読み取り権限がありません。

解決策: Secret 内の認証情報を確認します:

kubectl get secret oss-secret -o yaml

必要に応じて、正しい値で Secret を再作成し、JindoRuntime を再起動してください。

推論サービスの Pod が Init 状態でスタックする

現象: qwen-fluid Pod が Init 状態のままになります。

原因: Fuse サイドカーがまだデータセットをマウントしていないか、データセットが Bound フェーズになっていません。

解決策: まず、データセットのフェーズを確認します:

kubectl get dataset qwen-7b-chat-int8

推論サービスの Pod が処理を続行する前に、PHASE: Bound になるまで待ちます。データセットが Bound になっても Pod がまだスタックしている場合は、Pod のイベントを確認します:

kubectl describe pod $POD_NAME

次のステップ

参考