OpenShift AIにLLMをデプロイしてみた

はじめに

こんにちはサイオステクノロジーの小野です。前回はシングルモデルサービング環境の構築を行い、LLMをデプロイする方法を解説しました。今回はHugging Face HubからLLMをダウンロードし、そのLLMをOpenShift AIにデプロイして、LLM APIを利用する方法を解説します。

公開LLM

有名な公開LLM

  • Llama3
    • Meta社が開発したLLMです。軽量かつ高精度なモデルでオープンでありながらGPT-3.5に匹敵する性能があります。
  • Mistral
    • Mistral teamが開発したLLMです。Llamaと同様に軽量であるのに加えて、推論が速いという特徴があります。
  • Deepseek-R1
    • 中国のDeepseek社が開発したLLMです。OpenAIの最新モデルであるo1に匹敵する性能を持っています。今最も流行に乗っているモデルです。

LLMの取得設定

Hugging Face Hubでの操作

Hugging Face Hubとは

AIモデル、データセット、AIデモアプリを公開・管理するプラットフォームです。GitHubのAIモデル版のようなイメージです。

モデルの内容

今回はMistral-7B-Instruct-v0.3というLLMをデプロイします。

https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.3

このLLMは70億個のパラメータを持ち、Instruct-tunningと呼ばれる自然な会話ができるようになる調整がされています。

必要な登録

Hugging Face Hubのアカウントを作成してください。Hugging Face Hubのモデルをダウンロードするにはアクセストークンが必要になります。SettingのAccess Tokensを開き、Create new tokenを押下します。

Hugging Face Hubのアクセストークン作成

今回はモデルのダウンロードのみに使用するのでToken typeをReadとしてトークンを作成します。

アクセストークンのToken typeをReadに設定

作成するとトークンの値が表示されます。このトークン値は見れなくなるので必ずメモしておいてください。

Hugging Face Hubのアクセストークンの表示。閉じると見れなくなるのでメモしてください。

アクセストークンが作成できたらMistral-7B-Instruct-v0.3のページを開いてください。モデルにアクセスするには連絡先を共有することに同意が必要と表示されるので、利用規約を読んで納得した上で同意してください。

LLMの利用規約の同意。必ず規約を読んだうえで同意してください。(画像はMistral-7b-Instruct-v0.2ですがv0.3の規約に同意してください)

しばらくしたらSettingのGated Repos StatusのMistral-7B-Instruct-v0.3がACCEPTEDとなることを確認します。これでモデルが利用できるようになります。

Gated Repos Statusの項目がACCEPTEDとなれば利用可能になります

OpenShift AIでのモデルデプロイ

前提条件

シングルモデルサービング構築済み(前回の記事を参考にしてください)
データ接続設定済み(以前の記事を参考にしてください)

Hugging Face HubからモデルのダウンロードとS3へのアップロード

OpenShift AIのモデルサービングはS3ストレージにモデルファイルを格納して、そこからモデルをデプロイするという流れになります。したがってHugging Face HubのMistral-7B-Instruct-v0.3をダウンロードしてAWSのS3にアップロードします。

どのような方法でアップロードしてもかまいませんが、今回はOpenShiftAIのワークベンチ機能を利用してアップロードする方法について解説します。

別の方法としてはLLMをS3へ簡単にアップロードするツールが存在するので、公式のツールではありませんが、ぜひ確認してみてください。https://github.com/opendatahub-io-contrib/odh-tec

それでは最初にモデルのダウンロードをするために、適当なワークベンチを作成します。モデルデータを保存するS3とのデータ接続と連携するのと、大きなファイルをダウンロードするのでPVのサイズを40GiBに設定してください。

LLMダウンロード用ワークベンチ作成。PVのサイズを40GiBに設定し、モデルを保存するS3ストレージへのデータ接続を設定する。

次にHugging Face Hubの認証を行います。ワークベンチのJupyterLabでhuggingface_hubのライブラリをインストールしてください。

!pip install huggingface_hub

インストールできたらHugging Face Hubへログインを行います。tokenにはHugging Face Hubのアクセストークンの値を入れてください。

from huggingface_hub import login
login(token='<メモしたトークンの値>')

これによりHugging faceからダウンロードが可能になります。次にHugging Face HubからMistral-7B-Instruct-v0.3をダウンロードします。

from huggingface_hub import snapshot_download
snapshot_download(repo_id="mistralai/Mistral-7B-Instruct-v0.3", local_dir="./models")

ダウンロードが完了したら、データ接続したS3ストレージへアップロードします。

