AI-Master-Book
  • about AI-Master-Book
  • AI Master Book
    • 이상치 탐지 with Python
    • 베이지안 뉴럴네트워크 (BNN) with Python
    • 그래프 뉴럴네트워크 (GNN) with Python
    • 데이터 마케팅 분석 with Python
  • LLM MASTER BOOK
    • OpenAI API 쿡북 with Python
    • 기초부터 심화까지 RAG 쿡북 with Python
    • MCP 에이전트 쿡북 with Python
  • LLMs
    • OpenAI API
      • 1️⃣ChatCompletion
      • 2️⃣DALL-E
      • 3️⃣Text to Speech
      • 4️⃣Video to Transcripts
      • 5️⃣Assistants API
      • 6️⃣Prompt Engineering
      • 7️⃣OpenAI New GPT-4o
    • LangChain
      • LangChain Basic
        • 1️⃣Basic Modules
        • 2️⃣Model I/O
        • 3️⃣Prompts
        • 4️⃣Chains
        • 5️⃣Agents
        • 6️⃣Tools
        • 7️⃣Memory
      • LangChain Intermediate
        • 1️⃣OpenAI LLM
        • 2️⃣Prompt Template
        • 3️⃣Retrieval
        • 4️⃣RAG ChatBot
        • 5️⃣RAG with Gemini
        • 6️⃣New Huggingface-LangChain
        • 7️⃣Huggingface Hub
        • 8️⃣SQL Agent & Chain
        • 9️⃣Expression Language(LCEL)
        • 🔟Llama3-8B with LangChain
      • LangChain Advanced
        • 1️⃣LLM Evaluation
        • 2️⃣RAG Evaluation with RAGAS
        • 3️⃣LangChain with RAGAS
        • 4️⃣RAG Paradigms
        • 5️⃣LangChain: Advance Techniques
        • 6️⃣LangChain with NeMo-Guardrails
        • 7️⃣LangChain vs. LlamaIndex
        • 8️⃣LangChain LCEL vs. LangGraph
    • LlamaIndex
      • LlamaIndex Basic
        • 1️⃣Introduction
        • 2️⃣Customization
        • 3️⃣Data Connectors
        • 4️⃣Documents & Nodes
        • 5️⃣Naive RAG
        • 6️⃣Advanced RAG
        • 7️⃣Llama3-8B with LlamaIndex
        • 8️⃣LlmaPack
      • LlamaIndex Intermediate
        • 1️⃣QueryEngine
        • 2️⃣Agent
        • 3️⃣Evaluation
        • 4️⃣Evaluation-Driven Development
        • 5️⃣Fine-tuning
        • 6️⃣Prompt Compression with LLMLingua
      • LlamaIndex Advanced
        • 1️⃣Agentic RAG: Router Engine
        • 2️⃣Agentic RAG: Tool Calling
        • 3️⃣Building Agent Reasoning Loop
        • 4️⃣Building Multi-document Agent
    • Hugging Face
      • Huggingface Basic
        • 1️⃣Datasets
        • 2️⃣Tokenizer
        • 3️⃣Sentence Embeddings
        • 4️⃣Transformers
        • 5️⃣Sentence Transformers
        • 6️⃣Evaluate
        • 7️⃣Diffusers
      • Huggingface Tasks
        • NLP
          • 1️⃣Sentiment Analysis
          • 2️⃣Zero-shot Classification
          • 3️⃣Aspect-Based Sentiment Analysis
          • 4️⃣Feature Extraction
          • 5️⃣Intent Classification
          • 6️⃣Topic Modeling: BERTopic
          • 7️⃣NER: Token Classification
          • 8️⃣Summarization
          • 9️⃣Translation
          • 🔟Text Generation
        • Audio & Tabular
          • 1️⃣Text-to-Speech: TTS
          • 2️⃣Speech Recognition: Whisper
          • 3️⃣Audio Classification
          • 4️⃣Tabular Qustaion & Answering
        • Vision & Multimodal
          • 1️⃣Image-to-Text
          • 2️⃣Text to Image
          • 3️⃣Image to Image
          • 4️⃣Text or Image-to-Video
          • 5️⃣Depth Estimation
          • 6️⃣Image Classification
          • 7️⃣Object Detection
          • 8️⃣Segmentatio
      • Huggingface Optimization
        • 1️⃣Accelerator
        • 2️⃣Bitsandbytes
        • 3️⃣Flash Attention
        • 4️⃣Quantization
        • 5️⃣Safetensors
        • 6️⃣Optimum-ONNX
        • 7️⃣Optimum-NVIDIA
        • 8️⃣Optimum-Intel
      • Huggingface Fine-tuning
        • 1️⃣Transformer Fine-tuning
        • 2️⃣PEFT Fine-tuning
        • 3️⃣PEFT: Fine-tuning with QLoRA
        • 4️⃣PEFT: Fine-tuning Phi-2 with QLoRA
        • 5️⃣Axoltl Fine-tuning with QLoRA
        • 6️⃣TRL: RLHF Alignment Fine-tuning
        • 7️⃣TRL: DPO Fine-tuning with Phi-3-4k-instruct
        • 8️⃣TRL: ORPO Fine-tuning with Llama3-8B
        • 9️⃣Convert GGUF gemma-2b with llama.cpp
        • 🔟Apple Silicon Fine-tuning Gemma-2B with MLX
        • 🔢LLM Mergekit
    • Agentic LLM
      • Agentic LLM
        • 1️⃣Basic Agentic LLM
        • 2️⃣Multi-agent with CrewAI
        • 3️⃣LangGraph: Multi-agent Basic
        • 4️⃣LangGraph: Agentic RAG with LangChain
        • 5️⃣LangGraph: Agentic RAG with Llama3-8B by Groq
      • Autonomous Agent
        • 1️⃣LLM Autonomous Agent?
        • 2️⃣AutoGPT: Worldcup Winner Search with LangChain
        • 3️⃣BabyAGI: Weather Report with LangChain
        • 4️⃣AutoGen: Writing Blog Post with LangChain
        • 5️⃣LangChain: Autonomous-agent Debates with Tools
        • 6️⃣CAMEL Role-playing Autonomous Cooperative Agents
        • 7️⃣LangChain: Two-player Harry Potter D&D based CAMEL
        • 8️⃣LangChain: Multi-agent Bid for K-Pop Debate
        • 9️⃣LangChain: Multi-agent Authoritarian Speaker Selection
        • 🔟LangChain: Multi-Agent Simulated Environment with PettingZoo
    • Multimodal
      • 1️⃣PaliGemma: Open Vision LLM
      • 2️⃣FLUX.1: Generative Image
    • Building LLM
      • 1️⃣DSPy
      • 2️⃣DSPy RAG
      • 3️⃣DSPy with LangChain
      • 4️⃣Mamba
      • 5️⃣Mamba RAG with LangChain
      • 7️⃣PostgreSQL VectorDB with pgvorco.rs
