サーバ用GPUではサクサク動くことはわかってるFugaku-LLM。
前回はCPUのみで動かしてみましたが、
今回は自宅用GPUを追加して早くなるのかを試してみました。
結果:とりあえず20倍くらい高速化
自宅用GPU(Geforce 2070)を使うとFugaku-LLMは少し早くなる。
・GPUでのサポートあり実行結果:約4分
・CPUのみでの実行時間:約70分
実行環境
以前の実行環境を強化しました。
・GPU:Geforce 2070を追加
・メモリ:64GB追加(合計96GB)
PCスペック:GPU追加、メモリ強化
・CPU:Intel Core i5-13500
・メモリ:96GB(DDR4-3200×4枚)← 以前は32GB
・GPU:Geforce 2070(8GB)
・SSD:NVMe 1TB
・その他:
・メモリを3倍、古めのGPU搭載しました。
OSなど
・OS:Ubuntu 22.04 LTS Desktop
・今回は仮想化やコンテナは利用していません。
実行コード
以前と同じです。
import datetime
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
dt = datetime.datetime.now()
start = 'start: '+str(dt)
print(start)
model_path = "Fugaku-LLM/Fugaku-LLM-13B-instruct"
dt = datetime.datetime.now()
str1 = 'after_model_path: '+str(dt)
print(str1)
tokenizer = AutoTokenizer.from_pretrained(model_path)
dt = datetime.datetime.now()
str1 = 'after_tokenizer: '+str(dt)
print(str1)
model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.bfloat16, device_map="auto")
dt = datetime.datetime.now()
str1 = 'after_model: '+str(dt)
print(str1)
model.eval()
dt = datetime.datetime.now()
str1 = 'after_model.eval(): '+str(dt)
print(str1)
system_example = "以下は、タスクを説明する指示です。要求を適切に満たす応答を書きなさい。"
instruction_example = "スーパーコンピュータ「富岳」の名前の由来を教えてください。"
prompt = f"{system_example}\n\n### 指示:\n{instruction_example}\n\n### 応答:\n"
input_ids = tokenizer.encode(prompt,
add_special_tokens=False,
return_tensors="pt")
dt = datetime.datetime.now()
str1 = 'after_input_ids: '+str(dt)
print(str1)
tokens = model.generate(
input_ids.to(device=model.device),
max_new_tokens=128,
do_sample=True,
temperature=0.1,
top_p=1.0,
repetition_penalty=1.0,
top_k=0
)
dt = datetime.datetime.now()
str1 = 'after_tokens: '+str(dt)
print(str1)
out = tokenizer.decode(tokens[0], skip_special_tokens=True)
dt = datetime.datetime.now()
str1 = 'after_out: '+str(dt)
print(str1)
print(out)
実行ログ
tsubasa@ubuntu2204:~/fugaku$ python3 fugaku.py
start: 2024-06-04 23:25:21.430459
after_model_path: 2024-06-04 23:25:21.430477
after_tokenizer: 2024-06-04 23:25:22.056591
Loading checkpoint shards: 17%|████████▊ | 1/6 [00:00<00:02, Loading checkpoint shards: 33%|█████████████████▋ | 2/6 [00:00Loading checkpoint shards: 83%|█████████████████████████████████████████Loading checkpoint shards: 100%|█████████████████████████████████████████████████████| 6/6 [00:00<00:00, 7.37it/s]
WARNING:root:Some parameters are on the meta device device because they were offloaded to the cpu.
after_model: 2024-06-04 23:25:23.883337
after_model.eval(): 2024-06-04 23:25:23.883999
after_input_ids: 2024-06-04 23:25:23.885092
after_tokens: 2024-06-04 23:29:28.747243
after_out: 2024-06-04 23:29:28.747494
以下は、タスクを説明する指示です。要求を適切に満たす応答を書きなさい。
### 指示:
スーパーコンピュータ「富岳」の名前の由来を教えてください。
### 応答:
「富岳」は日本の理化学研究所と富士通が共同で開発したスーパーコンピュータで、富士山の異名である「富嶽」に由来している。この名前は、スーパーコンピュータが日本の高い技術力と革新性を象徴し、世界の科学と技術の進歩に貢献することを願って付けられた。また、富士山が四季を通じて美しく、荘厳であり続けるように、「富岳」もスーパーコンピュータの安定性、スピード、性能の象徴であり続けることを願って名付けられた。
考察とこれから
今回は家庭用GPUを使って動かしてみましたが、
結果、実行時間が約1/20になりました。
しかし、まだ4分もかかっており遅い。
この原因を考えます。
原因1:GPUメモリが足りない。
実行前からわかっていましたが、
「Geforce 2070のGPUメモリ8GBには、
Fugaku-LLM全てはGPUメモリには乗り切らない」です。
(完全GPU動作させるにはGPUメモリが28GBくらい必要な模様)
このため、Pytouchでは、
GPUをアクセラレーターとして使い、
足りないメモリ領域をCPUで動かしているようです。
これは、実行時に以下のようなWARNINGが出てることからもほぼ確定。
WARNING:root:Some parameters are on the meta device device because they were offloaded to the cpu.
以下は実行時スクショですが、
やっぱりGPUメモリだけでは足りずCPU側のメインメモリも食っています。
まぁ、足りないものは仕方ないですから…
…サーバ用GPUとか高くて買えないし、
ストレージにスワップするよりはマシでしょう。
原因2:CPUが全然回っていない
こちらのスクショからもわかるんですが、
CPUコアの合計利用率が
トータル1コア分100%以上にならないんですよ。
なんで???
で、
感覚的なもの(理由はきちんと追求してない)では、
・CPU利用率がトータル100%にキャップされている
という可能性もありなんですが、
なんとなく、
・メモリ転送速度の方で詰まってね?
って気もします。
ここらへん、
CPUとメモリの利用のあたり勉強しないとわかんないっすね。
いや、ソースコード読めっていうツッコミもありますが。。。
原因3:実行時に毎回メモリロードしている
これはサンプルコードをただ流用して動かしてるせいなんですが、
このコード、
「実行するたびに毎回LLMをメモリ上に展開してる」
んですよね。
これは非効率なんで、
この辺は後日改善しようと思います。
最後に広告
本業の方の広告になってしまうのですが、
会社関係で「メタバース・デジタルツイン講座」やってます。
メタバース・デジタルツインに興味のある人はぜひよろしくお願いします。
https://www.kcc.knowledgewing.com/icm/srv/course-application/init-detail?cd=FLM&pcd=FLMC&cscd=UMT01L