AI

LLM은 실제로 어떻게 작동할까?

행복한 수지아빠 2026. 6. 9. 12:08
반응형

토큰부터 어텐션, 다음 단어 예측까지 한 번에 이해하기

요즘 AI를 이야기할 때 가장 많이 등장하는 단어가 있습니다. 바로 LLM, 즉 대규모 언어 모델입니다.

ChatGPT, Claude, Gemini, LLaMA 같은 모델들이 모두 이 범주에 들어갑니다. 겉으로 보면 이 모델들은 사람처럼 글을 읽고, 질문에 답하고, 코드를 짜고, 번역하고, 요약하고, 심지어 창작까지 하는 것처럼 보입니다.

그런데 내부에서는 실제로 무슨 일이 벌어질까요?

LLM은 사람이 글을 읽듯이 문장을 “이해”하는 방식으로 작동하지 않습니다. 더 정확히 말하면, 텍스트를 숫자로 바꾸고, 그 숫자들 사이의 관계를 계산한 뒤, 다음에 올 가능성이 높은 토큰을 하나씩 예측하는 방식으로 작동합니다.

현대 LLM의 대부분은 트랜스포머 Transformer라는 구조를 기반으로 만들어집니다. 트랜스포머 블록을 여러 층으로 계속 쌓아 올린 것이 오늘날의 대형 언어 모델이라고 볼 수 있습니다.

이 글에서는 복잡한 수식은 최대한 줄이고, LLM 내부에서 어떤 순서로 일이 일어나는지 차근차근 살펴보겠습니다.


1. 텍스트는 먼저 숫자가 된다: 토큰화

LLM은 우리가 입력한 문장을 그대로 읽지 않습니다.

예를 들어 우리가 이렇게 입력했다고 해보겠습니다.

오늘 날씨가 정말 좋다.

사람은 이 문장을 바로 읽고 의미를 이해합니다. 하지만 LLM은 이 문장을 직접 처리하지 않습니다. 먼저 문장을 잘게 쪼갠 뒤, 각각을 숫자로 바꿉니다. 이 과정을 토큰화 Tokenization라고 합니다.

토큰은 반드시 단어 하나와 같지 않습니다. 어떤 단어는 하나의 토큰이 될 수도 있고, 어떤 단어는 여러 토큰으로 쪼개질 수도 있습니다.

예를 들어 영어 단어 tokenization은 다음처럼 나뉠 수 있습니다.

token + ization

또 running은 다음처럼 나뉠 수 있습니다.

run + ning

한국어도 마찬가지입니다. “먹었습니다” 같은 표현은 모델의 토크나이저에 따라 여러 조각으로 나뉠 수 있습니다.

중요한 점은 이것입니다.

LLM은 글자 자체를 보는 것이 아니라, 토큰 ID라는 숫자들의 배열을 본다.

예를 들어 어떤 토큰이 1532번, 어떤 토큰이 48921번처럼 숫자로 바뀌는 식입니다. 모델 입장에서는 “강아지”라는 글자를 직접 보는 것이 아니라, “강아지”에 해당하는 숫자 ID를 입력받는 것입니다.

왜 굳이 이렇게 쪼갤까?

단어 단위로만 처리하면 문제가 생깁니다.

세상에는 너무 많은 단어가 있습니다. 신조어도 계속 생기고, 이름, 브랜드명, 외국어, 오타, 줄임말도 많습니다. 모든 단어를 통째로 사전에 넣으려면 어휘 목록이 너무 커집니다.

반대로 글자 하나하나로 처리하면 너무 비효율적입니다. “안녕하세요”를 글자 단위로 처리하면 모델이 훨씬 긴 시퀀스를 다뤄야 합니다.

그래서 현대 LLM은 보통 서브워드 subword 방식을 사용합니다. 자주 나오는 단어 조각은 하나의 토큰으로 만들고, 드문 단어나 새로운 단어는 작은 조각들을 조합해서 표현합니다.

쉽게 말하면 레고 블록과 비슷합니다. 자주 쓰는 모양은 큰 블록으로 준비해두고, 특이한 모양은 작은 블록들을 조합해서 만드는 방식입니다.


2. 숫자에 의미를 입히는 단계: 임베딩

토큰화가 끝나면 문장은 숫자 배열이 됩니다.