import os
import boto3
import botocore

aws_access_key_id = os.environ.get('AWS_ACCESS_KEY_ID')
aws_secret_access_key = os.environ.get('AWS_SECRET_ACCESS_KEY')
endpoint_url = os.environ.get('AWS_S3_ENDPOINT')
region_name = os.environ.get('AWS_DEFAULT_REGION')
bucket_name = os.environ.get('AWS_S3_BUCKET')

if not all([aws_access_key_id, aws_secret_access_key, endpoint_url, region_name, bucket_name]):
    raise ValueError("One or data connection variables are empty.  "
                     "Please check your data connection to an S3 bucket.")

session = boto3.session.Session(aws_access_key_id=aws_access_key_id,
                                aws_secret_access_key=aws_secret_access_key)

s3_resource = session.resource(
    's3',
    config=botocore.client.Config(signature_version='s3v4'),
    endpoint_url=endpoint_url,
    region_name=region_name)

bucket = s3_resource.Bucket(bucket_name)

def upload_directory_to_s3(local_directory, s3_prefix):
    num_files = 0
    for root, dirs, files in os.walk(local_directory):
        for filename in files:
            file_path = os.path.join(root, filename)
            relative_path = os.path.relpath(file_path, local_directory)
            s3_key = os.path.join(s3_prefix, relative_path)
            print(f"{file_path} -> {s3_key}")
            bucket.upload_file(file_path, s3_key)
            num_files += 1
    return num_files

model_dir = "./models"
s3_model_dir = "models/mistral"

upload_directory_to_s3(model_dir, s3_model_dir)

print(f"{model_dir} has been uploaded to {s3_model_dir}") 

これによりS3ストレージにLLMをアップロードできます。

S3にアップロードされたLLMのファイル

LLMのデプロイ

S3にLLMが保存されたので、そのLLMをOpenShiftAIにデプロイします。前回の記事のシングルサービング形式を選択してモデルをデプロイできる状態にしてください。

以下のようにデプロイ設定してください:

  • Model deployment name:test-llm
  • Serving runtime:vLLM ServingRuntime for KServe
  • Number of model server replicas to deploy:1
  • Model server size:Small
  • Accelerator:NVIDIA GPU
  • Number of Accelerators:1
  • Make route:✅
  • Token authentication:✅
  • Service account name:test-token
  • Connection:モデルが保存されているデータ接続
  • Path:models/mistral
  • Additional serving runtime arguments:–max-model-len=8192
    • vLLMのエンジンに渡す引数を設定できます。
    • デフォルトのままだとメモリが不足してエラーが出るので出力するトークン数を制限します。
    • 詳しくはドキュメント参照してください。https://docs.vllm.ai/en/latest/serving/engine_args.html

デプロイ設定

Statusに✅がついたらデプロイ完了です。「Internal and external endpoint details」を押下するとAPIのエンドポイントを確認できます。Externalの方にAPIを送ります。

デプロイされたLLM。ステータスに✅がつけばデプロイ完了。

APIのエンドポイント確認。urlが内部公開されているエンドポイントでExternalが外部公開されているエンドポイント。

またモデルの詳細を開くとAPIのトークンを確認できます。

モデルの詳細を開くとAPIトークンを確認できる

APIの検証

デプロイしたLLMに対してAPIリクエストを送り、質問に対して回答することを検証します。

以下のコードを実行します。<APIエンドポイント>にはExternalの方のエンドポイントを入れ、<APIトークンの値>にはAPIトークンの値を入れてください。

import requests
import json

# URLとヘッダーの設定
url = "<APIエンドポイント>/v1/chat/completions"
token = "<APIトークンの値>"
headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {token}"
}

# リクエストボディの設定
data = {
    "model": "test-llm",
    "messages": [
        {"role": "system", "content": "あなたは丁寧なアシスタントです.ユーザーからの質問に回答して下さい"},
        {"role": "user", "content": "OpenShiftとは何ですか?"}
    ]
}

# POSTリクエストの送信
response = requests.post(url, headers=headers, data=json.dumps(data))

# レスポンスの表示
print(response)
formatted_json = json.dumps(response.json(), indent=4, ensure_ascii=False)
print(formatted_json)

実行した結果が以下になります。こちらの質問に対して回答してくれることが確認できます。

APIの実行結果。「OpenShiftとは何ですか?」という問いに対して、LLM APIが回答している。

おわりに

LLMをデプロイしたことでLLM APIを利用できるようになりました。OpenShift AIを利用してぜひLLMサービスを展開してみてください。

参考

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です