Views
No views yet
1!pip uninstall unsloth -y
2!pip install --upgrade --no-cache-dir "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
3!pip install --upgrade torch
4!pip install --upgrade xformers
5
6# Install Flash Attention 2 for softcapping support
7import torch
8if torch.cuda.get_device_capability()[0] >= 8:
9 !pip install --no-deps packaging ninja einops "flash-attn>=2.6.3"
10
11# Hugging Face Token を指定
12HF_TOKEN = "your-token" #@param {type:"string"}
13
14# llm-jp/llm-jp-3-13bを4bit量子化のqLoRA設定でロード。
15
16from unsloth import FastLanguageModel
17import torch
18max_seq_length = 1024 # unslothではRoPEをサポートしているのでコンテキスト長は自由に設定可能
19dtype = None # Noneにしておけば自動で設定
20load_in_4bit = True # 今回は13Bモデルを扱うためTrue
21
22model_id = "llm-jp/llm-jp-3-13b"
23new_model_id = "llm-jp-3-13b-it" #Fine-Tuningしたモデルにつけたい名前、it: Instruction Tuning
24# FastLanguageModel インスタンスを作成
25model, tokenizer = FastLanguageModel.from_pretrained(
26 model_name=model_id,
27 dtype=dtype,
28 load_in_4bit=load_in_4bit,
29 trust_remote_code=True,
30)
31
32# SFT用のモデルを用意
33model = FastLanguageModel.get_peft_model(
34 model,
35 r = 32,
36 target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
37 "gate_proj", "up_proj", "down_proj",],
38 lora_alpha = 32,
39 lora_dropout = 0.05,
40 bias = "none",
41 use_gradient_checkpointing = "unsloth",
42 random_state = 3407,
43 use_rslora = False,
44 loftq_config = None,
45 max_seq_length = max_seq_length,
46)
47
48# 学習に用いるデータセットの指定
49# CC-BY-NC-SAですのでモデルはライセンスを継承する前提でお使いください。
50# https://liat-aip.sakura.ne.jp/wp/llmのための日本語インストラクションデータ作成/llmのための日本語インストラクションデータ-公開/
51# 関根聡, 安藤まや, 後藤美知子, 鈴木久美, 河原大輔, 井之上直也, 乾健太郎. ichikara-instruction: LLMのための日本語インストラクションデータの構築. 言語処理学会第30回年次大会(2024)
52
53from datasets import load_dataset
54
55dataset = load_dataset("json", data_files="/content/ichikara-instruction-003-001-1.json")
56
57# 学習時のプロンプトフォーマットの定義
58prompt = """### 指示
59{}
60### 回答
61{}"""
62
63
64"""
65formatting_prompts_func: 各データをプロンプトに合わせた形式に合わせる
66"""
67EOS_TOKEN = tokenizer.eos_token # トークナイザーのEOSトークン(文末トークン)
68def formatting_prompts_func(examples):
69 input = examples["text"] # 入力データ
70 output = examples["output"] # 出力データ
71 text = prompt.format(input, output) + EOS_TOKEN # プロンプトの作成
72 return { "formatted_text" : text, } # 新しいフィールド "formatted_text" を返す
73pass
74
75# # 各データにフォーマットを適用
76dataset = dataset.map(
77 formatting_prompts_func,
78 num_proc= 4, # 並列処理数を指定
79)
80
81dataset
82
83
84# training_arguments: 学習の設定
85from trl import SFTTrainer
86from transformers import TrainingArguments
87from unsloth import is_bfloat16_supported
88
89trainer = SFTTrainer(
90 model = model,
91 tokenizer = tokenizer,
92 train_dataset=dataset["train"],
93 max_seq_length = max_seq_length,
94 dataset_text_field="formatted_text",
95 packing = False,
96 args = TrainingArguments(
97 per_device_train_batch_size = 2,
98 gradient_accumulation_steps = 4,
99 num_train_epochs = 1,
100 logging_steps = 10,
101 warmup_steps = 10,
102 save_steps=100,
103 save_total_limit=2,
104 max_steps=-1,
105 learning_rate = 2e-4,
106 fp16 = not is_bfloat16_supported(),
107 bf16 = is_bfloat16_supported(),
108 group_by_length=True,
109 seed = 3407,
110 output_dir = "outputs",
111 report_to = "none",
112 ),
113)
114
115
116#@title 学習実行
117trainer_stats = trainer.train()
118
119
120# データセットの読み込み。
121import json
122datasets = []
123with open("/content//elyza-tasks-100-TV_0.jsonl", "r") as f:
124 item = ""
125 for line in f:
126 line = line.strip()
127 item += line
128 if item.endswith("}"):
129 datasets.append(json.loads(item))
130 item = ""
131
132
133# 学習したモデルを用いてタスクを実行
134from tqdm import tqdm
135
136# 推論するためにモデルのモードを変更
137FastLanguageModel.for_inference(model)
138
139results = []
140for dt in tqdm(datasets):
141 input = dt["input"]
142
143 prompt = f"""### 指示\n{input}\n### 回答\n"""
144
145 inputs = tokenizer([prompt], return_tensors = "pt").to(model.device)
146
147 outputs = model.generate(**inputs, max_new_tokens = 1024, use_cache = True, do_sample=False, repetition_penalty=1.2)
148 prediction = tokenizer.decode(outputs[0], skip_special_tokens=True).split('\n### 回答')[-1]
149
150 results.append({"task_id": dt["task_id"], "input": input, "output": prediction})
151
152
153# jsonlで保存
154with open(f"{new_model_id}_output.jsonl", 'w', encoding='utf-8') as f:
155 for result in results:
156 json.dump(result, f, ensure_ascii=False)
157 f.write('\n')
158
159
160# LoRAアダプタだけ保存
161new_model_id = "WatariNAKANO/llm-jp-3-13b-it-2" #Fine-Tuningしたモデルにつけたい名前
162model.push_to_hub_merged(
163 new_model_id+"_lora",
164 tokenizer=tokenizer,
165 save_method="lora",
166 token=HF_TOKEN,
167 private=True
168)
169