èªå® ã®RTX3060ã§å°ããªLLMãèªäœããŠã¿ã
ãã¡ãã®ã€ãã³ãã«åå ããããã®ãã¿ãšããŠèªå® ã®PC(RTX3060)ã§é空æåº«ã®ããŒã¿ã»ããã䜿ã£ãŠããŒã¯ãã€ã¶ãŒãèªäœãGPT-2ã¢ãŒããã¯ãã£ã®ãã©ã¡ãŒã¿ãŒæ°ã42.1Mã®ã¢ãã«ã§ã®äºååŠç¿ããã£ãŠã¿ãŸããã
ïŒã€ãã³ãããªãã£ããäºååŠç¿ããã£ãŠã¿ãããšã¯æããããªãã£ãã¯ãã§ãã®ãããªæ©äŒãèšããŠãã ãã£ãã¬ãã¬ãããã«ã¯å€§å€æè¬ããŠããŸãïŒïŒ
ããŒã¿ã»ãã
ãã¡ãã®ååŠçæžã¿ã®é空æåº«ã®ããŒã¿ã»ããã䜿ããŸããã
ããã«ä»åã¯ä»¥äžã®ããã«æåé£ããæ°åæ°ä»®åã«çµã£ãŠåŠç¿ãè¡ããŸã
raw_dataset = load_dataset("globis-university/aozorabunko-clean", split="train")
filtered_dataset = raw_dataset.filter(lambda row: row["meta"]["æåé£ãçš®å¥"] == "æ°åæ°ä»®å")
print(filtered_dataset)
print(f"Filtered dataset size: {filtered_dataset.num_rows:,} entries")
ããã1äžä»¶ã®ããŒã¿ã«ãªããŸãã
Dataset({
features: ['text', 'footnote', 'meta'],
num_rows: 10246
})
Filtered dataset size: 10,246 entries
ããŒã¯ãã€ã¶ãŒ
é空æåº«ã®ããŒã¿ã®ã¿ã§åŠç¿ãè¡ããšããããšããããèªåœã«åããããããšãæ³å®ãããŸãã
ããã§æ¢åã®ããŒã¯ãã€ã¶ãŒã䜿ãããå°çšã®ãã®ã䜿çšããæ¹ãè¯ãã ãããšèãèªäœããããšã«ããŸãããSentencePiece ã§ unigram ãåŠç¿ããŠããŸãã
äžè¬çãªCPUã§ãã10åã»ã©ã§äœæãå®äºããŸããã
ãã©ã¡ãŒã¿ãŒã«ã€ããŠ
-
model_type: unigramäºæã®ããŒã¯ã³åãç¶æãã€ã€æ¥æ¬èªç¹æã®èªå°Ÿã现ããå»ã¿ããã£ãã®ã§unigramãéžæã -
vocab_size: 32,000ãªã GPT-2 Small ãšåãã¹ã±ãŒã«ã®åã蟌ã¿è¡åã§ãã -
character_coverage: 0.9995ã«ããããšã§æŽå²çä»®åé£ããªã©ã®åºçŸé »åºŠã極端ã«äœãæåãèœãšãã€ã€ãbyte_fallbackã§ã©ãããŠãå¿ èŠãªæåã¯ãã€ãåãšããŠè¡šçŸããŸãã -
input_sentence_size=2_000_000ã«å¶éããããšã§ SentencePiece ã®ãµã³ããªã³ã°ãå®å®ããæ¯ååããããªèªåœãåŸãããŸãã -
shuffle_input_sentence=Trueãç«ãŠãŠé空æåº«ç¹æã®é·å€§ãªäœåã§ãåããªããµãã¯ãŒããæœåºãããããã«ããŸããã -
<|endoftext|>㯠GPT-2 ã® EOS ãšæããç®çã§user_defined_symbolsã«è¿œå ããåŠç¿ããŒã¿ã®ææ«ã«ãåžžã«ä»äžããŠããããšã§åŸæ®µã®Trainerã PAD ãš EOS ãå Œçšã§ããŸãã - normalization:
normalization_rule_name="nfkc"ãšbyte_fallback=Trueã®çµã¿åããã§æ§åäœãæ£èŠåãã€ã€æªç¥æåãèœãšããªãããã«ããŠããŸãã
spm.SentencePieceTrainer.train(
sentence_iterator=corpus_iterator(filtered_dataset),
model_prefix=str(OUTPUT_DIR / "aozora_spm_gpt2"),
model_type="unigram",
vocab_size=32000,
character_coverage=0.9995,
normalization_rule_name="nfkc",
byte_fallback=True,
unk_id=0, bos_id=-1, eos_id=-1, pad_id=-1,
user_defined_symbols=["<|endoftext|>"],
input_sentence_size=2_000_000,
shuffle_input_sentence=True,
train_extremely_large_corpus=True,
num_threads=8,
add_dummy_prefix=False,
remove_extra_whitespaces=False,
hard_vocab_limit=False,
)
çµæ
ããŒã¯ãã€ã¶ãŒãšããŠåãããŠã¿ãçµæã§ããåœç¶ããŠã§ã¹ããã³ã¹ã¿ãŒãã®ãããªåºæåè©ã«ã¯åŒ±ãã§ãããããšãªã£ãŠãããéãŸã£ãŠããããªã©ãäžã€ã®èªåœãšããŠæ±ãããŠããã®ã¯ããããã§ãã
--- Sample 1 ---
Original: æ·±ããã©ããã«ããããŠã
Token IDs: [874, 11406, 264, 366, 15219, 258]
Pieces: ['æ·±ã', 'ãã©ãã', 'ã«', 'ã', 'ãããŠ', 'ã']
--- Sample 2 ---
Original: åé«ããŠã§ã¹ããã³ã¹ã¿ãŒã«
Token IDs: [15899, 14107, 2047, 10438, 7545, 264]
Pieces: ['åé«ã', 'ãŠã§', 'ã¹ã', 'ãã³', 'ã¹ã¿ãŒ', 'ã«']
--- Sample 3 ---
Original: çé®ãç³ã®èšå¿µç¢ãšãªã£ãŠ
Token IDs: [21674, 278, 3600, 5815, 9470, 1070]
Pieces: ['çé®', 'ã', 'ç³ã®', 'èšå¿µ', 'ç¢', 'ãšãªã£ãŠ']
--- Sample 4 ---
Original: ãã¹ãŠã®ç䟯貎æãéãŸã£ãŠããã®ãã¿ãã°ã
Token IDs: [2200, 965, 6015, 5559, 262, 26889, 260, 266, 5117, 258]
Pieces: ['ãã¹ãŠã®', 'ç', '䟯', '貎æ', 'ã', 'éãŸã£ãŠãã', 'ã®', 'ã', 'ã¿ãã°', 'ã']
--- Sample 5 ---
Original: ä»ã¯ãããã¿ããã»ããããèŠæ ããªãã
Token IDs: [1291, 12277, 3254, 268, 258, 18540, 268, 258, 340, 2529, 510, 259]
Pieces: ['ä»ã¯', 'ãã', 'ãã¿', 'ã', 'ã', 'ã»ãã', 'ã', 'ã', 'èŠ', 'æ ', 'ããªã', 'ã']
ã¢ãã«
RTX 3060 ã§ãåžžçšã§ãã 8 å±€ 512 次å ã® GPT-2 ãæ§ç¯ããŸããããã®æ§æã§ã¯42.1M ã®ãã©ã¡ãŒã¿æ°ã«ãªããŸãã
ãã©ã¡ãŒã¿ãŒã«ã€ããŠ
-
n_embd=512㯠RTX3060 ã® 12GB ã«åãŸãã®ãªã®ãªã®ç·ã§ãn_layerã 8 ã«ããããšã§åŠç¿æéãšã®ãã©ã³ã¹ããšããŸããã -
n_ctx=256ã¯é空æåº«ã®æ®µèœåäœã®æèãã«ããŒãã€ã€ããããã 32 ãµã³ãã«ç©ããçšåºŠã«æããŠããŸãã - BOS/EOS/PAD ã
<|endoftext|>ã«çµ±äžããæ¬ æãæ°ã«ããã«Trainerã®default_data_collatorã䜿ããããã«ããŠããŸãã -
use_cache=FalseïŒãã¬ãŒãã³ã°æã®åèšç®ã蚱容ããŠã§ã VRAM æ¶è²»ãæããåŸé ççºãèµ·ããã«ããããŠããŸãã
config = GPT2Config(
vocab_size=vocab_size,
n_positions=block_size,
n_ctx=block_size,
n_embd=512,
n_layer=8,
n_head=8,
bos_token_id=endoftext_id,
eos_token_id=endoftext_id,
pad_token_id=endoftext_id,
)
model = GPT2LMHeadModel(config)
model.config.use_cache = False
äºååŠç¿
ãã©ã¡ãŒã¿ãŒã«ã€ããŠ
-
epoch=1ïŒè©Šãã«1epochã®åŠç¿ã宿œããŸããã -
block_size=256ïŒé·ç·šå°èª¬ã§ã段èœåäœã§ãŸãšãŸããåºãé·ããVRAMãšã®å Œãåãã§åŠ¥åãããšããã§ãã -
per_device_train_batch_size=2Ãgradient_accumulation_steps=16ïŒããã€ã¹ããã 2 ãµã³ãã«ããç©ããªãèšå®ã§ã 32 ãµã³ãã«çžåœã§æŽæ°ã§ããããããµã€ãºäŸåã®åŠç¿å®å®æ§ã確ä¿ã§ããŸãã -
learning_rate=5e-4+warmup_steps=500ïŒäºååŠç¿ã 1Epoch ã§çµããããé«ãã®åŠç¿çãæ¡çšãã€ã€ãæåã® 500step ã§å°ããã€äžããŠæŽèµ°ãé²ããŸãã -
weight_decay=0.1ïŒèªåœãæ°èŠã«åŠç¿ããŠããã®ã§æ£ååã匷ãã«å ¥ãããŸããªããŒã¯ã³ã§ã® overfitting ãæããŠããŸãã -
eval/save/logging_steps=500ïŒã³ãŒãã¹å šäœã§ 3000step ååŸãªã®ã§ 500step ããšã«ã€ãã³ãã眮ããšãèš 5 åçšåºŠã®ã¹ãããã·ã§ããã§æšç§»ã远ããèšç®ã§ãã -
fp16=TrueïŒRTX3060 ã§ãåŠç¿ãé«éåã§ããVRAM ã®ããŒã¯ã 1ã1.2GB ã»ã©äžããããŸãã
tokenized = dataset_dict.map(
encode_with_sentencepiece,
batched=True,
remove_columns=original_columns,
desc="Tokenizing with SentencePiece",
)
lm_datasets = tokenized.map(
group_texts,
batched=True,
desc="Grouping texts into fixed-size blocks",
)
training_args = TrainingArguments(
output_dir=str(output_dir),
num_train_epochs=1,
per_device_train_batch_size=2,
per_device_eval_batch_size=2,
gradient_accumulation_steps=16,
learning_rate=5e-4,
warmup_steps=500,
weight_decay=0.1,
logging_steps=100,
eval_steps=500,
save_steps=500,
evaluation_strategy="steps",
save_strategy="steps",
fp16=torch.cuda.is_available(),
report_to=[],
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=lm_datasets["train"],
eval_dataset=lm_datasets["test"],
data_collator=default_data_collator,
)
åŠç¿çµé
1æé45åã»ã©ã§åŠç¿ã¯å®äºããŸããã

