Uploaded model
- Developed by: daichira
- License: cc-by-nc-4.0
- Finetuned from model : llm-jp/llm-jp-3-13b
This llama model was trained 2x faster with Unsloth and Huggingface's TRL library.
README.md
llm-jp-3-13b-itnew9
概要
このプロジェクトは、Hugging Face上で提供される言語モデルllm-jp/llm-jp-3-13b
を基盤とし、さらなる指示応答タスク向けに微調整(SFT: Supervised Fine-Tuning)を施した'daichira/llm-jp-3-13b-finetune2'から、さらに後述のコードによりSFTを施したモデルllm-jp-3-13b-itnew9
を公開するものです。このREADMEは、モデルのセットアップ、トレーニング、推論の再現性を確保するための手順を示します。
前提条件
このプロジェクトを実行するには、以下の環境とツールが必要です:
- Python 3.8以上
- Google Colabまたはローカル環境 (GPU推奨)
- Hugging Faceアクセストークン (HF_TOKEN)
セットアップ手順
1. ライブラリのインストール
Google Colabの場合、以下のコマンドを使用して必要なライブラリをインストールします:
!pip uninstall unsloth -y && pip install --upgrade --no-cache-dir "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
!pip install --upgrade torch
!pip install --upgrade xformers
!pip install ipywidgets --upgrade
Flash Attention 2をサポートするために、以下をインストールします:
import torch
if torch.cuda.get_device_capability()[0] >= 8:
!pip install --no-deps packaging ninja einops "flash-attn>=2.6.3"
2. モデルとトークナイザーのロード
以下のコードを使用して、Hugging Faceからベースモデルをロードし、LoRAの設定を適用します:
from transformers import AutoModelForCausalLM, AutoTokenizer
from unsloth import FastLanguageModel
max_seq_length = 1024
dtype = None
load_in_4bit = True
model_id = "daichira/llm-jp-3-13b-finetune2"
new_model_id = "llm-jp-3-13b-itnew9"
model, tokenizer = FastLanguageModel.from_pretrained(
model_name=model_id,
dtype=dtype,
load_in_4bit=load_in_4bit,
trust_remote_code=True,
)
model = FastLanguageModel.get_peft_model(
model,
r=32,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],
lora_alpha=32,
lora_dropout=0.05,
bias="none",
use_gradient_checkpointing="unsloth",
random_state=3407,
use_rslora=False,
loftq_config=None,
max_seq_length=max_seq_length,
)
データセットの準備
データの分割と保存
以下のコードでデータセットをHugging Faceからロードし、分割して保存します:
HF_TOKEN = "Your_token" # Write権限
!pip install datasets
import os
from datasets import load_dataset
dataset = load_dataset("DeL-TaiseiOzaki/Tengentoppa-sft-v1.0", split="train")
chunk_size = 30000
output_dir = "/content/tengentoppa_chunks"
os.makedirs(output_dir, exist_ok=True)
total_rows = len(dataset)
num_chunks = (total_rows + chunk_size - 1) // chunk_size
for i in range(num_chunks):
start_idx = i * chunk_size
end_idx = min(start_idx + chunk_size, total_rows)
chunk = dataset.select(range(start_idx, end_idx))
chunk_file = f"{output_dir}/tengentoppa_chunk_{i+1}.json"
chunk.to_json(chunk_file)
print(f"Saved chunk {i+1}/{num_chunks} to {chunk_file}")
print("All chunks have been saved!")
JSON形式でのデータセット読み込み
以下のコードでJSONデータセットをロードします:
json_path = "/content/tengentoppa_chunks/tengentoppa_chunk_3.json"
dataset = load_dataset("json", data_files=json_path)
print(dataset)
トレーニングの設定
以下の手順でトレーニングを設定します:
prompt = """### 指示
{}
### 回答
{}"""
EOS_TOKEN = tokenizer.eos_token
def formatting_prompts_func(examples):
input_text = examples["instruction"]
output_text = examples["output"]
return {"formatted_text": prompt.format(input_text, output_text) + EOS_TOKEN}
dataset = dataset.map(formatting_prompts_func, num_proc=4)
from trl import SFTTrainer
from transformers import TrainingArguments
from unsloth import is_bfloat16_supported
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=dataset["train"],
max_seq_length=max_seq_length,
dataset_text_field="formatted_text",
args=TrainingArguments(
per_device_train_batch_size=6,
gradient_accumulation_steps=4,
num_train_epochs=1,
logging_steps=50,
warmup_steps=500,
save_steps=500,
save_total_limit=2,
learning_rate=3e-4,
fp16=not is_bfloat16_supported(),
bf16=is_bfloat16_supported(),
group_by_length=True,
seed=3407,
output_dir="outputs",
),
)
# 学習実行
torch.cuda.empty_cache()
trainer.train()
推論
以下のコードでトレーニング済みモデルを使用して推論を行います:
import json
from tqdm import tqdm
with open("/content/elyza-tasks-100-TV_0.jsonl", "r") as f:
datasets = [json.loads(line) for line in f if line.strip().endswith("}")]
FastLanguageModel.for_inference(model)
results = []
for dt in tqdm(datasets):
input_text = dt["input"]
prompt = f"### 指示\n{input_text}\n### 回答\n"
inputs = tokenizer([prompt], return_tensors="pt").to(model.device)
outputs = model.generate(**inputs, max_new_tokens=512, use_cache=True, do_sample=False, repetition_penalty=1.2)
prediction = tokenizer.decode(outputs[0], skip_special_tokens=True).split('\n### 回答')[-1]
results.append({"task_id": dt["task_id"], "input": input_text, "output": prediction})
with open(f"{new_model_id}_output.jsonl", 'w', encoding='utf-8') as f:
for result in results:
json.dump(result, f, ensure_ascii=False)
f.write('\n')
注意事項
- 本モデルは日本語専用で設計されています。
- 再現性を確保するため、ランダムシードを固定しています (
seed=3407
)。 - モデルのパラメータ量が大きいため、十分なGPUメモリを確保してください (推奨: 16GB以上)。
実行コード全体
# 必要なライブラリのインストール
!pip uninstall unsloth -y && pip install --upgrade --no-cache-dir "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
!pip install --upgrade torch
!pip install --upgrade xformers
!pip install ipywidgets --upgrade
# Flash Attention 2のインストール
import torch
if torch.cuda.get_device_capability()[0] >= 8:
!pip install --no-deps packaging ninja einops "flash-attn>=2.6.3"
# モデルとトークナイザーのロード
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from unsloth import FastLanguageModel
# モデル設定
max_seq_length = 1024
dtype = None
load_in_4bit = True
model_id = "daichira/llm-jp-3-13b-finetune2"
new_model_id = "llm-jp-3-13b-itnew9"
model, tokenizer = FastLanguageModel.from_pretrained(
model_name=model_id,
dtype=dtype,
load_in_4bit=load_in_4bit,
trust_remote_code=True,
)
# SFT用のモデル設定
model = FastLanguageModel.get_peft_model(
model,
r=32,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],
lora_alpha=32,
lora_dropout=0.05,
bias="none",
use_gradient_checkpointing="unsloth",
random_state=3407,
use_rslora=False,
loftq_config=None,
max_seq_length=max_seq_length,
)
# Hugging Faceのトークン設定
HF_TOKEN = "your_token"
# データセットの準備
!pip install datasets
import os
from datasets import load_dataset
dataset = load_dataset("DeL-TaiseiOzaki/Tengentoppa-sft-v1.0", split="train")
chunk_size = 30000
output_dir = "/content/tengentoppa_chunks"
os.makedirs(output_dir, exist_ok=True)
total_rows = len(dataset)
num_chunks = (total_rows + chunk_size - 1) // chunk_size
for i in range(num_chunks):
start_idx = i * chunk_size
end_idx = min(start_idx + chunk_size, total_rows)
chunk = dataset.select(range(start_idx, end_idx))
chunk_file = f"{output_dir}/tengentoppa_chunk_{i+1}.json"
chunk.to_json(chunk_file)
print(f"Saved chunk {i+1}/{num_chunks} to {chunk_file}")
print("All chunks have been saved!")
# JSON形式のデータセットをロード
json_path = "/content/tengentoppa_chunks/tengentoppa_chunk_3.json"
dataset = load_dataset("json", data_files=json_path)
print(dataset)
# プロンプトフォーマットの適用
prompt = """### 指示
{}
### 回答
{}"""
EOS_TOKEN = tokenizer.eos_token
def formatting_prompts_func(examples):
input_text = examples["instruction"]
output_text = examples["output"]
return {"formatted_text": prompt.format(input_text, output_text) + EOS_TOKEN}
dataset = dataset.map(formatting_prompts_func, num_proc=4)
# トレーニングの設定
from trl import SFTTrainer
from transformers import TrainingArguments
from unsloth import is_bfloat16_supported
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=dataset["train"],
max_seq_length=max_seq_length,
dataset_text_field="formatted_text",
args=TrainingArguments(
per_device_train_batch_size=6,
gradient_accumulation_steps=4,
num_train_epochs=1,
logging_steps=50,
warmup_steps=500,
save_steps=500,
save_total_limit=2,
learning_rate=3e-4,
fp16=not is_bfloat16_supported(),
bf16=is_bfloat16_supported(),
group_by_length=True,
seed=3407,
output_dir="outputs",
),
)
# 学習実行
torch.cuda.empty_cache()
trainer.train()
# 推論の準備
import json
from tqdm import tqdm
with open("/content/elyza-tasks-100-TV_0.jsonl", "r") as f:
datasets = [json.loads(line) for line in f if line.strip().endswith("}")]
FastLanguageModel.for_inference(model)
results = []
for dt in tqdm(datasets):
input_text = dt["input"]
prompt = f"""### 指示\n{input_text}\n### 回答\n"""
inputs = tokenizer([prompt], return_tensors="pt").to(model.device)
outputs = model.generate(**inputs, max_new_tokens=512, use_cache=True, do_sample=False, repetition_penalty=1.2)
prediction = tokenizer.decode(outputs[0], skip_special_tokens=True).split('\n### 回答')[-1]
results.append({"task_id": dt["task_id"], "input": input_text, "output": prediction})
# 推論結果の保存
with open(f"{new_model_id}_output.jsonl", 'w', encoding='utf-8') as f:
for result in results:
json.dump(result, f, ensure_ascii=False)
f.write('\n')
Model tree for daichira/llm-jp-3-13b-itnew9
Base model
llm-jp/llm-jp-3-13b