직접 선호도 최적화(DPO)를 사용하여 악소롯을 이용한 오픈 소스 LLM의 미세 조정

LLM은 AI 응용 프로그램을 위한 무수히 많은 새로운 기회를 열어주었습니다. 자신의 모델을 세밀하게 조정해보고 싶다면, 이 안내서를 통해 어떻게 손쉽게 코드를 작성하지 않고도 할 수 있는지 보여드릴 것입니다. Axolotl과 DPO와 같은 도구를 사용하여, 단계별로 프로세스를 진행해 보겠습니다.

LLM이란 무엇인가?

대규모 언어 모델(LLM)은 방대한 양의 텍스트 데이터(수십 조 문자)를 학습한 강력한 AI 모델로, 시퀀스에서 다음 단어 세트를 예측합니다. 이는 GPU 컴퓨팅에서 이루어진 발전으로 인해 가능해졌으며, 이로써 수주에 걸치는 거대한 모델이 몇 주 안에 학습될 수 있게 되었습니다.

아마도 ChatGPT나 Claude와 같은 제품을 통해 LLM과 상호 작용한 경험이 있고, 그들의 인간과 비슷한 응답을 이해하고 생성하는 능력을 직접 경험했을 것입니다.

LLM을 세밀하게 조정하는 이유는?

모든 것을 위해 GPT-4o를 사용할 수는 없을까요? 이 글을 쓰는 시점에 우리가 가진 가장 강력한 모델이기는 하지만, 항상 가장 실용적인 선택은 아닙니다. 30억에서 140억 개의 매개변수를 갖는 더 작은 모델을 세밀하게 조정하면, 원가의 소액에 유사한 결과를 얻을 수 있습니다. 더불어 세밀한 조정을 통해 지적 재산권을 소유하고 타사에 대한 의존을 줄일 수 있습니다.

베이스, 인스트럭트, 챗 모델 이해하기

세밀하게 조정에 들어가기 전에, 존재하는 다양한 유형의 LLM을 이해하는 것이 중요합니다:

  • 기본 모델: 이 모델들은 책이나 인터넷 데이터와 같은 대규모의 비정형 텍스트로 사전 훈련되었습니다. 언어에 대한 본능적인 이해력을 갖고 있지만 추론에 최적화되지 않았으며 일관성 없는 결과물을 생성할 것입니다. 기본 모델은 더 특화된 모델을 개발하기 위한 시작점으로 개발되었습니다.
  • 지시 모델: 기본 모델을 기반으로 구축된 지시 모델은 프롬프트-응답 쌍과 같은 구조화된 데이터를 사용하여 세밀하게 조정되었습니다. 특정 지침을 따르거나 질문에 답변하기 위해 설계되었습니다.
  • 채팅 모델: 기본 모델을 기반으로 구축되었지만, 지시 모델과는 달리 채팅 모델은 대화 데이터로 훈련되어 있어 앞뒤로 대화할 수 있습니다.

강화 학습과 DPO란?

강화 학습(RL)은 모델이 행동에 대한 피드백을 받아 학습하는 기술입니다. 이 기술은 지시 모델이나 채팅 모델에 적용되어 출력물의 품질을 더욱 세밀하게 조정합니다. 일반적으로 RL은 기본 모델 위에서 수행되지 않으며 학습 속도가 훨씬 낮기 때문에 충분한 영향을 미치지 못합니다.

DPO는 모델이 동일한 프롬프트/대화에 대한 좋은 답변과 나쁜 답변의 쌍을 사용하여 훈련되는 RL의 한 형태입니다. 이러한 쌍을 제시함으로써 모델은 좋은 예제를 선호하고 나쁜 예제를 피하도록 학습합니다.

DPO 사용 시기

DPO는 모델의 스타일이나 행동을 조정하고 싶을 때 특히 유용합니다. 예를 들어:

  • 스타일 조정: 응답의 길이, 세부 사항의 수준 또는 모델이 표현하는 확신의 정도를 수정합니다.
  • 안전 조치: 모델이 잠재적으로 안전하지 않거나 부적절한 프롬프트에 대한 답변을 거부하도록 훈련합니다.

