
이젠 진짜 해야함
How Transformer LLMs Work
Understand the transformer architecture that powers large language models (LLMs) to use them more effectively.
www.deeplearning.ai
이 강의를 들어보기로 했음
한시간반 강의이고 실습 + 강의임
무료라서 좋은데 한국말 자막이 안나옴!
그래도 영어 스크립트는 줘서 지피티한테 번역시켜서 이해해보려고 함
Introduction
여기선 llm 아키텍쳐 트랜스포머를 가르쳐준다고 함.

만약 영어를 독일어로 바꾸는 모델이 있다고 하자
이 때 인코더는 영문 전체를 처리하며 번역에 필요한 컨텍스트를 추출한다.
그리고 디코더는 이 문맥을 사용해서 독일어 문장을 생성한다.
인코더 모델은 입력 텍스트를 풍부한 컨텍스트 문맥으로 바꾼다. -> bert와 rag 검색에 사용된다.
반대로 디코더 모델은 텍스트 생성 작업을 수행한다. 오늘날 가장 인기 있는 llm들은 대부분 디코더 기반이다.
Laguage as a Bag-of-Words
Bag-of-words는 단어가 등장했는지 여부만 기록하는 큰 숫자배열로 단어를 표현하는 알고리즘이다.
이 기법은 초기 기법으로 오늘날 기술의 토대가 되었으며, 문맥을 제대로 반영하지 못하지만 baseline으로는 유용하다.

모델은 이런식으로 세 가지의 방식으로 발전해왔다.
encoder only는 문장을 숫자로 잘 표현하는데 유리하고, decoder-only-models는 텍스트 생성에 특화되어있다.
언어를 컴퓨터에서 배우는 것은 매우 까다롭다. 텍스트는 비정형적이고, 0과 1로 표현하면 의미가 손실되기 떄문이다.
그래서 인공지능에서의 핵심은 언어를 구조적인 형채로 표현하는 것이 핵심 목표였다.
초기에 비정형데이터를 분석하기 위해 만들어진 방법이 Bag-of-Words다.
예를 들어 that is a cute dog라는 문장과 my cat is cute라는 문장의 관계를 숫자화한다고 하자.

그럼 일단 이렇게 토큰화 할 수 있다.
그 다음 두 문장에서 등장한 단어들을 모아 vocabulary를 만든다.

그 다음 특정 문장에 대해 voca에서 해당 단어가 몇번 나왔는지 count한다. 그 결과로 나온 것이 위의 배열이다.
이런 수치 표현을 vactor representation이라고 한다.
이 예시에서는 count 기반이라 의미가 명확하지만, 고급모델들은 0-1 사이 값으로 직관적인 의미를 알기 어렵다.
(Word) Embeddings
위에서 본 bag-of-words는 단어를 그저 묶음으로 보고 텍스트의 의미는 완전히 무시한다는 문제점이 있다.
그래서 Word2Vec라는 방법을 사용해서 embedding 안에 텍스트의 의미를 포착하려는 시도를 하였다.

Word2Vec는 서로 연결된 뉴럴 네트워크를 활용한다. 이 안에는 서로 연결된 layer, node들이 있다.
이들은 입력에 따라 변화하는 weight를 학습힌다.

이 방법은 문장에서 어떤 단어들이 서로 이웃으로 등장하는지를 기반으로 word embedding을 학습한다.
먼저 vocabulary 안의 모든 단어에 5차원 임베딩을 랜덤값으로 초기화 한 후, training step 마다 단어 쌍을 보고 서로 문맥 내에서 이웃할 가능성이 있는지 예측한다.
학습 과정에서 단어 간 관계를 파악하여 embedding에 정보를 압축하고, 이웃이 비슷한 단어는 embedding이 서로 가까워지고, 그 반대면 서로 멀어진다.

