adept/fuyu-8bをJupyter Notebookで4bit量子化で動かす【LLM】

はじめに

以下のツイートを見て、マルチモーダルの軽量LLMが出ていることを知ったので動かしてみます. 手元の環境では、量子化なしではGPU RAMが足りなかったので4bit量子化を行っています

環境

  • cuda:12.2.0
  • ubuntu22.04
  • NVIDIA-L4

実行

基本的には、以下のHFのページのコードを動かせばいいのですがそのままでは動かない部分があったため、issue等を確認しつつ動かします

huggingface.co

準備

!pip install transformers
!pip install pillow
!pip install git+https://github.com/huggingface/transformers.git

上記で必要なライブラリをインストールします。
この時に !pip install git+https://github.com/huggingface/transformers.git を入れないと以下のエラーが出たため、HFのサンプルから追加で対応しています。(詳細は discussions

推論用の画像を環境に入れます。 今回はHFで用意されている以下の画像のサンプルを使用します。

推論

以下のコードで4bit量子化でロードをして、推論を行います

from transformers import FuyuProcessor, FuyuForCausalLM
from PIL import Image

# load model and processor
model_id = "adept/fuyu-8b"
processor = FuyuProcessor.from_pretrained(model_id)
model = FuyuForCausalLM.from_pretrained(model_id, device_map="cuda:0",low_cpu_mem_usage=True,load_in_4bit=True)

# prepare inputs for the model
text_prompt = "Generate a coco-style caption.\n"
image_path = "images/bus.png"  # https://huggingface.co/adept-hf-collab/fuyu-8b/blob/main/bus.png
image = Image.open(image_path)

inputs = processor(text=text_prompt, images=image, return_tensors="pt")
for k, v in inputs.items():
    inputs[k] = v.to("cuda:0")

# autoregressively generate text
generation_output = model.generate(**inputs, max_new_tokens=7)
generation_text = processor.batch_decode(generation_output[:, -7:], skip_special_tokens=True)
# assert generation_text == ['A bus parked on the side of a road.']
print(generation_text)

結果は以下のようになりました

['A blue bus parked on the side of a road.']

推論時間は22sです

推論時のGPU RAMは14.7GBです

エラーが出た時

Gitが入っていないと言われた場合

  ERROR: Error [Errno 2] No such file or directory: 'git' while executing command git version
ERROR: Cannot find command 'git' - do you have 'git' installed and in your PATH?

上記のようにgitが入っていないと言われ場合は、環境にgitを追加します。

  1. sudo apt-get update でパッケージを更新します。
  2. sudo apt-get install git -y で gitを追加します

GPU RAMが足りないと言われ場合

環境によっては、GPU RAMが足りずに以下のエラーが出ることがあります。

OutOfMemoryError: CUDA out of memory. Tried to allocate 4.00 GiB. 
GPU 0 has a total capacty of 21.96 GiB of which 3.27 GiB is free. 
Process 2448267 has 18.68 GiB memory in use. 
Of the allocated memory 18.50 GiB is allocated by PyTorch, and 40.00 KiB is reserved by PyTorch but unallocated. 
If reserved but unallocated memory is large try setting max_split_size_mb to avoid fragmentation.  See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

モデルをロードする際に、引数に以下を追加して量子化でロードするようにします

low_cpu_mem_usage=True,load_in_4bit=True