그러나 DPO는 모델에게 새로운 지식이나 사실을 가르치는 데 적합하지 않습니다. 그 목적을 위해서는 감독된 미세 조정(SFT) 또는 검색 보강 생성(RAG) 기술이 더 적합합니다.

DPO 데이터셋 만들기

생산 환경에서는 일반적으로 사용자 피드백을 사용하여 DPO 데이터셋을 생성합니다. 예를 들어:

  • 사용자 피드백: 응답에 대해 좋아요/싫어요 메커니즘을 구현합니다.
  • 비교 선택: 사용자에게 두 가지 다른 출력을 제시하고 더 나은 것을 선택하게 합니다.

사용자 데이터가 부족한 경우, 더 크고 능력 있는 LLM을 활용하여 합성 데이터셋을 만들 수도 있습니다. 예를 들어, 작은 모델을 사용하여 나쁜 답변을 생성한 다음 GPT-4o를 사용하여 수정할 수 있습니다.

간단함을 위해 HuggingFace의 기성 데이터셋을 사용할 것입니다: olivermolenschot/alpaca_messages_dpo_test. 데이터셋을 검사하면 선택된 답변과 거부된 답변이 포함된 프롬프트가 있다는 것을 알 수 있습니다. 이들은 좋은 예와 나쁜 예입니다. 이 데이터는 GPT-3.5-turbo와 GPT-4를 사용하여 합성적으로 생성되었습니다.

효과적인 훈련을 위해서는 최소 500쌍에서 1,000쌍의 데이터가 필요합니다. 가장 큰 DPO 데이터셋은 최대 15,000–20,000쌍을 포함합니다.

Axolotl로 Qwen2.5 3B 지침 미세 조정

Axolotl을 사용하여 현재 OpenLLM Leaderboard의 상위에 있는 Qwen2.5 3B Instruct 모델을 세밀하게 조정할 것입니다. Axolotl을 사용하면 코드 한 줄을 작성하지 않고도 YAML 구성 파일만 있으면 모델을 세밀하게 조정할 수 있습니다. 아래는 사용할 config.yml 파일입니다:

base_model: Qwen/Qwen2.5-3B-Instruct
strict: false

# Axolotl will automatically map the dataset from HuggingFace to the prompt template of Qwen 2.5
chat_template: qwen_25
rl: dpo
datasets:
  - path: olivermolenschot/alpaca_messages_dpo_test
    type: chat_template.default
    field_messages: conversation
    field_chosen: chosen
    field_rejected: rejected
    message_field_role: role
    message_field_content: content

# We pick a directory inside /workspace since that's typically where cloud hosts mount the volume
output_dir: /workspace/dpo-output

# Qwen 2.5 supports up to 32,768 tokens with a max generation of 8,192 tokens
sequence_len: 8192

# Sample packing does not currently work with DPO. Pad to sequence length is added to avoid a Torch bug
sample_packing: false
pad_to_sequence_len: true

# Add your WanDB account if you want to get nice reporting on your training performance
wandb_project:
wandb_entity:
wandb_watch:
wandb_name:
wandb_log_model:

# Can make training more efficient by batching multiple rows together
gradient_accumulation_steps: 1
micro_batch_size: 1

# Do one pass on the dataset. Can set to a higher number like 2 or 3 to do multiple
num_epochs: 1

# Optimizers don't make much of a difference when training LLMs. Adam is the standard
optimizer: adamw_torch

# DPO requires a smaller learning rate than regular SFT
lr_scheduler: constant
learning_rate: 0.00005

# Train in bf16 precision since the base model is also bf16
bf16: auto

# Reduces memory requirements
gradient_checkpointing: true

# Makes training faster (only suported on Ampere, Ada, or Hopper GPUs)
flash_attention: true

# Can save multiple times per epoch to get multiple checkpoint candidates to compare
saves_per_epoch: 1

logging_steps: 1
warmup_steps: 0

