DeepDive LLM 2편 - Supervised Fine Tuning

Supervised Fine Tuning

Post Training 의 첫번째 단계 SFT 입니다. Pre Training 에 비하면 아주 작은 양의 데이터만 필요하지만, 실제로 성능을 이끌어 내는데에는 중요한 단계입니다.

멀티턴 대화 (Multi Turn Conversation)

ChatGPT 를 포함해서 대부분의 AI 서비스들은 대화형입니다. 베이스 모델은 그렇지 않죠. “질문-답변” 형태의 사용자가 원하는 포맷으로 대화하는 능력이 없어요.

사람이 만든(혹은 편집한) 대화형 데이터(User-Assistant 쌍)를 모델이 직접 학습하게 하면, 모델이 “대화”를 잘 흉내 내는 어시스턴트로 만들 수가 있습니다.

Tiktokenizer 로 대화형 데이터를 token으로 바꿔 보겠습니다.

<|im_start|> <|im_sep|> <|im_end|> 와 같은 이상한 문자들이 중간중간 삽입되었고요, 이 친구들은 각자 하나의 토큰입니다. 대화형을 만들기 위해서 토크나이저에 애초에 이러한 특수 토큰들이 자리 잡고 있어요.

LLM 이 보기에는 대화 역시 이런 특수 토큰들이 포함된 그저 sequence of tokens 인 것이죠.

베이스 모델에 다양한 대화들을 만들어서 추가 학습을 시키면 우리가 원하는 비서같이 대화를 해주는 AI 모델이 됩니다. 여기서의 추가학습이 Post Training 의 첫 단계이자, Supervised Fine Tuning 이고요, 보통은 Instruction 튜닝이라고도 많이 부릅니다.

멀티턴 대화 데이터셋 만들기

앞선 베이스 모델은 인터넷에서 글을 "잘" 긁어와 데이터셋을 만든다고 했는데요. 이 데이터셋을 어떻게 만들었을까요?

💡
초기에는 사람이 직접 만들었습니다!

OpenAI 가 2022년 공개한 Instruct GPT 페이퍼에 따르면, 양질의 대화 데이터셋을 생성하기 위한 사람을 40명 고용해서 진행했다고 써있네요. Upwork 랑 ScaleAI 라는 회사를 통해서 고용했다는 군요.

재미있는 내용들이 꽤 있는데요, "어떤 대화 데이터가 좋은 대화 데이터인가?" 에 대한 기준들이 있습니다. Human Labeler 들에게 준 가이드라인 입니다.

  • Helpful, Truthful, Harmless, Toxicity, Continuity

이러한 기준들이 자세하게 있고, 어떤 식으로 레이블링을 했는지 시스템도 나와있고, 175B 의 베이스 모델인 GPT-3, 이를 SFT 한 Instruct GPT 와의 비교 까지 볼만한 부분들이 많으니, 관심있으신 분들은 페이퍼를 한번 보시는 것 추천드립니다.

OpenAI 는 참고로 이 데이터는 공개하지 않았고요, 대신 HuggingFace 에 많은 멀티턴 대화 데이터셋이 있습니다. 하나만 한번 보죠.

OpenAssistant/oasst1 · Datasets at Hugging Face
We’re on a journey to advance and democratize artificial intelligence through open source and open science.

예시들 중 하나일 뿐인데, 질문, 답변 대화 텍스트가 100k 정도 규모로 있습니다.

이런 질답 예시들을 학습하면, 모든 존재가능한 질문을 학습하는 것은 아니지만, Helpful, truthful, harmless 한 페르소나가 생성이 되는 것 입니다. 나중에 사용자가 질문을 하면, 비슷한 방식으로 답변을 하는 것이죠. 예시들을 통해 말하는 법을 배운다라고 보면 되겠습니다.


💡
현재도 이렇게 사람이 만들까요? 당연히 아니죠. 이제는 데이터셋도 LLM이 만듧니다.

HuggingFace 의 UltraChat 이 대표적인 예시인데요. 사람이 직접 대화를 작성하는 것이 아니라, AI 끼리 대화를 하고 사람이 마지막 터치만 해줍니다. Human Generated 가 아니고 Human Edited 인 셈이죠. 이 데이터셋은 Zephyr 모델 학습에 사용되었습니다.

요즘에는 완전히 LLM 이 생성하고 사람이 관여하지 않는 Synthetic (합성) 데이터셋도 많이 사용합니다.

유명한 예시로는 Alpaca 도 있고, 요즘 distillation 기법들이나 deepseek의 방법을 한번 살펴보면 더 이해가 잘 될 것입니다. 뒤이어 보겠습니다.

이러한 데이터셋으로 추가 학습을 하면 대화형으로 동작하는 Assistant 모델이 생성이 되게 됩니다.

Hallucination 문제와 해결 방법