예를들어 cats의 임베딩을 생각해보자. 값이 -1에서 1이라고 했을 때, 임베딩은 단어의 속성을 표시한다.
newborn, animal... 등의 속성을 가지고, 높은 연관성이 있는 속성의 값이 높은 것을 확인할 수 있다. 이 차원수를 embedding dimension이라고 한다. dimension은 수백, 수천개가 되기도 한다.
하지만 실제로는 이 속성들이 각각 뭘 의미하는지는 모른다. 왜냐하면 복잡한 수학적 학습을 통해 자동으로 만들어지기 때문이다. 하지만 이런 속성떄문에 임베딩끼리 유사도 비교도 가능하다.

위 예시는 단어 단위의 임베딩이지만, 임베딩 종류는 다양하다. word2vec처럼 텍스트를 임베딩으로 변환하는 모델을 Representation Model이라고 한다.
그리고 만약 Tokenization할 때 Tokenizer은 고정된 vocabulary를 가지고 있기 때문에 존재하지 않는 단어는 쪼갤수도 있다.

위와 같이 쪼개진 다음, 이 값을 평균한 값이 전체 단어의 임베딩값이라고 볼 수 있다.

이렇게 단어 뿐만 아니라, 문장, 문서도 임베딩이 가능하다.
Encoding and Decoding Context with Attention
이전의 임베딩 방식에서는 문맥을 반영하는 능력이 제한적이었다. 따라서 이번에는 attention을 통해서 어떻게 인코딩하고 디코딩하는지 알아보겠다.
"bank"라는 단어는 금융기관이라고도 해석되지만, 강둑이라고도 해석된다. 이를 정확하게 해석하는 것은 매우 중요하다.
이를 위한 첫걸음은 RNN에서 시작된다.

RNN은 입력문장을 인코딩하거나, 디코딩할 때 사용된다.
I love llamas가 네덜란드어로 번역되는 과정을 보면 텍스트는 인코더로 전달되고, 인코더는 임베딩을 통해 이를 잘 표현하고자 한다.
i love llamas는 ik hou van lama's로 번역된다. 이 아키텍쳐의 각 단계는 autoregressive하다. 즉, 다음 단어를 생성할 때 이전에 생성한 모든 단어를 계속 참조한다.

다음과 같이 토큰은 하나씩 생성되는데 각 단계마다 토큰이 생성되면 그 토큰도 input값으로 순차적으로 들어가게된다.
대부분의 모델은 autogressiveg하며, 매번 한 토큰씩 생성한다.

다시 자세히 보면, 인코딩 과정에서 입력으로 Word2Vec 임베딩을 사용할 수 있다. 이 임베딩은 정적이지만, 인코더는 전체 시퀀스를 한번에 처리하며 문맥을 고려한다.
이 과정을 통해 인코딩에서는 하나의 임베딩 형태로 문맥을 생성하고, 디코더는 이 문맥 임베딩을 이용해 출력 문장을 사용한다.
이 때 출력토큰들은 한번에 하나씩 생성된다.
하지만 단일 문맥 임베딩방식은 입력 전체를 하나의 임베딩에 담기 때문에 긴 문장을 처리하는데 어렵다.
이를 개선하기 위해 Attention이 등장했다.
Attention은 입력 시퀀스 안에서 서로 관련 있는 부분에 집중하여 그 신호를 강화한다.

아까와 같은 사례를 적용하면 위와 같이 단어가 연관이 있을 때에는 높은 어텐션을, 연관성이 낮을때는 낮은 어텐션을 가진다.
디코더 단계에 어텐션을 추가하면 RNN은 어떤 단어가 출력에 영향을 줄지 신호를 더 잘 전달할 수 있다.
입력은

위와 같이 word2vec 임베딩되어 인코더로 전달되고, 디코더로 전달될 때에는 단 하나의 문맥 임베딩만 전달하는 것이 아니라 입력 모든 단어의 hidden state가 디코더로 전달된다.
hidden state는 이전에 등장한 단어 정보를 포함하는 RNN의 내부 벡터이다.
디코더는 attention을 통해 전체 입력 시퀀스를 살피고, 언어를 생성한다.
어텐션 덕분에 모든 단어의 임베딩을 활용해 전체 문맥을 볼 수 있어 출력 품질이 크게 향상된다.
생성 도중에는 가장 관련 있는 입력을 집중적으로 참조하는데, 예를 들어 "ik hou van"까지 생성된 상태라면 attention은 이 단계에서 가장 관련 있는 입력 단어를 더 강조한다.
하지만, 이 구조는 순차적 처리 특성때문에 실제 훈련 시 병렬처리가 어렵다.
Transformer

