Views
No views yet
llm-jp/llm-jp-3-13b + KazMarketing/llm-jp-3-13b-it_lora_v3)を用いて
入力データ(elyza-tasks-100-TV_0.jsonl)を推論し、jsonlファイルを生成します。
課題の成果として提出可能なフォーマットになっております。1%%capture
2!pip install unsloth
3# Also get the latest nightly Unsloth!
4!pip uninstall unsloth -y && pip install --upgrade --no-cache-dir --no-deps git+https://github.com/unslothai/unsloth.git1from unsloth import PatchDPOTrainer
2PatchDPOTrainer()1from google.colab import userdata
2HF_TOKEN=userdata.get('HF_TOKEN')
3
4# HF_TOKEN = "your-token"#ご自身のToken1from unsloth import FastLanguageModel
2import torch
3max_seq_length = 2048 # Choose any! We auto support RoPE Scaling internally!
4dtype = None # None for auto detection. Float16 for Tesla T4, V100, Bfloat16 for Ampere+
5load_in_4bit = True # Use 4bit quantization to reduce memory usage. Can be False.
6
7model, tokenizer = FastLanguageModel.from_pretrained(
8 # 自分がUnslothを使ってFTして、loraだけアップロードしているモデル
9 model_name = "KazMarketing/llm-jp-3-13b-it_lora_v3",
10 max_seq_length = max_seq_length,
11 dtype = dtype,
12 load_in_4bit = load_in_4bit,
13 token = HF_TOKEN,
14)1from huggingface_hub import login
2
3# 生成したトークンをペースト
4login(HF_TOKEN)#weblab-GENIAC/aya-ja-nemotron-dpo-maskedのデータセットを読み込みためにログインしておく。
5
6from datasets import load_dataset
7
8# データセットをロード
9ds = load_dataset("weblab-GENIAC/aya-ja-nemotron-dpo-masked")
10
11# フィルタリング関数を定義
12def filter_short_examples(example):
13 return (
14 len(example['prompt']) <= 2000 and
15 len(example['chosen']) <= 2000 and
16 len(example['rejected']) <= 2000
17 )1# トレーニングデータをフィルタリング
2filtered_train = ds['train'].filter(filter_short_examples)
3
4# データセットをトレーニング用と評価用に分割 (80%をトレーニング用、20%を評価用)
5train_size = int(0.8 * len(filtered_train)) # トレーニングデータのサイズ
6eval_size = len(filtered_train) - train_size # 評価データのサイズ
7
8# インデックスを順序通りに生成 (ランダム性なし)
9train_indices = list(range(train_size)) # トレーニング用インデックス
10eval_indices = list(range(train_size, len(filtered_train))) # 評価用インデックス
11
12# トレーニングデータと評価データを選択
13train_dataset = filtered_train.select(train_indices)
14eval_dataset = filtered_train.select(eval_indices)
15
16# データセットのサイズを出力
17print(f"トレーニングデータセットのサイズ: {len(train_dataset)}")
18print(f"評価データセットのサイズ: {len(eval_dataset)}")1use_dataset = train_dataset.select(range(100))
2use_dataset
3# One must patch the DPO Trainer first!
4from unsloth import PatchDPOTrainer
5PatchDPOTrainer()1from transformers import TrainingArguments
2from trl import DPOTrainer, DPOConfig
3from unsloth import is_bfloat16_supported
4
5dpo_trainer = DPOTrainer(
6 model = model,
7 ref_model = None,
8 args = DPOConfig(
9 per_device_train_batch_size = 2,
10 gradient_accumulation_steps = 4,
11 warmup_ratio = 0.1,
12 num_train_epochs = 1,
13 learning_rate = 5e-6,
14 fp16 = not is_bfloat16_supported(),
15 bf16 = is_bfloat16_supported(),
16 logging_steps = 1,
17 optim = "adamw_8bit",
18 weight_decay = 0.0,
19 lr_scheduler_type = "linear",
20 seed = 1111, #42から変更,
21 output_dir = "outputs",
22 report_to = "none", # Use this for WandB etc
23 ),
24 beta = 0.1,
25 train_dataset = use_dataset, #raw_datasets["train"],
26 # eval_dataset = raw_datasets["test"],
27 tokenizer = tokenizer,
28 max_length = 2048,
29 max_prompt_length = 1024,
30)
31dpo_trainer.train()./content/elyza-tasks-100-TV_0.jsonlというファイルからデータセットをロード
※Google Colab環境では特に配下を指定しなければ基本的にContentにアップされる1# ELYZA-tasks-100-TVの読み込み。事前にファイルをアップロードしてください
2# データセットの読み込み。
3# omnicampusの開発環境では、左にタスクのjsonlをドラッグアンドドロップしてから実行。
4import json
5datasets = []
6with open("/content/elyza-tasks-100-TV_0.jsonl", "r") as f:
7 item = ""
8 for line in f:
9 line = line.strip()
10 item += line
11 if item.endswith("}"):
12 datasets.append(json.loads(item))
13 item = ""1# 学習したモデルを用いてタスクを実行
2from tqdm import tqdm
3
4# 推論するためにモデルのモードを変更
5FastLanguageModel.for_inference(model)
6
7results = []
8for dt in tqdm(datasets):
9 input = dt["input"]
10
11 prompt = f"""### 指示\n{input}\n### 回答\n"""
12
13 inputs = tokenizer([prompt], return_tensors = "pt").to(model.device)
14
15 outputs = model.generate(**inputs,
16 max_new_tokens = 2048,
17 use_cache = True,
18 do_sample=False,
19 repetition_penalty=1.2)
20 prediction = tokenizer.decode(outputs[0], skip_special_tokens=True).split('\n### 回答')[-1]
21
22 results.append({"task_id": dt["task_id"], "input": input, "output": prediction})1# modelをhugging faceにアップロード
2# LoRAアダプタだけ保存
3model.push_to_hub_merged(
4 "llm-jp-3-13b-it_lora-DPO-241215_v2",#保存するモデルの名前
5 tokenizer=tokenizer,
6 save_method="lora",#loraだけ保存
7 token=HF_TOKEN,
8 private=True
9)KazMarketing/llm-jp-3-13b-it_lora_v3 を作成するための推論用コードは下記である1!pip install "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
2!pip install -U xformers --index-url https://download.pytorch.org/whl/cu124
3!pip install --no-deps "trl<0.9.0" peft accelerate bitsandbytes
4!pip uninstall unsloth -y
5!pip install --upgrade --no-cache-dir "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
6# Google Colab のデフォルトで入っているパッケージをアップグレード
7!pip install --upgrade torch
8!pip install --upgrade xformers1# Install Flash Attention 2 for softcapping support
2import torch
3if torch.cuda.get_device_capability()[0] >= 8:
4 !pip install --no-deps packaging ninja einops "flash-attn>=2.6.3"HF_TOKEN = "your_token" #@param {type:"string"}1# llm-jp/llm-jp-3-13bを4bit量子化のqLoRA設定でロード。
2from unsloth import FastLanguageModel
3import torch
4max_seq_length = 512 # unslothではRoPEをサポートしているのでコンテキスト長は自由に設定可能
5dtype = None # Noneにしておけば自動で設定
6load_in_4bit = True # 今回は13Bモデルを扱うためTrue
7model_id = "llm-jp/llm-jp-3-13b"
8new_model_id = "llm-jp-3-13b-it" #Fine-Tuningしたモデルにつけたい名前、it: Instruction Tuning
9# FastLanguageModel インスタンスを作成
10model, tokenizer = FastLanguageModel.from_pretrained(
11 model_name=model_id,
12 dtype=dtype,
13 load_in_4bit=load_in_4bit,
14 trust_remote_code=True,
15)
16# SFT用のモデルを用意
17model = FastLanguageModel.get_peft_model(
18 model,
19 r = 32,
20 target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
21 "gate_proj", "up_proj", "down_proj",],
22 lora_alpha = 64,
23 lora_dropout = 0.01,
24 bias = "none",
25 use_gradient_checkpointing = "unsloth",
26 random_state = 3407,
27 use_rslora = False,
28 loftq_config = None,
29 max_seq_length = max_seq_length,
30)1from datasets import load_dataset
2dataset = load_dataset("json", data_files="./ichikara-instruction-003-001-1.json")1# 学習時のプロンプトフォーマットの定義
2prompt = """### 指示
3{}
4### 回答
5{}"""
6"""
7formatting_prompts_func: 各データをプロンプトに合わせた形式に合わせる
8"""
9EOS_TOKEN = tokenizer.eos_token # トークナイザーのEOSトークン(文末トークン)
10def formatting_prompts_func(examples):
11 input = examples["text"] # 入力データ
12 output = examples["output"] # 出力データ
13 text = prompt.format(input, output) + EOS_TOKEN # プロンプトの作成
14 return { "formatted_text" : text, } # 新しいフィールド "formatted_text" を返す
15pass
16# # 各データにフォーマットを適用
17dataset = dataset.map(
18 formatting_prompts_func,
19 num_proc= 4, # 並列処理数を指定
20)
21dataset1# データを確認
2print(dataset["train"]["formatted_text"][3])1"""
2training_arguments: 学習の設定
3 - output_dir:
4 -トレーニング後のモデルを保存するディレクトリ
5 - per_device_train_batch_size:
6 - デバイスごとのトレーニングバッチサイズ
7 - per_device_eval_batch_size:
8 - デバイスごとの評価バッチサイズ
9 - gradient_accumulation_steps:
10 - 勾配を更新する前にステップを積み重ねる回数
11 - optim:
12 - オプティマイザの設定
13 - num_train_epochs:
14 - エポック数
15 - eval_strategy:
16 - 評価の戦略 ("no"/"steps"/"epoch")
17 - eval_steps:
18 - eval_strategyが"steps"のとき、評価を行うstep間隔
19 - logging_strategy:
20 - ログ記録の戦略
21 - logging_steps:
22 - ログを出力するステップ間隔
23 - warmup_steps:
24 - 学習率のウォームアップステップ数
25 - save_steps:
26 - モデルを保存するステップ間隔
27 - save_total_limit:
28 - 保存しておくcheckpointの数
29 - max_steps:
30 - トレーニングの最大ステップ数
31 - learning_rate:
32 - 学習率
33 - fp16:
34 - 16bit浮動小数点の使用設定(第8回演習を参考にすると良いです)
35 - bf16:
36 - BFloat16の使用設定
37 - group_by_length:
38 - 入力シーケンスの長さによりバッチをグループ化 (トレーニングの効率化)
39 - report_to:
40 - ログの送信先 ("wandb"/"tensorboard"など)
41"""
42from trl import SFTTrainer
43from transformers import TrainingArguments
44from unsloth import is_bfloat16_supported
45trainer = SFTTrainer(
46 model = model,
47 tokenizer = tokenizer,
48 train_dataset=dataset["train"],
49 max_seq_length = max_seq_length,
50 dataset_text_field="formatted_text",
51 packing = False,
52 args = TrainingArguments(
53 per_device_train_batch_size = 2,
54 gradient_accumulation_steps = 4,
55 num_train_epochs = 1,
56 logging_steps = 10,
57 warmup_steps = 10,
58 save_steps=100,
59 save_total_limit=2,
60 max_steps=-1,
61 learning_rate = 2e-4,
62 fp16 = not is_bfloat16_supported(),
63 bf16 = is_bfloat16_supported(),
64 group_by_length=True,
65 seed = 3407,
66 output_dir = "outputs",
67 report_to = "none",
68 ),
69)1#@title 現在のメモリ使用量を表示
2gpu_stats = torch.cuda.get_device_properties(0)
3start_gpu_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)
4max_memory = round(gpu_stats.total_memory / 1024 / 1024 / 1024, 3)
5print(f"GPU = {gpu_stats.name}. Max memory = {max_memory} GB.")
6print(f"{start_gpu_memory} GB of memory reserved.")1#@title 学習実行
2trainer_stats = trainer.train()1# ELYZA-tasks-100-TVの読み込み。事前にファイルをアップロードしてください
2# データセットの読み込み。
3# omnicampusの開発環境では、左にタスクのjsonlをドラッグアンドドロップしてから実行。
4import json
5datasets = []
6with open("/content//elyza-tasks-100-TV_0.jsonl", "r") as f:
7 item = ""
8 for line in f:
9 line = line.strip()
10 item += line
11 if item.endswith("}"):
12 datasets.append(json.loads(item))
13 item = ""1# 学習したモデルを用いてタスクを実行
2from tqdm import tqdm
3# 推論するためにモデルのモードを変更
4FastLanguageModel.for_inference(model)
5results = []
6for dt in tqdm(datasets):
7 input = dt["input"]
8 prompt = f"""### 指示\n{input}\n### 回答\n"""
9 inputs = tokenizer([prompt], return_tensors = "pt").to(model.device)
10 outputs = model.generate(**inputs, max_new_tokens = 512, use_cache = True, do_sample=False, repetition_penalty=1.2)
11 prediction = tokenizer.decode(outputs[0], skip_special_tokens=True).split('\n### 回答')[-1]
12 results.append({"task_id": dt["task_id"], "input": input, "output": prediction})1# jsonlで保存
2with open(f"{new_model_id}_output.jsonl", 'w', encoding='utf-8') as f:
3 for result in results:
4 json.dump(result, f, ensure_ascii=False)
5 f.write('\n')```
6
7# LoRAアダプタだけ保存
8model.push_to_hub_merged(
9 new_model_id+"_lora",
10 tokenizer=tokenizer,
11 save_method="lora",
12 # token=HF_TOKEN,
13 token="HF_TOKEN",
14 private=True
15)