Transformer는 문장을 순서대로 한 토큰씩 읽는 구조가 아니다. RNN은 앞에서 뒤로 흐르면서 자연스럽게 순서 정보를 얻지만, Transformer의 self-attention은 한 번에 여러 토큰을 놓고 서로의 관계를 계산한다. 이 구조는 병렬 계산에 강하지만, 토큰의 순서를 별도로 넣어주지 않으면 “나는 밥을 먹었다”와 “밥은 나를 먹었다”의 차이를 구조만으로 알기 어렵다.
Sinusoidal positional encoding은 이 문제를 해결하기 위해 Transformer 입력에 위치 정보를 더하는 방식이다. Attention Is All You Need 논문에서 사용된 기본 위치 인코딩이며, 각 토큰의 위치를 여러 주파수의 sine과 cosine 값으로 바꿔 벡터에 더한다.
내가 이 메커니즘을 정리할 때 가장 중요하게 보는 지점은 “순서를 숫자 하나로 박아 넣는 것”이 아니라 “위치를 여러 파장의 신호 조합으로 표현한다”는 점이다. 이 관점으로 보면 공식이 훨씬 덜 낯설어진다.

Sinusoidal positional encoding의 위치별 패턴. 출처: Naoki Shibuya
1. Transformer에는 왜 위치 정보가 필요한가
문장은 단어의 집합이 아니라 순서가 있는 구조다. 같은 단어라도 앞뒤 위치가 바뀌면 의미가 바뀐다.
예를 들어 다음 두 문장은 같은 단어를 거의 공유하지만 의미가 다르다.
- 고양이가 생선을 먹었다.
- 생선이 고양이를 먹었다.
사람은 조사와 어순을 함께 보며 의미를 파악한다. 모델도 마찬가지로 토큰 자체의 의미뿐 아니라 각 토큰이 문장 안에서 어디에 있는지 알아야 한다.
RNN 계열 모델은 순서대로 계산하기 때문에 위치가 계산 흐름 안에 자연스럽게 들어간다. 반면 Transformer의 attention은 모든 토큰 쌍을 동시에 비교한다. 이 방식은 빠르고 강력하지만, 별도 장치가 없으면 “몇 번째 토큰인가”라는 정보가 사라진다.

Transformer 입력 단계에서 위치 정보가 추가되는 구조. 출처: Gowri Shankar
2. 가장 단순한 생각은 위치 번호를 더하는 것이다
가장 단순한 방법은 각 토큰에 0, 1, 2, 3 같은 위치 번호를 붙이는 것이다. 하지만 위치 번호 하나를 그대로 넣으면 문제가 생긴다.
첫째, 위치 번호는 토큰 임베딩 벡터와 크기와 의미가 다르다. 임베딩은 보통 수백 차원의 벡터인데, 위치 번호는 하나의 정수다. 둘을 바로 더하면 표현 방식이 맞지 않는다.
둘째, 큰 위치 번호는 값의 스케일 문제를 만들 수 있다. 10번째 토큰과 10000번째 토큰을 같은 방식으로 다루기 어렵다.
셋째, 모델은 절대 위치뿐 아니라 상대 위치도 알아야 한다. “지금 토큰에서 세 칸 앞” 같은 관계는 언어 이해에서 매우 중요하다.
그래서 Transformer는 위치 번호를 그대로 쓰지 않고, 위치 번호를 임베딩과 같은 차원의 벡터로 바꾼다. Sinusoidal positional encoding은 이 변환을 sine과 cosine 함수로 수행한다.

토큰 임베딩에 위치 인코딩을 더해 Transformer 입력을 만드는 구조. 출처: Naoki Shibuya
3. 공식은 길지만 의미는 단순하다
논문에서 사용한 sinusoidal positional encoding 공식은 다음과 같다.
PE(pos, 2i) = sin(pos / 10000^(2i / d_model))
PE(pos, 2i + 1) = cos(pos / 10000^(2i / d_model))
여기서 pos는 토큰의 위치다. 첫 번째 토큰이면 0, 두 번째 토큰이면 1처럼 생각하면 된다.
i는 벡터 안의 차원 인덱스다. 짝수 차원에는 sine 값을 넣고, 홀수 차원에는 cosine 값을 넣는다.
d_model은 Transformer가 사용하는 임베딩 차원 수다. 예를 들어 d_model = 512라면 위치 인코딩도 512차원 벡터가 된다.
이 공식은 복잡해 보이지만 핵심은 하나다. 위치 pos를 여러 속도의 파동으로 동시에 표현한다. 낮은 차원에는 빠르게 변하는 파동이 들어가고, 높은 차원에는 천천히 변하는 파동이 들어간다.

