Gamoooo commited on
Commit
0161dc3
·
verified ·
1 Parent(s): b07fbc1

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +43 -203
README.md CHANGED
@@ -6,7 +6,6 @@ tags:
6
  - unsloth
7
  - llama
8
  - trl
9
- license: apache-2.0
10
  language:
11
  - en
12
  - ja
@@ -24,27 +23,27 @@ This llama model was trained 2x faster with [Unsloth](https://github.com/unsloth
24
 
25
  # 推論用コード
26
  # Hugging Faceにアップロードしたモデルを用いてELYZA-tasks-100-TVの出力を得るためのコードです。 このコードで生成されたjsonlファイルは課題の成果として提出可能なフォーマットになっております。
 
 
 
 
 
27
 
28
- !pip uninstall unsloth -y
29
- !pip install --upgrade --no-cache-dir "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
30
- !pip install --upgrade torch
31
- !pip install --upgrade xformers
32
-
33
- # Install Flash Attention 2 for softcapping support
34
- import torch
35
- if torch.cuda.get_device_capability()[0] >= 8:
36
- !pip install --no-deps packaging ninja einops "flash-attn>=2.6.3"
37
-
38
- from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
39
  from unsloth import FastLanguageModel
 
40
  import torch
41
-
42
- max_seq_length = 512
43
- dtype = None
44
- load_in_4bit = True
45
 
46
  model_id = "llm-jp/llm-jp-3-13b"
47
- new_model_id = "llm-jp-3-13b-last"
 
 
 
 
 
48
 
49
  model, tokenizer = FastLanguageModel.from_pretrained(
50
  model_name=model_id,
@@ -53,203 +52,44 @@ model, tokenizer = FastLanguageModel.from_pretrained(
53
  trust_remote_code=True,
54
  )
55
 
56
- # SFT用のモデルを用意
57
- model = FastLanguageModel.get_peft_model(
58
- model,
59
- r=32,
60
- target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
61
- "gate_proj", "up_proj", "down_proj"],
62
- lora_alpha=32,
63
- lora_dropout=0.05,
64
- bias="none",
65
- use_gradient_checkpointing="unsloth",
66
- random_state=3407,
67
- use_rslora=False,
68
- loftq_config=None,
69
- max_seq_length=max_seq_length,
70
- )
71
-
72
- # https://huggingface.co/settings/tokens
73
- HF_TOKEN = "your-token" # @param {type:"string"}
74
-
75
- from datasets import load_dataset, concatenate_datasets
76
-
77
- # データセットのロード
78
- ichikara_dataset = load_dataset("json", data_files="/content/ichikara-instruction-003-001-1.json")
79
- elyza_dataset = load_dataset("elyza/ELYZA-tasks-100")
80
-
81
- EOS_TOKEN = tokenizer.eos_token #
82
-
83
- # 学習時のプロンプトフォーマットの定義
84
- prompt = """### 指示
85
- {}
86
- ### 回答
87
- {}"""
88
-
89
- """
90
- formatting_prompts_func: 各データをプロンプトに合わせた形式に合わせる
91
- """
92
- def formatting_prompts_func(examples):
93
- input = examples["text"]
94
- output = examples["output"]
95
- text = prompt.format(input, output) + EOS_TOKEN
96
- return {"formatted_text": text}
97
-
98
- # ichikara-instruction のデータフォーマット
99
- ichikara_dataset = ichikara_dataset.map(
100
- formatting_prompts_func,
101
- num_proc=4,
102
- )
103
-
104
- # ELYZA-tasks-100 データセットのフォーマット関数
105
- def elyza_formatting_prompts_func(examples):
106
- input = examples["input"]
107
- output = examples["output"]
108
- text = prompt.format(input, output) + EOS_TOKEN
109
- return {"formatted_text": text}
110
-
111
- # ELYZA-tasks-100 のデータフォーマット
112
- elyza_dataset = elyza_dataset.map(
113
- elyza_formatting_prompts_func,
114
- num_proc=4
115
- )
116
-
117
- from datasets import concatenate_datasets
118
-
119
- # ichikara-instruction と ELYZA-tasks-100 を統合
120
- combined_dataset = concatenate_datasets([
121
- ichikara_dataset["train"],
122
- elyza_dataset["test"]
123
- ])
124
-
125
- # データ品質チェック
126
- # 1. ランダムサンプルを確認
127
- import random
128
- sample_indices = random.sample(range(len(combined_dataset)), 10)
129
- for idx in sample_indices:
130
- print(combined_dataset[idx]["formatted_text"])
131
-
132
- # 2. 自動検査ルール
133
- # 短すぎるデータをチェック(Noneチェックを追加)
134
- short_data = combined_dataset.filter(
135
- lambda x: x["input"] is not None and x["output"] is not None and (len(x["input"]) < 5 or len(x["output"]) < 5)
136
- )
137
- print(f"\n短すぎるデータ数: {len(short_data)}")
138
-
139
- # 指示と回答が同一のデータ(Noneチェックを追加)
140
- duplicate_data = combined_dataset.filter(
141
- lambda x: x["input"] is not None and x["output"] is not None and x["input"].strip() == x["output"].strip()
142
- )
143
- print(f"\n指示と回答が同一のデータ数: {len(duplicate_data)}")
144
-
145
- # 問題のあるデータをフィルタリング(Noneチェックを追加)
146
- filtered_dataset = combined_dataset.filter(
147
- lambda x: x["input"] is not None and x["output"] is not None and len(x["input"]) > 5 and len(x["output"]) > 5 and x["input"].strip() != x["output"].strip()
148
- )
149
-
150
- print(f"元のデータ数: {len(combined_dataset)}")
151
- print(f"フィルタリング後のデータ数: {len(filtered_dataset)}")
152
- print(f"除外されたデータ数: {len(combined_dataset) - len(filtered_dataset)}")
153
-
154
- # フィルタリング後のデータの例を確認
155
- print(filtered_dataset[0])
156
-
157
- """
158
- training_arguments: 学習の設定
159
- """
160
- from trl import SFTTrainer
161
- from transformers import TrainingArguments
162
- from unsloth import is_bfloat16_supported
163
-
164
- trainer = SFTTrainer(
165
- model=model,
166
- tokenizer=tokenizer,
167
- train_dataset=filtered_dataset,
168
- max_seq_length=max_seq_length,
169
- dataset_text_field="formatted_text",
170
- packing=False,
171
- args=TrainingArguments(
172
- per_device_train_batch_size=2,
173
- gradient_accumulation_steps=4,
174
- num_train_epochs=3,
175
- logging_steps=10,
176
- warmup_steps=10,
177
- save_steps=50,
178
- save_total_limit=2,
179
- max_steps=200,
180
- learning_rate=2e-4,
181
- fp16=not is_bfloat16_supported(),
182
- bf16=is_bfloat16_supported(),
183
- group_by_length=True,
184
- seed=3407,
185
- output_dir="outputs",
186
- report_to="none",
187
- ),
188
- )
189
 
190
- #@title 学習実行
191
- trainer_stats = trainer.train()
192
-
193
- import json
194
- from datasets import load_dataset
195
-
196
- dataset = load_dataset("json", data_files="/content/elyza-tasks-100-TV_0.jsonl", split="train")
197
-
198
- datasets = []
199
- with open("/content/elyza-tasks-100-TV_0.jsonl", "r", encoding="utf-8") 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
 
208
- from tqdm import tqdm
209
- import json
210
-
211
- # 推論するためにモデルのモードを変更
212
  FastLanguageModel.for_inference(model)
213
 
214
  results = []
215
  for dt in tqdm(datasets):
216
- try:
217
- input_text = dt["input"]
218
-
219
- # プロンプトを生成
220
- prompt = f"### 指示\n{input_text}\n次の要件を満たしてください:\n1. 簡潔に回答する。\n2. 必要なら箇条書きを使用して要点を整理する。\n3. 指示された内容に忠実に答える。\n### 回答\n"
221
-
222
 
223
- # トークナイズ
224
- inputs = tokenizer([prompt], return_tensors="pt").to(model.device)
225
 
226
- # 推論
227
- outputs = model.generate(
228
- **inputs,
229
- max_new_tokens=512,
230
- use_cache=True,
231
- do_sample=False,
232
- repetition_penalty=1.2,
233
- )
234
- prediction = tokenizer.decode(outputs[0], skip_special_tokens=True).split('\n### 回答')[-1]
235
 
236
- # 結果を保存
237
- results.append({"task_id": dt["task_id"], "input": input_text, "output": prediction})
238
- except Exception as e:
239
- print(f"Error processing task_id {dt.get('task_id', 'Unknown')}: {e}")
240
- results.append({"task_id": dt.get("task_id", "Unknown"), "input": dt.get("input", ""), "output": "Error"})
 
 
 
241
 
 
242
 
243
- # 結果をJSONL形式で保存
244
- output_file_jsonl = "/content/llm-jp-3-13b-last.jsonl"
245
- with open(output_file_jsonl, "w", encoding="utf-8") as f:
246
  for result in results:
247
- f.write(json.dumps(result, ensure_ascii=False) + "\n")
248
-
249
- model.push_to_hub_merged(
250
- new_model_id,
251
- tokenizer=tokenizer,
252
- save_method="lora",
253
- token=HF_TOKEN,
254
- private=True
255
- )
 
6
  - unsloth
7
  - llama
8
  - trl
 
9
  language:
10
  - en
11
  - ja
 
23
 
24
  # 推論用コード
25
  # Hugging Faceにアップロードしたモデルを用いてELYZA-tasks-100-TVの出力を得るためのコードです。 このコードで生成されたjsonlファイルは課題の成果として提出可能なフォーマットになっております。
26
+ # セットアップ
27
+ !pip install unsloth
28
+ !pip uninstall unsloth -y && pip install --upgrade --no-cache-dir "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
29
+ !pip install -U torch
30
+ !pip install -U peft
31
 
32
+ # モデル・トークナイザの読み込み
 
 
 
 
 
 
 
 
 
 
33
  from unsloth import FastLanguageModel
34
+ from peft import PeftModel
35
  import torch
36
+ import json
37
+ from tqdm import tqdm
38
+ import re
 
39
 
40
  model_id = "llm-jp/llm-jp-3-13b"
41
+ adapter_id = "Gamoooo/llm-jp-3-13b-last"
42
+
43
+ HF_TOKEN = "your-token" #@param {type:"string"}
44
+
45
+ dtype = None
46
+ load_in_4bit = True
47
 
48
  model, tokenizer = FastLanguageModel.from_pretrained(
49
  model_name=model_id,
 
52
  trust_remote_code=True,
53
  )
54
 
55
+ model = PeftModel.from_pretrained(model, adapter_id, token = HF_TOKEN)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
+ # 入力データの準備
58
+ datasets = []
59
+ with open("./elyza-tasks-100-TV_0.jsonl", "r") as f:
 
 
 
 
 
 
 
60
  item = ""
61
  for line in f:
62
+ line = line.strip()
63
+ item += line
64
+ if item.endswith("}"):
65
+ datasets.append(json.loads(item))
66
+ item = ""
67
 
68
+ # 推論実行
 
 
 
69
  FastLanguageModel.for_inference(model)
70
 
71
  results = []
72
  for dt in tqdm(datasets):
73
+ input = dt["input"]
 
 
 
 
 
74
 
75
+ prompt = f"### 指示\n{input}\n次の要件を満たしてください:\n1. 簡潔に回答する。\n2. 必要なら箇条書きを使用して要点を整理する。\n3. 指示された内容に忠実に答える。\n### 回答\n"
 
76
 
77
+ inputs = tokenizer([prompt], return_tensors="pt").to(model.device)
 
 
 
 
 
 
 
 
78
 
79
+ outputs = model.generate(
80
+ **inputs,
81
+ max_new_tokens=512,
82
+ use_cache=True,
83
+ do_sample=False,
84
+ repetition_penalty=1.2,
85
+ )
86
+ prediction = tokenizer.decode(outputs[0], skip_special_tokens=True).split('\n### 回答')[-1]
87
 
88
+ results.append({"task_id": dt["task_id"], "input": input, "output": prediction})
89
 
90
+ # 出力の保存
91
+ json_file_id = re.sub(".*/", "", adapter_id)
92
+ with open(f"/content/{json_file_id}_output.jsonl", 'w', encoding='utf-8') as f:
93
  for result in results:
94
+ json.dump(result, f, ensure_ascii=False)
95
+ f.write('\n')