概要
背景
- 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のインストール方法がわかる
関連記事
著者使用環境
項目 | 内容 | 備考 |
---|---|---|
OS | Windows 10 | WSL不使用 |
python | ver.3.10.10 | pyenv使用 |
python仮想環境 | venv | |
実行環境 | ローカル | Google Colab不使用 |
GPU | RTX4070(VRAM 12GB) | PEFTでのLoRAに使用 |
前提条件
本記事の内容を実行するための前提条件は以下の通りです。
- pythonをインストール済み
- pyenvをインストール済み
- 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.