5부 · 추론: 모델은 어떻게 답을 만드는가

← 4부 학습 · 목차 · 다음: 6부 한계와 그 이유 →

4부에서 모델이 어떻게 만들어지는지(학습)를 봤습니다. 이제 완성되어 다이얼이 고정된 모델이, 당신의 질문에 실제로 답을 만들어내는 순간을 봅니다. 이를 추론(inference) 또는 생성(generation) 이라 합니다.

한 줄 요약입니다.

모델은 답 전체를 한 번에 떠올리지 않는다. 매 단계 "다음 토큰의 확률 분포"를 만들고, 거기서 하나를 골라 붙이고, 그걸 다시 입력에 더해 또 다음을 고르는 일을 끝날 때까지 반복한다.

이것이 1부 첫 그림의 반복 고리를, 이번엔 생성하는 쪽에서 자세히 들여다보는 것입니다.

5.1 한 토큰씩 — 자기회귀 생성

모델이 한 단계에서 하는 일은 1부~3부에서 본 그대로입니다. 지금까지의 토큰들을 받아, 어텐션·트랜스포머 층을 거쳐, 마지막에 다음 토큰의 확률 분포를 내놓습니다. 어휘의 모든 토큰(보통 5만~10만 개 이상)에 점수를 매긴 표라고 보면 됩니다.

flowchart LR
    IN["입력: '하늘이'"] --> M["모델"]
    M --> DIST["다음 토큰 확률<br/>맑다 62%<br/>흐리다 18%<br/>파랗다 12%<br/>… 나머지 8%"]
    DIST --> PICK["하나 선택: '맑다'"]
    PICK --> NEW["'하늘이 맑다'"]
    NEW -->|"다시 입력으로"| M

    classDef input fill:#fff3b0,stroke:#e0a800,color:#000
    classDef inside fill:#a8e6e2,stroke:#2ba89e,color:#000
    classDef out fill:#b9f6ca,stroke:#2e9e5b,color:#000
    class IN,NEW input
    class M,DIST inside
    class PICK out

선택한 토큰을 입력 끝에 붙이고, 그 새 입력으로 다시 분포를 계산합니다. 이렇게 자기가 방금 만든 출력을 다시 입력으로 먹으며 한 토큰씩 이어 가는 방식을 자기회귀(autoregressive) 라 부릅니다. 끝맺음 토큰이 나오거나 정해진 길이에 도달하면 멈춥니다.

비유 — 한 칸씩 채우는 끝말잇기
답을 통째로 미리 정해 두는 게 아니라, 매번 "지금까지를 보고 다음 한 칸"만 고릅니다. 그 한 칸이 다음 칸의 조건이 됩니다.
이 비유가 깨지는 곳: 끝말잇기는 사람이 의도를 갖고 단어를 고르지만, 모델은 매 칸에서 확률 분포를 계산해 뽑을 뿐, 문장 끝을 미리 계획하지 않습니다(이 점이 6부 산수·계획 약점과 이어집니다).
흔한 오해 깨기
흔히들 "AI가 답을 먼저 머릿속에 완성한 뒤 풀어 쓴다"고 생각하지만, 실제로는 다음 한 토큰만 보고 나아갑니다. 그래서 앞에서 어쩌다 잘못 디딘 한 걸음이 뒤로 갈수록 더 큰 탈선으로 번질 수 있습니다(오류 누적).

🔬 더 깊이 — KV 캐시

매 단계 이전 토큰 전체를 처음부터 다시 계산하면 너무 느립니다. 그래서 트랜스포머는 앞 토큰들의 열쇠(Key)·값(Value)을 저장해 두고 재활용합니다(KV 캐시). 덕분에 새 토큰 하나만 추가 계산하면 됩니다. 이 캐시는 맥락이 길어질수록 메모리를 많이 먹어, 긴 컨텍스트의 비용·한계와 직결됩니다(5.3).

5.2 확률 분포와 샘플링 — 무엇을 어떻게 고르나

분포가 나왔다면, 거기서 어떻게 한 토큰을 고를까요? 여기엔 선택지가 있고, 이 선택이 답의 성격을 크게 바꿉니다.

가장 단순한 방법은 항상 1등을 고르기(탐욕적 디코딩, greedy decoding)입니다. 매번 확률이 가장 높은 토큰만 뽑습니다. 안정적이지만, 반복적이고 단조로운 글이 되기 쉽습니다. 그래서 대부분의 챗봇은 약간의 무작위성을 섞어, 높은 확률 토큰을 주로 뽑되 가끔 다른 후보도 뽑는 샘플링(sampling) 을 씁니다.

