Llama 3.1をOpenShift AIでホストする

こんにちは、Red Hatでソリューションアーキテクトをしている石川です。

本日Meta社が新たなオープンLLMとしてLlama 3.1を発表し、LLM界隈では大きな盛り上がりを見せています。

これまでもMeta社は独自のLLMとしてLlamaシリーズを発表してきていましたが、性能面ではOpenAIのGPT-4oや、AnthropicのClaude 3.5 SonnetなどのクローズドLLMに一歩及んでいませんでした。しかし、新たなLlama 3.1ではこうしたLLMにも負けない、むしろいくつかのベンチマークでは上回る結果を出し、今非常に大きな注目を集めています。
これだけでもオープンLLMにとって大きな前進と言えますが、更にLlama 3.1で適用された新たなライセンスはLlama 3.1で生成したデータを他のLLMの学習に利用することを許可しています。これまで多くのクローズドLLMでは利用規約の中でこうした利用を禁止していましたが、今回Llama 3.1がこのような方針を示したことで、今後小中規模のLLMで生成された学習データを活用したファインチューニングが行われ、高性能なモデルがより増えてくることが期待できます。 対応する言語として日本語は含まれていませんが、今後派生するモデルで対応が行われていくと考えられます。

本ブログではそんなLlama 3.1をOpenShift AI上で動かしてみたいと思います。
なお本記事はあくまで個人的な検証であるため、内容についてサポートへのお問い合わせはご遠慮下さい。

環境の準備

OpenShift環境

今回はOpenShift環境としてROSA HCPを利用します。主題から外れるため構築方法は割愛とさせて頂きますが、弊社メンバーのブログ記事などを参照頂くと簡単に構築できると思います。

Worker NodeとしてAWSの下記のインスタンスタイプを準備し、検証を行いました。
ややオーバースペック気味なので、実際にはもう少し小さいインスタンスタイプでも十分だと思います。
・m5.4xlarge(16vCPU,64GiB Memory) * 3
・g5.4xlarge(16vCPU,64GiB Memory, A10G GPU 24GiB VRAM)

LLMを実行する上で重要となるのがGPUのVRAMの大きさです。
本ブログではパラメータが8BのLlama 3.1を動かすため、およそ8 * 2 =16GiBほどのVRAM容量が要求されると予想できます。AWSのG5インスタンスに搭載されるA10G GPUであれば十分な容量が確保できます。

Operatorのインストール

OpenShiftクラスタが構築できたら、必要なOperatorをOperatorHubからインストールしていきます。
今回必要となるOperatorは以下の通りです。
・Node Feature Discovery(NFD) Operator
・NVIDIA GPU Operator
・OpenShift Serverless Operator
・OpenShift ServiceMesh Operator
・OpenShift AI Operator

上2つのNFD OperatorとGPU OperatorはOpenShiftクラスタの中でGPUを利用するために必要となるOperatorです。

それぞれのOperatorをインストールした後に、NFDではNodeFeatureDiscovery、GPU OperatorではClusterPolicyというカスタムリソースを作成します。設定値について、今回の検証では両者ともデフォルト値のままで大丈夫です。

NFD OperatorがGPUデバイスを搭載したNodeにラベルを付与し、そのラベルを元にGPU Operatorが対象のNodeへGPUドライバ等のコンポーネントをロードします。

ClusterPolicy CRを作成後、nvidia-gpu-operatorNameSpaceでnvidia-driver Podが起動していればOKです。

oc get pod -n nvidia-gpu-operator | grep nvidia-driver
---
nvidia-driver-daemonset-416.94.202407030122-0-skdd2   2/2     Running     0          3h34m

続いて残りのOperatorをインストールします。
OpenShift ServerlessとServiceMeshはOpenShift AIでLLMを実行する際に用いるKServeというOSSの依存関係としてインストールが必要となります。
OpenShift AIのKServeでは2つのデプロイパターンが利用できます。今回のようにLLMなど比較的大きいモデルを実行する際は、1つのランタイムに1つのモデルをロードするSingle model servingと呼ばれる方法でデプロイを行います。 docs.redhat.com

もう一つのデプロイパターンとしてMulti model serving(Model Mesh)という複数のモデルを1つのランタイムで実行する方法も存在しますが、こちらはより小さなモデルを対象としており、今回は使用しません。

OperatorHubからServerless、ServieMeshを検索しインストールしましょう。NFD/GPU Operatorと異なり自分でカスタムリソースを作成する必要はありません。

最後にOpenShift AIのインストールを行います。これまでと同様OperatorHubで検索し、インストールを実行します。Operatorのインストールが完了するとDataScienceClusterというカスタムリソースの作成が求められるため、デフォルト設定のまま作成します。

ステータスがReadyとなるとOpenShiftコンソールの右上のメニューからOpenShift AIコンソールへのリンクが追加されます。

リンクを開き、認証を行うとOpenShift AIコンソールにアクセスできます。

