【LLM】llama2(ラマ2)/ファインチューニング LORA編
↓ 環境構築に関しては下記を参照。
llama-recipesのインストール
↓2023年12月時点のインストールコマンド
pip install --extra-index-url https://download.pytorch.org/whl/test/cu118 llama-recipes
HFモデルに変換
metaから取得したデータ(llama-2-7bの場合は下記の用にデータが入っている)をHugging face用に変換してあげる必要がある。
checklist.chk consolidated.00.pth params.json
(1) フォルダ名を7Bに変更しておく
cp -r llama-2-7b 7B
(2) transformersのgitをクローン
git clone https://github.com/huggingface/transformers.git
(3) convert_llama_weights_to_hf.py で変換処理を実施
⭐️手順2 1で作成した7Bがある同階層にllamaのtokenizer.modelを置いてあること
python src/transformers/models/llama/convert_llama_weights_to_hf.py \
--input_dir <7Bフォルダとトークナイザーがあるディレクトリ> --model_size 7B --output_dir <outputのディレクトリ>
⭐️chatの場合はpip install protobufが必要か
変換後のフォルダの中身は下記のようになっているはず。
generation_config.json pytorch_model-00002-of-00003.bin tokenizer.json
pytorch_model-00003-of-00003.bin tokenizer.model
pytorch_model.bin.index.json tokenizer_config.json
デフォルトのデータセット(samsumデータセットを用いて学習する)
カレントを
/mnt/pvc/llama/
HF用のモデルが下記のフォルダにあると仮定
/mnt/pvc/llama/output
出力先のフォルダ
output/peft
とする。
python -m llama_recipes.finetuning --use_peft --peft_method lora --quantization --model_name /mnt/pvc/llama/output --output_dir output/peft
デフォルトでは、自動的に「samsum」で学習が開始する。(1GPUだと結構かかる)
実施すると出力先フォルダに下記のデータが作成される。
README.md adapter_config.json adapter_model.bin
通常のllamaのモデルの読み込みの場合はLlamaForCausalLMで良いが
tokenizer = LlamaTokenizer.from_pretrained("output")
model = LlamaForCausalLM.from_pretrained("output")
model.to('cuda')
PEFT
peft_model_id = "output/peft" ## PEFT出力先フォルダのパス
model = LlamaForCausalLM.from_pretrained("output")
lora_model = PeftModel.from_pretrained(model,peft_model_id)
lora_model.to('cuda')
のようにモデルを読み込む必要がある。
PEFT前のモデルとPEFT後のモデルで結果を検証してみよう。
from transformers import LlamaForCausalLM, LlamaTokenizer
from peft import PeftConfig,PeftModel
from transformers.trainer_utils import get_last_checkpoint
import torch
peft_model_id = "output/peft" # contains adapter_config.json and the associated .bin files
tokenizer = LlamaTokenizer.from_pretrained("output")
model = LlamaForCausalLM.from_pretrained("output") #instance
model.to('cuda')
prompt="Summarize this dialog:\nAmanda: I baked cookies. Do you want some?\nJerry: Sure!\nAmanda: I'll bring you tomorrow :-)\n---"
print("prompt:" + prompt)
inputs = tokenizer(prompt, return_tensors="pt")
with torch.no_grad():
pre_generate_ids = model.generate(do_sample=True,temperature=0.6,top_p=0.9 ,input_ids=inputs["input_ids"].to("cuda"),max_length= 100,pad_token_id=tokenizer.eos_token_id)
pre_returned = tokenizer.batch_decode(pre_generate_ids, skip_special_tokens = True,clean_up_tokenization_spaces=False)[0]
print("-----")
print(pre_returned)
lora_model = PeftModel.from_pretrained(model,peft_model_id)
lora_model.to('cuda')
with torch.no_grad():
lora_model = PeftModel.from_pretrained(model,peft_model_id)
lora_model.to('cuda')
generate_ids = lora_model.generate(do_sample=True,temperature=0.6,top_p=0.9,input_ids=inputs["input_ids"].to("cuda"),max_length= 100,pad_token_id=tokenizer.eos_token_id)
returned = tokenizer.batch_decode(generate_ids, skip_special_tokens = True,clean_up_tokenization_spaces=False)[0]
print("-----")
print(returned)
カスタムデータを使用する場合
*公式のドキュメントを閲覧するのがおすすめだが、筆者は(ほぼ)力技で構築した。
/opt/miniconda/envs/llama/lib/python3.10/site-packages/llama_recipes/dataset
に'get_custom_dataset(dataset_config, tokenizer, split)' でデータセットを返す関数を作成。
def get_custom_dataset(dataset_config, tokenizer, split):
....
if __name__=="__main__":
tokenizer = LlamaTokenizer.from_pretrained("/mnt/pvc/llama/tokenizer.model")
tokenizer.add_special_tokens(
{
"pad_token": "<PAD>",
}
)
print(tokenizer.special_tokens_map)
print(get_custom_dataset({},tokenizer,"train"))
mainで実行して動作することを確認。
⭐️/opt/miniconda/envs/llama/lib/python3.10/site-packages/llama_recipes/configs/datasets.py
⭐️/opt/miniconda/envs/llama/lib/python3.10/site-packages/llama_recipes/utils/dataset_utils.py
🌟/opt/miniconda/envs/llama/lib/python3.10/site-packages/llama_recipes/datasets/init.py
を編集。
上記の設定を実施して、下記コマンドを実行。PEFTが行われる。
python -m llama_recipes.finetuning --dataset "custom_dataset" --use_peft --peft_method lora --quantization --model_name /mnt/pvc/llama/output --output_dir output/peft2
Discussion