하지만 숫자 자체에는 아무 의미가 없습니다.

예를 들어 토큰 ID 1024가 있다고 해도, 그 숫자만 보고는 “사과”인지 “컴퓨터”인지 “걷다”인지 알 수 없습니다.

그래서 필요한 것이 임베딩 Embedding입니다.

임베딩은 각 토큰 ID를 긴 숫자 벡터로 바꾸는 과정입니다. 여기서 벡터란 숫자들의 리스트입니다.

예를 들어 “고양이”라는 토큰이 다음과 같은 벡터로 바뀐다고 생각할 수 있습니다.

[0.21, -0.13, 0.88, 0.04, ...]

실제 모델에서는 이 벡터의 길이가 수천 차원일 수 있습니다. 7B급 모델에서는 토큰 하나가 4,096개 정도의 숫자로 표현되기도 합니다.

임베딩은 단순한 번호표가 아니다

흥미로운 점은 비슷한 의미를 가진 토큰들이 비슷한 위치의 벡터를 갖게 된다는 것입니다.

예를 들어 다음 단어들은 서로 가까운 방향의 벡터를 가질 가능성이 있습니다.

왕, 여왕, 왕자, 공주
서울, 한국, 도쿄, 일본
고양이, 강아지, 동물

이 관계는 사람이 직접 규칙으로 넣은 것이 아닙니다. 모델이 방대한 텍스트를 학습하면서 “이 단어들은 비슷한 맥락에서 자주 쓰인다”는 패턴을 스스로 조정한 결과입니다.

유명한 예시로 이런 것이 있습니다.

king - man + woman ≈ queen

물론 이 예시는 단순화된 설명이지만, 임베딩 공간 안에 의미적 관계가 어느 정도 구조화되어 있다는 점을 보여줍니다.

정리하면 이렇습니다.

토큰화는 문자를 숫자 ID로 바꾸는 과정이고, 임베딩은 그 숫자 ID를 의미 있는 벡터로 바꾸는 과정입니다.


3. 단어의 순서를 알려주는 장치: 위치 인코딩

여기서 문제가 하나 생깁니다.

“강아지가 고양이를 물었다”와 “고양이가 강아지를 물었다”는 완전히 다른 문장입니다. 단어는 비슷하지만 순서가 다릅니다. 사람은 순서를 보고 의미를 이해합니다.

하지만 기본적인 임베딩만 보면 “강아지”라는 토큰은 문장 앞에 있든 뒤에 있든 같은 벡터를 가집니다.

즉, 모델은 별도의 장치 없이는 토큰이 몇 번째 위치에 있는지 알기 어렵습니다.

그래서 필요한 것이 위치 인코딩 Positional Encoding입니다.

위치 인코딩은 각 토큰에 “너는 문장의 몇 번째 위치에 있다”는 정보를 넣어주는 장치입니다.

초기의 트랜스포머는 사인과 코사인 함수를 사용해 위치 정보를 임베딩에 더했습니다. 쉽게 말하면, 1번째 위치에는 1번째 위치용 패턴을, 5번째 위치에는 5번째 위치용 패턴을 추가하는 식입니다.

그러면 같은 “강아지”라도 1번째에 있을 때와 5번째에 있을 때 모델 내부 표현이 달라집니다.

현대 모델에서 자주 쓰이는 RoPE

현대 LLM에서는 RoPE Rotary Position Embeddings라는 방식이 많이 쓰입니다.

RoPE는 위치 정보를 단순히 벡터에 더하는 대신, 어텐션에서 사용하는 Query와 Key 벡터를 위치에 따라 회전시키는 방식입니다.

비유하자면 이렇습니다.

문장 안의 각 토큰이 나침반을 하나씩 들고 있다고 해보겠습니다. 첫 번째 토큰은 조금만 회전하고, 100번째 토큰은 더 많이 회전합니다. 그러면 두 토큰이 서로를 비교할 때 “둘 사이가 얼마나 떨어져 있는지”가 자연스럽게 반영됩니다.

이 방식은 절대 위치뿐만 아니라 상대적 거리 정보를 잘 반영할 수 있다는 장점이 있습니다.

예를 들어 모델은 이런 관계를 파악해야 합니다.