대규모 언어모델의 핵심은 attention의 등장으로 시작되었다. 이 구조는 모델을 병렬학습할 수 있게 해주어 rnn기반 모델처럼 순차적으로 계산해야하는 모델보다 더 빠르게 할 수 있다.
Transformer은 여러개의 encoder과 decoder 블록을 쌓은 구조이다.
이 블록들은 동일한 attention 메커니즘을 가지고, 이 블록을 여러 층으로 쌓아서 성능을 강화시킨다.
Encoder
encoder을 자세히 살펴보면,

입력값은 word2vec를 사용하지 않고 완전 랜덤값을 사용한다. 그 다음 self attention이 적용되어서 자신만의 attention을 수행하여 이 임베딩을 업데이트한다. 이렇게 업데이트 된 임베딩은 attention 메커니즘의 결과로 더 많은 문맥 정보를 얻게된다.
이 임베딩들은 Feed-forward-neural-network로 전달되어 최종적으로 문맥이 반영된 토큰임베딩을 만든다.(확실하게 벡터화하는 느낌?)
인코더의 목적은 텍스트를 표현하는 것이기 때문에 텍스트 임베딩을 생성하는데 매우 적합하다.
self-attention은 attention의 한 메커니즘이고, 두개의 다른 시퀀스를 처리하는 대힌 자기 자신과 비교하여 생성된다.( 한 문장 안에서 각각의 단어가 문장 내의 모든 단어들과 어떤 attention을 가지는지 계산)
Decoder
Encoder가 입력을 처리하면 다음은 Decoder이다.
decoder은 이전에 생성된 단어들을 받아 masked self-attention을 수행한다.

masked self attention은 self attention과 비슷하지만, 행렬의 대각선 위쪽을 가림으로서 미래에 올 단어를 볼 수 없도록 미래 위치를 마스킹하고, attention을 계산한다.
이렇게 하면 모델이 다음 단어를 예측할 때 아직 생성되지 않은 정보를 미리 훔쳐보는 것을 방지할 수 있다.
이걸 하는 이유는 실제 모델이 동작할 때에는 미래에 생성될 토큰을 모르기 때문에 학습과정에서도 이런식으로 조정을 한번 해주는 것이다.

위 과정을 거친 후 생성된 중간 임베딩은 이전 인코더에서 생성된 아웃풋과 함께 또 다른 attention 네트워크로 전달된다. 이 출력은 신경망으로 전달되어 다음 단어를 생성한다.
Representation Models
원래 transformer 모델은 인코더-디코더 아키텍처로 번역 작업에 매우 적합했지만, 텍스트 분류와 같은 다른 작업에는 쉽게 적용하기 어려웠다.
그래서 BERT가 등장하였다. BERT는 Encoder-Only 아키텍처이고, 언어를 표현하고, 문맥이 반영된 단어 임베딩을 생성하는데 초점을 맞춘다.

BERT는 다음과 같은 과정을 거친다. 입력에는 [CLS] 토큰이 필요한데 이 토큰은 전체 입력 문장을 대표하는 임베딩이고, 주로 Fine-tuning 할 때 이 토큰 임베딩을 사용한다.
BERT 계열 모델은 Masked Language Modeling(MLM) 기법으로 학습한다.

이런식으로 단어 하나를 무작위로 mask처리한 후 모델이 마스크 된 단어를 예측하도록 학습시킨다. 이 과정을 통해 모델이 언어구조를 스스로 학습하여 문맥을 반영한 표현을 얻게 된다.

훈련은 주로 MLM을 적용하는 Pre-training 단계, 그리고 이후 여러 작업에 맞게 FIne-tuning하는 작업으로 나뉜다.
Generative Models

