추론 — ChatGPT 작동 원리, 한 글자씩 답이 나오는 정체

Table of Contents

추론 — ChatGPT 작동 원리, 한 글자씩 답이 나오는 정체

LLM 이론 집중코스 · 3편
1편(가중치·벡터·토큰·임베딩)과 2편(학습 — 산 내려가기)을 안 읽으셨다면 먼저 보고 오시면 좋아요.

ChatGPT 작동 원리는 한 줄로 요약되지 않아요. 한 글자씩 답이 뜨는 그 단순해 보이는 동작 뒤에 — autoregressive 디코딩, KV 캐시, GPU·VRAM·HBM, 양자화, Softmax, Temperature, BPE 어휘집, 컨텍스트 윈도우, JSON streaming까지 줄줄이 이어져 있어요. 이 모든 동작을 — 한일 양쪽 시장에서 AI 도구를 다뤄온 시선으로, 그리고 LLM을 처음 마주하는 독자가 반드시 막힐 자리들을 미리 짚어가며 — 한 글에 정리했어요.

📖 이 글이 답할 것 · 약 25분
 1️⃣ ChatGPT가 한 글자씩 답하는 그 모든 동작의 정체 (autoregressive + KV 캐시)
 2️⃣ GPU·VRAM·HBM·양자화·컨텍스트 윈도우가 다 같은 문제의 답이라는 큰 그림
 3️⃣ 직접 만든 비유 — 스킬 메타데이터 = 표지 없는 도서관에 표지 붙이기

2편 끝에서 이런 그림이 그려졌어요. 80억 가중치가 데이터로 정해진 뒤 박혀버렸다. 그 다음에 자연스럽게 떠오르는 질문이 이거예요.

“그럼 우리가 ChatGPT에 질문을 던질 때, 그 박혀 있는 80억 개 위에서 정확히 무슨 일이 일어나는 거예요?”

이 글은 그 질문 하나에 답하는 글이에요. 답이 단순할 줄 알았는데, 따라가다 보니 한 글자씩 답이 나오는 메커니즘부터 GPU 메모리·HBM·양자화·Temperature·Top-K/P·BPE 어휘집·컨텍스트 윈도우·시스템 프롬프트·JSON streaming까지 줄줄이 이어졌어요. 그리고 그 다음 편(3.5편)에서는 Reasoning 모델·에이전트·#1196 사건·창의성까지 갑니다.

저는 LLM을 직접 공부하면서 막힌 지점 모두를 글에 박았어요. 제가 막힌 곳이 곧 독자가 막힐 곳이라는 가정으로요.


이 글에서 답할 질문들 — 직접 막혔던 지점 그대로

이 글(3편)과 다음 글(3.5편)에서 답하는 질문 모음이에요. 요약하지 않고 원문 그대로 박았어요. 한 질문이라도 답이 궁금하면 그 섹션부터 읽어도 좋아요.

📍 3편 (이번 글) — 추론 메커니즘
 1. 추론이 뭐고 학습과 어떻게 다른가
 2. “한 글자씩 답한다는 게 진짜로 LLM 32층을 통째로 한 글자씩 다시 처음부터 돌리는 건가? 100단어면 32층을 100번? 어마어마한 계산량인데?”
 3. KV 캐시가 정확히 뭐고 K·V는 뭔가 (Attention 살짝)
 4. 첫 글자만 느리고 그 다음은 빠른 이유 (Prefill vs Decode)
 5. “가중치가 안 변하는데 왜 GPU가 필요해?”
 6. “VRAM이 뭐고 왜 모델 14GB → GPU VRAM ≥ 14GB가 되지? 1바이트가 왜 8비트야?”
 7. 메모리 대역폭이란 / HBM이 빠른 이유
 8. “A100 40GB와 80GB는 왜 두 배 차이야? A와 H의 차이는? H100 80GB → H200 141GB는 왜 정확히 2배가 아니야? 핸드폰은 64→128로 정확히 2배인데?”
 9. “405B를 8bit로 하면 405GB인데 H100 80GB 5~6대면 되지 않나? 왜 8대가 필요해?”
 10. 역전파가 왜 거꾸로만 가야 하는가 (체인 룰)
 11. “Softmax는 그냥 소수점 자르는 건가? 왜 소수점을 자르지?”
 12. “Sampling은 1등 확률이 압도적이면 작은 수치가 나오는 건지, 작은 수치가 나오면 평평하게 만드는 건지?”
 13. “매번 다른 답을 위해 Temperature를 만든 건가? 사람들은 어떻게 상황마다 정해놨지?”
 14. Top-K·Top-P는 왜 필요한가 / 회사마다 고정값?
 15. “95%여도 5% 확률로 다른 토큰이 나오는 건가?”
 16. “모델마다 어휘집 등록 형식이 다른데, BPE는 어휘집을 학습으로 만든 건가? 12만 8천이 된 계기는?”
 17. “한국어는 단어와 조사가 띄어쓰기 없이 오는데 LLM이 어떻게 처리하지? 왜 한글 글자가 영어와 다르게 2~3토큰으로 쪼개지지?”
 18. 컨텍스트 윈도우가 뭐고 책상이 꽉 차면 누가 자르나
 19. 시스템 프롬프트가 사용자 메시지보다 강한 이유
 20. 스킬 메타데이터 = 표지 없는 도서관에 표지 붙이기 (이 비유는 직접 만든 것)
 21. “프롬프트를 토큰화하는 것은 누가 어떤 단계에서 하는지? 토크나이저·어휘집은 회사마다 비밀인지?”
 22. “하나도 띄어쓰기를 안 해도 답변 품질은 떨어지지 않는지 이론적으로?”
 23. “md 파일이 AI가 인식하기 편하다는데, md는 AI를 위해 만들어진 건가? PDF와 뭐가 다른가?”
 24. “LLM 출력이 JSON 형식으로 오는 이유? JSON이 뭐고 AI를 위해 만들어졌나? JSON 안 쓰면 어떻게 되지?”
 25. “토큰 단위로 보내는 게 사용자 만족도라면 한꺼번에 보내는 게 경제적으로 합리적이지 않나?”
📍 3.5편 (다음 글) — Reasoning·에이전트·창의성
 25. Reasoning 모델 (o1, o3, GPT-5.4 Pro, Claude Extended Thinking)이 일반 모델과 어떻게 다른가
 26. “23 × 47을 한 번에 왜 못 풀고 왜 40 × 23은 할 수 있지? 비유인지 진짜 못 푸는지?”
 27. 요즘 모델 계산 정확도가 점점 오르는 이유
 28. “계산이 필요할 때만 계산기를 오픈소스로 불러오면 좋지 않을까 했는데 왜 안 됐었지? 모델은 못했고 에이전트가 된다면 단계가 늘어 어려워지는 건가?”
 29. 모델 vs 에이전트의 정확한 정의
 30. “내부 사고 토큰의 기준은 뭔가? Web search·fetch가 다 output으로 잡히면 비정상적으로 커질 텐데 어떻게 막지? 글자 수 보고 자르나? 후반은 안 보이게 되나?”
 31. “GPT-5.4 Pro가 #1196에 패턴이 작게나마 보여서 해봤더니 그럴듯해서 출력한 거지? 그러면 수학적 추론을 한 게 아직도 아니지?”
 32. “GPT는 그게 그럴듯하다고 어떻게 판단했지?”
 33. “GPT는 완전 새로운 것을 창조해낼 수는 없는 건지, 아니면 인간의 창의력도 기존 것에 기존 것을 적용해서 새로워 보이는 것을 만들어왔던 거고 AI도 통계적으로 그것을 할 수 있지 않나?”
 34. “LLM은 1초에 몇억 몇조 단위 계산을 하니 더 빠르게 관계없어 보이는 것 사이의 연결점을 찾을 수 있다면 AI가 더 잠재적 창의력은 크지 않나?”
 35. 변형적 창의성 9개 예시 (코페르니쿠스·다윈·칸트·쿤·피카소·쇤베르크 등)
 36. 변형적 창의성은 지금 AI 구조로 가능한가 / 조합형 끝에 답이 있는가

이 중 한 질문이라도 답이 궁금하면 — 시작합시다.


ChatGPT 작동 원리의 출발점 — 추론과 학습의 차이

먼저 단어부터 잡고 갑시다. 추론(Inference) = 학습이 끝난 모델로 답을 만드는 행위예요.

2편에서 우리는 “산 내려가기”로 80억 가중치를 정했어요. 그게 학습. 추론은 그 정해진 가중치를 쓰는 단계예요.

단계 무엇을 하나 가중치는?
학습 (Training) 데이터로 가중치를 만든다 계속 바뀜
추론 (Inference) 만들어진 가중치로 사용한다 고정 (절대 안 바뀜)

ChatGPT를 우리가 쓸 때(이게 추론) 가중치는 한 비트도 안 바뀌어요. 이미 OpenAI가 학습 단계에서 다 정해놓은 그 80억(혹은 더 많은) 숫자가 그대로 박혀 있고, 우리 질문은 그 고정된 숫자들 사이를 한 번 통과해서 답을 만들어내는 거예요.

비유하면 이래요.

  • 학습 = 요리 레시피를 수만 번 시행착오로 완성하는 과정
  • 추론 = 완성된 레시피대로 한 번 요리하는 것

이 글에서 다루는 건 전부 추론 이야기예요. 학습은 2편에서 끝났어요.


“한 글자씩 답이 나온다”는 게 진짜로 한 글자씩 32층을 다시 도는 거예요?

자, 이게 제가 진짜 막혔던 첫 질문이에요.

ChatGPT에 질문을 던지면 답이 다다닥 한 글자씩 떠요. 솔직히 그게 연출인 줄 알았어요 — 답을 다 만들어놓고 보여주는 속도만 느리게 한 줄. 근데 아니더라고요.

진짜로 한 토큰마다 LLM 32층을 처음부터 끝까지 다시 돌립니다.

업계 정확 명칭은 autoregressive decoding (자기회귀 디코딩)이에요. 1차 자료 그대로:

“Autoregressive decoding in language models is inherently slow, generating only one token per forward pass.”

여기서 1 forward pass = 32층 한 번 통째 통과. 그러니까 토큰 하나 만들 때마다 32층을 한 번 통과한다는 뜻이에요.

흐름은 이래요.

프롬프트: "오늘 날씨가"

Forward Pass 1: [오늘 날씨가] → 32층 통과 → 다음 토큰 "정말" 생성
Forward Pass 2: [오늘 날씨가 정말] → 32층 통과 → 다음 토큰 "좋다" 생성
Forward Pass 3: [오늘 날씨가 정말 좋다] → 32층 통과 → 다음 토큰 "."
Forward Pass 4: [오늘 날씨가 정말 좋다 .] → 32층 통과 → 다음 토큰 "[END]"

한 토큰 출력 = 32층 1번 통과. 100토큰 출력 = 32층 100번 통과.

🔁 한 토큰마다 32층을 다시 도는 흐름
Pass 1: [오늘 날씨가] → 32층 통과 → “정말” 생성
Pass 2: [오늘 날씨가 정말] → 32층 다시 통과 → “좋다”
Pass 3: [오늘 날씨가 정말 좋다] → 32층 또 통과 → “.”
Pass 4: [오늘 날씨가 정말 좋다 .] → 32층 또또 통과 → [END]
100토큰이면 32층을 100번 도는 셈. 그래서 어마어마한 계산이 필요한 게 맞아요.

여기서 자연스럽게 다음 의문이 따라와요. “100토큰 답하면 32층을 100번 도는 거? 한 층 안에 1677만 곱셈, 32층이면 5억 곱셈, 100번이면 500억 곱셈인데, 이게 가능한가? 어마어마한 계산량인데?”

저도 똑같이 막혔어요. 답이 흥미로워요. 순진하게 다시 계산하면 진짜 그 계산이 다 일어나야 해요. 근데 그러면 너무 느려서 못 써요. 그래서 한 가지 트릭이 들어가요. KV 캐시.


KV 캐시 — 근데 그 전에, Attention이 뭔지 한 줄만