“그는 민수를 만났다. 그는 반갑게 웃었다.”

여기서 두 번째 “그는”이 누구를 가리키는지 이해하려면 앞 문장의 구조와 거리, 문맥을 함께 봐야 합니다. 위치 정보는 이런 관계 파악의 기초가 됩니다.


4. 토큰들이 서로 정보를 주고받는 방법: 어텐션

트랜스포머의 핵심은 어텐션 Attention입니다.

어텐션은 각 토큰이 문장 안의 다른 토큰들을 바라보며 “나에게 중요한 정보가 어디에 있는가?”를 계산하는 장치입니다.

예를 들어 이런 문장이 있다고 해보겠습니다.

어제 내가 본 고양이는 소파 위에서 자고 있었다.

여기서 “자고 있었다”를 이해하려면 무엇이 자고 있었는지 알아야 합니다. 답은 “고양이”입니다. 하지만 “고양이”는 문장 앞쪽에 있고, “자고 있었다”는 뒤쪽에 있습니다.

어텐션은 뒤쪽 토큰이 앞쪽 토큰을 참고할 수 있게 해줍니다.

Query, Key, Value

어텐션에서는 각 토큰이 세 가지 역할을 합니다.

  1. Query: 나는 무엇을 찾고 있는가?
  2. Key: 나는 어떤 정보와 잘 맞는가?
  3. Value: 내가 전달할 실제 정보는 무엇인가?

예를 들어 “자고 있었다”라는 표현은 “누가 자고 있었는가?”라는 정보를 찾고 있습니다. 이것이 Query에 가깝습니다.

반면 “고양이”는 “나는 주어가 될 수 있는 명사다”라는 정보를 제공합니다. 이것이 Key에 가깝습니다.

두 정보가 잘 맞으면 어텐션 점수가 높아집니다. 그러면 “자고 있었다”는 “고양이”의 Value 정보를 많이 가져오게 됩니다.

즉, 모델 내부에서는 이런 일이 벌어지는 셈입니다.

“자고 있었다” → 관련 있는 토큰을 찾음 → “고양이”에 높은 점수 → 고양이 정보 반영

이것이 어텐션의 핵심입니다.

미래를 보지 못하게 하는 장치: causal masking

GPT 계열의 언어 모델은 보통 왼쪽에서 오른쪽으로 다음 토큰을 생성합니다.

예를 들어 모델이 다음 문장을 생성 중이라고 해보겠습니다.

오늘 점심은 김치찌개를

이 시점에서 모델은 다음에 “먹었다”, “먹고 싶다”, “주문했다” 같은 토큰을 예측해야 합니다. 그런데 아직 생성되지 않은 미래 토큰을 보면 안 됩니다.

그래서 GPT식 모델은 현재 위치보다 뒤에 있는 토큰을 볼 수 없도록 막습니다. 이것을 causal masking이라고 합니다.

쉽게 말하면 시험 볼 때 뒤 페이지 정답을 미리 못 보게 가리는 것과 비슷합니다.


5. 하나의 관점으로는 부족하다: 멀티헤드 어텐션

하나의 어텐션만 있으면 모델은 한 가지 방식으로만 토큰 관계를 봅니다.

하지만 언어에는 여러 관계가 동시에 존재합니다.

예를 들어 이런 문장이 있습니다.

지민이는 민수에게 책을 빌려주었고, 그는 다음 날 그것을 돌려주었다.

이 문장에서 모델은 여러 관계를 동시에 파악해야 합니다.

  • “그”는 누구인가?
  • “그것”은 무엇인가?
  • 누가 빌려주었고, 누가 돌려주었는가?
  • 시간 순서는 어떻게 되는가?

이런 다양한 관계를 하나의 어텐션으로 모두 처리하기는 어렵습니다.

그래서 트랜스포머는 멀티헤드 어텐션 Multi-head Attention을 사용합니다.

멀티헤드 어텐션은 여러 개의 어텐션 헤드를 병렬로 실행합니다. 각 헤드는 같은 문장을 보지만, 서로 다른 관점으로 관계를 학습합니다.

어떤 헤드는 주어와 동사의 관계를 잘 볼 수 있고, 어떤 헤드는 대명사 참조를 잘 볼 수 있으며, 어떤 헤드는 반복 패턴을 잘 볼 수 있습니다.