Powered by GitBook
On this page
  • Approach to Fine-tuning
  • Huggingface Fine-tuning
  • Huggingface Fine-tuning 개발
  • Huggingface: Basic Fine-tuning
  • Setup Environments
  • 1. Load Dataset
  • 2. Preprocessing
  • 3. Dynamic padding
  • 4. Fine-tuning with Trainer API
  • 5. Evaluation
  • 6. Trainer with Evaluation
  1. LLMs
  2. Hugging Face
  3. Huggingface Fine-tuning

Transformer Fine-tuning

PreviousHuggingface Fine-tuningNextPEFT Fine-tuning

Last updated 1 year ago

Approach to Fine-tuning

  1. Self-supervised Learning

자기 지도 학습에서는 모델이 훈련 데이터의 내재적 구조를 기반으로 학습됩니다. 언어 모델의 경우, 주어진 순서에서 다음 단어나 토큰을 예측하는 것이 일반적입니다.(next token prediction)

초기 모델 개발 이후, 자기 지도 학습은 세세한 조정에 적용될 수 있으며, 예제 텍스트를 기반으로 특정 쓰기 스타일을 에뮬레이트하는 모델을 만드는 등의 용도로 활용될 수 있습니다.

  1. Supervised Learning

지도 학습은 모델 세세한 조정을 위한 인기 있는 방법 중 하나로 두드러집니다. 이는 특정 작업에 대한 입력-출력 쌍을 기반으로 모델을 훈련시키는 것을 포함합니다.