KV 캐시를 풀려면 KV가 뭔지부터 알아야 하는데, 그게 사실 5편 주제인 Attention의 영역이에요. 그래서 5편에서 깊이 풀고, 여기선 한 줄만 잡고 갑시다.

Attention = 문장 안의 단어들이 서로 주의를 기울이는 메커니즘이에요.

1편 마지막에 박아둔 거 기억하시죠? “근면한 사과를 먹었다”의 “사과”는 근면한을 보고 좋은 의미가 되고, “용서 사과를 했다”의 “사과”는 용서를 보고 부정적 의미가 돼요. 그 보는 행위가 Attention이에요.

각 토큰이 “다른 토큰들 중에 누가 나랑 관련 있나?”를 묻고 답하는 구조. 이걸 통해서 같은 토큰 “사과”가 맥락에 따라 다른 의미가 돼요 (1편의 문맥 임베딩이 이거).

이 “묻고 답하는” 일에 세 가지 행렬이 쓰여요.

  • Q (Query, 질문): “내가 알고 싶은 게 뭐지?”
  • K (Key, 신호등): “나는 이런 정보 가지고 있어요”
  • V (Value, 내용): “그 정보의 실제 내용은 이거예요”

예: “근면한 사과”의 사과가 “근면한”을 볼 때 —

  • 사과의 Q ↔ 근면한의 K → 매칭 점수 높음
  • → 근면한의 V (내용)를 가져와서 사과 의미에 섞음
  • → 사과가 “근면 측면이 강조된 사과”가 됨

여기까지만 잡으세요. 자세한 건 5편에서 비유 깊이 풀게요. 지금은 “Q는 질문, K는 신호등, V는 내용물. Attention = 토큰들이 서로 주의 기울이는 메커니즘” 정도면 충분.


그래서 KV 캐시가 하는 일

추론 중에 새 토큰을 만들 때마다 모든 이전 토큰의 K, V를 다시 계산하면 낭비예요. 왜냐하면 이전 토큰의 K, V는 절대 안 변하거든요. 그 토큰 자체가 안 바뀌니까.

Forward Pass 1: "오늘 날씨가" 입력
  - "오늘"의 Q, K, V 계산 → K, V만 캐시 저장
  - "날씨가"의 Q, K, V 계산 → K, V만 캐시 저장
  - "정말" 출력

Forward Pass 2: "오늘 날씨가 정말" 입력
  - "오늘"의 K, V → 캐시에서 꺼내옴 (재계산 X)
  - "날씨가"의 K, V → 캐시에서 꺼내옴 (재계산 X)
  - "정말"의 K, V만 새로 계산해서 캐시 추가
  - "정말"의 새 Q로 캐시의 모든 K, V를 봄 → "좋다" 출력

Q는 왜 캐시 못 하나?
매 토큰마다 “내가 지금 무엇을 알고 싶은가”가 달라짐 → 새로 계산해야 함.

K, V는 왜 캐시 가능한가?
“내가 가진 정보”라서 토큰 자체가 안 바뀌면 안 변함 → 한 번 만들면 끝.

그래서 이름이 KV 캐시 (Q는 안 들어감).


Prefill vs Decode — 첫 글자만 느리고 그 다음은 빠른 이유

KV 캐시 덕분에 추론은 두 단계로 나뉘어요.

Prefill (첫 토큰 만들 때):
– 입력 프롬프트의 모든 토큰의 K, V를 한 번에 계산해서 캐시에 저장
– 토큰 수만큼 일이 폭증 → 시간 오래 걸림
– 1차 자료 (H100 GPU 기준): 1만 토큰 프롬프트의 prefill = 200~400ms

Decode (두 번째 토큰부터):
– 새 토큰 1개에 대해서만 K, V 계산 + 캐시에서 나머지 꺼냄
– 토큰당 일정한 속도로 빠르게
– 1차 자료: 초당 30~150 토큰 출력

이게 제가 ChatGPT 쓸 때 “첫 글자가 뜨기까지가 가장 느리고, 그 다음부터는 다다닥 빨리 나오는” 현상의 정체예요.

긴 프롬프트 던지면 첫 글자 뜨는 데 1초씩 걸리는 거 보셨죠? 그건 prefill이에요. 그 다음 답이 다다닥 나오는 건 decode.

“한 토큰 만들 때마다 32층 5억 곱셈을 다 새로 한다”는 명제의 정확한 답:
32층 통과는 매번 한다. 한 토큰마다 32층 통째 통과.
그런데 K, V 계산은 새 토큰 한 개분만 한다. 이전 토큰의 K, V는 캐시에서 가져옴.
– 그래서 50억 곱셈이 완전히 50억 그대로가 아니라 상당 부분 캐시 재활용. 실제 추가 계산은 새 토큰 1개분.


가중치가 안 변하는데 왜 GPU가 필요해요?

저도 처음에 이게 헷갈렸어요. “가중치가 변하니까 GPU로 빨리 계산해야 하는 거 아닌가? 가중치가 안 변하면 한 번 계산해두고 저장해두면 되잖아?”

답: 가중치는 안 변하지만, 입력이 매번 바뀌니까 곱셈은 매번 새로 해야 해요.

스팸 모델로 다시 보면 명확해져요.

  • 가중치 (2.0, -1.5, 0.3) — 학습 끝나서 고정
  • 새 메일 들어옴 → “당첨” 횟수, “회의” 횟수, 느낌표 개수 측정 → 가중치랑 곱하기

가중치는 안 변해도, 새 입력 × 가중치 곱셈은 매번 새로 해야 해요. 메일이 바뀌면 결과가 바뀌니까.

LLM에서는 이 곱셈이 어마어마해요.

  • 1 forward pass = 32층 통과
  • 한 층 = 4096 × 4096 행렬 곱셈 = 1677만 곱셈
  • 32층이면 ≈ 5억 곱셈
    • 마지막 출력층 (4096 × 12만8천 = 5억 더) → 한 토큰에 약 10억 곱셈

직감이 맞아요. 곱셈 수만 보면 학습 한 step이랑 비슷한 양이에요. 다만 학습은 순방향 + 역전파 + 가중치 업데이트라서 곱셈이 약 3배. 추론은 순방향만이라 1배.

GPU가 필요한 이유는 제가 이미 정확히 아세요 — 병렬 곱셈에 압도적으로 강해서. CPU는 한 번에 1~10개 곱셈, GPU는 한 번에 수천 개 곱셈을 동시에 해요. 1677만 곱셈을 GPU는 0.001초 안에 끝내요.

근데 여기서 진짜 헷갈렸던 건 따로 있어요. “GPU 메모리”라는 말이 자주 나오거든요. VRAM이 뭐고, 왜 모델이 통째로 거기에 올라가야 하는지가 막혔어요.


VRAM이 뭐예요?

VRAM = Video RAM (영상용 메모리)의 줄임말이에요. 컴퓨터 메모리 종류 중 하나인데, GPU 옆에 직접 붙어 있는 전용 메모리예요.

먼저 컴퓨터 안에 메모리가 두 종류 있다는 걸 잡고 가야 해요.

[일반 컴퓨터 구조]
CPU ←→ RAM (시스템 메모리, 16GB·32GB)
                ↑ 일반 작업용 (워드, 브라우저, 엑셀 등)

GPU ←→ VRAM (그래픽 메모리, 8GB·24GB·80GB)
                ↑ GPU 전용 (게임, 영상편집, AI)

왜 GPU가 자기 메모리를 따로 가졌나?

원래는 게임 화면 그리려고 만들어진 거예요 — 이름이 “Video” RAM인 이유. 게임 화면을 1초에 60번 그리려면 텍스처·도형 데이터를 어마어마하게 빠르게 읽어야 해요. 그래서 GPU 칩 바로 옆에 메모리를 붙여서 둘 사이 거리를 짧게 만든 거예요. CPU 옆의 RAM은 GPU에서 멀리 있어서 데이터가 도착하는 데 시간이 걸려요.

LLM 시대가 와서 보니까 — GPU 옆 VRAM의 빠른 데이터 이동 속도가 LLM 추론에도 딱 필요했어요. 그래서 GPU가 AI 칩의 표준이 됐어요.

1차 자료의 비교:

메모리 종류 용량 데이터 이동 속도
시스템 RAM (CPU용) 보통 16~64GB 50~100 GB/s
VRAM (GPU용, 데이터센터) 80~141GB 2,000~4,800 GB/s

VRAM이 시스템 RAM보다 20~100배 빨라요. 이 속도 차이가 LLM에서는 결정적이에요.


왜 모델이 통째로 VRAM에 올라가야 하나?

LLM 추론 한 번에 80억 가중치 전부가 곱셈에 동원돼요. 한 토큰 만들 때마다 80억 가중치를 다 읽어야 해요. 즉:

한 토큰 출력 한 번 = GPU가 14GB의 가중치 전부를 한 번 다 읽음

이걸 1초에 30~150번 해야 해요 (사용자가 답을 다다닥 받으려면). 만약 가중치가 시스템 RAM에 있으면:
– 시스템 RAM → GPU로 데이터 옮기는 속도 = 50GB/s
– 14GB 옮기는 데 0.28초 → 1초에 한 토큰밖에 못 만듦
– → ChatGPT가 한 글자 나오는 데 0.28초 걸림 → 너무 느려서 못 씀

가중치를 VRAM에 올려두면:
– VRAM → GPU 속도 = 2000GB/s
– 14GB 읽는 데 0.007초 → 1초에 140 토큰 가능
– → ChatGPT의 다다닥 답변이 가능

그래서 모델은 반드시 VRAM에 통째로 올라가 있어야 해요. 시스템 RAM에 두면 너무 느려서 사실상 안 돌아가요.

이게 모델 14GB → GPU VRAM 14GB 이상 필요 조건의 진짜 이유예요. “공간이 있어야”라기보다 “GPU 옆 빠른 메모리에 통째로 올라가 있어야 빠른 추론이 가능”.


메모리 대역폭이란 — 도로 차선 수 비유

메모리 대역폭 (Memory Bandwidth) = 1초에 메모리에서 GPU로 옮길 수 있는 데이터의 양

[좁은 도로 = 낮은 대역폭]
시스템 RAM: 50 GB/s
→ 1초에 50기가바이트만큼만 차가 지나갈 수 있음

[넓은 고속도로 = 높은 대역폭]
A100 VRAM: 2,000 GB/s
H100 VRAM: 3,350 GB/s
H200 VRAM: 4,800 GB/s
→ 1초에 5테라바이트(=5000기가바이트) 차가 지나감

LLM 추론 속도는 GPU의 곱셈 능력보다 메모리 대역폭에 더 묶여 있어요.

이유: 한 토큰 만들 때마다 모델 가중치 14GB(7B 모델)를 통째로 읽어야 해요. GPU의 곱셈 자체는 한 토큰 처리에 0.0001초밖에 안 걸려도, 가중치 14GB를 메모리에서 가져오는 데 시간이 더 걸리거든요.

[7B 모델 한 토큰 출력 한 번에]
A100 (대역폭 2000 GB/s):
  14GB ÷ 2000 = 0.007초 → 1초에 140 토큰

H100 (대역폭 3350 GB/s):
  14GB ÷ 3350 = 0.004초 → 1초에 240 토큰

대역폭이 빠를수록 LLM 추론이 빨라요. GPU 칩 자체의 성능보다 메모리 대역폭 차이가 H100과 A100 격차의 더 큰 부분이에요.


잠깐 — 1바이트가 왜 8비트예요?

여기서 막힌 게 하나 더 있어요. “FP16 = 2바이트, 1바이트 = 8비트”라는 말이 자꾸 나오는데, 왜 정확히 8비트인지 모르겠는 거예요.

답: 역사적 결정이에요. 수학적 필연이 아니에요.

옛날 컴퓨터는 1바이트가 8비트가 아니었어요. 1차 자료 (Wikipedia):

“Early computer systems often had memory words of 12, 18, 24, 30, 36, 48, or 60 bits”

