LLM & Generative AI 기초 정리

요즘 AI 서비스를 찾아보면 LLM, 생성형 AI, Transformer, GPT 같은 단어가 한꺼번에 나온다.

처음 공부할 때는 각각 다른 기술처럼 보이는데, 큰 흐름으로 보면 어느 정도 연결되어 있다.

앞에서 머신러닝과 딥러닝의 기본 학습 과정을 정리했다면, LLM을 이해하기 위해서는 그 위에 어떤 구조가 올라가는지를 보면 된다.

대략적인 흐름은 이렇다.

물론 이걸 엄밀한 계층 구조라고 보기는 어렵다. 생성형 AI가 LLM만을 의미하는 것도 아니고, Transformer가 LLM에서만 사용되는 것도 아니다.

그래도 전체적인 맥락을 잡는 데는 이 정도 구조가 편하다.

언어 모델은 무엇을 하는가

언어 모델(Language Model)은 주어진 문맥을 보고 다음에 올 가능성이 높은 토큰을 예측하는 모델이라고 생각하면 이해하기 쉽다.

예를 들어,

오늘 점심에는

이라는 문장이 주어졌다면 모델은 뒤에 올 가능성이 높은 토큰을 계산한다.

오늘 점심에는 -> 밥
오늘 점심에는 -> 햄버거
오늘 점심에는 -> 라면

각 후보에 대한 확률을 계산하고 그중 하나를 선택한다.

중요한 건 LLM이 문장을 통째로 만들어서 한 번에 출력하는 방식이 아니라는 점이다.

기본적으로는 다음 토큰을 예측하는 과정을 반복한다.

입력 문맥-> 다음 Token 예측-> Token 추가-> 다시 예측-> Token 추가-> 반복

그래서 긴 문장도 결국 작은 단위의 예측을 반복해서 만들어진다.


텍스트를 그대로 이해하는 것은 아니다

컴퓨터가 문자열을 그대로 신경망에 넣을 수는 없다.

그래서 먼저 텍스트를 Token이라는 단위로 나눈다.

예를 들어 하나의 문장이 있다면,

"나는 게임을 개발한다."

이것이 모델 내부에서는 여러 토큰으로 분리될 수 있다.

"나는" "게임" "을" "개발" "한다" "."

실제 Tokenization 방식은 모델과 tokenizer에 따라 달라진다. 단어 단위라고 생각하면 정확하지 않다.

영어에서는 단어 전체가 하나의 토큰이 될 수도 있고 단어의 일부가 여러 토큰으로 나뉠 수도 있다. 한국어도 마찬가지다.

결국 모델이 직접 다루는 것은 우리가 보는 문장이 아니라 토큰들의 시퀀스다.

텍스트-> Tokenization-> Token IDs

Token은 숫자로 바뀐다

토큰을 얻었다고 해서 바로 신경망에 넣을 수 있는 것도 아니다.

각 토큰은 숫자로 표현된다.

Token-> Token ID-> Embedding-> 벡터

예를 들어 어떤 토큰이 특정한 ID를 가지고 있다고 해보자.

"게임" -> 18273

이 숫자 자체에 의미가 있는 것은 아니다.

모델은 Token ID를 이용해 해당 토큰을 고차원 벡터로 변환한다. 이것이 Embedding이다.

게임-> Token ID-> [0.12, -0.43, 0.87, ...]

Embedding은 단순한 번호표가 아니다.

학습을 거치면서 모델이 토큰의 다양한 관계를 표현할 수 있는 벡터 공간을 형성한다.

그래서 비슷한 맥락에서 사용되는 단어나 개념이 벡터 공간에서 특정한 관계를 갖게 될 수 있다.


Transformer가 등장한다

LLM을 이야기할 때 빠지지 않는 것이 Transformer다.

Transformer는 2017년에 발표된 “Attention Is All You Need” 논문에서 제안된 신경망 구조다.

기존의 순차적인 언어 처리 방식과 달리 Transformer는 Attention을 중심으로 입력 토큰 사이의 관계를 계산한다.

문장을 처리할 때 단순히 바로 앞의 단어만 보는 것이 아니라 문장 안의 다른 토큰들과 어떤 관계가 있는지를 함께 계산할 수 있다.

예를 들어,

