카테고리 없음

대규모 언어 모델(LLM), 각자의 쓸모에 맞게 활용하기 - 원리부터 프롬프팅과 파인튜닝까지

린몬 2025. 2. 11. 08:57
인공지능과 LLM이 키워드가 된 지는 꽤나 많은 시간이 흘렀지만, 기술적인 원리들과 용어들은 전공자가 아닌 입장에서 보면 여전히 막연하게 느껴질 수도 있을 것 같습니다. 이 블로그에서는 LLM과 다양한 최신 딥러닝 모델들이 더이상 '내부를 알 수 없는' 미지의 존재로 여겨지지 않도록 다양한 깊이와 관점에서 다뤄 보려고 합니다. 어떤 방식으로 동작하고, 어떤 방식으로 활용될 수 있는지 예측 가능한 친근한 개념으로 인공지능 모델을 소개하는 것이 목표입니다.

대규모 언어 모델(LLM)은 이름에서도 알 수 있듯이, 방대한 양의 언어 데이터를 '학습'시켜 만들어낸 거대한 딥러닝 모델입니다. GPT-3, ChatGPT와 같은 생성 기반의 LLM이 큰 관심을 얻기 전까지, 딥러닝 모델을 학습시키는 과정은 대부분 정답을 미리 표기해 놓은 데이터셋에 의존했습니다.

지도 학습(supervised)에서 자기지도(self-supervised) 학습으로

스팸메일을 걸러내는 작업을 예시로 생각해볼까요? 이 작업에서는 주어진 이메일이 '스팸'인지, '정상'인지 분류하는 것이 목표가 될 겁니다. 이 작업을 수행하는 딥러닝 모델은 분류할 이메일 내용을 입력으로 받고, 스팸 또는 정상 둘 중 하나의 출력을 제공하게 됩니다. 이런 모델이 좋은 성능을 내기 위해서는 (1) 다양한 이메일의 내용으로 이루어진 충분한 양의 데이터로 학습해야 하고, (2) 학습 과정에서 제공하는 정답 레이블이 최대한 정확해야 합니다. 학습 데이터에 성인 사이트 유도 스팸 메일은 많이 들어있었지만, "[긴급] 고객님 계정 보안 점검 필수! 지금 바로 링크 클릭 후 확인하세요 → http://xxxx.link" 처럼 피싱을 시도하는 스팸 메일 종류는 거의 없었다면 어떨까요? 당연하게도 피싱 메일을 탐지하는 데에는 떨어진 성능을 보일 것입니다. 하지만 학습 과정에서 사용되는 데이터가 많아지면 많아질수록, 사람이 이 데이터를 직접 확인하고 정답을 표기하는 데에 드는 비용도 높아집니다. 데이터셋을 무한정 키우는 데에 제한이 있다는 것입니다.

태스크 특화 모델에서 사전 훈련 모델로

또한, 이렇게 처음부터 특정 작업에 특화된 모델을 매번 학습시키는 것도 비효율적인 여지가 있습니다. 이메일 어플리케이션을 개발하는 개발자의 입장이 되어 봅시다. 트렌디한 인공지능 기반 이메일 앱을 만들기 위해 우수한 스팸 필터, 메일을 내용에 따라 정리해주는 자동 카테고리 분류기, 받은 이메일을 한줄로 요약해주는 기능, 그리고 이메일 내용을 자동완성해주는 고급 기능도 추가하고 싶습니다. 이 기능 각각에 대해 데이터셋을 따로 만들고, 별개의 모델들을 처음부터 따로 학습해야 한다면 굉장한 낭비가 아닐 수 없습니다. 따지고 보면, 이런 모델의 입력은 동일하게 이메일 텍스트입니다. 그리고 스팸 메일 탐지든, 카테고리 분류든, 내용 요약이든 모두 이메일 내용의 언어적인 의미를 이해함으로써 가능한 작업들입니다.

이렇게 다양한 작업에서 공통적으로 요하는 '언어 이해'를 목표로, 특정 작업(태스크)에 끼워맞추지 않은 일반적인 모델을 먼저 학습해보자는 아이디어가 바로 사전훈련(Pre-training) 기법입니다. 명확한 태스크와 출력 형태를 목표로 하는 것이 아니니, 이런 사전 훈련에는 정답이 필요하지 않습니다. 나중에 다른 포스트에서 더 자세히 설명하려고 하지만, 아주 간단하게는, 텍스트 중간중간에 '빈칸'을 뚫고, 이 빈칸에 들어갈 단어를 맞춰보라는 식으로 모델을 훈련합니다. 아직 한글을 다 떼지 못한 어린아이에게 국어 문제를 풀라고 줄 수는 없겠죠. 대신 여러 단어들이 포함된 다양한 문맥에 익숙해지도록 하는 과정입니다.

정답이 필요하지 않다면, 인터넷 세상에 떠다니는 (지금도 이렇게 증식하고 있는) 텍스트를 마구 수집해서 말 그대로 '거대한' 데이터셋을 만들 수 있습니다. 모델 파라미터 훈련 자체에 필요한 GPU 성능이 받쳐주는 한 데이터셋과 모델의 크기를 기존의 몇천, 몇만 배로 늘리는 게 가능해졌습니다. 자연스럽게 구글, OpenAI 등 딥러닝 인프라가 잘 구축되어 있는 빅테크 기업들을 중심으로 파라미터 수가 10 million, 1 billion, 10 billion, 그리고 100 billion 이상의 '거대 모델'들이 탄생하기 시작했고 연구자들은 흥미로운 현상을 관찰합니다.

 

출처: Emergenet Abilities of Large Language Models (Google Research, 2022)

그래프가 복잡해 보이지만, 담고 있는 내용은 간단합니다. x축이 모델의 크기, y축은 모델을 여러 가지 태스크에 적용했을 때의 성능 지표입니다. 모든 태스크에서 모델의 규모가 어떤 지점에 도달했을 때 성능이 비약적으로 상승하는 것을 확인할 수 있습니다. 이러한 현상을 연구자들은 창발성이라고 일컫습니다. 창발성(Emergence)은 사실 자연과학에서 이미 많이 쓰이던 용어이며, '개별 구성 요소들의 단순한 합을 넘어서는 새로운 특성이나 능력이 나타나는 현상'으로 정의됩니다. 이 특성이 인공지능 모델에서 나타난다는 것이 꽤나 재미있습니다. 창발성의 대표적인 예시가 생명체이기 때문입니다. 단순한 세포들이 모여 조직을 형성하고, 이런 조직들이 복잡한 기관을 이루며 결국에는 하나의 생명체로서 고유한 기능과 특성을 발휘하게 됩니다. 이러한 특성은 개별 세포나 조직에서는 볼 수 없지만, 전체 시스템의 복잡한 상호작용을 통해 나타납니다. 그리고 충분히 복잡한 세포의 조합은 결국 '인간'이라는 메타 인지가 가능한 생물을 발명해냈습니다. 비슷하게, 인공 뉴런의 조합으로 이루어진 딥러닝 모델에서도 어느 정도의 규모에 도달했을 때, 작은 규모의 모델에서는 거의 불가능해 보였던 복잡한 언어 이해 능력이나 문제 해결 능력이 관찰되는 것입니다.

거칠게 이야기해서, 결국 LLM은 '창발성'을 갖게 될 만큼 충분한 크기를 가진, 범용 사전 훈련 모델입니다. 물론 최신 ChatGPT, o1 모델과 같은 논리적 추론 능력을 갖춘 LLM은 사람과 더 자연스러운 대화를 나눌 수 있도록 몇 가지 최적화 과정을 더 거치지만, 다음 기회에 더 자세히 설명하도록 하겠습니다. 

다시 이메일 어플리케이션 예시로 돌아가봅시다. 앞서 이야기한 다양한 기능(스팸, 카테고리 분류, 요약)은 이제 한 종류의 LLM으로도 충분히 가능합니다. 이메일에 관련된 작업 뿐만 아니라, 논문 요약이나 면접 준비처럼 일상의 다양한 작업에도 적용 가능합니다. 앞서 이야기했듯, 어떤 태스크에 국한되지 않고 일반적인 언어 이해 능력을 목표로 훈련한 덕분에, 훌륭한 범용성을 가진 모델이 탄생했습니다.

하지만 이런 범용성이 양날의 검이 되기도 합니다. 우리가 다시 LLM을 특정 태스크에 맞춰서 사용하려고 해도, 이 LLM이 학습 과정 동안 너무 다양한 학습 데이터에 이미 노출되었기 때문에, 생각보다 몇 마디의 프롬프트만으로 LLM을 내가 원하는 특정 기능에 딱 맞춰 쓰기가 쉽지 않습니다. 휴대폰 판매점의 사장이 되었다고 가정해볼까요? ChatGPT를 고객 상담 챗봇으로 활용하고 싶은 상황입니다.

고객에게 휴대폰 영업하라니까 너무나 쉽게 게임 이야기로 빠져드는 ChatGPT

휴대폰 추천을 하라고 만들어놓은 챗봇인데, 막상 고객 앞에 놓아두고 보니 열과 성을 다해 우리 회사와는 상관없는 모바일 게임을 열심히 추천하고 있습니다. 사장 입장에서는 속이 터질 노릇입니다.

프롬프팅, 혹은 파인튜닝

이렇게 LLM을 실용적인 기능으로 활용하기 위해서는 태스크에 맞게 프롬프팅(Prompting), 혹은 파인튜닝(Fine-tuning) 하는 과정이 필요합니다. 일반화된 사전훈련 모델을 다시 태스크 특화된 출력을 만들어내도록 조정하는 과정입니다. 이 과정에서 사전훈련된 모델이 가진 복잡한 언어적 이해 능력은 최대한 보존하면서도 모델이 일관적으로 태스크에 적합한 답을 내놓도록 하는 것이 목표입니다. 이 균형을 맞추는 것이 사실 미묘하고 조금 어려운 영역입니다. 새로운 태스크에만 너무 치우치게 되면 LLM이 사전 훈련 동안 얻은 일반적이고 복합적인 언어 이해 능력을 잃고 (이 현상은 Catastrophic Forgetting이라고도 알려져 있습니다) 기계적인 답만 내놓게 될 수 있으며, 새로운 태스크를 충분히 학습하지 못하면 위와 같이 특정 작업에 LLM을 적용했을 때 엉뚱한 답을 내놓을 수도 있기 때문입니다. 

프롬프팅이 아마도 조금 더 쉽고 간편한 선택일 것입니다. 사실 위의 예제에서 "앞으로 휴대폰 기종을 추천하는 우리 회사의 고객 상담 챗봇으로 행동해줘. 앞으로 주어지는 사용자 질문에 충실이 응대하고 삼성 휴대폰 중 하나를 추천해드려" 라는 문장도 일종의 프롬프팅입니다. 사용자의 입력에 이런 지시사항을 모델에 매번 추가해서, 모델의 생성 결과가 휴대폰 추천과 관련되도록 '유도'하는 것이니까요. 하지만 프롬프팅은 기본적으로 모델 내부의 파라미터를 변경하기보다는, 모델에 들어가는 입력에만 관여하는 방식이기 때문에 단순한 지시 사항 몇 줄로는 모델의 생성 결과를 강하게 컨트롤하기 어렵습니다. 특히 이런 대화형 LLM에서는, 대화가 길어질수록 앞서 이야기한 맥락 일부가 무시되는 현상도 심심치 않게 경험할 수 있죠. 이를 해결하기 위해 프롬프트 안에 예시 입력-출력 몇 쌍을 포함한다던지, 모델이 어떤 과정을 통해 결과를 생성할지 중간 방법을 알려준다던지, 모델이 최종 정답을 내놓기 전에 이 답을 어떤 방식으로 도출하는지 그 과정 또한 함께 출력하는 Chain-of-Thought(CoT) 방식 등 조금 더 고도화된 프롬프팅 기법들이 많이 제안되었습니다. 여러 프롬프트 버전을 만들어서, 지금 갖고 있는 입력에 대해 가장 좋은 결과를 내는 프롬프트를 자동으로 선택하는 '프롬프트 최적화' 기법들도 존재하고요. 아래와 같이 기존의 결과를 기반으로 프롬프트를 조금 더 다듬는 것만으로도 조금씩 더 원하는 결과에 가까워지도록 할 수 있습니다.

여전히 지나치게 모든 방면으로 친절하기는 하지만, 스마트폰 판매원으로서의 본분은 잊지 않는 것 같다.