1950년대 컴퓨터는 6비트 바이트, 12비트 바이트 다 있었어요. 표준이 없었음.

1964년 IBM이 System/360이라는 컴퓨터를 만들면서 8비트로 정함. 이게 표준이 됐어요. 이유 4개:

  1. 영문자 한 글자 표현에 충분 — 영어 알파벳 + 숫자 + 기호 = 128개 정도. 표현하려면 7비트 + 여유 1비트 = 8비트
  2. 2의 제곱 (수학적 깔끔함) — 8 = 2³, 컴퓨터가 곱셈·시프트 연산이 편함
  3. 0~255 범위 (실용적) — 색깔 1채널(RGB)이 정확히 0~255 → 8비트가 표준이 된 또 다른 이유
  4. IBM 시장 점유율 — 1969년 IBM이 System/360을 월 1000대 팔았어요. 다른 회사들이 호환 위해 따라옴

즉 1바이트 = 8비트는 “그렇게 정한 약속”이에요. 우주의 법칙이 아니라 1960년대 IBM 결정이 표준이 된 거. 오늘은 너무 표준이라 바뀔 수 없어요.


모델 크기 계산 — 7B는 왜 14GB인가

가중치 1개를 컴퓨터 메모리에 어떻게 저장하나부터.

가중치 1개는 소수예요 (예: 0.347291482763). 컴퓨터에서 소수 1개를 표현하려면 정밀도(precision)를 정해야 해요.

  • FP32 (32비트 = 4바이트): 정밀하게. 학습할 때 주로 사용
  • FP16 (16비트 = 2바이트): 살짝 정밀도 낮춤. 추론 시 주로 사용
  • INT8 (8비트 = 1바이트): 양자화. 추론 비용 절감
  • INT4 (4비트 = 0.5바이트): 더 양자화. 추론 비용 더 절감

FP16(2바이트) 기준 7B 모델 크기:

7,000,000,000개 가중치 × 2바이트 = 14,000,000,000 바이트
                                = 14 GB

(GB = 10억 바이트, 정확히는 1024³이지만 LLM 업계는 10억으로 셈)

이 14GB가 곧 VRAM에 올려야 하는 양이에요. 위에서 본 이유 그대로.


양자화 — 같은 모델을 절반·1/4로 줄이는 마법

학습은 정밀도 풀로 해야 하지만, 추론은 정밀도 좀 낮춰도 답이 거의 같아요. 그래서 학습 끝난 모델을 양자화해서 추론용으로 배포하는 게 표준이에요. (자세한 건 6편에서 다시.)

원본 (FP32 = 4바이트): 0.347291482763
FP16 (2바이트):       0.34729148  ← 거의 같음
INT8 (1바이트):       0.347       ← 살짝 거침
INT4 (0.5바이트):     0.3         ← 더 거침

같은 7B 모델이라도 정밀도에 따라 메모리가 달라요.

7B FP16 = 14 GB
7B INT8 = 7 GB
7B INT4 = 3.5 GB

추론 답변 품질은 INT8까지는 거의 그대로, INT4부터는 약간 떨어져요. 그래서 작은 GPU에서 큰 모델 돌리기 위해 양자화를 씁니다.


405B를 GPU 8대에 띄우는 법 — 직접 계산

제가 아까 405B를 8bit로 계산하셨던 거 그대로 따라가요.

405B 가중치 × 8bit 정밀도
= 405,000,000,000개 × 1 byte
= 405,000,000,000 byte
= 405 GB

계산 정확합니다. 405B 8bit = 405GB.

그럼 H100 80GB가 몇 대 필요한가?

H100 80GB × 5대 = 400GB → 가중치만 정확히 안 들어감 (5GB 부족)
H100 80GB × 6대 = 480GB → 가중치는 들어가지만 여유 부족
H100 80GB × 7대 = 560GB → 안전
H100 80GB × 8대 = 640GB → 충분

근데 1차 자료 (NVIDIA 공식)에서는 FP8(8bit) 405B를 H100 8대로 쓰라고 권해요. 왜 6대가 아니라 8대?

이유: VRAM은 가중치만 들어가는 게 아니에요.

[실제 405B 8bit 서빙 메모리 계산]
가중치: 405GB
KV 캐시 (10명 동시 사용자): 50~100GB
중간 계산: 20~30GB
여유: 50GB
─────────────────────
총 필요: 약 525~585GB
─────────────────────
H100 80GB × 8대 = 640GB → 딱 맞음
H100 80GB × 7대 = 560GB → 빠듯, 사용자 수 제한해야 함

그래서 NVIDIA가 8대를 권하는 거예요. 가중치만 보면 6대로도 가능하지만, 실제 서빙엔 KV 캐시·중간 계산·동시 사용자까지 고려해야 해서 8대가 표준.

4bit 양자화로 더 줄이면:

405B × 0.5 byte = 202GB (가중치만)
+ KV·중간계산 등 = 약 280GB
H100 80GB × 4대 = 320GB → 가능

이게 “H100 4대로 405B 4bit 가능”의 근거예요.


A100 vs H100 vs H200 — 알파벳이 위로 갈수록 신세대

여기서 막혔던 게 또 있어요. “A100 40GB와 80GB는 왜 두 배 차이?”, “A와 H의 차이는?”, “H100 80GB → H200 141GB는 왜 정확히 두 배가 아닌가?”

하나씩 풀어볼게요.

A100 40GB vs 80GB

같은 칩에 메모리를 다른 용량으로 붙여서 만든 두 가지 SKU예요. 자동차 같은 모델인데 트렁크 크기만 다른 거.

NVIDIA가 A100을 출시할 때 두 버전으로 나왔어요:
A100 40GB (2020년 출시, 초기 모델)
A100 80GB (2021년 출시, 메모리 두 배 늘린 버전)

칩(GPU 코어)은 같고, 옆에 붙은 HBM 메모리 모듈만 다른 거. 80GB가 큰 모델 띄우기 좋아서 LLM 업계에서 표준이 됐어요.

A vs H

NVIDIA의 데이터센터 GPU 세대 이름이에요. 알파벳이 위로 갈수록 신세대.

세대 출시년 코드명
A (A100) 2020 Ampere
H (H100, H200) 2022 Hopper
B (B100, B200) 2024 Blackwell

A → H로 넘어가면서:
– 메모리 대역폭: A100 2TB/s → H100 3.35TB/s (67% 증가)
– 주로 LLM에 중요한 메모리 대역폭이 큰 차이 — 곱셈 자체보다 데이터 읽고 쓰는 속도가 LLM 추론 병목이라서

H100 80GB → H200 141GB가 정확히 2배가 아닌 이유

좋은 직감이에요. “핸드폰 저장용량은 64 → 128로 정확히 2배인데?”

답: HBM은 핸드폰 NAND 플래시랑 다른 종류의 메모리예요.

H200은 H100과 칩(GPU 코어)이 같아요. 메모리만 다른 종류로 업그레이드한 모델이에요:
– H100: HBM3 (한 스택당 24GB) × 6 스택 = 144GB이지만 실제로 80GB만 활성화
– H200: HBM3e (스택당 더 큰 용량 가능) × 6 스택 = 141GB

NVIDIA가 H100에서 80GB만 노출한 이유는 수율 (제조 시 정상 작동하는 비율) 문제. 모든 스택을 풀 용량으로 쓰면 불량률이 올라감. 그래서 의도적으로 일부만 활성화.

H200에선 HBM3e 신기술로 더 안정적으로 만들 수 있어서 141GB까지 노출.

즉 정확히 2배가 아닌 이유 = HBM 메모리 모듈 스펙 + NVIDIA의 수율 기반 비즈니스 결정. 핸드폰 NAND 플래시는 칩 크기 자체를 자유롭게 만들 수 있지만, HBM은 GPU 옆에 직접 쌓는 구조라 제조 공정에 묶여 있어요.


HBM이 뭐길래 빠른가

VRAM 종류 중 가장 빠른 게 HBM (High Bandwidth Memory, 고대역폭 메모리)이에요.

일반 메모리 (DDR, GDDR):
– 칩 옆에 띄엄띄엄 배치
– 데이터가 옆 칩까지 수 cm 이동 필요
– 거리 = 시간 손실

HBM:
– 메모리 칩을 수직으로 16층 쌓아서 GPU 옆에 직접 붙임
– 데이터 이동 거리가 수 mm로 짧아짐
– → 더 많은 데이터를 더 빨리 옮길 수 있음

비유: 도서관 책 빌리기
– 일반 메모리 = 도서관 가서 책 한 권씩 빌리기 (왕복 시간 큼)
– HBM = 책상 옆 책장에서 한 번에 16권 뽑기 (왕복 시간 작음)

H200이 H100보다 빠른 이유 = HBM3e (신세대 HBM)을 써서 대역폭이 3350 → 4800 GB/s로 올라감.


잠깐, 학습 얘기로 돌아가서 — 역전파는 왜 거꾸로 가야 하나?

여기서 추론 학습하다 2편(학습)으로 잠깐 돌아가야 하는 의문이 생겼어요. 2편에서 “역전파 = 회사 부서 책임 추궁” 비유를 들었지만, 솔직히 왜 거꾸로 가야만 하는가가 안 풀렸거든요. 추론 영역에 들어와서 가중치가 안 변한다는 사실이 명확해지니까, 그제야 역전파 거꾸로 가는 이유도 다시 깊이 풀고 싶어졌어요.

답: 순방향에서는 “고친다”는 행위 자체가 불가능해요. 왜냐하면 어떻게 고쳐야 할지를 모르거든요.

스팸 모델 3층짜리로 풀게요. 가중치를 단순히 w₁(1층), w₂(2층), w₃(3층) 한 개씩만 있다고 가정해요. 입력 = 5, 정답 = 0.

입력 5 ──[w₁=2]──→ 1층 결과 ──[w₂=3]──→ 2층 결과 ──[w₃=1]──→ 출력
                  10              30              30

출력 30 - 정답 0 = 틀린 정도 30

이제 “어느 가중치를 얼마나 고쳐야 하나?” 가 질문이에요.

시나리오 A: 순방향으로 고치려고 시도

w₁부터 고치고 싶어요. 근데 w₁을 얼마나 바꿔야 출력이 0에 가까워지나? 알 수가 없어요. 왜냐하면:

  • w₁을 고쳐도 출력에 도달하려면 w₂, w₃를 아직 통과해야 함
  • w₂, w₃이 그대로면 w₁ 변경의 효과는 w₂ × w₃ = 3 곱하기 만큼 증폭돼서 출력에 도달
  • 근데 우리는 전체 사슬 효과가 얼마인지 출력 본 뒤에야 알 수 있음
  • 계산 끝까지 안 가보면 w₁의 영향력을 모름

순방향에서는 “내가 출력에 얼마나 영향을 미쳤나”를 누구도 모르는 상태예요. 출력이 만들어지기 전이니까.

시나리오 B: 역방향으로 고치는 (실제 방식)

[순방향 끝낸 뒤]
출력 30, 정답 0, 틀린 정도 30

[역방향 시작]
1단계: 출력에 가장 가까운 w₃부터 본다
       "w₃를 1만큼 키우면 출력이 얼마나 변하나?"
       → 2층 결과(30) × 1 = 출력 30 변함
       → w₃의 영향력 = 30 (직접적, 곧바로 알 수 있음)

2단계: w₂를 본다
       "w₂를 1만큼 키우면 출력이 얼마나 변하나?"
       → 1층 결과(10) × 1단계에서 안 영향력 = 10 × 30
       → w₂의 영향력 = 300

3단계: w₁을 본다
       "w₁을 1만큼 키우면 출력이 얼마나 변하나?"
       → 입력(5) × 2단계에서 안 영향력 = 5 × ...
       → w₁의 영향력 = 거꾸로 거슬러 올라가며 곱셈

핵심: w₃부터 시작하면 영향력을 직접 잴 수 있어요. w₃은 출력 바로 앞이니까 변화가 즉시 출력에 보임. w₂는 w₃을 통과해야 출력에 도달하니까, w₃의 영향력을 먼저 알아야 계산 가능. w₁은 w₂, w₃를 다 통과해야 하니까 둘 다 알아야 계산 가능.

