본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 24. 02:26

LLM이 글자 수를 세지 못하는 이유 (그리고 어떻게 속이는가)

요약

LLM이 글자 수 세기나 운율 찾기에 취약한 이유는 텍스트를 직접 읽지 않고 토크나이저를 통해 정수 시퀀스로 변환하여 처리하기 때문입니다. BPE 알고리즘을 통해 단어가 토큰 단위로 묶이면서 개별 문자에 대한 정보가 손실되는 메커니즘을 설명합니다.

핵심 포인트

  • LLM은 문자열이 아닌 토크나이저가 변환한 정수 시퀀스를 입력받음
  • BPE(Byte Pair Encoding) 알고리즘이 현대 LLM의 주요 토큰화 방식임
  • 토큰화 과정에서 개별 문자의 정보가 손실되어 글자 수 계산 오류 발생
  • 토크나이저는 모델 학습 전 고정되어 모델이 직접 수정할 수 없음

아마 이런 현상을 목격하신 적이 있을 것입니다:

  • 언어 모델에게 "strawberry"의 글자 수를 세어보라고 하면, 자신 있게 틀린 답을 내놓습니다.
  • "entrepreneur"와 운율이 맞는 단어를 찾아달라고 하면 버벅거립니다.
  • "teh quick brown fox"에서 오타를 수정해달라고 하면 눈 하나 깜빡이지 않고 처리합니다.

같은 모델인데 결과는 극명하게 다릅니다. 왜 그럴까요?

정답은 "모델의 철자 능력이 부족해서"가 아닙니다. 이 모델들이 실제로 텍스트를 읽는 방식에 원인이 있으며, 이는 대부분의 사람들이 추측하는 것과는 다릅니다. 일단 그 메커니즘을 이해하면, 모델을 실행하기도 전에 어떤 작업은 완벽히 해낼 것이고 어떤 작업은 망칠 것인지 예측할 수 있습니다.

모델은 당신의 텍스트를 결코 직접 보지 않습니다

LLM에 메시지를 입력할 때, 모델은 문자열 (string)을 받는 것이 아닙니다. 모델은 정수 (integer)의 시퀀스를 받습니다.

당신의 입력값이 신경망 (neural network)에 닿기 전에, 그것은 **토크나이저 (tokenizer)**를 통과합니다. 토크나이저는 원문 텍스트를 토큰 ID (token IDs)로 변환하는 별도의 구성 요소입니다. 문자열 "strawberry"[496, 19772]가 될 수 있습니다. 모델이 실제로 다루는 것은 바로 이것입니다.

The model never sees your text: a tokenizer converts the string to integers before the network runs

토크나이저는 LLM 자체보다 먼저 별도로 학습되며, 그 이후에는 고정(frozen)됩니다. 모델은 이를 업데이트하지 않습니다. 모델은 단지 토크나이저가 학습한 매핑 (mapping)을 그대로 물려받을 뿐입니다. 따라서 당신의 프롬프트에 일어나는 가장 첫 번째 일은, 모델이 관여할 수 없는 손실이 발생하는 번역 (lossy translation) 과정입니다.

매핑이 결정되는 방식: BPE

대부분의 현대적 LLM이 사용하는 알고리즘은 **Byte Pair Encoding (BPE)**라고 불립니다.

이 메커니즘을 한 문장으로 설명하면 다음과 같습니다: BPE는 개별 문자를 어휘 사전 (vocabulary)으로 시작하여, 목표 어휘 사전 크기에 도달할 때까지 학습 코퍼스 (training corpus)에서 가장 빈번하게 함께 나타나는 토큰 쌍을 반복적으로 병합합니다.

따라서 다음과 같이 문자로 시작합니다: s, t, r, a, w, b, e, r, r, y

그다음 어떤 쌍들이 지속적으로 함께 나타나는지 감지하여 병합합니다: s·t·r·a·wstraw로 합쳐지고, b·e·r·r·yberry로 합쳐집니다. 이 과정은 어휘 사전 (vocabulary)이 목표 크기에 도달하여 안정화될 때까지 계속됩니다 (GPT-4는 약 100,000개의 토큰을 사용합니다).

결과적으로: "strawberry"["straw", "berry"]로 토큰화 (tokenize)될 수 있습니다. 이는 이 단어들이 언어학적으로 의미 있는 단위이기 때문이 아니라, 해당 바이트 시퀀스 (byte sequences)가 학습 데이터에서 병합 과정을 거쳐 살아남을 만큼 충분히 빈번했기 때문입니다.

이것이 핵심적인 직관입니다: 분할은 문법이 아니라 빈도수를 추적합니다. "the"와 같은 흔한 단어는 하나의 토큰이 됩니다. 드물거나 기술적인 단어들은 조각조각 잘게 쪼개집니다. "thransformer"(오타)와 같은 단어는 모델이 한 번도 그런 방식으로 묶여 본 적 없는 4개 또는 5개의 토큰이 될 수 있습니다.

