Hugging Face Transformers と Amazon SageMaker を使用して、GPT-J 6B を推論のためにデプロイします
Deploy GPT-J 6B for inference using Hugging Face Transformers and Amazon SageMaker.
約6ヶ月前の今日、EleutherAIはGPT-3のオープンソースの代替となるGPT-J 6Bをリリースしました。GPT-J 6BはEleutherAIs GPT-NEOファミリーの6,000,000,000パラメータの後継モデルであり、テキスト生成のためのGPTアーキテクチャに基づくトランスフォーマーベースの言語モデルです。
EleutherAIの主な目標は、GPT-3と同じサイズのモデルを訓練し、オープンライセンスの下で一般の人々に提供することです。
過去6ヶ月間、GPT-Jは研究者、データサイエンティスト、さらにはソフトウェア開発者から多くの関心を集めてきましたが、実世界のユースケースや製品にGPT-Jを本番環境に展開することは非常に困難でした。
Hugging Face Inference APIやEleutherAIs 6b playgroundなど、製品ワークロードでGPT-Jを使用するためのホステッドソリューションはいくつかありますが、自分自身の環境に簡単に展開する方法の例は少ないです。
このブログ記事では、Amazon SageMakerとHugging Face Inference Toolkitを使用して、数行のコードでGPT-Jを簡単に展開する方法を学びます。これにより、スケーラブルで信頼性の高いセキュアなリアルタイムの推論が可能な通常サイズのNVIDIA T4(約500ドル/月)のGPUインスタンスを使用します。
しかし、それに入る前に、なぜGPT-Jを本番環境に展開するのが困難なのかを説明したいと思います。
背景
6,000,000,000パラメータモデルの重みは、約24GBのメモリを使用します。float32でロードするためには、少なくとも2倍のモデルサイズのCPU RAMが必要です。初期重みのために1倍、チェックポイントのロードのために1倍です。したがって、GPT-Jをロードするには少なくとも48GBのCPU RAMが必要です。
モデルをよりアクセス可能にするために、EleutherAIはfloat16の重みを提供しており、transformersには大規模な言語モデルのロード時のメモリ使用量を削減する新しいオプションがあります。これらすべてを組み合わせると、モデルのロードにはおおよそ12.1GBのCPU RAMが必要です。
from transformers import GPTJForCausalLM
import torch
model = GPTJForCausalLM.from_pretrained(
"EleutherAI/gpt-j-6B",
revision="float16",
torch_dtype=torch.float16,
low_cpu_mem_usage=True
)
この例の注意点は、モデルをメモリにロードして使用準備ができるまでに非常に長い時間がかかるということです。私の実験では、P3.2xlarge
AWS EC2インスタンスでモデルをディスクに保存せずに上記のコードスニペットでモデルをロードするのに3分32秒
かかりました。この時間は、モデルをすでにディスクに保存している場合、ロード時間が1分23秒
に短縮されますが、本番ワークロードではスケーリングと信頼性を考慮する必要があるため、それでも非常に長いです。
例えば、Amazon SageMakerではリクエストの応答時間が60秒の制限があります。つまり、モデルをロードし、予測を実行する必要が60秒以内に完了する必要があります。これにより、モデル/エンドポイントがワークロードに対してスケーラブルかつ信頼性が高くなるため、非常に合理的な制限だと思われます。予測時間が長い場合は、バッチ変換を使用することができます。
Transformersでは、from_pretrained
メソッドでロードされるモデルは、PyTorchの推奨される方法に従っています。これにより、BERTの場合には約1.97秒
かかります。PyTorchにはtorch.save(model, PATH)
とtorch.load(PATH)
を使用してモデルを保存およびロードする別の方法もあります。
「この方法でモデルを保存すると、Pythonのpickleモジュールを使用してモジュール全体が保存されます。このアプローチの欠点は、シリアル化されたデータが特定のクラスとモデルの保存時に使用された正確なディレクトリ構造に依存しているということです。」
これは、transformers==4.13.2
でモデルを保存した場合、transformers==4.15.0
でロードしようとすると互換性がない可能性があることを意味します。ただし、この方法でモデルをロードすると、ロード時間が約12倍短縮され、BERTの場合は0.166秒
になります。
これをGPT-Jに適用すると、ロード時間を1分23秒
から7.7秒
に短縮できます。これは約10.5倍の高速化です。
図1. BERTとGPTJのモデル読み込み時間
チュートリアル
このモデルの保存と読み込みの方法により、本番シナリオに対応したのモデル読み込みパフォーマンスを実現しました。ただし、以下の点に注意する必要があります。
モデルの保存に
torch.save(model,PATH)
を使用し、モデルの読み込みにtorch.load(PATH)
を使用する際に、PyTorchとTransformersのバージョンを整合させることで、互換性の問題を回避します。
torch.save
を使用してGPT-Jを保存する
Transformersとfrom_pretrained
メソッドを使用してを読み込み、torch.save()
で保存して、torch.load()
と互換性のあるモデルファイルを作成します。
from transformers import AutoTokenizer,GPTJForCausalLM
import torch
# fp 16モデルを読み込む
model = GPTJForCausalLM.from_pretrained("EleutherAI/gpt-j-6B", revision="float16", torch_dtype=torch.float16)
# torch.saveでモデルを保存
torch.save(model, "gptj.pt")
これで、torch.load()
でモデルを読み込み、予測を実行することができます。
from transformers import pipeline
import torch
# モデルを読み込む
model = torch.load("gptj.pt")
# トークナイザーを読み込む
tokenizer = AutoTokenizer.from_pretrained("EleutherAI/gpt-j-6B")
# パイプラインを作成する
gen = pipeline("text-generation",model=model,tokenizer=tokenizer,device=0)
# 予測を実行する
gen("My Name is philipp")
#[{'generated_text': 'My Name is philipp k. and I live just outside of Detroit....
Amazon SageMakerリアルタイムエンドポイント用のmodel.tar.gz
を作成する
モデルを素早く読み込んで推論を実行できるため、Amazon SageMakerにデプロイします。
Amazon SageMakerには、Transformersをデプロイする方法として、「Hugging Face Hubからモデルをデプロイする」または「S3に保存されたmodel_data
を使用してモデルをデプロイする」という2つの方法があります。デフォルトのTransformersメソッドを使用しないため、2番目のオプションを選択し、S3に保存されたモデルを使用してエンドポイントをデプロイする必要があります。
そのためには、モデルの重みと推論に必要な追加のファイル(たとえばtokenizer.json
)を含むmodel.tar.gz
アーティファクトを作成する必要があります。
アップロードされてパブリックアクセス可能なmodel.tar.gz
アーティファクトを提供しており、HuggingFaceModel
を使用してをAmazon SageMakerにデプロイすることができます。
使用方法については、「Amazon SageMakerエンドポイントとしてをデプロイする」を参照してください。
規制ガイドラインに従う必要がある場合など、独自のmodel.tar.gz
を作成する場合は、convert_gpt.pyというヘルパースクリプトを使用することができます。このスクリプトはmodel.tar.gz
を作成し、S3にアップロードします。
# ディレクトリをクローンする
git clone https://github.com/philschmid/amazon-sagemaker-gpt-j-sample.git
# amazon-sagemaker-gpt-j-sampleディレクトリに移動する
cd amazon-sagemaker-gpt-j-sample
# model.tar.gzを作成してアップロードする
pip3 install -r requirements.txt
python3 convert_gptj.py --bucket_name {model_storage}
convert_gpt.py
は、次のようなS3 URIを表示するはずです。s3://hf-sagemaker-inference/gpt-j/model.tar.gz
。
Amazon SageMakerエンドポイントとしてをデプロイする
Amazon SageMakerエンドポイントをデプロイするためには、Amazon SageMaker Python SDKとHuggingFaceModel
クラスを使用します。
以下のスニペットでは、get_execution_role
を使用していますが、これはAmazon SageMakerノートブックインスタンスまたはスタジオ内でのみ利用可能です。それ以外の場所でモデルをデプロイする場合は、ドキュメントを参照してください。
model_uri
は、GPT-J
モデルアーティファクトの場所を定義しています。公開されているものを使用します。
from sagemaker.huggingface import HuggingFaceModel
import sagemaker
# エンドポイントを作成するための権限を持つIAMロール
role = sagemaker.get_execution_role()
# gpt-jアーティファクトへの公開S3 URI
model_uri="s3://huggingface-sagemaker-models/transformers/4.12.3/pytorch/1.9.1/gpt-j/model.tar.gz"
# Hugging Faceモデルクラスを作成
huggingface_model = HuggingFaceModel(
model_data=model_uri,
transformers_version='4.12.3',
pytorch_version='1.9.1',
py_version='py38',
role=role,
)
# SageMaker Inferenceにモデルをデプロイ
predictor = huggingface_model.deploy(
initial_instance_count=1, # インスタンス数
instance_type='ml.g4dn.xlarge' #'ml.p3.2xlarge' # EC2インスタンスタイプ
)
独自のmodel.tar.gz
を使用する場合は、model_uri
をS3 URIに置き換えてください。
デプロイには約3〜5分かかります。
予測の実行
.deploy
メソッドによって作成されたpredictor
インスタンスを使用して予測を実行できます。リクエストをエンドポイントに送信するには、predictor.predict
をinputs
と共に使用します。
predictor.predict({
"inputs": "詳細について教えていただけますか?"
})
min_length
などの追加のkwargs
を使用して予測をカスタマイズするには、以下の「使用上のベストプラクティス」を参照してください。
使用上のベストプラクティス
生成モデルを使用する場合、ほとんどの場合は予測を設定またはカスタマイズしてニーズに合わせることが望まれます。例えば、ビームサーチを使用したり、生成されたシーケンスの最大長や最小長を設定したり、繰り返しを減らすために温度を調整したりすることができます。Transformersライブラリは、これを行うためのさまざまな戦略とkwargs
を提供しています。Hugging Face Inferenceツールキットは、同じ機能をリクエストペイロードのparameters
属性を使用して提供します。以下に、パラメータを使用しない、ビームサーチを使用する、カスタム設定を使用するテキストの生成の例を示します。異なるデコード戦略については、このブログ記事を参照してください。
デフォルトのリクエスト
これはgreedy
サーチを使用したデフォルトのリクエストの例です。
最初のリクエスト後の推論時間:3秒
predictor.predict({
"inputs": "詳細について教えていただけますか?"
})
ビームサーチリクエスト
これは、5つのビームを使用したビームサーチを行うリクエストの例です。
最初のリクエスト後の推論時間:3.3秒
predictor.predict({
"inputs": "詳細について教えていただけますか?",
"parameters" : {
"num_beams": 5,
}
})
パラメータ付きリクエスト
これは、最低でも512トークンを生成するためのmin_length
を使用したカスタムパラメータを使用するリクエストの例です。
最初のリクエスト後の推論時間:38秒
predictor.predict({
"inputs": "詳細について教えていただけますか?",
"parameters" : {
"max_length": 512,
"temperature": 0.9,
}
})
Few-Shotの例(高度)
これは、特定のトークン(例:\n
、.
、または###
)で生成を停止するためにeos_token_id
を使用する方法の例です。キーワードに対してツイートを生成するFew-Shotの例が示されています。
最初のリクエスト後の推論時間:15-45秒
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("EleutherAI/gpt-j-6B")
end_sequence="###"
temperature=4
max_generated_token_length=25
prompt= """key: markets
tweet: 自然と市場のフィードバックを受け取りましょう。人々からではなく。
###
key: children
tweet: たぶん私たちは子供として生まれ変わるために死ぬのかもしれません。
###
key: startups
tweet: スタートアップは火を消す方法ではなく、火を起こす方法を心配すべきです。
###
key: hugging face
tweet:"""
predictor.predict({
'inputs': prompt,
"parameters" : {
"max_length": int(len(prompt) + max_generated_token_length),
"temperature": float(temperature),
"eos_token_id": int(tokenizer.convert_tokens_to_ids(end_sequence)),
"return_full_text":False
}
})
エンドポイントを削除するには、次のコマンドを実行します。
predictor.delete_endpoint()
結論
私たちは、EleutherAIによって作成された600億パラメータの言語モデル「GPT-J」を使用して、Amazon SageMakerを使ってデプロイすることに成功しました。モデルの読み込み時間を3.5分から8秒に短縮し、スケーラブルで信頼性のある推論を実行できるようにしました。
torch.save()
とtorch.load()
を使用すると、互換性の問題が発生する可能性があることに注意してください。Amazon SageMakerエンドポイントのスケーリングについて詳しく学びたい場合は、私の他のブログ記事「MLOps:Hub&SageMakerパイプラインでのHugging Face Transformersのエンドツーエンド」をチェックしてください。
読んでいただきありがとうございます!ご質問があれば、お気軽にGithubやフォーラムを通じてご連絡ください。TwitterやLinkedInでもご連絡いただけます。
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles