清水理史の「イニシャルB」
自宅PCで「rinna」の日本語言語モデルを試用、メモリ32GBあればCPUだけでも動くぞ!
2023年6月5日 06:00
日本語に対応した大規模言語モデル(LLM)の登場が相次いでいる。5月17日に、サイバーエージェントから日本国内では最大となる68億パラメーターのモデルが、同日にrinnaからも36億パラメーターのモデルがリリースされた。
快適な利用にはVRAM16GB程度のGPUが必要だが、CPUと32GB以上のメモリがあれば、GPUなしでも動かすことが可能だ。今回は、自宅のPCでrinnaの36億パラメーターのモデルを動かしてみた。
VRAMが欲しい……
最初に、今回の検証をしての感想を述べるが、切実にビデオカード、それもVRAMを大量に積んだビデオカードが欲しくなった。
ここ数年は、ゲームのプレイ頻度も減ってきたので、メインPCのビデオカードも数年前に買ったRTX3070 8GBで不満を感じていなかったのだが、この1カ月で、認識がすっかり変わってしまった。
冒頭で述べたように日本語言語モデルが続々公開されるのを見て、ぜひ自宅のPCでも、これらのモデルを動かしてみたいと思った。しかし、いざ試してみると、VRAMのメモリ不足に苦しめられた。せっかく精度が高くなった日本語のモデルが試せるようになってきたにもかかわらず、手持ちのPCの力不足が判明してしまったわけだ。
最終的に、CPUのみでも動くようにできたが、処理速度は「激遅」で、実用性としてはかなり厳しい。質問から回答まで長いと1分ほど待たなければならない。
今は、発表されたばかりのRTX4060ti 16GBを待つか、中古でRTX3090 24GBを買うか、真剣に悩んでいる。いずれにせよ、こんなに切実にビデオカード、いや、VRAMが欲しいと思ったのは初めてだ。
rinnaの36億パラメーター言語モデルをセットアップする
話を戻して、検証内容を紹介していこう。今回試したのは、rinnaが公開した36億パラメーターの日本語対応言語モデルだ。
rinnaは2022年1月に13億パラメーターの日本語対応言語モデルをリリースしていて、日本語対応の言語モデルは以前からあった。しかし、今回はパラメーター数が大幅に増え、精度が大きく向上していることが特徴だ。
詳細は同社のプレスリリースを参照して欲しいが、今回提供されたのは汎用言語モデル と、対話形式の会話に最適化された対話言語モデルの2種類となる。
言語モデルは、基本的に「次の単語を予測する」という動作となっており、予測できる単語をどこまで絞り込めるかが「perplexity(パープレキシティ)」というひとつの指標として使われることがあるが、今回のモデルは、この値が8.68となっている。
つまり、文章を生成する際に、次の単語の候補を8.68にまで絞り込めるということになる。
この値は、少ないほど精度が高くなるが、昨年リリースされた13億パラメーターのモデルではperplexityが14だったので、かなり精度が上がったと言える。
なお、OpenAIのGPT-3は1750億パラメーター、GoogleのPaLM 2は5400億パラメーターなので、これらと規模を比べるのは酷だが、それでも日本語に特化した学習によって、自然な日本語を生成できるモデルが、一般的なPCでも動作可能になったことは画期的と言えるだろう。
言語モデルの動作にGPUは必須か?
さて、「一般的なPCでも動作可能」とは言ったが、要求されるスペックはそれなりに高く、どんなPCでも動作可能なわけではない。
大規模言語モデルでは計算にGPUを利用するのが一般的だが、今回の36億パラメーターのモデルの場合、通常で14GB前後のVRAMが必要となる。
つまり、現行のRTX4000シリーズだと、16GBのRTX4080、24GBのRTX4090、旧世代の3000シリーズだと24GBのRTX3090あたりが候補となる。
ただし、実行時に、float16(半精度の浮動小数点)のパラメーターを設定すれば、使用メモリを約半分にできるため、実質的には12GBクラスのGPUでも利用可能となる。RTX 3060(12GB版)、RTX3080あたりでも動作可能だ。
なお、半分と言っても、重要な小数部分はあまり減らさずに、あまり関係のない整数部分を減らすので、大きく精度が落ちることはない。
残念ながら、GeForceシリーズがない、もしくはあってもVRAMが8GBなどで不足している場合は、CPUのみで動かすこともできる。
この場合、RAMでも同様に14GB前後が必要になるので、システムが使用する分も含めて32GB程度のメモリが搭載されたPCなら、「一応」動作させることができる。もちろん、CPUの性能も関係するが、速度を追求しないならローエンドモデルでも利用可能だ(4コア8スレッドのCore i3-10100で検証済み)。
PC環境を用意する
続けて、今回の検証環境をPCに構築していく。
まずはPythonをインストールする。Microsoft Store経由でPython 3.11をダウンロードできるので、これをインストールしよう。Microsoft Store経由の場合、更新が簡単なうえ、パスの設定も自動的に行われるので手間が少ない。
また、必須ではないが、あると便利なので「Visual Studio Code」もインストールしておく。同様にMicrosoft Store経由でインストールするのが簡単だ。
Pythonの実行環境が用意できたら、バージョンを確認したり、パッケージインストール用のpipをアップデートしたりしておく。PowrShellで以下のコマンドを入力しよう。
python –version
pip --version
pip install –-upgrade pip
続いて、必要なパッケージをインストールしていく。まずは、Python用機械学習ライブラリのPyTorchをインストールする。PyTorchのウェブサイトで環境を選択すると、インストール用のコマンドが表示されるので、そのまま入力すればインストール可能だ。今回は、CPUで動かすが、GPUでも動かせるようにするためにCUDAも選択している。
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
さらに、テキストをトークン化するためのトークナイザーの「sentencepiece」、およびモデルがHugging Faceで公開されているのでHugging Faceのモデルを利用するための「transformers」をインストールしておく。入力するコマンドは以下だ。
Pip install transformers sentencepiece
Pythonのコードを実行する
以上で環境が整った。後はコードを実行するだけだ。今回は、rinnaのサイトで公開されているサンプルコードを若干、カスタマイズして、以下のようなコードを利用した。
頭の部分でCPUやGPUなど、モデルを選択できるようにしている。標準はCPU処理になっているので、GPUで処理したい場合は「#」のコメントを付けて、利用したいモデルの「#」を外せばいい。
なお、今回は対話モデルを利用し、会話をするときに自動的に前の質問と回答も含めるようにしている。思ったように前の会話を受けて答えてくれない場合もあるが、何とか会話が成立する印象だ。
import time
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
tokenizer = AutoTokenizer.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-sft", use_fast=False)
# 標準
#model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-sft")
# 自動
#model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-sft", device_map='auto')
# 自動(VRAM16GB以下でも8GBはNG)
# model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-sft", torch_dtype=torch.float16, device_map='auto')
# CPU指定
model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-sft").to("cpu")
# GPU指定
#model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-sft").to("cuda")
# GPU指定(VRAM16GB以下でも8GBはNG)
#model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-sft", torch_dtype=torch.float16).to("cuda")
#繰り返し(抜けるのはCtl+c)
prompt = ""
while True:
# 質問を入力
question = input("質問をどうぞ: ")
if question.lower() == 'clear':
question = ""
prompt = ""
prompt = prompt+f"ユーザー: {question}<NL>システム: "
# 時間計測開始
start = time.time()
token_ids = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt")
with torch.no_grad():
output_ids = model.generate(
token_ids.to(model.device),
do_sample=True,
max_new_tokens=128,
temperature=0.7,
pad_token_id=tokenizer.pad_token_id,
bos_token_id=tokenizer.bos_token_id,
eos_token_id=tokenizer.eos_token_id
)
output = tokenizer.decode(output_ids.tolist()[0][token_ids.size(1):])
output = output.replace("<NL>", "\n")
# 時間表示
end = time.time()
print(end-start)
# print(prompt)
print(output)
prompt = prompt+output+"<NL>"
GPUなら数秒、CPUだと数十秒
実行してみると、やはりCPUだとかなり遅い。
回答の長さにもよるが、Core i3-10100の場合、回答に30秒~1分ほど待たされる。Ryzen 9 3900(12コア24スレッド)にすると、シンプルな回答なら20~30秒、長いと50~60秒といったところになる。
とにかく入力してから、出力が完了するまで、結構待たされる印象で、正直、検証といえども会話を重ねるのがつらい。
ちなみに、RTX3070 8GBでもfloat16を指定することで、一応モデルを動作させることは可能だ。CUDAの威力によって、ほとんどの質問に10秒以下で回答してくれる。ただし、2~3回質問するとメモリオーバーになって停止してしまうため、実用的ではない。
今回は検証できなかったが、12GBのRTX3060シリーズであれば、実用的な速度で利用できる可能性は高いと予想される。
自然な会話は十分に可能
肝心の精度だが、回答の正確性は別にして、36億と少ないパラメーターにしては、自然な会話が成立する印象だ。
「日本で一番標高が高い山を教えて」に対して「日本の最高峰は、標高4,850 m(12,320フィート)の日本アルプスの薬師岳です。」と答えるように、内容が必ずしも正確でないのは、ChatGPTなどと同様だが、少なくとも山について回答しているし、標高などの単語も考慮している。
今回のモデルは、公式サイトでも記載されているように、標準のモデルをベースにして、さらに学習(fine-tuning)したり、事前知識を与えたりして、企業などが特定のドメイン用に組み込んで使えるようにするためのものなので、自然な会話が成立しているだけで十分と言える。
このため、例えば、以下のように、プロンプトで事前知識などを与えると、かなり正確かつ自然な回答が得られる。社内のデータベースや情報などをうまくプロンプトに取り込むだけで、活用の幅は広がると言えそうだ。
事前知識ではなく以下のコンテキストを活用して質問に回答してください。
コンテキスト:
- プロジェクト「ブルー」は次世代の社員アシスタントAIを実現するための新規事業
- 社内文書をデータベース化しGPT-4ベースのチャットAIとして提供する
- 2024年4月の全社展開を目指す
- 予算規模は1億円
質問:
プロジェクトブルーについて教えてください。
VRAM16GBで世界が変わる
以上、rinnaの36億パラメーターの日本語言語モデルを試してみたが、このレベルの言語モデルが自宅のPCで動くのは驚異的だ。さすがにCPUのみでは実用性は低いが、VRAMが16GBあれば世界が変わると言っていい。
ウェブ検索やファイル検索などと組み合わせた自宅対話型AIサーバーのベースとして企業などで活用できそうだし、ゲームなどに組み込むことも不可能ではなさそうだ。興味がある人は、ぜひ動かしてみることをおすすめする。