본문 바로가기

LLM/Llama

Code Llama FineTune

<목차>

Llama2 특징

Supervised Fine-Tuning (SFT)

Reinforcement Learning from Human Feedback (RLHF)

언패킹 LoRA 기술

필요 라이브러리

모델과 토큰나이저 세팅

양자화 설정


Llama2 특징

Llama2는 확장된 컨텍스트 길이와 모델의 추론 확장성을 향상시키는 GQA(Grouped Query Attention)의 혁신적인 도입을 자랑합니다.

 

트레이닝 코퍼스(Training Corpus): 방대한 2조 개의 토큰으로 트레이닝된 이 모델은 노출된 데이터의 폭에 있어서는 전혀 뒤떨어지지 않습니다.

4K로 확장된 컨텍스트 길이를 통해 모델은 광범위한 콘텐츠를 파악하고 생성할 수 있습니다.

GQA(Grouped Query Attention): 추론 확장성을 개선하기 위해 채택된 GQA는 이전 토큰 쌍을 캐싱하여 어텐션 계산을 가속화합니다.

성능: Llama 2 모델은 지속적으로 이전 모델보다 성능이 뛰어났습니다. 이 모델은 다양한 벤치마크에서 빛을 발하며 Llama 1 65B 및 Falcon 모델과 같은 경쟁사에 비해 우월합니다.

 

튜닝

- LLaMA ChatLLaMA Chat 대화 사용 사례에 최적화된 LLaMA Chat은 대화 능력을 향상시키기 위해 백만 개가 넘는 주석에 대한 교육을 받았습니다.

- Code LLaMA: 코드 생성에 중점을 두고 Python, Java, C++와 같은 여러 프로그래밍 언어를 지원합니다. 5,000억 개의 코드 토큰으로 구성된 대규모 코퍼스에 대해 훈련되어 프로그래밍 관련 작업에 대한 전문성을 보여줍니다

.

 

Supervised Fine-Tuning (SFT)

- SFT(Supervised Fine-Tuning)는 사전 훈련된 언어 모델이 인간 감독 하에 더 작은 작업별 데이터 세트에서 추가로 훈련(미세 조정)되는 프로세스입니다. 목표는 모델의 일반 지식을 특정 작업이나 영역에 적용하는 것

- 특정 데이터 셋에 과적합 되지 않는게 중요

 

Reinforcement Learning from Human Feedback (RLHF)

- RLHF(Reinforcement Learning from Human Feedback)는 LLaMA2와 같은 언어 모델의 성능을 더욱 개선하는 데 사용되는 고급 미세 조정 기술입니다. 여기에는 인간 상호 작용에서 파생된 피드백을 사용하여 모델을 교육하는 작업이 포함

- 강화 학습 패러다임 기반

- 미세 조정 방법은 대화 생성, 윤리적 추론 또는 창의적인 글쓰기와 같은 복잡하고 주관적인 작업에서 모델의 성능을 향상시키는 데 특히 유용합니다. RLHF는 모델이 인간 의사소통의 뉘앙스와 미묘함을 이해하도록 도와줌으로써 보다 적절하고 상황에 민감하며 인간과 유사한 반응을 생성

 

언패킹 LoRA 기술

Parameter-Efficient Fine-Tuning (PEFT)

- PEFT 기술은 BERT, GPT 계열이 새로운 테스크에 FT 하는 방법을 제공한다.

- 이는 모델 매개변수의 작은 하위 집합에 초점을 맞춰 미세 조정 프로세스를 보다 효율적이고 리소스 집약적이지 않게 만들어 달성

- PEFT에서 널리 사용되는 두 가지 방법은 LoRA(Low-Rank Adaptation)와 QLoRA(Quantized Low-Rank Adaptation)

 

- 과적합 감소: 제한된 데이터 세트로 인해 문제가 발생할 수 있습니다. 매개변수를 너무 많이 수정하면 모델이 과적합될 수 있습니다. PEFT를 사용하면 모델의 다양성의 균형을 유지하면서 새로운 작업에 맞게 조정할 수 있습니다.

