はじめに
こんにちはサイオステクノロジーの小野です。前回はシングルモデルサービング環境の構築を行い、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を押下します。
今回はモデルのダウンロードのみに使用するのでToken typeをReadとしてトークンを作成します。
作成するとトークンの値が表示されます。このトークン値は見れなくなるので必ずメモしておいてください。
アクセストークンが作成できたらMistral-7B-Instruct-v0.3のページを開いてください。モデルにアクセスするには連絡先を共有することに同意が必要と表示されるので、利用規約を読んで納得した上で同意してください。
しばらくしたらSettingのGated Repos StatusのMistral-7B-Instruct-v0.3が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に設定してください。
次に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をアップロードできます。
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を送ります。
またモデルの詳細を開くと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)
実行した結果が以下になります。こちらの質問に対して回答してくれることが確認できます。
おわりに
LLMをデプロイしたことでLLM APIを利用できるようになりました。OpenShift AIを利用してぜひLLMサービスを展開してみてください。