You can make anything
by writing

C.S.Lewis

by 돌부처 Feb 02. 2025

[AI상식] LLM은 어떻게 카지노 게임할까? #2

Positional Encoding 편


LLM 동작에 대해서 지난 글에서는 간략한 개요와, Embedding에 대해서 알아봤습니다. 실제 Embedding의 동작에 대해서 깊게 알아보려면 많은 이해가 필요합니다만, 개념적인 이해를 위해서 최대한 간단하고 쉽게 작성하려고 해 봤습니다. 아. 우리가 말하는 AI라는 것이 LLM이라는 것을 쓰는데, 이렇게 동작하는구나? 정도의 이해를 할 수 있을 정도로요. �


지난 글은 아래를 참고해주세요.


https://unnamed-underdogs.tistory.com/28


이어서 2편을 시작해 보겠습니다. 이번에는 Positional Encoding이라는 것에 대해서 알아보려고 합니다. 이름에서 알 수 있듯이 위치에 대한 뭔가 처리를 하는 그런 것입니다.


우리가 AI(LLM)에 뭔가를 요청할 때 텍스트를 주면, LLM은 이를 토큰이라는 것으로 변환한다고 했었죠? (Embedding). 그런데 우리가 주는 문장을 보면, 중요한 부분이 있죠. 문장들의 순서입니다. 이 순서가 잘 못되면 문장을 이해하기 어렵잖아요? 그런데 embedding 과정에서는 단순히 단어를 토큰(+정보)으로 변환을 했을 뿐, 문장을 구성하는 각 토큰(단어)들의 순서에 대한 정보는 없습니다.


그것을 해결하기 위한 것이 바로, Positional Encoding인 것이죠. LLM이라는 것이 들여다 보면 재밌는 부분 중 하나는, 사람이 생각하는 것을 기계가 어떻게 동일하게 할 수 있을지를 연구하는 것이라고 생각합니다. �


Positional Encoding이라는 것을 간단히 설명하면, 각 단어가 문장속에서 어느 위치에 있는지를 알려주는 것입니다.


"안녕, 나는 고양이를 좋아해"라는 문장이,

토큰화를 거치면 [409, 12, 25, 7, 99, 101, 103] 처럼 토큰 ID로 변환이 되고요,

Positional 정보는 [0, 1, 2, 3, 4, 5, 6]이 되는 것입니다. (문장 내 각 단어의 위치 정보, 여기서는 그냥 예시입니다.)


그리고 이 두 정보를 "결합" 해서 단어 임베딩에 위치 정보를 반영하게 되고 이것이 모델 (Transformer)의 입력으로 들어가게 되는 것입니다.


만약 position 정보가 없다면, "안녕/나/는/고양이/를/좋아해" 라는 문장과 "안녕/고양이/는/나/를/좋아해"를 LLM에서는 구분할 수 없게 되는 것이죠. 고양이라는 단어(토큰)와 나라는 단어(토큰)의 위치가 어디 인지 알 수가 없거든요. 그래서 이러한 정보들을 가지고 모델은 학습을 하면서, 문장 처음에 "고양이"라는 단어가 올 때 어떤"확률"로 다음 단어가 되는지, 또는 문장 중간에 "고양이"라는 단어가 오면 어떤 구문이 자연스러운지 등을"배우게"되는 것입니다.


이러한 position 정보를 만드는 방법은 크게 2가지 입니다.

sin/cos 기반 (Sinusoidal Encoding)

학습형 벡터 (Learned Positional Encoding)

sin/cos 나오니까 벌써 머리가 아프시다고요? 네 저도 그렇습니다. �

그래서 최대한 간단하게 살펴보겠습니다. 한 번 같이 보시죠.


Sinusoidal Encoding


먼저 sin/cos 기반의 인코딩은, 문장 내 위치를 수학적카지노 게임 표현해 보자! 에서부터 시작합니다. Attention is all you need라는 논문에서 처음 제안된 기법카지노 게임, 각 단어가문장 내 몇 번째 위치인지(0번, 1번, 2번…)를사인(sin), 코사인(cos)함수를 이용해벡터로 나타내는 것입니다.


머리 꽉 잡으세요 수식 나갑니다.


위치 = pos, 임베딩 차원에서의 인덱스 = i (짝수/홀수), 모델의 임베딩 차원 = d_model 이라고 할 때, 아래와 같습니다.


카지노 게임


개념적카지노 게임 간단하게 살펴 볼께요.

sin, cos은 "주기적"카지노 게임 오르락, 내리락하는 모양을 나타냅니다. sin/cos 그래프는 많이들 보셨으리라 생각합니다.

카지노 게임