- 신속한 훈련: 매개변수 조정이 적다는 것은 계산 횟수가 적다는 것을 의미하므로 훈련 세션이 더 빨라집니다.

- 리소스가 많이 소요됨: 심층 신경 훈련은 리소스 집약적입니다. PEFT는 계산 및 메모리 부담을 최소화하여 리소스가 부족한 시나리오에서 배포를 보다 실용적으로 만듭니다.

- 지식 보존: 광범위한 데이터 세트에 대한 광범위한 사전 교육을 통해 모델에 귀중한 일반 지식이 포함됩니다. PEFT를 사용하면 모델을 새로운 작업에 적용할 때 이 보물이 손실되지 않도록 보장합니다.

 

LoRA 설명
1) LoRA는 모델 내 특정 레이어의 가중치만 수정하는 데 중점을 두고, 특히 작업에 가장 영향을 미치는 레이어를 대상으로 합니다.
2) 이는 모델의 순방향 전달 중에 이러한 가중치를 변환하기 위해 낮은 순위 행렬(Low-Rank Matrices)을 적용하여 수행 
3) LoRA의 장점은 모델의 원래 매개변수 수를 유지하므로 광범위한 수정 없이 배포가 더 쉽다는 것

QLoRA 설명
1) QLoRA에는 모델의 매개변수를 양자화하여 성능을 유지하면서 가중치의 정밀도를 줄이는 작업이 포함됩니다.
2) 이 접근 방식은 모델의 메모리 공간과 계산 요구 사항을 크게 줄이므로 리소스가 제한된 환경에 모델을 배포하는 데 특히 유용합니다.

 

- LoRA는 학습 파라미터를 10,000배 감소 시켰습니다.

- 일반적으로 주요 병목 현상인 GPU 요구 사항이 3배 감소합니다.
- 전체 모델을 미세 조정하지 않더라도 성능은 비슷하거나 더 좋습니다.

- 미세 조정 시 새로운 예를 사용하여 사전 훈련된 모델의 기존 가중치를 수정합니다. 전통적으로 이를 위해서는 동일한 크기의 행렬이 필요했습니다.

- 그러나 약간의 창의성과 순위 분해(Rank Factorization) 개념을 사용하면 행렬을 두 개의 작은 행렬로 나눌 수 있습니다. 곱해지면 원래 행렬에 가까워집니다.

 

 

 

- 시각화하려면 1,000,000개의 매개변수에 해당하는 1000×1000 행렬을 고려해 보세요. 순위 인수분해 (Rank Factorization) 를 사용하면 Rank 5라면 둘 다 1000×5인 두 개의 행렬을 가질 수 있습니다. 이를 합치면 단 10,000개의 매개변수만 나타냅니다. 이는 엄청난 감소입니다.

 

필요 라이브러리

!pip install -q accelerate==0.21.0 peft==0.4.0 bitsandbytes==0.40.2 transformers==4.31.0 trl==0.4.7
 
import os, torch, logging
from datasets import load_dataset
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, HfArgumentParser, TrainingArguments, pipeline
from peft import LoraConfig, PeftModel
from trl import SFTTrainer

 

- 이는 널리 알려진 timdettmers/openassistant-guanaco 데이터 세트의 하위 집합이며 1,000개의 샘플을 포함합니다. Llama 2의 프롬프트 형식과 호환되도록 처리되었습니다.

- 이러한 샘플은 Llama 2의 프롬프트 형식과 원활하게 일치하도록 특수 처리되어 추가 수정 없이 교육에 직접 사용할 수 있습니다.

 

- 이 하위 집합은 이미 Llama 2의 프롬프트 형식에 맞게 처리되었으므로 특정 애플리케이션에 대한 모델을 훈련하는 데 직접 사용할 수 있습니다. 이는 timdettmers/openassistant-guanaco 데이터 세트 스타일로 언어를 이해하고 생성해야 하는 챗봇, 가상 비서 또는 기타 애플리케이션을 만드는 데 사용될 수 있습니다.