출력에 가까운 가중치부터 거꾸로 가야 한다. 이게 거꾸로 가는 이유.

직관 비유: 회사 책임 추궁 — 다시

매출 -1억이 났을 때:

  • 순방향 책임 추궁 (불가능): “원자재팀, 너 책임 얼마야?” — 원자재팀: “글쎄, 가공·조립·마케팅 다 거쳐서 어떻게 됐는지 모르겠어요”
  • 역방향 책임 추궁 (가능): “마케팅팀, 너 책임 얼마야?” — 마케팅팀: “내가 직접 매출 만들었으니 100%” → “조립팀, 마케팅 입력에 영향 얼마?” → “가공팀, 조립 입력에 영향 얼마?” → 거꾸로 사슬

원자재팀은 자기 행동이 매출에 어떻게 도달했는지 직접 모르고, 매출에 가까운 부서들의 영향을 다 알아야 자기 영향을 계산할 수 있어요. 이게 체인 룰의 본질이에요.

→ “거꾸로”는 알고리즘 선택이 아니라 수학적으로 거꾸로 가는 것 외엔 방법이 없는 거예요.

“동시”라는 표현 정정

2편에서 “순방향과 역전파가 동시”라는 표현이 있었다면 그건 정확하지 않아요. 정확히는:

  • 순방향과 역전파는 동시가 아님 — 순서대로 일어남
  • “동시”라고 표현했던 건 한 층 안의 80억 가중치가 한 번에 업데이트된다는 뜻

1 step 안에서 시간 순서:

[1단계] 순방향 (Forward Pass)
        입력 → 1층 → 2층 → ... → 32층 → 출력 → 틀린 정도 측정
        ※ 각 층의 중간 결과를 메모리에 다 저장해둠 (역전파 때 필요)

[2단계] 역방향 (Backward Pass)
        틀린 정도 → 32층 경사 → 31층 경사 → ... → 1층 경사
        ※ 1단계에서 저장해둔 중간 결과를 꺼내 쓰면서 거꾸로 곱셈

[3단계] 가중치 업데이트
        1층~32층의 80억 가중치를 한 번에 업데이트

순방향 끝나야 역전파 시작 가능. 역전파 끝나야 가중치 업데이트 가능. 순서가 강제돼요. 80억 개를 시점적으로 동시에 다 바꾸는 건 3단계의 일이에요.


FROM 바이브코딩 태일러 · 매주 월요일
바빠도 5분이면 읽는
이번 주 AI 흐름
태일러가 고른 AI 뉴스 TOP 3 · 벤치마크 순위 · 급상승 키워드 · 판단 기준 보너스. 광고 없는 클린 미디어입니다.

무료로 받아보기 →

선착순 100명 영구 무료 · 언제든 해지

다시 추론으로 — 32층 통과하고 나면 뭐가 나오나

자, 추론으로 돌아왔어요. 32층을 통과하면 뭐가 나오는지 다시 짚읍시다.

1편 마지막에 박아둔 거예요. 마지막 출력층의 정체 = 어휘집 12만 8천 개 토큰 임베딩과의 거리 비교. 32층 출력 벡터에 가장 가까운 토큰의 점수가 가장 높게 나와요.

근데 점수가 정확히 뭐냐. 제가 여기서 막혔어요.

32층 통과 후 점수(로짓) 12만 8천 개:
좋다  →  23.4
많다  →  18.2
흐리다 → 12.1
나쁘다 →  -5.2     ← 음수도 나올 수 있음
이상하다 → -100   ← 한참 음수도 나올 수 있음

이 숫자들이 확률이 아니에요. 음수도 있고, 다 더해도 100%가 안 돼요. 그래서 확률로 바꿔줘야 토큰을 뽑을 수 있어요.

여기서 자연스럽게 떠오르는 의문: “그냥 비율 계산하면 안 돼? 23.4 / (23.4+18.2+12.1+…) 이런 식으로?”

안 돼요. 두 가지 이유.

  1. 음수가 있으면 비율이 안 됨 (확률은 음수가 될 수 없음)
  2. 최댓값과 최솟값의 차이가 충분히 크게 안 벌어짐

그래서 등장하는 게 Softmax예요.


Softmax — 자르는 게 아니라 변환하는 식

처음에 “Softmax = 소수점 자르는 거?” 라고 추측했어요. 아니에요. 자르지 않아요.

Softmax는 두 단계로 풀어요:

1단계: 모든 점수에 e의 지수를 씌움 (지수함수)
       e^23.4, e^18.2, e^12.1, e^-5.2, ...
       → 모두 양수가 되고, 큰 점수와 작은 점수의 차이가 폭발적으로 벌어짐

2단계: 각각을 전체 합으로 나눔 (정규화)
       → 모두 0~1 사이, 다 더하면 1.0

“다 더하면 100%가 되나?”

예, 정확히 100% 돼요. Softmax는 수학적으로 반드시 합이 1.0이 되도록 설계됐어요.

Softmax 식: 각 토큰의 확률 = e^로짓 / (모든 토큰의 e^로짓의 합)

분자에 각각의 e^로짓, 분모에 모두 더한 e^로짓의 합을 두면:

(e^로짓₁ + e^로짓₂ + ... + e^로짓ₙ) / (e^로짓₁ + e^로짓₂ + ... + e^로짓ₙ) = 1.0

분자랑 분모가 같은 합이니까 정확히 1.0. 컴퓨터의 부동소수점 오차로 0.9999… 가 될 수 있지만, 수학적으로는 정확히 1.0.

“e^23.4가 어마어마한 큰 숫자가 되니까 그런가?”

정확히 짚으셨어요. 이게 Softmax가 “차이를 폭발적으로 벌리는” 핵심 이유예요.

수치로 보여드릴게요. 점수 두 개가 23.4와 18.2라고 해봐요:

[원래 점수 비율]
23.4 : 18.2 = 1.29 : 1
→ 둘이 거의 비슷해 보임 (차이 30%)

[e의 지수 씌우면]
e^23.4 ≈ 1.46 × 10^10  (146억)
e^18.2 ≈ 8.0  × 10^7   (8천만)

비율: 약 180 : 1
→ 23.4 토큰이 18.2 토큰의 180배 더 자주 뽑힘

지수함수의 마법이에요. 입력 차이가 5밖에 안 나도, 지수 씌우면 비율이 180배로 폭발해요.

비유: 리히터 지진 규모도 지수함수예요. 5.0과 7.0은 숫자로는 2 차이지만, 실제 에너지는 1000배 차이.

Softmax가 e를 쓰는 이유 두 가지:
1. 모두 양수가 됨 (음수도 e^음수 = 양수)
2. 차이가 폭발적으로 벌어짐 → 1등 토큰이 압도적으로 자주 뽑힘 → LLM이 헛소리 안 함

분모로 나누는 정규화 덕분에 결국 합은 정확히 1.0이 돼요. “큰 숫자 만들어놓고 다 더해도 1되게 다시 줄이는 셈.” 차이는 폭발적으로 벌리고, 합은 1.0 유지.


Sampling — “1등 확률이 압도적이면 작은 수치가 나오는 건지, 작은 수치가 나오면 평평하게 만드는 건지”

여기가 진짜 헷갈렸어요. Sampling이 분포를 비트는 것인지 분포대로 뽑는 것인지가 안 잡혔어요. 원문 질문 그대로 옮기면:

“sampling은 1등의 확률이 압도적이라면 작은 수치가 나오는 건지 아니면 작은 수치가 나오면 평평하게 만들려고 움직이는 건지 뭐가 전자 후자인지 모르겠음. 애초에 왜 필요한 거지?”

답: Sampling은 비트는 게 아니에요. 그냥 분포대로 무작위로 뽑는 거예요.

비유로 풀게요. 주사위가 있는데 1이 나올 확률이 95%, 2가 5%, 나머지가 0%인 주사위라고 해봐요. 100번 던지면:

  • 95번 정도는 1이 나옴
  • 5번 정도는 2가 나옴
  • 3, 4, 5, 6은 거의 안 나옴

1등 확률이 압도적이면, 거의 항상 1등이 뽑혀요. 가끔 2등이 뽑힐 뿐.

LLM 토큰 sampling도 똑같아요:

"좋다" 95%, "많다" 4%, "흐리다" 0.5%, ...
→ 100번 중 95번은 "좋다", 4번은 "많다", 1번은 "흐리다"

“평평하게 만든다”가 아니라 “분포대로 뽑는다.”

분포를 비트는 건 Sampling이 아니라 그 전 단계인 Temperature예요.

[순서]
1. 32층 통과 → 로짓 (점수)
2. Temperature로 점수 비틀기 (분포 비틀기)
3. Softmax로 확률로 변환
4. Top-K/Top-P로 후보 좁히기
5. Sampling으로 확률대로 무작위 뽑기

Temperature가 분포를 평평하게/뾰족하게 만들고, Sampling은 그 결과대로 뽑기만 해요.


Temperature — 인간다운 답변을 위한 노브

짚으신 “매번 다른 답변을 내기 위해서 temperature을 만든 건가?” — 정확해요. 더 정확히는 결정성 vs 창의성 조절.

분포가 먼저, Temperature가 위에서 비틈

또 다른 질문: “분포를 보고 temperature을 정하는 게 먼저인지, 분포를 보고 나중에 temperature가 따라오는 건지.”

답: 두 번째. 분포(점수)가 32층 통과 결과로 자동으로 나오고, Temperature는 사람이 미리 정해놓은 값이에요. T 값 자체는 분포 보고 정하는 게 아니라 용도에 따라 미리 정해둠.

Temperature가 하는 일을 식으로 보면:

Temperature 적용 = 모든 점수를 T로 나누기
새 점수 = 원래 점수 / T

T = 1.0 (기본): 점수 그대로
T = 0.5 (낮음): 점수 두 배로 → 차이 더 커짐 → 1등 더 압도적
T = 2.0 (높음): 점수 절반으로 → 차이 줄어듦 → 분포 평평

수치로 보면:

원래 점수: [좋다 23, 많다 18, 흐리다 12]

T = 0.5 (창의성 낮춤):
  [46, 36, 24] → 1등 확률 거의 100%

T = 1.0 (기본):
  [23, 18, 12] → 1등 95%, 2등 4%, 3등 1%

T = 2.0 (창의성 올림):
  [11.5, 9, 6] → 1등 70%, 2등 20%, 3등 10%

“95%면 그래도 5% 확률로 다른 토큰 나오는지”

두 번째 질문, 답은 예, 정확히 그렇게 작동해요.

좋다 95% 확률 → 100번 중 95번 뽑힘
많다 4%      → 100번 중 4번 뽑힘
흐리다 1%    → 100번 중 1번 뽑힘

가장 큰 확률이 무조건 뽑히는 게 아니에요. 5%의 확률로 다른 토큰이 나와요. 그게 추론에 sampling이 들어가는 핵심 이유 — 같은 질문에 매번 살짝 다른 답을 내려고.

만약 무조건 1등만 뽑히는 모드가 필요하면 Temperature를 0으로 설정하거나 Greedy decoding이라는 별도 모드를 써요. 코드 생성·번역에서 종종 사용.

Sampling (T = 1.0):    매번 다른 답 가능
Greedy decoding (T=0): 같은 입력 → 항상 같은 답

제가 ChatGPT에 같은 질문 두 번 던졌을 때 미세하게 답이 다른 이유 = Temperature가 0이 아니어서 sampling으로 매번 다르게 뽑히는 거예요.

Temperature 값 어떻게 정하나

마지막 질문: “사람들은 어떻게 상황마다 temperature을 정해놨지?”

답: 시행착오 + 용도별 경험치 + 사람마다 약간 다름. 표준 공식은 없어요.

업계 통용 가이드라인:

용도 권장 Temperature 이유
코드 생성 0.0 ~ 0.3 정확성이 핵심. 같은 입력 = 같은 답 원함
번역 0.0 ~ 0.3 정확성. 창의성 불필요
사실 검색·QA 0.3 ~ 0.5 정확하되 자연스러움
이메일·일반 글쓰기 0.7 ~ 1.0 자연스러운 답변
마케팅·카피 1.0 ~ 1.3 창의성, 매번 다른 표현
시·이야기 1.0 ~ 1.5 창의성 최우선
브레인스토밍 1.2 ~ 2.0 의외의 단어 자주 나와야 함

이 값들이 어떻게 정해졌나? 역사적 시행착오로 결정됐어요. 정확히는:

  1. 모델 출시할 때 OpenAI/Anthropic 등이 기본값 1.0으로 설정 (수학적 의미: 분포 그대로)
  2. API 사용자들이 다양한 용도로 써보면서 “이 용도엔 이 값이 좋더라”가 누적
  3. 블로그·논문·실무 가이드를 통해 표준값이 자리잡음

아무도 “코드는 0.2가 정답” 같은 공식을 증명한 적 없어요. 사용자들이 시도해보면서 “0.7로 코드 짜면 너무 헛소리 많이 함, 0.2가 안전함” 같은 경험치를 공유.

ChatGPT 웹 화면에서는 일반 사용자가 Temperature를 못 봐요. OpenAI가 적당한 기본값(약 1.0)으로 고정해놓고 쓰는 거. API로 직접 호출하면 조정 가능.


Top-K, Top-P — 헛소리 방지장치

문제: Sampling만 하면 가끔 정말 이상한 토큰이 뽑혀요.

12만 8천 개 토큰 중 23등 토큰의 확률이 0.0001%라고 해도, 그게 뽑힐 수 있어요. 100만 번 샘플링하면 한 번은 뽑히죠. 그러면 LLM이 갑자기 헛소리.

그래서 “확률이 너무 낮은 후보는 아예 제외시키자”가 Top-K, Top-P예요.

  • Top-K = 상위 K개만 후보로 (예: K=50, 51등 이하 다 제거)
  • Top-P (Nucleus) = 누적 확률 P%까지만 후보로 (예: P=0.9, 누적 90%까지의 토큰만)

차이는 “고정 개수”“누적 확률”. Top-K는 후보 수가 항상 같음. Top-P는 분포가 뾰족하면 후보가 적어지고, 평평하면 후보가 많아짐 (적응형).

회사마다 다른가? 지금도 쓰나?

다음 질문에 1차 자료 그대로:

Temperature 기본값 Temperature 범위 Top-P Top-K
OpenAI (GPT-4 등) 1.0 0.0 ~ 2.0 사용자 조정 가능 API에 없음 (2026년 4월 기준)
OpenAI o1, o3 (추론 모델) 1.0 고정 변경 불가
Anthropic (Claude) 1.0 0.0 ~ 1.0 사용자 조정 가능 사용자 조정 가능

답:
회사마다 노출하는 파라미터가 다름 (OpenAI는 Top-K 안 노출, Anthropic은 노출)
고정값이 아니라 사용자가 API에서 조정 가능 (단, OpenAI o1·o3 같은 추론 모델은 Temperature 고정)
지금도 쓰고 있음. 모든 LLM 추론에 매번 적용되는 표준 기술

흥미로운 변화: Anthropic은 최근에 “Temperature와 Top-P 둘 다 같이 지정하지 마라”는 정책으로 바꿨어요 (Claude Opus 4.1부터). 둘 다 분포를 비트는 도구라서 같이 쓰면 결과 예측이 어려워서.


학습 중 정답 vs 추론 시 정답 — 정리

여기까지 왔으면 제가 짚으셨던 “학습 중에는 정답이 있지만 추론에는 정답이 없구나, 가장 확률이 높아도 sampling 단계에서 두 번째 확률의 토큰이 불릴 수도 있다는 건가?” — 이게 정확히 맞다는 게 보여요.

  • 학습 중: 정답 = 다음 토큰 (자기지도학습). 모델이 “좋다”라고 예측해야 하는데 “춥다”라고 예측하면 → 틀린 정도 측정 → 가중치 업데이트.
  • 추론 중: 정답이라는 개념 자체가 없음. 모델은 그냥 12만 8천 개 토큰의 확률 분포를 출력 → 그중 하나를 sampling으로 뽑음 → 그게 답.

추론에는 loss 측정도, 가중치 업데이트도, 역전파도 없어요. 한 번 통과 + 토큰 뽑기. 끝.


어휘집 — 모델마다 다르다는 건 어떻게 만들어진 건데?

제가 여기서 핵심 질문 던지셨어요:

“LLM의 어휘집에는 토큰마다 등록이 되어있다는 건 아니지 왜냐하면 모델마다 어휘집에 등록되어 있는 형식이 다르니까. BPE는 어휘집도 학습으로 만든 건가? 아니면 미리 정해둔 건가?”

답: BPE = 어휘집을 만드는 알고리즘이에요. 학습 데이터로 어휘집을 자동 구축해요.

BPE의 진짜 의미가 두 가지예요:

  1. 어휘집 만드는 방법 (Tokenizer Training) — 학습 데이터로 어휘집 구축
  2. 그 어휘집으로 텍스트 자르는 방법 (Tokenization) — 새 텍스트를 어휘집의 토큰들로 쪼개기

이 둘은 다른 작업이에요. 어휘집 만들기는 모델 학습 전에 한 번만 해요.


BPE로 어휘집 만드는 과정

1. 학습 데이터 전체 모음 (수조 개 글자)
2. 처음엔 모든 글자(byte) 단위로 시작
   - 영어: 256개 byte (UTF-8 모든 byte)
3. 학습 데이터에서 가장 자주 같이 나오는 두 토큰을 찾아서 합치기
   - 예: "사" + "과"가 자주 같이 나옴 → "사과" 라는 새 토큰 등록
4. 어휘집이 목표 크기에 도달할 때까지 3을 반복
   - GPT-4: 100,258개 도달할 때까지
   - llama3: 128,000개 도달할 때까지

질문: “어휘집이 12만 8천이 된 계기 자체도 그게 같이 나올 확률이나 정답에 가까워졌으니 그렇게 되었는지”

이건 약간 다르게 짚으셨어요. 12만 8천은 설계자가 미리 정한 상한이에요. “이 정도면 충분하지” 하고 끊는 거. 결정 기준은:

  • 너무 작으면(예: 1만): 흔한 단어도 잘게 쪼개져서 토큰 수가 폭증 → 추론 비용 증가
  • 너무 크면(예: 100만): 마지막 출력층 가중치(어휘집 크기 × 4096)가 폭발 → 모델 크기 증가
  • llama3가 12만 8천을 고른 이유: GPT-4 (10만)보다 살짝 크게, 다국어 지원에 유리

BPE 어휘집은 학습으로 만들지만, 만들고 나면 고정. 모델 가중치와 별도로 어휘집 파일이 같이 배포돼요. tokenizer.json 같은 파일.

제가 “모델마다 어휘집에 등록되어 있는 형식이 다르니까” 라고 하신 부분 — 정확해요. 모델마다 어휘집이 다 달라요. GPT-4의 어휘집과 llama3의 어휘집은 다른 토큰 셋이에요. 같은 단어가 GPT-4에서는 1토큰, llama3에서는 3토큰으로 잘릴 수 있어요.


한글이 영어보다 토큰을 많이 먹는 이유

마지막 질문: “왜 한글 글자가 영어와 다르게 2~3토큰으로 쪼개지지?”

원인 두 개예요.

원인 1: UTF-8 인코딩 자체의 차이

컴퓨터가 글자를 저장할 때 쓰는 표준이 UTF-8이에요. UTF-8에서:

  • 영어 알파벳 (a, b, c, …): 1 byte
  • 한글 글자 (가, 나, 사, 과, …): 3 bytes

byte는 0~255의 숫자. 1글자가 1 숫자가 아니라 여러 숫자로 쪼개져요. 한글 “사”는 3개의 byte로 표현돼요.

"a"  →  byte 1개
"사" →  byte 3개

BPE는 byte 단위로 시작하기 때문에, “사” 하나가 처음엔 3개 토큰으로 잡혀요.

원인 2: 학습 데이터 비율

BPE는 자주 같이 나오는 byte를 합쳐 어휘집을 만들죠. 그런데 학습 데이터가 영어 비중이 압도적이에요 (인터넷 텍스트의 70~80%가 영어).

  • 영어는 학습 데이터에 자주 나옴 → “the”, “is”, “you” 같은 흔한 단어가 통째로 어휘집에 등록 → 1토큰
  • 한국어는 학습 데이터에 적게 나옴 → “사”, “과”, “를” 같은 자주 쓰는 글자도 어휘집에 통째로 등록 안 됨 → byte 단위로 남음 → 3토큰

결과: 같은 의미를 한국어로 쓰면 영어보다 2~3배 토큰 수가 많아져요.

이걸 “byte premium effect”라고 해요. 한국어·일본어·중국어 사용자가 OpenAI API에서 영어보다 비싸게 쓰는 이유. 같은 1000자라도 한국어는 토큰이 많이 쓰이니까.

llama3가 12만 8천 어휘집을 쓰는 이유 중 하나: 다국어를 더 잘 압축하려고. GPT-4(10만)보다 한국어가 살짝 효율적이에요.


한국어는 띄어쓰기가 모호한데 토큰화는 어떻게?

제가 처음에 던지신 질문: “한국어는 단어와 조사가 띄어쓰기 없이 오는데 LLM을 어떻게 하는 거야?”

답: LLM은 띄어쓰기 단위로 자르지 않아요. BPE로 자릅니다.

"사과를 먹었다"
       ↓ BPE 토큰화
"사과" + "를" + " 먹" + "었" + "다"

“사과”는 자주 나와서 통째로 한 토큰. “를” 같은 조사도 너무 자주 나와서 통째로 한 토큰. 모델이 “어디까지가 단어, 어디부터가 조사” 같은 문법을 배운 적이 없어요. 그냥 통계적으로 자주 같이 나오는 글자 묶음을 한 토큰으로 만든 거예요.

신기한 건, BPE가 결과적으로 한국어 형태소 경계와 거의 비슷하게 잘려요. 학습 데이터에 “사과를”, “사과가”, “사과는”이 다 나오면 BPE는 “사과”를 공통으로 떼어내요. 이게 통계로 문법이 자연스럽게 발견되는 현상이에요.

1편에서 제가 박아두신 부분 — “모델은 조사와 명사를 구별하지 않는다, 그냥 토큰일 뿐” — 이 정확히 맞아요.


컨텍스트 윈도우 — 책상의 정확한 정체

여기까지 보면 자연스럽게 다음 의문이 떠올라요. “그래서 LLM이 한 번에 처리할 수 있는 입력 길이는 얼마예요?”

답: 컨텍스트 윈도우(Context Window)가 그 한계예요.

비유로 잡으면 책상의 크기예요. 책상 위에 시스템 프롬프트, 이전 대화, 새 질문, 도구 정보, 그리고 모델이 답으로 만드는 토큰까지 다 올라가 있어야 해요. 책상이 크면 한 번에 많이 올릴 수 있고, 작으면 적게 올림.

모델별 책상 크기 (2026년 5월 기준)

모델 컨텍스트 윈도우
Claude Opus 4.7 1,000,000 토큰 (1M)
Claude Sonnet 4.6 1,000,000 토큰
Claude Haiku 4.5 200,000 토큰
GPT-5.5 1,000,000 토큰
Gemini 3.1 Pro 1,000,000 토큰
Llama 3.1 (로컬) 128,000 토큰

회사·모델마다 달라요. 같은 회사 안에서도 작은 모델은 작은 윈도우인 경우가 많아요.

진짜 책상 안을 들여다본 모습

추상적인 비유 같죠? 근데 진짜로 책상 안을 볼 수 있어요. 제가 Claude Code(개발자 도구)에서 /context를 입력했을 때 본 화면이에요.