ChatGPT 스타일의 Assistant 모델이 생성이 되었지만, 아직은 문제가 있습니다. 아래와 같은 상황을 가정해보겠습니다.

학습과정에 일반적인 질답 데이터가 있습니다. 톰 크루즈에 대해 물으면 배우 톰 크루즈에 대한 설명을 주고, 겐지스 칸에 물으면 몽골 제국의 겐지스 칸에 대해 정답을 줍니다.

그런데 실전에서 갑자기 Orson Kovacs ? 모르는 사람에 대해서 질문을 주면 모델은 어떻게 대답해야 할까요?

정답은 "모릅니다!" 여야 합니다.

그렇지만, 학습 했던 데이터와 비슷한 형식으로 답을 내놓게 되죠. 요즘엔 많이 나아졌지만, ChatGPT 서비스에서도 많이 목격되는 문제, Hallucination (환각) 입니다.  

이를 해결하는 방법에는  크게 두가지가 있습니다.

  1. 모른다고 대답하도록 학습하기
  2. 구글링을 할 수 있게 도구를 쥐어주기

첫 번째 "모른다고 대답하는 학습" 을 해보겠습니다. 이 방법은 Pre-Train 단계에서 봤던 Llama 3 Herd of Models 페이퍼에 잘 나와 있습니다. "무엇을 알고 있는지" 에 대해 align을 시켜야 합니다. 마치 메타인지 교육 같네요.

Align the model to "Know what it knows"

1. Extract a data snippet from the pre-training data.
2. Generate a factual question about these snippets (context) by prompting Llama 3.
3. Sample responses from Llama 3 to the question.
4. Score the correctness of the generations using the original context as a reference and Llama 3 as a judge.
5. Score the informativeness of the generations using Llama 3 as a judge.
6. Generate a refusal for responses which are consistently informative and incorrect across the generations, using Llama 3.

위 토글은 원문 발췌이고요, 쉽게 예시를 들어 설명을 해보겠습니다.

  1. pretrain 에서 사용한 글을 하나 선택 합니다.
  2. 문서를 보고 Llama3 에게 질문을 만들라 시킵니다.
  3. 원글 없이 질문을 Llama3 에게 풀려봅니다.
  4. 원글을 보면서 Llama3 에게 채점을 (correctness, informativeness) 시켜봅니다.
  5. 틀린 질답이 세트가 있을 것이에요, 답변을 모른다고 바꿔써주고, 그 데이터로 SFT를 합니다.

이렇게 하면, 본인이 pre-train에서 봤지만, 잘 모르는 내용들을 모른다고 대답하도록 학습할 수 있습니다.

두번째 방법은 tool use 를 시키는 것입니다. ChatGPT 사용 하시다 보면, 지가 알아서 bing 에 가서 검색을 하고 결과를 내주는 동작을 보셨을 것입니다. 잘 모르겠으면, 알아서 판단해서 검색을 하고 결과를 보고 대답을 해줍니다.

모르겠는 질문이 나온다면, <SEARCH_START> 와 같은 "구글링을 해야겠다!" 라는 특수 토큰이 나오게 됩니다. 이것이 tool use 에요. Llama3 같은 경우도, Instruct tuned 모델은 tool use 가 가능하다고 명시되어 있습니다. 요즘의 모델들은 사실상 모두 tool use 가 가능합니다.

웹 검색 말고, 자체 db 검색이나, 자유로운 api 호출이나 여러가지 도구를 사용하는 것이 가능합니다. 지금은 hallucination 을 해결하기 위한 방법으로 소개를 했지만, diffusion 써서 이미지를 생성해주는 것과 같은 범용적인 응용이 가능합니다.

💡
Parameter 에는 한달 전에 본 지식이 담겨있고,
Context windows 에 들어온 지식은 메뉴얼이나 구글링 결과를 보고 있는 것입니다.

자기 자신에 대한 인식 / 지식

What model are you? Who built you?

라고 물어본다면, 뭐라고 대답해야할까요.

그냥 통계적으로 그럴듯한 대답을 해야겟죠. pre-trained 단계든 SFT 단계든 학습했던 데이터죠.

자기 자신에 대한 정체성을 부여하기 위해서는 학습단계에서 명시적으로 데이터를 학습시켜줘야 합니다.

allenai/olmo-2-hard-coded · Datasets at Hugging Face
We’re on a journey to advance and democratize artificial intelligence through open source and open science.

Olmo 라는 "완전 오프소스" LLM 의 학습 데이터를 보면, 다음과 같은 데이터가 SFT 학습 데이터 셋으로 존재합니다.

{ "content": "Tell me about yourself.", "role": "user" }

{ "content": "I'm OLMo, an open language model developed by AI2 (Allen Institute for Artificial Intelligence). I can assist with a variety of tasks, such as answering questions, providing suggestions, and much more. Whether you're looking for information, advice, or just a chat, I'm here to help to do my best to help!", "role": "assistant" }