OpenShift AIにおける各種設定

ここからはOpenShift AIでLLMのサービングを行うにあたり必要な各種設定を行なっていきます。
OpenShift AIのKServeを利用しLLMを実行する場合、以下の図のようにLLMを一端オブジェクトストレージに格納し、そこからモデルの実行ランタイム(vLLM、等)にロード、実行します。 そのため、まず初めにモデルの保存先となるオブジェクトストレージの設定やランタイムの登録を行います。

Data Science Project と Data Connectionの設定

OpenShift AIでは、ユーザーが取り組むAIプロジェクトごとに、Data Science Projectという単位でリソースを管理します。OpenShift AIのコンソールから画面左のData Science Projectsを選択し、新たなProjectを作成しましょう。実態としてはこれらはラベルの付いたNameSpaceであり、その中でPod等の各種リソースが作成、実行されます。

上図のData Science Projectを作成すると、llm-servingというNameSpaceがOpenShiftに新たに作成されます。

Projectが作成できたら、続いてData connectionを作成します。
Data connectionでは利用するオブジェクトストレージへのアクセス情報を設定します。

今回はAWS S3にてmy-trial-llmというバケットをあらかじめ作成しており、そこへのアクセス情報を設定しました。 S3のエンドポイントについては以下のドキュメントを確認し、自分が利用するリージョンのエンドポイントを設定しましょう。 docs.aws.amazon.com Data ConnectionではS3互換のオブジェクトストレージであれば利用することができるため、例えばMinioやOpenShift Data Foundationなども同様に設定することができます。 ここで設定した内容はSecretとして管理されます。

便利ツール(ODH Tools)の追加

KServeによってLLMをホストするには、HuggingFaceで公開されているLLMのモデルファイルをオブジェクトストレージバケットに保存する必要があります。 必要なファイルを一端全て自身の端末にダウンロードしてからそれをまたアップロードする、という方法でも対応できますが、便利ツールとしてOpen Data Hub Tools & Extensions Companionというものがコミュニティで公開されています。 github.com こちらを使うことでHuggingFace上のモデルを直接バケットに保存することができます。

利用にはOpenShift AIのSettingsからODH ToolsのコンテナイメージをカスタムNotebook imageとして登録します。この設定はcluster-adminロールの権限が必要なので注意して下さい。(kubeadmin不可のため注意)

Image locationとしてquay.io/rh-aiservices-bu/odh-tec:latestを登録しましょう。 登録が完了するとデフォルトで準備されているNotebook imageと同様に利用することができるようになります。

カスタムServing Runtimeの追加

Llama 3.1をホストするにあたりモデルのランタイムとしてvLLMを利用します。OpenShift AIではvLLMのコンテナイメージがデフォルトでサポートされますが、vLLMプロジェクトのこちらのissueを確認すると、Llama 3.1をホストするには最新のvLLMバージョン(v0.5.3.post1)とtransformersライブラリ(4.43.1)が必要とのことです。現行のOpenShift AI(v2.11)ではこちらのバージョンに対応していないため、代替手段としてカスタムのランタイムイメージを登録します。OpenShift AIの次期バージョン(v2.12)以降ではサポートされるvLLMもバージョンアップされこの作業は不要となるでしょう。

SettingsメニューからServing runtimesを選択し、Pre-installedされたvLLMを複製(duplicate)します。

ここで2点変更を加えます。

apiVersion: serving.kserve.io/v1alpha1
kind: ServingRuntime
metadata:
  annotations:
    opendatahub.io/recommended-accelerators: '["nvidia.com/gpu"]'
    openshift.io/display-name: Latest vLLM ServingRuntime for KServe
  labels:
    opendatahub.io/dashboard: "true"
  name: vllm-runtime-copy
spec:
  annotations:
    prometheus.io/path: /metrics
    prometheus.io/port: "8080"
  containers:
    - args:
        - --port=8080
        - --model=/mnt/models
        - --served-model-name={{.Name}}
        - --distributed-executor-backend=mp
        - --max-model-len=8192 #実行オプション追加
      command:
        - python
        - -m
        - vllm.entrypoints.openai.api_server
      env:
        - name: HF_HOME
          value: /tmp/hf_home
      image: quay.io/jishikaw/vllm-openai-ubi9:0.5.3.post1 #イメージ変更
      name: kserve-container
      ports:
        - containerPort: 8080
          protocol: TCP
  multiModel: false
  supportedModelFormats:
    - autoSelect: true
      name: vLLM

一つは利用するコンテナイメージの変更です。 最新のライブラリを含むコンテナイメージをビルドし、Quayで公開しているのでこちらを利用します。 quay.io/jishikaw/vllm-openai-ubi9:0.5.3.post1

二つ目としてvLLMコンテナ実行時のオプションとして--max-model-len=8192を追加します。 Llama 3.1はコンテクスト長として128kまでサポートしていますが、そのままでは利用するVRAMサイズに納まらないため、オプションにより制限をかけています。