çµæ
é空æåº«ã§åŠç¿ãããç²æããã£ãŠãç¹ã«æœè±¡çãªåããæããã°ãããããããšãèšãããã«ãªããŸããã
人çãšã¯ãå šãååã®äžæ®µéã®äººéåŠã®ãç¥ããšãã®çµ±äžã®äžã«ååšãããã®ãšããŠèŠãããŠããããããç§ã¯ããã®ææ³çå®åšã«æŒãŠãåããŠãäžççãªãååšå²ãšãã圢åŒãèªèŠãæ¥ã£ããèããŠããã«å²åŠãå±éãããã®ã§ããã
æãšã¯ããã®ææ ã®çŽæ¥é¢ä¿ã«ããªããã®ã§ãªããŠã¯ãªããªãã®ã§ãã£ãŠããããã£ãŠããã¯åã«åãªãæ§è³ªäžã®çžéã«ããããšãæå³ããã«ãããªããšèããã®ã§ããããããã®ççŸãåå ãããšããã°ãèªç¶ã¯ãã®è¡çºã«ãã£ãŠå€åããªããšããçµæã«ãªããšããã®ã§ããã
ç¥ãšã¯ãå šãå¥ã®äžçã§ã¯ãªãã®ã§ãããŸãããã®äºã€ãäœã§ããããšãããšãäžã€ã¯äžã€ã«åããŠãã®åäžé åãžéããããšããŸãå¥ã®ãã®ãšããŠåäžç¯å²ã«åããã®ã§ãããŸããããããã«å¯ŸããéèŠäŸ¡å€ããã®ãããã®æä»£ã«æŒãŠç°ããã®ã§ããããšåããŸãã
äºååŠç¿äŒåå è ã®äžã§ã¯æããã§å°ããªã¢ãã«ã ã£ããšæããŸããåºåã«é¢ããŠã¯çµæ§é¢çœãã£ãŠããããã®ã§ããããã£ãã§ãã
詊ããŠã¿ããæ¹åã
äžå¿ããŒã¯ãã€ã¶ãŒãšã¢ãã«ã«é¢ããŠã¯Hugging Faceã«ã¢ããããŒãããŠããŸãã
æšè«ãå®è¡ã§ããColabãçšæããã®ã§èå³ããæ¹ã¯ãã²è§Šã£ãŠã¿ãŠãã ããã
åè
HuggingFaceå ¬åŒãã¥ãŒããªã¢ã«
124.2Mã®GPT-2ãPythonã®ã³ãŒãè£å®å°çšã®ã¢ãã«ãšããŠäºååŠç¿ãããã¥ãŒããªã¢ã«ã§ããã³ãŒãã®å€§æ ã¯ãã¡ããåèã«ããŸãããæ¥æ¬èªã«ç¿»èš³ããããã®ãå ¬éãããŠããŸãã
ã€ãããªããåŠã¶ïŒLLM èªäœå ¥é
PyTorchã䜿ã£ãŠ0ããGPT-2çžåœã®ã¢ãã«ãæ§ç¯ãããŸã§ãäœéšã§ããæžç±ã§ãã
æ®å¿µãªããæ¬æžã§ã¯GPT-2ã®æ¬æ ŒçãªäºååŠç¿ã¯çç¥ãããŠããŸãã
ä»åã®äºååŠç¿ãšåãããŠLLMãã€ãããšããããšãã©ãããããšãã®æè§ŠããåŸãããšãã§ããŸããã
Discussion