sine 파형은 위치를 연속적인 신호값으로 바꾸는 기본 재료다. 출처: All About Circuits
4. sine과 cosine은 위치를 파동의 조합으로 바꾼다
sine과 cosine은 주기적으로 반복되는 함수다. 이 주기성 때문에 처음 보면 “반복되면 위치가 헷갈리지 않나”라는 생각이 든다. 중요한 점은 하나의 sine 값만 쓰지 않는다는 것이다.
Sinusoidal positional encoding은 여러 주파수의 sine과 cosine을 한꺼번에 사용한다. 어떤 차원은 짧은 주기로 빠르게 출렁이고, 어떤 차원은 긴 주기로 천천히 변한다. 여러 파장을 조합하면 각 위치는 꽤 구분 가능한 패턴을 갖게 된다.
비유하면 위치 하나를 색 하나로 표현하지 않고, 여러 색의 비율로 표현하는 방식에 가깝다. 빨강 하나만 보면 비슷한 색이 많지만, 빨강, 초록, 파랑, 밝기, 채도를 함께 보면 훨씬 더 많은 상태를 구분할 수 있다.
이 구조는 르장드르 근사와도 연결해서 볼 수 있다. 르장드르 근사는 함수를 직교적인 다항식 기저의 조합으로 표현한다. Sinusoidal positional encoding은 위치를 여러 주파수의 삼각함수 성분으로 표현한다. 둘 다 복잡한 대상을 여러 기저 성분의 조합으로 다룬다는 점에서 같은 큰 틀의 사고방식을 공유한다.

위치와 차원에 따라 달라지는 positional encoding heatmap. 출처: QuarkML
5. 위치 벡터는 토큰 임베딩에 더해진다
Transformer 입력은 보통 토큰 임베딩과 위치 인코딩을 더해서 만든다.
input_vector = token_embedding + positional_encoding
토큰 임베딩은 “이 토큰이 무엇인가”를 담는다. 위치 인코딩은 “이 토큰이 어디에 있는가”를 담는다. 둘을 더하면 모델은 한 벡터 안에서 의미와 위치를 함께 받는다.
예를 들어 “고양이”라는 토큰이 문장 첫 번째에 있을 때와 다섯 번째에 있을 때 토큰 임베딩 자체는 같을 수 있다. 하지만 위치 인코딩이 다르기 때문에 Transformer에 들어가는 최종 입력 벡터는 달라진다.
이 방식은 단순하지만 강력하다. 모델 구조를 크게 바꾸지 않고도 위치 정보를 입력에 주입할 수 있다. self-attention은 이 벡터들을 사용해 토큰 간 관계를 계산하므로, attention 계산 안에도 위치 정보가 간접적으로 반영된다.

위치 인코딩이 위치와 차원으로 구성된 행렬 형태를 갖는다는 점을 보여주는 그림. 출처: Next Electronics
6. 왜 sine과 cosine을 같이 쓰는가
sine만 써도 위치에 따라 값이 달라진다. 그런데 cosine을 함께 쓰면 같은 주파수에서 위상 차이가 있는 두 신호를 동시에 사용할 수 있다.
sine과 cosine은 같은 파형이지만 서로 90도 어긋나 있다. 이 조합은 위치 이동을 표현할 때 유리하다. 논문에서는 sinusoidal encoding을 쓰면 모델이 상대 위치에 대한 표현을 쉽게 학습할 수 있다고 설명한다. 특정 offset k에 대해 PE(pos + k)를 PE(pos)의 선형 함수로 표현할 수 있기 때문이다.
이 말은 초보자 입장에서는 이렇게 이해하면 된다. 한 토큰의 위치 벡터와 다른 토큰의 위치 벡터를 비교하면 “두 토큰이 얼마나 떨어져 있는지”를 모델이 계산하기 쉬운 형태로 남긴다는 뜻이다.
절대 위치만 알면 “이 토큰은 10번째”라는 정보가 된다. 상대 위치까지 다루기 쉬우면 “이 토큰은 저 토큰보다 3칸 뒤”라는 관계를 표현하기 좋아진다. 언어에서는 후자가 매우 중요하다.