다시 입력 시퀀스가 있고, 랜덤 임베딩으로 초기화된다고 했을 때, 입력은 오직 decoder만 통과한다.
그 구현중 하나가 GPT(Generative Pre-trained Transformer)이다.
Decoder 블록은 다시 Masked Self Attention을 사용하고, 그 결과를 신경망에 전달하여 단어를 생성한다.
Context Length의 개념

예를 들어 입력 프롬프트가 tell me something about llamas라고 했을 때 이미 모델이 몇개의 토큰을 생성했으면 이전 입력과 새로 생성된 토큰을 합친 것이 현재의 context length를 이룬다. 즉, context length는 현재 모델이 처리중인 토큰 수이다. 이 때 현재 생성중인 토큰도 context text에 포함된다.
안타깝게도 GPT, BERT같은 모델에는 context length가 존재하다. 예를 들어 512 토큰이면 512 토큰만 처리할 수 있다는 뜻이다.
또한 모델의 파라미터 크기는 계속해서 향상하고 있다. 파라미터가 증가할수록 모델의 성능 역시 증가하고 있다.
QKV
그럼 여기서 궁금해진게 우리 연구실에서는 Q K V 캐시를 다루는 것을 연구하는데 이들의 값은 어떻게 정해지는 것일까? 였다.
이 캐시들은 self attention에 사용된다 Q는 현재 탐색중인 단어에 대한 값이고 k는 연관성을 알고자 하는 단어에 대한 값이다.

Q,K,V는 위와 같이 가중값과 현재 임베딩 값을 곱해서 만들어진다.

그 다음 위와 같이 각 단어의 K값을 현재의 Q값과 연산하여 score 값을 구하고,

softmax 함수로 가중치 정규화를 한 후 가중치로 value 값을 합침으로서 최종 self attention 값을 생성한다.
qkv 가중치는 훈련을 하면서 업데이트 되고, 실제 모델로 사용할 때에는 고정되어있다.
Tokenizer

이전에 input이 주어지면 이를 tokenization 한 후, 이 토큰들을 임베딩 한 값을 language model 에 넣어서 다음 토큰을 구한다고 했다.
임베딩은 language model에서 처리되어 문맥화 된 임베딩으로 변환된다. 문맥화된 임베딩도 여전히 토큰마다 하나씩 존재하지만, 모든 다른 토큰들을 고려해 가공된 표현이다.

위와 같은 문장이 있다고 했을 때 vocabulary수가 제한되어있기 때문에 만약 해당 단어가 voca 안에 있는 단어가 아니라면 위와 같이 서브 토큰으로 쪼개기도 한다. 각 토큰은 인코딩, 디코딩을 쉽게 하기 위한 id가 연결되어 있다. 이 id들이 언어모델에 입력되고, 모델 내부에서 토큰 임베딩이 생성된다. 이 모델의 출력도 또 다른 토큰 id이고, 이는 실제 토큰 또는 단어로 연결된다.
tockenize에는 여러 수준이 있다.

예를 들어 위와 같이 특수기호화 함께 있을 수 있다. 단어 토큰에서 서브토큰으로 변환되면, voca 안에 없는 단어들은 쪼개진다. 이를 더 잘게 쪼개 문자단위의 토큰을 만들수도 있다. 가장 작은 단위는 Byte단위이고, 컴퓨터가 한 문자를 인코딩할 때 사용된다.
이 작업은 모든 문자에 대해 수행된다. 특수기호는 다른 문자에 비해 복잡해서 추가 바이트가 필요하다.

자 이제 직접 토크나이징을 해보자. 토크나이징은 Bert 모델의 토크나이저를 사용했다. 토크나이저로 입력 문장을 처리해 토큰 ID를 뽑아내고, 이를 출력해보면 여러개의 숫자값이 들어가있다. 이를 디코딩해보면 CLS라는 토큰으로 시작하고 SEP라는 토큰으로 특수문자가 처리되는 것을 볼 수 있다.
이제 색깔로 토크나이즈를 해보자