Claude Code 컨텍스트 윈도우 사용량 화면 — claude-opus-4-7[1m] 모델, 329.7k/1.0M 토큰(33%) 사용 중
실제 책상(1M 토큰) 안에 뭐가 올라가 있는지 — System prompt 9.2k · System tools 12.9k · Memory files 5.8k · Skills 4.6k · Messages 297.6k · Autocompact buffer 33k · 빈 공간 637k.

이걸 보면 비유가 진짜로 일어나는 일이라는 게 보여요.

  • Skills 4.6k (0.5%) — 스킬 메타데이터(이름·설명)만 올라가 있음. 본문은 아래에서 다룰 표지 비유가 정확히 여기 보임
  • System tools 12.9k (1.3%) — 사용 가능한 도구의 사용법
  • Messages 297.6k (29.8%) — 가장 많은 자리. 사용자랑 주고받은 모든 대화
  • Autocompact buffer 33k압축 예정 자리. 책상이 꽉 차기 전에 압축할 영역 미리 잡아둠 (3편 뒤에 나올 압축 개념)
  • Free space 637k (63.7%) — 아직 빈 자리
💡 의외의 사실
시스템 프롬프트(9.2k) + 시스템 도구(12.9k) + 메모리(5.8k) + 스킬(4.6k) = 32.5k. 이게 *책상에 미리 박혀 있는 기본 셋업*. 사용자가 한 마디 하기 전에 이미 책상의 3.3%가 차 있어요.

책상 위에 올라가는 것

[책상 = 컨텍스트 윈도우 1M 토큰]
├─ 시스템 프롬프트 (모델 정체성·기본 행동)
├─ 도구 정의 (사용 가능한 함수들)
├─ 스킬 메타데이터 (이름·설명만)
├─ 이전 대화 (User ↔ Assistant 주고받은 메시지)
├─ 새 사용자 메시지
└─ 모델이 만들 답 (출력 토큰까지 윈도우에 포함)

모델이 만드는 답도 윈도우에 들어가요. 즉 입력 99만 토큰 + 출력 1만 토큰 = 100만으로 꽉 참.

책상이 꽉 차면? — 누가 자르는가

제가 “가장 오래된 토큰부터 잘린다”고 잡으셨는데, 정확히는 다음과 같아요.

LLM 자체는 자르지 않아요. 한도 넘기면 에러로 거부해요.

프롬프트 + 시스템 + 이전 대화 + 도구 = 1,000,001 토큰 던짐
       ↓
API 응답: 400 Bad Request
"context_length_exceeded: max 1000000"

자동으로 안 잘려요. 자르는 일은 그 위의 앱이 해요.

환경 책상 꽉 찰 때 동작
API 직접 호출 에러 반환. 개발자가 미리 줄여 보내야 함
ChatGPT 일반 화면 옛 대화부터 잘라서 보냄 (자동 truncation, 압축 없음)
Claude Code·Cursor 압축 후 보냄 (요약으로 옛 대화 압축)

제가 잡으신 거 정확:
“GPT 일반 화면에서 압축이 없어서 잘리고 느려진다” — 맞음. 단순 자르기.
“개발 모드에서는 압축 자동, 압축 후 정확도 떨어진다” — 정확. 압축은 요약이라 정보 손실 발생.

컨텍스트가 길어지면 답변 품질은?

제가 정확히 잡으신 거 하나 더:

“컨텍스트가 5만일 때와 90만일 때의 LLM의 답변은 그래도 떨어지지만 그 감소 기울기는 완만하다.”

이게 “Lost in the Middle” 현상으로 알려져 있어요. 1차 자료 표현 그대로:
– 책상이 클수록 모델이 중간에 있는 정보를 까먹기 쉬움
– 시작과 끝은 잘 기억하는데 중간은 약함
– 90만 토큰 던지면 어딘가 빠짐 가능성 늘어남

근데 말 그대로 기울기는 완만. 5만에선 거의 완벽, 90만에선 살짝 떨어짐. 완전히 무용지물이 되는 건 아님.

KV 캐시 vs 책상

질문 그대로:

“KV 캐시는 추론시에 중복된 내용을 출력하지 않고 비용을 효율화하는 비용에 관점을 맞춘 것이고 책상의 크기는 맥락 유지를 위해서 즉 답변 품질 유지를 위한 기능으로 생각한다.”

거의 정확하지만 살짝 보정 필요. 둘이 같은 시스템의 다른 측면이에요.

컨텍스트 윈도우 (책상) KV 캐시
무엇 모델이 처리 가능한 최대 토큰 수 (한도) 그 토큰들의 K, V를 저장한 GPU 메모리
목적 입력 한계를 정함 재계산 피해 속도 향상
단위 토큰 수 (1M, 200K) 바이트 (GB)

책상은 한도, KV 캐시는 그 한도 안의 토큰들을 GPU에 보관하는 실제 메모리 공간. 책상이 1M이면 KV 캐시도 그 1M 토큰의 K, V를 다 들고 있어야 함. 그래서 컨텍스트가 길어지면 KV 캐시 메모리가 비례해서 커지고, 그게 추론 비용의 큰 부분.

비용 — 예측 검증

제가 “10만과 100만의 입력 비용은 정확히 10배”라고 하셨는데:

답: 거의 맞지만 살짝 다름.

  • API 가격 정책: 입력 토큰당 가격은 고정 (예: $3/1M tokens). 그래서 가격은 선형. 정확.
  • 실제 GPU 비용: Attention의 연산량이 토큰 수에 제곱에 가까움. 100만은 10만의 100배 연산량. 그래서 OpenAI/Anthropic은 내부적으로 100만 토큰을 더 비싸게 처리하고 있어요. 사용자에게는 선형으로 청구.

회사들이 제곱 비용을 선형 가격으로 부담하는 셈이에요. 그래서 1M 컨텍스트를 공식 지원하기 시작한 모델이 늘어나는 데 시간이 걸린 거. 인프라가 따라잡아야 해서.


시스템 프롬프트 — 책상 위 가장 첫 자리에 박힌 것

책상에 올라가는 것 중 가장 먼저 박히는 게 시스템 프롬프트예요.

이게 정확히 뭐냐. 모델이 어떤 정체성·행동·제약을 가져야 하는지 사용자 메시지보다 먼저 박아놓는 텍스트예요.

[시스템 프롬프트 예시]
"당신은 Claude입니다. Anthropic이 만든 AI 어시스턴트.
 사용자에게 도움이 되도록 답하세요.
 한국어 질문에는 한국어로 답하세요.
 모르는 건 모른다고 말하세요.
 ..."

이런 식으로 모델 정체성부터 기초 행동 규칙까지 시스템 프롬프트에 들어가요.

환경별 차이

환경 시스템 프롬프트
API 직접 호출 개발자가 자유롭게 작성
ChatGPT/Claude.ai 구독 회사가 박아둔 것. 사용자는 볼 수도 없음
로컬 모델 (Ollama, LM Studio) 사용자/개발자가 자유롭게 작성

제가 잡으신 거 정확:
“API형이면 개발자가 작성 가능, 구독제이면 사용자가 볼 수도 없고 기업에서 이미 박아놓은 게 있다” — 맞음
“당신은 claude ~~ 모델입니다부터 누구인지부터 엄청 기초적인 내용부터 시작한다” — 맞음

시스템 프롬프트가 사용자 메시지보다 영향력이 강한 이유

같은 토큰열인데 왜 시스템 프롬프트가 더 강한가?

답: 학습 단계에서 그렇게 배웠기 때문이에요.

학습 데이터에 “system: ~~ user: ~~ assistant: ~~” 같은 구조가 어마어마하게 많이 들어가 있었고, 모델이 거기서 system 영역의 지시를 따르는 패턴을 배움. 즉 시스템 프롬프트의 권위는 학습으로 박힌 행동 양식이지 기술적으로 다른 영역이 아니에요.

그래서 사용자가 시스템 프롬프트를 덮어쓰려고 시도하는 게 prompt injection. 모델이 학습에서 system을 우선시하도록 배웠지만, 영리한 사용자 메시지로 그걸 흔들 수 있어요.


스킬 메타데이터 — 표지 없는 도서관에 표지 붙이기

이건 제가 직접 만드신 비유예요. 그대로 박아둘게요.

책에 표지가 없으면 LLM이 모든 책 내용을 다 읽어야 해요. 그게 컨텍스트 증폭. Anthropic이 스킬 개념을 도입해서 책에 표지(이름 + description)를 붙였어요. 시스템 프롬프트에는 표지(메타데이터)만 들어가니까 컨텍스트 절약. 단, LLM이 표지 보고 “이 책 필요” 라고 판단해야 책을 펼쳐요. 잘못 판단하면 정확도 떨어짐.

이게 컨텍스트 절약 vs 정확도 손실의 트레이드오프예요.

📚 표지 없는 도서관
시스템 프롬프트에 책 50권의 전문이 다 박혀 있음.

책1 전문 (1만 토큰) +
책2 전문 (1만 토큰) +
… × 50권 = 50만 토큰

→ 책상이 그 자체로 가득 참
→ 사용자 메시지 들어갈 자리 없음
→ 컨텍스트 폭증. API 비용 폭증.

📖 표지 붙은 도서관
시스템 프롬프트에 책 50권의 표지만 박힘.

책1 표지 (50 토큰) +
책2 표지 (50 토큰) +
… × 50권 = 2,500 토큰

→ 책상의 0.25%만 차지
→ LLM이 “이 책 필요” 판단 시에만 펼침
→ 컨텍스트 200배 절약. 비용 절약.

⚠️ 함정
LLM이 표지 보고 “이 책 필요 없어” 라고 잘못 판단하면 그 스킬은 아예 안 펼쳐짐. 답변 정확도가 그만큼 떨어져요. 컨텍스트 절약 vs 답변 품질 — 영원한 트레이드오프.

구조 정리

[스킬 없는 시절]
시스템 프롬프트:
  - 책1 전문 (1만 토큰)
  - 책2 전문 (1만 토큰)
  - 책3 전문 (1만 토큰)
  - ...
  → 책상 위에 책 50권 다 올려놓음 = 컨텍스트 폭증

[스킬 도입 후]
시스템 프롬프트:
  - 책1 표지 (50 토큰): "스킬명: blog-writer / 설명: 블로그 글 쓰기"
  - 책2 표지 (50 토큰): "스킬명: pixel-office / 설명: 폴더 구조 시각화"
  - ... × 50권
  → 책상에 표지만 = 50 × 50 = 2500 토큰

LLM이 표지 보고 "어, 지금 blog-writer 필요" 판단:
  → 그 책만 펼쳐서 본문 읽음
  → 나머지 49권은 안 읽음

트레이드오프

[비용 관점]
스킬 사용: 컨텍스트 작음 → API 비용 절약 → 구독료 효율
스킬 안 씀: 컨텍스트 큼 → API 비용 증가

[답변 품질 관점]
스킬 사용: LLM이 "이 책 필요" 판단을 잘못할 위험
스킬 안 씀: 모든 책이 시스템 프롬프트에 박혀 있어서 항상 참고 가능 → 답변 품질 유리

연구 결과로도 컨텍스트에 모든 정보를 박아두면 정확도가 더 높다는 게 많아요. 다만 그게 비용을 무시한 비교. 비용을 같이 보면 스킬이 합리적.

컨텍스트가 길어지면 답변 품질은?

제가 잡은 마지막 포인트:

“컨텍스트가 5만일 때와 90만일 때의 LLM의 답변은 그래도 떨어지지만 그 감소 기울기는 완만하다. 안 떨어지는 것은 아니다.”

정확. 떨어지긴 함. 안 떨어지는 게 아님. 다만 곡선이 완만해서, 90만 컨텍스트에서도 충분히 쓸만함. 90만 컨텍스트가 5만의 18배인 걸 생각하면 답변 품질 감소가 그 만큼은 아님.

이게 1M 컨텍스트 모델이 상품으로 의미 있는 이유. 진짜로 18배 더 많은 정보를 한 번에 처리할 수 있어요. 답변 품질이 2배 떨어지는 건 아닌 완만한 감소.

