|
--- |
|
base_model: llm-jp/llm-jp-3-13b |
|
tags: |
|
- text-generation-inference |
|
- transformers |
|
- unsloth |
|
- llama |
|
- trl |
|
license: apache-2.0 |
|
language: |
|
- en |
|
library_name: peft |
|
--- |
|
|
|
# Uploaded model |
|
|
|
- **Developed by:** libkazz |
|
- **License:** apache-2.0 |
|
- **Finetuned from model :** llm-jp/llm-jp-3-13b |
|
|
|
This llama model was trained 2x faster with [Unsloth](https://github.com/unslothai/unsloth) and Huggingface's TRL library. |
|
|
|
[<img src="https://raw.githubusercontent.com/unslothai/unsloth/main/images/unsloth%20made%20with%20love.png" width="200"/>](https://github.com/unslothai/unsloth) |
|
|
|
### Training Details |
|
指示チューニングデータとして下記のものを利用しました。 |
|
* ichikara-instruction-003-001-1.json |
|
* ichikara-instruction-003-002-1.json |
|
* ichikara-instruction-003-003-1.json |
|
|
|
以下について, 指示に対して複数の回答を持つデータは回答を1件のみ抽出して指示データをして利用しました。 |
|
* ichikara-instruction-003-001-5.1.json |
|
* ichikara-instruction-003-001-5.2.json |
|
* ichikara-instruction-003-001-2.1.json |
|
* ichikara-instruction-003-001-2.2.json |
|
|
|
回答を1件のみ抽出するために gpt-4o-mini で下記 script を利用しました。 |
|
<details> |
|
<summary>script</summary> |
|
|
|
```python |
|
# gpt-4o-mini を使って最も適切そうな回答を選定 |
|
def select_best_response(file_path, output_dir): |
|
with open(file_path, "r", encoding="utf-8") as file: |
|
data = json.load(file) |
|
|
|
grouped_data = {} |
|
|
|
# データをデータ番号ごとに分類 |
|
for item in data: |
|
data_number = item["ID"].split("-")[4] |
|
grouped_data.setdefault(data_number, []).append(item) |
|
|
|
filtered_data = [] |
|
for data_number, responses in grouped_data.items(): |
|
print(f"\n#### {data_number} ####") |
|
|
|
# 指示と回答リストを生成 |
|
instructions = [r["text"] for r in responses] |
|
outputs = [r["output"] for r in responses] |
|
|
|
# GPT-4o-miniに最適な回答を選定させる |
|
prompt = ( |
|
"以下の指示に対して最も適切な回答を選定してください。\n\n" |
|
f"### 指示 ###\n```\n{instructions[0]}\n```\n\n" |
|
"### 候補 ###\n" + "\n\n".join([f"{i+1}: \n```\n{output}\n```" for i, output in enumerate(outputs)]) + |
|
"\n\n### 回答 ###\n番号(1 or 2)のみを回答してください。1つだけ選択してください。\n" |
|
) |
|
|
|
try: |
|
response = openai.chat.completions.create( |
|
model="gpt-4o-mini", |
|
messages=[ |
|
{"role": "system", "content": "あなたはIQ140の論理的思考力の高い文章評価の専門家です。"}, |
|
{"role": "user", "content": prompt} |
|
] |
|
) |
|
content = response.choices[0].message.content |
|
print(content) |
|
best_choice = int(content.strip()) - 1 |
|
except ValueError as e: |
|
print(f"ValueError: 無効な応答がありました。データ番号: {data_number}") |
|
print(f"応答内容: {response.choices[0].message['content']}") |
|
best_choice = 1 |
|
except Exception as e: |
|
print(f"予期しないエラーが発生しました。データ番号: {data_number}") |
|
print(e) |
|
best_choice = 1 |
|
|
|
filtered_data.append(responses[best_choice]) |
|
|
|
output_file_name = os.path.basename(file_path) |
|
output_file_path = os.path.join(output_dir, output_file_name) |
|
with open(output_file_path, "w", encoding="utf-8") as output_file: |
|
json.dump(filtered_data, output_file, ensure_ascii=False, indent=2) |
|
``` |
|
|
|
|
|
</details> |
|
|
|
### ライセンス |
|
* ichikara-instruction データセットのライセンスは cc-by-nc-sa になっております。 |
|
|
|
### SFTの概要 |
|
* 4bit量子化 |
|
* LoRAによるSFT |
|
* learning_rate = 2e-4 |
|
* num_train_epochs = 2 |
|
|
|
## Bias, Risks, and Limitations |
|
RLHF,DPOを実施していないため不適切な表現が出力される可能性があります。 |
|
|
|
# elyza-tasks-100-TV_0.jsonl の出力方法 |
|
|
|
elyza-tasks-100-TV_0.jsonl に記載されている指示に対する返答のサンプル出力コードは次のようになります。 |
|
|
|
```python |
|
import torch |
|
from transformers import ( |
|
AutoTokenizer, |
|
AutoModelForCausalLM, |
|
BitsAndBytesConfig, |
|
) |
|
from peft import LoraConfig, PeftModel |
|
from datasets import load_dataset |
|
|
|
BASE_MODEL = "llm-jp/llm-jp-3-13b" |
|
PEFT_MODEL = "libkazz/llm-jp-3-13b-it_lora" |
|
|
|
tokenizer = AutoTokenizer.from_pretrained(PEFT_MODEL) |
|
bnb_config = BitsAndBytesConfig( |
|
load_in_4bit=True, |
|
bnb_4bit_compute_dtype=torch.float16, |
|
bnb_4bit_quant_type="nf4", |
|
bnb_4bit_use_double_quant=False, |
|
) |
|
|
|
base_model = AutoModelForCausalLM.from_pretrained( |
|
BASE_MODEL, |
|
device_map="auto", |
|
quantization_config=bnb_config, |
|
torch_dtype="auto", |
|
trust_remote_code=True, |
|
) |
|
|
|
model = PeftModel.from_pretrained(base_model, PEFT_MODEL) |
|
|
|
# elyza-tasks-100-TV_0.jsonl データの読み込み |
|
from datasets import load_dataset |
|
from tqdm import tqdm |
|
|
|
datasets = load_dataset("json", data_files="./elyza-tasks-100-TV_0.jsonl", split="train") |
|
|
|
results = [] |
|
for dt in tqdm(datasets): |
|
input = dt["input"] |
|
prompt = f"次の指示に忠実に回答を作成しなさい。\n\n### 指示:\n{input}\n\n### 回答:\n" |
|
|
|
model_input = tokenizer([prompt], return_tensors = "pt").to(model.device) |
|
|
|
if "token_type_ids" in model_input: |
|
del model_input["token_type_ids"] |
|
|
|
outputs = model.generate( |
|
**model_input, |
|
max_new_tokens = 512, |
|
pad_token_id=tokenizer.pad_token_id, |
|
eos_token_id=tokenizer.eos_token_id, |
|
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, "output": prediction}) |
|
|
|
# ファイルに保存する |
|
import json |
|
with open("output.jsonl", "wt", encoding='utf-8') as f: |
|
for result in results: |
|
json.dump(result, f, ensure_ascii=False) |
|
f.write('\n') |
|
``` |
|
|
|
|