LLMをコード流用で実行しようとしたら他のモデルでは問題なかったのに突然エラーが出て困った話【Python】

LLM

スポンサーリンク

今回はタイトルの通り、「さっきまで他のLLMで問題なかったのに何でこのモデルだけ!?」みたいなエラーに遭遇したのでその備忘録です。

事象

実行コード1

エラーの前に、実行したコードを部分的に抜粋して紹介します。

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig

model_path = "cyberagent/Llama-3.1-70B-Japanese-Instruct-2407"
quantization_config = BitsAndBytesConfig(load_in_8bit=True)
model = AutoModelForCausalLM.from_pretrained(model_path, 
                                             quantization_config=quantization_config, 
                                             device_map="auto")
model.eval()

よくあるコードですね。
同じようなコードばかりで、もう見飽きたという方も多いのではないでしょうか。

ちなみに、今回試したモデルはサイバーエージェント社から出ている、"Llama-3.1-70B-Japanese-Instruct-2407″です。
何やら日本語性能が現状最も高いらしいので、気になってトライしてみた次第です。

遭遇したエラー1

実行後、こんなエラーが出てきました。

ValueError: Some modules are dispatched on the CPU or the disk. Make sure you have enough GPU RAM to fit the quantized model. If you want to dispatch the model on the CPU or the disk while keeping these modules in 32-bit, you need to set `load_in_8bit_fp32_cpu_offload=True` and pass a custom `device_map` to `from_pretrained`. Check https://huggingface.co/docs/transformers/main/en/main_classes/quantization#offload-between-cpu-and-gpu for more details.

どうやら、load_in_8bit_fp32_cpu_offload=Trueをセットし、device_mapをあれこれしろと言っているようなので、とりあえずload_in_8bit_fp32_cpu_offload=Trueをセットしてみました。

実行コード2

load_in_8bit_fp32_cpu_offloadを追加。

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig

model_path = "cyberagent/Llama-3.1-70B-Japanese-Instruct-2407"
quantization_config = BitsAndBytesConfig(load_in_8bit=True)
model = AutoModelForCausalLM.from_pretrained(model_path, 
                                             quantization_config=quantization_config, 
                                             load_in_8bit_fp32_cpu_offload=True, # 追加
                                             device_map="auto")
model.eval()

遭遇したエラー2

実行したところ、こんなエラーが・・・

TypeError: LlamaForCausalLM.__init__() got an unexpected keyword argument 'load_in_8bit_fp32_cpu_offload'

簡単にいってしまうと、「load_in_8bit_fp32_cpu_offloadなんて引数ないよ」ってことですね。
何がどうなっているのか・・・

解決策

コード

いろいろ試した結果、こちらで改善しました。

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig

model_path = "cyberagent/Llama-3.1-70B-Japanese-Instruct-2407"
quantization_config = BitsAndBytesConfig(load_in_8bit=True)
model = AutoModelForCausalLM.from_pretrained(model_path, 
                                             quantization_config=quantization_config, 
                                             #load_in_8bit_fp32_cpu_offload=True, # 削除
                                             device_map={"":0}) # 変更
model.eval()

load_in_8bit_fp32_cpu_offloadは削除し、device_map="auto"からdevice_map={“":0}に変更しました。

device_mapについてあまりちゃんと理解できていませんが、GPU設定をオートではなくcuda:0を使用するように定義したような雰囲気っぽいです。
ちなみに、作業環境ではNVIDIA GeForce RTX 4070 Ti Super (VRAM 16GB)を使っています。

出力結果

動作してみた結果、以下のようなエラーが発生しました。

torch.OutOfMemoryError: CUDA out of memory. Tried to allocate 448.00 MiB. GPU 0 has a total capacity of 15.99 GiB of which 0 bytes is free. Of the allocated memory 45.59 GiB is allocated by PyTorch, and 388.71 MiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation.  See documentation for Memory Management  (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)

モデルサイズが大きすぎてVRAMが大きくメモリリークしていますね。
VRAM 16GB程度では8bit量子化でも70Bクラスには全く太刀打ちできないようです。う~ん、残念。

以上です。

【Reference】

https://discuss.huggingface.co/t/typeerror-llamaforcausallm-init-got-an-unexpected-keyword-argument-load-in-4bit/41245/5

LLM

Posted by このめ