環境
- L4 GPU
- ubuntu22.04
- 学習データ bbz662bbz/databricks-dolly-15k-ja-gozarinnemon
参考サイト
準備
ライブラリのインストール
QLoRAをcloneをして、ライブラリをインストールします
# パッケージのインストール
!git clone https://github.com/artidoro/qlora
%cd qlora
!pip install -U -r requirements.txt
qlora.pyの変更
学習をするために、qlora.py
を変更します
573行目あたりの以下で、使用するデータセット名に書き換えます
def load_data(dataset_name): if dataset_name == 'alpaca': - return load_dataset("tatsu-lab/alpaca") + return load_dataset("bbz662bbz/databricks-dolly-15k-ja-gozarinnemon") elif dataset_name == 'alpaca-clean': return load_dataset("yahma/alpaca-cleaned") elif dataset_name == 'chip2':
次に704行目あたりの以下で、パラメータを追加します
model, tokenizer = get_accelerate_model(args, checkpoint_dir) model.config.use_cache = False + model.config.pretraining_tp = 1 print('loaded model') set_seed(args.seed)
学習
以下のようなスクリプト作成して、CALM2を使って学習をします
# 学習の実行 !python qlora.py \ --model_name cyberagent/calm2-7b \ --output_dir "./output/calm_peft" \ --dataset "alpaca" \ --max_steps 1000 \ --use_auth \ --logging_steps 10 \ --save_strategy steps \ --data_seed 42 \ --save_steps 50 \ --save_total_limit 40 \ --max_new_tokens 32 \ --dataloader_num_workers 1 \ --group_by_length \ --logging_strategy steps \ --remove_unused_columns False \ --do_train \ --lora_r 64 \ --lora_alpha 16 \ --lora_modules all \ --double_quant \ --quant_type nf4 \ --bf16 \ --bits 4 \ --warmup_ratio 0.03 \ --lr_scheduler_type constant \ --gradient_checkpointing \ --source_max_len 16 \ --target_max_len 512 \ --per_device_train_batch_size 1 \ --gradient_accumulation_steps 16 \ --eval_steps 187 \ --learning_rate 0.0002 \ --adam_beta2 0.999 \ --max_grad_norm 0.3 \ --lora_dropout 0.1 \ --weight_decay 0.0 \ --seed 0 \ --load_in_4bit \ --use_peft \ --batch_size 4 \ --gradient_accumulation_steps 2
学習したモデルで推論
以下でモデルをロードして、実際に推論してみます
import torch from peft import PeftModel from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig # トークナイザーとモデルの読み込み tokenizer = AutoTokenizer.from_pretrained( "cyberagent/calm2-7b-chat" ) model = AutoModelForCausalLM.from_pretrained( "cyberagent/calm2-7b-chat", quantization_config=BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_use_double_quant=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.bfloat16 ), device_map={"":0} ) # LoRAの読み込み model = PeftModel.from_pretrained( model, "./output/calm_peft/checkpoint-1000/adapter_model/", device_map={"":0} ) model.eval() # プロンプトの準備 prompt = "### Instruction: 富士山とは?\n\n### Response: " # 推論の実行 inputs = tokenizer(prompt, return_tensors="pt").to("cuda:0") with torch.no_grad(): outputs = model.generate(**inputs, max_new_tokens=100) print(tokenizer.decode(outputs[0], skip_special_tokens=True))
結果は以下のようになりました!無事に語尾が変わっていますね
### Instruction: 富士山とは? ### Response: 富士山は、日本の山の一つでござる。知らんけど。
備考
ValueError: Tokenizer class GPTNeoXTokenizer does not exist or is not currently imported.のエラー対応
以下のissueの対応を行う
346行目あたりの以下の部分を use_fast=True
にする
# Tokenizer tokenizer = AutoTokenizer.from_pretrained( args.model_name_or_path, cache_dir=args.cache_dir, padding_side="right", use_fast=True, # Fast tokenizer giving issues. tokenizer_type='llama' if 'llama' in args.model_name_or_path else None, # Needed for HF name change trust_remote_code=args.trust_remote_code, use_auth_token=args.use_auth_token, )