철수는 게임을 만들었다. 그는 밤새 코드를 작성했다.

두 번째 문장의 “그는”이 누구를 가리키는지 이해하려면 앞의 “철수”와의 관계를 봐야 한다.

Attention은 이런 식으로 문맥 안의 토큰들이 서로 어떤 관계를 갖는지 계산하는 데 사용된다.


Attention은 무엇을 하는가

Attention을 아주 단순화하면 현재 토큰을 처리할 때 다른 토큰을 얼마나 참고할지 계산하는 과정으로 볼 수 있다.

예를 들어,

나는 어제 친구와 게임을 만들었다.

에서 “게임”이라는 토큰을 처리한다고 생각해보자.

모델은 주변 토큰과의 관계를 계산하면서 현재 토큰의 표현을 만든다.

나는
어제
친구와
게임
을
만들었다

각 토큰이 서로에게 어느 정도 영향을 줄지 계산하는 것이다.

Transformer에서는 이를 Self-Attention이라고 한다.

구현 수준에서는 Query, Key, Value라는 세 가지 표현을 사용해 Attention을 계산한다.

대표적인 형태는 다음과 같다.

Attention(Q, K, V)
= softmax(QKᵀ / √dₖ)V

수식을 직접 계산할 일이 많지는 않더라도, 이 수식이 결국 토큰 사이의 관련성을 계산하고 그 결과를 이용해 새로운 표현을 만드는 과정이라는 정도는 알고 넘어가는 게 좋다.


Transformer가 LLM이 되는 과정

Transformer라는 구조가 있다고 해서 바로 LLM이 되는 것은 아니다.

큰 규모의 텍스트 데이터를 이용해 언어 모델을 학습시키고, 충분한 파라미터와 계산 자원을 사용해 규모를 키우면서 대규모 언어 모델이 만들어진다.

여기서 LLM은 Large Language Model의 약자다.

정확히 “파라미터가 몇 개 이상이면 LLM이다”처럼 명확한 기준이 있는 것은 아니다.

보통 대규모 데이터와 많은 파라미터를 사용해 언어를 모델링하는 큰 규모의 모델을 LLM이라고 부른다.

GPT 계열 모델도 이런 대규모 언어 모델에 해당한다.


LLM은 어떻게 학습하는가

LLM의 기본적인 학습 방식은 앞에서 정리했던 머신러닝의 흐름과 크게 다르지 않다.

텍스트 데이터가 있고, 모델이 다음 토큰을 예측한다.

입력:
"나는 오늘 게임을"

정답:
"개발"

모델이 예측한 결과와 실제 다음 토큰을 비교해서 Loss를 계산한다.

이 과정을 엄청난 양의 텍스트에 대해 반복한다.

결국 LLM도 학습 가능한 파라미터를 가진 신경망이고, 앞에서 봤던 학습 과정에서 크게 벗어나지 않는다.

차이는 규모다.


그런데 어떻게 문장과 지식을 생성할 수 있을까

여기서 LLM이 재미있는 지점이 나온다.

학습 목표 자체는 상당히 단순하다.

주어진 문맥을 보고 다음에 올 토큰을 예측하는 것.

그런데 모델의 크기와 학습 데이터가 충분히 커지면서 단순한 다음 토큰 예측만으로도 문법, 문맥, 표현 방식, 코드 구조, 여러 지식과 패턴 등을 상당히 많이 학습하게 된다.

예를 들어 다음과 같은 입력이 있다고 하자.

C#에서 List<int> numbers에 저장된 요소의 개수를 확인하려면

모델은 지금까지 학습한 C# 코드와 문장 패턴을 바탕으로 다음에 어떤 토큰이 등장할 가능성이 높은지 계산한다.

이 문맥에서는 다음과 같은 후보들이 있을 수 있다.

Count
Length
Capacity

하지만 List<T>의 요소 개수를 확인하는 C# 코드에서 Count가 등장할 가능성이 가장 높다고 판단할 수 있다.

C#에서 List<int> numbers에 저장된 요소의 개수를 확인하려면 Count

이제 모델은 방금 생성한 Count까지 포함된 새로운 문맥을 다시 입력으로 사용한다.

C#에서 List<int> numbers에 저장된 요소의 개수를 확인하려면 Count