클라우드 환경 설정하기

트레이닝을 실행하기 위해 Runpod나 Vultr과 같은 클라우드 호스팅 서비스를 사용할 것입니다. 필요한 것은 다음과 같습니다:

  • 도커 이미지: Axolotl 팀에서 제공하는 winglian/axolotl-cloud:main 도커 이미지를 클론합니다.
  • *하드웨어 요구 사항: 80GB VRAM GPU(예: 1×A100 PCIe 노드)가 이 모델의 크기에 충분합니다.
  • 저장 공간: 필요한 모든 파일을 수용할 200GB의 볼륨 스토리지가 필요합니다.
  • CUDA 버전: CUDA 버전은 적어도 12.1 이어야 합니다.

*이 유형의 트레이닝은 LLM의 전체 세밀한 조정으로 간주되므로 매우 VRAM 집중적입니다. 클라우드 호스트에 의존하지 않고 로컬에서 트레이닝을 실행하려면 QLoRA를 사용해볼 수 있습니다. DPO 및 QLoRA를 결합하는 것이 이론적으로 가능하지만 실제로는 거의 사용되지 않습니다.

트레이닝 시작 단계

  1. HuggingFace 캐시 디렉토리 설정:
export HF_HOME=/workspace/hf

원본 모델이 지속되는 볼륨 스토리지에 다운로드되도록 합니다.

  1. 구성 파일 생성: 이전에 생성한 config.yml 파일을 /workspace/config.yml에 저장합니다.
  1. 트레이닝 시작:
python -m axolotl.cli.train /workspace/config.yml

그리고 보세요! 귀하의 훈련이 시작되어야 합니다. Axolotl이 모델과 훈련 데이터를 다운로드한 후, 다음과 유사한 출력이 표시되어야 합니다:

[2024-12-02 11:22:34,798] [DEBUG] [axolotl.train.train:98] [PID:3813] [RANK:0] loading model

[2024-12-02 11:23:17,925] [INFO] [axolotl.train.train:178] [PID:3813] [RANK:0] Starting trainer...

이 훈련은 단지 264개 행의 소규모 데이터셋이기 때문에 몇 분 정도 소요될 것입니다. 미세 조정된 모델은 /workspace/dpo-output에 저장될 것입니다.

HuggingFace로 모델 업로드하기

CLI를 사용하여 모델을 HuggingFace에 업로드할 수 있습니다:

  1. HuggingFace Hub CLI 설치:
pip install huggingface_hub[cli]
  1. 모델 업로드:
huggingface-cli upload /workspace/dpo-output yourname/yourrepo

yourname/yourrepo를 실제 HuggingFace 사용자명과 저장소 이름으로 대체하세요.

미세 조정된 모델 평가하기

평가를 위해 원본 및 미세 조정된 모델을 모두 텍스트 생성 추론 (TGI)와 같은 도구를 사용하여 호스팅하는 것이 좋습니다. 그런 다음 온도 설정을 0으로 설정하여 두 모델에서 추론을 수행하고 두 모델의 응답을 수동으로 비교하세요.

이 실용적인 접근 방식은 LLM에서의 언어 생성의 미묘한 차이를 캡처하지 못할 수 있는 훈련 평가 손실 지표만 의존하는 것보다 더 나은 통찰력을 제공합니다.

결론

DPO를 사용하여 LLM을 미세 조정하면 비용을 관리 가능하게 유지하면서 애플리케이션의 요구 사항에 더 잘 맞도록 모델을 사용자 정의할 수 있습니다. 이 기사에 설명된 단계를 따르면 오픈 소스 도구와 데이터 세트의 힘을 활용하여 특정 요구 사항에 맞는 모델을 만들 수 있습니다. 응답 스타일을 조정하거나 안전 조치를 구현하려는 경우, DPO는 LLM을 개선하는 실용적인 접근 방식을 제공합니다.

행복한 미세 조정 되시길 바랍니다!

Source:
https://www.sitepoint.com/fine-tuning-llm-with-direct-preference-optimization-dpo/