이 무작위성의 정도를 조절하는 대표적 손잡이가 temperature(온도) 입니다.

flowchart TB
    subgraph LOW["낮은 temperature (예: 0.2)"]
        L["맑다 ████████ 88%<br/>흐리다 ██ 9%<br/>파랗다 ▌ 3%"]
    end
    subgraph HIGH["높은 temperature (예: 1.2)"]
        H["맑다 ████ 45%<br/>흐리다 ███ 30%<br/>파랗다 ██ 25%"]
    end
    LOW --> LR["→ 거의 늘 '맑다'<br/>일관·안전·반복적"]
    HIGH --> HR["→ 들쭉날쭉<br/>창의적·다양·위험"]

    classDef low fill:#a8e6e2,stroke:#2ba89e,color:#000
    classDef high fill:#d8b4f8,stroke:#8b5cf6,color:#000
    classDef res fill:#b9f6ca,stroke:#2e9e5b,color:#000
    class L low
    class H high
    class LR,HR res

직관적으로 temperature는 분포의 뾰족함/평평함을 조절합니다. 낮으면(0에 가까움) 분포가 뾰족해져 1등이 거의 독식하고, 출력이 일관되고 보수적이 됩니다. 높으면 분포가 평평해져 낮은 확률 토큰도 뽑힐 여지가 커지고, 더 다양하고 창의적이지만 엉뚱해질 위험도 커집니다. temperature를 0으로 두면 사실상 탐욕적 디코딩과 같아집니다.

temperature분포 모양성격어울리는 일
낮음 (0~0.3)뾰족함일관·보수적사실 질답, 코드, 분류
중간 (0.4~0.8)보통균형일반 대화, 요약
높음 (0.9~1.2)평평함다양·창의적창작, 브레인스토밍
비유 — 주사위의 무게추
후보 토큰마다 주사위 면이 있다고 생각해 보세요. temperature를 낮추면 1등 면 쪽으로 무게추를 실어 거의 그것만 나오게 하고, 높이면 무게추를 풀어 여러 면이 골고루 나오게 합니다.
이 비유가 깨지는 곳: 주사위는 면이 몇 개로 고정이지만, 여기선 매 단계 후보 분포 자체가 새로 계산됩니다. 또 temperature는 확률을 재조정할 뿐, 모델이 아는 것을 바꾸지는 않습니다.

🔬 더 깊이 — top-k와 top-p

무작위성을 다루는 다른 손잡이도 있습니다. top-k는 확률 상위 k개 후보만 남기고 나머지를 잘라냅니다. top-p(핵 샘플링)는 개수가 아니라, 확률을 큰 것부터 더해 합이 p(예: 0.9)가 될 때까지의 후보만 남깁니다. temperature가 분포의 모양을 바꾼다면, top-k/top-p는 후보의 범위를 자릅니다. 둘을 함께 쓰기도 합니다. 이들은 모두 학습된 가중치가 아니라 추론 시점에 매 호출마다 조절하는 설정입니다.

5.3 컨텍스트 윈도우 — 왜 유한하고 무엇이 담기나

모델이 한 번에 "볼 수 있는" 토큰의 양에는 한계가 있습니다. 이를 컨텍스트 윈도우(context window) 라 합니다. 당신의 질문, 앞선 대화, 모델이 지금까지 생성한 답이 모두 이 창 안에 들어갑니다.

flowchart LR
    subgraph WIN["컨텍스트 윈도우 (유한한 작업 공간)"]
        direction TB
        SYS["시스템 지시"]
        HIST["이전 대화"]
        Q["현재 질문"]
        GEN["생성 중인 답"]
    end
    WIN --> M["모델은 이 창 안의<br/>토큰만 참조 가능"]
    OLD["창을 넘어선<br/>오래된 내용"] -.->|"밀려남"| X["더 이상 안 보임"]

    classDef win fill:#fff3b0,stroke:#e0a800,color:#000
    classDef inside fill:#a8e6e2,stroke:#2ba89e,color:#000
    classDef gone fill:#ffcdd2,stroke:#c62828,color:#000
    class SYS,HIST,Q,GEN win
    class M inside
    class OLD,X gone

왜 유한할까요? 어텐션은 모든 토큰이 서로를 참조하므로, 창이 길어질수록 계산량과 메모리(특히 5.1의 KV 캐시)가 가파르게 늘기 때문입니다. 또 모델은 특정 길이까지만 학습되어, 그 한계를 넘으면 품질이 무너지기도 합니다.

이 유한성이 실전에서 중요한 결과를 낳습니다.