그리고 이번에는 다음에 .이 올 가능성이 높다고 판단할 수 있다.

C#에서 List<int> numbers에 저장된 요소의 개수를 확인하려면 Count.

다음에는 ;이 나올 수도 있고, 이나 같은 자연어가 이어질 수도 있다. 문맥에 따라 각각의 가능성이 달라진다.

좀 더 명확한 예를 들어보면 다음과 같다.

대한민국의 수도는

이 문맥에서 모델은 다음 토큰을 예측한다.

서울

반면 문맥이

프랑스의 수도는

라면 다음 토큰으로 높은 확률을 가지는 것은

파리

가 된다.

모델이 서울이나 파리라는 단어를 단순히 사전에 저장해놓고 꺼내는 것이 아니라, 앞에 주어진 문맥과 학습 과정에서 형성된 파라미터를 이용해 다음에 어떤 토큰이 나올 가능성이 높은지를 계산하는 것이다.

그리고 생성된 토큰은 다시 다음 예측의 입력에 포함된다.

대한민국의 수도는
-> 서울
-> 대한민국의 수도는 서울
-> 다음 토큰 예측
-> 대한민국의 수도는 서울이다
-> 다음 토큰 예측
-> ...

이 과정이 계속 반복되면서 하나의 문장이나 코드가 만들어진다.

따라서 모델이 처음부터 완성된 답변을 만들어놓고 꺼내는 방식과는 다르다.

매 순간 현재까지의 문맥을 기준으로 다음 토큰을 예측하고, 생성된 결과를 다시 문맥에 추가한 뒤 다음 토큰을 예측하는 과정을 반복한다.

결국 LLM의 생성은 매우 단순한 형태로 보면 다음과 같다.

문맥-> 다음 토큰 예측-> 토큰 생성-> 문맥에 추가-> 다음 토큰 예측-> 토큰 생성-> 반복

이 단순한 과정을 매우 큰 모델과 방대한 데이터에 적용하면서, 모델은 단순한 단어 연결을 넘어 문법, 문맥, 코드 구조, 지식과 같은 복잡한 패턴까지 활용할 수 있게 된다.


Generative AI는 LLM과 같은 것인가

여기서 LLM과 생성형 AI를 구분할 필요가 있다.

Generative AI는 새로운 콘텐츠를 생성하는 AI 기술 전반을 가리키는 더 넓은 개념이다.

텍스트뿐만 아니라 이미지, 음성, 음악, 영상, 코드 등을 생성하는 모델도 포함된다.

Generative AI-> Text-> Image-> Audio-> Video-> Code

LLM은 그중에서도 주로 텍스트와 언어를 다루는 대규모 모델이다.

그래서 관계를 단순하게 표현하면,

Generative AI-> 여러 종류의 생성 모델-> 그중 언어 생성 모델-> LLM

정도로 볼 수 있다.

다만 실제 시스템에서는 텍스트 모델과 이미지 모델 등을 하나의 서비스에서 함께 사용하는 경우도 있기 때문에 이 둘을 완전히 분리해서 생각할 필요는 없다.


LLM을 실제 서비스에서는 어떻게 사용하는가

LLM 자체를 학습시키는 것과 LLM을 서비스에 사용하는 것은 상당히 다른 문제다.

대부분의 개발자가 직접 거대한 LLM을 처음부터 학습시키지는 않는다.

이미 학습된 모델에 요청을 보내고 그 결과를 서비스에 활용하는 경우가 훨씬 많다.

가장 단순한 형태는 다음과 같다.

사용자 입력-> LLM-> 생성 결과-> 사용자에게 반환

하지만 실제 서비스에서는 이것만으로 끝나는 경우가 많지 않다.

예를 들어 회사 내부 문서를 기반으로 답변하는 챗봇을 만든다면 LLM에게 모든 문서를 학습시킬 필요는 없다.

문서를 검색하고 필요한 내용을 가져온 다음 LLM의 입력에 넣어줄 수 있다.

사용자 질문-> 관련 문서 검색-> 검색 결과 + 질문-> LLM-> 답변

이런 구조가 RAG(Retrieval-Augmented Generation)다.

LLM 자체의 능력과 외부 데이터를 연결하는 방식이라고 보면 된다.


Prompt는 왜 중요한가

