huggingface/trl SFTTrainer
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
「[[.NET 開発基盤部会 Wiki>http://dotnetdevelopmentinfras...
-[[戻る>テキスト生成系(Transformer系)#j2f01d54]] > [[チ...
--[[LLMのPE]]
--[[LLMのRAG]]
--[[LLMのFT]]
---[[huggingface/transformers Trainer]]
---huggingface/trl SFTTrainer
--[[LLMエージェント]]
*目次 [#ndebe625]
#contents
*概要 [#tfd2a307]
huggingface/trl SFTTrainer
**huggingface/trl [#f564f186]
-Hugging Faceが提供するtransformersの拡張
-Transformer Reinforcement Learningの略で[[指示・強化学習...
**SFTTrainer [#a5f88e61]
***trlに含まれるトレーナー・クラス [#vf315bc4]
-教師ありファインチューニング(SFT)に特化したトレーナー。
-Trainerクラスを継承していて、SFT向けの機能を追加している。
***SFTTrainerでできること [#h31da3eb]
-CLM(Causal Language Modeling)による学習(次単語を予測...
collator = DataCollatorForLanguageModeling(tokenizer=tok...
-MLM(Masked Language Modeling)による学習(マスクを予測...
collator = DataCollatorForLanguageModeling(tokenizer=tok...
-Instruction Tuning:formatting_func、data_collatorをInst...
collator = DataCollatorForCompletionOnlyLM(response_temp...
-LoRAによるチューニング
-packingによる学習
-NEFTuneによる学習
*詳細 [#ud2fe008]
**実装準備 [#cd8f6842]
***インストール [#ddf11f78]
-領域が足りないことがあるので注意
--「pip cache purge」&「TMPDIR=/mnt/tmp pip install」を...
--必要に応じて[[ディスク追加>OSSのLLM#u0d612e8]]を行う。
-ModuleNotFoundError: No module named '_lzma'
***[[プロキシ環境>Python#y9ac7218]] [#w16e12cf]
***データセット [#vb74629b]
-kunishou/databricks-dolly-15k-ja
from datasets import load_dataset
dolly_dataset = load_dataset("kunishou/databricks-dolly-...
# 簡易化のためinputの値が空のデータに絞る
# npakaさんの記事(https://note.com/npaka/n/nc7a4c20f98f...
dolly_train_dataset = dolly_dataset['train'].filter(lamb...
print(dolly_train_dataset)
# データ件数は全部で10,417件
#Dataset({
# features: ['output', 'index', 'category', 'instruct...
# num_rows: 10417
#})
print(dolly_train_dataset[0])
#{'output': 'イコクエイラクブカ',
# 'index': '1',
# 'category': 'classification',
# 'instruction': '魚の種類はどっち?イコクエイラクブカと...
# 'input': ''}
-自作JSON(jsonl)
--ロード
train_file = "data/train.jsonl"
dataset = datasets.load_dataset("json", data_files=train...
dataset = datasets.DatasetDict({'train': dataset})
--JSONL~
各行が個別の JSON オブジェクトとして扱われるファイル形式
{"answer":"XXX","question":"YYY","context":"ZZZ"}
{"answer":"XXX","question":"YYY","context":"ZZZ"}
{"answer":"XXX","question":"YYY","context":"ZZZ"}
...
--split="train"を書いた場合と書かない場合の話~
多くのHugging FaceのAPIやTrainerなどは Dataset オブジェク...
---書いた場合~
split="train" を指定することで、datasets.load_dataset() ...
DatasetDict({
'train': Dataset(...)
})
---書かない場合~
split を指定しない場合、戻り値は DatasetDict 型になり、こ...
その後、再度 DatasetDict にtrainと言うキー名でラップして...
DatasetDict({
'train': DatasetDict({
'train': Dataset(...)
})
})
※ kunishou/databricks-dolly-15k-jaを使う例ではcontextを使...
***モデル [#b6baa2c4]
-モデルとトークナイザ(文字列と数値IDを相互変換する道具)
-2つの例を見ると、オプションに違いがあるが、コレは?
|オプション|説明|h
|device_map="auto"|GPUやCPUへ自動で重みを割り当て|
|torch_dtype=torch.bfloat16|省メモリ・高速化のためのデー...
|trust_remote_code=True|モデル定義にカスタムコードが含ま...
|force_download=True|キャッシュ無視して強制的に再取得|
-cyberagent/open-calm-large
--ダウンロード
from transformers import AutoModelForCausalLM, AutoToken...
# open-calm-largeは約7億パラメータの小さめのLLMです。
# とはいえ、本記事で紹介するコードをそのまま使うとcolab ...
# お手元のGPUのリソースが限られている場合、動作確認が目...
model_name = "cyberagent/open-calm-large"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
device_map="auto",
# torch_dtype=torch.float16,
# torch.float16を指定すると、train時のlossが0.0にな...
# TrainerArgumentsを修正(bf16 = True)したところ正...
)
--ロード
save_pretrainedしていれば、model = AutoModelForCausalLM....
--print(model)の出力
GPTNeoXForCausalLM(
(gpt_neox): GPTNeoXModel(
(embed_in): Embedding(52096, 1536)
(emb_dropout): Dropout(p=0.0, inplace=False)
(layers): ModuleList(
(0-23): 24 x GPTNeoXLayer(
(input_layernorm): LayerNorm((1536,), eps=1e-05,...
(post_attention_layernorm): LayerNorm((1536,), e...
(post_attention_dropout): Dropout(p=0.0, inplace...
(post_mlp_dropout): Dropout(p=0.0, inplace=False)
(attention): GPTNeoXAttention(
(rotary_emb): GPTNeoXRotaryEmbedding()
(query_key_value): Linear(in_features=1536, ou...
(dense): Linear(in_features=1536, out_features...
(attention_dropout): Dropout(p=0.0, inplace=Fa...
)
(mlp): GPTNeoXMLP(
(dense_h_to_4h): Linear(in_features=1536, out_...
(dense_4h_to_h): Linear(in_features=6144, out_...
(act): GELUActivation()
)
)
)
(final_layer_norm): LayerNorm((1536,), eps=1e-05, el...
)
(embed_out): Linear(in_features=1536, out_features=520...
)
-Llama-3.2-1B-Instruct
--ダウンロード
import transformers
from transformers import (
AutoTokenizer
)
import torch
MODEL_URI = "meta-llama/Llama-3.2-1B-Instruct"
MODEL_PATH = 'models/Llama-3.2-1B-Instruct'
TOKENIZER_PATH = 'models/Llama-3.2-1B-Instruct'
# model
model = transformers.AutoModelForCausalLM.from_pretrained(
MODEL_URI,
torch_dtype=torch.bfloat16,
trust_remote_code=True,
force_download=True
)
model.save_pretrained(MODEL_PATH)
# tokenizer
tokenizer = AutoTokenizer.from_pretrained(MODEL_URI)
tokenizer.save_pretrained(TOKENIZER_PATH)
--ロード
# model
model = AutoModelForCausalLM.from_pretrained(MODEL_PATH)
# tokenizer
tokenizer = AutoTokenizer.from_pretrained(TOKENIZER_PATH)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token # コレは要...
--print(model)の出力
...
**Instruction Tuning [#u28e7e53]
Instruction Tuningは、言語モデルに 命令(Instruction)と...
***変換関数 [#l190987d]
-Instruction Tuningのプロンプト・フォーマット / テンプレ...
--日本語、指示、応答
text = f"以下は、タスクを説明する指示です。要求を適切に...
--英語、question, context, answer~
ちなみに、コンテキストには、RAGのチャンクの様な参考情報が...
text = f"Please answer the question based on the given c...
-SFTTrainerのformatting_func引数に渡すプロンプトフォーマ...
--kunishou/databricks-dolly-15k-ja
print(tokenizer.eos_token)
#'<|endoftext|>'
def formatting_prompts_func(example):
output_texts = []
for i in range(len(example['instruction'])):
text = f"以下は、タスクを説明する指示です。要求...
output_texts.append(text)
return output_texts
--自作JSON(jsonl)
def formatting_prompts_func(example):
output_texts = []
for i in range(len(example['question'])):
text = f"Please answer the question based on the...
output_texts.append(text)
return output_texts
***損失計算 [#tfe911c1]
-Instruction + Responseの両方を含むプロンプトを使って学習...
--「すべてのトークンを損失計算対象にする(全体を正解とし...
--後者の方が「モデルが指示を理解し、応答を生成する能力」...
-SFTTrainerのdata_collator引数に渡すDataCollatorForComple...
使用するにはpacking=Falseが必要で、この場合、dataset_text...
--template
---response_templateは必須指定
response_template = "### 応答:\n" # "### answer\n"
---instruction_templateは複数回の対話形式の場合に必要(1...
instruction_template = "### 指示:\n" # "### question\n"
--response_template以降のトークンだけを labels に設定~
(他は、PyTorch の CrossEntropyLoss で無視されるラベル = ...
from trl import DataCollatorForCompletionOnlyLM
# response_templateは必須指定
response_template = "### 応答:\n"
collator = DataCollatorForCompletionOnlyLM(response_temp...
***SFTTrainerの構成 [#t3a58389]
-ポイント
--formatting_funcで1問1答形式の文字列を作る。
--data_collatorで応答部分だけを損失対象にする。
--packing=Falseにより、packingせずに処理する。
from transformers import TrainingArguments
from trl import SFTTrainer
# SFTTrainerはTrainingArgumentsを使用することができる。
# 指定しない場合、TrainingArgumentsのデフォルトが指定さ...
args = TrainingArguments(
output_dir='./output',
num_train_epochs=2,
gradient_accumulation_steps=8,
per_device_train_batch_size=8,
save_strategy="no",
logging_steps=20,
lr_scheduler_type="constant",
save_total_limit=1,
fp16=True,
)
trainer = SFTTrainer(
model,
args=args,
train_dataset=dolly_train_dataset,
formatting_func=formatting_prompts_func,
max_seq_length=1024,
data_collator=collator,
)
-指定したデータセットがプロンプトフォーマットに変換されて...
print(trainer.train_dataset)
# Dataset({
# features: ['input_ids', 'attention_mask'],
# num_rows: 10417
# })
print(tokenizer.decode(trainer.train_dataset[0]['input_i...
# 以下は、タスクを説明する指示です。要求を適切に満たす応...
#
# ### 指示:
# XXXXXXXXXX
#
# ### 応答:
# YYYYYYYYYY<|endoftext|>
-損失対象の確認(Instruction部分やpaddingには -100、応答...
from torch.utils.data import DataLoader
loader = DataLoader(trainer.train_dataset, collate_fn=co...
batch = next(iter(loader))
print(batch['labels'][0])
#tensor([ -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, 275, 19052, 4044...
# 0, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100])
***学習・保存 [#s8e8326a]
-学習・保存
trainer.train()
trainer.save_model()
-学習済みモデルのロード
--cyberagent/open-calm-large
lora_model = AutoModelForCausalLM.from_pretrained('./out...
***推論の実行 [#k0be0ea6]
-ロード
--cyberagent/open-calm-large~
model = AutoModelForCausalLM.from_pretrained(MODEL_PATH,...
tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH)
-プロンプトのトークン化(pt = torch.Tensor)
inputs = tokenizer('...プロンプト...', return_tensors="p...
print(inputs) # テンソルのディクショナリになっている。
-推論時、勾配計算しないブロックに格納、~
また、**inputsで「ディクショナリのキー・値」が「キーワー...
with torch.no_grad():
tokens = model.generate(
**inputs,
max_new_tokens=64,
do_sample=True,
temperature=0.7,
top_p=0.9,
repetition_penalty=1.05,
pad_token_id=tokenizer.pad_token_id,
)
-デトークン化した推論結果の表示
output = tokenizer.decode(tokens[0], skip_special_tokens...
print(output)
**LoRAによるチューニング [#zb2bd049]
***コードの差異 [#k62a4fb0]
-peftでLoraConfigを定義して、SFTTrainerのpeft_config引数...
(data_collator引数やformatting_func引数などは前述と同様...
from peft import LoraConfig
peft_config = LoraConfig(
r=8,
lora_alpha=16,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
args = TrainingArguments(
output_dir='./output_lora',
...同上...,
)
trainer = SFTTrainer(
...同上...,
peft_config=peft_config,
)
trainer.train()
trainer.save_model()
-モデルのロード
--cyberagent/open-calm-large~
Adapter + ベース・パラメタ = adapter_config.json の base_...
lora_model = AutoModelForCausalLM.from_pretrained('./out...
***確認事項 [#k7d159ce]
-LoRA Adapterが挿入されない層のパラメタ~
SFTTrainerにmodelを渡す前、渡した前、学習後で変化なしのハ...
--cyberagent/open-calm-large
# 最初の層のFFNの一部を確認する
# この時点ではrequires_grad=Trueになっている
first_ffn_param = model.gpt_neox.layers[0].mlp.dense_h_t...
print(first_ffn_param)
#Parameter containing:
#tensor([[-0.1072, 0.0417, -0.0432, ..., -0.0873, -0.1...
# [-0.0934, 0.0773, 0.0074, ..., -0.2107, 0.0...
# [-0.0506, -0.1282, -0.1511, ..., 0.1120, -0.0...
# ...,
# [ 0.1274, -0.0688, 0.1787, ..., 0.1432, 0.0...
# [-0.1108, -0.0758, 0.0035, ..., -0.0404, -0.1...
# [ 0.0669, 0.0399, -0.0443, ..., -0.2275, -0.1...
# device='cuda:0', requires_grad=True)
--Llama-3.2-1B-Instruct
-SFTTrainerにmodelを渡した後でSFTTrainerからmodelにアクセ...
LoraConfigのtarget_modulesに指定しなくても、いい感じにAda...
--cyberagent/open-calm-large~
「(attention): GPTNeoXAttention」の「(query_key_value): L...
PeftModelForCausalLM(
(base_model): LoraModel(
(model): GPTNeoXForCausalLM(
(gpt_neox): GPTNeoXModel(
(embed_in): Embedding(52096, 1536)
(emb_dropout): Dropout(p=0.0, inplace=False)
(layers): ModuleList(
(0-23): 24 x GPTNeoXLayer(
(input_layernorm): LayerNorm((1536,), eps=1e...
(post_attention_layernorm): LayerNorm((1536,...
(post_attention_dropout): Dropout(p=0.0, inp...
(post_mlp_dropout): Dropout(p=0.0, inplace=F...
(attention): GPTNeoXAttention(
(rotary_emb): GPTNeoXRotaryEmbedding()
(query_key_value): Linear(
in_features=1536, out_features=4608, bia...
(lora_dropout): ModuleDict(
(default): Dropout(p=0.05, inplace=Fal...
)
(lora_A): ModuleDict(
(default): Linear(in_features=1536, ou...
)
(lora_B): ModuleDict(
(default): Linear(in_features=8, out_f...
)
(lora_embedding_A): ParameterDict()
(lora_embedding_B): ParameterDict()
)
(dense): Linear(in_features=1536, out_feat...
(attention_dropout): Dropout(p=0.0, inplac...
)
(mlp): GPTNeoXMLP(
(dense_h_to_4h): Linear(in_features=1536, ...
(dense_4h_to_h): Linear(in_features=6144, ...
(act): GELUActivation()
)
)
)
(final_layer_norm): LayerNorm((1536,), eps=1e-05...
)
(embed_out): Linear(in_features=1536, out_features...
)
)
)
--Llama-3.2-1B-Instruct
-学習されるパラメタ数を確認~
LoRAにより、trainableなパラメタは、かなり少なくなっている...
--cyberagent/open-calm-large
trainer.model.print_trainable_parameters()
#trainable params: 1,179,648 || all params: 841,178,112 ...
--Llama-3.2-1B-Instruct
-SFTTrainerで学習した後のLoRA Adapterが挿入されない層のパ...
--cyberagent/open-calm-large
# Adapterが挿入されていない層はパラメタはbaseモデルのと...
(lora_model.gpt_neox.layers[0].mlp.dense_h_to_4h.weight ...
#tensor(True, device='cuda:0') ## GPU上にあるテンソルの...
--Llama-3.2-1B-Instruct
**NEFTuneによる学習 [#m6d89a97]
**packingを用いた学習 [#c1f0b2f2]
**学習結果の比較 [#qe8b9bad]
*参考 [#w465ae3e]
https://github.com/OpenTouryoProject/DxCommon/blob/master...
**Qiita [#x7ffee2d]
-huggingface/TRLのSFTTrainerクラスを使えばLLMのInstructio...
https://qiita.com/m__k/items/23ced0db6846e97d41cd
-OpenCALM-7Bのコードリーディング(基本編)~
https://zenn.dev/hijikix/articles/549180d467df3c
**Hugging Face [#n4339d0b]
The AI community building the future.
-TRL - Transformer Reinforcement Learning~
https://huggingface.co/docs/trl/index
-Supervised Fine-tuning Trainer~
https://huggingface.co/docs/trl/sft_trainer
**github.com [#aee3b3d2]
https://github.com/huggingface/trl/blob/main/trl/
-https://github.com/huggingface/trl/blob/main/trl/scripts...
終了行:
「[[.NET 開発基盤部会 Wiki>http://dotnetdevelopmentinfras...
-[[戻る>テキスト生成系(Transformer系)#j2f01d54]] > [[チ...
--[[LLMのPE]]
--[[LLMのRAG]]
--[[LLMのFT]]
---[[huggingface/transformers Trainer]]
---huggingface/trl SFTTrainer
--[[LLMエージェント]]
*目次 [#ndebe625]
#contents
*概要 [#tfd2a307]
huggingface/trl SFTTrainer
**huggingface/trl [#f564f186]
-Hugging Faceが提供するtransformersの拡張
-Transformer Reinforcement Learningの略で[[指示・強化学習...
**SFTTrainer [#a5f88e61]
***trlに含まれるトレーナー・クラス [#vf315bc4]
-教師ありファインチューニング(SFT)に特化したトレーナー。
-Trainerクラスを継承していて、SFT向けの機能を追加している。
***SFTTrainerでできること [#h31da3eb]
-CLM(Causal Language Modeling)による学習(次単語を予測...
collator = DataCollatorForLanguageModeling(tokenizer=tok...
-MLM(Masked Language Modeling)による学習(マスクを予測...
collator = DataCollatorForLanguageModeling(tokenizer=tok...
-Instruction Tuning:formatting_func、data_collatorをInst...
collator = DataCollatorForCompletionOnlyLM(response_temp...
-LoRAによるチューニング
-packingによる学習
-NEFTuneによる学習
*詳細 [#ud2fe008]
**実装準備 [#cd8f6842]
***インストール [#ddf11f78]
-領域が足りないことがあるので注意
--「pip cache purge」&「TMPDIR=/mnt/tmp pip install」を...
--必要に応じて[[ディスク追加>OSSのLLM#u0d612e8]]を行う。
-ModuleNotFoundError: No module named '_lzma'
***[[プロキシ環境>Python#y9ac7218]] [#w16e12cf]
***データセット [#vb74629b]
-kunishou/databricks-dolly-15k-ja
from datasets import load_dataset
dolly_dataset = load_dataset("kunishou/databricks-dolly-...
# 簡易化のためinputの値が空のデータに絞る
# npakaさんの記事(https://note.com/npaka/n/nc7a4c20f98f...
dolly_train_dataset = dolly_dataset['train'].filter(lamb...
print(dolly_train_dataset)
# データ件数は全部で10,417件
#Dataset({
# features: ['output', 'index', 'category', 'instruct...
# num_rows: 10417
#})
print(dolly_train_dataset[0])
#{'output': 'イコクエイラクブカ',
# 'index': '1',
# 'category': 'classification',
# 'instruction': '魚の種類はどっち?イコクエイラクブカと...
# 'input': ''}
-自作JSON(jsonl)
--ロード
train_file = "data/train.jsonl"
dataset = datasets.load_dataset("json", data_files=train...
dataset = datasets.DatasetDict({'train': dataset})
--JSONL~
各行が個別の JSON オブジェクトとして扱われるファイル形式
{"answer":"XXX","question":"YYY","context":"ZZZ"}
{"answer":"XXX","question":"YYY","context":"ZZZ"}
{"answer":"XXX","question":"YYY","context":"ZZZ"}
...
--split="train"を書いた場合と書かない場合の話~
多くのHugging FaceのAPIやTrainerなどは Dataset オブジェク...
---書いた場合~
split="train" を指定することで、datasets.load_dataset() ...
DatasetDict({
'train': Dataset(...)
})
---書かない場合~
split を指定しない場合、戻り値は DatasetDict 型になり、こ...
その後、再度 DatasetDict にtrainと言うキー名でラップして...
DatasetDict({
'train': DatasetDict({
'train': Dataset(...)
})
})
※ kunishou/databricks-dolly-15k-jaを使う例ではcontextを使...
***モデル [#b6baa2c4]
-モデルとトークナイザ(文字列と数値IDを相互変換する道具)
-2つの例を見ると、オプションに違いがあるが、コレは?
|オプション|説明|h
|device_map="auto"|GPUやCPUへ自動で重みを割り当て|
|torch_dtype=torch.bfloat16|省メモリ・高速化のためのデー...
|trust_remote_code=True|モデル定義にカスタムコードが含ま...
|force_download=True|キャッシュ無視して強制的に再取得|
-cyberagent/open-calm-large
--ダウンロード
from transformers import AutoModelForCausalLM, AutoToken...
# open-calm-largeは約7億パラメータの小さめのLLMです。
# とはいえ、本記事で紹介するコードをそのまま使うとcolab ...
# お手元のGPUのリソースが限られている場合、動作確認が目...
model_name = "cyberagent/open-calm-large"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
device_map="auto",
# torch_dtype=torch.float16,
# torch.float16を指定すると、train時のlossが0.0にな...
# TrainerArgumentsを修正(bf16 = True)したところ正...
)
--ロード
save_pretrainedしていれば、model = AutoModelForCausalLM....
--print(model)の出力
GPTNeoXForCausalLM(
(gpt_neox): GPTNeoXModel(
(embed_in): Embedding(52096, 1536)
(emb_dropout): Dropout(p=0.0, inplace=False)
(layers): ModuleList(
(0-23): 24 x GPTNeoXLayer(
(input_layernorm): LayerNorm((1536,), eps=1e-05,...
(post_attention_layernorm): LayerNorm((1536,), e...
(post_attention_dropout): Dropout(p=0.0, inplace...
(post_mlp_dropout): Dropout(p=0.0, inplace=False)
(attention): GPTNeoXAttention(
(rotary_emb): GPTNeoXRotaryEmbedding()
(query_key_value): Linear(in_features=1536, ou...
(dense): Linear(in_features=1536, out_features...
(attention_dropout): Dropout(p=0.0, inplace=Fa...
)
(mlp): GPTNeoXMLP(
(dense_h_to_4h): Linear(in_features=1536, out_...
(dense_4h_to_h): Linear(in_features=6144, out_...
(act): GELUActivation()
)
)
)
(final_layer_norm): LayerNorm((1536,), eps=1e-05, el...
)
(embed_out): Linear(in_features=1536, out_features=520...
)
-Llama-3.2-1B-Instruct
--ダウンロード
import transformers
from transformers import (
AutoTokenizer
)
import torch
MODEL_URI = "meta-llama/Llama-3.2-1B-Instruct"
MODEL_PATH = 'models/Llama-3.2-1B-Instruct'
TOKENIZER_PATH = 'models/Llama-3.2-1B-Instruct'
# model
model = transformers.AutoModelForCausalLM.from_pretrained(
MODEL_URI,
torch_dtype=torch.bfloat16,
trust_remote_code=True,
force_download=True
)
model.save_pretrained(MODEL_PATH)
# tokenizer
tokenizer = AutoTokenizer.from_pretrained(MODEL_URI)
tokenizer.save_pretrained(TOKENIZER_PATH)
--ロード
# model
model = AutoModelForCausalLM.from_pretrained(MODEL_PATH)
# tokenizer
tokenizer = AutoTokenizer.from_pretrained(TOKENIZER_PATH)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token # コレは要...
--print(model)の出力
...
**Instruction Tuning [#u28e7e53]
Instruction Tuningは、言語モデルに 命令(Instruction)と...
***変換関数 [#l190987d]
-Instruction Tuningのプロンプト・フォーマット / テンプレ...
--日本語、指示、応答
text = f"以下は、タスクを説明する指示です。要求を適切に...
--英語、question, context, answer~
ちなみに、コンテキストには、RAGのチャンクの様な参考情報が...
text = f"Please answer the question based on the given c...
-SFTTrainerのformatting_func引数に渡すプロンプトフォーマ...
--kunishou/databricks-dolly-15k-ja
print(tokenizer.eos_token)
#'<|endoftext|>'
def formatting_prompts_func(example):
output_texts = []
for i in range(len(example['instruction'])):
text = f"以下は、タスクを説明する指示です。要求...
output_texts.append(text)
return output_texts
--自作JSON(jsonl)
def formatting_prompts_func(example):
output_texts = []
for i in range(len(example['question'])):
text = f"Please answer the question based on the...
output_texts.append(text)
return output_texts
***損失計算 [#tfe911c1]
-Instruction + Responseの両方を含むプロンプトを使って学習...
--「すべてのトークンを損失計算対象にする(全体を正解とし...
--後者の方が「モデルが指示を理解し、応答を生成する能力」...
-SFTTrainerのdata_collator引数に渡すDataCollatorForComple...
使用するにはpacking=Falseが必要で、この場合、dataset_text...
--template
---response_templateは必須指定
response_template = "### 応答:\n" # "### answer\n"
---instruction_templateは複数回の対話形式の場合に必要(1...
instruction_template = "### 指示:\n" # "### question\n"
--response_template以降のトークンだけを labels に設定~
(他は、PyTorch の CrossEntropyLoss で無視されるラベル = ...
from trl import DataCollatorForCompletionOnlyLM
# response_templateは必須指定
response_template = "### 応答:\n"
collator = DataCollatorForCompletionOnlyLM(response_temp...
***SFTTrainerの構成 [#t3a58389]
-ポイント
--formatting_funcで1問1答形式の文字列を作る。
--data_collatorで応答部分だけを損失対象にする。
--packing=Falseにより、packingせずに処理する。
from transformers import TrainingArguments
from trl import SFTTrainer
# SFTTrainerはTrainingArgumentsを使用することができる。
# 指定しない場合、TrainingArgumentsのデフォルトが指定さ...
args = TrainingArguments(
output_dir='./output',
num_train_epochs=2,
gradient_accumulation_steps=8,
per_device_train_batch_size=8,
save_strategy="no",
logging_steps=20,
lr_scheduler_type="constant",
save_total_limit=1,
fp16=True,
)
trainer = SFTTrainer(
model,
args=args,
train_dataset=dolly_train_dataset,
formatting_func=formatting_prompts_func,
max_seq_length=1024,
data_collator=collator,
)
-指定したデータセットがプロンプトフォーマットに変換されて...
print(trainer.train_dataset)
# Dataset({
# features: ['input_ids', 'attention_mask'],
# num_rows: 10417
# })
print(tokenizer.decode(trainer.train_dataset[0]['input_i...
# 以下は、タスクを説明する指示です。要求を適切に満たす応...
#
# ### 指示:
# XXXXXXXXXX
#
# ### 応答:
# YYYYYYYYYY<|endoftext|>
-損失対象の確認(Instruction部分やpaddingには -100、応答...
from torch.utils.data import DataLoader
loader = DataLoader(trainer.train_dataset, collate_fn=co...
batch = next(iter(loader))
print(batch['labels'][0])
#tensor([ -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, 275, 19052, 4044...
# 0, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100, -100, -100...
# -100, -100, -100, -100, -100])
***学習・保存 [#s8e8326a]
-学習・保存
trainer.train()
trainer.save_model()
-学習済みモデルのロード
--cyberagent/open-calm-large
lora_model = AutoModelForCausalLM.from_pretrained('./out...
***推論の実行 [#k0be0ea6]
-ロード
--cyberagent/open-calm-large~
model = AutoModelForCausalLM.from_pretrained(MODEL_PATH,...
tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH)
-プロンプトのトークン化(pt = torch.Tensor)
inputs = tokenizer('...プロンプト...', return_tensors="p...
print(inputs) # テンソルのディクショナリになっている。
-推論時、勾配計算しないブロックに格納、~
また、**inputsで「ディクショナリのキー・値」が「キーワー...
with torch.no_grad():
tokens = model.generate(
**inputs,
max_new_tokens=64,
do_sample=True,
temperature=0.7,
top_p=0.9,
repetition_penalty=1.05,
pad_token_id=tokenizer.pad_token_id,
)
-デトークン化した推論結果の表示
output = tokenizer.decode(tokens[0], skip_special_tokens...
print(output)
**LoRAによるチューニング [#zb2bd049]
***コードの差異 [#k62a4fb0]
-peftでLoraConfigを定義して、SFTTrainerのpeft_config引数...
(data_collator引数やformatting_func引数などは前述と同様...
from peft import LoraConfig
peft_config = LoraConfig(
r=8,
lora_alpha=16,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
args = TrainingArguments(
output_dir='./output_lora',
...同上...,
)
trainer = SFTTrainer(
...同上...,
peft_config=peft_config,
)
trainer.train()
trainer.save_model()
-モデルのロード
--cyberagent/open-calm-large~
Adapter + ベース・パラメタ = adapter_config.json の base_...
lora_model = AutoModelForCausalLM.from_pretrained('./out...
***確認事項 [#k7d159ce]
-LoRA Adapterが挿入されない層のパラメタ~
SFTTrainerにmodelを渡す前、渡した前、学習後で変化なしのハ...
--cyberagent/open-calm-large
# 最初の層のFFNの一部を確認する
# この時点ではrequires_grad=Trueになっている
first_ffn_param = model.gpt_neox.layers[0].mlp.dense_h_t...
print(first_ffn_param)
#Parameter containing:
#tensor([[-0.1072, 0.0417, -0.0432, ..., -0.0873, -0.1...
# [-0.0934, 0.0773, 0.0074, ..., -0.2107, 0.0...
# [-0.0506, -0.1282, -0.1511, ..., 0.1120, -0.0...
# ...,
# [ 0.1274, -0.0688, 0.1787, ..., 0.1432, 0.0...
# [-0.1108, -0.0758, 0.0035, ..., -0.0404, -0.1...
# [ 0.0669, 0.0399, -0.0443, ..., -0.2275, -0.1...
# device='cuda:0', requires_grad=True)
--Llama-3.2-1B-Instruct
-SFTTrainerにmodelを渡した後でSFTTrainerからmodelにアクセ...
LoraConfigのtarget_modulesに指定しなくても、いい感じにAda...
--cyberagent/open-calm-large~
「(attention): GPTNeoXAttention」の「(query_key_value): L...
PeftModelForCausalLM(
(base_model): LoraModel(
(model): GPTNeoXForCausalLM(
(gpt_neox): GPTNeoXModel(
(embed_in): Embedding(52096, 1536)
(emb_dropout): Dropout(p=0.0, inplace=False)
(layers): ModuleList(
(0-23): 24 x GPTNeoXLayer(
(input_layernorm): LayerNorm((1536,), eps=1e...
(post_attention_layernorm): LayerNorm((1536,...
(post_attention_dropout): Dropout(p=0.0, inp...
(post_mlp_dropout): Dropout(p=0.0, inplace=F...
(attention): GPTNeoXAttention(
(rotary_emb): GPTNeoXRotaryEmbedding()
(query_key_value): Linear(
in_features=1536, out_features=4608, bia...
(lora_dropout): ModuleDict(
(default): Dropout(p=0.05, inplace=Fal...
)
(lora_A): ModuleDict(
(default): Linear(in_features=1536, ou...
)
(lora_B): ModuleDict(
(default): Linear(in_features=8, out_f...
)
(lora_embedding_A): ParameterDict()
(lora_embedding_B): ParameterDict()
)
(dense): Linear(in_features=1536, out_feat...
(attention_dropout): Dropout(p=0.0, inplac...
)
(mlp): GPTNeoXMLP(
(dense_h_to_4h): Linear(in_features=1536, ...
(dense_4h_to_h): Linear(in_features=6144, ...
(act): GELUActivation()
)
)
)
(final_layer_norm): LayerNorm((1536,), eps=1e-05...
)
(embed_out): Linear(in_features=1536, out_features...
)
)
)
--Llama-3.2-1B-Instruct
-学習されるパラメタ数を確認~
LoRAにより、trainableなパラメタは、かなり少なくなっている...
--cyberagent/open-calm-large
trainer.model.print_trainable_parameters()
#trainable params: 1,179,648 || all params: 841,178,112 ...
--Llama-3.2-1B-Instruct
-SFTTrainerで学習した後のLoRA Adapterが挿入されない層のパ...
--cyberagent/open-calm-large
# Adapterが挿入されていない層はパラメタはbaseモデルのと...
(lora_model.gpt_neox.layers[0].mlp.dense_h_to_4h.weight ...
#tensor(True, device='cuda:0') ## GPU上にあるテンソルの...
--Llama-3.2-1B-Instruct
**NEFTuneによる学習 [#m6d89a97]
**packingを用いた学習 [#c1f0b2f2]
**学習結果の比較 [#qe8b9bad]
*参考 [#w465ae3e]
https://github.com/OpenTouryoProject/DxCommon/blob/master...
**Qiita [#x7ffee2d]
-huggingface/TRLのSFTTrainerクラスを使えばLLMのInstructio...
https://qiita.com/m__k/items/23ced0db6846e97d41cd
-OpenCALM-7Bのコードリーディング(基本編)~
https://zenn.dev/hijikix/articles/549180d467df3c
**Hugging Face [#n4339d0b]
The AI community building the future.
-TRL - Transformer Reinforcement Learning~
https://huggingface.co/docs/trl/index
-Supervised Fine-tuning Trainer~
https://huggingface.co/docs/trl/sft_trainer
**github.com [#aee3b3d2]
https://github.com/huggingface/trl/blob/main/trl/
-https://github.com/huggingface/trl/blob/main/trl/scripts...
ページ名: