GDC エアギャップでのオープンウェイト LLM ユーザーガイド

このデプロイガイドでは、Google Distributed Cloud(GDC)のエアギャップ環境でオープンソース ソフトウェア(OSS)を使用して最先端の大規模言語モデル(LLM)を実行する方法について詳しく説明します。このガイドでは、Gemma、DeepSeek、Llama モデルの最新リリースを実行するために必要なすべての手順を紹介するとともに、一般公開されている他の LLM をサービングするための一般的な手順も紹介します。vLLM や Ollama などのコンテナ化されたサービング バックエンドを活用します。これらは、幅広い機能、さまざまなレベルの構成、デプロイの容易さを備えています。

コンテンツの概要

このガイドでは、Google Distributed Cloud(GDC)のエアギャップ環境でのオープンソースの大規模言語モデル(LLM)のデプロイと運用について詳しく説明します。

コアの目標とインフラストラクチャ

  • 目的: vLLM や Ollama などの最適化されたバックエンドを使用して、Gemma 3(マルチモーダル)、DeepSeek-R1、Llama(3.1/3.2)などの最先端の LLM を実行するための詳細な手順。
  • 最小リリース: GDC エアギャップ ソフトウェア リリース 1.15.x*。
  • ハードウェア要件: 最小 1 個の NVIDIA A100 GPU が必要です。モデルの重みの読み込み時間を 30 分から 5 分未満に短縮するには、ハイ パフォーマンス ストレージ(500 GiB 以上の PVC)をおすすめします。

デプロイ コンポーネント

コンポーネント 説明
LLM バックエンド vLLM(PagedAttention を使用した高スループット サービング)と Ollama(ローカル管理の簡素化とマルチモーダル サポート)
モデル Gemma、DeepSeek、Llama ファミリーなどの一般公開されている LLM
アクセラレータ モデルの VRAM フットプリントに応じて、完全な NVIDIA A100 GPU または マルチインスタンス GPU(MIG)スライスをサポート
GDC サービス GDC コンテナ サービス、ロードバランサ(ELB/ILB)、Harbor Container Registryを使用

主な運用手順

  • モデル管理: LLM バックエンドは、使用状況に基づいてモデルの読み込みとアンロードを管理します。vLLM はモデルをメモリに固定して一貫した低レイテンシを実現しますが、Ollama では動的なモデルの読み込みが可能ですが、30 分間使用されないとモデルが自動的にアンロードされます。
  • カスタマイズ: ユーザーは、インターネットから LLM を取得し、新しい Docker イメージをビルドして、ローカルの Harbor レジストリにアップロードすることで、好みの LLM を使用できます。

前提条件

リリース

  • GDC エアギャップ バージョン 1.15.1 以降。

コンポーネント

  • 十分なリソース(CPU、メモリ、GPU)で作成されたユーザー クラスタ。
  • NVIDIA A100 GPU が 1 つ以上必要です。
  • Harbor インスタンスが利用可能でアクセス可能である。
  • ユーザー クラスタにアクセスするように構成された kubectl CLI と gdcloud CLI。
  • Docker クライアントがインストールされ、Harbor に push するように構成されている。
  • 必要な IAM 権限が付与されている(Namespace 管理者、クラスタ デベロッパーなど)。
  • 制限付きモデルを使用する場合は、Hugging Face アカウントと認証が構成されている。

必要な容量

リソース 容量
CPU 8 vCPU
RAM メモリ 32 GiB
エフェメラル ストレージ 16 Gi
GPU NVIDIA A100 GPU 1 個
永続ボリューム *500GiB+

これらのハードウェア リソースは、サービング バックエンドが GPU アクセラレーションで LLM を実行するために必要です。たとえば、1 つの a2-ultragpu-1g-gdc マシンタイプで十分なリソースが提供されます。

概要図

オープン ウェイト LLM サービングの概要図。

この図は、2 つの LLM バックエンド(vLLM と Ollama)によって公開された API を使用して、Gemma、Llama、DeepSeek などのオープンソース モデルから推論レスポンスを取得するユーザーを示しています。モデルサイズ(数十億のパラメータで測定)に応じて、各 LLM の実行には GPU 全体またはその一部が必要になる場合があります。

LLM デプロイのサービスとセキュリティの境界図

このソリューションは、GDC エアギャップ ソフトウェア スタックにすでに含まれている次のサービスに依存しています。

  • GDC Container Service: すべてのプロセスを実行し、HPA を使用してスケーリングします。
  • GDC ロードバランサ: Kubernetes Service を使用して、このソリューションのすべてのバックエンドを処理し、顧客ネットワークから LLM にアクセスできるようにします。これは ELB(外部ロードバランサ)と呼ばれます。逆に、ユーザー クラスタ内からのみ LLM にアクセスできるようにすることもできます。これは、ソリューション内で推論をリクエストする内部エージェントのみが存在する場合に便利です。これは ILB(内部ロードバランサ)と呼ばれます。
  • GDC CI/CD: LLM バックエンドとモデルの重みを保存する Harbor コンテナ レジストリ。
  • GDC Observability Stack: バックエンド ログを収集して検索し、ダッシュボードを提供します。

セキュリティの面では、LLM デプロイへのアクセスは、LLM サービング バックエンドを公開するロードバランサ サービスにアクセスできるユーザーによって異なります。このバックエンドは、Kubernetes プロジェクト / Namespace の Pod として実行されます。

サービスとセキュリティ境界のアーキテクチャ図。

デプロイ

前提条件

GDC エアギャップ環境に接続されたワークステーションに次のツールをインストールします。

  1. docker
  2. kubectl
  3. gdcloud CLI

このドキュメントには、LLM のデプロイに必要なすべてのソースコードと構成ファイルが含まれています。

Harbor からイメージを pull するための Secret を作成する

GDC エアギャップでコンテナ ワークロードのイメージ pull Secret を構成するには、限定公開の Harbor プロジェクトにアクセスするための認証情報を含む Kubernetes docker-registry Secret を作成する必要があります。この Secret は、デプロイ仕様で参照されます。

非公開の Harbor プロジェクトのイメージにプログラムでアクセスするには、Harbor ロボット アカウントを使用する必要があります。

イメージ pull シークレットを構成する手順は次のとおりです。

Harbor ロボット アカウントを作成します。

  • Harbor インスタンスの UI に移動します。
  • Harbor プロジェクトに移動します。
  • [ロボット アカウント] タブを選択します。
  • [+ 新しいロボット アカウント] をクリックします。
  • 名前(例: oss-llm-puller)を付け、有効期限まで必要な権限(少なくとも「pull」アクセス)を付与します。
  • ロボット アカウント名(robot$oss-llm-puller など)と提供されたシークレット トークンを安全に保存します。

