Views
No views yet
1# llm-jp/llm-jp-3-13bを4bit量子化のqLoRA設定でロード。
2
3from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
4from unsloth import FastLanguageModel
5import torch
6max_seq_length = 512 # unslothではRoPEをサポートしているのでコンテキスト長は自由に設定可能
7dtype = None # Noneにしておけば自動で設定
8load_in_4bit = True # 今回は8Bクラスのモデルを扱うためTrue
9
10model_id = "llm-jp/llm-jp-3-13b"
11new_model_id = "llm-jp-3-13b-it" #Fine-Tuningしたモデルにつけたい名前、it: Instruction Tuning
12# FastLanguageModel インスタンスを作成
13model, tokenizer = FastLanguageModel.from_pretrained(
14 model_name=model_id,
15 dtype=dtype,
16 load_in_4bit=load_in_4bit,
17 trust_remote_code=True,
18)
19
20# SFT用のモデルを用意
21model = FastLanguageModel.get_peft_model(
22 model,
23 r = 32,
24 target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
25 "gate_proj", "up_proj", "down_proj",],
26 lora_alpha = 32,
27 lora_dropout = 0.05,
28 bias = "none",
29 use_gradient_checkpointing = "unsloth",
30 random_state = 3407,
31 use_rslora = False,
32 loftq_config = None,
33 max_seq_length = max_seq_length,
34)
35
36HF_TOKEN = "your_token"
37
38from datasets import load_dataset
39file_path = "your_file_path"
40dataset = load_dataset("json", data_files=file_path)
41
42# 学習時のプロンプトフォーマットの定義
43prompt = """### 指示
44{}
45### 回答
46{}"""
47
48
49
50"""
51formatting_prompts_func: 各データをプロンプトに合わせた形式に合わせる
52"""
53EOS_TOKEN = tokenizer.eos_token # トークナイザーのEOSトークン(文末トークン)
54def formatting_prompts_func(examples):
55 input = examples["text"] # 入力データ
56 output = examples["output"] # 出力データ
57 text = prompt.format(input, output) + EOS_TOKEN # プロンプトの作成
58 return { "formatted_text" : text, } # 新しいフィールド "formatted_text" を返す
59pass
60
61# # 各データにフォーマットを適用
62dataset = dataset.map(
63 formatting_prompts_func,
64 num_proc= 4, # 並列処理数を指定
65)
66
67dataset
68
69from trl import SFTTrainer
70from transformers import TrainingArguments
71from unsloth import is_bfloat16_supported
72
73trainer = SFTTrainer(
74 model = model,
75 tokenizer = tokenizer,
76 train_dataset=dataset["train"],
77 max_seq_length = max_seq_length,
78 dataset_text_field="formatted_text",
79 packing = False,
80 args = TrainingArguments(
81 per_device_train_batch_size = 2,
82 gradient_accumulation_steps = 4,
83 num_train_epochs = 1,
84 logging_steps = 10,
85 warmup_steps = 10,
86 save_steps=100,
87 save_total_limit=2,
88 max_steps=-1,
89 learning_rate = 2e-4,
90 fp16 = not is_bfloat16_supported(),
91 bf16 = is_bfloat16_supported(),
92 group_by_length=True,
93 seed = 3407,
94 output_dir = "outputs",
95 report_to = "none",
96 ),
97)
98
99#@title 学習実行
100trainer_stats = trainer.train()
101
102# ELYZA-tasks-100-TVの読み込み。事前にファイルをアップロードしてください
103# データセットの読み込み。
104# omnicampusの開発環境では、左にタスクのjsonlをドラッグアンドドロップしてから実行。
105import json
106datasets = []
107with open("/content/elyza-tasks-100-TV_0.jsonl", "r") as f:
108 item = ""
109 for line in f:
110 line = line.strip()
111 item += line
112 if item.endswith("}"):
113 datasets.append(json.loads(item))
114 item = ""
115
116# 学習したモデルを用いてタスクを実行
117from tqdm import tqdm
118
119# 推論するためにモデルのモードを変更
120FastLanguageModel.for_inference(model)
121
122results = []
123for dt in tqdm(datasets):
124 input = dt["input"]
125
126 prompt = f"""### 指示\n{input}\n### 回答\n"""
127
128 inputs = tokenizer([prompt], return_tensors = "pt").to(model.device)
129
130 outputs = model.generate(**inputs, max_new_tokens = 512, use_cache = True, do_sample=False, repetition_penalty=1.2)
131 prediction = tokenizer.decode(outputs[0], skip_special_tokens=True).split('\n### 回答')[-1]
132
133 results.append({"task_id": dt["task_id"], "input": input, "output": prediction})
134
135# jsonlで保存
136with open(f"{new_model_id}_output.jsonl", 'w', encoding='utf-8') as f:
137 for result in results:
138 json.dump(result, f, ensure_ascii=False)
139 f.write('\n')
1401# 必要なライブラリを読み込み
2from unsloth import FastLanguageModel
3from peft import PeftModel
4import torch
5import json
6from tqdm import tqdm
7import re
8
9# Hugging Faceで取得したTokenをこちらに貼る。
10HF_TOKEN = "Hugging Face Token"
11
12# ベースとなるモデルと学習したLoRAのアダプタ(Hugging FaceのIDを指定)。
13model_id = "llm-jp/llm-jp-3-13b"
14adapter_id = "choucho/llm-jp-3-13b-it"
15
16# QLoRA config
17bnb_config = BitsAndBytesConfig(
18 load_in_4bit=True,
19 bnb_4bit_quant_type="nf4",
20 bnb_4bit_compute_dtype=torch.bfloat16,
21)
22
23# Load model
24model = AutoModelForCausalLM.from_pretrained(
25 model_id,
26 quantization_config=bnb_config,
27 device_map="auto",
28 token = HF_TOKEN
29)
30
31# Load tokenizer
32tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True, token = HF_TOKEN)
33
34# 元のモデルにLoRAのアダプタを統合。
35model = PeftModel.from_pretrained(model, adapter_id, token = HF_TOKEN)
36
37# データセットの読み込み。
38# omnicampusの開発環境では、左にタスクのjsonlをドラッグアンドドロップしてから実行。
39datasets = []
40with open("./elyza-tasks-100-TV_0.jsonl", "r") as f:
41 item = ""
42 for line in f:
43 line = line.strip()
44 item += line
45 if item.endswith("}"):
46 datasets.append(json.loads(item))
47 item = ""
48
49# llmjp
50results = []
51for data in tqdm(datasets):
52
53 input = data["input"]
54
55 prompt = f"""### 指示
56 {input}
57 ### 回答
58 """
59
60 tokenized_input = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt").to(model.device)
61 attention_mask = torch.ones_like(tokenized_input)
62 with torch.no_grad():
63 outputs = model.generate(
64 tokenized_input,
65 attention_mask=attention_mask,
66 max_new_tokens=100,
67 do_sample=False,
68 repetition_penalty=1.2,
69 pad_token_id=tokenizer.eos_token_id
70 )[0]
71 output = tokenizer.decode(outputs[tokenized_input.size(1):], skip_special_tokens=True)
72
73 results.append({"task_id": data["task_id"], "input": input, "output": output})
74
75# output
76import re
77jsonl_id = re.sub(".*/", "", adapter_id)
78with open(f"./{jsonl_id}-outputs.jsonl", 'w', encoding='utf-8') as f:
79 for result in results:
80 json.dump(result, f, ensure_ascii=False) # ensure_ascii=False for handling non-ASCII characters
81 f.write('\n')