다음 token 예측이라는 한 문장

오늘의 질문

LLM을 처음 접하면 흔히 “다음 말을 예측하도록 훈련된 모델”이라는 설명을 듣는다. 그런데 이 설명을 곧이곧대로 받아들이면 바로 이런 의문이 든다.

다음 단어 맞히기가 대체 어떻게 코드를 짜고 문서를 요약하는 것까지 되나? 그건 완전히 다른 일 아닌가?

이 글은 이 간극을 메운다. 결론부터 말하면, “다른 일”처럼 보이는 것들이 사실은 전부 같은 모양의 문제로 바뀐 것이다.

먼저 답하기

한 문장으로 줄이면 이렇다.

문장을 잇는 일도, 코드를 짜는 일도, 요약을 만드는 일도 — 전부 “지금까지 나온 조각들 다음에 올 조각 하나를 고르는 일”의 반복이다.

“코드를 짠다”는 하나의 작업처럼 보이지만, 실제로는 def를 쓰고, 그다음 함수 이름을 쓰고, 그다음 괄호를 쓰는 식으로 한 조각씩 순서대로 만들어진 결과물이다. “요약한다”도 마찬가지다. 요약문의 첫 단어를 쓰고 그다음 단어를 쓰는 과정이 끝까지 반복된 것뿐이다.

즉 겉으로 보이는 “작업의 종류”가 다른 게 아니라, 매 순간 풀어야 하는 문제는 항상 하나뿐이다. 지금까지 나온 조각들을 보고, 다음에 올 조각 하나의 확률을 매겨서, 그중 하나를 고른다. 이 하나의 동작이 충분히 잘 되면, 그걸 계속 반복하는 것만으로 문장도 코드도 요약도 나온다.

주제에 맞는 핵심 설명

“다음 조각 맞히기”는 이미 익숙한 감각이다

아래 문장을 눈으로만 읽어보자.

“오늘 점심에 김치찌개를 먹으러 ___”

빈칸에 뭐가 올지 대부분 비슷하게 예상한다. “갔다”, “간다”, “먹었다” 같은 말이 떠오르고, “코끼리”나 “파랗다” 같은 말은 안 떠오른다. 이미 머릿속에서 후보들을 순위 매기고 있는 것이다. 다음 token 예측은 이 감각을 숫자로 만든 것뿐이다.

여기서 이번 글에서 계속 쓸 용어 하나를 정의하고 간다. token이란 모델이 다루는 텍스트의 최소 조각을 말한다. 단어 하나일 수도, 단어의 일부일 수도, 문장부호 하나일 수도 있다. “다음 token 예측”이라고 할 때 이 조각 하나를 고르는 게 예측의 단위다.

token, 확률, 생성을 순서대로

**확률(probability)**은 다음 token 후보 각각에 매긴 “그럴듯함”의 크기다. 모든 후보의 확률을 다 더하면 1이 된다. 확률이 높다고 그 후보가 반드시 정답이라는 뜻은 아니다. 단지 지금까지 나온 문맥에서 더 자연스러운 다음 조각이라는 뜻이다.

**다음 token 예측(next-token prediction)**은 지금까지의 token 나열을 입력으로 받아, 다음 token 후보 전체에 확률을 매기는 동작이다. 여기까지는 “예측”이지 아직 “생성”이 아니다. 확률표를 만드는 것과 그중 하나를 실제로 고르는 것은 다른 단계다.

**생성(generation)**은 다음 token 후보 중 하나를 실제로 고르고, 그걸 지금까지의 나열 뒤에 이어 붙인 다음, 늘어난 나열을 가지고 다시 다음 token 예측을 반복하는 전체 과정이다. “생성”이라는 단어가 거창하게 들리지만, 실체는 “예측 → 선택 → 이어 붙이기”의 반복이다.

이 반복 구조를 그림으로 보면 아래와 같다. 문맥에서 시작해 예측과 선택, 이어 붙이기를 거치고, 늘어난 문맥을 가지고 다시 예측으로 돌아가는 순환이 보인다.

문맥에서 시작해 예측, 선택, 이어 붙이기를 거치고 늘어난 문맥으로 다시 예측 단계로 돌아가는 반복 흐름을 보여주는 다이어그램

보라색 점선이 이 그림의 핵심이다. 이어 붙이기에서 만들어진 새 문맥이 다시 예측 단계의 입력으로 들어간다. “코드를 짠다”든 “요약한다”든, 이 순환이 도는 횟수만 다를 뿐 도는 방식 자체는 똑같다.

왜 이 반복 하나로 코드와 요약까지 되는가

여기가 오늘 질문의 핵심이다. 세 가지가 성립하면, 위 반복만으로 문장 종류와 무관하게 결과물이 나온다.

