u9999Yoko commited on
Commit
a8e940e
·
verified ·
1 Parent(s): cdd2bdd

Upload README.md

Browse files
Files changed (1) hide show
  1. README.md +245 -0
README.md ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Uploaded model
2
+
3
+ - **Developed by:** u9999Yoko
4
+ - **License:** CC BY-NC-SA
5
+ - **Finetuned from model :** llm-jp/llm-jp-3-13b
6
+
7
+ ## Abstract
8
+
9
+ 「llm-jp/llm-jp-3-13bモデルにichikara-instructionデータを用いてファインチューニングを行ったモデルです。
10
+ 松尾研究室の講義のコンペ用としてモデルを作成しました。
11
+ https://weblab.t.u-tokyo.ac.jp/lecture/course-list/large-language-model/
12
+ https://llm-jp.nii.ac.jp/blog/2024/04/30/v2.0-release.html
13
+
14
+ ## Dataset
15
+ データセットは以下を使用しました。
16
+ - ichikara-instruction-003-001-1.json
17
+
18
+ ## Attention
19
+ ichikara-instructionデータは、CC BY-NC-SAライセンス(表示-非営利-継承)で公開されています。
20
+ このライセンスの下では、非営利目的での利用が許可されていますが、商用利用は認められていません。
21
+ 詳しくは次のホームページをご覧ください。
22
+ https://llm-jp.nii.ac.jp/blog/2024/04/30/v2.0-release.html
23
+
24
+ ## Usage
25
+ Execute following code in Notebook
26
+
27
+ ```python
28
+ # 必要なライブラリをインストール
29
+ conda install --yes --file requirements.txt
30
+
31
+ from requests.exceptions import HTTPError
32
+ from transformers import (
33
+ AutoModelForCausalLM,
34
+ AutoTokenizer,
35
+ TrainingArguments,
36
+ )
37
+ from peft import (
38
+ LoraConfig,
39
+ get_peft_model,
40
+ )
41
+ import torch
42
+ from datasets import load_dataset
43
+ from trl import SFTTrainer
44
+ from tqdm import tqdm
45
+
46
+ # HuggingFaceにログイン
47
+ from huggingface_hub import notebook_login
48
+
49
+ # 取得したTokenを入力
50
+ notebook_login()
51
+
52
+ # base model id
53
+ base_model_id = "llm-jp/llm-jp-3-13b"
54
+ new_model_id = "u9999Yoko//llm-jp-3-13b-finetune"
55
+
56
+
57
+ model = AutoModelForCausalLM.from_pretrained(
58
+ base_model_id,
59
+ device_map="auto",
60
+ torch_dtype=torch.bfloat16, # 半精度計算で効率化
61
+ )
62
+
63
+ tokenizer = AutoTokenizer.from_pretrained(base_model_id, trust_remote_code=True)
64
+
65
+ """
66
+ peft_config: PEFTの構成設定
67
+ - r
68
+ - LoRA のランク (4, 8, 16 ,32...)
69
+ - 増やすほど学習が捗るが, 過学習のリスクも高まるので注意
70
+ - lora_alpha
71
+ - LoRAのスケーリング係数
72
+ - lora_dropout
73
+ - ドロップアウト率(過学習を防ぐための割合)
74
+ - bias
75
+ - バイアス項の扱い ("none"の場合、LoRAはバイアスを学習しない)
76
+ - task_type
77
+ - タスクタイプ
78
+ - target_modules
79
+ - LoRAを適用するターゲットモジュール (前のコードで特定した層)
80
+ """
81
+
82
+ # LoRA設定
83
+ lora_config = LoraConfig(
84
+ r=8,
85
+ lora_alpha=16,
86
+ target_modules=["q_proj", "v_proj"], # トレーニング対象の層
87
+ lora_dropout=0.1,
88
+ task_type="CAUSAL_LM",
89
+ )
90
+
91
+ model = get_peft_model(model, lora_config)
92
+
93
+ dataset = load_dataset("json", data_files="./ichikara-instruction-003-001-1.json")
94
+
95
+ # 学習時のプロンプトフォーマットの定義
96
+ prompt = """### 指示
97
+ {}
98
+ ### 回答
99
+ {}"""
100
+
101
+
102
+ """
103
+ formatting_prompts_func: 各データをプロンプトに合わせた形式に合わせる
104
+ """
105
+ EOS_TOKEN = tokenizer.eos_token # トークナイザーのEOSトークン(文末トークン)
106
+ def formatting_prompts_func(examples):
107
+ input = examples["text"] # 入力データ
108
+ output = examples["output"] # 出力データ
109
+ text = prompt.format(input, output) + EOS_TOKEN # プロンプトの作成
110
+ return { "formatted_text" : text, } # 新しいフィールド "formatted_text" を返す
111
+ pass
112
+
113
+ # # 各データにフォーマットを適用
114
+ dataset = dataset.map(
115
+ formatting_prompts_func,
116
+ num_proc= 4, # 並列処理数を指定
117
+ )
118
+
119
+ # データを確認
120
+ print(dataset["train"]["formatted_text"][3])
121
+
122
+ # データをtrainデータとtestデータに分割 (test_sizeの比率に)
123
+ dataset = dataset["train"].train_test_split(test_size=0.1)
124
+ print(dataset)
125
+
126
+ """
127
+ training_arguments: 学習の設定
128
+ output_dir:トレーニング後のモデルを保存するディレクトリ
129
+ per_device_train_batch_size: デバイスごとのトレーニングバッチサイズ
130
+ per_device__batch_size:デバイスごとの評価バッチサイズ
131
+ gradient_accumulation_steps:勾配を更新する前にステップを積み重ねる回数
132
+ optim: オプティマイザの設定
133
+ num_train_epochs:エポック数
134
+ eval_strategy:評価の戦略 ("no"/"steps"/"epoch")
135
+ eval_steps: eval_strategyが"steps"のとき、評価を行うstep間隔
136
+ logging_strategy: ログ記録の戦略
137
+ logging_steps: ログを出力するステップ間隔
138
+ warmup_steps: 学習率のウォームアップステップ数
139
+ save_steps: モデルを保存するステップ間隔
140
+ save_total_limit: 保存しておくcheckpointの数
141
+ max_steps:トレーニングの最大ステップ数
142
+ learning_rate: 学習率
143
+ fp16:16bit浮動小数点の使用設定(第8回演習を参考にすると良いです)
144
+ bf16:BFloat16の使用設定
145
+ group_by_length:入力シーケンスの長さによりバッチをグループ化 (トレーニングの効率化)
146
+ report_to:ログの送信先 ("wandb"/"tensorboard"���ど)
147
+ """
148
+
149
+ training_arguments = TrainingArguments(
150
+ output_dir=new_model_id,
151
+ per_device_train_batch_size=1,
152
+ gradient_accumulation_steps=8,
153
+ # optim="paged_adamw_32bit",
154
+ num_train_epochs=3,
155
+ logging_strategy="steps",
156
+ logging_steps=10,
157
+ warmup_steps=10,
158
+ save_steps=1000,
159
+ save_total_limit = 2,
160
+ max_steps = -1,
161
+ learning_rate=5e-5,
162
+ fp16=False,
163
+ bf16=True,
164
+ seed = 3407,
165
+ group_by_length=True,
166
+ report_to="none"
167
+ )
168
+
169
+ """
170
+ SFTTrainer: Supervised Fine-Tuningに関する設定
171
+ model:読み込んだベースのモデル
172
+ train_dataset:トレーニングに使用するデータセット
173
+ eval_dataset:評価に使用するデータセット
174
+ peft_config: PEFT(Parameter-Efficient Fine-Tuning)の設定(LoRAを利用する場合に指定)
175
+ max_seq_length:モデルに入力されるシーケンスの最大トークン長
176
+ dataset_text_field:データセット内の学習に使うテキストを含むフィールド名
177
+ tokenizer:モデルに対応するトークナイザー
178
+ args:トレーニングに使用するハイパーパラメータ(TrainingArgumentsの設定を指定)
179
+ packing:入力シーケンスのパッキングを行うかどうかの設定 (False に設定することで、各入力を独立して扱う)
180
+ """
181
+ trainer = SFTTrainer(
182
+ model=model,
183
+ train_dataset=dataset["train"],
184
+ peft_config=lora_config,
185
+ max_seq_length= 512,
186
+ dataset_text_field="formatted_text",
187
+ tokenizer=tokenizer,
188
+ args=training_arguments,
189
+ packing= False,
190
+ )
191
+
192
+ model.config.use_cache = False # キャッシュ機能を無効化
193
+ trainer.train() # トレーニングを実行
194
+
195
+ # タスクとなるデータの読み込み。
196
+
197
+ import json
198
+ datasets = []
199
+ with open("./elyza-tasks-100-TV_0.jsonl", "r") as f:
200
+ item = ""
201
+ for line in f:
202
+ line = line.strip()
203
+ item += line
204
+ if item.endswith("}"):
205
+ datasets.append(json.loads(item))
206
+ item = ""
207
+ print(datasets)
208
+
209
+
210
+ # モデルによるタスクの推論。
211
+
212
+ results = []
213
+ for data in tqdm(datasets):
214
+
215
+ input = data["input"]
216
+
217
+ prompt = f"""### 指示
218
+ {input}
219
+ ### 回答
220
+ """
221
+
222
+ tokenized_input = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt").to(model.device)
223
+ attention_mask = torch.ones_like(tokenized_input)
224
+
225
+ with torch.no_grad():
226
+ outputs = model.generate(
227
+ tokenized_input,
228
+ attention_mask=attention_mask,
229
+ max_new_tokens=400,
230
+ do_sample=False,
231
+ repetition_penalty=1.2,
232
+ pad_token_id=tokenizer.eos_token_id
233
+ )[0]
234
+ output = tokenizer.decode(outputs[tokenized_input.size(1):], skip_special_tokens=True)
235
+
236
+ results.append({"task_id": data["task_id"], "input": input, "output": output})
237
+
238
+ # 結果をjsonlで保存。
239
+ import re
240
+ jsonl_id = re.sub(".*/", "", new_model_id)
241
+ with open(f"./{jsonl_id}-outputs.jsonl", 'w', encoding='utf-8') as f:
242
+ for result in results:
243
+ json.dump(result, f, ensure_ascii=False) # ensure_ascii=False for handling non-ASCII characters
244
+ f.write('\n')
245
+ ```