概要
以下は、作成したコードの推論部分です。google-colab上で動作します。 ベースとなったDPOアダプタの作成は、実行コードよりも下の部分に記載しています。
また、ベースとなったSFTは、次のURLを参照してください https://huggingface.co/hatsukaze86/llm-jp-3-13b-20241127-hatsukaze4-4-4_lora
使用上の注意点 1.リソース節約のため、実行終了時に自動でセッションを削除します。そのため、出力したjsonファイルはdriveに自動的に上がります。ファイルパスを適切に設定してください。 2.WAN-DBやHFのKeyはシークレットから読み込みます。こちらも、事前設定をお願いします。 3.データセットも、Drive上のデータを自動読み込みにしています。適切にパスを変更して使用してください
推論用コード
Hugging Faceにアップロードしたモデルを用いてELYZA-tasks-100-TVの出力を得るためのコードです。
LoRA_template_20241127.ipynbで学習したLoRAアダプタとDPOtemplate_20241207.ipynbで学習したDPOアダプタを用いる想定です。
このコードで生成されたjsonlファイルは課題の成果として提出可能なフォーマットになっております。
ファイルの読み込み、結果の自動書き込み準備
from google.colab import runtime
from google.colab import drive
drive.mount('/content/drive')
wandbの準備
!pip install wandb
#学習状況を可視化
import wandb
import os
from google.colab import userdata
api_key = userdata.get('WANDB_APIKEY')
#W&Bにログイン。
#https://wandb.ai/settings --> Danger Zone --> API keys --> APIキーをコピペ。
#wandb.login(key=api_key)
#wandb.init(project="llm-lecture-2024-competition-DPO")
必要なライブラリのインストール・インポート
!pip install -U ipywidgets
!pip install transformers==4.46.3
!pip install -U bitsandbytes
!pip install -U accelerate
!pip install -U datasets
!pip install -U peft==0.13.2
!pip install -U trl==0.12.1
from transformers import (
AutoModelForCausalLM,
AutoTokenizer,
BitsAndBytesConfig,
TrainingArguments,
logging,
)
from peft import (
LoraConfig,
PeftModel,
get_peft_model,
)
from trl import (
SFTTrainer,
DPOConfig,
DPOTrainer
)
from IPython.display import display
from datasets import load_dataset
import ipywidgets as widgets
import os, torch, gc, json
import bitsandbytes as bnb
from tqdm import tqdm
import pandas as pd
Hugging Faceのトークン利用処理
#Hugging Faceで取得したTokenをこちらに貼る。
from google.colab import userdata
HF_TOKEN=userdata.get('HF_TOKEN')
ベースとなるモデルと学習したLoRAのアダプタ設定
#model_idの値はomnicampusの環境におけるモデルのパスを表しており、それ以外の環境で実行する場合は変更の必要があります。
#model_id = "models/models--llm-jp--llm-jp-3-13b/snapshots/cd3823f4c1fcbb0ad2e2af46036ab1b0ca13192a"
#omnicampus以外の環境をご利用の方は以下をご利用ください。
base_model_id = "llm-jp/llm-jp-3-13b"
adapter_id = "hatsukaze86/llm-jp-3-13b-20241127-hatsukaze4-4-4_lora" # こちらにアップロードしたLoRAアダプタのHugging FaceのIDを指定してください。
adapter_dpo_id = "hatsukaze86/llm-jp-3-13b-dpo-hatsukaze4-4_lora_5" # こちらにアップロードしたDPOアダプタのHugging FaceのIDを指定してください。
コンフィグ設定、モデル設定
#QLoRA config
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
)
#Load model
model = AutoModelForCausalLM.from_pretrained(
base_model_id,
quantization_config=bnb_config,
device_map="auto",
token = HF_TOKEN
)
#Load tokenizer
tokenizer = AutoTokenizer.from_pretrained(base_model_id, trust_remote_code=True, token = HF_TOKEN)
#元のモデルにLoRAのアダプタを統合。
model = PeftModel.from_pretrained(model, adapter_id, token = HF_TOKEN)
#LoRAのモデルにDPOのアダプタを統合。
model = PeftModel.from_pretrained(model, adapter_dpo_id, token = HF_TOKEN)
データセットの読み込み。
#omnicampusの開発環境では、左にタスクのjsonlをドラッグアンドドロップしてから実行。
datasets = []
with open("/content/drive/MyDrive/Colab Notebooks/Student_LLM/input/elyza-tasks-100-TV_0.jsonl", "r") as f:
item = ""
for line in f:
line = line.strip()
item += line
if item.endswith("}"):
datasets.append(json.loads(item))
item = ""
推論の実行
#llmjp
results = []
for data in tqdm(datasets):
input = data["input"]
prompt = f"""### 指示
{input}\n簡潔に回答してください\n
### 回答
"""
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=512,
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も含んでいますが、なくても問題ありません。
#必須なのはtask_idとoutputとなります。
import re
jsonl_id = re.sub(".*/", "", adapter_dpo_id)
with open(f"./{jsonl_id}-adapter512-prompt-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')
#保存先のディレクトリを指定
save_dir = '/content/drive/MyDrive/Colab Notebooks/Student_LLM/output/'
#保存するファイルのパスを作成
file_path = f"{save_dir}{jsonl_id}_adapter512_prompt_output.jsonl"
#jsonlで保存
with open(file_path, 'w', encoding='utf-8') as f:
for result in results:
json.dump(result, f, ensure_ascii=False)
f.write('\n')
ランタイムを終了、終了すると当然一時保存データは消えます。ドライブへの保存を実施していない場合や、コンピューティングユニット消費を気にしない場合は、無視してください
runtime.unassign()
ここからは、推論には関係ありません!
以下は、作成したコードのDPO部分全体です。google-colab上で動作します。
また、ベースとなったSFTは、次のURLを参照してください https://huggingface.co/hatsukaze86/llm-jp-3-13b-20241127-hatsukaze4-4-4_lora
基本的に実施したことは、次の通りです。 1.パラメータ調整 2.elyza-tasks-100をベースに作成した100件のDPOデータによるDPO
使用上の注意点 1.リソース節約のため、実行終了時に自動でセッションを削除します。そのため、出力したjsonファイルはdriveに自動的に上がります。ファイルパスを適切に設定してください。 2.WAN-DBやHFのKeyはシークレットから読み込みます。こちらも、事前設定をお願いします。 3.データセットも、Drive上のデータを自動読み込みにしています。適切にパスを変更して使用してください
コンペ用DPOテンプレート
こちらは、コンペにてDPOを行いたい方に向けたテンプレートとなるDPOコードです。
from google.colab import runtime from google.colab import drive drive.mount('/content/drive')
!pip install wandb
#学習状況を可視化 import wandb import os from google.colab import userdata
api_key = userdata.get('WANDB_APIKEY')
W&Bにログイン。
https://wandb.ai/settings
wandb.login(key=api_key) wandb.init(project="llm-lecture-2024-competition-DPO")
!pip install -U ipywidgets !pip install transformers==4.46.3 !pip install -U bitsandbytes !pip install -U accelerate !pip install -U datasets !pip install -U peft==0.13.2 !pip install -U trl==0.12.1
from transformers import ( AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, TrainingArguments, logging, ) from peft import ( LoraConfig, PeftModel, get_peft_model, ) from trl import ( SFTTrainer, DPOConfig, DPOTrainer ) from IPython.display import display from datasets import load_dataset import ipywidgets as widgets import os, torch, gc, json import bitsandbytes as bnb from tqdm import tqdm import pandas as pd
Hugging Face Token (write権限)
HF_TOKEN=userdata.get('HF_TOKEN')
モデルを読み込み。
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するベースモデル
Google Colab などをお使いの方は下記のbase_model_idのコメントアウトを外してください。
base_model_id = "llm-jp/llm-jp-3-13b"
adapter_id = "hatsukaze86/llm-jp-3-13b-20241127-hatsukaze4-4_lora" #dpoするベースモデル (あなたがFine-Tuningしたモデル - 今回はアダプタのみを想定) new_model_id = "llm-jp-3-13b-dpo-hatsukaze4-4_lora_5" #dpoするモデルにつけたい名前
QLoRA config
bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.bfloat16, )
Load model
model = AutoModelForCausalLM.from_pretrained( base_model_id, quantization_config=bnb_config, device_map="auto", token = HF_TOKEN )
Load tokenizer
tokenizer = AutoTokenizer.from_pretrained(base_model_id, trust_remote_code=True, token = HF_TOKEN)
元のモデルにLoRAのアダプタを統合。
model = PeftModel.from_pretrained(model, adapter_id, token = HF_TOKEN)
合成データ作成
DPO用にElyza Tasks 100のようなタスクおよび回答の合成データを作成します。
その後、人手で「良い」「悪い」をアノテーションします。
'''# 参考用のデータとしてElyza tasks 100を読み込み datasets = load_dataset("elyza/ELYZA-tasks-100") datasets '''
評価データの作成
DPOの学習のために評価データを作成します。
手順は以下の通りです。
- ELYZA-tasks-100(オリジナル)を参考にしてLLMに新しいタスクを生成させます。
- 生成されたタスクを目視で確認します。
- (任意で)手作業でタスクを修正します。
- 生成した各タスクに対してLLMに複数個の出力を生成させます。
- 同じタスクに対する出力を比較して良い出力(chosen)と悪い出力(rejected)のペアを作成します。
1. 新しいタスクの生成
時間とマシンリソースさえあればnum_return_sequencesの値を増やすことでいくらでも生成可能ですが
たくさん生成させるとデータの質は低下するためバランスを探るために何パターンか試すのが望ましいです。
''' task_results = [] for ref_input in tqdm(datasets['test']['input']):
prompt = f"""以下に示す参考タスクに従って、類似したタスクを生成しなさい。
参考タスク
仕事の熱意を取り戻すためのアイデアを5つ挙げてください。
類似タスク
試合に挑む心構えを3つほど挙げてください。
参考タスク
{ref_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, num_return_sequences=1, # 1つの参考タスクからいくつ新タスクを生み出すか do_sample=True, temperature=0.6, top_p=0.9, repetition_penalty=1.2, pad_token_id=tokenizer.eos_token_id )
output_texts = [tokenizer.decode(output[tokenized_input.size(1):], skip_special_tokens=True) for output in outputs]
new_task = {"reference_task": ref_input} new_task.update({f"similar_task_{i}": output_text for i, output_text in enumerate(output_texts)}) task_results.append(new_task) '''
'''
2. 生成されたタスクを目視で確認。
df = pd.DataFrame(task_results) df.head() '''
'''
3. 生成したタスクの手作業による修正
生成されたタスクの質が低い場合、手作業で修正することも検討してください。
修正したい場合はcsvで出力して修正しましょう。
EXCELやGoogleスプレッドシートで編集します。
簡単に修正可能な内容であれば修正し、修正が難しいものは削除して下さい。
※一度、GPU環境を止めて修正が終わってからGPU環境を再開してください
(再開時は「評価データの作成」の1、2とこのコードは実行不要です)。
逆に手直ししない人は3と3.1はスキップしてください。
df.to_csv("elyza-new-tasks.csv", encoding="utf-8-sig") '''
'''
3.1. 修正したcsvを読み込み。
手作業による修正をしていない人は実行の必要なし。
df = pd.read_csv("elyza-new-tasks.csv") '''
'''
4. モデルによる回答データの生成
こちらもnum_return_sequencesの数によっていくらでも生成可能である。
この後、タスクごとに良い出力と悪い出力のペアを作成するのだが
タスクによっては良い出力が出ない、悪い出力が出ないということが起こり得る。
多様な出力を得るために多めに出力するのが望ましい一方で
多くし過ぎると出力に膨大な時間がかかる上に評価の負担も増すので難しい。
生成したタスクを全て一つのリストに追加
tasks = [] for key in df.columns[1:]: tasks.extend([task for task in df[key] if isinstance(task, str) and task])
outputs_results = [] for task in tqdm(tasks):
prompt = f"""### 指示: {task}
回答:
"""
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=512, num_return_sequences=3, # 1つのタスクに対し何個出力させるか。ペアを作るので最低でも2個は必要 do_sample=True, temperature=0.6, top_p=0.9, repetition_penalty=1.2, pad_token_id=tokenizer.eos_token_id )
output_texts = [tokenizer.decode(output[tokenized_input.size(1):], skip_special_tokens=True) for output in outputs]
outputs_results.append({"task": task, "outputs": output_texts}) '''
5. 良い出力と悪い出力のペアを作成
DPOの学習を行うためには良い出力(chosen)と悪い出力(rejected)のペアを用意する必要があります。
ここで以下の3つを挙げるので、一つ選んで実行してください。
5.1. csvで出力した上でEXCELやGoogleスプレッドシートを使いペアを作成
5.2. Google ColabのGUIを用いてタスクごとに2段階評価
5.3. CUIで頑張って2段階評価
他にも3段階以上の評価を使う方法もあります。
2段階評価では良い出力と悪い出力の組み合わせでしかペアが作れませんが
3段階以上の評価では
- 1番良い出力と2番目に良い出力
- 1番良い出力と最も悪い出力
- 2番目に良い出力と最も悪い出力
というようにペアを増やすことができ
回答の数が同じでもペアを増やせるメリットがあります。
また、評価の粒度が細かくなるのでより正確な評価を反映できる可能性があります。
一方で増やし過ぎると過学習になるリスクもあるので最適なバランスは難しいところです。
'''
5.1.の方法で作成する場合はこちらを実行。
5.1.1. タスクと出力をcsvに保存
保存したelyza-new-tasks-and-preds.csvをExcelやGoogleスプレッドシートで開いた上で
1列目にinput、2列目に良い回答(chosen)、3列目に悪い回答(rejected)を記入したcsvを新たに作成し
"good_and_bad_outputs.csv"という名前で保存してください。
回答に良い回答がない場合はそのタスク自体を削除するか、出力を手直ししても構いません。
この作業を行った場合、5.2や5.3は行う必要ありません。
※一度、GPU環境を止めてペア作成が終わってからGPU環境を再開してください。
(再開時は「評価データの作成」の1~4とこのコードは実行不要です)。
import csv
csv.writer(open("elyza-new-tasks-and-preds.csv", "w", encoding="utf-8-sig")).writerows([(row["task"], output) for row in outputs_results for output in row["outputs"]]) '''
5.1.2. 「5.1.1」で作成したペアのcsvを読み込み
import csv dpo_datasets = [ {"prompt":row[0], "chosen":row[1], "rejected":row[2]} for row in csv.reader(open("/content/drive/MyDrive/Colab Notebooks/Student_LLM/input/good_and_bad_outputs.csv", encoding="utf-8")) ]
5.2. Google Colab上でのGUIによる二段階評価
今回はOmniでの使用を想定しているのでコメントアウトしています。
こちらの作業を行う場合は5.1と5.3は実行不要です。
※一度、GPU環境を止めてペア作成が終わってからGPU環境を再開してください
(再開時は「評価データの作成」の1~4と5.1.およびこのコードは実行不要です)。
current_index = 0
current_output_index = 0
task_label = widgets.Label(value=f"指示: {outputs_results[current_index]['task']}")
output_label = widgets.Textarea(
value=f"回答:\n{outputs_results[current_index]['outputs'][current_output_index]}",
disabled=True,
layout=widgets.Layout(width='100%', height='100px')
)
yes_button = widgets.Button(description="Yes")
no_button = widgets.Button(description="No")
for item in outputs_results:
item["annotations"] = [None] * len(item["outputs"])
def on_yes_clicked(b):
annotate_current_item("Yes")
def on_no_clicked(b):
annotate_current_item("No")
def annotate_current_item(annotation):
global current_index, current_output_index
outputs_results[current_index]["annotations"][current_output_index] = annotation # アノテーションを記録
next_item()
def next_item():
global current_index, current_output_index
current_output_index += 1
if current_output_index >= len(outputs_results[current_index]["outputs"]):
current_output_index = 0
current_index += 1
if current_index < len(outputs_results):
task_label.value = f"指示: {outputs_results[current_index]['task']}"
output_label.value = f"回答:\n{outputs_results[current_index]['outputs'][current_output_index]}"
else:
task_label.value = "アノテーションが完了しました!"
output_label.value = ""
yes_button.disabled = True
no_button.disabled = True
# display_results()
def display_results():
print("アノテーション結果:")
for item in outputs_results:
print(f"指示: {item['task']}")
for output, annotation in zip(item["outputs"], item["annotations"]):
print(f" 回答:\n{output}\n アノテーション: {annotation}")
yes_button.on_click(on_yes_clicked)
no_button.on_click(on_no_clicked)
display(task_label, output_label, yes_button, no_button)
'''
5.3 CUIで手動で2段階評価
こちらの作業を行う場合は5.1と5.2は実行不要です。
※一度、GPU環境を止めてペア作成が終わってからGPU環境を再開してください
(再開時は「評価データの作成」の1~4と5.1.およびこのコードは実行不要です)。
current_index = 0
ここから繰り返してください
print("指示: ",outputs_results[current_index]["task"]) for i, item in enumerate(outputs_results[current_index]["outputs"]): print("----------------------------------") print(f"回答{i}:\n{item}") '''
'''
5.3.の続き
annotationのリストの数は回答データのnum_return_sequencesの数と同じ
annotation = ["", "", ""] # 各回答に対応して[]に "Yes"か "No"を追加してください。(例: ["Yes", "Yes", "No"])
outputs_results[current_index]["annotations"] = annotation current_index += 1
if current_index < len(outputs_results): remain_len = len(outputs_results) - current_index print(f"あと{remain_len}タスク分残っています。二つ前に戻って操作を繰り返してください。") else: print(f"お疲れ様でした。これで以上になります!!") '''
'''
5.2または5.3を実行した場合、このコードで二段階評価をペアに変換する必要があります。
5.1を実行した方は不要です。
なお、このコードではタスクごとにペアを1組だけ作成していますが、もっと多くのペアを作っても構いません。
また、各データの長さは最大でも500くらいにしておくと学習がOOMせずに安定します。
データセットの作成
import random
def process_item(item): prompt = item["task"]
# "Yes" と "No" の両方を含まないタスクの場合は None を返す
if "GOOD" not in item["evaluation"] or "BAD" not in item["evaluation"]:
return None
chosen_items = [output for output, annotation in zip(item["output"], item["evaluation"]) if annotation == "GOOD"]
rejected_items = [output for output, annotation in zip(item["output"], item["evaluation"]) if annotation == "BAD"]
# ランダムにchosenとrejectedを1つずつ選択
chosen = random.choice(chosen_items)
rejected = random.choice(rejected_items)
return {"prompt": prompt, "chosen": chosen, "rejected": rejected}
map + filter を使用
dpo_datasets = list(filter(None, map(process_item, outputs_results))) '''
作成したデータセットを見てみる
for key, value in dpo_datasets[0].items(): print(f"\n{key}:\n{value}\n")
DPOによる学習
上の「評価データの作成」で一旦、環境を再起動していると思いますが、もし再起動していない場合、タスクや出力生成で使用されているGPUメモリを解放するために一旦、再起動してモデルとデータを読み込みなおしてください。
peft_config = LoraConfig( r=32, lora_alpha=32, lora_dropout=0.1, bias="none", task_type="CAUSAL_LM", target_modules=["q_proj", "v_proj",]#の全てをターゲットとするとL4で動かないので, 計算負荷を抑えるために一部のモジュール("q_proj"と"v_proj")を選択しています。["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj",] )
model = get_peft_model(model, peft_config)
from datasets import Dataset
dpo_datasets = Dataset.from_list(dpo_datasets)
split_dpo_datasets = dpo_datasets_hf.train_test_split(test_size=0.1)
train_dataset = split_dpo_datasets["train"]
test_dataset = split_dpo_datasets["test"]
training_args = DPOConfig( output_dir=new_model_id, per_device_train_batch_size=2, # メモリに余裕があれば2に増やすことでステップあたりの更新を安定化 per_device_eval_batch_size=2, gradient_accumulation_steps=4, optim="paged_adamw_32bit", num_train_epochs=1, # エポック数を増やす(3~5程度)ことで小データでも安定した学習 max_steps=-1, learning_rate=2e-4, # 2e-4より低めの1e-4設定し、安定性確保するのも手 warmup_ratio=0.1, # 学習初期の不安定な収束を回避 lr_scheduler_type="cosine", # コサインスケジューラで徐々にLR減少 weight_decay=0.01, # 過学習抑制のため max_grad_norm=1.0, # 勾配クリッピングで安定性向上 logging_strategy="steps", logging_steps=5, save_steps=5, save_total_limit=1, #eval_strategy="steps", #eval_steps=50, fp16=False, bf16=True, # A100でbf16が安定&高速 gradient_checkpointing=True, # メモリ節約&安定性(大モデルで有効) report_to="wandb" )
dpo_trainer = DPOTrainer( model, args=training_args, train_dataset=dpo_datasets, #train_dataset, # eval_dataset=test_dataset, tokenizer=tokenizer, peft_config=peft_config, )
model.config.use_cache = False dpo_trainer.train()
演習環境上に保存(再起動したときに使用可能)
model.config.use_cache = True dpo_trainer.save_model(training_args.output_dir)
HF_TOKEN=userdata.get('HF_TOKEN')
モデルとトークナイザーを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
ランタイムを終了
runtime.unassign()
タスクの推論
DPOの学習で使用したGPUメモリ次第では推論時にメモリ不足になる場合があるため
上手くいかなかった場合は再起動してdpo_trainer.save_modelで保存したアダプタを読み込むか
Hugging FaceにDPOのアダプタを一旦保存して
Model_Inference_Template_DPO_20241207.ipynb
で推論することをお勧めします。
タスクとなるデータの読み込み。
omnicampusの開発環境では、左にタスクのjsonlをドラッグアンドドロップしてから実行。
import json datasets = [] with open("/content/drive/MyDrive/Colab Notebooks/Student_LLM/input/elyza-tasks-100-TV_0.jsonl", "r") as f: item = "" for line in f: line = line.strip() item += line if item.endswith("}"): datasets.append(json.loads(item)) item = ""
モデルによるタスクの推論。
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も含んでいますが、なくても問題ありません。
必須なのは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')
保存先のディレクトリを指定
save_dir = '/content/drive/MyDrive/Colab Notebooks/Student_LLM/output/'
保存するファイルのパスを作成
file_path = f"{save_dir}{new_model_id}_output.jsonl"
jsonlで保存
with open(file_path, 'w', encoding='utf-8') as f: for result in results: json.dump(result, f, ensure_ascii=False) 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
ランタイムを終了
runtime.unassign()
Model Card for Model ID
データセット使用させていただきました。有難うございました。 https://liat-aip.sakura.ne.jp/wp/llmのための日本語インストラクションデータ作成/llmのための日本語インストラクションデータ-公開/
関根聡, 安藤まや, 後藤美知子, 鈴木久美, 河原大輔, 井之上直也, 乾健太郎. ichikara-instruction: LLMのための日本語インストラクションデータの構築. 言語処理学会第30回年次大会(2024)
Model Details
Model Description
This is the model card of a 🤗 transformers model that has been pushed on the Hub. This model card has been automatically generated.
- Developed by: [More Information Needed]
- Funded by [optional]: [More Information Needed]
- Shared by [optional]: [More Information Needed]
- Model type: [More Information Needed]
- Language(s) (NLP): [More Information Needed]
- License: [More Information Needed]
- Finetuned from model [optional]: [More Information Needed]
Model Sources [optional]
- Repository: [More Information Needed]
- Paper [optional]: [More Information Needed]
- Demo [optional]: [More Information Needed]
Uses
Direct Use
[More Information Needed]
Downstream Use [optional]
[More Information Needed]
Out-of-Scope Use
[More Information Needed]
Bias, Risks, and Limitations
[More Information Needed]
Recommendations
Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations.
How to Get Started with the Model
Use the code below to get started with the model.
[More Information Needed]
Training Details
Training Data
[More Information Needed]
Training Procedure
Preprocessing [optional]
[More Information Needed]
Training Hyperparameters
- Training regime: [More Information Needed]
Speeds, Sizes, Times [optional]
[More Information Needed]
Evaluation
Testing Data, Factors & Metrics
Testing Data
[More Information Needed]
Factors
[More Information Needed]
Metrics
[More Information Needed]
Results
[More Information Needed]
Summary
Model Examination [optional]
[More Information Needed]
Environmental Impact
Carbon emissions can be estimated using the Machine Learning Impact calculator presented in Lacoste et al. (2019).
- Hardware Type: [More Information Needed]
- Hours used: [More Information Needed]
- Cloud Provider: [More Information Needed]
- Compute Region: [More Information Needed]
- Carbon Emitted: [More Information Needed]
Technical Specifications [optional]
Model Architecture and Objective
[More Information Needed]
Compute Infrastructure
[More Information Needed]
Hardware
[More Information Needed]
Software
[More Information Needed]
Citation [optional]
BibTeX:
[More Information Needed]
APA:
[More Information Needed]
Glossary [optional]
[More Information Needed]
More Information [optional]
[More Information Needed]
Model Card Authors [optional]
[More Information Needed]
Model Card Contact
[More Information Needed]