「.NET 開発基盤部会 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
LLMのファイン・チューニング(FT)は既存LLMを特定の用途や業界向けに最適化するための手法
FTは、以下のような場面で活用される。
場面 | 使途 |
カスタマーサポート | 自社独自のFAQや業界特有の表現に適応させる。 |
医療や法律分野 | 専門用語や規制対応の正確な知識を学習させる。 |
文書生成や翻訳 | 高精度な自然言語処理を必要とする場面。 |
主に以下の手法がある。
分類 | 種類 | 解説 |
フル・ファインチューニング | 全体調整型 | LLM全体を再学習させる方法。高いカスタマイズ性があるが、学習に大量のデータと計算リソースが必要。 |
軽量ファイン・チューニング | 表現調整型・パラメタ効率型 | 一部のパラメタや特定の層に限定して調整を加える方法。計算コストを抑えつつ高いカスタマイズ性を維持。 |
分類 | 手法 |
全体調整型 | Full Fine-Tuning |
部分調整型 | ReFT (Representation Fine-Tuning), Reward Fine-Tuning |
パラメタ効率型(PEFT: Parameter-Efficient Fine-Tuning) | LoRA, QLoRA, Adapter, Prefix Tuning, BitFit |
指示・強化学習型 | Instruction Tuning, RLHF(Reinforcement Learning from Human Feedback) |
モデルの全パラメタを特定のタスクやドメインに合わせて調整するプロセス
PEFT:Parameter-Efficient Fine-Tuning
モデルの内部(≒埋め込み層、隠れ層、アテンション機構)を報酬を使って微調整する。
LoRA:Low-Rank Adaptation(低ランク適応)
JSON: {"input": "ユーザーの質問", "output": "AIの回答"}
QLoRA:Quantized Low-Rank Adaptation
※ 余談だが、
LoRA:Low-Rank Adaptationの「スキップ接続された線形結合層」(Adapter)を追加(Adaptation)するような方法、全般。
BitFit?:Bias-only fine-tuning
指示に基づいてモデルを調整する教師あり学習(Supervised Fine-Tuning, SFT)
RLHF:Reinforcement Learning from Human Feedback
pip install torch transformers accelerate datasets peft trl
from transformers import AutoModelForCausalLM, AutoTokenizer from peft import prepare_model_for_kbit_training model_id = "microsoft/phi-3-mini-4k-instruct" tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained( model_id, device_map="auto", # or specific CUDA index trust_remote_code=True, torch_dtype="auto" )※「trust_remote_code=True」はHugging Faceの共通でないモデルのカスタムコードをダウンロード・実行する動作を許可するみたいなこと。
from peft import LoraConfig, get_peft_model model = prepare_model_for_kbit_training(model) # 量子化前提、しないなら不要 lora_config = LoraConfig( r=8, lora_alpha=16, target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "fc1", "fc2"], # Phi-3 に合わせて調整 lora_dropout=0.05, bias="none", task_type="CAUSAL_LM" ) model = get_peft_model(model, lora_config)
from datasets import load_dataset dataset = load_dataset("json", data_files={"train": "train.json"})
{"prompt": "What is the capital of France?", "response": "Paris"}
from trl import SFTTrainer from transformers import TrainingArguments training_args = TrainingArguments( output_dir="./phi3-lora", per_device_train_batch_size=4, gradient_accumulation_steps=4, num_train_epochs=3, logging_steps=10, save_strategy="epoch", learning_rate=2e-4, fp16=True, # or bf16=True if available ) trainer = SFTTrainer( model=model, args=training_args, train_dataset=dataset["train"], dataset_text_field="prompt", # 入力項目 tokenizer=tokenizer, max_seq_length=1024, packing=False, ) trainer.train()
model.save_pretrained("phi3-lora-ft") tokenizer.save_pretrained("phi3-lora-ft")
from transformers import pipeline pipe = pipeline("text-generation", model="phi3-lora-ft", tokenizer=tokenizer) print(pipe("Tell me about the sun:", max_new_tokens=100))
from peft import PeftModel base_model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-hf", device_map="auto") model = PeftModel.from_pretrained(base_model, "path/to/lora_adapter") merged_model = model.merge_and_unload() merged_model.save_pretrained("merged_model") tokenizer.save_pretrained("merged_model")
FROM llama2 # ファインチューニング済み GGUF を追加 PARAMETER_FILE ./llama-2-7b-q4.gguf
ollama create my-llama2-qa -f Modelfile
ollama run my-llama2-qa