도구(Tool)도 같은 구조

스킬과 비슷한 게 도구(Tool, Function calling). 사용 가능한 함수의 이름·인수·설명만 시스템 프롬프트에 박혀 있고, 모델이 “이 도구 필요” 라고 판단하면 그 함수를 호출하는 JSON을 출력.

[도구 정의 (시스템 프롬프트에 박힘)]
{
  "name": "search_web",
  "description": "웹 검색을 수행합니다",
  "parameters": {
    "query": "검색어"
  }
}

스킬과 같은 표지 없는 도서관의 다른 형태. 도구 본체가 시스템 프롬프트에 박히는 게 아니라 사용법만 박힘.


사용자가 던진 텍스트는 어떻게 토큰이 되나

지금까지 “토큰”을 자연스럽게 써왔는데, 언제·어디서· 누가 그걸 만드는지를 짚고 가야 해요.

답: OpenAI/Anthropic 서버에서, 입력받자마자, BPE 토크나이저로.

흐름:

[1] 사용자: "오늘 날씨 어때?" 텍스트 입력
[2] ChatGPT 화면(클라이언트)이 그대로 API에 던짐 — 토큰화 X, 텍스트 그대로
[3] OpenAI 서버 도착
[4] 서버에서 BPE 토크나이저로 토큰화
    "오늘 날씨 어때?" → [101, 234, 567, 89]
[5] 그 토큰들을 GPU에 올려서 추론 시작

토큰화는 모델 자체가 하는 게 아니에요. 모델 옆에 붙어 있는 토크나이저(BPE 어휘집)가 해요. 모델이랑 별도 파일이지만 같이 배포돼요.

제가 OpenAI Playground 같은 데서 토큰 수 미리 보는 도구를 본 적 있으실 거예요. 그건 클라이언트 측에서 같은 BPE 토크나이저를 돌려서 미리 보여주는 거. 실제 추론 토큰화는 서버에서 다시 해요.

토크나이저 공개 정책 — 회사마다 다름

회사 토크나이저 어휘집
OpenAI 공개 (tiktoken 라이브러리, GitHub 오픈소스)
Anthropic (Claude) 비공개 (엔드포인트로만 토큰 수 알 수 있음)
Google (Gemini) 부분 공개
Meta (Llama) 공개 (오픈소스 모델이라 토크나이저도 공개)

OpenAI는 어휘집 자체를 공개해요. pip install tiktoken으로 누구나 다운받아서 실제 토큰이 어떻게 잘리는지 확인 가능. 왜 공개? — 개발자가 토큰 수 미리 계산해서 비용 견적 내야 하니까.

Anthropic은 비공개. 토큰 수 알고 싶으면 Anthropic API에 “이 텍스트 토큰 몇 개?” 물어보는 엔드포인트로만 가능. 토큰 수만 알려주고 어떻게 잘렸는지는 알려주지 않음.


LLM은 띄어쓰기를 어떻게 인식하나

자주 헷갈리는 지점. 답: 띄어쓰기는 LLM에게 토큰의 일부예요.

영어 BPE 예시:

" hello"  → 1토큰 (앞 띄어쓰기 포함)
"hello"   → 1토큰 (다른 토큰)

띄어쓰기가 글자처럼 토큰에 박혀 들어가요. 즉 모델은 띄어쓰기를 별도로 인식하는 게 아니라, 띄어쓰기를 글자 데이터의 일부로 봐요.

띄어쓰기 안 한 텍스트의 답변 품질은:

  • 영어: 띄어쓰기 없으면 답 품질 심하게 떨어짐. 영어는 띄어쓰기가 단어 경계의 핵심.
  • 한국어: 살짝 떨어지지만 영어보다 덜함. 한국어는 원래 띄어쓰기가 모호한 언어라 학습 데이터에 띄어쓰기 안 된 한국어가 일정 비율 들어가 있음.
  • 중국어·일본어: 거의 영향 없음. 원래 띄어쓰기 안 쓰는 언어.

이론적으로도 실제로도 띄어쓰기 안 하면 품질 떨어짐. 다만 정도가 언어마다 다름. 완전히 망가지진 않음.


md vs PDF — 같은 내용을 어느 형식으로 줘야 LLM이 잘 읽나

여기서 좋은 의문이 하나 더 떠올라요. “같은 내용이라도 md 파일 로 주면 LLM이 더 잘 읽는다는데, md는 AI를 위해 만들어진 거야? 아니면 우연히 AI가 잘 읽는 형식이 된 거야? PDF와 뭐가 다른 거야?”

답부터 — md(Markdown)는 AI를 위해 만들어진 게 아니에요. 우연히 AI가 가장 편하게 읽는 형식이 됐어요.

md의 탄생 — AI 무관

Markdown은 2004년 John Gruber와 Aaron Swartz가 만들었어요. 목표는 단순했어요. 사람이 일반 텍스트로 글을 빠르게 쓰면, 그게 자동으로 HTML로 변환되어 웹에 올라가게 하는 것. 블로거·개발자가 글 쓰는 속도를 안 잃으면서 구조 있는 글을 쓰게 하려고 만든 거예요. 이때 LLM 같은 건 존재하지도 않았어요.

근데 2020년대에 LLM 시대가 오자 — md가 우연히 AI에게 가장 친숙한 형식이 돼버렸어요. 세 가지 이유로.

이유 1 — 순수 텍스트라 토큰화가 깔끔

md는 바이너리 인코딩·압축·이미지 임베드·서체 메타데이터 같은 게 없어요. 파일을 그대로 열면 텍스트 그 자체. 그래서 BPE 토크나이저가 추가 처리 없이 곧장 토큰으로 자를 수 있어요.

PDF는 그 반대예요. PDF는 본질적으로 시각적 레이아웃 우선 형식이에요. 텍스트가 위치 좌표에 박혀 있고, 한 줄도 여러 텍스트 블록으로 쪼개져요. 텍스트 추출만 해도 순서가 뒤섞이거나 표가 깨지는 일이 흔해요.

이유 2 — 구조가 평문 안에 박혀 있음

md의 진짜 강점은 문서 구조를 텍스트 그 자체에 박는다는 거예요.

## 제목 (큰 헤더)
### 부제 (작은 헤더)
- 리스트 항목
- **강조**된 글자
| 표 | 도 |
| 가능 |

##큰 헤더, **강조, -리스트. 모델이 이런 마커를 어마어마하게 많이 학습 데이터에서 봤어요. 그래서 마커가 들어오면 “여긴 헤더야, 여긴 강조야” 를 자동으로 인식해요.

PDF에서 같은 구조를 추출하면 그냥 평문 으로 떨어져요. 모델이 “이 줄이 헤더인지 본문인지” 구분 불가. 1차 자료 표현 그대로 — “평문은 정보를 평평하게 만들어 모델이 관계를 파악하기 어렵게 한다”.

이유 3 — 학습 데이터에서 압도적

GitHub README, 기술 블로그, Stack Overflow, 위키 일부, 문서 사이트 — 인터넷 텍스트의 큰 비중이 이미 md예요. LLM이 학습할 때 md를 수십억 번 봤어요. 모델이 md를 모국어처럼 이해하는 이유.

PDF는 학습 데이터에 상대적으로 적게 들어가요 (저작권·추출 어려움 때문). 그리고 PDF에서 텍스트 추출한 결과가 지저분하니 모델이 PDF 표기를 거의 못 익혀요.

실제 성능 차이 (1차 자료)

같은 내용을 md로 깨끗하게 정리 vs PDF에서 거칠게 추출 비교 시:

  • RAG 검색 정확도: md가 PDF 추출 평문 대비 최대 35% 향상
  • 토큰 사용량: md가 20~30% 적음 (불필요한 마크업 없음)

제가 ChatGPT/Claude에 정보 줄 때 PDF를 그대로 던지지 말고 md로 변환해서 던지는답변 품질·비용 양쪽 다 유리한 이유.

정리

