Uploaded model

  • Developed by: IWAIYuma
  • License: apache-2.0
  • Finetuned from model : llm-jp/llm-jp-3-13b

This llama model was trained 2x faster with Unsloth and Huggingface's TRL library.

サンプルコードで作成したモデルを強化学習する。

使用するデータセットは、『cyberagent/chatbot-arena-ja-calm2-7b-chat-experimental』のオープンソースを使用

https://huggingface.co/datasets/cyberagent/chatbot-arena-ja-calm2-7b-chat-experimental)

このソースは『このデータセットを用いてcalm2-7b-chatに対してDirect Preference Optimization (DPO)を行い、calm2-7b-chat-dpoを作成しました。 Instruction Tuningの評価用タスクであるELYZA-tasks-100とJapanese MT-Benchを用いてGPT-4による自動評価を行ったところ、どちらのデータセットでもcalm2-7b-chat-dpoの方がcalm2-7b-chatよりも高いスコアが得られました。』とあるため期待

◯ 参考にしたコード『自作FT済みモデルからDPOするためのサンプルコード(Unsloth最新版 2024.12.2)』にある、藤越様のコードを参考にし、RLHFをしてみました。

https://matsuolab-geniac.notion.site/FT-DPO-Unsloth-2024-12-2-bac63c15586840b9ad118f5f5b27420a