예시로 이해하기

문장 하나를 여러 명의 편집자가 동시에 읽는다고 생각해보겠습니다.

  • 문법 담당자는 주어와 동사를 봅니다.
  • 맥락 담당자는 앞뒤 문장을 봅니다.
  • 인물 담당자는 대명사가 누구를 가리키는지 봅니다.
  • 스타일 담당자는 문장의 톤을 봅니다.

각자 다른 관점으로 문장을 본 뒤, 마지막에 의견을 합칩니다.

멀티헤드 어텐션도 비슷합니다. 여러 헤드가 각자 다른 관계를 계산하고, 그 결과를 다시 하나의 벡터로 합칩니다.


6. 모델의 많은 지식이 들어 있는 곳: 피드포워드 네트워크

어텐션이 토큰들 사이의 관계를 섞는 역할을 한다면, 피드포워드 네트워크 Feed-forward Network, FFN는 각 토큰의 내부 표현을 더 깊게 처리하는 역할을 합니다.

트랜스포머 블록은 보통 크게 두 부분으로 구성됩니다.

  1. 어텐션
  2. 피드포워드 네트워크

어텐션이 “다른 토큰들과 어떤 관계가 있는가?”를 본다면, FFN은 “이 토큰 표현 자체를 어떻게 더 가공할 것인가?”를 처리합니다.

FFN은 보통 다음 과정을 거칩니다.

  1. 벡터를 더 큰 차원으로 확장한다.
  2. 비선형 함수를 적용한다.
  3. 다시 원래 차원으로 압축한다.

왜 비선형 함수가 필요할까?

비선형 함수가 없다면 여러 층의 선형 변환은 결국 하나의 선형 변환과 비슷해집니다.

쉽게 말하면, 아무리 여러 번 계산해도 표현력이 크게 늘어나지 않습니다.

비선형 함수는 이 단순한 계산 흐름을 꺾어줍니다. 그래서 모델이 더 복잡한 패턴을 배울 수 있게 됩니다.

예전에는 ReLU, GELU 같은 함수가 많이 쓰였고, 현대 모델에서는 SwiGLU 같은 방식도 자주 언급됩니다.

지식은 어디에 저장될까?

LLM이 “파리는 프랑스의 수도다” 같은 사실을 알고 있는 것처럼 보일 때, 그 정보는 특정 문장 형태로 저장되어 있는 것이 아닙니다.

모델의 가중치, 특히 여러 층의 FFN과 관련된 파라미터 안에 분산되어 저장되어 있다고 볼 수 있습니다.

예를 들어 모델 내부의 특정 뉴런이 프로그래밍 언어 관련 문맥에서 강하게 활성화될 수도 있고, 다른 뉴런은 특정 도시나 인물, 문법 패턴에 반응할 수도 있습니다.

물론 이것은 사람이 쓰는 데이터베이스처럼 “질문: 프랑스 수도 / 답: 파리” 형태로 저장된 것은 아닙니다. 수많은 숫자들의 연결 속에 통계적 패턴으로 녹아 있는 것입니다.


7. 아주 깊은 모델을 가능하게 하는 장치: 잔차 연결과 정규화

현대 LLM은 트랜스포머 블록을 수십 층, 때로는 그 이상 쌓습니다.

그런데 신경망을 너무 깊게 만들면 학습이 어려워집니다. 앞쪽 층의 정보가 뒤로 가면서 사라지거나, 반대로 값이 너무 커져서 학습이 불안정해질 수 있습니다.

이 문제를 줄이기 위해 중요한 두 장치가 사용됩니다.

  1. 잔차 연결 Residual Connection
  2. 레이어 정규화 Layer Normalization

잔차 연결

잔차 연결은 어떤 블록의 출력이 기존 벡터를 완전히 대체하지 않고, 기존 벡터에 더해지도록 만드는 구조입니다.

즉, 이런 식입니다.

새로운 표현 = 기존 표현 + 블록의 계산 결과

이 구조 덕분에 정보가 깊은 층까지 비교적 안정적으로 전달됩니다. 각 층은 이전 정보를 완전히 지워버리는 것이 아니라, 그 위에 새로운 정보를 덧붙입니다.

