Views
No views yet
1# Google Colabの場合はunslothのインストールのみを行ってください
2!pip uninstall unsloth -y
3!pip install --upgrade --no-cache-dir "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
4!pip install --upgrade torch
5!pip install --upgrade xformers
6
7# Install Flash Attention 2 for softcapping support
8import torch
9if torch.cuda.get_device_capability()[0] >= 8:
10 !pip install --no-deps packaging ninja einops "flash-attn>=2.6.3"
11
12# Settings for HuggingFace
13from google.colab import userdata
14from huggingface_hub import login
15
16HF_TOKEN=userdata.get('HF_TOKEN')
17login(token=HF_TOKEN)
18print(login)
19
20#@title 現在のメモリ使用量を表示
21gpu_stats = torch.cuda.get_device_properties(0)
22start_gpu_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)
23max_memory = round(gpu_stats.total_memory / 1024 / 1024 / 1024, 3)
24print(f"GPU = {gpu_stats.name}. Max memory = {max_memory} GB.")
25print(f"{start_gpu_memory} GB of memory reserved.")
26
27# Load a model
28from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
29from unsloth import FastLanguageModel
30import torch
31
32# Settings
33max_seq_length = 2048
34dtype = None
35load_in_4bit = True
36model_id = "llm-jp/llm-jp-3-13b"
37
38# FastLanguageModel インスタンスを作成
39model, tokenizer = FastLanguageModel.from_pretrained(
40 model_name=model_id,
41 dtype=dtype,
42 load_in_4bit=load_in_4bit,
43 trust_remote_code=True,
44)
45
46# SFT用のモデルを用意
47model = FastLanguageModel.get_peft_model(
48 model,
49 r = 32,
50 target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
51 "gate_proj", "up_proj", "down_proj",],
52 lora_alpha = 32,
53 lora_dropout = 0.05,
54 bias = "none",
55 use_gradient_checkpointing = "unsloth",
56 random_state = 3407,
57 use_rslora = False,
58 loftq_config = None,
59 max_seq_length = max_seq_length,
60)
61
62#@title 現在のメモリ使用量を表示
63gpu_stats = torch.cuda.get_device_properties(0)
64start_gpu_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)
65max_memory = round(gpu_stats.total_memory / 1024 / 1024 / 1024, 3)
66print(f"GPU = {gpu_stats.name}. Max memory = {max_memory} GB.")
67print(f"{start_gpu_memory} GB of memory reserved.")
68
69
70"""
71dataset: 学習に用いるデータセット
72
73 ベースコードでは以下のリンクからデータをダウンロードして使います。zipを展開(!unzip)してデータのパスを指定してください。
74 (https://liat-aip.sakura.ne.jp/wp/llmのための日本語インストラクションデータ作成/llmのための日本語インストラクションデータ-公開/)
75 関根聡, 安藤まや, 後藤美知子, 鈴木久美, 河原大輔, 井之上直也, 乾健太郎.
76 ichikara-instruction: LLMのための日本語インストラクションデータの構築. 言語処理学会第30回年次大会(2024)
77
78omnicampusの開発環境では取得したデータを左側にドラッグアンドドロップしてお使いください。
79"""
80from datasets import load_dataset
81
82dataset = load_dataset("json", data_files="./dataset/ichikara-instruction-003-001-1.json")
83dataset
84
85# 学習時のプロンプトフォーマットの定義
86prompt = """### 指示
87{}
88### 回答
89{}"""
90
91
92
93"""
94formatting_prompts_func: 各データをプロンプトに合わせた形式に合わせる
95"""
96EOS_TOKEN = tokenizer.eos_token # トークナイザーのEOSトークン(文末トークン)
97def formatting_prompts_func(examples):
98 input = examples["text"] # 入力データ
99 output = examples["output"] # 出力データ
100 text = prompt.format(input, output) + EOS_TOKEN # プロンプトの作成
101 return { "formatted_text" : text, } # 新しいフィールド "formatted_text" を返す
102pass
103
104# # 各データにフォーマットを適用
105dataset = dataset.map(
106 formatting_prompts_func,
107 num_proc= 4, # 並列処理数を指定
108)
109
110dataset
111
112# データを確認
113print(dataset["train"]["formatted_text"][3])
114
115from trl import SFTTrainer
116from transformers import TrainingArguments
117from unsloth import is_bfloat16_supported
118
119args = TrainingArguments(
120 # バッチとメモリの設定
121 per_device_train_batch_size=8,
122 gradient_accumulation_steps=4,
123
124 # 学習のスケジューリング
125 num_train_epochs=3,
126 learning_rate=2e-5,
127 warmup_steps=50,
128 max_steps=-1,
129
130 # シンプルなモニタリング設定
131 logging_steps=10,
132 logging_first_step=True,
133
134 # チェックポイント設定
135 save_steps=100,
136 save_total_limit=2,
137
138 # A100向け最適化
139 bf16=True,
140 gradient_checkpointing=True,
141
142 # 高速化設定
143 optim="adamw_torch_fused",
144 torch_compile=True,
145
146 # データローディング最適化
147 dataloader_num_workers=4,
148 dataloader_pin_memory=True,
149 group_by_length=True,
150
151 # その他の基本設定
152 seed=3407,
153 output_dir="outputs",
154 report_to="none",
155)
156
157trainer = SFTTrainer(
158 model = model,
159 tokenizer = tokenizer,
160 train_dataset=dataset["train"],
161 max_seq_length = max_seq_length,
162 dataset_text_field="formatted_text",
163 packing = False,
164 args = args,
165)
166
167#@title 学習実行
168trainer_stats = trainer.train()
169
170# ELYZA-tasks-100-TVの読み込み。事前にファイルをアップロードしてください
171# データセットの読み込み。
172# omnicampusの開発環境では、左にタスクのjsonlをドラッグアンドドロップしてから実行。
173import json
174datasets = []
175with open("./elyza-tasks-100-TV_0.jsonl", "r") as f:
176 item = ""
177 for line in f:
178 line = line.strip()
179 item += line
180 if item.endswith("}"):
181 datasets.append(json.loads(item))
182 item = ""
183
184def generate_prompt(input):
185 prompt = f"""### 指示\n{input}\n###制約- Please provide a thorough and detailed explanation.- You must address exactly the number of items requested - no more, no less.- Break down your thinking process step by step.- Please respond in Japanese.\n### 回答\n"""
186
187 return prompt
188
189# 学習したモデルを用いてタスクを実行
190from tqdm import tqdm
191
192# 推論するためにモデルのモードを変更
193FastLanguageModel.for_inference(model)
194
195results = []
196for dt in tqdm(datasets):
197 input = dt["input"]
198
199 prompt = generate_prompt(input)
200
201 inputs = tokenizer([prompt], return_tensors = "pt").to(model.device)
202
203 outputs = model.generate(**inputs, max_new_tokens = 512, use_cache = True, do_sample=False, repetition_penalty=1.2)
204 prediction = tokenizer.decode(outputs[0], skip_special_tokens=True).split('\n### 回答')[-1]
205
206 results.append({"task_id": dt["task_id"], "input": input, "output": prediction})
207
208new_model_id = "llm-jp-3-13b-finetune-20241126B"
209
210# jsonlで保存
211with open(f"{new_model_id}_output.jsonl", 'w', encoding='utf-8') as f:
212 for result in results:
213 json.dump(result, f, ensure_ascii=False)
214 f.write('\n')
215
216# csvでも保存
217import csv
218with open(f"{new_model_id}_output.csv", 'w', encoding='utf-8', newline='') as f:
219 writer = csv.writer(f)
220 # ヘッダーを書き込み
221 writer.writerow(['task_id', 'input', 'output'])
222 # データを書き込み
223 for result in results:
224 writer.writerow([
225 result['task_id'],
226 result['input'],
227 result['output']
228 ])
229
230# モデルとトークナイザーをHugging Faceにアップロード。
231# 一旦privateでアップロードしてください。
232# 最終成果物が決まったらpublicにするようお願いします。
233# 現在公開しているModel_Inference_Template.ipynbはunslothを想定していないためそのままでは動かない可能性があります。
234model.push_to_hub_merged(
235 new_model_id,
236 tokenizer=tokenizer,
237 save_method="lora",
238 token=HF_TOKEN,
239 private=True
240)
241
242# model.push_to_hub(new_model_id, token=HF_TOKEN, private=True) # Online saving
243# tokenizer.push_to_hub(new_model_id, token=HF_TOKEN) # Online saving
244