Docker を Harbor に対して認証します。

Docker がインストールされ、Harbor レジストリにネットワーク アクセスできるマシンで、ロボット アカウントの認証情報を使用してログインします。

export INSTANCE_URL="your-harbor-instance-url"
# for example, harbor1-project1.org1.zone1.google.gdc.com

export ROBOT_NAME="your-robot-account-name"
# for example, robot\$oss-llm-puller (note how we escape the $ character)

export ROBOT_SECRET="your-robot-account-secret"

docker login ${INSTANCE_URL} --username ${ROBOT_NAME} --password ${ROBOT_SECRET}

# Sample output:

WARNING! Using --password via the CLI is insecure. Use --password-stdin.

WARNING! Your credentials are stored unencrypted in '$HOME/.docker/config.json'.
Configure a credential helper to remove this warning. See
https://docs.docker.com/go/credential-store/

Login Succeeded

サンプル出力に示すように、このコマンドは認証の詳細を使用してローカルの Docker 構成ファイル($HOME/.docker/config.json)を更新します。config.json ファイルは次のようになります。

{
    "auths": {
        "harbor1-project1.org1.zone1.google.gdc.com": {
            "auth": "...omitted..."
        }
    }
}

過去に Docker クライアントを使用して他のレジストリにログインしたことがある場合は、「auths」内にエントリが追加されています。

Kubernetes イメージ プルシークレットを作成します。

kubectl を使用して、前の手順で更新した Docker 構成ファイルを使用して、プロジェクトの Namespace に docker-registry タイプの Secret を作成します。

# Log in to GDC air-gapped using the next commands

gdcloud auth login --login-config-cert {path to your web TLS certificate}

gdcloud clusters get-credentials {Your User Cluster}
kubectl config set-context --current --namespace=NAMESPACE

export SECRET_NAME="oss-llm-pull-secret" # You can choose another name
export NAMESPACE="your-project-namespace"
# Assuming default Docker config path. Adjust if necessary.
export DOCKER_CONFIG_PATH="$HOME/.docker/config.json"

kubectl create secret docker-registry ${SECRET_NAME} \
      --from-file=.dockerconfigjson=${DOCKER_CONFIG_PATH} \
      -n ${NAMESPACE}

このシークレットは、後で imagePullSecrets フィールドを含めることで、LLM バックエンド コンテナ仕様で参照します。

これらの手順に沿って操作すると、Kubernetes クラスタは、指定された認証情報を使用して、GDC エアギャップ環境にあるプライベート Harbor レジストリからコンテナ イメージを pull するようになります。これらの手順は、プロダクトのドキュメントにも記載されています。

LLM デプロイを設定する

LLM バックエンドには次の2 つのオプションがあります。

  • vLLM
  • Ollama

いずれか 1 つを選択するか、両方のバックエンドをデプロイできます。各バックエンドでは、1 つ以上の LLM を実行できます。次に例を示します。

  • Gemma 3
  • DeepSeek
  • Llama
  • その他の LLM

セクション 1 では vLLM をデプロイする方法について説明し、セクション 2 では Ollama をインストールする方法について説明します。

1. LLM バックエンドとして vLLM をデプロイする

vLLM Docker イメージを取得する

一般に、vLLM は HuggingFace からダウンロードしたモデルのサービングに使用されます。この LLM デプロイで示すように、一部のモデルはゲート付きです。つまり、ユーザーがダウンロードまたは使用する前に、Hugging Face Hub でファイルとコンテンツへのアクセスを明示的にリクエストするか、同意する必要があります。

ドキュメントの説明に沿って、Docker を使用して Harbor インスタンスにログインします。インターネット アクセスのあるマシンで、vLLM Docker イメージを pull して、Harbor プロジェクトに転送します。

# Pull and Tag vLLM (v0.13.0 recommended for stability)
docker pull vllm/vllm-openai:v0.13.0
docker tag vllm/vllm-openai:v0.13.0 HARBOR_URL/PROJECT/vllm-openai:v0.13.0
docker push HARBOR_URL/PROJECT/vllm-openai:v0.13.0

次のように置き換えます。

  • HARBOR_URL: Harbor インスタンスの URL。
  • PROJECT: Harbor プロジェクト名。

このデプロイガイドで使用する vLLM のバージョンは v0.13.0 です。

LLM モデルの重みを PVC に保存する

新しいターミナルを開き、vLLM デプロイ ファイルを保存するフォルダを作成します。

mkdir vllm-deployment
cd vllm-deployment

次に、標準の Kubernetes プリミティブを使用して Persistent Volume Claim(PVC)を宣言する YAML ファイル(model-pvc.yaml など)を作成します。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: model-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 500Gi
  storageClassName: standard-rwo
  volumeMode: Filesystem

GDC エアギャップ クラスタに接続して、PVC を適用します。

# Log in to GDC air-gapped using the next commands

gdcloud auth login --login-config-cert {path to your web TLS cert}

gdcloud clusters get-credentials {Your User Cluster}
kubectl config set-context --current --namespace=NAMESPACE

# Apply the PVC manifest
kubectl apply -f model-pvc.yaml

Hugging Face からモデルの重みをダウンロードします。

# Log in to Hugging Face
hf auth login

# Download weights for Gemma 3 (for example, 4B instruction-tuned)
hf download google/gemma-3-4b-it

出力例:

Fetching 9 files: 100%| 9/9 [00:00<00:00, 19.34it/s]
Downloading (…)7f58a/.gitattributes: 100%| 1.62k/1.62k [00:00<00:00, 7.82MB/s]
Downloading (…)del-00002-of-00002.safetensors: 100%| 3.75G/3.75G [00:46<00:00, 81.3MB/s]
Downloading (…)del-00001-of-00002.safetensors: 100%| 4.90G/4.90G [00:54<00:00, 90.1MB/s]
Downloading (…)-3-4b-it/README.md: 100%| 23.3k/23.3k [00:00<00:00, 48.0MB/s]
Downloading (…)8a/model.safetensors.index.json: 100%| 26.3k/26.3k [00:00<00:00, 39.5MB/s]
Downloading (…)f58a/config.json: 100%| 908/908 [00:00<00:00, 4.41MB/s]
Downloading (…)generation_config.json: 100%| 210/210 [00:00<00:00, 936kB/s]
Downloading (…)tokenizer.json: 100%| 33.1M/33.1M [00:01<00:00, 17.6MB/s]
/Users/rashjab/.cache/huggingface/hub/models--google--gemma-3-4b-it/snapshots/952ec8ffca3adadfd00c6d71b40280ebdbb7f58a

