Uploaded model
- Developed by: u9999Yoko
- License: CC BY-NC-SA
- Finetuned from model : llm-jp/llm-jp-3-13b
Abstract
「llm-jp/llm-jp-3-13bモデルにichikara-instructionデータを用いてファインチューニングを行ったモデルです。 松尾研究室の講義のコンペ用としてモデルを作成しました。 https://weblab.t.u-tokyo.ac.jp/lecture/course-list/large-language-model/ https://llm-jp.nii.ac.jp/blog/2024/04/30/v2.0-release.html
Dataset
データセットは以下を使用しました。
- ichikara-instruction-003-001-1.json
Attention
ichikara-instructionデータは、CC BY-NC-SAライセンス(表示-非営利-継承)で公開されています。 このライセンスの下では、非営利目的での利用が許可されていますが、商用利用は認められていません。 詳しくは次のホームページをご覧ください。 https://llm-jp.nii.ac.jp/blog/2024/04/30/v2.0-release.html
Usage
Execute following code in Notebook
# 必要なライブラリをインストール
conda install --yes --file requirements.txt
from requests.exceptions import HTTPError
from transformers import (
AutoModelForCausalLM,
AutoTokenizer,
TrainingArguments,
)
from peft import (
LoraConfig,
get_peft_model,
)
import torch
from datasets import load_dataset
from trl import SFTTrainer
from tqdm import tqdm
# HuggingFaceにログイン
from huggingface_hub import notebook_login
# 取得したTokenを入力
notebook_login()
# base model id
base_model_id = "llm-jp/llm-jp-3-13b"
new_model_id = "u9999Yoko//llm-jp-3-13b-finetune"
model = AutoModelForCausalLM.from_pretrained(
base_model_id,
device_map="auto",
torch_dtype=torch.bfloat16, # 半精度計算で効率化
)
tokenizer = AutoTokenizer.from_pretrained(base_model_id, trust_remote_code=True)
"""
peft_config: PEFTの構成設定
- r
- LoRA のランク (4, 8, 16 ,32...)
- 増やすほど学習が捗るが, 過学習のリスクも高まるので注意
- lora_alpha
- LoRAのスケーリング係数
- lora_dropout
- ドロップアウト率(過学習を防ぐための割合)
- bias
- バイアス項の扱い ("none"の場合、LoRAはバイアスを学習しない)
- task_type
- タスクタイプ
- target_modules
- LoRAを適用するターゲットモジュール (前のコードで特定した層)
"""
# LoRA設定
lora_config = LoraConfig(
r=8,
lora_alpha=16,
target_modules=["q_proj", "v_proj"], # トレーニング対象の層
lora_dropout=0.1,
task_type="CAUSAL_LM",
)
model = get_peft_model(model, lora_config)
dataset = load_dataset("json", data_files="./ichikara-instruction-003-001-1.json")
# 学習時のプロンプトフォーマットの定義
prompt = """### 指示
{}
### 回答
{}"""
"""
formatting_prompts_func: 各データをプロンプトに合わせた形式に合わせる
"""
EOS_TOKEN = tokenizer.eos_token # トークナイザーのEOSトークン(文末トークン)
def formatting_prompts_func(examples):
input = examples["text"] # 入力データ
output = examples["output"] # 出力データ
text = prompt.format(input, output) + EOS_TOKEN # プロンプトの作成
return { "formatted_text" : text, } # 新しいフィールド "formatted_text" を返す
pass
# # 各データにフォーマットを適用
dataset = dataset.map(
formatting_prompts_func,
num_proc= 4, # 並列処理数を指定
)
# データを確認
print(dataset["train"]["formatted_text"][3])
# データをtrainデータとtestデータに分割 (test_sizeの比率に)
dataset = dataset["train"].train_test_split(test_size=0.1)
print(dataset)
"""
training_arguments: 学習の設定
output_dir:トレーニング後のモデルを保存するディレクトリ
per_device_train_batch_size: デバイスごとのトレーニングバッチサイズ
per_device__batch_size:デバイスごとの評価バッチサイズ
gradient_accumulation_steps:勾配を更新する前にステップを積み重ねる回数
optim: オプティマイザの設定
num_train_epochs:エポック数
eval_strategy:評価の戦略 ("no"/"steps"/"epoch")
eval_steps: eval_strategyが"steps"のとき、評価を行うstep間隔
logging_strategy: ログ記録の戦略
logging_steps: ログを出力するステップ間隔
warmup_steps: 学習率のウォームアップステップ数
save_steps: モデルを保存するステップ間隔
save_total_limit: 保存しておくcheckpointの数
max_steps:トレーニングの最大ステップ数
learning_rate: 学習率
fp16:16bit浮動小数点の使用設定(第8回演習を参考にすると良いです)
bf16:BFloat16の使用設定
group_by_length:入力シーケンスの長さによりバッチをグループ化 (トレーニングの効率化)
report_to:ログの送信先 ("wandb"/"tensorboard"など)
"""
training_arguments = TrainingArguments(
output_dir=new_model_id,
per_device_train_batch_size=1,
gradient_accumulation_steps=8,
# optim="paged_adamw_32bit",
num_train_epochs=3,
logging_strategy="steps",
logging_steps=10,
warmup_steps=10,
save_steps=1000,
save_total_limit = 2,
max_steps = -1,
learning_rate=5e-5,
fp16=False,
bf16=True,
seed = 3407,
group_by_length=True,
report_to="none"
)
"""
SFTTrainer: Supervised Fine-Tuningに関する設定
model:読み込んだベースのモデル
train_dataset:トレーニングに使用するデータセット
eval_dataset:評価に使用するデータセット
peft_config: PEFT(Parameter-Efficient Fine-Tuning)の設定(LoRAを利用する場合に指定)
max_seq_length:モデルに入力されるシーケンスの最大トークン長
dataset_text_field:データセット内の学習に使うテキストを含むフィールド名
tokenizer:モデルに対応するトークナイザー
args:トレーニングに使用するハイパーパラメータ(TrainingArgumentsの設定を指定)
packing:入力シーケンスのパッキングを行うかどうかの設定 (False に設定することで、各入力を独立して扱う)
"""
trainer = SFTTrainer(
model=model,
train_dataset=dataset["train"],
peft_config=lora_config,
max_seq_length= 512,
dataset_text_field="formatted_text",
tokenizer=tokenizer,
args=training_arguments,
packing= False,
)
model.config.use_cache = False # キャッシュ機能を無効化
trainer.train() # トレーニングを実行
# タスクとなるデータの読み込み。
import json
datasets = []
with open("./elyza-tasks-100-TV_0.jsonl", "r") as f:
item = ""
for line in f:
line = line.strip()
item += line
if item.endswith("}"):
datasets.append(json.loads(item))
item = ""
print(datasets)
# モデルによるタスクの推論。
results = []
for data in tqdm(datasets):
input = data["input"]
prompt = f"""### 指示
{input}
### 回答
"""
tokenized_input = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt").to(model.device)
attention_mask = torch.ones_like(tokenized_input)
with torch.no_grad():
outputs = model.generate(
tokenized_input,
attention_mask=attention_mask,
max_new_tokens=400,
do_sample=False,
repetition_penalty=1.2,
pad_token_id=tokenizer.eos_token_id
)[0]
output = tokenizer.decode(outputs[tokenized_input.size(1):], skip_special_tokens=True)
results.append({"task_id": data["task_id"], "input": input, "output": output})
# 結果をjsonlで保存。
import re
jsonl_id = re.sub(".*/", "", new_model_id)
with open(f"./{jsonl_id}-outputs.jsonl", 'w', encoding='utf-8') as f:
for result in results:
json.dump(result, f, ensure_ascii=False) # ensure_ascii=False for handling non-ASCII characters
f.write('\n')
- Downloads last month
- 3
Inference Providers
NEW
This model is not currently available via any of the supported third-party Inference Providers, and
the model is not deployed on the HF Inference API.
Model tree for u9999Yoko/llm-jp-3-13b-finetune
Base model
llm-jp/llm-jp-3-13b