이번에는 vocab length도 출력해봤다. 28996개의 단어가 있다고 한다.
여기서는 대문자로만 이루어진 단어와 숫자, 특수기호가 포함되어있다. 이 토큰을 살펴보면 CLS 토큰으로 시작하고, 대문자 표기를 표현하는데 어려움을 보인다. 그리고 단어를 실제로 표현하기 위해서 여러 토큰으로 잘게 나누어지는 것도 살표볼 수 있다. 토큰 앞의 #는 그 토큰이 바로 앞 토큰에 이어지는 조각임을 의미한다. 토큰 사이이 UNK 토큰은 unknown 토큰으로 어떻게 토큰으로 표현할지 모를 때 사용된다.

이제 gpt의 토크나이저를 보자. 여기는 bert 모델보다 어휘크기가 3배 큰 것을 확인할 수 있다. 그 덕분에 동일한 입력에 대한 필요한 토큰의 수가 적다. 이 토크나이저는 생성형 표현에 맞춰져있어 CLP, SEP와 같은 특수 토큰을 사용하지 않는다.
하지만 이렇게 어휘 크기가 크면 각 토큰에 대한 임베딩을 더 많이 학습하고 계산해야한다. 그럼 비용이 커진다.
따라서 어휘크기와 학습비용은 서로 트레이드오프 관계이다.
그럼 전체 플로우에서 ID는 어디 쓰이지?
나는 분명히 행렬로 계산된다고 알고 있는데 저 토큰 id는 계산도 안되는데 왜 있는걸까라는 의문이 들었다.
그래서 찾아본 결과 임베딩 행렬이 토큰 id별 행렬값을 저장하고 있는 것이었다.
아니 사실 좀 지금 생각하면 어이없긴 한데 초반에 이 값이 랜덤으로 생성된다고 해서 당연히 모든 경우에 랜덤생성인줄 알았는데 그건 모델 생성 완전 초반 이야기이고, 학습을 하면서 이 임베딩 행렬이 업데이트 되는 것이라고 한다. 그래서 토크나이저로 id 값을 얻으면 임베딩벡터 안에서 해당 id에 해당하는 행렬을 가져와서 계산을 하면 되는 것이다.

이런식으로..
아 그리고 더 의문이었던 것은 동음이의어인 단어에 대한 것도 모두 같은 토크나이저 id를 가진다는 것이다.
그럼
고구마처럼 맛있는 (밤)
아 이제 슬슬 어두워지네 (밤)
처럼 같은 글자이지만 다른 의미의 단어가 와야 할 때에 어떻게 같은 벡터값을 가지고 있는데 두 경우에 모두 밤이 올 확률이 높다고 인지할 수 있는거지? 라는 생각이 들었다.( 단어 의미가 완전히 다르니까 당연히 다른 id값을 가진 벡터와 연관성이 높지 않을까? 라는 생각)
그런데 모델은 의미를 맞추는 것이 아니라 다음에 올 토큰 자체를 맞추는 것이다.

이건 각 토큰별로 계산을 해서 어떤 토큰이 가장 다음에 올 확률이 높은지 계산하는 수식이다. 여기서 h는 문맥이다. 즉 "고구마처럼 맛있는"을 self attention 등으로 히든벡터로 만든 것이다.

이들을 이런식으로 최종적으로 계산했을 때 당연히 둘의 값이 같을수는 없다.
하지만 다음 토큰을 결정하는 것은 이런 상대적인 점수차가 아닌 다른 토큰들(사과, 낮, 다람쥐 등..) 에 비해서 가장 높은지 여부이다.
따라서 같은 토큰이 다른 의미를 가진 h가 나와도 다음 토큰으로 뽑힐 수 가 있다는 것이다.

'AI > LLM' 카테고리의 다른 글
| [LLM]안드레이 카파시: ChatGPT와 같은 LLM 기술의 심층 분석(강화학습 등) (0) | 2025.09.25 |
|---|---|
| [LLM] 안드레이 카파시 : ChatGPT와 같은 LLM 기술의 심층 분석(훈련 과정) (0) | 2025.09.24 |