절대 위치와 상대 위치를 함께 생각할 때 필요한 positional encoding 관점. 출처: nomulog
7. 학습되는 위치 임베딩과 무엇이 다른가
위치 정보를 넣는 방법은 크게 두 가지로 나눌 수 있다.
- 고정된 공식으로 위치 벡터를 만든다.
- 위치 벡터 자체를 파라미터로 두고 학습한다.
Sinusoidal positional encoding은 첫 번째 방식이다. 학습으로 바뀌지 않는다. 위치 번호와 차원 인덱스를 공식에 넣으면 항상 같은 값이 나온다.
학습되는 위치 임베딩은 두 번째 방식이다. 모델이 학습 데이터에서 각 위치의 벡터를 직접 조정한다. 이 방식은 데이터와 태스크에 잘 맞는 위치 표현을 배울 수 있지만, 학습 때 보지 못한 더 긴 길이에 대한 일반화는 별도의 고려가 필요하다.
Sinusoidal 방식의 장점은 공식 기반이라는 점이다. 학습 파라미터가 늘어나지 않고, 이론적으로는 학습 때보다 긴 위치에 대해서도 값을 계산할 수 있다. 다만 실제 긴 문장 일반화 성능은 모델 구조, 학습 데이터, attention 구현, 컨텍스트 길이 설정에 함께 영향을 받는다.

위치 정보를 표현하는 여러 방식의 비교. 출처: nomulog
8. 초보자가 공식에서 놓치기 쉬운 부분
첫째, positional encoding은 토큰을 정렬하는 알고리듬이 아니다. 이미 주어진 토큰 순서에 위치 신호를 붙이는 입력 표현 방식이다.
둘째, sine과 cosine은 장식이 아니다. 여러 주파수의 파동을 사용해 위치를 고차원 벡터로 펼치는 장치다.
셋째, 위치 인코딩만으로 문장을 이해하는 것은 아니다. 위치 인코딩은 재료 중 하나다. 실제 의미 관계는 self-attention, feed-forward network, normalization, 학습된 가중치가 함께 만들게 된다.
넷째, Transformer가 위치 정보를 모른다는 말은 “구조적으로 순서를 자동으로 처리하지 않는다”는 뜻에 가깝다. 입력에 위치 정보를 추가하면 self-attention도 순서가 반영된 벡터를 다룬다.
9. 근사 추론 관점에서 보면 무엇이 보이는가
Sinusoidal positional encoding은 위치라는 이산적인 값을 연속적인 함수값들의 조합으로 바꾼다. 각 위치는 하나의 정수가 아니라 여러 파동 성분의 벡터가 된다.
이 관점은 근사 계산과도 연결된다. 복잡한 대상을 직접 다루기 어렵다면, 계산하기 쉬운 기저 성분들의 조합으로 바꿔 다룰 수 있다. 르장드르 근사가 함수를 다항식 기저의 계수로 압축하듯, sinusoidal positional encoding은 위치를 삼각함수 기저의 패턴으로 펼친다.
Transformer는 이 위치 패턴을 그대로 해석하는 것이 아니라, 학습된 attention 가중치와 선형 변환을 통해 필요한 관계를 뽑아낸다. 그래서 positional encoding은 “위치를 이해한 결과”가 아니라 “위치를 이해할 수 있게 해주는 입력 좌표계”에 가깝다.
10. 한 문장으로 정리하기
Sinusoidal positional encoding은 Transformer가 토큰 순서를 알 수 있도록, 각 위치를 여러 주파수의 sine과 cosine 값으로 만든 고차원 벡터로 바꿔 토큰 임베딩에 더하는 방식이다.
공식 자체보다 중요한 것은 구조다. Transformer는 순서를 자동으로 갖고 있지 않다. 그래서 위치를 벡터로 만들어 입력에 넣는다. 이때 sine과 cosine은 위치를 여러 파장의 조합으로 표현하게 해주며, 그 결과 모델은 절대 위치와 상대적인 거리 관계를 학습하기 쉬운 형태로 입력받는다.