정체성을 부여하는 학습 데이터 셋이 들어가, 정체성을 학습하게 됩니다.

또 다른 방법은, "system" role 의 프롬프팅 입니다.

위 대화 데이터를 보면, "role" 이 있습니다. "user" 와 "assistant"가 보이는데요, 이런 대화 형식의 role 에는 보통 "system" 역할도 있습니다.

tiktokenizer 의 디폴트 상태 입력창인데요, 여기에도 system 역할로 "you are a helpful asisstant" 가 들어가 있습니다. 대부분의 현 LLM 들은 위와 같이 system message 를 꼭 입력 받도록 되어있습니다.

모델은 생각할 시간이 필요하다!

왼쪽 오른쪽 중에 LLM 입장에서 뭐가 더 좋은 대답방식 일까요?

정답은 오른쪽 입니다, 생각할 시간을 가지고 대답했기 때문이죠.

왼쪽은 정답인 $3 를 대답하기까지 약 4토큰, 오른쪽은 수십 토큰이 들었어요. 총 계산량을 따져보면, 오른쪽이 훨씬 많이 계산했죠. LLM 은 하나의 토큰을 내놓기 위해 연산량이 정해져있습니다. 많은 토큰들이 정답 이전에 나왔다면, 그만큼 연산을 더 할 기회가 있는 것입니다.

물론 연산을 많이 한다고 무조건 더 좋은 것은 아닙니다만, 사람도 생각을 하고 대답하는 경우에 바로바로 대답하는 경우보다 더 좋은 답을 내놓는 경우가 많습니다.

OPENAI 에서 human data labeler 들이 SFT 용 데이터를 만들 때, 이 부분을 신경을 많이 썼다고 합니다. 왼쪽 처럼 데이터셋을 만들면, LLM 이 일단 풀이 없이 대답 부터 질러버리기 때문에 hallucination이 일어날 확률이 높고, 논리적 사고를 요하는 문제일 수록 더 그렇습니다. 대표적으로 수학이나 코딩과 같은 상황이죠.

이 문제는 최근에도 큰 화두인데요. Chain of Thought 프롬프팅으로도 어느정도 해결이 가능하고요, 혹은 요즘의 reasoning 모델 들이 "강제 생각 시간" 을 가지도록 만들어져서 똑똑함을 달성하도록 해결하기도 했습니다. 이는 뒤에서 더 다루도록 하겠습니다.

토큰들로만 생각하는 것이 아니라 앞서 이야기한 "tool use" 를 통해서도 생각할 시간을 가지고 더 잘 할 수 있습니다.

이렇게 질문에 코드를 짜서 풀라고 명시를 하면, 알아서 code tool 를 사용합니다. chatgpt 에서는 이를 "코드 인터프리터" 라는 이름으로 부릅니다.

파이썬 코드를 작성해서, 직접 돌려보고 그 결과를 얻어와서 대답한 것이죠. 그냥 토큰들로만 대답하는 것이 아니라요. 카파시 선생님은 이걸 "metal arithmetic" 이 믿을만 하지 못 하다라고 이야기 하더군요. "암산" 같은 개념으로 보면 되겠습니다.

토크나이저가 불러온 또 다른 난제들

모델이 또 못하는 것들이 있습니다.

ㅂ 갯수도 못 세네요.

How many 'r' s in "strawberry"?

원래 이 질문에 답을 못해서 유명해진 문제입니다. 지금은 잘 세네요.

고작 이런 글자 카운팅도 못하는데 어떻게 수학 문제는 인간 0.1% 수준이지? 라는 의문이 들만 합니다.

그 이유를 생각해보면, 토크나이저 때문 이에요.

LLM 이 바라보는 세상에는 " 밥", "밥", "버" 라는 토큰들이 있을 뿐입니다. 이 글자하나하나 단위로 인풋을 받지 않아요. 그래서 "밥" 토큰은 'ㅂ'이 두 개 라는 것을 알기가 힘들죠. 학습데이터에 이런게 들어가 있지 않다면요.

예시를 하나만 더 보겠습니다.

💡
9.11 이랑 9.9 중에 뭐가 더 커?

이 문제도 자주 틀리게 됩니다, OpenAI 내부자들의 탐구에 따르면, "성경 구절" 이라는 feature (뉴런) 들이 활성화 된다고 하더군요. 9.11, 9.9 라는 숫자가 pretrain 단계에서 성경 구절로서 많이 등장을 했었나 봅니다.

이런 문제는 사람이 바라보는 글과 LLM 이 바라보는 토큰이 달라서 생기는 모든 항목에 대해 발생합니다. 스펠링을 포함해서요. "tool use" 와 같은 방법을 잘 활용해서 LLM 이 문제를 풀 수 있도록 지시를 비틀어 주는 작업이 필요합니다.

유니버설한 범용 머신으로서의 LLM 은 아직은 조금 더 개선의 여지가 남아 있다고 볼 수 있습니다.