サンプル出力からわかるように、ディスク上のモデルサイズは 8.64 GB で、前に定義した 500 GiB の PVC に収まります。永続ボリューム(PV)に読み込むモデルでは、常にこのようになっていることを確認してください。たとえば、15 GB のモデルで 500 GiB の PVC を使用して 1,500 IOPS を実現すると、重みの読み込み時間を約 30 分から 5 分未満に大幅に短縮できます。

モデルファイルをボリュームにコピーして、PV を入力します。通常は以下が含まれます。

  • PV をマウントする一時的な「ヘルパー」Pod を作成します。
  • kubectl cp を使用して、ワークステーションからヘルパー Pod のマウントされたボリュームにモデルファイルをコピーします。
  • ヘルパー Pod の例:

helper-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: model-uploader
spec:
  containers:
  - name: uploader
    image: HARBOR_URL/PROJECT/busybox:latest
    command: ["sleep", "3600"]
    volumeMounts:
    - name: model-data
      mountPath: /data
  imagePullSecrets:
  - name: oss-llm-pull-secret
  volumes:
  - name: model-data
    persistentVolumeClaim:
      claimName: model-pvc

次のように置き換えます。

  • HARBOR_URL: Harbor インスタンスの URL。
  • PROJECT: Harbor プロジェクト名。
  • oss-llm-pull-secret: 別のイメージ pull シークレット名を選択した場合。
  • model-pvc: PVC に付けた名前。

ヘルパー Docker イメージ(busybox)を push します。

docker pull busybox:latest
docker tag busybox HARBOR_URL/PROJECT/busybox:latest
docker push HARBOR_URL/PROJECT/busybox:latest

次のように置き換えます。

  • HARBOR_URL: Harbor インスタンスの URL。
  • PROJECT: Harbor プロジェクト名。

helper-pod.yaml ファイルを適用し、モデルの重みを PV にコピーします。

kubectl apply -f helper-pod.yaml

# Wait for the pod to be Running
kubectl cp ~/.cache/huggingface/hub/ NAMESPACE/model-uploader:/data/

# After copying, delete the helper pod
kubectl delete pod model-uploader

vLLM バックエンドをデプロイする

vLLM のデプロイ ファイルを作成して、モデルサーバーを実行します。次の例では、gemma-3-4b-it モデルをデプロイします。

vllm-gemma-3-4b-it-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gemma-3-4b-it
  labels:
    app: gemma-3-4b-it
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gemma-3-4b-it
  template:
    metadata:
      labels:
        app: gemma-3-4b-it
    spec:
      volumes:
      - name: cache-volume
        persistentVolumeClaim:
          claimName: model-pvc # change with the name you gave initially to your PVC
      # vLLM needs to access the host's shared memory for tensor parallel inference.
      - name: shm
        emptyDir:
          medium: Memory
          sizeLimit: "16Gi"
      containers:
      - name: gemma-3-4b-it
        image: HARBOR_URL/PROJECT/vllm-openai:v0.13.0
        command: ["python3"]
        args: [
          "-m",
          "vllm.entrypoints.openai.api_server",
          "--model",
          "google/gemma-3-4b-it", # Use the repo ID
          "--max-model-len",
          "32768",
          "--enforce-eager"
        ]
        env:
        - name: HF_HUB_OFFLINE
          value: "1"
        - name: HF_HOME
          value: "/model" # Tells vLLM to look for models in /model/hub
        # --- PERFORMANCE & STABILITY OPTIMIZATIONS ---
        - name: NCCL_P2P_DISABLE
          value: "1" # Prevents initialization hangs on P2P checks
        - name: NCCL_IB_DISABLE
          value: "1" # Prevents initialization hangs on InfiniBand checks
        # --- FIPS BYPASS ---
        - name: BORINGSSL_FIPS
          value: "0"
        - name: OPENSSL_FIPS
          value: "0"
        - name: OPENSSL_CONF
          value: "/dev/null"
        - name: FIPS_SIG
          value: "off"
        ports:
        - containerPort: 8000
        securityContext:
          privileged: true
          runAsUser: 0
        resources:
          limits:
            nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE: 1
            cpu: "8"       # Increased to handle model weight verification
            memory: "64Gi"  # Increased to ensure headroom for weight loading
          requests:
            nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE: 1
            cpu: "8"
            memory: "32Gi"
        volumeMounts:
        - name: cache-volume
          mountPath: /model
        - name: shm
          mountPath: /dev/shm
      imagePullSecrets:
      - name: oss-llm-pull-secret

次のように置き換えます。

  • HARBOR_URL: Harbor インスタンスの URL。
  • PROJECT: Harbor プロジェクト名。
  • oss-llm-pull-secret: イメージ pull シークレットの作成時に指定した名前。
  • claimName: 最初の PVC の作成時に指定した名前。

次に、vLLM バックエンド API を公開する Kubernetes Service ファイルを作成します。

vllm-gemma-3-4b-it-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: gemma-3-4b-it
  namespace: NAMESPACE
spec:
  ports:
  - name: http-gemma-3-4b-it
    port: 80
    protocol: TCP
    targetPort: 8000
  selector:
    app: gemma-3-4b-it
  sessionAffinity: None
  type: LoadBalancer

デプロイとサービスの構成を適用します。

kubectl apply -f vllm-gemma-3-4b-it-deployment.yaml
kubectl apply -f vllm-gemma-3-4b-it-service.yaml

