우선 27억 개의 파라미터로 구성된 SLM(Small Language Model)인 Microsoft의 Phi-2 LLM을 살펴보고, 이를 통해 LLM의 미세 조정하는 방법에 대해 알아보겠습니다.
Phi-2와 기본 활용 튜토리얼
LLM Fine-tuning 방법론과 절차 실습
1. What is Phi-2?
Phi-2는 Microsoft Research에서 개발한 27억 개의 매개변수를 가진 언어 모델로 규모가 훨씬 큰 모델에 비해 최첨단 성능을 달성하는 것을 목표로 하는 Microsoft의 소형 언어 모델인 "Phi" 시리즈의 2번째 버전이다.
Phi-2는 트랜스포머 아키텍처를 사용하는 언어 모델로 자연어 처리 및 코딩을 위해 합성 및 웹 데이터 세트의 조합으로부터 1조 4천억 개의 토큰을 학습했다. 인간의 피드백을 통한 강화 학습(RLHF)을 통해 미세 조정되거나 정렬되지 않은 기본 모델이다..=
Phi-2의 개발은 두 가지 핵심 인사이트를 중심으로 이루졌다:
학습 데이터의 품질: '교과서 수준의' 데이터를 강조하는 이 접근 방식은 합성 데이터 세트와 고가치 웹 콘텐츠를 활용하여 상식적인 추론, 일반 지식, 과학, 일상 활동 등에 대해 모델을 가르치는 데 중점을 둔다.
확장된 지식 전달: 13억 개의 매개변수 모델 Phi-1.5의 지식을 27억 개의 매개변수 Phi-2에 포함하면 학습 프로세스가 가속화되고 Phi-2 벤치마크 점수가 향상된다.
Phi-2 compared to other language models
Phi-2는 상식 추론, 언어 이해, 수학 및 코딩을 아우르는 여러 벤치마크에서 Llama-2 및 Mistral과 같은 7B-13B 파라미터 모델의 성능을 뛰어넘는다.. 코딩과 수학 등 다단계 추론이 필요한 작업에서는 25배 더 큰 Llama-2-70B 모델보다 성능이 뛰어나다.
image8.png
모델은 모바일 기기에 직접 설치하여 대형 언어 모델과 유사한 성능을 달성할 수 있다. Phi-2는 빅 벤치 하드, BoolQ, MBPP 벤치마크에서 더 작은 크기에도 불구하고 구글 제미니 나노 2보다 성능이 뛰어나다.
from IPython.display import Markdown
prompt = "Please create a Python application that can change wallpapers automatically."
outputs = pipe(
prompt,
max_new_tokens=300,
do_sample=True,
temperature=0.7,
top_k=50,
top_p=0.95,
)
Markdown(outputs[0]["generated_text"])
3. Basic Operations
Q&A
outputs = pipe( "Who is the richest person in the world?",max_new_tokens=70)
print(outputs[0]["generated_text"])
Who is the richest person in the world? The richest person in the world is Jeff Bezos, the founder of Amazon. He is worth $137 billion.
Code
prompt = '''def num_triangle(n):
"""
Print all numbers in array in a triangular shape
"""'''
outputs = pipe(prompt,max_new_tokens=120)
print(outputs[0]["generated_text"])
"""
Print all numbers in array in a triangular shape
"""
for i in range(1, n+1):
for j in range(1, i+1):
print(j, end=" ")
print()
Chat
from transformers import pipeline, Conversation
model_name = "microsoft/phi-2"
pipe = pipeline(
"conversational",
model=model_name,
device_map="auto",
trust_remote_code=True,
)
conversation_1 = Conversation("Hello, what's the current weather situation in Ireland?")
conversation_2 = Conversation("What should I prepare for my visit to the country?")
chat = pipe([conversation_1, conversation_2])
for i in range(len(chat)):
print("user: ",chat[i].messages[0]["content"].split("<|im_end|>")[0])
print("assistant: ",chat[i].messages[1]["content"].split("<|im_end|>")[0],"\n")
user: Hello, what's the current weather situation in Ireland?
assistant: The current weather in Ireland is sunny with a high of 25....
user: What should I prepare for my visit to the country?
assistant: You should prepare your passport, visa, and any necessary.....
# Save the fine-tuned model & model push
trainer.model.save_pretrained(new_model)
trainer.push_to_hub(new_model)
Model Evaluation
logging.set_verbosity(logging.CRITICAL)
prompt = '''
<|system|>Wonder Woman is a warrior princess of the Amazons with a strong sense of justice and a mission.
<|user|> What motivates you to fight for peace and love?
<|assistant|>
'''
pipe = pipeline(
task="text-generation",
model=model,
tokenizer=tokenizer,
max_length=200
)
result = pipe(prompt) print(result[0]['generated_text'])
prompt = '''
<|system|>In a galaxy far, far away, there exists a wise and powerful Jedi Master known as Yoda.
<|user|> What is the meaning of love?
<|assistant|>
'''
result = pipe(prompt) print(result[0]['generated_text'])
Fine-tuning 예제 실습: QLoRA, PEFT, SFTT
finetuning에 들어가기 전에 먼저 LLM 학습 프로세스를 이해해 보겠습니다.대규모 언어 모델에는 두 가지 주요 프로세스가 있는데 하나는 사전 학습이고 다른 하나는 미세 조정입니다.
Pre-training
Pre-traing은 모델이 라벨링되지 않은 방대한 양의 텍스트 데이터에 노출되는 훈련의 초기 단계입니다. 이 단계에서 모델은 시퀀스의 다음 단어를 예측하거나 누락된 단어를 채워 넣음으로써 언어 내의 구조, 패턴 및 관계를 이해하는 방법을 학습합니다. 이 과정을 통해 모델은 문법, 구문, 의미론에 대한 기초적인 이해를 쌓을 수 있습니다.
Fine-tuning
반면에 fine-tuning이라 불리는 미세조정은 또는 인스트럭션 조정은 사전 학습된 모델을 더 작은 데이터 세트에 대해 추가로 학습시켜 특정 작업이나 도메인에 맞게 지식을 조정하는 프로세스입니다. 이 프로세스는 특정 작업을 수행하기 위해 모델의 매개변수(model parameters)를 조정합니다.
예를 들어, 다양한 웹 기사 집합에 대해 사전 학습된 모델은 의료 질문에 대한 답변 작업에서 즉시 잘 수행하지 못할 수 있습니다. 미세 조정에는 두 가지 방법이 있습니다:
Supervised fine tuning (SFT): 모델은 레이블이 지정된 데이터 세트에 대해 학습됩니다. 레이블이 지정된 데이터 세트에는 일반적으로 작업과 관련된 명령어(입력) 및 응답(출력) 쌍의 예가 포함되어 있습니다. 이 과정에서 모델은 특정 명령에 응답하는 방법을 학습합니다.
Reinforcement Learning from Human Feedback(RLHF): 모델이 사용자와 상호 작용하여 응답을 생성하고 강화 신호의 형태로 피드백을 받습니다. 기본적으로 모델은 수신한 피드백을 기반으로 학습하고 성능을 개선합니다.
LLM Fine-tune with Phi-2
LLM 미세 조정은 계산 비용이 많이 들고 수십억 개의 파라미터 모델을 훈련하기 위해 수백 GB의 VRAM이 필요하므로 일반 사용자의 하드웨어에서 실행하거나 훈련하기에는 큰 어려움이 있습니다. 이 문제를 해결하기 위해 LoRA(Low-Rank Adapters)의 확장인 QLoRA(Quantized Low-Rank Adaptation)라는 parameter-efficient fine-tuning(PEFT) 기술을 사용합니다. 이 기술은 기존 파라미터를 동결(frozen) 하면서 소수의 추가 모델 파라미터를 미세 조정하여 메모리 사용량을 줄입니다. 이를 통해 고성능을 유지하면서 일반적으로 4비트 정밀도로 모델을 실행할 수 있습니다.
이제 간단하게 Hugginface에 있는 microsoft/phi-2를 base_model로 해서 나만의 데이터로 fine-tuning해서 새로운 모델인 phi-2-loudai 를 만들어 보겠습니다.
Downloading readme: 100%|██████████| 274/274 [00:00<00:00, 672kB/s]
Downloading data: 100%|██████████| 1.61M/1.61M [00:00<00:00, 1.62MB/s]
Generating train split: 100%|██████████| 1000/1000 [00:00<00:00, 31695.79 examples/s]
Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.
다음으로, Phi-2 매개변수의 양자화를 활성화하도록 bitsandbytes를 구성합니다. 여기에는 4비트 양자화 유형, 계산 데이터 유형 등과 같은 매개변수를 지정하는 작업이 포함됩니다.
AutoModelForCausalLM 함수로 pretrained 기본 LLM을 지정합니다.
# Load base moodel
model = AutoModelForCausalLM.from_pretrained(
base_model,
quantization_config=bnb_config,
trust_remote_code=True,
low_cpu_mem_usage=True,
device_map={"": 0},
revision="refs/pr/23" #the main version of Phi-2 doesn’t support gradient checkpointing (while training this model)
)
model.config.use_cache = False
model.config.pretraining_tp = 1
model = prepare_model_for_kbit_training(
model,
use_gradient_checkpointing=True
)
학습하고자 하는 Arguments 인수를 지정합니다. 훈련 매개변수에는 결과 디렉터리 설정, 훈련 에포크 수, 배치 크기, 최적화 전략, 학습 속도 등이 포함됩니다. 이러한 매개변수는 미세 조정 중에 Phi-2가 특정 작업에 적응하는 방식에 영향을 미칩니다.
LoRA에 대한 configuration을 설정합니다. peft 매개변수를 사용하여 LoRA 구성을 설정합니다. LoRA 구성에는 순위, 알파, 바이어스, 작업 유형 및 대상 모듈과 같은 매개 변수를 지정하는 것이 포함됩니다. 이러한 매개변수는 미세 조정 중에 모델이 적응하는 방식을 결정합니다.
Downloading shards: 100%|██████████| 2/2 [04:09<00:00, 124.97s/it]
Loading checkpoint shards: 100%|██████████| 2/2 [00:01<00:00, 1.02it/s]
You are using an old version of the checkpointing format that is deprecated (We will also silently ignore `gradient_checkpointing_kwargs` in case you passed it).Please update to the new format on your modeling file. To use the new format, you need to completely remove the definition of the method `_set_gradient_checkpointing` in your model.
You are using an old version of the checkpointing format that is deprecated (We will also silently ignore `gradient_checkpointing_kwargs` in case you passed it).Please update to the new format on your modeling file. To use the new format, you need to completely remove the definition of the method `_set_gradient_checkpointing` in your model.
/home/kubwa/anaconda3/envs/llm/lib/python3.11/site-packages/trl/trainer/sft_trainer.py:246: UserWarning: You didn't pass a `max_seq_length` argument to the SFTTrainer, this will default to 1024
warnings.warn(
Map: 100%|██████████| 1000/1000 [00:00<00:00, 1627.56 examples/s]
# Save trained model
trainer.model.save_pretrained(new_model)
TensorBoard로 시각화를 해보겠습니다.
#Check training results with tensorboard
%load_ext tensorboard
%tensorboard --logdir results/runs
GPU Memory에 남아있는 기존의 model, pipe, trainer를 삭제합니다. 메모리가 넉넉하다면 삭제할 필요는 업습니다. 모자란 GPU 메모리 관리차원에서 ^^
# Clear the memory
del model, pipe, trainer
Fine-tuned Model Test
텍스트 생성 파이프라인을 따라 모델을 테스트합니다.
# Run text generation pipeline with our model
logging.set_verbosity(logging.CRITICAL)
prompt = "위장관 종양의 치료법은 무엇인가요?"
instruction = f"### Instruction: {prompt} "
pipe = pipeline(
task="text-generation",
model=model,
tokenizer=tokenizer,
max_length=200
)
result = pipe(instruction)
print(result[0]['generated_text'][len(instruction):])
위장관 종양에는 다음과 같은 여러 가지 치료법이 있습니다:
1. 수술: 위장관 카르시노이드 종양의 일차 치료는 종양을 제거하는 수술입니다.
2. 화학 요법: 화학 요법은 암세포를 죽이기 위해 약물을 사용하는 치료법입니다. 위장관 카르시노이드 종양 치료를 위해 수술과 함께 사용되는 경우가 많습니다.
3. 방사선 요법: 방사선 요법은 고에너지 방사선을 사용하여 암세포를 죽이는 치료법입니다. 위장관 카르시노이드 종양을 치료하기 위해 수술 및 화학 요법과 함께 자주 사용됩니다.
4. 표적 치료: 표적 치료는 암세포의 성장과 확산에 관여하는 특정 분자 또는 경로를 표적으로 하는 치료법입니다. 종종 수술, 화학 요법 및 방사선 요법과 함께 다음을 위해 사용됩니다.
Reload & Push to Hugginface Hub
LLM에 질문을 던져 더 많은 것을 시도하고 테스트할 수도 있고, 파라미터를 변경하여 성능을 확인할 수도 있습니다. Huggingface Hub에 푸시하여 모델을 저장을 해보겠습니다.
# Reload model and merge it with LoRA parameters
model = AutoModelForCausalLM.from_pretrained(
base_model,
torch_dtype=torch.float16,
trust_remote_code=True,
cache_dir="",
device_map={"": 0},
)
model = PeftModel.from_pretrained(model, new_model)
model = model.merge_and_unload()
# Reload tokenizer to save it
tokenizer = AutoTokenizer.from_pretrained(
base_model,
trust_remote_code=True
)
tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "right"