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