예를 들어, 지시 조정은 모델이 질문에 답하거나 사용자 프롬프트에 응답하는 능력을 향상시키는 것을 목표로 합니다.

  1. Reinforcement Learning

강화 학습(RL)을 사용하여 모델을 세세하게 조정하는 것입니다. RL은 보상 모델을 활용하여 기본 모델의 훈련을 안내하며, 언어 모델의 완성을 인간 라벨러의 선호도에 맞추려고 합니다. 보상 모델을 Proximal Policy Optimization (PPO)과 같은 강화 학습 알고리즘과 결합하여, 사전 훈련된 모델이 효과적으로 세세하게 조정됩니다

Huggingface Fine-tuning

LLM Fine-tuning에서 적용되는 기본 요소는 여러가지가 있습니다. Huggingface에서는 이러한 기본 요소를 Transformer 기본 라이브러리에서 Class로 제공하고 이외에 peft, trl, bitsandbytes, accelerate를 함께 사용하여 fine-tuning을 지원합니다.

Huggingface Fine-tuning 개발

1. 일반적인 모델 Fine-tuning: Transformer Trainer 클래스 사용

2. LLM에서 PEFT(Parameter Efficient Fine-tuning)은 아래 라이브러리를 함께 사용합니다.

  • transformer :기본 라이브러리

  • peft: PEFT를 위한 LoRa, QLoRa 사용

  • trl: SFTTraine 클래스 사용

  • bitsandbytes: 양자화를 위한 라이브러리

  • accelerate: GPU 분산 학습을 위한 라이브러리

3. Reinforcement Learning은 TRL 라이브러리를 사용합니다.

  • Supervised fine-tuning: SFTTrainer

  • Direct Preference Optimization: DPOTrainer

  • Reward: RewardTrainer

  • Proximal Policy Optimization: PPOTrainer

  • Contrastive Preference Optimization: CPOTrainer

  • Optimization without Reference Model: ORPOTrainer


Huggingface: Basic Fine-tuning

가장 기본적인 Transformer 모델을 Dataset을 통해서 Fine-tuning 하겠습니다. 절차는 아래와 같습니다:

  1. Load Dataset

  2. Preprocessing: Tokenization & Embedding

  3. Dynamic Padding

  4. Train with Trainer

  5. Evaluate

  6. Train with evaluate function

Setup Environments

%pip install -q transformers
%pip install -q datasets
%pip install -q -U accelerate

1. Load Dataset

Huggingface의 dataset에서 MRPC(Microsoft Research Paraphrase Corpus) Dataset을 로드하겠습니다.

from datasets import load_dataset

raw_datasets = load_dataset("glue", "mrpc")
raw_datasets
DatasetDict({
    train: Dataset({
        features: ['sentence1', 'sentence2', 'label', 'idx'],
        num_rows: 3668
    })
    validation: Dataset({
        features: ['sentence1', 'sentence2', 'label', 'idx'],
        num_rows: 408
    })
    test: Dataset({
        features: ['sentence1', 'sentence2', 'label', 'idx'],
        num_rows: 1725
    })
})

dataset의 한 문장을 확인해보면

raw_train_dataset = raw_datasets["train"]
raw_train_dataset[0]
{'sentence1': 'Amrozi accused his brother , whom he called " the witness " , of deliberately distorting his evidence .',
 'sentence2': 'Referring to him as only " the witness " , Amrozi accused his brother of deliberately distorting his evidence .',
 'label': 1,
 'idx': 0}