비유하자면 원고를 계속 새로 쓰는 것이 아니라, 기존 원고 위에 수정 사항과 코멘트를 누적하는 방식에 가깝습니다.

레이어 정규화

여러 층에서 계속 값을 더하다 보면 숫자의 크기가 불안정해질 수 있습니다.

너무 커질 수도 있고, 너무 작아질 수도 있습니다.

레이어 정규화는 각 토큰 벡터의 값들을 일정한 범위로 맞춰주는 역할을 합니다. 덕분에 모델이 깊어져도 학습이 더 안정적으로 진행됩니다.

현대 모델에서는 일반 LayerNorm뿐 아니라 RMSNorm 같은 변형도 많이 사용됩니다. RMSNorm은 평균을 빼는 과정을 생략하고 크기 조정에 집중하는 더 단순한 방식입니다.


8. LLM이 실제로 하는 일: 다음 토큰 예측

LLM이 실제로 하는 핵심 작업은 단순합니다.

다음 토큰을 예측하는 것.

예를 들어 사용자가 이렇게 입력했다고 해보겠습니다.

오늘 저녁에는 김치찌개를

모델은 다음에 올 가능성이 높은 토큰들을 계산합니다.

  • 먹고
  • 만들
  • 주문
  • 끓여
  • 먹었다

각 후보 토큰마다 점수가 계산됩니다. 이 점수를 logit이라고 합니다. logit은 아직 확률이 아닙니다. 이 값들이 softmax를 거치면 확률처럼 해석할 수 있는 분포가 됩니다.

그다음 모델은 설정에 따라 하나의 토큰을 선택합니다.

선택된 토큰이 “먹고”라면 문장은 이렇게 됩니다.

오늘 저녁에는 김치찌개를 먹고

이제 모델은 다시 다음 토큰을 예측합니다.

오늘 저녁에는 김치찌개를 먹고 싶다

이런 식으로 한 토큰씩 계속 생성합니다.

우리가 보기에는 모델이 한 문단을 한 번에 쓰는 것처럼 보이지만, 실제로는 다음 토큰을 하나씩 반복해서 고르는 과정입니다.

온도, top-k, top-p

같은 모델도 설정에 따라 답변 스타일이 달라집니다.

Temperature는 무작위성을 조절합니다.

  • 낮은 temperature: 더 보수적이고 예측 가능한 답변
  • 높은 temperature: 더 다양하고 창의적인 답변

예를 들어 “오늘 날씨가” 다음에 낮은 temperature에서는 “좋다”처럼 흔한 표현이 나올 가능성이 높습니다. 높은 temperature에서는 “이상하게 다정하다” 같은 조금 더 창의적인 표현이 나올 가능성이 커질 수 있습니다.

Top-k와 top-p는 후보 토큰의 범위를 제한하는 방식입니다. 너무 이상한 후보를 제외하고, 그럴듯한 후보들 안에서만 선택하도록 도와줍니다.


9. 그래서 GPT, Claude, Gemini, LLaMA는 무엇이 다를까?

겉으로 보면 모델마다 성격과 성능이 다릅니다.

어떤 모델은 글을 잘 쓰고, 어떤 모델은 코딩에 강하고, 어떤 모델은 긴 문맥 처리에 강하고, 어떤 모델은 대화 톤이 자연스럽습니다.

하지만 큰 틀에서 보면 현대 LLM은 대부분 비슷한 트랜스포머 계열 구조를 공유합니다.

공통적으로 들어가는 요소는 대략 다음과 같습니다.

  • 토큰화
  • 임베딩
  • 위치 인코딩
  • 여러 층의 트랜스포머 블록
  • 어텐션
  • 피드포워드 네트워크
  • 잔차 연결
  • 정규화
  • 다음 토큰 예측

차이는 주로 다음에서 나옵니다.

1. 학습 데이터

무엇을 얼마나 많이 학습했는지가 중요합니다.

코드 데이터를 많이 학습한 모델은 코딩에 강할 가능성이 높습니다. 다양한 언어 데이터를 충분히 학습한 모델은 다국어 처리에 강할 가능성이 있습니다.

2. 모델 크기와 구조

층 수, hidden size, attention head 수, vocabulary 크기, dense 모델인지 MoE 모델인지에 따라 성능과 비용이 달라집니다.