カスタムServing Runtimeの登録を行うとPre-installedされたランタイムと同様にモデルサービング時に利用することができます。

モデルのダウンロード

それでは先ほど登録したODH toolsを使ってHuggingFaceからLlama 3.1のモデルファイルをダウンロードしましょう。

今回利用するMeta-Llama-3.1-8B-InstructはHuggingFaceの以下のURLで公開されています。 https://huggingface.co/meta-llama/Meta-Llama-3.1-8B-Instruct こちらはGated modelとなっており、利用には以下が必要です。
・HuggingFaceアカウントの作成
・HF Tokenの払い出し
・Llama 3.1利用申請

既にHuggingFaceアカウントを持っておりアクセスTokenがある場合は、上2つはスキップして下さい。 3点目のLlama 3.1への利用申請は、先ほどのURLから行います。申請してから利用承認を得るまで若干時間がかかります。(10-20分程度)
承認が得られると以下のようなメールが送られてきます。

それではOpenShift AIのコンソールに戻り、先ほど作成したData Science Projectから新たなWorkbenchを起動します。
Workbenchの起動画面にて以下の設定を行います。
・Notebook image / image selection: 先ほど登録したODH toolsを選択
・Environment variables: Keyとして"HF_TOKEN"、Valueに取得したTokenを設定
・Data connections: Use existing data connectionを選択し、作成済みのData Connectionを選択

他の項目はデフォルトのままでOKです。
Workbenchが起動すると以下のようなオブジェクトストレージのブラウジング画面が表示されます。

ここでImport HF modelを選択し、以下のようにLlama 3.1のリポジトリを選択します。アクセス承認済みであり、Tokenの設定が正しく行われていれば、ファイルのダウンロードが開始されます。

ダウンロードが完了するとLlama 3.1のsafetensorsファイル等がオブジェクトストレージに保存されたのを確認できるはずです。

モデルのサービング

それではLlama 3.1を実行しましょう。再びData Sceince Projectに戻り、Modelsタブを開きます。Single model servingを選択し、デプロイのための設定を行います。

・Model name: llama31
・Serving runtime: 先ほど設定したカスタムランタイム
・Model framework (name - version): vLLM
・Model server replicas: 1
・Compute resources per replica / Model server size: Custom
・CPU requests / limits: 1 - 8
・Memory requests / limits: 4 - 28
・Accelerator: NVIDIA GPU
・Number of accelerators: 1
・Model location: Existing data connection
・Name: 作成済みのData connection
・Path: ダウンロードしたsafetensorsファイルが存在するオブジェクトストレージのパス

設定後Deployを押すとモデルのサービングが始まります。

オブジェクトストレージからのモデルファイルの取得や、容量の大きいランタイムコンテナイメージのpullを行うため、最初は特に時間がかかります。 デプロイが成功すると以下の画像のように推論のAPIエンドポイントが表示されます。
これで無事Llama 3.1のデプロイが完了しました。

推論の実行

最後に推論を実行してみましょう。 Llama 3.1は対応する言語として日本語は含まれていませんが、ここではあえて日本語で質問したいと思います。 以下のコマンドを実行します。

export LLM_ROUTE={表示された推論APIエンドポイント}

curl ${LLM_ROUTE}/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{
        "model": "llama31",
        "messages": [
            {"role": "system", "content": "あなたは丁寧なアシスタントです.ユーザーからの質問に回答して下さい"},
            {"role": "user", "content": "Red Hatとはどんな会社ですか?"}
        ]
    }' | jq .

結果は以下の通りです。

{
  "id": "chat-ff392dae4bc24e6e803cb29325896953",
  "object": "chat.completion",
  "created": 1721818057,
  "model": "llama31",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Red Hatは、オープンソースソフトウェアの開発、販売、サポートを手掛ける米国の企業です。主にLinuxオペレーティングシステムとその周辺ソフトウェアの開発と販売を中心に事業を行っています。",
        "tool_calls": []
      },
      "logprobs": null,
      "finish_reason": "stop",
      "stop_reason": null
    }
  ],
  "usage": {
    "prompt_tokens": 47,
    "total_tokens": 106,
    "completion_tokens": 59
  }
}

無事回答を得られました。何度かやり取りをするとやはり日本語対応は不自然な点がありますが、そちらについては今後出てくるであろう日本語チューニングされたモデルの登場を待ちたいと思います。

OpenShift AIで実行するvLLMについては以下の通り関連するメトリクスをPrometheusにより取得し、表示することもできます。

まとめ

今回は今ホットなLLMであるLlama 3.1をOpenShift AIで実行しました。オンプレミスやエッジ環境など、実行環境を選ばず利用可能なオープンLLMは今後より発展が見込まれると考えられます。Red HatはAIでもOpen Hybrid Cloudを実現し、AI活用の更なる可能性を広げていきます。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。