Posted on 2025/10/12, 10:46 AM By admin22
Unslothをつかったファインチューニングをためしてみました。

ファインチューニングといえば、かなり重いイメージがありましたが、このライブラリをつかうことで16GBのGPUメモリで数分で終わりました。データ数がすくなくモデルも軽いという点もありますが、いい実験になります。
データがすくないので、過学習になってしまいますが、学習効果を確認できることは、気持ちいいです。
学習
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70  | 
						# Unsloth + Hugging Face + QLoRA で知識注入 import torch from unsloth import FastLanguageModel from datasets import load_dataset from trl import SFTTrainer, SFTConfig # ① ベースモデルをロード model, tokenizer = FastLanguageModel.from_pretrained(     "meta-llama/Meta-Llama-3-8B-Instruct",     load_in_4bit=True,  # QLoRA用:4bit量子化     max_seq_length=2048, ) # ② データセットをロード dataset = load_dataset("json", data_files="new_knowledge.json", split="train") # データセットをフォーマット(テキストフィールドを追加) def format_dataset(example):     # Llama 3のチャット形式を使用     text = f"<|begin_of_text|><|start_header_id|>user<|end_header_id|>\n\n{example['instruction']}<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n{example['output']}<|eot_id|>"     return {"text": text} dataset = dataset.map(format_dataset, remove_columns=dataset.column_names) # ③ LoRA アダプタを作成 model = FastLanguageModel.get_peft_model(     model,     r=16,                        # rank を増やして学習能力向上     target_modules=["q_proj", "k_proj", "v_proj", "o_proj",                     "gate_proj", "up_proj", "down_proj"],  # 全ての線形層を対象     lora_alpha=16,     lora_dropout=0,     bias="none",     use_gradient_checkpointing="unsloth", ) # ④ ファインチューニング trainer = SFTTrainer(     model=model,     tokenizer=tokenizer,     train_dataset=dataset,     dataset_text_field="text",     max_seq_length=2048,     args=SFTConfig(         per_device_train_batch_size=1,  # バッチサイズを小さく         gradient_accumulation_steps=4,         warmup_steps=10,         num_train_epochs=20,  # 小さいデータセットなのでエポックを増やす         max_steps=60,  # 最大ステップ数を制限         learning_rate=5e-4,  # 学習率を上げて強く学習         fp16=not torch.cuda.is_bf16_supported(),         bf16=torch.cuda.is_bf16_supported(),         logging_steps=1,         optim="adamw_8bit",         weight_decay=0.001,  # weight decayを下げる         lr_scheduler_type="linear",         seed=3407,         output_dir="outputs",         save_strategy="steps",         save_steps=20,         save_total_limit=3,         load_best_model_at_end=False,     ), ) trainer.train() # ⑤ 保存 model.save_pretrained("llama3-x1000-lora") tokenizer.save_pretrained("llama3-x1000-lora")  | 
					
推論
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69  | 
						# Unsloth LoRA チャットボット推論プログラム import torch from unsloth import FastLanguageModel # ① モデルとLoRAアダプタをロード model, tokenizer = FastLanguageModel.from_pretrained(     model_name="llama3-x1000-lora",  # 学習済みLoRAアダプタのパス     max_seq_length=2048,     load_in_4bit=True, ) # 推論モードに設定 FastLanguageModel.for_inference(model) # ② チャット関数 def chat(instruction):     # Llama 3のチャット形式でプロンプトをフォーマット     prompt = f"<|begin_of_text|><|start_header_id|>user<|end_header_id|>\n\n{instruction}<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n"     # トークナイズ     inputs = tokenizer([prompt], return_tensors="pt").to("cuda")     input_length = inputs.input_ids.shape[1]     # 生成     outputs = model.generate(         **inputs,         max_new_tokens=256,         temperature=0.3,  # 温度を下げて正確性向上         top_p=0.9,         do_sample=True,         repetition_penalty=1.15,         use_cache=True,         eos_token_id=tokenizer.eos_token_id,     )     # 入力部分を除いて新しく生成された部分のみデコード     generated_ids = outputs[0][input_length:]     response = tokenizer.decode(generated_ids, skip_special_tokens=True)     return response.strip() # ③ 対話ループ def main():     print("=" * 50)     print("Unsloth LoRA チャットボット")     print("=" * 50)     print("終了するには 'exit' または 'quit' を入力してください")     print()     while True:         # ユーザー入力         user_input = input("あなた: ").strip()         # 終了チェック         if user_input.lower() in ['exit', 'quit', '終了']:             print("チャットボットを終了します。")             break         if not user_input:             continue         # 推論実行         print("AI: ", end="", flush=True)         response = chat(user_input)         print(response)         print() if __name__ == "__main__":     main()  | 
					
 Categories: 未分類 
	
	

