인공지능/자연어 처리

LLaMa3 LoRA를 통해 parameter efficient fine-tuning 진행하기 1(Matlab 도메인) - python

이게될까 2024. 7. 22. 18:18
728x90
728x90

2024.07.22 - [인공지능/자연어 처리] - 자연어 처리 Python 실습 - Parameter Efficient Fine tuning

 

자연어 처리 Python 실습 - Parameter Efficient Fine tuning

2024.06.05 - [인공지능/자연어 처리] - 자연어 처리 17강 - Parameter efficient Tuning 자연어 처리 17강 - Parameter efficient TuningLLM의 파라미터를 효율적으로, 효과적으로 튜닝하는 방법이다.언어 모델은 Semi s

yoonschallenge.tistory.com

여기서 배운 내용을 토대로 파인튜닝을 진행해야 합니다.

일단 LLaMa3 모델을 받아와야 하는데...

리눅스에서 다운받아와서 옮기겠습니다.

다 다운받고 보니까 어떻게 써야 하는거지 했는데 그럴 필요가 없었네요 ㅎㅎ......

 

https://www.datacamp.com/tutorial/llama3-fine-tuning-locally#rdl

여기서 사용법은 알아냈습니다.

 

이제 데이터 셋을 준비해야 하는데 영어 데이터를 획득해야 겠네요

matlab을 들어가서 어떻게 찾을지 고민해보겠습니다.

 

일단 잘 되는지 확인하기 위해 한개의 사이트 분량만 학습시켜봤습니다.

https://kr.mathworks.com/help/driving/ref/drivingscenariodesigner-app.html

 

Design driving scenarios, configure sensors, and generate synthetic data - MATLAB - MathWorks 한국

Starting in R2018b, in the Camera Settings group of the Driving Scenario Designer app, the Image Width and Image Height parameters set their expected values. Previously, Image Width set the height of images produced by the camera, and Image Height set the

kr.mathworks.com

import requests
from bs4 import BeautifulSoup
import pandas as pd
import re

file_path = 'matlabData.txt'
with open(file_path, 'r', encoding='utf-8') as file:
    data = file.read()

# \n, \t와 같은 불필요한 공백 문자 제거
data = re.sub(r'[\n\t\r]', ' ', data)

# 텍스트 정제 및 문장 단위로 나누기
sentences = re.split(r'(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?)\s', data)
sentences = [sentence.strip() for sentence in sentences if sentence.strip()]

# 중복 문장 제거 (순서 유지)
unique_sentences = list(dict.fromkeys(sentences))

# 데이터프레임 생성
df = pd.DataFrame(unique_sentences, columns=['Text'])

df.to_csv('/mnt/data/cleaned_matlab_data.csv', index=False)

웹을 그냥 긁어와서 txt에 넣으면 전처리해줍니다. 

데이터 양은 얼마 안됩니다....

 

이제 Kaggle에서 LLaMa를 불러옵시다.

https://www.kaggle.com/models/metaresearch/llama-3

 

Meta | Llama 3 | Kaggle

Llama 3 is a collection of pretrained and fine-tuned generative text models ranging in scale from 8 billion to 70 billion parameters

www.kaggle.com

이 사이트에 처음 들어가면 허가 받으라고 할 겁니다.

저는 이미 허가를 받아서 2로 대충 짤라 보여드렸습니다.

신청하고 10분도 안되어서 허가가 났습니다.

그럼 kaggle code에서 모델을 불러와 주면 됩니다.

이렇게 모델을 불러올 수 있습니다.

저는 GPU도 없고, 학습할 데이터도 많이 없으니 8b모델을 통해 공짜 GPU로 학습시켜보겠습니다.

%pip install -U transformers 
%pip install -U datasets 
%pip install -U accelerate 
%pip install -U peft 
%pip install -U trl 
%pip install -U bitsandbytes

필요한 패키지들 다 설치해줍니다.

