Model Card for Fine-Tuned LLM-JP-3-13B
Model Details
Model Description
This model is a Fine-Tuned Version of the llm-jp-3-13b
base model for Japanese text tasks. Fine-tuning was performed using the Ichikara Instruction Dataset for supervised instruction-following tasks. It enables the model to generate structured responses based on specific prompts.
- Developed by: Omnicampus User
- Model type: Causal Language Model (LoRA Fine-Tuning)
- Language(s) (NLP): Japanese
- License: CC-BY-NC-SA-4.0 (inherits from training data license)
- Finetuned from model:
llm-jp/llm-jp-3-13b
Model Sources
- Repository: Hugging Face Link
- Dataset: Ichikara Instruction Dataset
Uses
Direct Use
This model is designed for Japanese instruction-following tasks, such as:
- Summarization
- Question-answering
- Dialogue generation
Downstream Use
The model can be further fine-tuned for:
- Machine Translation
- Sentiment Analysis
- Task-Specific Question-Answering
Out-of-Scope Use
This model may not perform well on:
- Non-Japanese languages
- Highly technical or niche domains without additional fine-tuning
- Malicious or harmful content generation
Bias, Risks, and Limitations
While the model was fine-tuned on curated Japanese instruction data, biases in the training data may still persist:
- Potential biases related to Japanese cultural norms and values
- Limited performance on underrepresented topics or linguistic patterns
Recommendations
Users should evaluate the outputs, particularly for applications involving sensitive data or domains.
How to Get Started with the Model
Below is an example for generating predictions using the fine-tuned model:
from transformers import AutoTokenizer, AutoModelForCausalLM
model_id = "Hiro00099/llm-jp-3-13b-finetune"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id)
input_prompt = """### 指示
野球選手が今シーズン活躍するために取り組むべき5つのことを教えてください。
### 回答"""
input_ids = tokenizer(input_prompt, return_tensors="pt").input_ids
output_ids = model.generate(input_ids, max_new_tokens=100)
output = tokenizer.decode(output_ids[0], skip_special_tokens=True)
print(output)
# Sample Use
# コンペ用Fine-Tuningテンプレート
こちらは、コンペにてFineーTuningを行いたい方に向けたテンプレートとなるFine-tuningコードです。
こちらを実行いただくだけでコンペの基準に達することができると思います。上手く活用してコンペ上位を目指しましょう!!
本コードはOmnicampusで提供される演習環境での実行を想定しています。
それ以外の環境で実行される場合は適宜、修正して下さい。
# python 3.10.12
!pip install -U pip
!pip install -U transformers
!pip install -U bitsandbytes
!pip install -U accelerate
!pip install -U datasets
!pip install -U peft
!pip install -U trl
!pip install -U wandb
!pip install ipywidgets --upgrade
from transformers import (
AutoModelForCausalLM,
AutoTokenizer,
BitsAndBytesConfig,
TrainingArguments,
logging,
)
from peft import (
LoraConfig,
PeftModel,
get_peft_model,
)
import os, torch, gc
from datasets import load_dataset
import bitsandbytes as bnb
from trl import SFTTrainer
# Hugging Face Token
HF_TOKEN = "HFT"
# モデルを読み込み。
# llm-jp-3 1.8B, 3.7B, 13Bのsnapshotをダウンロード済みでmodelsディレクトリに格納してあります。
# base_model_idの値はomnicampusの環境におけるモデルのパスを表しており、それ以外の環境で実行する場合は変更の必要があります。
# その他のモデルは取得に承諾が必要なため、各自でダウンロードお願いします。
base_model_id = "models/models--llm-jp--llm-jp-3-13b/snapshots/cd3823f4c1fcbb0ad2e2af46036ab1b0ca13192a" #Fine-Tuningするベースモデル
# omnicampus以外の環境をご利用の方は以下をご利用ください。
# base_model_id = "llm-jp/llm-jp-3-13b"
new_model_id = "llm-jp-3-13b-finetune" #Fine-Tuningしたモデルにつけたい名前
"""
bnb_config: 量子化の設定
- load_in_4bit:
- 4bit量子化形式でモデルをロード
- bnb_4bit_quant_type:
- 量子化の形式を指定
- bnb_4bit_compute_dtype:
- 量子化された重みを用いて計算する際のデータ型
"""
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4", # nf4は通常のINT4より精度が高く、ニューラルネットワークの分布に最適です
bnb_4bit_compute_dtype=torch.bfloat16,
)
from huggingface_hub import login
login("HFT")
base_model_id = "llm-jp/llm-jp-3-13b"
from transformers import AutoModelForCausalLM, BitsAndBytesConfig, AutoTokenizer
from huggingface_hub import login
# Hugging Faceにログイン
login("HFT")
# 量子化設定
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16
)
# モデル読み込み
base_model_id = "llm-jp/llm-jp-3-13b"
device_map = "auto"
model = AutoModelForCausalLM.from_pretrained(
base_model_id,
quantization_config=bnb_config,
device_map=device_map,
trust_remote_code=True
)
tokenizer = AutoTokenizer.from_pretrained(base_model_id, trust_remote_code=True)
print("モデルとトークナイザーが正常にロードされました")
"""
find_all_linear_names: モデル内の4bit量子化線形層を探します。
"""
def find_all_linear_names(model):
cls = bnb.nn.Linear4bit # 4bit量子化線形層クラスを指定
lora_module_names = set() # ここに取得した線形層を保持します。
# モデル内の全てのモジュールを探索します
for name, module in model.named_modules():
if isinstance(module, cls): # モジュールが4bit量子化線形層の場合
names = name.split('.') # モジュールの名前を分割 (ネストされてる際などに対処)
lora_module_names.add(names[0] if len(names) == 1 else names[-1]) # 最下層の名前をlora_module_namesに追加
# 'lm_head' は16ビット演算の際に除外する必要があるため、lora_module_namesから削除
if 'lm_head' in lora_module_names:
lora_module_names.remove('lm_head')
return list(lora_module_names) # lora_module_namesをリストに変換して返します。
modules = find_all_linear_names(model)
"""
peft_config: PEFTの構成設定
- r
- LoRA のランク (4, 8, 16 ,32...)
- 増やすほど学習が捗るが, 過学習のリスクも高まるので注意
- lora_alpha
- LoRAのスケーリング係数
- lora_dropout
- ドロップアウト率(過学習を防ぐための割合)
- bias
- バイアス項の扱い ("none"の場合、LoRAはバイアスを学習しない)
- task_type
- タスクタイプ
- target_modules
- LoRAを適用するターゲットモジュール (前のコードで特定した層)
"""
peft_config = LoraConfig(
r=16,
lora_alpha=32,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
target_modules=modules,
)
model = get_peft_model(model, peft_config)
"""
学習に用いるデータセットの指定
今回はLLM-jp の公開している Ichikara Instruction を使います。データにアクセスするためには申請が必要ですので、使いたい方のみ申請をしてください。
Ichikara Instruciton を Hugging Face Hub にて公開することはお控えください。
また、CC-BY-NC-SAですのでモデルはライセンスを継承する前提でお使いください。
下記のリンクから申請を終えた先に Google Drive があり、Distribution20241221_all というフォルダごとダウンロードしてください。
今回は「ichikara-instruction-003-001-1.json」を使います。必要であれば展開(!unzip など)し、データセットのパスを適切に指定してください。
omnicampusの開発環境では取得したデータを左側にドラッグアンドドロップしてお使いください。
https://liat-aip.sakura.ne.jp/wp/llmのための日本語インストラクションデータ作成/llmのための日本語インストラクションデータ-公開/
関根聡, 安藤まや, 後藤美知子, 鈴木久美, 河原大輔, 井之上直也, 乾健太郎. ichikara-instruction: LLMのための日本語インストラクションデータの構築. 言語処理学会第30回年次大会(2024)
"""
dataset = load_dataset("json", data_files="./ichikara-instruction-003-001-1.json")
dataset
# 学習時のプロンプトフォーマットの定義
prompt = """### 指示
{}
### 回答
{}"""
"""
formatting_prompts_func: 各データをプロンプトに合わせた形式に合わせる
"""
EOS_TOKEN = tokenizer.eos_token # トークナイザーのEOSトークン(文末トークン)
def formatting_prompts_func(examples):
input = examples["text"] # 入力データ
output = examples["output"] # 出力データ
text = prompt.format(input, output) + EOS_TOKEN # プロンプトの作成
return { "formatted_text" : text, } # 新しいフィールド "formatted_text" を返す
pass
# # 各データにフォーマットを適用
dataset = dataset.map(
formatting_prompts_func,
num_proc= 4, # 並列処理数を指定
)
dataset
# データを確認
print(dataset["train"]["formatted_text"][3])
# データをtrainデータとtestデータに分割 (test_sizeの比率に)
# dataset = dataset["train"].train_test_split(test_size=0.1)
# dataset
"""
training_arguments: 学習の設定
- output_dir:
-トレーニング後のモデルを保存するディレクトリ
- per_device_train_batch_size:
- デバイスごとのトレーニングバッチサイズ
- per_device_
_batch_size:
- デバイスごとの評価バッチサイズ
- gradient_accumulation_steps:
- 勾配を更新する前にステップを積み重ねる回数
- optim:
- オプティマイザの設定
- num_train_epochs:
- エポック数
- eval_strategy:
- 評価の戦略 ("no"/"steps"/"epoch")
- eval_steps:
- eval_strategyが"steps"のとき、評価を行うstep間隔
- logging_strategy:
- ログ記録の戦略
- logging_steps:
- ログを出力するステップ間隔
- warmup_steps:
- 学習率のウォームアップステップ数
- save_steps:
- モデルを保存するステップ間隔
- save_total_limit:
- 保存しておくcheckpointの数
- max_steps:
- トレーニングの最大ステップ数
- learning_rate:
- 学習率
- fp16:
- 16bit浮動小数点の使用設定(第8回演習を参考にすると良いです)
- bf16:
- BFloat16の使用設定
- group_by_length:
- 入力シーケンスの長さによりバッチをグループ化 (トレーニングの効率化)
- report_to:
- ログの送信先 ("wandb"/"tensorboard"など)
"""
training_arguments = TrainingArguments(
output_dir=new_model_id,
per_device_train_batch_size=1,
gradient_accumulation_steps=2,
optim="paged_adamw_32bit",
num_train_epochs=1,
logging_strategy="steps",
logging_steps=10,
warmup_steps=10,
save_steps=100,
save_total_limit = 2,
max_steps = -1,
learning_rate=5e-5,
fp16=False,
bf16=False,
seed = 3407,
group_by_length=True,
report_to="none"
)
# トークナイザーで事前処理
tokenized_datasets = dataset.map(
lambda example: tokenizer(
example["formatted_text"],
truncation=True,
max_length=512,
padding="max_length"
),
batched=True
)
# SFTTrainerの呼び出し
trainer = SFTTrainer(
model=model,
train_dataset=tokenized_datasets["train"],
peft_config=peft_config,
args=training_arguments
)
trainer.train()
import os
file_path = "./elyza-tasks-100-TV_0.jsonl"
if os.path.exists(file_path):
print("File exists at:", os.path.abspath(file_path))
else:
print("File not found!")
import json
file_path = "/content/elyza-tasks-100-TV_0.jsonl" # 正しいファイルパス
datasets = []
with open(file_path, "r") as f:
item = ""
for line in f:
line = line.strip()
item += line
if item.endswith("}"):
datasets.append(json.loads(item))
item = ""
print("Loaded datasets:", datasets)
# モデルによるタスクの推論。
from tqdm import tqdm
results = []
for data in tqdm(datasets):
input = data["input"]
prompt = f"""### 指示
{input}
### 回答
"""
tokenized_input = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt").to(model.device)
attention_mask = torch.ones_like(tokenized_input)
with torch.no_grad():
outputs = model.generate(
tokenized_input,
attention_mask=attention_mask,
max_new_tokens=100,
do_sample=False,
repetition_penalty=1.2,
pad_token_id=tokenizer.eos_token_id
)[0]
output = tokenizer.decode(outputs[tokenized_input.size(1):], skip_special_tokens=True)
results.append({"task_id": data["task_id"], "input": input, "output": output})
# こちらで生成されたjsolを提出してください。
# 本コードではinputとeval_aspectも含んでいますが、なくても問題ありません。
# 必須なのはtask_idとoutputとなります。
import re
jsonl_id = re.sub(".*/", "", new_model_id)
with open(f"./{jsonl_id}-outputs.jsonl", 'w', encoding='utf-8') as f:
for result in results:
json.dump(result, f, ensure_ascii=False) # ensure_ascii=False for handling non-ASCII characters
f.write('\n')
# モデルとトークナイザーをHugging Faceにアップロード
model.push_to_hub(new_model_id, token=HF_TOKEN, private=True) # Online saving
tokenizer.push_to_hub(new_model_id, token=HF_TOKEN, private=True) # Online saving
https://liat-aip.sakura.ne.jp/wp/llmのための日本語インストラクションデータ作成/llmのための日本語インストラクションデータ-公開/
関根聡, 安藤まや, 後藤美知子, 鈴木久美, 河原大輔, 井之上直也, 乾健太郎. ichikara-instruction: LLMのための日本語インストラクションデータの構築. 言語処理学会第30回年次大会(2024)