이미 label이 숫자표기로 되어있습니다. 어떤 label 값을 가지고 있는지 확인해 보자

raw_train_dataset.features
{'sentence1': Value(dtype='string', id=None),
 'sentence2': Value(dtype='string', id=None),
 'label': ClassLabel(names=['not_equivalent', 'equivalent'], id=None),
 'idx': Value(dtype='int32', id=None)}

2. Preprocessing

AutoTokenizer로 Token 화 변환한다.

from transformers import AutoTokenizer

checkpoint = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
tokenized_sentences_1 = tokenizer(raw_datasets["train"]["sentence1"])
tokenized_sentences_2 = tokenizer(raw_datasets["train"]["sentence2"])

model에 넣을 때 sentence1과 sentence2, 두 문장을 한번에 token화하게 된다.

inputs = tokenizer("This is the first sentence.", "This is the second one.")
inputs
{'input_ids': [101, 2023, 2003, 1996, 2034, 6251, 1012, 102, 2023, 2003, 1996, 2117, 2028, 1012, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
  • token_type_ids: 첫 문장과 두번째 문장의 구분을 나타내는 값

  • input_ids 값을 decode 하게 되면 아래와 같이 얻을 수 있다

tokenizer.convert_ids_to_tokens(inputs["input_ids"])
['[CLS]',
 'this',
 'is',
 'the',
 'first',
 'sentence',
 '.',
 '[SEP]',
 'this',
 'is',
 'the',
 'second',
 'one',
 '.',
 '[SEP]']

Dataset 객체를 생성하는기본적인 방법은 아래와 같이 정의할 수 있다.

tokenized_dataset = tokenizer(
    raw_datasets["train"]["sentence1"],
    raw_datasets["train"]["sentence2"],
    padding=True,
    truncation=True,
)

Dataset.map method를 사용하여 dataset의 각 element들에게 적용된다.

tokenize 함수를 아래와 같이 설정하고 dataset.map을 통해 모든 element를 tokenize할 수 있도록 한다.

def tokenize_function(example):
    return tokenizer(
        example["sentence1"], 
        example["sentence2"], 
        truncation=True)
tokenized_datasets = raw_datasets.map(
    tokenize_function, 
    batched=True
)
tokenized_datasets
Map:   0%|          | 0/3668 [00:00<?, ? examples/s]



Map:   0%|          | 0/408 [00:00<?, ? examples/s]



Map:   0%|          | 0/1725 [00:00<?, ? examples/s]





DatasetDict({
    train: Dataset({
        features: ['sentence1', 'sentence2', 'label', 'idx', 'input_ids', 'token_type_ids', 'attention_mask'],
        num_rows: 3668
    })
    validation: Dataset({
        features: ['sentence1', 'sentence2', 'label', 'idx', 'input_ids', 'token_type_ids', 'attention_mask'],
        num_rows: 408
    })
    test: Dataset({
        features: ['sentence1', 'sentence2', 'label', 'idx', 'input_ids', 'token_type_ids', 'attention_mask'],
        num_rows: 1725
    })
})

input_ids ,attention_mask, token_type_ids 가 추가된 것을 확인할 수 있다.

3. Dynamic padding

Dataset을 DataLoader에 담아 데이터를 꺼내어 사용하게 되는데 우리는 불필요한 패딩을 줄이기위해 각 batch별로 가장 큰 길이를 지정하여 padding을 생성하게 된다.

여기서는 DataCollatorWithPadding 함수를 사용해 padding을 만들어 본다.

from transformers import DataCollatorWithPadding

data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
samples = tokenized_datasets["train"][:8]
samples = {
    k: v for k, v in samples.items() if k not in ["idx", "sentence1", "sentence2"]
}
[len(x) for x in samples["input_ids"]]
[50, 59, 47, 67, 59, 50, 62, 32]

샘플 데이터를 추출하여 data_collator 에 넣어보면

batch = data_collator(samples)
{k: v.shape for k, v in batch.items()}
{'input_ids': torch.Size([8, 67]),
 'token_type_ids': torch.Size([8, 67]),
 'attention_mask': torch.Size([8, 67]),
 'labels': torch.Size([8])}

4. Fine-tuning with Trainer API

Transformer에서 제공가는 Trainer 클래스를 사용하여 fine-tune을 합니다.

앞의 Data Load, Preprocessing을 하나로 구성하여 실행하겠습니다.

from datasets import load_dataset
from transformers import AutoTokenizer, DataCollatorWithPadding

raw_datasets = load_dataset("glue", "mrpc")
checkpoint = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)

def tokenize_function(example):
    return tokenizer(
        example["sentence1"], 
        example["sentence2"], 
        truncation=True
    )

tokenized_datasets = raw_datasets.map(
    tokenize_function, 
    batched=True
)
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
Map:   0%|          | 0/1725 [00:00<?, ? examples/s]

TrainingArguments 클래스를 TrainArgument를 구성합니다.

from transformers import TrainingArguments

training_args = TrainingArguments("test-trainer")
from transformers import AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2)
Some weights of BertForSequenceClassification were not initialized from the model checkpoint at bert-base-uncased and are newly initialized: ['classifier.bias', 'classifier.weight']
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.

