LLM의 "멍청한" 실패 다수는 사실 멍청한 게 아니야 — tokenization 아티팩트야. 실패 모드를 알고 나면 신비롭지 않고 예측 가능해져.
strawberry 문제
GPT-4한테 "strawberry에 r이 몇 개?"라고 물으면 틀릴 수 있어. cl100k_base로 토큰화하면 "strawberry"는 ['str', 'aw', 'berry']로 쪼개져. 모델은 s, t, r, a, w, b, e, r, r, y 같은 개별 글자를 직접 본 적 없어. 답하려면 subword 조각들의 글자 구성을 추론해야 하는데, 질문이 character 단위 정체성이면 본질적으로 lossy한 연산이야.
다른 체계적 특이점
- 긴 숫자 연산. "1234567"이 ['12', '345', '67']로 토큰화될 수 있어. 모델은 digit을 보는 게 아니라 subword 덩어리 셋을 보는 거 — 그래서 긴 숫자 연산이 불안정해.
- 앞 공백 민감도. "Paris"랑 " Paris"(앞 공백 있는 거)는 보통 다른 토큰. 단어를 문장 시작에 두느냐 중간에 두느냐에 따라 다른 embedding 맞아.
- 코드의 whitespace 모양. 공백 2칸 vs 4칸은 다른 토큰. 일부 LLM이 4-space Python을 미묘하게 선호하는 게 그렇게 학습돼서야.
- CJK 효율 절벽. 영어 중심 tokenizer에서 한국어 문장은 영어 번역의 2-4배 토큰을 먹을 수 있어 — 토큰당 API 가격이 한국어로 의미 있게 비싸지는 이유.
이 특이점들은 버그가 아니야 — "모델이 character가 아니라 subword 조각을 본다"의 직접적 귀결이지. 이걸 체화하면 LLM이 어떤 질문에 안정적이고 어떤 질문에 약할지 예측할 수 있어.