하지만 실제 어플리케이션의 기능으로 활용할 정도의 안정성을 보장하려면, 프롬프팅만으로는 한계가 있는 경우가 많습니다. 위의 예시에서도 휴대폰 추천과 관련없는 질문에 '한줄로 간단히 답변하라'는 요구사항이 완벽하게 처리되지는 않았습니다. 앞서 말했듯, 프롬프팅은 기본적으로 모델 내부에 존재하는 파라미터, 즉 이미 학습된 '값'들을 바꾸는 것이 아니기 때문에 생성할 수 있는 결과의 범위에 한계가 있습니다. 명확한 방향성이나 원칙("프롬프트에 A를 바꾸면 결과에 B가 바뀌겠지?"와 같은)이 있는 것도 아니기에 원하는 결과에 가까운 프롬프트를 만들어내는 것 자체가 굉장히 반복적이고 '감'에 의존하는 일이 됩니다.

파인튜닝은 프롬프팅과는 달리 태스크에 특화된 새로운 데이터셋을 추가적으로 학습시켜 모델의 파라미터를 업데이트하는 방식입니다. 충분한 수의, 정답이 있는 데이터셋이 존재한다면 가장 효과적인 방법입니다. 언어모델이 가진 일반적인 지식을 기반으로 하면서도, 미리 정해진 이상적인 정답에 맞춰서 모델 자체를 정교하게 조정하기 때문입니다. 하지만 당장 프로토타입 수준이나 일반인 수준에서 파인튜닝을 하는 것은 프롬프팅에 비해 지나치게 비용이 많이 듭니다. 파인튜닝 과정도 일종의 학습 과정이기 때문에 비싼 GPU들이 필요하고, 또 정답이 달려있는 많은 수의 데이터셋도 필요합니다. 앞서 말했듯, 파인튜닝을 잘못하면 LLM 자체의 강점인 일반화 성능이 급감할 위험성도 있습니다.

최근에는 이런 프롬프팅과 파인튜닝 기법의 장점만을 섞고자 하는 하이브리드 방법론들도 주목받고 있습니다. 프롬프트 자체를 학습 가능한 연속적인 파라미터로 다루고 적은 수의 데이터셋으로 최적화된 프롬프트 벡터를 형성하는 소프트 프롬프팅(Soft Prompting), LLM 모델의 각 층에 학습 가능한 일부 영역을 붙여서 '내부 프롬프트'처럼 활용하는 프리픽스 튜닝(Prefix-tuning) 방법론 등이 있습니다. 파인튜닝이라고 하기에는 모델의 아주 작은 일부만을 변경하고, 프롬프팅이라고 하기에는 적은 수의 데이터셋을 사용해서 실제로 작은 규모의 '학습'을 하는 과정들이고, 연구 결과에 따르면 저비용으로도 특정 작업에 대한 모델 성능을 효과적으로 향상시킬 수 있다고 알려져 있습니다. 조금 더 학술적인 내용이 궁금하신 분들은 이곳 블로그에 최근 논문들을 중심으로 이런 방법론들이 잘 정리되어 있으니 참고하셔도 되겠습니다.

LLM을 활용한 소프트웨어나 제품들은 아직 실험 단계에 있는 것들이 대부분이고, 활발히 서비스되는 것들이 많지는 않은 듯 합니다. 아직 LLM을 사용해서 무언가를 개발하고 싶어! 라고 한다면 당장 프롬프팅을 선택해야 할지, 오픈소스 모델을 받아서 파인튜닝을 하는 것이 나을지에서부터 막연한 부분이 많죠. 짧은 생각으로는, 당장 LLM을 활용한 새로운 기능을 개발하려고 한다면, 간단한 프롬프팅을 통해 기본적인 LLM 모델이 어느 정도 성능을 보이는지를 확인하고, 이 과정에서 모델을 추가적으로 훈련시킬 데이터를 모으는 것이 우선이 되어야 하지 않을까 생각해 봅니다. 프로토타입과 베타 테스팅 단계에서는 프롬프팅을 활용하고, 안정화해서 실제 기능으로 배포하기 전에는 파인튜닝을 고려하는 식으로요.

지금까지 LLM의 탄생 배경부터 활용 방법론까지, 겉핥기이지만 전체적인 스토리 중심으로 정리해봤습니다. 더 자세히 알고 싶은 영역이나, 내용에 오류가 있다면 알려주시면 감사하겠습니다.