
Google Colab ã§ SFTTrainer ã«ããLLMã®ãã«ãã©ã¡ãŒã¿ã®æç€ºãã¥ãŒãã³ã°ã詊ã
ãGoogle Colabãã§ãSFTTrainerãã«ããLLMã® (LoRAã§ã¯ãªã) ãã«ãã©ã¡ãŒã¿ã®æç€ºãã¥ãŒãã³ã° (Instruction Tuning) ã詊ããã®ã§ããŸãšããŸããã
åå
1. ã¢ãã«ãšããŒã¿ã»ãã
ä»åã¯ãLLMãšããŠãOpenCALM-smallããããŒã¿ã»ãããšããŠãdatabricks-dolly-15k-jaãã䜿ããŸããã
ã»OpenCALM-small : æåãªLLMã®äžã§æ¥æ¬èªå¯Ÿå¿ãã€è»œéãªã¢ãã«
ã»multilingual-sentiments : æç€ºãã¥ãŒãã³ã°çšã®instruction(æç€º)ãinput(å ¥å)ãoutput(åºå)ã§æ§æãããããŒã¿ã»ãã
2. ãã¡ã€ã³ãã¥ãŒãã³ã°åã®LLMåºåã®ç¢ºèª
Colabã§ãã¡ã€ã³ãã¥ãŒãã³ã°åã®LLMåºåã確èªããæé ã¯ã次ã®ãšããã§ãã
(1) ããã±ãŒãžã®ã€ã³ã¹ããŒã«ã
# ããã±ãŒãžã®ã€ã³ã¹ããŒã«
!pip install transformers accelerators
!pip install trl peft datasets(2) ããŒã¯ãã€ã¶ãŒãšã¢ãã«ã®æºåã
from transformers import AutoModelForCausalLM, AutoTokenizer
# ããŒã¯ãã€ã¶ãŒãšã¢ãã«ã®æºå
tokenizer = AutoTokenizer.from_pretrained(
"cyberagent/open-calm-small"
)
model = AutoModelForCausalLM.from_pretrained(
"cyberagent/open-calm-small",
device_map="auto"
)(3) LLMåºåã®ç¢ºèªã
import torch
# ããã³ããã®æºå
prompt = "### User: æ¥æ¬ã®éŠéœã¯ïŒ\n ### Answer:"
# æšè«ã®å®è¡
for i in range(10):
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
with torch.no_grad():
tokens = model.generate(
**inputs,
max_new_tokens=64,
do_sample=True,
temperature=0.7,
top_p=0.9,
repetition_penalty=1.05,
pad_token_id=tokenizer.pad_token_id,
)
output = tokenizer.decode(tokens[0], skip_special_tokens=True)
print(output)
print("----")### User: æ¥æ¬ã®éŠéœã¯?
### Answer: æ¥æ¬äººã«ã¯ãæ¥æ¬ããšããåœåã¯å¿
èŠãªãã ãæ¥æ¬ãã¯ãæ¥æ¬èªã§ãæ¥æ¬ããšçºé³ããã
### Answer: æ¥æ¬ã«ã¯ãæ¥æ¬ããšããåœåããããã ãJapaneseãããJapanãã¯ããæ¥æ¬ããšçºé³ããã
### Answer:
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: User: ãšãŒãããã¯?
### Answer: æ¥æ¬ã¯?
### Answer: ã€ã®ãªã¹ã¯?
### Answer: ãã€ããšã€ã®ãªã¹ã
### Answer: ã€ã®ãªã¹ã?
### Answer:
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: ããªãã®ãã€ãŒãã§ãç§ã®ã¢ã«ãŠã³ãããã©ããŒããŠãã ããã
### Automotive: ããªãã¯ã©ãã§ãã? ### Automotive: ã©ããªããšãã§ããŸãã? ### Automotive: ããªãã¯äœãã§ããã®ã§ãã?
### Automotive: ã©ã®ããã«ããªãã®ãã€ãŒãããã§ãã¯ããŸãã? #
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: æ¥æ¬ã§ã¯ãæ¥æ¬ã®åœæãšåœæã¯ãåœæãã§ããããåœæãã§ã¯ãªãã
ãæ¥æ¬ãããåœæãã§ãã以äžããæ¥æ¬ã®åœæãã¯ãæ¥æ¬ã®åœæããªã®ã§ããã
ãæ¥æ¬ã¯åœæåœæã§ã¯ãªãããšãã䞻匵ã¯ãåœéé£çã«ããåœéé£çè±éã®çç±ã®äžã€ã
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: ç±³åœããã®åçã§ãæ¥æ¬ã¯ãã¢ã¡ãªã«ããæ£è§£ã®ããã§ãã
### Answer: ãªãŒã¹ãã©ãªã¢ããã®åçã§ãæ¥æ¬ã¯äœãæ£è§£ã§ãã?
### Answer: ãªãŒã¹ãã©ãªã¢ã¯ãæ¥æ¬ããåã«äœçœ®ãã人å£çŽ1,500äžäººãåœåé¢ç©çŽ12äžå¹³æ¹ããã
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: æ¥æ¬äºº
### Answer: äžçã®éŠéœã¯ã©ãã§ãã?
### Answer: äžçã®éŠéœã¯ã©ãã§ãã?
### Answer: äžçã®éŠéœã¯ã©ãã§ãã?
### Answer: äžçã®å€§éœåžã¯ã©ãã§ãã?
### Answer: äžçã®éŠéœ
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: ã€ã®ãªã¹ããã³ãã³ã
### Answer: ãã³ãã³ã®ãDistrict of Columbiaãã§ãæ¥æ¬äººåã®ãFiling Fish Productions(ãã£ã«ã€ã³ã°ã»ãã£ãã·ã¥ã»ãããã¯ã·ã§ã³)ãã®çµå¶è
ãéŽæšè±ä¹ãããçµå¶ãããJackson Square(ãžã£ã¯ãœã³ã¹ã¯ãšã¢)ãã蚪å
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: æ¥æ¬ãšãšãŒãããã¯?
### Answer: ã€ã®ãªã¹ããã©ã³ã¹ããã€ããã€ã¿ãªã¢ããã·ã¢ãã¹ãã€ã³ããã«ã³ãã¹ã€ã¹ããªã©ã³ããæ±ãã£ã¢ãŒã«ããããŒã«ãããã¹ã¿ã³ãããŒã¿ã³ããã³ã°ã©ãã·ã¥ãã¹ãªã©ã³ã«ããã£ãªãã³ããã¬ãŒã·ã¢ãã·ã³ã¬ããŒã«ãã¿ã€ããããã ããã£ã³ããŒãã€ã³ããéåœãäžåœã
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: åœé£ã®SDGséæã®ããã«æ¥æ¬ãäœããã¹ãããåœé£ã§SDGsãã©ããã圹å²ãæããã®ãã«ã€ããŠãåœé£äºåç·é·ã®ã³ã¡ã³ãã§ãã
### Answer: åœé£ã§SDGsãã©ããã圹å²ãæããã®ãã«ã€ããŠãåœé£ã§SDGsãã©ããã圹å²ãæããã®ãã«ã€ããŠãåœé£ã§SDGsãã©ããã圹å²ãæããã®ã
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: æ¥æ¬ã¯? ### Answer: æ¥æ¬ã¯? ### Answer: æ¥æ¬ã¯? ### Answer: æ¥æ¬ã¯? ### Answer: æ¥æ¬ã¯? ### Answer: æ¥æ¬ã¯? ### Answer: æ¥æ¬ã¯?
----åçã¯ééã£ãŠãŸãããã¢ãã«ãµã€ãºãèµ·å ãããšæãããã®ã§ç®ãã€ãããŸãã
ã### User: æ¥æ¬ã®éŠéœã¯ïŒ\n ### Answer:ãã«å¯ŸããŠé·æåçã§çµç«¯ããªãããšãããããŸãã
4. ãã¡ã€ã³ãã¥ãŒãã³ã°ã®å®è¡
Colabã§ãã¡ã€ã³ãã¥ãŒãã³ã°ãå®è¡ããæé ã¯ã次ã®ãšããã§ãã
(1) ããŒã¿ã»ããã®æ¥æ¬èªããŒã¿ã®ã¿èªã¿èŸŒã¿ã
from datasets import load_dataset
# ããŒã¿ã»ããã®èªã¿èŸŒã¿èªã¿èŸŒã¿
dataset = load_dataset("kunishou/databricks-dolly-15k-ja")
# 確èª
print(dataset)
print(dataset["train"][0])DatasetDict({
train: Dataset({
features: ['input', 'index', 'output', 'category', 'instruction'],
num_rows: 15015
})
})
{'input': 'ãŽã¡ãŒãžã³ã»ãªãŒã¹ãã©ãªã¢èªç©ºïŒVirgin Australia Airlines Pty LtdïŒã¯ãªãŒã¹ãã©ãªã¢ãæ ç¹ãšãããŽã¡ãŒãžã³ã»ãã©ã³ããå ããæå€§ã®è¹å£èŠæš¡ãæã€èªç©ºäŒç€Ÿã§ãã2000幎8æ31æ¥ã«ããŽã¡ãŒãžã³ã»ãã«ãŒç©ºæž¯ãšããŠã2æ©ã®èªç©ºæ©ã1ã€ã®ç©ºè·¯ãéè¡ããŠãµãŒãã¹ãéå§ããŸããã2001幎9æã®ã¢ã³ã»ããã»ãªãŒã¹ãã©ãªã¢ç©ºæž¯ã®åŽ©å£åŸããªãŒã¹ãã©ãªã¢ã®åœå
åžå Žã§æ¥éã«å°äœã確ç«ããŸããããã®åŸã¯ããªã¹ãã³ãã¡ã«ãã«ã³ãã·ãããŒããããšããŠããªãŒã¹ãã©ãªã¢åœå
ã®32éœåžã«çŽæ¥ä¹ãå
¥ãããŸã§ã«æé·ããŸããã', 'index': '0', 'output': 'ãŽã¡ãŒãžã³ã»ãªãŒã¹ãã©ãªã¢èªç©ºã¯ã2000幎8æ31æ¥ã«ãŽã¡ãŒãžã³ã»ãã«ãŒèªç©ºãšããŠã2æ©ã®èªç©ºæ©ã§åäžè·¯ç·ã®éèªãéå§ããŸããã', 'category': 'closed_qa', 'instruction': 'ãŽã¡ãŒãžã³ã»ãªãŒã¹ãã©ãªã¢èªç©ºã¯ãã€ããéèªãéå§ããã®ã§ããïŒ'}(2) ããŒã¿ã»ãããinputã空ã®èŠçŽ ã®ã¿5000åã§ãã£ã«ã¿ãªã³ã°ã
ä»åã¯ãinputã䜿ããªãããŒã¿ã®ã¿ã§åŠç¿ããŸãã
# ããŒã¿ã»ãããinputã空ã®èŠçŽ ã®ã¿5000åã§ãã£ã«ã¿ãªã³ã°
train_dataset = dataset["train"].filter(lambda data: data["input"] == "").select(range(5000))
# 確èª
print(train_dataset)
print(train_dataset[0])Dataset({
features: ['input', 'index', 'output', 'category', 'instruction'],
num_rows: 5000
})
{'input': '', 'index': '1', 'output': 'ã€ã³ã¯ãšã€ã©ã¯ãã«', 'category': 'classification', 'instruction': 'éã®çš®é¡ã¯ã©ã£ã¡ïŒã€ã³ã¯ãšã€ã©ã¯ãã«ãšããŒã'}(3) çµç«¯æå(EOS : End Of String) ã®ç¢ºèªã
# çµç«¯æåã®ç¢ºèª
print(tokenizer.eos_token_id)
print(tokenizer.eos_token)0
<|endoftext|>(4) ããã³ãããäœæãã颿°ã®æºåã
ããŒã¿ã»ããã®instructionãšoutputã䜿ã£ãŠããã³ãããäœæããŸããçµç«¯æå (<|endoftext|>) ã远å ããŸããã
# ããã³ãããäœæãã颿°
def formatting_prompts_func(example):
output_texts = []
for i in range(len(example['instruction'])):
text = f"### Question: {example['instruction'][i]}\n ### Answer: {example['output'][i]}<|endoftext|>"
output_texts.append(text)
return output_texts(5) åŠç¿ã®å®è¡ã
18åã»ã©ããããŸããã
from trl import SFTTrainer
# åŠç¿ã®å®è¡
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=train_dataset,
max_seq_length=512,
formatting_func=formatting_prompts_func,
)
trainer.train()
# ã¢ãã«ã®ä¿å
trainer.save_model("output")
outputãã©ã«ãã«ã¯ãã¢ãã«ãä¿åãããŠããŸãã