첫째, 코드도 요약도 결국 token의 나열이다. def, (, “환불” 같은 것도 전부 token으로 쪼개진다. 모델 입장에서 “이건 코드다, 이건 문장이다”라는 구분이 근본적으로 다른 처리 경로를 타는 게 아니다.

둘째, 문맥이 다르면 그럴듯한 다음 token도 달라진다. def add(a, b): 다음에는 return류 token의 확률이 높아지고, “안녕하세요 고객님,” 다음에는 인사말류 token의 확률이 높아진다. 모델이 바뀌는 게 아니라 입력이 바뀌면서 확률표가 바뀌는 것이다.

셋째, 반복을 멈추는 조건만 있으면 하나의 결과물이 완성된다. 특정 종료 token이 나오거나 길이 제한에 닿으면 반복을 멈춘다.

그래서 “LLM에게 무엇을 시킬지”는 사실 모델을 바꾸는 일이 아니라 문맥을 바꾸는 일이다. 코드를 짜게 하고 싶으면 “다음 token이 코드일 확률이 높아지는 문맥”을 입력으로 만들어주면 된다.

이 반복 구조는 실제로 트랜스포머 구조를 처음 제시한 논문인 Vaswani 외, “Attention Is All You Need”(2017)에서 근거를 찾을 수 있다. 이 논문은 decoder가 이전에 생성한 기호들을 다음 기호 생성의 입력으로 함께 사용하는 구조를 취한다고 설명하고, decoder의 출력을 학습된 선형 변환과 소프트맥스 함수를 거쳐 다음 token에 대한 예측 확률로 바꾼다고 밝힌다. “지금까지의 나열 → 다음 token 확률표 → 하나 선택 → 다시 입력으로”라는 이 글의 뼈대는 이 논문이 기술하는 구조와 일치한다. 다만 이 논문 자체는 번역 과제로 이 구조를 검증한 것이고, 코드 생성이나 요약에도 그대로 적용된다는 확장은 논문이 직접 주장하는 바는 아니며, 위 세 가지 이유에서 자연스럽게 따라 나오는 해석이다.

작은 연습: 다음 단어 후보를 확률로 보기

다음 문장을 예로 들어보자.

“어제 저녁에 비가 와서 우산을 ___”

이 자리에 올 다음 token 후보를 감으로 몇 개만 뽑아, “그럴듯함”을 확률처럼 매겨보면 아래와 같다. 여기 나온 숫자는 실제 모델이 계산한 값이 아니라 직관을 보여주기 위해 임의로 붙인 값이다.

다음 token 후보 그럴듯함(가정값) 왜 이 정도인가
“썼다” 0.55 “비 → 우산 → 썼다”가 가장 흔한 연결
“챙겼다” 0.25 의미는 비슷하지만 앞의 “와서”와는 살짝 덜 자연스러움
“잃어버렸다” 0.08 문맥상 가능하지만 앞부분과 직접 연결이 약함
그 밖의 모든 후보 합 0.12 “샀다”, “펼쳤다” 등 수많은 다른 후보들이 나눠 가짐

실제 모델의 다음 token 후보는 “썼다”, “챙겼다” 같은 단어 전체가 아니라 그보다 잘게 쪼개진 단위일 수 있고, 후보 개수도 훨씬 많다. 이 표는 개수를 크게 줄인 설명용 단순화다. 그럼에도 이 표가 보여주려는 성질 하나는 실제와 같다. 후보가 몇 개든 확률은 항상 전체 합이 1이 되도록 나뉘고, 다음 token 선택은 이 나눠 가진 확률 중에서 하나를 고르는 일이라는 것이다. 가장 높은 확률을 고를 수도 있고, 확률에 비례해서 무작위로 고를 수도 있는데, 이 선택 방식 자체는 이 글에서 다루는 범위 밖이다.

자주 묻는 질문

모델은 항상 확률이 가장 높은 token만 고르나요? 꼭 그렇지는 않다. 확률표까지는 다음 token 예측의 결과지만, 그중 무엇을 실제로 고를지는 별도의 선택 방식에 달려 있다. 매번 1등만 고르면 같은 입력에 항상 같은 결과가 나오고, 확률에 비례해서 무작위로 고르면 매번 조금씩 다른 결과가 나올 수 있다. 실무에서 이 선택 방식을 조절하는 옵션(흔히 temperature나 sampling 관련 설정으로 불린다)을 만나게 되는데, 그 세부 동작은 이 글에서 다루는 범위 밖이다.

확률이 높은 token이 항상 맞는 token인가요? 아니다. 확률은 학습 데이터에서 이런 문맥 다음에 자주 나타났던 조각에 대한 크기이지, 사실인지를 재는 잣대가 아니다. “썼다”의 확률이 높다고 실제로 그 사람이 우산을 썼는지는 확률표가 보장해주지 않는다. 그래서 실무에서 LLM의 출력을 사실 검증이 필요한 용도로 쓸 때는, 확률이 높다는 것과 정답이라는 것을 같은 뜻으로 받아들이지 않는 것이 중요하다.

코드는 문법이 엄격한데, 이 확률 방식으로 문법이 맞는 코드가 나오는 게 신기한데요? 오히려 문법이 엄격하다는 점이 예측을 쉽게 만드는 방향으로 작용한다. def add(a, b): 다음 줄에 들여쓰기가 오고 return 같은 token이 올 확률이, 아무 문맥이나 올 확률보다 훨씬 크게 쏠려 있기 때문이다. 문맥이 엄격할수록 확률표가 몇몇 후보로 뾰족하게 몰리는 경향이 있다고 볼 수 있는데, 이는 이 글의 구조에서 자연스럽게 따라 나오는 해석이며 별도로 측정된 수치는 아니다.

token 하나가 항상 단어 하나인가요? 아니다. 앞서 정의했듯 token은 단어보다 작을 수도 있다. 예를 들어 낯선 단어는 여러 조각으로 쪼개져서 각 조각이 각각의 token이 될 수 있다. 정확히 어떻게 쪼개는지는 토크나이저라는 별도 구성 요소가 정하며, 이 글은 “쪼개진 조각 하나”라는 정의까지만 다룬다.