
Adapter란?
추가 학습 시 작은 사이즈의 네트워크 layer (adapter)를 추가시키고 해당 네트워크 layer만 학습에 참여시켜 학습에 필요한 비용을 줄이는 방법 => 전체 모델을 학습에 사용하는 것이 아니기 때문에 학습 속도를 높이고, 자원 사용량을 줄여 효과적으로 학습할 수 있다.
Adapter는 full fine tunning과는 다른데 일반적으로 fine tunning이라고 하면 모델 마지막에 레이어를 추가해서 학습하는 방법이었으나 Adapter는 모델 중간에 레이어가 들어가는게 차이가 있다고 볼 수 있다.

LoRA란? (Low-Rank Adaptation of Large Language Models)
rank decomposition matrix를 추가해서 파라미터를 효율적으로 학습하는 Adapter 종류 중에 하나이다.
기존 Adapter 방식은 모델 output을 Adapter의 인풋으로 넣었다면, LoRA는 모델의 input을 동일하게 받아서 병렬적으로 처리한 뒤 output 처리 단계에서 모델의 output과 합치는 방식으로 차이가 있다.
Gemma + LoRA 파인 튜닝 소스 코드
# !huggingface-cli login
from datasets import load_dataset
import torch
import pandas as pd
import numpy as np
import warnings
import json
import time
from transformers import (
AutoModelForCausalLM, # 자동으로 특정 언어 모델을 불러옴
AutoTokenizer, # 사전 학습된 토크나이저 제공
DataCollatorForLanguageModeling, # 언어 모델링을 위한 데이터 배치를 동적으로 생성, 텍스트의 일부를 마스킹하고 해당 위치의 원래 단어를 예측하는데 도움
BitsAndBytesConfig, # 큰 텍스트 데이터를 더 효율적으로 처리할 수 있도록 설계된 최신 토크나이저의 설정을 관리
TrainingArguments, # 학습 시 필요한 다양한 설정을 구성, 에포크, 배치 크기, 학습률
pipeline, # 사전 학습된 모델과 토크나이저를 사용하여 특정 NLP 테스트를 수행
logging, # 다양한 로그를 관리하고 설정할 수 있게 해줌, 디버깅이 용이해지고 필요한 정보를 적절한 로그 레벨로 출력 할 수 있음
)
from transformers import Trainer, TrainingArguments, DataCollatorForLanguageModeling, AutoModelForCausalLM, AutoTokenizer
from peft import LoraConfig, get_peft_model # 메모리를 덜 소모하면서 대형 모델의 미세 조정을 가속화하는 기술 lora에대한 컨피그
from trl import SFTTrainer # Trainer 대비 작은 데이터 셋에서 메모리 사용량도 적고, 더 빨리 학습됨
from huggingface_hub import notebook_login
# 'prompt' 필드 생성 함수
def format_instruction(example):
# 추가 컨텍스트(input 필드)가 있는 경우
if example['input'] and len(example['input']) > 0:
text = f"""user\n{example["instruction"]}\n{example["input"]}\nmodel\n{example["output"]}"""
# input 필드가 없는 경우
else:
text = f"""user\n{example["instruction"]}\nmodel\n{example["output"]}"""
return {'prompt': text}
# 데이터셋의 prompt 필드를 업데이트
dataset = dataset.map(format_instruction)
model_id = "google/gemma-7b-it"
# model_id = "google/gemma-7b"
# model_id = "google/gemma-2b-it"
# model_id = "google/gemma-2b"
bnb_config = BitsAndBytesConfig(load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16)
model = AutoModelForCausalLM.from_pretrained(model_id,
quantization_config=bnb_config,
device_map={"":0})
tokenizer = AutoTokenizer.from_pretrained(model_id, add_eos_token=True)
tokenizer.pad_token = tokenizer.eos_token
dataset = dataset.map(lambda samples: tokenizer(samples["prompt"]), batched=True)
dataset = dataset['train'].train_test_split(test_size=0.2)
train_data = dataset["train"]
test_data = dataset["test"]
torch.cuda.empty_cache()
lora_config = LoraConfig(
r=128, # 로라 적응을 위한 저랭크 행렬의 랭크
target_modules=['o_proj', 'q_proj', 'up_proj', 'v_proj', 'k_proj', 'down_proj', 'gate_proj'], # 로라 적용될 모델 내의 특정 모듈 리스트
lora_dropout=0.01, # 0.05 # 로라 계층에 적용되는 드롭아웃 비율
task_type="CAUSAL_LM"# 로라 테스크 타입, CAUSAL_LM은 주어진 문맥을 바탕으로 다음에 올 단어를 예측하는 테스크
)
model = get_peft_model(model, lora_config)
training_args = TrainingArguments(
num_train_epochs=5,
per_device_train_batch_size=1,
gradient_accumulation_steps=4,
warmup_steps=10,
max_steps=100,
learning_rate=2e-5,
# fp16=True,
# logging_steps=10,
output_dir="./outputs",
optim="paged_adamw_8bit",
)
trainer = SFTTrainer(
model=model,
train_dataset=train_data,
eval_dataset=test_data,
dataset_text_field="prompt",
peft_config=lora_config,
args=training_args,
data_collator=DataCollatorForLanguageModeling(tokenizer, mlm=False),
)
trainer.train()
result = get_completion(query="건강을 유지하기 위한 세 가지 팁을 알려주세요.",
model=trainer.model,
tokenizer=tokenizer)
new_model = "gemma-koalpaca-Rora-finetuned"
trainer.model.save_pretrained(new_model)'LLM 생성할레나' 카테고리의 다른 글
| [LLM/임베딩] 임베딩 이란? 임베딩 모델 추천 (1) | 2024.05.28 |
|---|---|
| [LLM/모델 선정] 모델 선정 시 고려 사항 (1) | 2024.05.27 |
| [STT/Whisper] Speech To Text 빠른 시도와 작은 실패 (0) | 2024.05.20 |
| [LLM/소형모델비교] Phi-3-mini, Gemma, Llama 3 차이 (0) | 2024.05.14 |
| [LLM/구글모델비교] BERT, Bard, Gemini 차이 (0) | 2024.05.14 |