vLLM デプロイを検証してテストする

  1. Pod のステータスを確認します。

    kubectl get pods
    

    Pod が Running 状態になるまで待ちます。

  2. サービスを確認します。

    kubectl get service
    

    出力例:

    # NAME          TYPE         CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
    # gemma-3-4b-it LoadBalancer 10.201.136.62  136.125.37.198   80:30109/TCP   3d1h
    

    前の出力から、vLLM サービスの EXTERNAL-IP(136.125.37.198 など)をメモしておきます。次のコマンドで印刷することもできます。

    kubectl get service gemma-3-4b-it \
    -o jsonpath='{.status.loadBalancer.ingress[*].ip}'
    
  3. ログを表示します。

    kubectl logs YOUR_VLLM_POD
    

    サーバーが起動してモデルが読み込まれたことを示すメッセージ(INFO: Application startup complete. など)を探します。Hugging Face のダウンロードがないため、ファイルが Persistent Volume 容量の大きい PVC にある場合は、すぐに完了します。

  4. curl で推論をテストします。

    vLLM Pod が実行されていることと、Service の外部 IP アドレスがあることを確認したら、curl を使用して推論リクエストを送信できます。vLLM は OpenAI 互換の API を提供するため、/v1/chat/completions エンドポイントを使用できます。

    curl http://EXTERNAL_IP/v1/chat/completions \
      -H "Content-Type: application/json" \
      -d '{
        "model": "google/gemma-3-4b-it",
        "messages": [
          {"role": "user", "content": "What is Google Distributed Cloud air-gapped?"}
        ],
        "max_tokens": 100
      }'
    

    EXTERNAL_IP は、vLLM サービスの外部 IP アドレスに置き換えます。

2. LLM バックエンドとして Ollama をデプロイする

Ollama は、オープンソース LLM をローカルおよびコンテナ化された環境で実行するための一般的なフレームワークです。重みのダウンロード、量子化、GPU アクセラレーションを処理することで、モデルの実行を簡素化します。補完、チャットの回答、エンベディングを生成するための組み込み REST API が含まれています。

他のサービング エンジンとは異なり、Ollama はモデルの実行を動的に管理します。

  • 動的モデル読み込み: 特定のモデルのリクエストを受信すると、Ollama はオンデマンドで重みをメモリ(GPU VRAM またはシステム RAM)に読み込みます。
  • 非アクティブ時のアンロード: モデルに対して 30 分間(OLLAMA_KEEP_ALIVE で構成可能)推論リクエストが受信されない場合、Ollama はモデルをメモリからアンロードして、他のワークロード用のハードウェア リソースを解放します。
  • インスタンスあたりのアクティブ モデルは 1 つ: Ollama は、サーバー インスタンスごとに 1 つのアクティブ モデルのリクエストを一度に処理します。複数のモデルが並行して呼び出されると、Ollama はリクエストをキューに登録し、モデルを順番に切り替えます。これにより、レイテンシが発生する可能性があります。スワップせずに複数のモデルを同時に提供するには、モデルごとに個別の Ollama インスタンスをデプロイする必要があります。

モデルの重みをダウンロードして Docker イメージを作成する

Persistent Volume から重みを直接読み込むことができる vLLM とは異なり、Ollama は通常、モデルが内部ディレクトリ形式(~/.ollama/models)で保存されていることを想定しています。

ランタイム コンテナが公共のインターネットからモデルをダウンロードできないエアギャップ環境では、ビルドフェーズでモデルの重みをコンテナ イメージ自体に事前にパッケージ化する必要があります。このアプローチにより、コンテナは完全に自己完結型となり、外部ネットワーク アクセスを必要とせずに、デプロイ後すぐにサービス提供を開始できます。

Ollama デプロイ用のフォルダを作成します。

mkdir ollama-gemma3
cd ollama-gemma3

次の内容の Dockerfile を作成します。

# Use a standard Linux base image
FROM ubuntu