여기서 sin, cos을 사용하는 이유는 "주기적으로 반복되는 패턴"을 수학적으로 나타낸 것일 뿐입니다. 그리고 10000 {...} 이 부분은 그 주기적으로 반복되는 패턴(파동)을 어떤 주기로 할 것인지를 결정하는 값인 것이죠. 이 값이 작은 값이면 빨리 변하는 파동, 큰 값이면 느리게 변하는 파동이 되는 것입니다.


예를 들어보면, 안녕 - 토큰 ID: 409번이 되고, 위치는 0일 때, 임베딩 차원이 4096이라고 하면,

임베딩 차원 4096개에 대해서,

임베딩 차원 0 - sin(),

임베딩 차원 1 - cos(),

...

임베딩 차원 4094 - sin(),

임베딩 차원 4095 - cos() 을 수행하면 4096개의 어떤 값이 나오겠죠? 그 값들을 모두 더한 값이 토큰 409번의 Positional Encoding 값이 되는 것입니다. Positional encoding을 구글 이미지 검색해 보면, 아래처럼 그라디에이션 된 색으로 표시된 그래프를 볼 수 있는데요. 이렇게 이해하시면 쉽습니다. sin/cos으로 생성된 각 파동이 각각의 LED라고 생각해 보세요. 이 LED는 자신만의 "주기"로 색깔이 계속해서 바뀐다고 가정해 보면요,

0번 LED는 1초 주기로 빨-노-파-빨,

1번 LED는 0.5초 주기로 빨-노-파-빨,

2번 LED는 2초 주기로 빨-노-파-빨,


그럼 특정 시간에 이 LED들이 비추는 곳을 보면, 어떤 특정 "색깔"을 갖고 있겠죠? 매 특정 시점마다 이 색깔은 모두 다른 값을 가지게 될 것입니다. 모델은 이 "색깔"을 보고 지금 시점의 시간이 무엇인지 "식별"할 수 있게 되는 것입니다. 즉 이렇게 여러 파동들이 합쳐진 값을 보고 이 토큰의 위치가 어디인지를 식별하게 되는 것이죠.


임베딩 차원이 8이라고 하면 이런 식의 그래프가 됩니다.

카지노 게임

그리고 임베딩 차원이 512이라고 하면, 이렇게 복잡한 그래프가 되는거죠.

(예제 코드로 표현한 것이므로, 실제와 다를 수 있습니다. 개념적카지노 게임 참고만 하세요 �)

이렇게 수식카지노 게임 표현할 수 있기 때문에, 추가적인 파라미터가 필요 없게 되고, 상대적카지노 게임 가볍고"규칙적"방식이 됩니다. 즉 이런 규칙적인 방식이 되기 때문에 패턴이 고정되니까, 어떨 때에는 더"유연한"방식이 필요할 수 있겠죠? 그래서 나온 방식이 위치별로 벡터를 직접"학습"하는 방식입니다.


Learned Positional Encoding


이 방식은 단어 임베딩과 유사합니다. pos_embedding_maxrix가 하나 있어야 하고요. 문장에서 0번 위치는 행 0, 1번 위치는 행 1... 이런 식으로 인덱싱 해서, 해당 위치에 있는 정보를 가져오는 것입니다. 해당 위치에 있는 정보는 당연히 "학습"시 업데이트 되겠죠? - 데이터 상, "첫 번째 단어는 이런 특성을 반영하면 예측이 더 좋아진다"와 같은 방식으로 이 정보(위치 벡터)가 계속 업데이트되는 것입니다. 이렇게 학습에 의해서 정보가 업데이트되기 때문에, 어떤 위치에서 어떤 벡터가 좋을지 스스로 결정할 수 있는 유연성이 확보되겠죠. 하지만 각 위치마다 파라미터가 추가로 필요하기 때문에, 추가로 메모리를 사용해야 하는 단점이 있습니다.


지금까지 살펴본 Sinusoidal Encoding 방식과 Learned Positional Encoding 방식 모두 공통적 속성이 있습니다. 두 방식 모두 절대적 위치(예: 0번 토큰, 1번 토큰…)”를 직접 벡터에 담는다는 것입니다. 따라서 문장의 일부를 잘라내거나, 중간에 문장을 삽입하거나 하면 이 절대 위치가 바뀌어버리겠죠? 그럼 모델이 대응하기 힘들어질거구요. 이를 해결하기 위한 상대적 위치 인코딩(Relative PE) 방식으로 등장한 기법이 RoPE (Rotary Position Embedding)입니다.


RoPE (Rotary Position Embedding)