현상왜 그런가
긴 대화에서 앞부분을 "잊는다"오래된 내용이 창 밖으로 밀려나면 더 이상 참조하지 못합니다.
아주 긴 문서를 통째로 못 다룬다창 크기를 넘는 입력은 잘리거나 들어가지 못합니다.
긴 맥락의 중간을 놓친다창 안에 있어도, 너무 길면 중간 정보의 활용도가 떨어지는 경향이 있습니다("중간 소실", 6부에서 자세히).
비유 — 책상 위 작업 공간
모델의 컨텍스트는 책상 넓이 같은 것입니다. 책상에 올린 서류(질문·대화·답)만 보며 일하고, 자리가 차면 오래된 서류를 밀어냅니다. 밀려난 서류의 내용은 더 이상 참고하지 못합니다.
이 비유가 깨지는 곳: 책상은 올린 서류를 또렷이 다 보지만, 모델은 창 안에 있어도 위치에 따라 주목도가 달라, "올려둔 것"과 "잘 활용하는 것"이 같지 않습니다.
흔한 오해 깨기
흔히들 "AI가 지난 대화를 다 기억한다"고 생각하지만, 실제로는 한 대화 안에서도 컨텍스트 창을 넘어선 내용은 사라지고, 새 대화에서는 (4부에서 봤듯) 가중치에 남지 않으니 아예 모릅니다. "기억하는 듯" 보이는 것은 매번 창에 그 내용을 다시 담아 주기 때문입니다.

5.4 왜 같은 질문에 다른 답이 나오나

이제 흔한 의문을 풀 수 있습니다. 왜 같은 질문을 두 번 하면 다른 답이 나올까요?

핵심 이유는 5.2의 샘플링입니다. temperature가 0보다 크면 모델은 매번 분포에서 무작위로 토큰을 뽑으므로, 첫 토큰부터 다른 선택이 나올 수 있고, 자기회귀 특성상 그 작은 차이가 이후 전체를 다른 방향으로 끌고 갑니다.

flowchart TB
    Q["같은 질문"] --> R1["실행 1: 첫 토큰 '맑다' 뽑힘"]
    Q --> R2["실행 2: 첫 토큰 '파랗다' 뽑힘"]
    R1 --> O1["→ 한 방향의 답"]
    R2 --> O2["→ 전혀 다른 답"]

    classDef q fill:#fff3b0,stroke:#e0a800,color:#000
    classDef run fill:#a8e6e2,stroke:#2ba89e,color:#000
    classDef out fill:#b9f6ca,stroke:#2e9e5b,color:#000
    class Q q
    class R1,R2 run
    class O1,O2 out

그 밖의 이유도 있습니다. 대화 맥락(창에 담긴 내용)이 조금만 달라도 분포가 달라집니다. 또 temperature를 0으로 두어 "탐욕적"으로 만들어도 완벽히 똑같은 답이 보장되지는 않습니다 — 대규모 병렬 계산의 미세한 연산 순서 차이로 결과가 살짝 달라질 수 있기 때문입니다.

흔한 오해 깨기
흔히들 "AI가 답이 다르게 나오는 건 마음이 바뀌어서"라고 의인화하지만, 실제로는 확률 분포에서 무작위로 뽑는 샘플링의 결과일 뿐입니다. "변덕"이 아니라 설계된 무작위성입니다.

5부 요약

  • 추론은 답을 한 번에 떠올리는 게 아니라, 다음 토큰 확률 분포 → 하나 선택 → 다시 입력에 더하기를 반복하는 자기회귀 과정입니다.
  • 매 단계의 작은 선택이 이후를 좌우하므로, 앞의 잘못된 한 걸음이 오류 누적으로 번질 수 있습니다.
  • 토큰을 고르는 방식(탐욕적 vs 샘플링)과 temperature·top-k·top-p가 답의 일관성/창의성을 조절합니다. 이 설정은 모델의 지식이 아니라 표현 방식을 바꿉니다.
  • 컨텍스트 윈도우는 모델이 한 번에 볼 수 있는 유한한 작업 공간이며, 이를 넘은 내용은 사라집니다. "기억하는 듯" 보이는 건 매번 다시 담아 주기 때문입니다.
  • 같은 질문에 답이 달라지는 주된 이유는 샘플링의 무작위성입니다. 변덕이 아니라 설계입니다.

다음 부에서는 지금까지 쌓은 원리로부터 LLM의 한계—환각·산수 약점·중간 소실·편향—가 생기는지를 끌어냅니다.

← 4부 학습 · 목차 · 다음: 6부 한계와 그 이유 →