from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    BitsAndBytesConfig,
    HfArgumentParser,
    TrainingArguments,
    pipeline,
    logging,
    Trainer,
    DataCollatorForLanguageModeling
)
from peft import (
    LoraConfig,
    PeftModel,
    prepare_model_for_kbit_training,
    get_peft_model,
)
import os, torch
from datasets import load_dataset

필요한 라이브러리들 다 import 해줍니다.

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
device

GPU도 올려주고

base_model = "/kaggle/input/llama-3/transformers/8b-hf/1"
new_model = "llama-3-8b-matlab"
dataset = load_dataset('csv', data_files='/kaggle/input/clean-matlabdata/cleaned_matlab_data.csv')

모델들 이름이랑 경로 지정해주기

# QLoRA config
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch_dtype,
    bnb_4bit_use_double_quant=True,
)

# Load model
model = AutoModelForCausalLM.from_pretrained(
    base_model,
    quantization_config=bnb_config,
    device_map="auto",
    attn_implementation=attn_implementation
)

이 부분은 살짝 어려워서 ...

더보기

이 코드는 Kaggle에서 LLaMa3 모델을 사용할 때, 모델을 양자화(quantization)하여 메모리 효율을 높이는 방법을 설명하는 예제입니다. 여기서 중요한 부분은 BitsAndBytesConfig를 사용하여 4비트 양자화 설정을 구성하고, 이를 사용하여 모델을 로드하는 과정입니다.

각 줄을 차례대로 설명해 보겠습니다.

QLoRA 설정

  1. BitsAndBytesConfig 객체 생성:
    • 이 객체는 양자화 설정을 정의합니다.
  2. load_in_4bit=True:
    • 모델을 4비트 정밀도로 로드합니다. 이는 메모리 사용량을 줄이고 모델을 더 효율적으로 실행할 수 있게 합니다.
  3. bnb_4bit_quant_type="nf4":
    • 4비트 양자화의 타입을 설정합니다. 여기서 "nf4"는 Non-negative Fractional 4-bit을 의미합니다.
  4. bnb_4bit_compute_dtype=torch_dtype:
    • 계산 시 사용할 데이터 타입을 지정합니다. torch_dtype는 PyTorch에서 지원하는 데이터 타입을 의미합니다.
  5. bnb_4bit_use_double_quant=True:
    • 이 옵션은 더블 양자화를 사용하도록 설정합니다. 이는 양자화의 정확성을 높이는 데 도움을 줄 수 있습니다.

모델 로드

  1. AutoModelForCausalLM.from_pretrained:
    • Hugging Face Transformers 라이브러리의 메서드로, 사전 학습된 언어 모델을 로드합니다.
  2. base_model:
    • 사전 학습된 모델의 이름 또는 경로입니다. 예를 들어, "gpt-3" 같은 모델을 지정할 수 있습니다.
  3. quantization_config=bnb_config:
    • 앞서 설정한 bnb_config를 양자화 설정으로 사용합니다.
  4. device_map="auto":
    • 모델을 자동으로 가능한 장치에 배치합니다. 이는 CPU와 GPU를 포함할 수 있습니다.
  5. attn_implementation=attn_implementation:
    • 주의 메커니즘(Attention mechanism)의 구현 방식을 지정합니다. 이는 모델의 성능 최적화를 위해 사용될 수 있습니다.

이 코드는 대용량 언어 모델을 메모리 효율적으로 사용하기 위한 설정과 로딩 과정을 설명하고 있으며, 특히 4비트 양자화를 통해 메모리 사용량을 줄이고 모델을 더 빠르게 실행할 수 있게 합니다.

 

# Load tokenizer
tokenizer = AutoTokenizer.from_pretrained(base_model)

토크나이저를 불러옵니다.

# LoRA config
peft_config = LoraConfig(
    r=16,
    lora_alpha=32,
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
    target_modules=['up_proj', 'down_proj', 'gate_proj', 'k_proj', 'q_proj', 'v_proj', 'o_proj']
)
model = get_peft_model(model, peft_config)

