LLM은 어떻게 작동하는가


먼저 이름부터 짚어보겠습니다. LLM은 large language model(거대 언어 모델)의 줄임말로, ChatGPT 같은 도구 뒤에 있는 AI, 즉 프롬프트를 보내면 텍스트로 응답을 받는 그 대상을 가리킵니다. 이 장은 그것이 실제로 무엇인지에 대한 작업용 그림을 그려주는 챕터입니다.
질문을 입력하면 몇 초 후 유창하고 자신감 있는 답변이 나타납니다. 마치 모델이 당신을 이해하고 답을 찾아본 것처럼 읽힙니다. 그런 인상은 유용하지만, 중요한 부분에서 틀렸기도 하고, 그 둘 사이의 간극에서 초보자들의 실수가 대부분 나옵니다.
이 장은 앞으로 이 도구들을 다루는 내내 도움이 될 챕터입니다. 모델을 학습시키는 수학을 알아야 모델로 무언가를 만들 수 있는 것은 아닙니다. 하지만 모델이 답을 낼 때 실제로 무슨 일이 벌어지는지에 대한 작업용 그림은 반드시 필요합니다. 그 그림이 나머지 모든 것을 설명해주기 때문입니다. 왜 프롬프팅이 효과가 있는지, 왜 같은 질문에 다른 답이 나오는지, 왜 모델이 사실을 지어내는지, 왜 비용이 그만큼 드는지, 왜 별것 아닐 것 같은 일부 기능이 실제로는 까다로운지까지. 이 핸드북의 이후 모든 내용은 여기서 나오는 아이디어의 결과물입니다.
모델이 실제로 무엇인가
채팅 인터페이스를 걷어내면 거대 언어 모델은 한 가지입니다. 수십억 개의 숫자로 이루어진 고정된 집합, 파라미터(가중치라고도 부릅니다)로 구성된 거대한 수학 함수입니다. 그게 모델의 전부입니다. 데이터베이스도 아니고, 검색 엔진도 아니고, 상자 속에 든 작은 사람도 아닙니다. 텍스트를 입력받아 텍스트를 출력하는, 아주 큰 숫자 더미일 뿐입니다.
그 숫자들은 프로그래머가 하나하나 타이핑해서 만든 것이 아닙니다. 학습(training) 과정에서 설정되었습니다. 제공업체는 모델에게 엄청난 양의 텍스트, 책, 코드, 기사, 웹페이지를 먹였고, 다음 단어를 가리고 모델에게 예측하게 한 뒤 틀릴 때마다 숫자를 살짝 조정하는 간단한 훈련을 수십억 번 반복했습니다. 이를 엄청난 규모로 반복하면 숫자들이 서서히 텍스트 예측에 유리한 값으로 자리 잡습니다. 학습이란 바로 이것입니다. 수십억 개의 다이얼을 예측이 잘될 때까지 조율하는 과정입니다.
여기서 두 가지가 따라오는데, 이 두 가지가 앞으로 마주칠 많은 행동을 설명해줍니다. 첫째, 학습은 미리, 딱 한 번 일어나고 비용이 엄청나게 많이 듭니다. 모델을 호출할 때쯔음이면 숫자들은 이미 고정되어 있습니다. 모델은 당신과의 대화에서 배우지 않습니다. 당신이 하는 말은 모델의 파라미터를 조금도 바꾸지 않습니다. 마치 기억하고 적응하는 것처럼 느껴지지만, 그것은 모델을 감싸고 있는 소프트웨어가 하는 일이며, 모델 자체가 하는 일이 아닙니다. 이 점은 컨텍스트 윈도우를 다루는 절에서 다시 강하게 등장합니다.
둘째, 모델 안에는 사실을 정리한 표 같은 것이 없습니다. "지식"은 만 개의 빵을 구워 본 제빵사가 레시피를 읽지 않고도 손에 기술을 지니고 있는 것처럼, 그 숫자들에 패턴으로 녹아들어 있습니다. 모델은 올바르고 자연스러운 텍스트의 형태를 배웠습니다. 그래서 같은 문장 안에서도 유창하면서 틀릴 수 있는 것입니다. 모델은 저장된 사실을 선반에서 꺼내 읽는 게 아니라, 좋은 답의 형태를 재현하고 있을 뿐입니다.
다음 토큰 예측하기
그 숫자 더미가 갖춰지면, 모델은 정확히 한 가지 일을 합니다. 다음 텍스트 조각을 계속 반복해서 예측하는 것입니다.
이 루프를 천천히 풀어보겠습니다. 당신이 텍스트를 넘겨줍니다. 모델은 그 텍스트를 모든 파라미터를 거쳐 실행하고, 가능한 다음 조각 각각에 대한 확률을 만들어냅니다. 알고 있는 수만 개의 후보 전체에 대해 동시에요. "The capital of France is"(프랑스의 수도는) 다음에는 "Paris"(파리)라는 조각이 97%, "a"가 1%, 나머지는 거의 0에 가까운 점수를 받을 수 있습니다.
그러면 모델은 조각 하나를 골라 텍스트에 이어붙이고, 다음 조각을 고르기 위해 전체 과정을 다시 실행합니다. 답이 완성될 때까지 이를 반복합니다.
이게 이 엔진의 전부입니다. 당신이 하나의 생각처럼 읽는 답변은 사실 한 번에 하나씩 만들어진 조각들이 모여서 된 것이고, 각 조각은 그 순간 새로 계산된 확률 순위에서 골라진 것이며, "다음에 뭐가 그럴듯한가"를 넘어서는 문장 전체에 대한 계획은 전혀 없습니다. 당신이 사용하게 될 모든 능력, 채팅, 코딩, 번역, 도구 사용, 추론은 모두 이 똑같은 루프가 아래에서 돌아가고 있는 것입니다.
다음 단어를 제안해주는 휴대폰 키보드도 같은 원리를 축소한 것입니다. 다른 점은 그 추측 뒤에 있는 수십억 개의 파라미터입니다. 충분히 많은 텍스트로 학습시키면, "가장 그럴듯한 다음 조각이 무엇인가"라는 원리만으로도 작동하는 코드와 명확한 설명을 써낼 만큼 충분히 좋아집니다. 하지만 그 기저의 작동 방식은 절대 바뀌지 않습니다. 이것은 예측이지, 이해가 아니며, 저장된 답을 찾아보는 것도 아닙니다.
무작위성 다이얼
모델이 항상 점수가 가장 높은 조각 하나만 골랐다면, 같은 프롬프트에 매번 같은 답을 내놓았을 것이고, 그 답은 대체로 밋밋하고 반복적이었을 것입니다. 그래서 대부분의 경우 선택에는 약간의 무작위성이 들어갑니다. 대개 확률이 높은 조각을 고르지만, 항상 최상위 것만 고르지는 않습니다. 그래서 정확히 같은 질문을 두 번 해도 다른 답변을 받을 수 있는 것입니다. 이것은 시스템이 설계대로 작동하는 것이지, 오류가 아닙니다.
이 무작위성의 정도는 **temperature(온도)**라는 설정으로 조절하며, 코드로 모델 호출하기 챕터에서 모델을 호출할 때 설정하게 됩니다. 지금 그 직관을 미리 가져보는 것이 좋습니다. temperature가 낮으면 모델은 상위권 선택지에 가까이 붙습니다. 집중되고, 일관되고, 예측 가능한데, 이는 인보이스에서 숫자를 뽑아내거나 텍스트를 분류할 때 바라는 특성입니다. temperature가 높으면 확률이 낮은 조각들도 더 자주 선택됩니다. 더 다양하고 창의적이지만, 틀린 방향으로 헤맬 가능성도 더 높습니다. 브레인스토밍과 창작 글쓰기는 높은 쪽을 원하고, 정답이 있는 작업은 낮은 쪽을 원합니다.
그러니 하나의 다이얼이 모델을 "신중하고 반복 가능한" 상태와 "놀랍고 창의적인" 상태 사이에서 움직입니다. 어느 쪽이든 예측 루프는 똑같습니다. temperature는 모델이 가장 안전한 추측을 넘어서 얼마나 대담하게 손을 뻗을지만 바꿉니다.
토큰
모델이 예측하는 "조각"에는 이름이 있습니다. **토큰**입니다. 토큰은 텍스트 한 조각으로, 온전한 단어인 경우가 많고, 때로는 단어의 일부에 불과합니다. 흔한 단어는 보통 하나의 토큰이고, 더 길거나 드문 단어는 여러 개로 쪼개집니다.
"tokenization" -> "token" + "ization"
"unbelievable" -> "un" + "believ" + "able"
"cat" -> "cat"왜 온전한 단어나 개별 글자 대신 이런 이상한 조각으로 텍스트를 잘라내는 걸까요? 여기에는 트레이드오프가 있습니다. 개별 글자를 쓰면 모든 시퀀스가 엄청나게 길어질 텐데, 길이는 곧 모델이 계산해야 할 양입니다. 온전한 단어를 쓰면 수백만 개 항목의 어휘집이 필요할 텐데, 그마저도 누군가 새 단어를 만들거나 오타를 내는 순간 바로 깨질 것입니다. 토큰은 그 중간 길입니다. 몇만 개 정도의 흔한 조각으로 이루어진 고정된 어휘집이며, 이를 조합하면 모델이 한 번도 본 적 없는 단어까지도 무엇이든 표현할 수 있습니다.
여기서 사람들을 놀라게 하는, 이면에 숨은 결과가 하나 있습니다. 모델은 글자를 결코 보지 않습니다. 모델이 보는 것은 토큰이고, 모델에게 그것은 사실 그 조각들을 가리키는 ID 번호일 뿐입니다. 그래서 우리에게는 힘들이지 않고 되는 것처럼 보이는 작업이 모델에게는 어려울 수 있습니다. 단어 속 글자 수 세기, 문자열 뒤집기, "strawberry"에 r이 세 개 있다는 것을 알아채는 것 같은 작업들입니다.
모델이 멍청해서 그런 게 아닙니다. 마치 다 구워진 빵 한 덩어리에서 개별 밀가루 낱알을 맛으로 구분할 수 없는 것처럼, 모델은 개별 글자를 아예 인식하지 못합니다. 모델이 맞춤법이나 글자 세기 작업에서 헛발질을 할 때, 그 이유가 바로 이것이며, 대개는 그 부분을 일반 코드로 처리하는 것이 해결책입니다.
토큰은 또한 당신이 늘 신경 써야 할 두 가지의 단위이기도 합니다.
- 비용: 제공업체는 토큰 단위로 요금을 매기는데, 당신이 보내는 토큰과 모델이 다시 써주는 토큰 모두를 계산합니다. 그래서 긴 문서를 입력하는 것과 긴 답을 받는 것 모두 비용을 더 들게 합니다. 영어에 대한 대략적인 감으로는 토큰당 약 4글자, 또는 75단어당 100토큰 정도입니다. 코드와 다른 언어는 흔히 더 많은 토큰으로 쪼개지는데, 이것이 그것들이 더 비쌀 수 있는 이유의 일부입니다. 코드로 모델 호출하기를 시작하면 이를 직접 마주하게 됩니다.
- 한계: 모델이 한 번에 다룰 수 있는 토큰 수에는 상한선이 있는데, 이것이 다음 절의 내용입니다.
컨텍스트 윈도우
**컨텍스트 윈도우**는 모델이 한 번에 받아들일 수 있는 텍스트의 양으로, 토큰 단위로 측정됩니다. 모델의 책상 크기라고 생각해보십시오. 하나의 요청에 관련된 모든 것, 즉 당신의 지시사항, 지금까지의 대화, 붙여넣은 문서들, 그리고 모델이 작성하고 있는 답변까지 모두 그 책상 위에 한꺼번에 놓여야 합니다.
왜 이런 한계가 존재할까요? 예측이 작동하는 방식에서 비롯됩니다. 다음 토큰을 고르기 위해 모델은 입력의 모든 토큰이 다른 모든 토큰과 어떤 관계인지를 가늠합니다. 그래야 "그것"이 세 문장 전에 나온 고양이를 가리킨다는 것을 알 수 있습니다. 이런 전체 대 전체 비교가 모델이 한 문단 전체에 걸쳐 의미를 추적하게 해주는 힘이지만, 동시에 긴 입력을 처리하는 비용이 커지는 원인이기도 합니다. 제공업체는 각 요청을 다룰 만한 크기로 유지하기 위해 상한선, 즉 컨텍스트 윈도우를 설정합니다.
책상이 가득 차면 뭔가는 치워야 합니다. 대화가 윈도우를 넘칠 만큼 길어지면, 가장 앞부분이 떨어져 나가고 모델은 더 이상 그것을 볼 수 없습니다. 이것이 긴 채팅이 처음에 당신이 말한 것을 "잊어버린" 것처럼 보이는 이유입니다. 인간적인 의미에서 잊어버린 것이 아니라, 그 토큰들이 책상 밖으로 밀려난 것입니다. 또한 모델은 책상 위에 있는 것 중 시작 부분과 끝부분에 가장 주의를 기울이는 경향이 있고, 중간에 묻힌 내용은 놓치기 쉽다는 점도 알아두면 좋습니다. 그러니 윈도우를 채울 때 중요한 텍스트를 어디에 두는지가 중요합니다.
이제 거의 모든 초보자를 붙잡는 핵심을 짚어보겠습니다. 나머지보다 더 중요한 내용입니다. 모델은 별개의 요청 사이에 아무 기억도 갖지 않습니다. 모델의 숫자는 고정되어 있다는 것을 기억하십시오. 각 호출은 빈 책상에서 시작합니다. 모델은 당신의 지난 질문, 당신의 이름, 1분 전의 어떤 것도 기억하지 못합니다.
채팅 앱이 하나의 흐르는 대화처럼 느껴지는 것은, 그 앱이 새 메시지를 보낼 때마다 전체 대화 이력을 조용히 다시 보내주기 때문입니다. 그 연속성은 모델을 감싸고 있는 소프트웨어가 만들어내는 것이며, 모델 자체가 지닌 것이 아닙니다.
이 한 가지 사실이 여기서부터 무엇을 만들든 그 방식을 결정합니다. 모델이 무언가를 알기를 원한다면, 그 요청 안의 책상 위에 그것을 올려놔야 합니다. 지금까지의 대화, 사용자의 세부 정보, 관련 문서까지, 매번 전부 다요. 이 핸드북의 상당 부분은 사실 그 한 가지 일을 잘하는 방법, 즉 올바른 텍스트를 책상 위에 올려놓는 방법에 관한 것입니다.
모델이 모르는 것
모델의 모든 지식은 학습 과정에서 스며들었으므로, 학습 데이터에 있던 것만 알고 있고, 그 데이터는 과거의 어느 마감 시점까지만 수집되었습니다. 여기서 두 가지 한계가 곧바로 따라옵니다.
첫째, 마감 시점 이후에 일어난 일은 전혀 모릅니다. 지난주 뉴스나 이번 달에 나온 라이브러리를 물어보면 제대로 알 도리가 없지만, 그럼에도 그럴듯해 보이는 답을 신나게 내놓을 수도 있습니다. 둘째, 사적인 것은 애초에 알 수가 없었습니다. 당신 회사의 내부 문서, 사용자의 주문 내역, 데이터베이스의 내용 같은 것은 그것이 학습한 공개 텍스트에 없었으므로, 아무리 곱게 물어봐도 알 수 없습니다.
더 조용한 한계도 있습니다. 모델은 대개 자신이 "아는" 것이 어디서 왔는지 말해주지 못합니다. 지식이 출처가 표기된 별개의 사실로 정리되어 있는 것이 아니라 내부에서 뒤섞여 있기 때문입니다. 인용을 만들어낼 수는 있지만, 그것은 실제 인용을 찾아보는 것이 아니라 인용이 어떻게 보여야 하는지를 예측하는 것입니다.
이것이 나중에 배울 검색, 즉 RAG라는 기법이 필요한 이유입니다. 최근 사건이나 당신의 사적인 데이터에 대해 모델이 답하게 하고 싶다면, 재학습을 시키지 않습니다. 관련 텍스트를 직접 가져와서 요청 시점의 책상 위에 놓아, 모델이 추측하는 대신 눈앞의 사실을 보게 하는 것입니다. 모델은 신뢰할 만한 구체적 사실의 우물이라기보다는, 당신이 준 텍스트에 대해 추론하는 존재에 훨씬 가깝습니다.
모델이 사실을 지어내는 이유
때로 모델은 완전한 자신감으로 거짓을 말합니다. 아무도 한 적 없는 인용문, 존재하지 않는 함수, 결코 쓰인 적 없는 연구에 대한 인용 같은 것들입니다. 이를 **환각(hallucination)**이라고 부르는데, 앞의 몇 절을 지나온 지금은 이것이 신비롭기보다는 거의 필연적으로 느껴질 것입니다.
그 이유는 모델에게 "참"과 "거짓"에 대한 내적 감각이 없다는 것입니다. 모델에게는 "그럴듯한 텍스트"와 "그럴듯하지 않은 텍스트"만 있습니다. 대부분의 경우 이 둘은 일치합니다. 모델이 학습한 텍스트에서는 참인 진술이 거짓인 진술보다 훨씬 많기 때문에, 그럴듯한 연속은 대개 맞는 것이기도 합니다.
하지만 모델이 공백에 부딙힐 때, 즉 한 번도 학습한 적 없는 것이나 결코 볼 수 없었던 당신의 사적인 데이터에 부딧힐 때, 모델은 멈춰서 그 공백을 표시하지 않습니다. 자신이 무엇을 모르는지 믿을 만하게 말할 수 없습니다. 늘 하던 그 한 가지 일을 합니다. 가장 그럴듯하게 들리는 연속을 만들어내는 것입니다.
자신감 있고, 잘 짜여진, 틀린 답이야말로 종종 가장 그럴듯하게 들리는 것 그 자체입니다. 모델을 유창하게 만드는 그 똑같은 메커니즘이, 틀렸을 때도 유창하게 만듭니다.
여기서 곰곰이 생각해봐야 할 부분입니다. 환각은 프롬프트로 완전히 없앨 수 있는 결함이 아닙니다. 줄일 수는 있고, 다음 장들에서 그 방법을 보여줍니다. 모델에게 "모른다"고 말해도 된다고 알려주는 것은 조금 도움이 됩니다. 당신이 제공한 텍스트에서만 답하라고 요청하는 것은 훨씬 더 도움이 됩니다. 이제는 고정된 학습 지식에서 채워야 할 공백이 없기 때문입니다. 하지만 그 경향은 모델이 근본적으로 무엇인지, 즉 내부에 사실 검증기가 없는 확률 기계라는 데서 나오므로, 지속적인 해법은 구조적인 것입니다. 학습 데이터에 있었기를 바라기보다 필요한 사실을 직접 건네주고, 중요한 답은 신뢰하기보다 검증하는 것입니다.
이 장에서 다른 무엇보다 하나의 규칙만 가져가십시오. 모델의 자신감은 그것이 맞는지에 대해 아무것도 말해주지 않습니다. 유창함과 정확함은 같은 과정에서 만들어지고 늘 서로 갈라집니다. 어떤 단일한 답이든 틀릴 수 있다고 가정하고 만드십시오. 실제로 어떤 단일한 답이든 틀릴 수 있기 때문입니다.
종합하기
이 장의 모든 내용은 하나의 아이디어를 여러 각도에서 본 것입니다. 모델은 다음 토큰을 예측하는, 고정된 숫자 더미이며, 당신이 다루게 될 거의 모든 행동이 여기서 나옵니다.
- 한 번에 하나의 토큰을 예측합니다. 확률 순위에서요. 그래서 회상하기보다 즉흥적으로 만들어내고, 약간의 무작위성(temperature)이 답을 다양하게 만듭니다.
- 토큰은 모델이 작업하는 조각입니다. 당신의 요금 단위이자 크기 제한 단위이며, 모델이 글자를 믿을 만하게 세지 못하는 이유입니다.
- 컨텍스트 윈도우는 하나의 요청이 쓰는 책상이며, 모든 것이 그것을 함께 씁니다. 모델은 요청 사이에 아무것도 기억하지 못하므로, 연속성은 당신의 일입니다.
- 모델의 지식은 학습 마감 시점에 고정되어 있고 당신의 사적인 데이터를 포함한 적이 결코 없습니다. 그래서 사실을 가져와 프롬프트에 넣는 것입니다.
- 환각은 진실에 대한 감각 없이 그럴듯한 텍스트를 예측하는 시스템의 대가이며, 근거화와 검증으로 줄어들 뿐, 그저 문구를 다듬는 것만으로는 줄어들지 않습니다.
이것들을 함께 붙잡으면, AI 엔지니어링의 놀랄 만큼 많은 부분이 실은 다른 옷을 입은 하나의 작업이라는 것을 알게 됩니다. 올바른 텍스트를 올바른 형태로, 올바른 순간에 책상 위에 올려놓고, 출력을 무조건 믿지 않는 것입니다. 다음 장 오픈 모델과 클로즈드 모델에서는 어떤 종류의 모델들이 있고 어떻게 하나를 구할 수 있는지 살펴보고, 그다음 프롬프팅에서 이 모든 예측을 당신이 실제로 원하는 방향으로 조종하기 시작합니다.