3. 후처리 학습

기본 모델은 다음 토큰 예측으로 학습됩니다. 하지만 우리가 사용하는 챗봇형 모델은 여기에 추가 학습이 들어갑니다.

예를 들어 다음과 같은 단계가 추가될 수 있습니다.

  • instruction tuning
  • preference tuning
  • human feedback 기반 조정
  • safety tuning

이 과정 덕분에 모델은 단순히 다음 단어를 예측하는 것에서 나아가, 사람의 지시에 더 잘 따르는 대화형 모델이 됩니다.


10. 쉬운 비유로 전체 흐름 다시 보기

LLM의 작동 과정을 식당 주방에 비유해보겠습니다.

사용자가 문장을 입력합니다.

오늘 저녁 메뉴 추천해줘.

이 문장은 먼저 재료 손질 단계로 갑니다.

1단계: 토큰화

문장을 작은 조각으로 자릅니다.

오늘 / 저녁 / 메뉴 / 추천 / 해줘

2단계: 임베딩

각 조각을 모델이 계산할 수 있는 숫자 벡터로 바꿉니다.

3단계: 위치 정보 추가

각 조각이 문장 안에서 몇 번째에 있는지 알려줍니다.

4단계: 어텐션

각 토큰이 다른 토큰을 보며 관계를 파악합니다.

“추천”은 “메뉴”와 강하게 연결되고, “저녁”은 추천의 조건으로 작동합니다.

5단계: FFN

각 토큰 표현을 더 깊게 가공합니다. 모델이 학습한 음식, 시간, 추천 문장 패턴 같은 정보가 반영됩니다.

6단계: 다음 토큰 예측

모델은 다음에 올 답변의 첫 토큰을 고릅니다.

“오늘”

그다음 또 예측합니다.

“오늘 저녁에는”

또 예측합니다.

“오늘 저녁에는 가볍게”

이 과정을 반복해서 하나의 답변이 완성됩니다.


11. LLM을 이해할 때 가장 중요한 포인트

LLM은 내부에 완성된 문장 창고를 가지고 있다가 꺼내오는 시스템이 아닙니다.

또 사람이 책을 읽고 개념을 이해하는 방식과도 다릅니다.

더 정확히는, 엄청나게 많은 텍스트에서 패턴을 학습한 거대한 함수에 가깝습니다. 입력된 토큰들을 숫자 벡터로 바꾸고, 수많은 층을 거쳐 관계를 계산한 뒤, 다음에 올 가능성이 높은 토큰을 계속 선택합니다.

그래서 LLM을 이해할 때는 다음 문장을 기억하면 좋습니다.

LLM은 텍스트를 숫자로 바꾸고, 숫자들 사이의 관계를 계산한 뒤, 다음 토큰을 하나씩 예측하는 시스템이다.

이 한 문장 안에 토큰화, 임베딩, 어텐션, FFN, 정규화, 디코딩의 핵심이 모두 들어 있습니다.


12. 앞으로의 방향

현재 LLM의 주류는 트랜스포머입니다. 하지만 이 구조가 영원히 유지된다고 단정할 수는 없습니다.

긴 문맥을 더 효율적으로 처리하기 위한 연구가 계속되고 있고, Mamba 같은 상태공간 모델, 하이브리드 아키텍처, Mixture of Experts 같은 구조도 활발히 논의되고 있습니다.

그럼에도 불구하고 지금 시점에서 LLM을 이해하려면 트랜스포머의 기본 구조를 아는 것이 가장 중요합니다.

토큰화, 임베딩, 위치 정보, 어텐션, 피드포워드 네트워크, 잔차 연결, 정규화, 다음 토큰 예측.

이 흐름을 이해하면 많은 LLM 논문, 모델 카드, 기술 블로그를 읽을 때 “이 부분이 모델의 어느 장치를 말하는지” 감을 잡을 수 있습니다.

AI가 마법처럼 보일수록 내부 구조를 이해하는 일은 더 중요해집니다.

결국 LLM은 마법이 아니라, 거대한 숫자 계산 시스템입니다.

다만 그 숫자 계산이 너무나 큰 규모로, 너무나 정교하게 쌓이다 보니 우리에게는 언어를 이해하는 것처럼 보이는 결과가 나오는 것입니다.

반응형