# Install necessary dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
    curl \
    ca-certificates \
    zstd \
    && rm -rf /var/lib/apt/lists/*

# Install Ollama
# This uses Ollama's official installation script, which adds Ollama to /usr/local/bin
RUN curl -fsSL https://ollama.com/install.sh -o install.sh && \
    chmod +x install.sh && \
    ./install.sh && \
    rm install.sh

# Set environment variables for Ollama (optional, but a good practice)
# ENV OLLAMA_HOST="0.0.0.0"

# If you want to customize the model storage path within the container, set OLLAMA_MODELS, for example:
# ENV OLLAMA_MODELS="/usr/local/ollama/models"
# The default OLLAMA_MODELS is /root/.ollama
# Then, ensure you create and populate that directory.

# --- Download Gemma 3 model weights ---
# This step starts Ollama server in the background, pulls the model,
# and then kills the server to allow the Docker build to continue.
# This approach works around the Docker RUN command limitations for services.

RUN ollama serve & \
    # Give the Ollama server a moment to start up
    # Use --retry and --retry-connrefused to handle startup delays
    curl --retry 10 --retry-connrefused -s http://localhost:11434 || true && \
    # Pull the Gemma 3 model weights
    ollama pull gemma3:latest && \
    # Stop the background Ollama server process cleanly
    pkill ollama || true

# Expose Ollama's default port
EXPOSE 11434

# Command to run Ollama server when the container starts
CMD ["ollama", "serve"]

Llama 3.2 ファミリーや DeepSeek-R1 ファミリーのモデルなど、別のオープンソース LLM を試す場合は、前の Dockerfile で次の Ollama コマンドを変更します。

ollama pull gemma3:latest

たとえば、30 億個のパラメータを含む Llama 3.2 を pull する場合は、次のコマンドを使用します。

ollama pull llama3.2:3b

または、80 億個のパラメータを持つ DeepSeek-R1 を使用する場合は、次のコマンドを使用します。

ollama pull deepseek-r1:8b

複数の LLM をダウンロードして、モデルの重みをコンテナ化することもできます。これにより、Ollama は、さまざまな事前読み込み済みモデルで推論をリクエストするときに、モデルを切り替えることができます。たとえば、Gemma モデルと Llama モデルの両方を Docker イメージに追加できます。エアギャップ環境では、Ollama バックエンドは Ollama ライブラリにアクセスしてモデルをいつでもダウンロードできません。

アプリケーションで実行する前に、各モデルのライセンスと利用規約を確認して同意してください。Ollama のライブラリには多くの LLM があります。LLM バックエンド Docker イメージのビルド中にモデルの重みをダウンロードする場合にのみ、インターネット接続が必要です。

Docker イメージをビルドして Harbor に push する

ドキュメントの説明に沿って、Docker を使用して Harbor インスタンスにログインします。Gemma 3 Docker イメージをビルドして、Harbor リポジトリにアップロードします。

docker build -t ollama-gemma3 .
docker tag ollama-gemma3 HARBOR_URL/PROJECT/ollama-gemma3:latest
docker push HARBOR_URL/PROJECT/ollama-gemma3:latest

次のように置き換えます。

  • HARBOR_URL: Harbor インスタンスの URL。
  • PROJECT: Harbor プロジェクト名。

このデプロイガイドで使用されている Ollama のバージョン: 0.14.1

Kubernetes Deployment と Service を準備する

ollama-gemma3.yaml というファイルを作成して、Ollama バックエンドのデプロイと、サービスとして公開するためのロードバランサ構成を定義します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ollama-gemma3
  namespace: osd-dev
  labels:
    app: ollama-gemma3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ollama-gemma3
  template:
    metadata:
      labels:
        app: ollama-gemma3
    spec:
      containers:
      - name: ollama-gemma3
        image: rashjab-mhs-rashjab-test2.gdc1.us-west6-a.staging.gpcdemolabs.com/rashjab-repo/ollama-gemma3:latest
        env:
        # This is the crucial fix: Tell Ollama to listen on all network interfaces
        - name: OLLAMA_HOST
          value: "0.0.0.0"
        imagePullPolicy: Always
        ports:
        - containerPort: 11434
        securityContext:
          privileged: true
          runAsUser: 0
        resources:
          limits:
            nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE: 1
          requests:
            nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE: 1
      imagePullSecrets:
      - name: oss-llm-pull-secret
---
apiVersion: v1
kind: Service
metadata:
  name: ollama-gemma3
  namespace: osd-dev
spec:
  type: LoadBalancer
  selector:
    app: ollama-gemma3
  ports:
  - name: ollama-gemma3-port
    port: 11434
    protocol: TCP
    targetPort: 11434

次のように置き換えます。

  • HARBOR_URL: Harbor インスタンスの URL。
  • PROJECT: Harbor プロジェクト名。
  • oss-llm-pull-secret: 別のイメージ pull シークレット名を選択した場合。

GPU の割り当てを確認する

GDC エアギャップは NVIDIA マルチインスタンス GPU(MIG)をサポートしています。さまざまな MIG プロファイルについては、公開されているドキュメントをご覧ください。小規模な LLM をデプロイする場合は、サイズ(メモリ内)を確認し、それに応じて GPU をパーティショニングすることをおすすめします。ノードプールのパーティショニング スキーマは、その Cluster カスタム リソースで定義されます。GPU パーティショニング スキームを適用する方法の詳細については、ノードプールを追加するをご覧ください。アプリケーション オペレーター(AO)の場合は、プロジェクト / クラスタにインストールされて使用可能なアクセラレータについてプラットフォーム管理者(PA)に問い合わせてください。GPU リソースを使用するようにコンテナを構成する方法と GPU リソース割り当てを確認する方法で、詳細を確認できます。

Gemma 3 4B モデルのデフォルトの精度は 16 ビットです。Google が公開しているこちらの表によると、この LLM の GPU メモリ要件は 6.4 GB で、BF16(16 ビット)精度を使用します。

前の ollama-gemma3.yaml では、10 GB の GPU スライス(NVIDIA A100)をコンテナにアタッチしました。これは、次の図に示すように、この量の VRAM メモリで Gemma 3 4B モデルを読み込んで実行するのに十分なためです。

ollama-gemma3.yaml

... omitted ...

        resources:
          limits:
            nvidia.com/mig-1g.10gb-NVIDIA_A100_80GB_PCIE: 1
          requests:
            nvidia.com/mig-1g.10gb-NVIDIA_A100_80GB_PCIE: 1

... omitted ...

Ollama バックエンドをデプロイしてサービスとして公開する

クラスタに接続し、コンテキストをプロジェクトの Namespace に設定します。

# Log in to GDC air-gapped using the next commands

gdcloud auth login --login-config-cert {path to your web TLS certificate}

gdcloud clusters get-credentials {Your User Cluster}
kubectl config set-context --current --namespace=NAMESPACE

Ollama マニフェストを適用します。

kubectl apply -f ollama-gemma3.yaml

Ollama Pod が実行され、関連付けられたサービスが配置されていることを確認します。

kubectl get pods

出力例:

# NAME                             READY   STATUS    RESTARTS   AGE
# ollama-gemma3-6fc6fff74b-9qtpf   1/1     Running   0          1h
kubectl get service

出力例:

# NAME             TYPE          CLUSTER-IP    EXTERNAL-IP    PORT(S)          AGE
# ollama-gemma3   LoadBalancer  172.0.0.1     10.0.0.1       11434:31822/TCP  1d

前の出力から、Ollama サービスの EXTERNAL-IP(10.0.0.1 など)をメモしておきます。次のコマンドで印刷することもできます。

kubectl get service ollama-gemma3 \
-o jsonpath='{.status.loadBalancer.ingress[*].ip}'

Ollama Gemma 3 が動作していることを確認する前に、次のようなネットワーク ポリシーを適用する必要があります。

apiVersion: networking.gdc.goog/v1
kind: ProjectNetworkPolicy
metadata:
  name: allow-ollama-ingress
  namespace: osd-dev
spec:
  subject:
    subjectType: UserWorkload
  policyType: Ingress
  ingress:
  - from:
    - ipBlock:
        cidr: 0.0.0.0/0 # Allows traffic from any IP. Restrict this for production.
    ports:
    - protocol: TCP
      port: 11434

ネットワーク ポリシーを適用します。

kubectl apply -f ollama-netpol.yaml

Ollama のデプロイを検証してテストします。

  1. Ollama が実行されているかどうかを確認します。

    curl http://EXTERNAL_IP:11434
    

    想定されるレスポンス: 「Ollama is running」

  2. 補完リクエストを送信します。

    curl -X POST http://EXTERNAL_IP:11434/v1/completions \
      -H "Content-Type: application/json" \
      -d '{
        "model": "gemma3:latest",
        "prompt": "Google Distributed Cloud air-gapped is a",
        "max_tokens": 128,
        "temperature": 0.90
      }'
    

推論をリクエストする

LLM バックエンド(vLLM と Ollama)がデプロイされ、それぞれの LoadBalancer サービスを介してアクセスできるようになったので、推論に使用できます。

ユースケースに応じて、次のオプションがあります。

  • インタラクティブなウェブ UI: テスト、プロトタイピング、またはユーザーに ChatGPT のようなエクスペリエンスを提供するには、Open WebUI または同様のフロントエンドをデプロイします。
  • コマンドライン インターフェース(CLI): 迅速な検証、スクリプト作成、自動化には、curl またはカスタム スクリプトを使用できます。
  • アプリケーション統合: 内部アプリケーション、AI エージェント、IDE プラグイン(VS Code/JetBrains 用の Continue など)を、vLLM(/v1)または Ollama(/v1)が提供する OpenAI 互換のエンドポイントに直接接続します。

1. UI を使用して LLM を操作する

モデルを操作するための ChatGPT のようなインターフェースを提供するには、クラスタに Open WebUI をデプロイします。

Open WebUI Deployment を作成する

open-webui-deployment.yaml を作成します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: open-webui
  namespace: osd-dev
  labels:
    app: open-webui
spec:
  replicas: 1
  selector:
    matchLabels:
      app: open-webui
  template:
    metadata:
      labels:
        app: open-webui
    spec:
      containers:
      - name: open-webui
        image: HARBOR_URL/PROJECT/open-webui:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
        env:
        - name: OPENAI_API_BASE_URL
          value: "http://gemma-3-4b-it/v1" # Point to your vLLM service
        - name: OPENAI_API_KEY
          value: "EMPTY"
        - name: WEBUI_AUTH
          value: "False"
      imagePullSecrets:
      - name: oss-llm-pull-secret
---
apiVersion: v1
kind: Service
metadata:
  name: open-webui
  namespace: osd-dev
spec:
  type: LoadBalancer
  selector:
    app: open-webui
  ports:
  - port: 80
    targetPort: 8080

ネットワーク ポリシーを適用する

マシンがポート 80 の Open WebUI サービスに到達できるようにする必要があります。

PNP プロジェクト ネットワーク ポリシーを更新して open-webui サービスを含めるか、広範なポリシーを適用します。

apiVersion: networking.gdc.goog/v1
kind: ProjectNetworkPolicy
metadata:
  name: allow-webui-ingress
  namespace: NAMESPACE
spec:
  subject:
    subjectType: UserWorkload
  policyType: Ingress
  ingress:
  - from:
    - ipBlock:
        cidr: 0.0.0.0/0 # Allows traffic from any IP then restrict this for production
    ports:
    - protocol: TCP
      port: 8080

検証

  1. WebUI の IP を取得します。

    kubectl get service open-webui -n NAMESPACE
    
  2. UI にアクセスする: ブラウザを開き、http://WEB_UI_EXTERNAL_IP に移動します。

  3. 構成: 初回ログイン時に、管理者アカウントを作成します。設定で、OpenAI 接続が http://gemma-3-4b-it/v1 を指していることを確認します。

  4. モデルを選択する: チャット インターフェースで、モデルのプルダウンから google/gemma-3-4b-it を選択します。

    WebUI モデル選択プルダウンを開きます。

2. CLI を使用して HTTP リクエストを行う

  • curl:
curl -X POST http://OLLAMA_LOAD_BALANCER_IP:11434/v1/completions \
-H "Content-Type: application/json" \
-d '{
  "model": "gemma3:latest",
  "prompt": "Google Distributed Cloud air-gapped is a",
  "max_tokens": 128,
  "temperature": 0.90
}'

検証と確認

すべてのコンテナとサービスが実行中であることを確認します。

# Log in to GDC air-gapped using the next commands

gdcloud auth login --login-config-cert {path to your web TLS cert}
gdcloud clusters get-credentials {Your User Cluster}
kubectl config set-context --current --namespace=NAMESPACE

# Pods

kubectl get pods # This command should return results like below

# NAME                                   READY   STATUS    RESTARTS   AGE
# vllm-6fc6fff74b-9qtpf                 1/1     Running   0          1h
# ollama-798fbf6ff6-9m7ln               1/1     Running   0          1h


# Services

kubectl get services # This command should return results like below

# NAME                      TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)           AGE
# vllm-service              LoadBalancer   172.0.0.1        10.0.0.1       11434:31822/TCP   1h
# ollama-service        LoadBalancer   172.0.0.2        10.0.0.2       11434:30728/TCP   1h

削除手順

  1. すべての Kubernetes リソースを削除します。

    kubectl delete -f vllm-gemma-3-4b-it-deployment.yaml
    kubectl delete -f vllm-gemma-3-4b-it-service.yaml
    
  2. 未使用のコンテナを Harbor リポジトリから手動で削除します。

運用

vLLM バックエンド

vLLM の基本

vLLM は、高パフォーマンスの単一モデル サービング エンジンとして設計されています。単一のサーバー プロセス内での複数のモデルのサービングや、単一の起動コマンドでの複数のモデルの定義はサポートされていません。複数のモデル(チャットモデルや個別のエンベディング モデルなど)をサービングするには、個別の vLLM インスタンスを起動する必要があります。各インスタンスは独自の Pod またはコンテナに配置され、必要に応じて異なる GPU または GPU スライスに割り当てられます。モデルを動的にスワップする他のバックエンドとは異なり、vLLM インスタンスは、初期化時にモデルと関連する KV キャッシュ メモリを固定して、一貫した高スループットと低レイテンシを確保します。

次のコマンドを使用すると、vLLM Pod のいずれかでターミナルを開くことができます。

kubectl exec -it gemma-3-4b-random-string -n NAMESPACE -- /bin/bash

読み込まれたモデル、その引数、PID が表示されます。

ps aux | grep vllm

予想される出力:

root           1  0.1  0.8 9436960 1550504 ?     Ssl  Feb04   9:18 python3 -m vllm.entrypoints.openai.api_server --model google/gemma-3-4b-it --max-model-len 32768 --enforce-eager
root         504  0.0  0.0   3476  1596 pts/0    S+   02:48   0:00 grep --color=auto vllm

grep コマンド自体とシステム PID の雑然とした表示を避け、よりクリーンで「Ollama らしい」ビューが必要な場合は、次の 1 行のコマンドを使用します。

ps aux | grep [v]llm.entrypoints | awk -F'--model ' '{print $2}' | awk '{print $1}'

レスポンスの例 :

google/gemma-3-4b-it

標準の kubectl コマンドを使用して、内部 API エンドポイントをクエリすることで、vLLM デプロイのステータスをモニタリングできます。

Pod のログを確認する

ターミナルを開いて、初期化ログとサービング ログを表示します。

kubectl logs -f gemma-3-4b-it-random_string -n NAMESPACE

サーバーの準備が整ったことを確認します。

(APIServer pid=1) INFO:     Started server process [1]
(APIServer pid=1) INFO:     Waiting for application startup.
(APIServer pid=1) INFO:     Application startup complete.

Query Internal Status

vLLM は OpenAI 互換の API を提供するため、クラスタ内のターミナルから(debug-sh Pod などを使用して)読み込まれたモデルとシステム ヘルスを直接確認できます。

まずデバッグ Pod を起動する必要があります。手順は次のとおりです。

デバッグ Pod を起動する

次のコマンドを実行して、プロジェクトの Namespace でエフェメラル シェルを起動します。この構成では、busybox イメージ(以前に Harbor レジストリに push されたもの)を使用し、--overrides フラグを使用して必要な認証情報を挿入します。

kubectl run --rm -it debug-sh \
  --image=HARBOR_URL/PROJECT/busybox:latest \
  --restart=Never -n osd-dev --overrides='{
    "spec": {
      "imagePullSecrets": [{"name": "oss-llm-pull-secret"}]
    }
  }' -- sh

主なパラメータ:

  • --rm: 終了時に Pod を自動的に削除し、クラスタ リソースを保持します。
  • --overrides: エアーギャップ環境で、Pod がプライベート Harbor レジストリで認証できるようにするために必須です。

モデルサーバーのステータスをクエリする

Pod 内に入ったら、wget ユーティリティを使用して vLLM API をクエリします。vLLM サービスは内部ポート 8000 をポート 80 にマッピングするため、サービスの DNS 名を使用できます。

  • 読み込まれたモデルを一覧表示する: vLLM エンジンが正常に初期化され、Gemma 3 の重みが読み込まれたことを確認します。

    wget -qO- http://gemma-3-4b-it/v1/models
    

    成功のレスポンス:

    {"object":"list","data":[{"id":"google/gemma-3-4b-it"}]}
    
  • アプリケーションの健全性を確認する: API サーバーがリクエストを処理する準備ができていることを確認します。

    wget -qO- http://gemma-3-4b-it/health
    

    成功のレスポンス:

    OK
    

Ollama の基本

Ollama は、複数のモデルを同時にメモリに読み込むことをサポートしていません。また、LLM を一定時間使用しないと(通常はデフォルトで 30 分)、Ollama は現在のモデルをメモリからアンロードします。

前述の動作により、ソリューションはニーズとユースケースに応じて 2 つ以上の Ollama バックエンドを実装します。これにより、多くのデベロッパーやユーザーが並行して使用できるようになり、1 つの Ollama インスタンスがモデルの読み込みと読み込み解除を頻繁に行い、不要なレイテンシが発生することを防ぎます。

次のコマンドを使用すると、Ollama Pod のいずれかでターミナルを開くことができます。

kubectl exec -it ollama-chat-random_string -- sh
kubectl exec -it ollama-autocomplete-random_string -- sh

Pod 内で、Ollama CLI を使用して使用可能なモデルを調べ、どのモデルが読み込まれているかを確認できます。

  • ollama-chat Pod には、次のモデルがあります。

    # ollama list
    NAME                     ID              SIZE      MODIFIED
    codegemma:7b-instruct    0c96700aaada    5.0 GB    2 hours ago
    
    # ollama ps
    NAME                     ID              SIZE     PROCESSOR    UNTIL
    codegemma:7b-instruct    0c96700aaada    10 GB    100% GPU     4 minutes from now
    
  • ollama-autocomplete Pod には、次の 2 つのモデルがあります。

    # ollama list
    NAME                     ID              SIZE      MODIFIED
    codegemma:2b             926331004170    1.6 GB    2 hours ago
    codegemma:7b-code        aee9a63c13b9    5.0 GB    2 hours ago
    
    # ollama ps
    NAME                 ID              SIZE      PROCESSOR    UNTIL
    codegemma:7b-code    aee9a63c13b9    7.1 GB    100% GPU     4 minutes from now
    
  • Ollama が現在のモデルをアンロードすると、出力は空になります。

    # ollama ps
    NAME    ID    SIZE    PROCESSOR    UNTIL
    

次のコード アシスタンス リクエストを送信すると、Ollama は手動操作なしでモデルを動的に読み込み直します。

GPU 容量の重要性

10 GB の GPU のスライスを 1 つプロビジョニングしても、モデルのメモリ使用量がそれよりも(わずかに)大きい場合、次のように LLM の一部が CPU に読み込まれます。

# ollama ps
NAME                     ID              SIZE     PROCESSOR         UNTIL
codegemma:7b-instruct    0c96700aaada    10 GB    6%/94% CPU/GPU    29 minutes from now

これは最適ではなく、応答レイテンシが高くなるため、このガイドで推奨されている GPU サイズを指定してください。

LLM

vLLM を使用して別の LLM またはお好みの LLM を使用する

GDC エアギャップで vLLM を使用して、さまざまなサイズの Gemma やその他のオープンソースの大規模言語モデル(LLM)(DeepSeek-R1 や Llama 3.1 など)を実行するには、新しいモデルの重みを環境に取り込み、新しいアセットを指すようにデプロイ マニフェストを更新する必要があります。

このソリューション用に確立された運用手順に基づいて、次の手順に沿って別のモデルを読み込みます。

  1. 新しいモデルの重みをダウンロードします。

    インターネットにアクセスできるワークステーションで、Hugging Face CLI を使用して、目的のモデルの重みをダウンロードします。

    • Gemma 3(3-12b-it)の場合:
    hf download google/gemma-3-12b-it
    
    • DeepSeek-R1(7B Distill)の場合:
    hf download deepseek-ai/DeepSeek-R1-Distill-Qwen-7B
    
    • Llama 3.1(8B)の場合:
    hf download meta-llama/Meta-Llama-3.1-8B-Instruct
    

    注: ダウンロードする前に、Hugging Face でモデルのライセンス条項に同意していることを確認してください。

  2. 永続ボリューム(PVC)にデータを入力します。

    既存の model-pvc を更新するか、新しいモデルに十分な 容量を持つ新しい を作成します。ヘルパー Pod メソッドを使用して、ワークステーションから重みを転送します。フォーム ファクタが大きいほど、必要なディスク容量が大幅に増えます。新しい重みを保存するのに十分な容量が Persistent Volume Claim(PVC)にあることを確認します。

    • Gemma 3 4B: 約 15.2 GB。
    • Gemma 3 27B: 約 54 GB 以上。
    • 推奨事項: モデルサイズに関係なく、高速読み込みのために高い IOPS(1,500)を確保するには、500 GiB の PVC の推奨事項を維持します。
    # Copy the new model's hub directory to the helper pod
    kubectl cp ~/.cache/huggingface/hub/ osd-dev/model-uploader:/data/
    
  3. vLLM デプロイ マニフェストを更新します。

    新しいモデル ID を参照するように vLLM デプロイ YAML を変更します。モデルを動的にスワップできる Ollama とは異なり、vLLM インスタンスは単一のモデル専用です。モデルを変更するには、更新または再デプロイする必要があります。

    使用しているモデルに応じて、デプロイの args セクションを更新します。ここでは、deepseek を例として示します。

    args: [
      "-m", "vllm.entrypoints.openai.api_server",
      "--model", "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B", # Update to new Repo ID
      "--max-model-len", "32768",
      "--enforce-eager" # Recommended for GDC stability
    ]
    
  4. GPU とメモリのリソースを調整します。

    モデルが大きいほど、重みと KV キャッシュに必要な VRAM が多くなります。4B モデルから 8B モデルまたは 14B モデルに移行する場合は、リソースの上限が十分であることを確認して、「メモリ不足」によるクラッシュを回避してください。

    • VRAM フットプリント: 16 ビット精度の場合、8B モデルには重みだけで約 16 GB が必要です。さらに、vLLM PagedAttention キャッシュ用の追加メモリが必要です。
    • 推奨事項: 7B パラメータを超えるモデルには、完全な A100 GPU(nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE: 1)を使用して、KV キャッシュの最適なパフォーマンスとヘッドルームを確保します。
  5. 新しいモデルを確認します。

    デプロイの調整が完了したら、内部 API を使用して新しいモデルがアクティブであることを確認します。

    # Inside a debug-sh pod
    wget -qO- http://gemma-3-4b-it/v1/models
    

    成功のレスポンス:

    {"object":"list","data":[{"id":"deepseek-ai/DeepSeek-R1-Distill-Qwen-7B"}]}
    

Ollama で別の LLM を使用する

Llama 3.2 ファミリーや DeepSeek-R1 ファミリーのモデルなど、別のオープンソース LLM を試す場合は、前の Dockerfile で次の Ollama コマンドを変更します。

ollama pull gemma3:latest

たとえば、30 億個のパラメータを含む Llama 3.2 を pull する場合は、次のコマンドを使用します。

ollama pull llama3.2:3b

または、80 億個のパラメータを持つ DeepSeek-R1 を使用する場合は、次のコマンドを使用します。

ollama pull deepseek-r1:8b

複数の LLM をダウンロードして、モデルの重みをコンテナ化することもできます。これにより、Ollama は、さまざまな事前読み込み済みモデルで推論をリクエストするときに、モデルを切り替えることができます。たとえば、Gemma モデルと Llama モデルの両方を Docker イメージに追加できます。エアギャップ環境では、Ollama バックエンドは Ollama ライブラリにアクセスしてモデルをいつでもダウンロードできません。

アプリケーションで実行する前に、各モデルのライセンスと利用規約を確認して同意してください。Ollama のライブラリには多くの LLM があります。LLM バックエンド Docker イメージのビルド中にモデルの重みをダウンロードする場合にのみ、インターネット接続が必要です。

WebUI を開く

Open WebUI Pod が実行状態かどうかを確認します。

kubectl get pods -n NAMESPACE

予想される出力 :

NAME                             READY   STATUS    RESTARTS   AGE
open-webui-69df4664d-przjl       1/1     Running   0          6d3h

サービス IP を確認します。

kubectl get service -n NAMESPACE

予想される出力:

NAME          TYPE            CLUSTER-IP       EXTERNAL-IP      PORT(S)           AGE
open-webui     LoadBalancer   10.201.137.164   136.125.37.224   80:30492/TCP      6d3h

以降のセクションでは、主な UI 機能の使用方法について説明します。

WebUI ユーザー インターフェースの図を開きます。

Ollama バックエンドでソリューションをスケーリングする

縦向き

  • ボトルネックになった LLM に、GPU 全体を使用するまで、より大きな GPU スライスを割り当てます。
  • レスポンスの精度を高めるために、より大きな LLM(7B パラメータではなく 405B パラメータの LLM など)を使用する場合は、スムーズに実行するために複数の GPU が必要になることがあります。
  • 複数の GPU に適合するモデルでは、GPU 間の通信に関連するレイテンシが発生します。

横向き

  • 特定の LLM で目標スループットを達成するために必要な数の Ollama Pod をデプロイします。
    • これを行うには、対応する Ollama デプロイ YAML ファイルの replica の数を増やします。
  • LoadBalancer タイプの Kubernetes Service は、コード アシスタンス リクエストをエンドポイント(Pod)間で分散し、公開された外部 IP を介してそれぞれのレスポンスを返します。
  • Continue プラグインは、機能ごとに 1 つの IP アドレスのみを指します。

オープンウェイト LLM スケーリング アーキテクチャ図。

GDC のエアギャップ環境内で vLLM バックエンドをスケーリングするには、Ollama で使用される戦略と同様の戦略に従い、ハードウェア リソースの割り当てと Pod のレプリケーションの両方に焦点を当てます。

vLLM バックエンドでソリューションをスケーリングする

縦向き

  • GPU 割り当てをアップグレードする: 推論スループット(トークン/秒)がボトルネックになった場合は、NVIDIA A100 GPU をすべて使用するまで、より大きな GPU スライスを割り当てます。
  • マルチ GPU 構成: 単一の 80 GB A100 のメモリに収まらない大規模なモデル(700 億から 4,050 億のパラメータなど)の場合は、テンソル並列処理を使用して複数の GPU にスケーリングする必要があります。
  • レイテンシの考慮事項: 複数の GPU にまたがるモデルでは、GPU 間の通信(NCCL 同期など)に関連するわずかなオーバーヘッドが発生する可能性があります。

横向き

  • レプリカを使用してスループットを増やす: 同じモデルに対する同時ユーザー リクエストの量が増えた場合は、vLLM デプロイ YAML の replicas カウントを増やします。
  • 専用モデル インスタンス: vLLM は単一モデルのサービング エンジンとして設計されており、初期化時に KV キャッシュ メモリを固定するため、ホストする LLM ごとに個別の Pod セットをデプロイする必要があります。
  • ロード バランシング: GDC Kubernetes サービス(タイプ LoadBalancer)は、そのサービスに関連付けられているすべての正常な vLLM Pod エンドポイントに、受信した推論リクエストを自動的に分散します。

トラブルシューティング

エラー 緩和策
FIPS SELFTEST FAILURE BoringSSL などのライブラリに完全性署名がない場合に発生します。BORINGSSL_FIPS=0 を設定し、公式の vLLM イメージを利用することで修正
体重の読み込みが停止する 小規模な PVC で IOPS スロットリングを確認します。パフォーマンス モデルの初期化には 500 GiB のボリュームが必要です。
接続が拒否されました PNP で targetPort(8000/8080)が明示的に許可されていることを確認します。GDC ファイアウォールは、ロードバランサ VIP のバックエンド ポートへのアクセスを自動的に許可しません。