버려지는 정보

여기서 중요한 점은 이것입니다: 문자 시퀀스가 일단 토큰 ID (token ID)가 되면, 문자들은 사라집니다.

Once it's a token ID the characters are gone:

모델은 19772("berry"에 매핑된 정수 등)를 봅니다. b, e, r, r, y를 보는 것이 아닙니다. "토큰 내부를 들여다보는" 연산은 존재하지 않습니다. 문자 수준 (character-level)의 접근도 없습니다. 서브토큰 (sub-token) 구조는 토큰화 (tokenization) 과정에서 파괴되며, 이후 단계로 전달되지 않습니다.

이것이 글자 수를 세는 것이 어려운 이유입니다. 당신이 "'strawberry'에 R이 몇 개 들어있나요?"라고 물을 때, 모델은 strawberry가 단지 두 개의 불투명한 정수일 뿐임에도 불구하고 학습 데이터의 통계적 패턴으로부터 문자 수준의 정보를 재구성해야 합니다. 모델이 이 정확한 질문에 대해 올바른 답변을 충분히 많이 보았기에 맞출 수도 있습니다. 하지만 그렇지 않을 수도 있습니다. 신뢰할 수 있는 메커니즘은 없으며, 단지 파괴된 신호 위에서 패턴 매칭 (pattern matching)을 수행할 뿐입니다.

운율 (rhyming)이 신뢰할 수 없는 것과 같은 이유입니다. 운율은 문자 수준 (character level)에서의 소리 패턴에 관한 것입니다. 모델은 이러한 패턴에 직접적으로 접근할 수 없습니다. 모델은 실제 음소 분석 (phoneme analysis)을 수행하는 것이 아니라, 이전에 보았던 운율 패턴에 대한 기억을 바탕으로 작동할 뿐입니다.

간단한 직관 테스트: 계속 읽기 전에 직접 예측해 보세요. 단어의 철자를 거꾸로 쓰는 것은 LLM에게 쉬울까요, 어려울까요? (어렵습니다. 글자 수를 세는 것과 같은 이유입니다. 토큰 ID (token ID)가 전달하지 못하는 문자 수준의 접근 (character-level access)이 필요하기 때문입니다.)

그렇다면 오타는 어떻게 처리할까요?

이 부분이 흥미로운 지점이자, 겉보기에 모순되는 부분입니다.

만약 모델이 문자 수준의 접근 권한이 없다면, 어떻게 "teh quick brown fox""the quick brown fox"로 올바르게 해석될 수 있을까요?

정답은 어텐션 (attention)입니다.

모델은 시퀀스 내의 모든 토큰을 다른 모든 토큰과의 관계 속에서 주목 (attend)합니다. "teh"는 비록 "the"와 다른 정수 ID를 가지고 있지만, "quick", "brown", "fox"와 같은 동일한 문맥 토큰들에 둘러싸여 나타납니다. 모델은 학습 과정에서 정확히 그러한 문맥 속의 "the"를 수십억 번 보았습니다. 어텐션 메커니즘은 "teh"에 대한 문맥적 표현 (contextual representation)을 구축하며, 이는 모델의 내부 공간에서 결국 "the"와 동일한 영역에 위치하게 됩니다.

모델은 오타를 교정하는 것이 아닙니다. 주변 환경을 바탕으로 해당 토큰을 표현하는 것이며, 그 표현이 결과적으로 의미론적으로 동일 (semantically equivalent)하게 되는 것입니다.

이것이 작동하는 이유는 "teh"가 흔한 오타이기 때문입니다. 학습 데이터에서 "the"와 동일한 문맥으로 충분히 자주 등장하기 때문에, 모델은 이 둘 사이를 연결하는 법을 학습했습니다.

이 논리가 무너지는 지점

동일한 논리를 적용하면 모델이 어디에서 실패할지 예측할 수 있습니다. 모델이 불안정해지는 세 가지 지점은 다음과 같습니다:

  • 오타가 난 희귀한 기술 용어 (A misspelled rare technical word): 예를 들어 `

토큰화 (Tokenization)는 트랜스포머 (Transformer) 파이프라인의 첫 번째 단계입니다. 만약 전체 스택 (임베딩 (embeddings), 위치 인코딩 (positional encoding), 어텐션 내부 구조 (attention internals) (Q/K/V), 피드포워드 네트워크 (feed-forward network), 잔차 스트림 (residual stream), 그리고 다음 토큰 루프 (next-token loop))를 알고 싶다면, 0xkato가 바닥부터 시작하는 훌륭한 가이드를 작성했습니다: How LLMs Actually Work. 이 글이 끝나는 지점에서 바로 내용을 이어갑니다.

Twitter에서 저를 찾아주세요.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0