- 변형: Hugging Face의 데이터 세트 저장소에서 사용할 수 있는 다른 대화 데이터 세트를 사용해 다양한 대화 스타일로 모델을 훈련하는 것을 고려해 보세요. Hugging Face의 Abirate/english_quotes 데이터세트는 Goodreads의 인용문으로 구성됩니다.

 

모델과 토큰나이저 세팅

- 미리 학습된 Llama2 모델을 ' llama-2-7b-mlabonne-enhanced'로 정하였다.

- fp16 작업과의 호환성을 보장하기 위해 토크나이저가 로드되고 약간 조정되었습니다.

반정밀도 부동 소수점 숫자(fp16)로 작업하면 메모리 소비 감소, 모델 훈련 속도 향상 등 여러 가지 이점을 얻을 수 있습니다

- 그러나 모든 작업이 바로 이 감소된 정밀도 형식과 호환되는 것은 아닙니다. 여기에는 모델 교육을 위한 텍스트 데이터를 준비하는 데 중요한 단계인 토큰화가 포함됩니다.

 

사전 훈련된 Llama 2 모델에는 양자화 구성이 로드됩니다. 그런 다음 캐싱을 비활성화하고 사전 훈련 온도 매개변수를 설정합니다.

 

- 모델 크기를 줄이고 추론 속도를 높이기 위해 BitsAndBytesConfig에서 제공하는 4비트 양자화를 사용합니다. 모델을 양자화한다는 것은 더 적은 메모리를 사용하는 방식으로 모델의 가중치를 표현하는 것을 의미합니다.

 

- 여기 구성에서는 양자화를 위해 'nf4' 유형을 사용합니다. 다양한 양자화 유형을 실험하여 잠재적인 성능 변화를 확인하세요.

 

# Dataset
data_name = "mlabonne/guanaco-llama2-1k"
training_data = load_dataset(data_name, split="train")
 
# Model and tokenizer names
base_model_name = "NousResearch/Llama-2-7b-chat-hf"
refined_model = "llama-2-7b-mlabonne-enhanced"
 
# Tokenizer
llama_tokenizer = AutoTokenizer.from_pretrained(base_model_name, trust_remote_code=True)
llama_tokenizer.pad_token = llama_tokenizer.eos_token
llama_tokenizer.padding_side = "right" # Fix for fp16
 
# Quantization Config
quant_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_use_double_quant=False
)
 
# Model
base_model = AutoModelForCausalLM.from_pretrained(
base_model_name,
quantization_config=quant_config,
device_map={"": 0}
)
base_model.config.use_cache = False
base_model.config.pretraining_tp = 1

 

양자화 설정

- 드롭아웃 비율(lora_dropout) 과적합을 방지하기 위해 훈련 중에 각 뉴런의 출력이 0으로 설정될 확률입니다. 과적합을 방지하기 위해 훈련 중에 각 뉴런의 출력이 0으로 설정될 확률입니다.

 

- 랭크(r): 순위는 기본적으로 원래 가중치 행렬이 더 간단하고 작은 행렬로 분할되는 방식을 측정한 것입니다. 이렇게 하면 계산 요구 사항과 메모리 소비가 줄어듭니다. 순위가 낮을수록 모델이 더 빨라지지만 성능이 저하될 수 있습니다원래 LoRA 논문에서는 8순위부터 시작할 것을 제안했지만 QLoRA의 경우 64순위가 필요합니다.

 

- lora_alpha: 이 매개변수는 낮은 랭크 근사치의 스케일링을 제어합니다. 이는 원래 모델과 낮은 순위 근사치 사이의 균형을 맞추는 행위와 같습니다. 값이 높을수록 미세 조정 프로세스에서 근사치가 더 큰 영향력을 발휘하여 성능과 계산 비용 모두에 영향을 미칠 수 있습니다.

 

# LoRA Config
peft_parameters = LoraConfig(
lora_alpha=16,
lora_dropout=0.1,
r=8,
bias="none",
task_type="CAUSAL_LM"
)
 
# Training Params
train_params = TrainingArguments(
output_dir="./results_modified",
num_train_epochs=1,
per_device_train_batch_size=4,
gradient_accumulation_steps=1,
optim="paged_adamw_32bit",
save_steps=25,
logging_steps=25,
learning_rate=2e-4,
weight_decay=0.001,
fp16=False,
bf16=False,
max_grad_norm=0.3,
max_steps=-1,
warmup_ratio=0.03,
group_by_length=True,
lr_scheduler_type="constant"
)
 
