Views
No views yet
1
2# 必要物のインストール
3!pip uninstall unsloth -y
4!pip install --upgrade --no-cache-dir "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
5!pip install --upgrade torch
6!pip install --upgrade xformers
7
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# Hugging Face Token を指定
13# Write権限を付与。
14HF_TOKEN = "hogehoge" #@param {type:"string"}
15
16# llm-jp/llm-jp-3-13bを4bit量子化のqLoRA設定でロード。
17
18from unsloth import FastLanguageModel
19import torch
20max_seq_length = 512
21dtype = None
22load_in_4bit = True
23
24model_id = "llm-jp/llm-jp-3-13b"
25new_model_id = "llm-jp-3-13b-it"
26model, tokenizer = FastLanguageModel.from_pretrained(
27 model_name=model_id,
28 dtype=dtype,
29 load_in_4bit=load_in_4bit,
30 trust_remote_code=True,
31)
32
33# SFT用のモデルを用意
34model = FastLanguageModel.get_peft_model(
35 model,
36 r = 32,
37 target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
38 "gate_proj", "up_proj", "down_proj",],
39 lora_alpha = 32,
40 lora_dropout = 0.05,
41 bias = "none",
42 use_gradient_checkpointing = "unsloth",
43 random_state = 3407,
44 use_rslora = False,
45 loftq_config = None,
46 max_seq_length = max_seq_length,
47)
48
49# 学習に用いるデータセットの指定
50from datasets import load_dataset
51dataset = load_dataset("json", data_files="ichikara-instruction-003-001-2.1.json")
52
53# 学習時のプロンプトフォーマットの定義
54prompt = """### 指示
55{}
56### 回答
57{}"""
58
59
60EOS_TOKEN = tokenizer.eos_token # トークナイザーのEOSトークン(文末トークン)
61def formatting_prompts_func(examples):
62 input = examples["text"] # 入力データ
63 output = examples["output"] # 出力データ
64 text = prompt.format(input, output) + EOS_TOKEN # プロンプトの作成
65 return { "formatted_text" : text, } # 新しいフィールド "formatted_text" を返す
66pass
67
68dataset = dataset.map(
69 formatting_prompts_func,
70 num_proc= 4, # 並列処理数を指定
71)
72
73dataset
74
75# データを確認
76print(dataset["train"]["formatted_text"][3])
77
78from trl import SFTTrainer
79from transformers import TrainingArguments
80from unsloth import is_bfloat16_supported
81
82trainer = SFTTrainer(
83 model = model,
84 tokenizer = tokenizer,
85 train_dataset=dataset["train"],
86 max_seq_length = max_seq_length,
87 dataset_text_field="formatted_text",
88 packing = False,
89 args = TrainingArguments(
90 per_device_train_batch_size = 2,
91 gradient_accumulation_steps = 4,
92 num_train_epochs = 1,
93 logging_steps = 10,
94 warmup_steps = 10,
95 save_steps=100,
96 save_total_limit=2,
97 max_steps=-1,
98 learning_rate = 2e-4,
99 fp16 = not is_bfloat16_supported(),
100 bf16 = is_bfloat16_supported(),
101 group_by_length=True,
102 seed = 3407,
103 output_dir = "outputs",
104 report_to = "none",
105 ),
106)
107
108# 現在のメモリ使用量を表示
109gpu_stats = torch.cuda.get_device_properties(0)
110start_gpu_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)
111max_memory = round(gpu_stats.total_memory / 1024 / 1024 / 1024, 3)
112print(f"GPU = {gpu_stats.name}. Max memory = {max_memory} GB.")
113print(f"{start_gpu_memory} GB of memory reserved.")
114
115# 学習実行
116trainer_stats = trainer.train()
117
118# データセットの読み込み。
119import json
120datasets = []
121with open("/content//elyza-tasks-100-TV_0.jsonl", "r") as f:
122 item = ""
123 for line in f:
124 line = line.strip()
125 item += line
126 if item.endswith("}"):
127 datasets.append(json.loads(item))
128 item = ""
129
130# 学習したモデルを用いてタスクを実行
131from tqdm import tqdm
132
133# 推論するためにモデルのモードを変更
134FastLanguageModel.for_inference(model)
135
136results = []
137for dt in tqdm(datasets):
138 input = dt["input"]
139
140 prompt = f"""### 指示\n{input}\n### 回答\n"""
141
142 inputs = tokenizer([prompt], return_tensors = "pt").to(model.device)
143
144 outputs = model.generate(**inputs, max_new_tokens = 512, use_cache = True, do_sample=False, repetition_penalty=1.2)
145 prediction = tokenizer.decode(outputs[0], skip_special_tokens=True).split('\n### 回答')[-1]
146
147 results.append({"task_id": dt["task_id"], "input": input, "output": prediction})
148
149# jsonlで保存
150with open(f"{new_model_id}_output.jsonl", 'w', encoding='utf-8') as f:
151 for result in results:
152 json.dump(result, f, ensure_ascii=False)
153 f.write('\n')
154
155# LoRAアダプタだけ保存
156model.push_to_hub_merged(
157 new_model_id+"_lora",
158 tokenizer=tokenizer,
159 save_method="lora",
160 token=HF_TOKEN,
161 private=True
162)
163