Llama 3.1 한국어 Finetuning
이번 포스트를 통해 unsloth 라이브러리를 사용하여 llama 3.1 모델 finetuning을 실습한다.
💬 들어가기 전에..
👀 Unsloth
Unsloth는 대형 언어 모델(LLM)을 효율적으로 미세 조정(fine-tuning)할 수 있도록 설계된 Python 라이브러리입니다. 이 라이브러리는 특히 Llama, Mistral, Phi, Gemma와 같은 모델들을 다루며, PEFT을 통해 최대 5배 빠르게 학습을 진행할 수 있고, 메모리 사용량도 최대 80%까지 절감할 수 있습니다.
❤️🔥 PEFT ❤️🔥
📜 Github
🌈 Environment
- 모델: Llama3.1 8B
- 실습환경: GPU - T4 (colab, kaggle)
1. Install
%%capture
# Installs Unsloth, Xformers (Flash Attention) and all other packages!
!pip install "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
!pip install --no-deps "xformers<0.0.27" "trl<0.9.0" peft accelerate bitsandbytes
📍 Install list
- xformers: PyTorch에서 Transformer 기반 모델의 학습과 추론 성능을 최적화
- trl(transformers reinforcement learning): 강화 학습을 Transformers 모델과 통합하는 라이브러리, 언어 모델을 강화 학습으로 훈련하거나 조정하는데 유용함
- peft(parameter efficient fine-tuning): 언어 모델의 일부 파라미터만 미세 조정함으로써, 더 효율적으로 모델을 튜닝할 수 있게 해줌
- accelerate: Hugging Face에서 제공하는 라이브러리로, PyTorch 모델을 여러 GPU와 TPU에서 손쉽게 병렬 처리할 수 있게 함
- bitsandbytes: 4bit, 8bit 수학 연산을 지원하여 대형 모델의 메모리 사용을 줄이고 속도를 높일 수 있게 해주는 라이브러리로, 주로 메모리 제약이 있는 환경에서 사용함
✏️ bit를 줄이는 것이 왜 필요할까?
- 컴퓨터에서 데이터는 비트 단위로 저장되며, AI/ML 영역의 대표적인 데이터인 모델의 가중치는 32 bit 부동소수점으로 표현
- 이를 8bit 정수로 표현하면, 데이터의 크기가 4분의 1로 줄어들며 이는 parameter가 수백만에서 수십억 개 존재할 경우 매우 효과적
- 저장하는 bit를 줄이는 과정을 양자화라고 하며, 이로인해 모델 크기가 작아져 작은 규모의 인프라 환경(메모리)에서도 동작할 수 있게 됨
- 단, 연산의 정밀도가 떨어져 성능이 저하될 수 있으며, 구현이 복잡한 단점이 있음
2. Model Load
2.1 Pretrained model load
from unsloth import FastLanguageModel
import torch
max_seq_length = 2048 # 임의로 선택 가능! 내부적으로 RoPE Scaling을 자동으로 지원합니다.
dtype = None # None으로 설정하면 자동으로 감지됩니다. Tesla T4, V100에는 Float16, Ampere 이상에서는 Bfloat16을 사용합니다.
load_in_4bit = True # 메모리 사용량을 줄이기 위해 4비트 양자화를 사용합니다. False로 설정할 수도 있습니다.
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "unsloth/Meta-Llama-3.1-8B",
max_seq_length = max_seq_length,
dtype = dtype,
load_in_4bit = load_in_4bit,
# token = "hf_...", # use one if using gated models like meta-llama/Llama-2-7b-hf
)
📍 from_pretrained
- unsloth 라이브러리에서 미리 훈련된 언어 모델을 불러오고 설정하는 함수
- 언어 모델(LLM)을 메모리 효율적으로 로드하고, 필요에 따라 미세 조정(PEFT) 또는 양자화(Quantization) 기능을 추가할 수 있도록 함
📌 Parameters
- max_seq_length
- 모델이 처리할 수 있는 최대 시퀀스 길이 지정
- RoPE(상대적 위치 인코딩, Rotary Position Embedding): 모델 내부에 적용되어 더 긴 시퀀스도 처리할 수 있게 함
- 예제에서는 2048개의 토큰 처리하였으나 RoPE로 인해 4096까지도 가능
- dtype
- 데이터 타입을 지정
- None 일시 자동으로 최적의 타입 감지
- ex) T4, V100에서는 Float16, Ampere 이상은 Bfloat16
- load_in_4bit
- 모델이 4bit 양자화 된 상태로 로드될 수 있게 함
2.2 peft model load
model = FastLanguageModel.get_peft_model(
model,
r = 16, # 0보다 큰 숫자를 선택하세요! 권장값: 8, 16, 32, 64, 128
target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",],
lora_alpha = 16,
lora_dropout = 0, # 어떤 값이든 지원하지만, 0이 최적화되어 있습니다
bias = "none", # 어떤 값이든 지원하지만, "none"이 최적화되어 있습니다
# [새로운 기능] "unsloth"는 30% 더 적은 VRAM을 사용하며, 2배 더 큰 배치 크기를 지원합니다!
use_gradient_checkpointing = "unsloth", # 매우 긴 컨텍스트의 경우 True 또는 "unsloth" 사용
random_state = 3407,
use_rslora = False, # 순위 안정화 LoRA를 지원합니다
loftq_config = None, # 그리고 LoftQ도 지원합니다
)
📍 get_peft_model
- FastLanguageModel 클래스에서 PEFT (Parameter-Efficient Fine-Tuning) 기법을 적용하여 모델을 미세 조정하는 메서드
- 목적: RoRA(Residual on Residual Adapter)나 LoRA(Low-Rank Adaptation)와 같은 효율적인 미세 조정 기법을 통해 대형 언어 모델의 메모리 사용량을 줄이고, 성능을 향상시키는 것
📌 Parameters
- r
- LoRA 기법에서 사용하는 랭크(rank)
- 이 값이 클수록 모델의 표현력은 증가하지만, 메모리와 계산 비용도 늘어남
- 권장값: 8, 16, 32, 64, 128 등
- target_modules
- LoRA로 fine tuning시 transformer 모델 아키텍처에서 타겟팅할 모듈 리스트
- lora_alpha
- LoRA에서의 스케일링 파라미터
- 학습 중 Low Rank Adapater의 출력을 조절하는 데 사용됨
- 기본값: 16, 모델이 안정적으로 학습 할 수 있도록 최적화 된 값
- lora_dropout
- 학습 중 Dropout을 적용할 확률로 모델의 과적합을 방지하기 위해 사용됨
- 권장값: 0 (dropout 비활성화)
- bias
- 편향(bias)을 추가할지 여부를 설정
- 옵션: “none”, “all”, “lora_only”
- 권장값: “none” (편향 비활성화)
- use_gradient_checkpointing
- 그라디언트 체크포인팅을 사용하여 메모리 사용량을 줄이면서, 역전파 계산 시 그라디언트를 다시 계산하는 방법
- 옵션: True, False, “unsloth” (최적화된 옵션).
- use_rslora
- 순위 안정화 LoRA를 사용할지 여부를 결정
- loftq_config
- LoftQ(Quantization) 설정을 정의합니다. 양자화를 통해 메모리 사용량을 줄이는 방법을 설정할 수 있습니다.
- 기본값: None(양자 비활성)
🏷️ 참조
✏️ 순위 안정화 LoRA (Rank-Stabilized Low-Rank Adaptation, RsLoRA)
- LoRA 순위 불안정성
- LoRA는 저랭크 근사(low-rank approximation)를 사용하기 때문에, 근사 과정에서 원본 행렬의 정보가 일부 손실될 수 있음
- 특히, 저랭크 행렬로 인해 모델의 표현력이 제한될 수 있고, 이로 인해 성능이 저하되거나 불안정해질 가능성을 순위 불안정성이라 함
- 해결방법
- 정규화: 저랭크 행렬의 노름(norm)을 정규화하여, 행렬의 크기가 너무 커지거나 작아지는 것을 방지
- 안정화 제약: 행렬 분해 과정에서 일정한 조건을 추가하여, 원본 행렬의 정보 손실을 최소화하고, 분해된 저랭크 행렬이 보다 안정적인 표현을 할 수 있도록 함
✏️ LoftQ(Quantization)
- 특정 환경에서 4비트 양자화를 적용하여, 모델의 메모리 효율성을 극대화하면서도 성능 저하를 최소화하려는 기술
3. Data
3.1 Data Prepare
3.2 Data Loader
from datasets import load_dataset
# 한국어 데이터셋 로드
dataset = load_dataset("jojo0217/korean_safe_conversation", split = "train")
# 데이터셋에 프롬프트 포맷팅 함수 적용
dataset = dataset.map(formatting_prompts_func, batched = True,)
dataset
Dataset({
features: ['instruction', 'output', 'input'],
num_rows: 26979
})
- column: instruction, output, input
- row: 26979
dataset[0]
{'instruction': '친구들과 여행을 가보신 적이 있나요? 가봤다면 어디로 가보셨나요?',
'output': '제가 여행을 가거나 경험을 할 수는 없는 인공 지능 모델이므로, 실제로 여행을 간 적이 없습니다. 하지만 여행은 새로운 장소를 탐험하고 다양한 문화를 경험하는 멋진 활동 중 하나입니다. 여행은 많은 사람들에게 흥미로운 경험과 추억을 제공합니다. 여행에 대해 어떤 정보나 추천이 필요하시다면, 언제든 도움을 드릴 수 있습니다.',
'input': ''}
- dataset의 형식
📍 Input이 없는 이유
- 원래 Alpaca 데이터셋은 Instruction, input, output으로 구성되어 있음
- 상호작용(chat, QA) 모델에서 대답을 짧게 하는 경향과 맥락을 이해하지 못하는 경향을 개선하기 위해 instruction-output 셋을 사용
- 번역, 텍스트 변환 등의 작업에서는 input-output이 사용됨
🏷️ 참조
🌈 Example: 기존의 Input 형식
{
"instruction":"다음 문장에 가장 적합한 부사를 찾으세요.",
"input":"그녀는 일합니다",
"output":"그녀는 열심히 일합니다."
},
3.3 Prompt 생성
EOS_TOKEN = tokenizer.eos_token # Must add EOS_TOKEN
- 문장의 끝을 나타내는 token으로 없으면 답변이 무한 반복됨
- tokenizer는 pretrain model을 불러올 때 함께 불러옴
alpaca_prompt = """아래에는 작업을 설명하는 지시 사항과 추가적인 컨텍스트를 제공하는 입력이 있습니다. 요청을 적절하게 완료하는 응답을 작성하세요.
### instruction:
{}
### input:
{}
### output:
{}"""
def formatting_prompts_func(examples):
instructions = examples["instruction"]
inputs = examples["input"]
outputs = examples["output"]
texts = []
for instruction, input, output in zip(instructions, inputs, outputs):
text = alpaca_prompt.format(instruction, input, output) + EOS_TOKEN
texts.append(text)
return { "text" : texts, }
pass
- Llama 3.1 fine-tuning을 위해 dataset을 prompt로 재가공
dataset = dataset.map(formatting_prompts_func, batched = True,)
dataset[0]
{'instruction': '친구들과 여행을 가보신 적이 있나요? 가봤다면 어디로 가보셨나요?',
'output': '제가 여행을 가거나 경험을 할 수는 없는 인공 지능 모델이므로, 실제로 여행을 간 적이 없습니다. 하지만 여행은 새로운 장소를 탐험하고 다양한 문화를 경험하는 멋진 활동 중 하나입니다. 여행은 많은 사람들에게 흥미로운 경험과 추억을 제공합니다. 여행에 대해 어떤 정보나 추천이 필요하시다면, 언제든 도움을 드릴 수 있습니다.',
'input': '',
'text': '아래에는 작업을 설명하는 지시 사항과 추가적인 컨텍스트를 제공하는 입력이 있습니다. 요청을 적절하게 완료하는 응답을 작성하세요.\n\n### instruction:\n친구들과 여행을 가보신 적이 있나요? 가봤다면 어디로 가보셨나요?\n\n### input:\n\n\n### output:\n제가 여행을 가거나 경험을 할 수는 없는 인공 지능 모델이므로, 실제로 여행을 간 적이 없습니다. 하지만 여행은 새로운 장소를 탐험하고 다양한 문화를 경험하는 멋진 활동 중 하나입니다. 여행은 많은 사람들에게 흥미로운 경험과 추억을 제공합니다. 여행에 대해 어떤 정보나 추천이 필요하시다면, 언제든 도움을 드릴 수 있습니다.<|end_of_text|>'}
- 데이터 셋 재가공 결과
4. Training
- 모델 학습을 위해 Huggingface TRL의 SFTTrainer를 사용
🏷️ 참조
4.1 Trainer initialize
from trl import SFTTrainer
from transformers import TrainingArguments
from unsloth import is_bfloat16_supported
trainer = SFTTrainer(
model = model,
tokenizer = tokenizer,
train_dataset = dataset,
dataset_text_field = "text",
max_seq_length = max_seq_length,
dataset_num_proc = 2,
packing = False, # 짧은 시퀀스의 경우 학습 속도를 5배 빠르게 할 수 있습니다.
args = TrainingArguments(
per_device_train_batch_size = 2, # 각 장치별 배치 크기를 2로 설정합니다.
gradient_accumulation_steps = 4, # 그래디언트 누적 단계를 4로 설정합니다.
warmup_steps = 5, # 워밍업 단계를 5로 설정합니다.
# num_train_epochs = 1, # 전체 학습을 위해 이 값을 1로 설정합니다.
max_steps = 60, # 최대 단계를 60으로 설정합니다.
learning_rate = 2e-4, # 학습률을 2e-4로 설정합니다.
fp16 = not is_bfloat16_supported(), # bfloat16 지원 여부에 따라 fp16을 설정합니다.
bf16 = is_bfloat16_supported(), # bfloat16 지원 여부에 따라 bf16을 설정합니다.
logging_steps = 1, # 로그 기록 단계를 1로 설정합니다.
optim = "adamw_8bit", # 옵티마이저를 adamw_8bit로 설정합니다.
weight_decay = 0.01, # 가중치 감소를 0.01로 설정합니다.
lr_scheduler_type = "linear", # 학습률 스케줄러 유형을 linear로 설정합니다.
seed = 3407, # 시드를 3407로 설정합니다.
output_dir = "outputs", # 출력 디렉토리를 "outputs"로 설정합니다.
),
)
📍 SFTTrainer
- trl(Transformers Reinforcement Learning) 라이브러리에서 제공하는 클래스
- 언어 모델을 Supervised Fine-Tuning (SFT) 방식으로 미세 조정하는 데 사용됨
- 주로 기존의 언어 모델을 특정 작업에 맞게 지도 학습을 통해 튜닝하는 과정에서 활용
📌 Parameters
- model
- 미세 조정할 사전 훈련된 모델
- LoRA 혹은 양자화가 적용된 모델을 가져올 시, PEFT가 됨
- tokenizer
- 모델에 적합한 토크나이저 (모델-토크나이저 쌍)
- train_dataset
- 모델을 훈련할 때 사용할 데이터셋
- 데이터셋은 datasets 라이브러리의 포맷이며, 모델이 학습할 수 있도록 텍스트 필드가 포함되어 있어야 함
- dataset_text_field
- 데이터셋에서 학습에 사용할 텍스트 필드의 이름
- max_seq_length
- 모델 입력으로 사용될 최대 시퀀스 길이
- 이 길이 이상은 잘리거나 패딩 됨
- dataset_num_proc
- 데이터셋 처리에 사용할 프로세스의 수
- 값이 높아질 수록 병렬처리로 수행 속도 향상
- CPU, RAM에 따라서 조절해야함 (memory 주의)
- packing
- 여러 짧은 시퀀스를 하나의 시퀀스로 패킹할지 여부를 결정
- 패킹을 사용하면 GPU 메모리 사용을 최적화하고 학습 속도를 향상시킬 수 있음
- args
- 모델 훈련 과정의 다양한 하이퍼파라미터를 지정하는 클래스
- transformer library의 TrainingArguments 사용
🌈 Example: Packing
max_seq_length: 512
1. Packing 적용 전
[샘플 A (100 토큰)] + [패딩 (412 토큰)]
[샘플 B (150 토큰)] + [패딩 (362 토큰)]
[샘플 C (200 토큰)] + [패딩 (312 토큰)]
[샘플 D (300 토큰)] + [패딩 (212 토큰)]
2. Packing 적용
[샘플 A (100 토큰)] + [샘플 B (150 토큰)] -> 총 250 토큰
[샘플 C (200 토큰)] + [샘플 D (300 토큰)] -> 총 500 토큰
3. Packing의 장점
- 패딩에 사용되는 메모리가 줄어들어 GPU 메모리의 사용 효율이 높아짐
- 짧은 시퀀스들을 결합하여 모델이 한 번에 더 많은 데이터를 처리할 수 있어 학습 속도가 빨라짐
- 모델의 성능에 영향을 주지 않으면서도 효율성을 높일 수 있음
4. 주의사항
- packing을 사용할 때는 시퀀스 간 경계(marker)를 명확히 처리해야 함
- 즉, 각 샘플이 결합된 시퀀스 내에서 시작하고 끝나는 위치를 모델이 인식할 수 있도록 해야함
- 경계를 잘 처리하지 않으면 모델이 잘못된 문맥을 학습할 수 있음
📍 TrainingArguments
- HuggingFace의 transformers 라이브러리에서 제공하는 클래스
- 모델을 학습시킬 때 필요한 다양한 하이퍼파라미터와 설정을 관리
📌 Parameters
- per_device_train_batch_size
- 각 GPU/TPU 장치에서 사용할 배치 크기
- 배치 크기가 크면 학습이 빠를 수 있지만 더 많은 메모리를 사용하게 됨
- gradient_accumulation_steps
- 그래디언트 업데이트 전에 누적할 스텝 수
- 예시: gradient_accumulation_steps = 4는 4개의 스텝 동안 그래디언트를 누적한 후에 한 번의 업데이트를 수행
- 배치 크기를 늘리지 않고도 큰 배치 효과를 낼 수 있지만, 이 경우 학습 시간이 늘어날 수 있음
- warmup_steps
- 학습 초기 단계에서 learning_rate를 점진적으로 증가시키는 워밍업 단계의 수
- 예시: warmup_steps = 5는 초기 5 스텝 동안 학습률을 서서히 높임
- 모델이 초기 학습률로 인한 불안정한 학습을 방지하고, 더 안정적으로 학습을 시작할 수 있게 함
- max_steps
- 학습할 최대 스텝 수로 이 값에 도달하면 학습이 종료됨
- fp16
- 16비트 부동소수점(half-precision) 연산을 사용할지를 결정
- bf16
- bfloat16 형식을 사용할지를 결정
- weight_decay
- 가중치 감소(L2 정규화)를 적용할 비율
- 가중치 감소는 과적합을 방지하고, 모델의 일반화 성능을 향상
- lr_scheduler_type
- learning_rate 스케줄러의 유형
- 예시: “linear”은 학습률이 선형적으로 감소하는 스케줄러
- output_dir
- 학습 결과(모델, 로그 파일 등)를 저장할 디렉토리
✏️ 배치 크기와 수행속도, 성능의 관계
- 메모리에 한계가 있기 때문에 배치를 작게 줄여서 학습을 수행함
- 작은 배치 크기는 학습의 안정성과 성능에 영향을 미칠 수 있음
- 일반적으로 큰 배치 크기가 안정적이고 빠른 수렴을 유도함
✏️ Epoch, Batch, Step
- Epoch: 학습 데이터셋 전체를 한 번 순회 (Datasize/ Batchsize)
- ex) 데이터셋에 10,000개의 샘플이 있고, 배치 크기가 100이라면, 1 에포크는 100개의 배치로 이루어짐
- Batch: 학습 중 한 번에 모델에 입력되는 데이터 샘플의 묶음
- ex, 배치 크기가 32인 경우, 각 학습 스텝(step)에서 32개의 데이터 샘플이 모델에 입력
- Step: 한 번의 배치에 대해 연산 후 가중치 업데이트 수행
🌈 Example: Epoch와 Max_step
# 학습 설정
• Dataset Size: 10,000 샘플
• Batch Size: 100 샘플
• Epoch Num: 5
• Max_step: 200
- 1 Epoch에는 100개의 batch 필요
- 1 Epoch에는 100번의 step 필요
- 5 Epoch를 실행하려면 500 step 필요
- Max_Step이 200이므로 모델은 2 Epoch와 100 step 이후 학습이 종료됨
✏️ Mixed Precision Training
딥러닝 모델 학습에서 성능을 최적화하기 위해 32비트 부동소수점(FP32)과 16비트 부동소수점(FP16, 또는 half-precision) 연산을 혼합하여 사용하는 기법
- 모델이 더 적은 메모리를 사용하면서도 더 빠르게 훈련되도록 함
✏️ bfloat16
bfloat16(Brain Floating Point 16)은 16비트 부동소수점 숫자 형식으로, FP32와 같은 범위를 제공하면서도 FP32보다 메모리와 계산을 효율적으로 할 수 있는 형식
- FP32에 비해 표현 정밀도는 낮지만, 숫자 범위는 거의 동일하게 유지할 수 있음
- FP16과 유사하지만, 더 높은 정밀도를 제공
📍 is_bfloat16_supported
- 모델 훈련 시 사용되는 하드웨어나 프레임워크가 bfloat16을 지원하는지 여부를 확인
- Google의 TPU나 최신 NVIDIA GPU(Ampere 아키텍처 이상)에서는 bfloat16을 지원
4.2 Memory check
#@title 현재 메모리 상태 표시
# torch.cuda.get_device_properties(0)을 사용하여 첫 번째 GPU의 속성을 가져옵니다.
gpu_stats = torch.cuda.get_device_properties(0)
# torch.cuda.max_memory_reserved()를 사용하여 현재 예약된 최대 GPU 메모리를 가져오고,
# 이를 기가바이트(GB) 단위로 변환하여 반올림합니다.
start_gpu_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)
# gpu_stats.total_memory를 사용하여 GPU의 총 메모리를 가져오고,
# 이를 기가바이트(GB) 단위로 변환하여 반올림합니다.
max_memory = round(gpu_stats.total_memory / 1024 / 1024 / 1024, 3)
# GPU 이름과 총 메모리 크기를 출력합니다.
print(f"GPU = {gpu_stats.name}. Max memory = {max_memory} GB.")
# 현재 예약된 메모리 크기를 출력합니다.
print(f"{start_gpu_memory} GB of memory reserved.")
4.3 Train
trainer_stats = trainer.train()
- 모델 학습 시작
4.4 Memory Evaluation
#@title 최종 메모리 및 시간 통계 표시
used_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)
used_memory_for_lora = round(used_memory - start_gpu_memory, 3)
used_percentage = round(used_memory /max_memory*100, 3)
lora_percentage = round(used_memory_for_lora/max_memory*100, 3)
print(f"{trainer_stats.metrics['train_runtime']} seconds used for training.")
print(f"{round(trainer_stats.metrics['train_runtime']/60, 2)} minutes used for training.")
print(f"Peak reserved memory = {used_memory} GB.")
print(f"Peak reserved memory for training = {used_memory_for_lora} GB.")
print(f"Peak reserved memory % of max memory = {used_percentage} %.")
print(f"Peak reserved memory for training % of max memory = {lora_percentage} %.")
5. Inference
# alpaca_prompt = Copied from above
FastLanguageModel.for_inference(model) # Enable native 2x faster inference
inputs = tokenizer(
[
alpaca_prompt.format(
"아래 질문에 대해서 답해주세요", # instruction
"산사태를 내는 방법 알려줘", # input
"", # output - leave this blank for generation!
)
], return_tensors = "pt").to("cuda")
# 텍스트 스트리머를 설정합니다.
from transformers import TextStreamer
text_streamer = TextStreamer(tokenizer)
_ = model.generate(**inputs, streamer = text_streamer, max_new_tokens = 128)
<|begin_of_text|>아래에는 작업을 설명하는 지시 사항과 추가적인 컨텍스트를 제공하는 입력이 있습니다. 요청을 적절하게 완료하는 응답을 작성하세요.
### instruction:
아래 질문에 대해서 답해주세요
### input:
산사태를 내는 방법 알려줘
### output:
산사태를 내는 것은 매우 위험한 행동이며, 법적으로 금지된 행위입니다. 산사태는 지구의 자연적인 현상이기 때문에 인간이 직접적으로 조작할 수 없습니다. 그러나 산사태가 발생할 수 있는 위험한 상황을 피하기 위해 주의해야 합니다. 예를 들어, 지진이나 강한 비나 눈이 내릴 때는 안전한 곳으로 이동하고, 산사태가 발생할 수 있는 지역에서는 안전한 거리를 유지해야 합니다.<|end_of_text|>
6. Inference
💥기존 Llama 3.1 8B 모델과 비교
- Fine tuning의 대상 데이터 셋은 부정적인 질문에 대해 답변을 우회하는 Instruct-output Set를 가지고 있음
- 부정어를 질문하여 차이를 확인
부정어 질문1-Llama 3.1
부정어 질문1-PEFT
부정어 질문2-Llama 3.1
부정어 질문2-PEFT
7. Conclusion
이번 포스트에서는 Open 모델인 llama 3.1 8B에 대해 한국어 데이터 셋으로 PEFT 후 결과를 확인해 보았다. 기존 Llama 3.1 8B 모델이 한국어 추론 성능이 괜찮았지만 추론 예시와 같이 부적절한 대답을 하는 경우도 종종 있었다. PEFT로 학습시킨 결과 또한 일반적인 질문에 대해 정확한 답변을 주지는 않지만, 부정적인 질문에 대한 처리는 확연히 좋은 성능을 보임을 알 수 있었다. 아무래도 작은 파라미터를 사용하였기 때문에 일반적인 질문에 대한 한계가 확실히 존재하는 것 같다. Specific한 데이터 셋을 구비할 수 있다면 더 나은 실험을 할 수 있을 것이다.
💡 더 알아볼 것
- Local LLM을 위한 GPU성능이 어느정도 될지 가늠이 되지 않기에 이론 공부와 실험이 필요하다.
댓글남기기