# Trainer
fine_tuning = SFTTrainer(
model=base_model,
train_dataset=training_data,
peft_config=peft_parameters,
dataset_text_field="text",
tokenizer=llama_tokenizer,
args=train_params
)
 
# Training
fine_tuning.train()
 
# Save Model
fine_tuning.model.save_pretrained(refined_model)

 

- 트레이너를 정의한 다음 학습 프로세스가 시작된다.

# Generate Text
query = "How do I use the OpenAI API?"

text_gen =
pipeline(
task="text-generation",
model=refined_model,
tokenizer=llama_tokenizer,
max_length=
200)

output = text_gen(f"<s>
[INST] {query} [/INST]
"
)
print(output[0]['generated_text'])

 

 

- GAtt(Ghost Attention) 도입. GAtt(Ghost Attention) 방법은 여러 차례에 걸쳐 대화 흐름을 유지하는 모델의 능력을 향상시킵니다. 예를 들어 모델이 이모티콘만 사용하여 응답하도록 지시받은 경우 GAtt는 모델이 두 번째 메시지로 잊어버릴 수 있는 GAtt가 없는 것과 달리 대화 전체에서 이 지시를 기억하도록 보장합니다.

 

- 미세 조정은 LLM의 잠재력을 최대한 활용하는 데 중추적인 역할을 합니다. 사전 훈련은 모델이 방대한 텍스트 말뭉치에서 학습할 수 있도록 하여 기반을 마련하는 반면, 미세 조정은 특정 작업에 맞게 모델을 선명하게 만듭니다. 

 

- Llama 2의 미세 조정 프로세스에는 SFT(감독 미세 조정)와 RLHF(인간 피드백을 통한 강화 학습)를 포함한 정렬 기술의 조합이 통합되어 있습니다. 이 엄격한 프로세스에는 모델에 특정 프롬프트를 제시하고 응답을 개선하여 모델이 인간의 선호도 및 안전 조치에 부합하는지 확인하는 작업이 포함됩니다.

 

- Llama 2와 같은 LLM(대형 언어 모델)에서 최대한의 결과를 추출하려는 경우 미세 조정이 필수적입니다. 초기 사전 학습 단계에서는 광범위한 텍스트 말뭉치에서 파생된 광범위한 지식 기반을 제공하지만 모델을 맞춤화하는 것은 미세 조정입니다. 전문적인 작업을 위해. 실험에서는 일반적인 SFT(Supervised Fine-Tuning) 또는 RLHF(Reinforcement Learning with Human Feedback)를 채택하는 대신 LoRA(Low-Rank Adaptation)의 기능을 활용했습니다.

미세 조정에 LoRA를 사용하면 얻을 수 있는 이점:

- 효율성: LoRA는 훈련 가능한 매개변수를 줄여 메모리와 비용을 절약합니다.
- 성능: 더 적은 수의 매개변수에도 불구하고 우월하지는 않더라도 비슷한 결과를 얻었습니다.
- 확장성: LoRA의 순위 분해를 통해 제한된 설정에서도 Llama 2와 같은 대규모 모델을 관리할 수 있습니다.

T4 GPU가 장착된 Google Colab에서 LoRA를 사용하여 효율적인 교육 세션을 경험했으며 기존 방법에서 볼 수 있었던 예상 기간을 단축했습니다.

GPU 메모리 활용도는 12GB에 불과했습니다. 이러한 효율성은 일반적인 메모리 부족 문제 없이 보다 원활한 교육을 의미합니다.

 

또한 중요한 과제는 낮은 처리량을 관리하는 것입니다. 이로 인해 응답 시간이 느려지고 여러 사용자 요청을 동시에 처리하기가 어려워집니다. 처리량을 향상시키기 위해 더 비싼 고성능 하드웨어가 필요한 경우가 많아 운영 비용이 증가합니다. 따라서 이러한 하드웨어에 투자해야 할 필요성으로 인해 이러한 모델을 배포하는 데 드는 계산 비용이 추가됩니다.

 