md PDF
만들어진 이유 사람이 글 쓰기 편하라고 (2004년, AI 무관) 시각적 인쇄·문서 보존 (1993년)
순수 텍스트? 아니요 (바이너리 + 좌표)
구조가 평문에 박힘? 예 (##, **, -) 아니요 (시각 레이아웃)
학습 데이터 비중 매우 큼 작음
LLM 친화도 ⭐⭐⭐⭐⭐ ⭐⭐

md는 AI 친화적인 게 목표가 아니라, 결과였어요. 사람이 글 쓰기 편하게 만든 형식이 우연히 AI도 가장 잘 읽는 형식이 된 — 이게 현재 LLM 시대의 흥미로운 우연 중 하나예요.

(같은 이유로 제가 Cursor·Claude Code 같은 개발자 도구에서 코드 + 문서를 같이 던질 때 md가 표준이에요. AI가 가장 정확히 읽기 때문.)


출력은 어떻게 나오나 — JSON과 SSE

제가 던진 의문 그대로. “출력이 LLM에서 JSON으로 오는 걸로 아는데 왜 JSON인지.”

먼저 정확히 짚을 게. 출력 자체가 JSON은 아니에요. 토큰을 JSON 안에 담아서 보내는 거.

JSON이 뭐예요?

JSON = JavaScript Object Notation. 데이터를 텍스트로 표현하는 표준 형식.

이름은 JavaScript에서 따왔지만 모든 프로그래밍 언어가 다 읽을 수 있어요.

[JSON 예시]
{
  "이름": "저",
  "나이": 30,
  "취미": ["블로그", "AI", "Pixel Office"]
}

규칙:
{ } 안에 키: 값
[ ] 안에 목록
– 문자열은 "따옴표"
– 숫자는 그대로

언제 만들어졌나: 2001년. AI랑 무관. 원래는 웹 브라우저와 서버 사이 데이터 주고받기 위해 만들어졌어요. 그게 표준이 되면서 모든 인터넷 서비스가 JSON을 씀.

LLM API가 나왔을 때 기존 JSON을 그대로 채택. AI 때문에 새로 만든 게 아님.

LLM 출력이 JSON으로 오는 이유

GPU 안에서:

모델이 토큰 1개 만듦 → 토큰 ID 한 개 (예: 234)
                    → 어휘집 보고 텍스트로 변환 ("좋")
                    → 이걸 사용자에게 보내야 함

서버에서 사용자로 보낼 때 토큰 1개를 그냥 평문으로 보내면 정보 부족:
– 첫 토큰인지 마지막 토큰인지?
– 누적 토큰 수는?
– 에러는 없는지?
– 모델 이름은?

메타정보랑 같이 묶어서 보내야 함 → JSON으로 포장.

실제 OpenAI 응답 예시:

data: {"id":"chatcmpl-123","object":"chat.completion.chunk",
       "created":1234,"model":"gpt-4",
       "choices":[{"delta":{"content":"좋"},"index":0}]}

data: {"id":"chatcmpl-123","choices":[{"delta":{"content":"다"}}]}

data: [DONE]

토큰 한 개(“좋”, “다”)가 JSON 안에 들어가서 옴. JSON은 포장지, 안에 든 게 진짜 토큰.

JSON이 의무는 아님

다른 형식도 가능:
XML: 태그 형식. 옛날 표준. 장황함
Protocol Buffers (Google): 더 빠르고 작음. Google 내부에서 씀
MessagePack: JSON 압축형

근데 LLM API는 다 JSON. 이유:
– 모든 언어가 읽음 (Python, JS, Go, Rust)
– 사람도 눈으로 읽음 (디버깅 편함)
– 표준이라서 모든 도구가 지원
살짝 비효율이지만 충분히 빠름

즉 “가장 효율적”은 아니에요. “가장 보편적”이라서 씀. 효율을 따지면 Protocol Buffers가 더 빠르지만, 그 대신 호환성을 잃음.


Streaming — ChatGPT 화면에 다다닥 뜨는 메커니즘

왜 토큰 단위로 보내나? ChatGPT 화면에 답이 다다닥 뜨는 그 효과를 위해서.

만약 답 전체가 다 만들어진 뒤에 한 번에 보내면:
– 사용자가 1초~10초씩 기다림
– “안 멈췄나?” 의심
– 답이 길수록 더 답답함

토큰 단위로 보내면:
– 첫 토큰 도착 시점 = 화면에 첫 글자 뜸
– 다음 토큰 도착 = 화면에 다음 글자 추가
– → 사용자가 답이 만들어지는 과정을 실시간으로 봄

이걸 streaming이라고 해요. 기술적으로는 SSE (Server-Sent Events) 라는 표준 프로토콜로 보내요. HTTP 연결을 한 번 열어두고 서버가 일방적으로 토큰을 계속 흘려보내는 방식.

사용자 → 서버: "오늘 날씨 어때?" (요청 1번)
서버 → 사용자: "좋" (실시간)
서버 → 사용자: "다" (실시간)
서버 → 사용자: "." (실시간)
서버 → 사용자: [DONE]

제가 ChatGPT 답이 글자별로 다다닥 뜨는 그 시각 효과 = autoregressive로 만들어진 토큰을 SSE로 JSON 포장해서 흘려보내는 결과. 두 단계가 합쳐진 결과물.

한꺼번에 보내는 게 경제적으로 더 합리적인가

질문 그대로:

“토큰 단위로 보내는 것이 사용자가 기다리지 않아도 돼서 만족도를 위한 거라면 한꺼번에 보내는 것이 경제적으로는 합리한지.”

답: 합리적인 게 아니라 같아요. 경제적으로 차이 거의 없음.

  • 토큰 단위로 보내든, 한꺼번에 보내든 생성 비용은 같음 (어차피 한 토큰씩 만들어짐)
  • 네트워크 비용도 거의 같음 (총 데이터양 비슷)
  • 차이는 사용자가 첫 글자 보는 속도

그래서 모든 LLM 회사가 streaming을 기본으로 채택. 비용 거의 같은데 사용자 만족도 차이 큼.

다만 한 가지 작은 차이:
Streaming: HTTP 연결을 답변 끝까지 열어둠 → 서버 동시 연결 수 한계
한꺼번에: 답 다 만든 뒤 1번만 보냄 → 서버 부담 적음

대규모 서비스에서는 streaming의 동시 연결 수가 비용이 됨. 근데 워낙 사용자 만족도 차이가 커서 동시 연결 비용을 감수하고 streaming 씀. ChatGPT처럼 수억 명이 동시에 쓰는 서비스는 이 동시 연결 관리가 큰 일이에요. OpenAI가 GPU만큼이나 네트워크 인프라에 투자하는 이유.


여기까지가 3편 — 그리고 다음 글의 분기점

여기서 3편이 닫혀요. 지금까지 풀린 막힘 24개를 한 번에 짚으면:

  1. 추론 vs 학습 / 2. 한 글자씩 = 32층 매번 통과 (autoregressive) / 3. KV 캐시 + Q·K·V 미리보기 / 4. Prefill vs Decode (첫 글자 느린 이유) / 5. 가중치 안 변해도 GPU 필요한 이유 / 6. VRAM이 뭐고 왜 통째로 올라가야 하나 / 7. 메모리 대역폭·HBM / 8. 1바이트=8비트 역사 / 9. 모델 크기 계산 + 양자화 / 10. A100/H100/H200 차이 + 405B를 GPU 8대에 띄우는 법 / 11. 역전파 거꾸로 가는 이유 / 12. Softmax (자르지 않고 변환, 합 1.0) / 13. Sampling = 분포대로 뽑기 / 14. Temperature = 인간다운 답변 노브 / 15. Top-K·Top-P = 헛소리 방지 / 16. 학습 정답 vs 추론 정답 (95%여도 5%로 다른 토큰) / 17. BPE 어휘집은 학습으로 만든다 / 18. 한글이 토큰 많이 먹는 이유 / 19. 띄어쓰기는 토큰의 일부 / 20. 컨텍스트 윈도우 = 책상 / 21. 자르기는 LLM 아닌 앱이 한다 / 22. 시스템 프롬프트가 강한 이유 / 23. 스킬 메타데이터 = 표지 비유 / 24. 토큰화·JSON·SSE streaming

이게 LLM 추론의 기본 메커니즘 전부예요. 여기까지만 알아도 ChatGPT가 한 글자씩 답하는 그 모든 동작을 완벽하게 머리에 그릴 수 있어요.

근데 이게 2024년까지의 그림이에요. 2024년 9월에 OpenAI가 o1을 발표하면서, 그리고 2026년 4월에 GPT-5.4 Pro가 60년 미해결 Erdős 수학 문제를 80분에 풀어버리면서, 추론의 그림 자체가 한 단계 진화했어요.

다음 글(3.5편)에서 다룰 내용은 이거예요.

여기서부터는 3.5편 영역

  • Reasoning 모델 (o1, o3, GPT-5.4 Pro, Claude Extended Thinking) — 답하기 전에 혼잣말로 한참 생각하고 답하는 새 방식
  • 23×47을 한 번에 왜 못 풀까 — LLM의 곱셈 한계와 토큰화의 관계
  • 계산기를 도구로 부르면 되지 않나? — 에이전트의 정확한 정의
  • 모델 vs 에이전트 — 그 경계가 정확히 어디인가
  • 사고 토큰의 기준 — Web 검색·Fetch는 어떻게 청구되나
  • Erdős #1196 사건 — 진짜 수학적 추론인가, 아니면 조합 시도가 우연히 맞은 건가
  • 창의성이란 무엇인가 — 변형적 창의성 9개 사례 (코페르니쿠스·다윈·칸트·쿤·피카소 등)
  • AI가 인간의 창의력을 넘을 수 있나 — 제가 직접 던진 큰 질문

제가 학습하면서 던진 진짜 어려운 질문들이 거기 다 박혀 있어요. 3편이 기본기라면 3.5편은 2026년 LLM의 가장 뜨거운 자리.

3.5편 읽으러 가기: 추론의 진화 — Reasoning, 에이전트, 그리고 AI가 진짜 추론을 하는가


핵심 정리 — ChatGPT 작동 원리 한 줄로

추론 = 학습으로 박힌 80억 가중치 위로 입력이 한 번 통과하면서, 32층 끝의 점수를 Softmax → Temperature → Sampling을 거쳐 한 토큰씩 뽑는 과정. KV 캐시로 이전 토큰 K·V를 재활용하고, VRAM에 가중치를 통째로 올려서 곱셈을 빠르게 하고, 양자화로 큰 모델을 GPU에 욱여넣고, 컨텍스트 윈도우(책상) 위에 시스템 프롬프트·스킬 표지·도구 정의·이전 대화·새 질문이 다 올라가고, 결과는 SSE/JSON으로 한 토큰씩 사용자에게 흘러나간다.

핵심 3가지:

  1. 추론은 한 번 통과 + 토큰 뽑기. 가중치를 바꾸는 단계가 없음. 정답이라는 개념도 없음. KV 캐시로 이전 토큰 재활용 → 첫 글자만 느리고 그 다음은 빠름.

  2. GPU·VRAM·HBM·양자화·컨텍스트 윈도우는 다 같은 문제의 답이다. “어떻게 80억 곱셈을 1초에 30~150번 하면서, 큰 모델을 메모리에 욱여넣고, 긴 입력을 책상에 올리는가.” 회사 전쟁의 본질이 이거예요.

  3. 출력은 SSE/JSON으로 한 토큰씩 흐름. ChatGPT 화면 다다닥 효과의 정체. JSON은 AI 무관 2001년 개념, 지금은 표준이라 채택.


다음 편 예고

3.5편: 추론의 진화 — Reasoning, 에이전트, 그리고 AI가 진짜 추론을 하는가

3편이 2024년까지의 LLM 추론 메커니즘이라면, 3.5편은 2024~2026년의 진화예요. Reasoning 모델·에이전트·도구 호출이 어떻게 LLM의 한계를 늘리고 있는지, 그리고 그 끝에 AI가 진짜 수학을 한 사건이 있어요.

3.5편으로 →

그 이후로는 4편(생성·Generation 깊이) → 5편(Attention) → 6편(Transformer) → 7편(양자화·RAG·Fine-tuning)으로 시리즈가 닫혀요.


자주 묻는 질문

Q. ChatGPT에서 답이 한 글자씩 뜨는 건 연출인가요, 진짜인가요?

진짜예요. autoregressive decoding이라고 부르며, 모델이 한 토큰을 만들면 그걸 SSE 프로토콜로 즉시 사용자에게 흘려보내요. 답을 다 만들어두고 보여주는 게 아니라 *만들어지는 동안* 보내는 거예요.

Q. 가중치가 안 변하는 추론에 왜 GPU가 필요해요?

가중치는 안 변하지만 *입력 × 가중치* 곱셈은 매번 새로 해야 해요. 한 토큰에 약 10억 곱셈, 그걸 1초에 30~150번. CPU로는 너무 느리고 GPU의 병렬 곱셈 능력이 필요해요.

Q. 컨텍스트 윈도우가 꽉 차면 LLM이 옛 대화부터 자르나요?

아니요. LLM 자체는 한도 넘기면 *에러로 거부*해요. 자르기는 ChatGPT 같은 앱이 해요. 개발자 도구(Cursor, Claude Code)는 자르기 대신 *압축*으로 처리하는데, 압축 후엔 정확도가 떨어져요.

Q. 한국어가 영어보다 토큰을 많이 먹는다는데, 그래서 비용이 더 들어요?

네. UTF-8에서 한글 1글자가 3바이트라서 BPE 시작 시 한 글자가 3토큰으로 잡혀요. 학습 데이터의 영어 비중이 압도적이라 BPE가 한글을 통째로 어휘집에 등록 안 함. 결과적으로 같은 의미를 한국어로 쓰면 영어 대비 2~3배 토큰. OpenAI API 비용도 그만큼 더 듦.

Q. Anthropic은 토크나이저를 왜 비공개해요?

OpenAI는 tiktoken 라이브러리를 공개해서 누구나 토큰 수 미리 계산 가능하지만, Anthropic은 비공개. 토큰 수 알고 싶으면 별도 엔드포인트로만 가능해요. 회사마다 정책이 다른 부분이에요.

Q. 405B 모델은 왜 H100 8대가 표준이에요?

405B를 8bit 양자화하면 405GB. 가중치만 보면 H100 80GB 6대로도 가능하지만, 실제 서빙은 KV 캐시(사용자별)·중간 계산·여유까지 포함해서 약 525~585GB 필요. 그래서 NVIDIA가 H100 8대(640GB)를 권장.


소스 / 더 읽을거리

  • HuggingFace, “KV Caching Explained” — 블로그
  • NVIDIA, “Mastering LLM Techniques: Inference Optimization” — 블로그
  • Wikipedia, “High Bandwidth Memory” — Wikipedia
  • Wikipedia, “Byte” (1바이트=8비트의 역사) — Wikipedia
  • Wikipedia, “JSON” — Wikipedia
  • arXiv, “Tokenization counts” (BPE와 한글 토큰 이슈) — 논문
  • Simon Willison, “How streaming LLM APIs work” — 블로그
  • GitHub, “openai/tiktoken” (OpenAI 공개 토크나이저) — GitHub

저자: VibeCoding Tailor (테이라)
shuntailor.net 운영. 고려대 공대생 · Lovable 공식 앰버서더. 고려대 캠퍼스타운 창업 경진대회 우수상으로 교내 창업사무실에 입주, 지금은 개발에 집중 중. 내가 IT·AI를 공부하며 막힌 지점은 모두가 막힐 지점이라는 가정으로, 그 막힘을 하나씩 깊이 파헤쳐 「쉽깊잼(쉽고·깊고·재미있게)」을 실현한다. 이 블로그는 AI 시대의 표준을 만들기 위해 시작한 미디어다.

바이브코딩 태일러
바이브코딩 태일러
AI의 작동 원리와 비즈니스 적용을 일본어·한국어로 기록합니다. 매주 월요일 뉴스레터 발행 중.
뉴스레터 구독하기 →

댓글

JAKO