공통 · 2026-09-09
LLM의 전체 구조: 임베딩 층에서 LM Head까지
텍스트가 토큰 ID와 벡터를 거쳐 어휘별 점수로 바뀌는 흐름과 임베딩 층, 디코더 블록, LM Head의 역할을 살펴봅니다.
지난 글에서는 LLM 시스템 엔지니어링을 모델, 하드웨어, 워크로드를 연결하는 관점에서 살펴봤습니다. 이번 글부터는 모델을 먼저 살펴보겠습니다. 모델 내부의 계산을 이해하려면 입력이 어떤 형태로 바뀌고, 어떤 경로를 거쳐 출력으로 이어지는지 알아야 합니다. 이번 글에서는 decoder-only Transformer를 기준으로 전체 구조와 그 양 끝에 있는 임베딩 층, LM Head의 역할을 설명하겠습니다.
모델의 전체 구조
LLM의 구조를 단순화하면 임베딩 층 → 여러 개의 디코더 블록 → LM Head로 볼 수 있습니다. 임베딩 층은 입력 토큰을 벡터로 바꾸고, 디코더 블록은 이 벡터들을 차례로 변환합니다. 마지막의 LM Head는 변환된 벡터를 다음 토큰을 선택하는 데 사용할 점수로 바꿉니다. 그림에서는 이 흐름을 보기 쉽도록 최종 정규화 등의 세부 단계를 생략했습니다.
왼쪽의 디코더 블록 × N을 펼치면 오른쪽처럼 여러 블록이 이어집니다. 한 블록의 출력이 다음 블록의 입력이 되는 구조입니다. 여기서 반복된다는 것은 같은 형태의 블록을 쌓는다는 뜻이며, 각 블록은 일반적으로 서로 다른 가중치를 갖습니다. 이번 글에서는 블록의 내부를 하나의 상자로 두고, 입력과 출력이 어떻게 이어지는지부터 살펴보겠습니다.
토크나이저: 텍스트를 ID로 변환하기
모델에 텍스트를 넣으려면 먼저 **토크나이저(Tokenizer)**를 거쳐야 합니다. 토크나이저는 텍스트를 토큰이라는 단위로 나누고, 각 토큰에 대응하는 정수 ID를 반환합니다. 토큰은 단어 전체일 수도 있고 단어의 일부, 공백이나 문장부호를 포함한 조각일 수도 있습니다. 어떤 단위로 나누고 어떤 ID를 부여하는지는 토크나이저에 따라 달라집니다.
예를 들어 Qwen3 토크나이저에서 Hello world!는 Hello, world, !로 나뉘고, 각각 9707, 1879, 0이라는 ID에 대응합니다. 그림의 ␣는 world 앞의 공백을 보이게 표시한 기호입니다. 이 ID는 각 토큰을 구별하는 번호입니다. ID의 숫자 크기가 토큰의 의미나 중요도를 나타내는 것은 아닙니다. 이제 이 ID 목록을 임베딩 층에 전달합니다.
임베딩 층: ID에 해당하는 벡터 가져오기
임베딩 층은 토큰 ID에 해당하는 임베딩 벡터를 가져옵니다. 벡터는 여러 숫자를 순서대로 나열한 것이고, 여기에 들어 있는 숫자의 개수를 차원이라고 합니다. 모델이 사용하는 토큰의 집합을 어휘(vocabulary)라고 할 때, 어휘 크기를 V, 모델 차원을 d라고 하면 임베딩 테이블은 V개의 행과 d개의 열로 이루어집니다. 각 행에는 해당 토큰의 d차원 벡터가 저장되어 있고, 이 값들은 모델 학습 과정에서 조정됩니다.
입력 ID가 9707이면 테이블에서 그 ID에 해당하는 행을 가져옵니다. 세 개의 토큰 ID를 넣으면 입력 순서대로 세 개의 벡터가 나옵니다. 이것이 임베딩 조회, 즉 embedding lookup입니다. 그림에서는 전체 테이블의 일부 행을 생략하고, 조회할 세 행을 강조했습니다. 테이블 안의 행 순서와 관계없이 출력은 입력 ID의 순서인 9707, 1879, 0을 따릅니다. 그림의 4차원 벡터와 숫자는 설명용 예시입니다.
디코더 블록: 차원은 유지되고, 벡터 값은 달라집니다
임베딩 층에서 나온 벡터들은 디코더 블록으로 들어갑니다. 토큰 수가 T이고 각 벡터의 차원이 d라면, 입력은 T개의 행과 d개의 열을 가진 T × d 형태로 나타낼 수 있습니다. 한 행이 한 토큰의 표현에 해당합니다. 디코더 블록은 이 표현들을 계산한 뒤 같은 T × d 형태로 출력합니다. 그림에서는 한 입력 문장을 기준으로 설명하기 위해 배치 축을 생략했습니다.
여기서 중요한 점은 입력과 출력의 차원이 같아도 벡터의 값은 달라진다는 것입니다. 디코더 블록을 지나면서 각 토큰의 벡터 값이 바뀌고, 앞선 토큰의 정보가 반영됩니다. 이 출력은 다시 다음 디코더 블록의 입력이 됩니다. 여러 블록이 같은 형태의 입출력을 유지하면서 벡터 값을 차례로 바꾸는 것입니다. 이 변환을 담당하는 블록 내부의 구조는 다음 글부터 살펴보겠습니다.
LM Head: 벡터를 어휘별 점수로 변환하기
디코더 블록들과 최종 정규화를 거친 토큰 표현은 LM Head로 들어갑니다. LM Head는 학습된 가중치와의 행렬 곱으로 각 토큰의 d차원 표현을 V개의 점수로 바꿉니다. V는 어휘 크기이며, 출력의 각 점수는 어휘 안의 토큰 하나에 대응합니다. 따라서 전체 형태는 T × d에서 T × V로 바뀝니다. 토큰 위치를 나타내는 행은 유지되고, 열의 의미가 모델의 특징에서 어휘별 점수로 달라집니다.
이 점수들을 logits라고 합니다. Logits는 아직 확률이 아니며, 다음 토큰을 선택하기 위한 기준이 됩니다. 생성할 때는 마지막 입력 위치에서 나온 점수들을 사용합니다. 예를 들어 세 토큰을 입력했다면 세 번째 위치의 점수로 그다음 토큰을 선택합니다. 임베딩 층이 입력 ID에 해당하는 벡터를 가져왔다면, LM Head는 문맥이 반영된 벡터에서 다음에 올 토큰들의 점수를 계산하는 역할을 합니다.
이제 텍스트가 토큰 ID와 벡터를 거쳐 어휘별 점수로 바뀌는 전체 경로를 살펴봤습니다. 다음 글에서는 하나의 상자로 두었던 디코더 블록의 내부를 살펴보겠습니다. 먼저 Residual 연결과 RMSNorm을 통해 블록의 골격을 살펴보고, 그 안에서 Attention과 MLP가 어떤 위치에 놓이는지 설명하겠습니다.