<전체 코드>

!pip install -q accelerate==0.21.0 peft==0.4.0 bitsandbytes==0.40.2 transformers==4.31.0 trl==0.4.7

import os, torch, logging
from datasets import load_dataset
from transformers import (
	AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, TrainingArguments,
    HfArgumentParser, pipeline
)
from peft import LoraConfig, PeftModel
from trl import SFTTrainer

# Dataset
data_name = "mlabonne/guanaco-llama2-1k"
training_data = load_dataset(data_name, split="train")

# Model and tokenizer names
base_model_name = "NousResearch/Llama-2-7b-chat-hf"
refined_model = "llama-2-7b-mlabonne-enhanced"

# Tokenizer
llama_tokenizer = AutoTokenizer.from_pretrained(base_model_name, trust_remote_code=True)
llama_tokenizer.pad_token = llama_tokenizer.eos_token
llama_tokenizer.padding_side = "right"  # Fix for fp16

# Quantization Config
quant_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.float16,
    bnb_4bit_use_double_quant=False
)

"""
load_in_4bit : 4-bit quantization 가중치 로드 여부
bnb_4bit_quant_type : 저장 데이터 타입, base 모델의 양자화 방식 선택 ("nf4": normalized float 4)
bnb_4bit_compute_dtype : 연산 데이터 타입
bnb_4bit_use_double_quant : Nested quantization 사용 여부
"""

# Model
base_model = AutoModelForCausalLM.from_pretrained(
    base_model_name,
    quantization_config=quant_config,
    device_map={"": 0}
)
base_model.config.use_cache = False
base_model.config.pretraining_tp = 1

# LoRA Config
peft_parameters = LoraConfig(
    lora_alpha=16,
    lora_dropout=0.1,
    r=8,
    bias="none",
    task_type="CAUSAL_LM"
)
# Training Params
train_params = TrainingArguments(
    output_dir="./results_modified",
    num_train_epochs=1,
    per_device_train_batch_size=4,
    gradient_accumulation_steps=1,
    optim="paged_adamw_32bit",
    save_steps=25,
    logging_steps=25,
    learning_rate=2e-4,
    weight_decay=0.001,
    fp16=False,
    bf16=False,
    max_grad_norm=0.3,
    max_steps=-1,
    warmup_ratio=0.03,
    group_by_length=True,
    lr_scheduler_type="constant"
)
# Trainer
fine_tuning = SFTTrainer(
    model=base_model,
    train_dataset=training_data,
    peft_config=peft_parameters,
    dataset_text_field="text",
    tokenizer=llama_tokenizer,
    args=train_params
)
# Training
fine_tuning.train()
# Save Model
fine_tuning.model.save_pretrained(refined_model)

 


대화형 모델: mlabonne/CodeLlama-2-20k · Datasets at Hugging Face

 

mlabonne/CodeLlama-2-20k · Datasets at Hugging Face

<s>[INST] <<SYS>> Below is an instruction that describes a task. Write a response that appropriately completes the request. <</SYS>> Create an array of length 15 containing numbers divisible by 3 up to 45. [/INST] arr = [3, 6, 9, 12, 15, 18, 21, 24, 27, 30

huggingface.co

 

생성형 모델: bigcode/codellama-generations · Datasets at Hugging Face

 

bigcode/codellama-generations · Datasets at Hugging Face

 

huggingface.co


참고 사이트

LLaMA 2 Fine Tuning: Building Your Own LLaMA, Step by Step (run.ai)

 

LLaMA 2 Fine Tuning: Building Your Own LLaMA, Step by Step

Introduced by Meta in 2023, LLaMA2 is an open-source language model part of the LLaMA family, ranging from 7 to 70 billion parameters.

www.run.ai

 

반응형

'LLM > Llama' 카테고리의 다른 글

[Llama-recipes] Readme.md 톺아보기  (0) 2024.03.11
[Llama-recipes] LLM_finetuning  (0) 2024.03.04
Code llama 개요  (0) 2024.02.18