LLM은 입력으로 주어진 문맥을 기반으로 다음 토큰을 생성한다.

그래서 어떤 내용을 어떻게 입력하느냐가 결과에 영향을 준다.

예를 들어 단순히

머신러닝 설명해줘

라고 입력하는 것과,

게임 개발자를 대상으로
머신러닝의 학습 과정을 설명해라.
수식은 최소화하고 실제 개발 과정과 연결해서 설명해라.

라고 입력하는 것은 모델이 참고할 수 있는 조건 자체가 다르다.

이런 입력을 Prompt라고 한다.

Prompt Engineering은 결국 LLM의 동작 특성을 고려해서 원하는 결과가 나오도록 입력과 지시를 구성하는 작업이라고 볼 수 있다.

다만 Prompt만 잘 작성한다고 해서 모든 문제가 해결되는 것은 아니다.

실제 서비스에서는 모델 선택, 데이터 구성, RAG, Fine-tuning, 평가 시스템, 출력 검증 등 여러 요소가 함께 중요하다.


Fine-tuning은 무엇인가

이미 학습된 모델을 특정 목적에 맞게 추가로 학습시키는 방법도 있다.

이를 Fine-tuning이라고 한다.

예를 들어 일반적인 언어 능력을 가진 모델이 있다고 하자.

여기에 특정 형식의 데이터를 추가로 학습시키면 특정 작업이나 스타일에 더 적합한 모델로 조정할 수 있다.

기존 LLM-> 특정 데이터로 추가 학습-> 특정 목적에 맞게 조정된 모델

다만 특정 정보를 모델에게 넣고 싶다는 이유만으로 항상 Fine-tuning을 사용하는 것은 아니다.

지식이 자주 바뀌거나 외부 문서를 기반으로 답변해야 한다면 RAG가 더 적합할 수도 있다.

반대로 특정한 출력 형식이나 행동 패턴을 지속적으로 학습시키고 싶다면 Fine-tuning이 더 적합할 수 있다.

결국 어떤 문제를 해결하려는지부터 봐야 한다.


LLM의 한계

LLM이 문장을 자연스럽게 만든다고 해서 항상 사실을 말하는 것은 아니다.

모델은 기본적으로 다음 토큰을 예측하는 방식으로 동작한다.

따라서 실제 사실 여부를 데이터베이스처럼 조회하고 검증하는 시스템과는 다르다.

그럴듯하지만 사실이 아닌 내용을 생성할 수도 있다. 흔히 Hallucination이라고 부르는 문제다.

질문-> LLM의 생성-> 자연스러운 답변

여기서 자연스럽다는 것과 정확하다는 것은 별개의 문제다.

그래서 실제 서비스에서는 외부 데이터 검색, 구조화된 데이터 조회, 출력 검증, 모델 평가 같은 장치를 함께 사용한다.

LLM에게 모든 것을 맡기는 것보다 LLM이 잘하는 부분과 외부 시스템이 잘하는 부분을 나누는 것이 실용적인 접근이다.


결국 LLM은 무엇인가

LLM을 지나치게 복잡하게 생각할 필요는 없다고 본다.

기본 구조는 머신러닝에서 봤던 것과 이어진다.

LLM에서는 이 모델이 Transformer 기반의 대규모 신경망이고, 입력 데이터가 주로 토큰화된 텍스트이며, 대표적인 학습 목표 중 하나가 다음 토큰 예측인 것이다.

사용할 때는 여기에 Prompt, RAG, Fine-tuning 같은 기술이 추가된다.

생성형 AI도 결국 이 위에서 이해할 수 있다.

텍스트를 생성하면 LLM 같은 언어 모델이 될 수 있고, 이미지를 생성하면 이미지 생성 모델이 될 수 있다.

중요한 건 각각의 기술 이름을 따로 외우는 것보다 어떤 데이터를 입력으로 받고, 어떤 방식으로 표현하고, 무엇을 예측하며, 어떻게 학습하고, 실제 서비스에서는 어떤 외부 시스템과 연결되는지를 보는 것이다.

그 관점으로 보면 LLM도 갑자기 등장한 별개의 기술이라기보다 딥러닝이 발전하면서 만들어진 하나의 큰 응용 영역으로 볼 수 있다.