Trainer로 Argument Congit를 구성합니다.

from transformers import Trainer

trainer = Trainer(
    model,
    training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    data_collator=data_collator,
    tokenizer=tokenizer,
)

이제 학습을 시작하겠습니다.

trainer.train()

Step Training Loss

TrainOutput(global_step=345, training_loss=0.3608564736186594, metrics={'train_runtime': 89.8265, 'train_samples_per_second': 122.503, 'train_steps_per_second': 3.841, 'total_flos': 450668126729280.0, 'train_loss': 0.3608564736186594, 'epoch': 3.0})

5. Evaluation

validation set으로 predict메서드로 예측값을 뽑습니다.

predictions = trainer.predict(tokenized_datasets["validation"])

print(predictions.predictions.shape, predictions.label_ids.shape)
(408, 2) (408,)

Softmax classification이기 때문에 argmax로 class를 결정합니다.

import numpy as np

preds = np.argmax(predictions.predictions, axis=-1)

datasets 라이브러리에서 제공하는 load_metric 함수로 간단하게 metrics를 계산할 수 있습니다.

from datasets import load_metric

metric = load_metric("glue", "mrpc")
metric.compute(predictions=preds, references=predictions.label_ids)
{'accuracy': 0.8700980392156863, 'f1': 0.9112227805695142}

6. Trainer with Evaluation

Metric을 사용자 함수 처리해 보겠습니다.

def compute_metrics(eval_preds):
    metric = load_metric("glue", "mrpc")
    logits, labels = eval_preds
    predictions = np.argmax(logits, axis=-1)
    return metric.compute(predictions=predictions, references=labels)

compute_metrics 사용자 함수를 Trainer에서 compute_metrics 매개변수에 넣어주면 학습 과정에서 자동으로 metric을 반영합니다.

training_args = TrainingArguments(
    "test-trainer", 
    evaluation_strategy="epoch"
)
model = AutoModelForSequenceClassification.from_pretrained(
    checkpoint, 
    num_labels=2
)

trainer = Trainer(
    model,
    training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    data_collator=data_collator,
    tokenizer=tokenizer,
    compute_metrics=compute_metrics
)

trainer.train()
Epoch Training Loss Validation Loss Accuracy F1 1 No log 0.429820 0.833333 0.881119 2 No log 0.364128 0.838235 0.887755 3 No log 0.432673 0.848039 0.893471
TrainOutput(global_step=345, training_loss=0.36642157513162366, metrics={'train_runtime': 93.1513, 'train_samples_per_second': 118.13, 'train_steps_per_second': 3.704, 'total_flos': 450668126729280.0, 'train_loss': 0.36642157513162366, 'epoch': 3.0})
1️⃣