'''python

Google Colab の場合は上記の環境構築手順を行なわず、単にこのセルから実行していってください。

!pip uninstall unsloth -y !pip install --upgrade --no-cache-dir "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"

Google Colab のデフォルトで入っているパッケージをアップグレード(Moriyasu さんありがとうございます)

!pip install --upgrade torch !pip install --upgrade xformers

notebookでインタラクティブな表示を可能とする(ただし、うまく動かない場合あり)

!pip install ipywidgets --upgrade

Install Flash Attention 2 for softcapping support

import torch if torch.cuda.get_device_capability()[0] >= 8: !pip install --no-deps packaging ninja einops "flash-attn>=2.6.3" from google.colab import output output.enable_custom_widget_manager()

Hugging Face Token を指定

from huggingface_hub import login from google.colab import userdata

hf_token = userdata.get('HF_TOKEN') if hf_token: login(token=hf_token) print("Hugging Face token found and logged in.") else: print("Hugging Face token not found. Please set it using userdata.set('HF_TOKEN', '')") print(dataset['train'][0])

学習時のプロンプトフォーマットの定義

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, # 並列処理数を指定 )

dataset """ training_arguments: 学習の設定

  • output_dir: -トレーニング後のモデルを保存するディレクトリ

  • per_device_train_batch_size:

    • デバイスごとのトレーニングバッチサイズ
  • per_device_eval_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"など) """ from trl import SFTTrainer from transformers import TrainingArguments from unsloth import is_bfloat16_supported

trainer = SFTTrainer( model = model, tokenizer = tokenizer, train_dataset=dataset["train"], max_seq_length = max_seq_length, dataset_text_field="formatted_text", packing = False, args = TrainingArguments( per_device_train_batch_size = 2, gradient_accumulation_steps = 4, num_train_epochs = 1, logging_steps = 10, warmup_steps = 10, save_steps=100, save_total_limit=2, max_steps=-1, learning_rate = 2e-4, fp16 = not is_bfloat16_supported(), bf16 = is_bfloat16_supported(), group_by_length=True, seed = 3407, output_dir = "outputs", report_to = "none", ), ) #@title 学習実行 trainer_stats = trainer.train() edataset = load_dataset("elyza/ELYZA-tasks-100") edataset = edataset.remove_columns('eval_aspect') edataset = edataset.rename_columns({'input':'text'}) print(edataset['test'][0])

学習時のプロンプトフォーマットの定義

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

# 各データにフォーマットを適用

edataset = edataset.map( formatting_prompts_func, num_proc= 4, # 並列処理数を指定 )

edataset

データを確認

print(edataset["test"]["formatted_text"][3]) etrainer = SFTTrainer( model = model, tokenizer = tokenizer, train_dataset=edataset["test"], max_seq_length = max_seq_length, dataset_text_field="formatted_text", packing = False, args = TrainingArguments( per_device_train_batch_size = 2, gradient_accumulation_steps = 4, num_train_epochs = 1, logging_steps = 10, warmup_steps = 10, save_steps=100, save_total_limit=2, max_steps=-1, learning_rate = 2e-4, fp16 = not is_bfloat16_supported(), bf16 = is_bfloat16_supported(), group_by_length=True, seed = 3407, output_dir = "outputs", report_to = "none", ), ) #@title 学習実行 trainer_stats = etrainer.train()

強化学習

%%capture !pip install unsloth

Also get the latest nightly Unsloth!

!pip uninstall unsloth -y && pip install --upgrade --no-cache-dir --no-deps git+https://github.com/unslothai/unsloth.git from huggingface_hub import login from google.colab import userdata

hugging faseにlog in

hf_token = userdata.get('HF_TOKEN') if hf_token: login(token=hf_token) print("Hugging Face token found. Logged in to Hugging Face.") else: print("Hugging Face token not found. Please set it using userdata.set('HF_TOKEN', '')") from unsloth import PatchDPOTrainer PatchDPOTrainer() from unsloth import FastLanguageModel import torch max_seq_length = 2048 # Choose any! We auto support RoPE Scaling internally! dtype = None # None for auto detection. Float16 for Tesla T4, V100, Bfloat16 for Ampere+ load_in_4bit = True # Use 4bit quantization to reduce memory usage. Can be False. model, tokenizer = FastLanguageModel.from_pretrained( model_name = "IWAIYuma/llm-jp-3-13b-it_v3", # 自分がUnslothを使ってFTして、loraだけアップロードしているモデル max_seq_length = max_seq_length, dtype = dtype, load_in_4bit = load_in_4bit, token = hf_token, )

cyberagent/chatbot-arena-ja-calm2-7b-chat-experimentalデータセットの読み込み

import json import codecs from pprint import pprint from datasets import load_dataset

データセットをロード

ds = load_dataset("cyberagent/chatbot-arena-ja-calm2-7b-chat-experimental")

フィルタリング関数を定義

def filter_short_examples(example): return ( len(example['prompt']) <= 2000 and len(example['chosen']) <= 2000 and len(example['rejected']) <= 2000 )

トレーニングデータをフィルタリング

filtered_train = ds['train'].filter(filter_short_examples)

データセットをトレーニング用と評価用に分割 (80%をトレーニング用、20%を評価用)

train_size = int(0.8 * len(filtered_train)) # トレーニングデータのサイズ eval_size = len(filtered_train) - train_size # 評価データのサイズ

インデックスを順序通りに生成 (ランダム性なし)

train_indices = list(range(train_size)) # トレーニング用インデックス eval_indices = list(range(train_size, len(filtered_train))) # 評価用インデックス

トレーニングデータと評価データを選択

train_dataset = filtered_train.select(train_indices) eval_dataset = filtered_train.select(eval_indices)

データセットのサイズを出力

print(f"トレーニングデータセットのサイズ: {len(train_dataset)}") print(f"評価データセットのサイズ: {len(eval_dataset)}") pprint(train_dataset[0]) print("\n") pprint(eval_dataset[0])

一旦100までを学習

結果が良かったので修正

use_dataset = train_dataset.select(range(100))

use_dataset = train_dataset use_dataset

One must patch the DPO Trainer first!

from unsloth import PatchDPOTrainer PatchDPOTrainer()

from transformers import TrainingArguments from trl import DPOTrainer, DPOConfig from unsloth import is_bfloat16_supported

dpo_trainer = DPOTrainer( model = model, ref_model = None, args = DPOConfig( per_device_train_batch_size = 2, gradient_accumulation_steps = 4, warmup_ratio = 0.1, num_train_epochs = 1, learning_rate = 5e-6, fp16 = not is_bfloat16_supported(), bf16 = is_bfloat16_supported(), logging_steps = 1, optim = "adamw_8bit", weight_decay = 0.0, lr_scheduler_type = "linear", seed = 42, output_dir = "outputs", report_to = "none", # Use this for WandB etc ), beta = 0.1, train_dataset = use_dataset, #raw_datasets["train"], # eval_dataset = raw_datasets["test"], tokenizer = tokenizer, max_length = 2048, max_prompt_length = 1024, )

学習の開始

dpo_trainer.train()

ELYZA-tasks-100-TV データセットの読み込み。

import json datasets = [] with open("/content/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 = ""

学習したモデルを用いてタスクを実行

from tqdm import tqdm

推論するためにモデルのモードを変更

FastLanguageModel.for_inference(model)

results = [] for dt in tqdm(datasets): input = dt["input"]

prompt = f"""### 指示\n{input} 簡潔に回答してください \n### 回答\n"""

inputs = tokenizer([prompt], return_tensors = "pt").to(model.device)

outputs = model.generate(**inputs, max_new_tokens = 2048, use_cache = True, do_sample=False, repetition_penalty=1.2) prediction = tokenizer.decode(outputs[0], skip_special_tokens=True).split('\n### 回答')[-1]

results.append({"task_id": dt["task_id"], "input": input, "output": prediction})

jsonlで保存

new_model_id = "llm-jp-3-13b-it" with open(f"{new_model_id}_output.jsonl", 'w', encoding='utf-8') as f: for result in results: json.dump(result, f, ensure_ascii=False) f.write('\n')

#書き込みにログイン whf_token = userdata.get('WHF_TOKEN') if whf_token: login(token=whf_token) print("Hugging Face token found and logged in.") else: print("Hugging Face token not found. Please set it using userdata.set('HF_TOKEN', '')")

モデルとトークナイザーをHugging Faceにアップロード

new_model_id = "llm-jp-3-13b-it" new_model_id = f"{new_model_id}_RLHFv3" model.push_to_hub(new_model_id, token=whf_token, private=True) tokenizer.push_to_hub(new_model_id, token=whf_token, private=True) '''

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model is not currently available via any of the supported Inference Providers.
The model cannot be deployed to the HF Inference API: The model has no pipeline_tag.

Model tree for IWAIYuma/llm-jp-3-13b-it_RLHFv3

Finetuned
(1120)
this model