로라 만들어주기!

더보기
 

이 코드는 LLaMa3 모델에 LoRA (Low-Rank Adaptation) 설정을 적용하는 예제입니다. LoRA는 모델의 적응을 저비용으로 구현할 수 있는 기술로, 파인튜닝 과정에서 필요한 메모리와 계산량을 줄이는 데 사용됩니다.

각 줄을 차례대로 설명해 보겠습니다.

LoRA 설정

  1. LoraConfig 객체 생성:
    • LoRA 설정을 정의하는 객체를 생성합니다.
  2. r=16:
    • LoRA의 랭크(순위)를 설정합니다. 랭크는 저차원 행렬의 크기를 결정하는 데 사용되며, 모델의 파라미터 수를 줄이기 위해 사용됩니다.
  3. lora_alpha=32:
    • LoRA의 스케일링 팩터를 설정합니다. 이는 저차원 행렬에서 계산된 값을 스케일링하는 데 사용됩니다.
  4. lora_dropout=0.05:
    • 드롭아웃 확률을 설정합니다. 드롭아웃은 학습 과정에서 과적합을 방지하기 위해 일부 뉴런의 출력을 무작위로 0으로 설정하는 기법입니다.
  5. bias="none":
    • 모델의 바이어스를 설정하는 방법을 지정합니다. 여기서는 바이어스를 사용하지 않도록 설정되어 있습니다.
  6. task_type="CAUSAL_LM":
    • LoRA가 적용될 작업의 유형을 설정합니다. 여기서는 Causal Language Modeling (CAUSAL_LM)으로 설정되어 있습니다.
  7. target_modules=['up_proj', 'down_proj', 'gate_proj', 'k_proj', 'q_proj', 'v_proj', 'o_proj']:
    • LoRA를 적용할 모델의 특정 모듈들을 지정합니다. 이는 LoRA가 적용될 모델의 부분을 지정하는데, 여기서는 여러 프로젝션(projection) 모듈들에 LoRA가 적용됩니다.

 

def tokenize_function(examples):
    return tokenizer(examples['Text'], padding='max_length', truncation=True)
    
    
tokenized_dataset = dataset.map(tokenize_function, batched=True)

토큰화도 진행

 

model = get_peft_model(model, peft_config)

기존 LLaMa3 에서 LoRA를 합쳐서 새로운 모델을 만들어 줍니다.

training_args = TrainingArguments(
    output_dir="./results",
    overwrite_output_dir=True,
    num_train_epochs=3,
    per_device_train_batch_size=4,
    save_steps=10_000,
    save_total_limit=2,
    prediction_loss_only=True,
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_dataset['train'],
    data_collator=DataCollatorForLanguageModeling(
        tokenizer=tokenizer,
        mlm=False,
    ),
)

트레이너 만들어주기!

epoch은 3을 주면 절대로 안되는 것 같습니다. 모델이 이상해졌어요 ㅎㅎ....

test_sentences = [
    "what is a driving scenario.",
    "what is a matlab."
]

# 입력 데이터를 토큰화
inputs = tokenizer(test_sentences, return_tensors='pt', padding=True, truncation=True)

이제 모델 평가해보기!

model.eval()

# 입력 데이터를 모델에 전달하여 예측 수행
with torch.no_grad():
    outputs = model(**inputs)

# 출력 토큰을 디코딩하여 텍스트로 변환
predicted_texts = [tokenizer.decode(output, skip_special_tokens=True) for output in outputs.logits.argmax(dim=-1)]

# 예측 결과 출력
for i, sentence in enumerate(test_sentences):
    print(f"Input: {sentence}")
    print(f"Predicted: {predicted_texts[i]}")

Input: what is a driving scenario.
Predicted:  you the lane route? A
Input: what is a matlab.
Predicted:  you the lane function Driving import

네 바보입니다.

epoch 3도 무리였나 싶고, 데이터 자체도 너무 적은 것이 문제였던 것 같네요 ㅎㅎ...

728x90