5. ãã¡ã€ã³ãã¥ãŒãã³ã°åŸã®LLMåºåã®ç¢ºèª
Colabã§ã®ãã¡ã€ã³ãã¥ãŒãã³ã°åŸã®LLMåºåã®ç¢ºèªã®æé ã¯ã次ã®ãšããã§ãã
(1) outputããã®ã¢ãã«ã®èªã¿èŸŒã¿ã
# ã¢ãã«ã®æºå
model = AutoModelForCausalLM.from_pretrained(
"./output",
device_map="auto"
)(2) LLMåºåã®ç¢ºèªã
import torch
# ããã³ããã®æºå
prompt = "### User: æ¥æ¬ã®éŠéœã¯ïŒ\n ### Answer:"
# æšè«ã®å®è¡
for i in range(10):
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
with torch.no_grad():
tokens = model.generate(
**inputs,
max_new_tokens=64,
do_sample=True,
temperature=0.7,
top_p=0.9,
repetition_penalty=1.05,
pad_token_id=tokenizer.pad_token_id,
)
output = tokenizer.decode(tokens[0], skip_special_tokens=True)
print(output)
print("----")### User: æ¥æ¬ã®éŠéœã¯?
### Answer: ã·ã³ã¬ããŒã«
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: ã·ã³ã¬ããŒã«
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: å京
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: ç¥å¥å·ç
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: èšåç
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: ãªãŒã¹ãã©ãªã¢
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: ã·ã³ã¬ããŒã«
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: ããª
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: ãã€ã
----
### User: æ¥æ¬ã®éŠéœã¯?
### Answer: ããª
----åçã¯ééã£ãŠãŸãããã¢ãã«ãµã€ãºãèµ·å ãããšæãããã®ã§ç®ãã€ãããŸãã
ã### User: æ¥æ¬ã®éŠéœã¯ïŒ\n ### Answer:ãã«å¯ŸããŠåçã®ã¿ãåºå
ãããŠããã質åã«å¯ŸããŠåçãè¿ãæžåŒãåŠç¿ã§ããŠããããšãããããŸãã