LoginSignup
6
5

Windows10でのPEFTの実行方法 (bitsandbytes-windows-webui使用)

Posted at

概要

背景

  • Windows10で、Peftを使用したLoRAが実施したい
    • PEFTの実行にはbitsandbytesライブラリが必要
    • しかし、純正のbitsandbytesはwindows OSには対応していない
  • こちらの記事の方法をもとに設定すれば、bitsandbytes=0.37.0をwindowsで使用できる
  • bitsandbytes-windows-webuiを使用すれば、更に簡単にbitsandbytesを使用できる

このページでできること

  • windows OSでbitsandbytesを使用できる
  • windows OSでPEFTが実行できる

このページの対象者

  • venvを使用したpython仮想環境の構築方法がわかる(venv+pyenvはこちら参照)
  • CUDA Toolkitのインストール方法がわかる

関連記事

PEFTをWindowsから遊ぶメモ

著者使用環境

項目 内容 備考
OS Windows 10 WSL不使用
python ver.3.10.10 pyenv使用
python仮想環境 venv
実行環境 ローカル Google Colab不使用
GPU RTX4070(VRAM 12GB) PEFTでのLoRAに使用

前提条件

本記事の内容を実行するための前提条件は以下の通りです。

  1. pythonをインストール済み
  2. pyenvをインストール済み
  3. CUDA Toolkitをインストール済み

python仮想環境構築&起動

以下のコマンドで、仮想環境を構築し、起動します。

cd <任意の場所>
mkdir tutorial # 本記事実施用のフォルダを作成
cd tutorial
mkdir .env # 仮想環境用のフォルダを作成
cd .env
pyenv install 3.10.10 # 3.10.10のpythonをインストール
pyenv local 3.10.10 # 3.10.10のpythonを使用
python --version # 3.10.10が表示されることを確認
python -m venv ./   # 仮想環境構築
cd Scripts
./activate # python仮想環境起動
pip list
<pip listで表示された"~\tutorial\.env\scripts\python.exe -m pip install --upgrade pip"の警告を実行し、pipのバージョン更新>
cd ../../

pip install

windows用bitsandbytesは、以下のコマンドでインストールできます。
bitsandbytesのインストール方法は以上です。動作確認したい場合は、以降も続けてお読みください。

pip install https://github.com/jllllll/bitsandbytes-windows-webui/raw/main/bitsandbytes-0.39.0-py3-none-any.whl

その他のライブラリも、以下のようにpip installします。

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
pip install datasets accelerate loralib transformers
pip install git+https://github.com/huggingface/peft.git

bitsandbytesの動作確認

先ほどの仮想環境上で以下のコマンドを打ち込んで、エラーが出ないことを確認します。

python
>>>import bitsandbytes

出力が以下のような内容で、特にエラーが表示されなければOK。
(下記内容の「<mask>」の部分は、環境ごとに異なります)

===================================BUG REPORT===================================
Welcome to bitsandbytes. For bug reports, please run
python -m bitsandbytes

 and submit this information together with your error trace to: https://github.com/TimDettmers/bitsandbytes/issues
================================================================================
bin <mask>\tutorial\.env\lib\site-packages\bitsandbytes\libbitsandbytes_cuda117.dll
CUDA SETUP: CUDA runtime path found: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\bin\cudart64_110.dll
CUDA SETUP: Highest compute capability among GPUs detected: 7.5
CUDA SETUP: Detected CUDA version 117
CUDA SETUP: Loading binary <mask>\tutorial\.env\lib\site-packages\bitsandbytes\libbitsandbytes_cuda117.dll...

caution
BUG REPORTの枠内に、以下のコマンドを実行するようにとの記載があります。

python -m bitsandbytes

このコマンドを実行した際、エラーが出る場合があります。
著者環境でもBUG REPORT INFOMATIONが表示されましたが、peftは実行できています(エラー原因は調査中)。

peft実行

tutorialフォルダ内に、以下のmain.pyを作成します。
なお、このmain.pyは、npaka様の「Google Colab で PEFT による大規模言語モデルのファインチューニングを試す」とほぼ同一のものです。

main.py
# モデルの読み込み
import os
os.environ["CUDA_VISIBLE_DEVICES"]="0"
import torch
import torch.nn as nn
import bitsandbytes as bnb
from transformers import AutoTokenizer, AutoConfig, AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained(
    "facebook/opt-6.7b", 
    load_in_8bit=True, 
    device_map='auto',
)

tokenizer = AutoTokenizer.from_pretrained("facebook/opt-6.7b")

for param in model.parameters():
  param.requires_grad = False  # モデルをフリーズ
  if param.ndim == 1:
    # 安定のためにレイヤーノルムをfp32にキャスト
    param.data = param.data.to(torch.float32)

model.gradient_checkpointing_enable()
model.enable_input_require_grads()

class CastOutputToFloat(nn.Sequential):
  def forward(self, x): return super().forward(x).to(torch.float32)
model.lm_head = CastOutputToFloat(model.lm_head)

def print_trainable_parameters(model):
    """
    モデル内の学習可能なパラメータ数を出力
    """
    trainable_params = 0
    all_param = 0
    for _, param in model.named_parameters():
        all_param += param.numel()
        if param.requires_grad:
            trainable_params += param.numel()
    print(
        f"trainable params: {trainable_params} || all params: {all_param} || trainable%: {100 * trainable_params / all_param}"
    )


from peft import LoraConfig, get_peft_model 

config = LoraConfig(
    r=16,
    lora_alpha=32,
    target_modules=["q_proj", "v_proj"],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM"
)

model = get_peft_model(model, config)
print_trainable_parameters(model)

import transformers
from datasets import load_dataset
data = load_dataset("Abirate/english_quotes")
data = data.map(lambda samples: tokenizer(samples['quote']), batched=True)

trainer = transformers.Trainer(
    model=model, 
    train_dataset=data['train'],
    args=transformers.TrainingArguments(
        per_device_train_batch_size=2, 
        gradient_accumulation_steps=4,
        warmup_steps=100, 
        max_steps=200, 
        learning_rate=2e-4, 
        fp16=True,
        logging_steps=1, 
        output_dir='outputs'
    ),
    data_collator=transformers.DataCollatorForLanguageModeling(tokenizer, mlm=False)
)
model.config.use_cache = False  # 警告を黙らせます。 推論のために再度有効にしてください。
trainer.train()

batch = tokenizer("Two things are infinite: ", return_tensors='pt')

with torch.cuda.amp.autocast():
  output_tokens = model.generate(**batch, max_new_tokens=50)

print('\n\n', tokenizer.decode(output_tokens[0], skip_special_tokens=True))

以下のコマンドで、pythonプログラムを実行します。

# 仮想環境をactivateしておくこと
python main.py

以下のような推論結果が得られれば成功です。

 Two things are infinite:  the universe, and human stupidity; and I'm not sure about the universe.  -Albert Einstein
I'm not sure about the universe either.
6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5