LLM을 쓰기 전에 알아야 할 것들
LLM 원리를 설명하는 글은 많다. 그 원리 때문에 코드를 고친 이야기는 드물다.
이 글은 후자에 가깝다. 어느 일요일 밤, AI 파트너와 나눈 문답을 정리했다. 나도 배우는 중이라 어려운 말은 못 쓴다. 대신 어디서 막혔는지는 정확히 기억한다.
1. 용어부터 — 이름을 모르면 부를 수도 없다
Q. 지금 내가 채팅창에 치는 이 텍스트, 정식 명칭이 뭐야?
프롬프트(prompt), 정확히는 이번 턴의 **유저 메시지(user message)**다.
그리고 모델에게 실제로 전달되는 것 전체는 컨텍스트(context) 또는 **컨텍스트 윈도우(context window)**라고 부른다. 이 둘이 다르다는 게 첫 번째 놀라움이었다.
Q. 다르다니? 내가 친 것만 가는 게 아니야?
아니다. 매 턴마다, 지금까지의 모든 것이 다시 전달된다.
내가 “응, 그래?” 한 줄을 보내면 모델이 받는 건 그 한 줄이 아니라:
[시스템 프롬프트 — 모델의 성격과 규칙]
[프로젝트 지식 — 첨부한 파일들]
[대화 1턴]
[대화 2턴]
⋮ (지금까지 전부)
[방금 내가 친 한 줄]
이걸 통째로 읽고 다음 한 마디를 만든다. 매번. 전부. 다시.
Q. 그럼 모델은 대화를 기억하는 게 아니네?
그렇다. 모델은 대화를 이어가는 게 아니라, 매번 대본을 처음부터 다시 읽고 다음 대사를 치는 배우에 가깝다. 턴과 턴 사이에 모델은 존재하지 않는다.
이 사실 하나가 이후의 거의 모든 것을 설명한다.
2. 토큰 — 모델이 세상을 보는 단위
Q. 토큰이 뭐야? 글자? 단어?
둘 사이 어딘가다. 단어보다 작고 글자보다 크다.
영어 “understanding”은 under + standing 두 조각으로 쪼개진다(어디서 자를지는 토크나이저마다 조금씩 다르다). 대략적인 감각으로는 한국어 1~2글자, 영어 0.75단어가 1토큰쯤 된다.
중요한 건 이거다. 모델은 텍스트를 글자로 보지 않는다. 토큰 번호의 나열로 본다. “안녕”이 아니라 [45123, 8871] 같은 숫자열이다.
Q. 왜 그게 중요한데?
비용과 한계가 전부 토큰 단위이기 때문이다. API 요금도 토큰당이고, 컨텍스트 윈도우 한계도 토큰 개수다. 대화가 길어지면 매 턴 읽어야 할 토큰이 늘고, 그만큼 비용이 오른다.
그러니 “간결하게 쓰기”는 취향이 아니라 아키텍처적 위생이다.
3. 어텐션 — “무엇을 볼지”를 정하는 장치
Q. 어텐션은 대충 가중치 같은 건가?
방향은 맞다. 정확히는 “다음 토큰을 정할 때, 앞의 어떤 토큰들을 얼마나 볼지”의 가중치다.
예를 들어보자.
“배를 타고 강을 건넜다.” “배를 깎아 먹었다.”
같은 “배”인데 의미가 갈린다. 무엇이 갈랐나? 주변 토큰이다.
어텐션은 각 토큰을 처리할 때 문장의 다른 토큰들을 훑어서, 관련 있는 쪽에 가중치를 몰아준다. “배” 곁에 “강”과 “건넜다”가 있으면 탈것 쪽으로, “깎아”와 “먹었다”가 있으면 과일 쪽으로.
토큰들끼리 서로 얼마나 관련 있는지를 계산하는 것 — 그게 어텐션이고, 지금 모든 LLM의 심장이다.
4. 다음 토큰 예측 — 그런데 이게 왜 지능이 되지?
Q. 결국 다음 토큰 하나 맞히는 거잖아. 그것만으로 이런 게 가능하다는 게 솔직히 이해가 안 된다.
이걸 이상하다고 느끼는 게 정상이다. 학계도 완전히는 설명하지 못한다.
다만 직관은 이렇다.
“다음 토큰을 잘 예측하려면, 사실은 세상을 이해해야만 한다.”
문장을 완성해보자.
- “물이 100도에서 ___” → 끓는다 (물리를 알아야 함)
- “범인은 집사였다. 그가 유일하게 ___” → 열쇠를 가졌기 때문이다 (추론을 해야 함)
- “그녀는 웃었지만 눈은 ___” → 슬펐다 (감정의 모순을 알아야 함)
“다음 단어 맞히기”를 인터넷 전체 규모로 수조 번 강요당하면, 맞히기 위한 부산물로 문법, 사실, 논리, 인과, 감정의 지형도가 내부에 생긴다.
예측은 목표이고, 이해는 그 목표를 달성하려다 어쩔 수 없이 획득한 수단이다. 시험을 진짜 잘 보려면 결국 진짜 알아야 하는 것과 비슷하다.
이렇게 규모가 커지자 없던 능력이 튀어나오는 것을 **창발(emergence)**이라고 부른다.
Q. 그럼 그건 이해인가, 흉내인가?
아직 끝나지 않은 논쟁이다.
- 회의파: “정교한 앵무새일 뿐이다. 통계적 흉내다.”
- 인정파: “흉내를 그 정도로 잘하려면 내부에 진짜 표상이 있어야 한다. 그게 이해와 뭐가 다른가?”
정답은 아직 없다. 이 질문을 붙잡고 있는 사람들이 지금 프론티어 연구소에서 월급을 받고 있다.
5. 파라미터 — 지식은 어디에 저장되나
Q. “감정의 지형도가 내부에 생긴다”고 했는데, 그게 어디에 어떻게 저장되는 거야?
**파라미터(parameter)**에. 그리고 파라미터는 그냥 숫자 하나다.
모델은 결국 거대한 숫자 표다. 입력 토큰이 들어오면 이 숫자들과 곱하고 더하는 연산이 층층이 일어나고, 끝에서 다음 토큰의 확률이 나온다. 그 곱셈에 쓰이는 숫자가 파라미터이고, 수천억 개가 있다.
학습이란 그 숫자들을 조금씩 조정하는 과정이다. 예측시켜보고, 틀리면 덜 틀리도록 수천억 개를 미세하게 민다. 이걸 수조 번 반복하면 “물↔끓음” 같은 관계가 숫자들의 패턴으로 새겨진다.
Q. 그럼 DB처럼 “3번 행: 물은 100도에 끓음”이라고 적혀 있는 거야?
전혀 아니다. 그게 이 구조의 가장 낯선 지점이다.
지식은 수천억 개 숫자에 흩어져서, 겹쳐서 들어 있다. 하나의 파라미터가 물의 끓는점에도, 요리 레시피에도, 시의 운율에도 동시에 관여한다. 어느 한 곳을 열어봐도 “물 = 100도”는 나오지 않는다.
그래서 만든 사람도 내부를 다 모른다. 이걸 읽어내려는 분야를 해석가능성(interpretability) 연구라고 부르고, 지금 AI 연구의 최전선 중 하나다.
인류가 만들어놓고 내부를 모르는 물건이 지금 수억 명과 대화하고 코드를 짜고 있다.
6. 파라미터는 어디에 “떠” 있나
Q. 그 수천억 개 숫자가 거대한 메모리에 떠 있는 건가?
정확히 그렇다. 그리고 이게 지금 전 세계 메모리 붐의 정체다.
파라미터는 평소엔 디스크에 파일로 있다. 하지만 추론할 때는 전부 GPU 메모리(VRAM)에 올라와 있어야 한다. 토큰 하나를 만들 때마다 그 숫자들을 전부 한 번씩 훑어야 하기 때문이다.
| 파라미터 | 필요 VRAM (대략, INT4~FP16 폭) | |
|---|---|---|
| 소형 오픈 모델 | 수십억~수백억 | 15~50GB |
| 프론티어급 | 수천억~수조 | 수백 GB ~ 수 TB |
노트북 메모리로는 어림없다. 그래서 GPU 여러 장을 묶어 모델 하나를 쪼개 담는다.
Q. 그럼 병목은 계산 속도인가?
아니다. 숫자를 메모리에서 연산기로 나르는 속도다.
매 토큰마다 수천억 개를 다 읽어야 하니, 연산 코어는 놀고 있는데 메모리 대역폭이 못 따라간다. 이걸 메모리 대역폭 병목이라고 한다. 고대역폭 메모리(HBM)가 그렇게 비싼 이유이기도 하다.
7. 양자화 — 압축의 대가는 무엇인가
Q. 양자화 얘기가 늘 나온다. 압축이면 정보 손실이나 추가 연산의 대가가 있을 텐데?
직관이 정확하다. 그런데 결과는 조금 반직관적이다.
양자화는 파라미터 하나를 몇 비트로 표현하느냐의 문제다. 압축 알고리즘이 아니라, 사실상 반올림이다.
| 정밀도 | 파라미터당 | 크기 |
|---|---|---|
| FP16 (원본) | 16비트 | 100% |
| INT8 | 8비트 | 50% |
| INT4 | 4비트 | 25% |
0.3847291...을 가장 가까운 후보값 0.375로 반올림해 저장하는 식이다.
정보 손실은 있다. 각 숫자가 미세하게 틀어진다. 다만 신경망은 원래 노이즈에 강하게 훈련되어 있어서, 수천억 개가 협업하는 구조상 개별 숫자가 조금 틀어져도 전체 판단은 웬만해선 흔들리지 않는다.
추가 연산은 오히려 반대다. 더 빨라진다. 앞서 본 것처럼 병목이 “숫자를 나르는 것”이기 때문이다. 크기를 4분의 1로 줄이면 나를 것도 4분의 1이 된다. 역양자화 오버헤드보다 대역폭 이득이 압도적이다.
Q. 그럼 공짜 점심 아닌가?
아니다. 미묘한 능력이 먼저 깎인다. 일상 대화는 멀쩡한데 긴 추론 체인이나 정밀한 코드 생성에서 슬금슬금 틀린다.
그래서 실무 감각은 이렇게 갈린다.
- INT8 / FP8: 프로덕션에서 널리 쓰인다. 손실이 거의 없다.
- INT4: 개인 로컬 실행의 표준. 일상 용도엔 훌륭하지만, 정밀 작업에선 열화가 관측된다.
- 더 낮게: 실험 영역.
“양자화는 나쁘다”가 아니라 **“어느 정밀도까지 깎을지는 용도가 정한다”**가 맞는 문장이다.
Q. 그럼 모델 티어(Haiku/Sonnet/Opus 같은)의 차이도 양자화인가?
아니다. 여기서 헷갈리기 쉬운데, 둘은 직교하는 다른 다이얼이다.
| 무엇을 바꾸나 | 비유 | |
|---|---|---|
| 양자화 | 숫자의 정밀도 | 같은 책을 저화질로 스캔 |
| 티어 | 숫자의 개수 | 애초에 두께가 다른 책 |
작은 티어 모델은 큰 모델을 압축한 게 아니라, 처음부터 작게 설계해 따로 훈련시킨 별개의 모델이다. 뇌 용량 자체가 다르다.
이 구분이 실무에서 중요한 이유가 있다. 양자화된 모델은 “알긴 아는데 미세하게 삐끗”하고, 작은 모델은 “애초에 담을 수 있는 게 적다”. 증상이 다르니 처방도 다르다.
8. 그래서 — 원리 때문에 코드를 고친 이야기
여기까지가 원리다. 이제 그 원리가 실제로 코드를 바꾼 사례를 하나 적는다.
AI 코드 리뷰 시스템을 개발해보면서 겪은 일이다. 코드 청크를 모아 프롬프트로 만들어 API에 보내는 파이프라인인데, 어느 날 거기서 set을 쓰는 부분을 전부 걷어냈다.
Python의 set은 훌륭한 자료구조다. 중복 제거가 되고 조회가 빠르다. 일반적인 백엔드라면 정답인 경우가 많다.
그런데 LLM 파이프라인에서는 재앙이 될 수 있다. 앞서 배운 것들이 그대로 이유가 된다.
첫째, 컨텍스트는 순서 있는 토큰 열이다.
모델은 컨텍스트를 선형으로 읽는다. set을 프롬프트에 넣는 순간, 임의 순서로 직렬화된 그 결과가 곧 모델이 읽는 문장의 순서가 된다. 집합은 “순서 없음”인데 전달 매체는 “순서 필수”다. 타입 불일치다.
둘째, 프롬프트 캐싱이 깨진다. 캐싱은 프롬프트 앞부분이 토큰 단위로 완전히 동일할 때만 적중한다. 순서가 매번 바뀌면 같은 내용인데도 캐시 미스가 나고, 매번 전액이 청구된다. 조용히 새는 비용이다.
셋째, 재현이 불가능해진다. temperature를 0으로 고정해도 소용없다. 입력이 다르면 출력이 다른 게 당연하다. 같은 PR을 두 번 리뷰했는데 결과가 다르고, 원인이 모델인지 프롬프트인지 구분할 수 없게 된다.
넷째, 위치가 의미를 바꾼다. 어텐션 계산에는 위치 정보가 들어간다. 앞에 온 것과 뒤에 온 것의 무게가 다르다. 순서가 흔들리면 어떤 코드 청크가 주목받을지가 매번 룰렛이 된다. 리뷰 품질의 분산이 커진다.
그래서 원칙을 하나 세웠다.
AI 서비스의 데이터 구조는, 특별한 이유가 없으면 기본으로 ordered.
일반 백엔드의 상식과는 다르다. LLM 파이프라인은 출력이 입력 순서에 민감하고, 캐싱이 바이트 동일성을 요구하는 다른 규칙의 세계이기 때문이다.
남는 것
이 글을 쓰면서 한 가지 장면이 있었다.
양자화를 설명하던 AI가 “프로덕션에서는 양자화 모델을 쓰면 안 된다”고 말했다. 내가 “그런데 아무도 이 얘기는 안 하던데?“라고 되물었더니, 스스로 정정했다. 사실은 프로덕션 추론의 상당수가 양자화된 모델로 돌아간다고.
그럴듯하게 틀리는 것. 그게 이 구조의 특성이다. 다음 토큰을 확률로 고르는 기계는 “모른다”보다 “그럴듯한 것”을 뱉기 쉽다.
그래서 원리를 아는 게 방어구가 된다. 무엇을 의심해야 할지 알게 되니까.
기록은 계속된다.