이 글은 Chain-of-Thought (CoT) 학습 데이터 생성 및 모델 개발 방법을 간략히 정리한다.
CoT와 관련해, 논리적 추론, 계획 수립, 지시 따르기 능력을 가르치는 데 효과적인 양질의 데이터셋은 여러 가지가 있다. 이런 데이터셋으로 학습하면 유사한 유스케이스에 대한 문제 해결 능력이 향상될 수 있다.
-
종합 추론 및 지시 따르기 데이터셋 (가장 유사한 케이스)
- Open-Orca: GPT-4와 같은 고성능 모델의 CoT 추론 과정을 포함한 약 100만 개의 데이터셋이다. 복잡한 질문에 대한 단계별 설명, 계획 수립 등 다양한 작업이 포함되어 있어 창의적 문제 해결 능력 학습에 매우 효과적이다.
- Dolly-15k: 질의응답, 요약, 창의적 글쓰기 등 15,000개의 고품질 프롬프트와 응답으로 구성되어 있다. 응답에 추론 과정이 명시적으로 포함된 경우가 많아 CoT 학습에 유용하다.
-
수학 및 과학 추론 데이터셋 (고전적인 CoT)
- GSM8K: 초등학교 수준의 수학 응용 문제에 대한 단계별 풀이 과정을 제공하는 대표적인 CoT 데이터셋이다. 논리적이고 순차적인 사고 능력을 가르치는 데 가장 좋은 데이터셋 중 하나이다.
- AQuA-RAT: 다양한 선택지 형식의 수학 문제에 대해 풀이 과정(Rationale)을 함께 제공한다.
학습 방법과 전략
가장 중요한 점: Ollama는 모델을 실행(Inference)하고 관리하는 도구이지, 모델을 훈련(Training)하는 도구가 아니다. 따라서 모델을 파인튜닝하는 작업은 다른 도구를 사용해 진행하고, 그 결과물을 Ollama로 가져와 사용하는 흐름으로 진행되어야 한다.
1. 데이터셋 형식 변환 (Instruction Tuning Format)
CoT 데이터셋을 모델 학습에 사용하려면 '지시(Instruction) 튜닝' 형식으로 변환해야 한다. 일반적으로 다음과 같은 JSONL 형식을 사용한다.
{
"instruction": "현재 장마철인 것을 고려해서 일본 3일 여행 일정을 짜줘.",
"input": "",
"output": "[1단계: 요구사항 명확화...] [2단계: 기본 전략 수립...] ... [5단계: 최종 계획안 요약]"
}
instruction
: 사용자 질문output
: 모델이 따라 배워야 할 이상적인 단계별 추론 과정 (CoT) 및 최종 답변
2. 학습 전략
- LoRA (Low-Rank Adaptation) 사용: 모델의 모든 가중치를 수정하는 '풀 파인튜닝'은 막대한 컴퓨팅 자원을 필요로 한다. 대신 LoRA는 원본 모델은 그대로 두고, 소규모의 '어댑터' 레이어만 추가하여 학습하는 파라미터 효율적 파인튜닝(PEFT) 방식이다. 적은 자원으로도 매우 효과적인 튜닝이 가능하여 개인이나 소규모 팀에게 가장 현실적인 방법이다.
- 품질 우선: 수백만 개의 저품질 데이터보다, 잘 정제된 수천~수만 개의 고품질 CoT 데이터가 모델 학습에 훨씬 효과적이다.
- 베이스 모델 선택: 파인튜닝의 기반이 될 좋은 성능의 오픈소스 모델을 선택하는 것이 중요하다. (예: Llama 3, Mistral, Gemma 등)
실행 방법
다음은 LoRA를 사용해 오픈소스 LLM을 CoT 데이터셋으로 파인튜닝하고 Ollama에서 실행하는 전체 과정이다.
1단계: 개발 환경 설정
Python, PyTorch, 그리고 Hugging Face의 주요 라이브러리를 설치한다.
pip install torch transformers datasets peft bitsandbytes accelerate
2단계: 데이터셋 준비
Hugging Face datasets
라이브러리로 CoT 데이터셋을 로드하고, 위에서 설명한 Instruction 형식으로 변환하는 전처리 스크립트를 작성해야 한다.
3단계: 모델 및 토크나이저 로드
파인튜닝할 베이스 모델과 토크나이저를 로드한다. (예: meta-llama/Meta-Llama-3-8B-Instruct
)
4단계: LoRA 설정 및 모델 튜닝
Hugging Face transformers
의 SFTTrainer
와 peft
라이브러리를 사용해 LoRA 파인튜닝을 진행한다.
# (개념적인 코드 예시)
from peft import LoraConfig
from transformers import TrainingArguments, SFTTrainer
# LoRA 설정
lora_config = LoraConfig(
r=16, # Rank
lora_alpha=32,
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
# 훈련 인자 설정
training_args = TrainingArguments(
output_dir="./lora-finetuned-model",
per_device_train_batch_size=4,
num_train_epochs=1,
learning_rate=2e-4,
logging_steps=10,
)
# SFTTrainer로 튜닝 시작
trainer = SFTTrainer(
model=base_model,
tokenizer=tokenizer,
train_dataset=formatted_dataset,
peft_config=lora_config,
args=training_args,
# ... 기타 설정
)
trainer.train()
5단계: 모델 병합 및 저장
LoRA 튜닝이 끝나면, 학습된 어댑터 가중치를 원본 베이스 모델과 병합하여 새로운 독립 모델로 저장한다.
6단계: Ollama로 모델 가져오기 및 실행
-
Modelfile 생성: 저장된 파인튜닝 모델 폴더를 기반으로
Modelfile
을 작성한다.코드 스니펫# 이 파일의 이름은 Modelfile이다. FROM ./path/to/your/merged-model-folder TEMPLATE """ <|begin_of_text|><|start_header_id|>user<|end_header_id|> {{ .Prompt }}<|eot_id|><|start_header_id|>assistant<|end_header_id|> """ # 베이스 모델에 맞는 프롬프트 템플릿을 지정한다.
-
Ollama 모델 생성: 터미널에서
ollama create
명령어로 나만의 모델을 생성한다.Bashollama create my-travel-planner -f ./Modelfile
-
Ollama 모델 실행: 생성된 커스텀 모델을 실행하여 결과를 확인한다.
Bashollama run my-travel-planner "현재 장마철인 것을 고려해서 일본 3일 여행 일정을 짜줘"
이 과정을 통해, 공개된 CoT 데이터셋으로 특정 문제 해결 능력이 강화된 나만의 LLM을 만들어 Ollama에서 손쉽게 활용하는 것이 가능하다.
참고: 에이전트 개발 시 ToT와 RAP 기법 비교
ToT는 이론적으로 모든 경로를 탐색하면 CoT에 비해 훨씬 더 많은 계산량과 시간이 필요하다는 단점이 있다. 나무의 가지(branch)가 깊어질수록 탐색해야 할 경우의 수가 기하급수적으로 늘어나기 때문이다. 하지만 실제 ToT 구현에서는 이 문제를 해결하기 위해 탐색을 제한하고 가지치기(Pruning)하는 여러 전략을 사용한다.
- 탐색 깊이 및 너비 제한: 무한정 탐색하는 것이 아니라, 최대 깊이(e.g., 5단계)와 각 단계에서 생성할 생각의 개수(너비, e.g., 3개)를 미리 정해둔다.
- 휴리스틱 평가 및 프루닝 (Heuristic Pruning): ToT의 핵심은 유망하지 않은 경로는 조기에 버리는 것이다. 각 생각을 생성한 후, 평가 함수를 통해 이 경로가 최종 정답으로 이어질 가능성을 점수화한다. 점수가 낮은 경로는 더 이상 탐색하지 않고 '가지치기'하여 계산 낭비를 막는다.
- 빔 서치 (Beam Search): 모든 유망한 경로를 유지하는 대신, 각 단계에서 가장 점수가 높은 상위 K개의 경로(생각의 빔)만 유지하고 나머지는 버린다. 이는 계산 비용을 통제하면서도 최적의 해를 찾을 확률을 높이는 효과적인 방법이다.
2. RAP(Reasoning and Acting)와 기존 기술의 융합
'기존 에이전트의 Function Calling'과 'CoT의 명시적 추론 과정'을 매우 효과적으로 융합한 형태이다.
-
기존 Function Calling: LLM이 사용자의 질문을 보고, 어떤 함수를 호출해야 할지 바로 결정하여 출력하는 방식이다.
(입력 -> 함수 호출)
과정에서 왜(Why) 그 함수를 호출했는지에 대한 설명이 부족한 경우가 많다. -
RAP의 차별점: RAP는 이 과정 사이에 CoT를 집어넣는다.
- (입력) -> [추론(Reasoning)] -> (함수 호출)
추론
단계에서 LLM은 "현재 상황이 이러하니, 목표를 달성하기 위해 다음 단계로 A 함수를 호출하는 것이 타당하다" 와 같은 **내부 독백(Internal Monologue)**을 CoT 형태로 명시적으로 생성한다.- 이 추론의 결과로
행동(Acting)
, 즉 Function Call이 결정된다.
이러한 융합이 가져오는 장점은 명확하다.
- 투명성 및 디버깅 용이성: 에이전트가 왜 그런 행동을 했는지 추론 과정을 통해 명확히 알 수 있다. 만약 잘못된 함수를 호출했다면, 어떤 논리적 오류 때문에 그런 결정을 했는지 파악하고 수정하기가 쉽다.
- 견고성 (Robustness): 함수 호출이 실패하거나 예상치 못한 결과를 반환했을 때, 에이전트는 그 실패를 '관찰(Observation)'하고, "A 함수가 실패했으니, 대안으로 B 함수를 시도해야겠다" 와 같이 다음 행동을 다시 '추론'할 수 있다. 스스로 오류를 복구하는 능력이 생긴다.
기법 | 핵심 아이디어 | 장점 | 단점 |
ToT | 문제 해결을 위한 여러 경로(생각)를 동시에 탐색하고 평가하여 최적의 경로를 찾는다. | 복잡하고 정답이 여러 개인 문제에 대해 더 높은 품질의 해결책을 찾을 수 있다. | CoT보다 계산 비용이 높다. 효율적인 평가 및 가지치기 전략이 필수적이다. |
RAP | '추론 -> 행동(도구 사용) -> 관찰'의 순환 루프를 통해 외부 세계와 상호작용한다. | 외부 도구/API를 활용할 수 있으며, 행동의 이유가 명확하고 오류에 강건하다. | 외부 도구/API를 잘 설계해야 하며, 상태 관리 및 루프 제어가 복잡해질 수 있다. |
댓글 없음:
댓글 쓰기