임베딩 차원을짝수/2개씩 쌍으로 묶어, 2차원씩 “회전 행렬”을 적용하는 것입니다. 즉 쉽게 말하면 "벡터를 회전"시키는 것이죠.


머리 아프지 않게 개념적으로 이해할 수 있게 살짝 살펴 보겠습니다. �

벡터를 회전시킨다는 것은 아래 그림과 같습니다.


(x, y)라는 좌표가 있을 때, 어떤 각도 (θ) 만큼 돌려서 새로운 좌표 (x', y')를 구하는 것이죠. RoPE에서는 문장 내 토큰의 위치가 바뀌면 이 회전각도(θ)가 달라집니다. 따라서, 같은 단어라도 문장 앞쪽에 있을 때와 뒤쪽에 있을 때, 벡터가살짝 다른 방향카지노 게임 회전하게 되는 것이죠. 결과적카지노 게임, “어느 두 토큰이 얼마나 떨어져 있느냐(상대적 거리)”가서로 다른 회전 상태로 나타나게 됩니다.모델은 “다른 각도로 돌려진 벡터들”을 보고, 문장 내 위치 정보를 학습할 수 있습니다.


RoPE가 카지노 게임하는 방식은 간단합니다. 임베딩 차원이 D라면, D/2개의 2D 쌍으로 나눕니다. 예를 들어 임베딩 차원(dim)=768 이면, 384개의 2D 쌍을 만다는 것이죠. 임베딩 차원이 768이라는 것은 지난 글에서 살펴 봤듯이, 한 토큰(단어)를 표현하기 위해 "768개의 숫자"를 쓰고 있다는 뜻입니다. RoPE에서는 “2차원(2D)마다 한 쌍”카지노 게임 묶어서(x, y)형태로 보고, 이를 빙글 돌리는 “회전”을 합니다. 즉, 768차원을 (x₀,y₀), (x₁,y₁), … (x₃₈₃,y₃₈₃)처럼384개 쌍으로 쪼갠 뒤, 각 쌍을 “회전 행렬”에 따라 돌려주면, 위치(pos)에 따라 다른 벡터가 만들어지는 원리예요. 그리고 문장 내 0번 단어, 1번 단어, … 각 위치(pos)마다, “이 위치에서 (x,y)를 몇 도(또는 몇 라디안)만큼 회전할지”라는각도를 정해둡니다(또는 미리 배열로 준비). 이렇게요. pos=0 →θ=0 (회전 없음), pos=1 →θ=0.01, pos=2 →θ=0.02... 이렇게 하는 이유는 간단하겠죠?문장 속에서 앞뒤 토큰의 상대적 위치 차이”를 ‘회전 상태(위상)’로 구분하려는 것입니다. 모델이 이 회전 상태를 보고 이 토큰의 위치가 어디인지나, 2개의 토큰의 거리가 얼마나 되는지 등을 아주 쉽게 알 수 있는 것이죠! �


(물론 좀 더 복잡한 공식을 적용할 수도 있습니다.)


그 후 self-attention 계산 시, Query[pos]와 Key[pos] 벡터에 RoPE를 적용해서 "회전"된 Q', K' 를획득하고, 이후 Q' x K' 점곱(dot product)에서, 위치 차이에 따른 위상(phase) 변화를 반영하게 됩니다. 즉위치 정보가 녹아 들어간 벡터가 된다는 것이죠.


갑자기 self-attention이니 Query니 Key가 나와서 당황스러울 수 있는데,

아직 self-attention에 대해서는 살펴보지 않았으니, 이 부분은 다음 글에서 설명하겠습니다. 다만, 회전된 Q와 K 벡터 간 내적을 구하면,“pos1 vs pos2” 토큰의 상대적 거리/순서를 구할 수 있게 되는데, RoPE는 “절대 위치” 대신“상대적 각도 차이”를 통해 어텐션에 위치 정보를 주입한다!라고 이해하면 좋습니다.


수식이 아주 조금 약간 있긴 했지만, 많은 수학적 지식 필요 없이 LLM (Transformer) 동작을 이해하실 수 있게 되셨을거라 생각합니다. �

The Transformer - model architecture from "Attention is all you need"


이 그림이 바로 transformer model의 아키텍처입니다. 우리가 사용하는 대부분의 AI (LLM)이 기본적카지노 게임 이러한 구조를 채택하고 있습니다. 지난번에 이어서 이번 글에서 살펴본 부분이 바로 그림의 맨 아래에 있는 Input Embedding과 Positional Encoding 부분인 것이죠.


다음 글에서는 self-attention을 살펴보겠습니다.


끝.


출처:https://unnamed-underdogs.tistory.com/29

브런치는 최신 브라우저에 최적화 되어있습니다.