LLM이 텍스트를 인식하는 방법: i18n 시스템이 알려준 토큰 경제학
제 사이트를 위한 i18n 번역 시스템을 구축할 때, 1,500단어 분량의 영어 블로그 글을 한국어로 번역하면 영어 원문보다 2.8배 더 많은 토큰을 소비한다는 사실을 발견했습니다. 동일한 의미 내용, 동일한 뜻이지만 API 비용은 2.8배입니다. 일본어는 2.4배, 중국어 번체는 2.1배, 스페인어는 1.15배였습니다. 다국어 콘텐츠의 토큰 경제학은 토크나이저의 작동 원리를 이해하지 못했기 때문에 완전히 예상 밖이었습니다.1
TL;DR
토큰화는 사람이 읽을 수 있는 텍스트를 언어 모델이 처리하는 숫자 토큰으로 변환하는 과정입니다. 27개의 블로그 글을 6개 언어로 번역한 후, 실제 비용 데이터를 확보했습니다: 비라틴 문자 체계는 의미 단위당 영어보다 2~3배 더 많은 토큰을 소비합니다. 아래의 인터랙티브 시각화 도구를 사용하면 어떤 언어의 텍스트든 붙여넣어 토큰 분석 결과를 확인할 수 있습니다. 토큰화를 이해함으로써 번역 파이프라인의 예산을 정확하게 책정하고, 프롬프트를 최적화하여 비용을 35% 절감했으며, 토크나이저가 각주 마커를 토큰 경계에 걸쳐 분할하면서 한국어 번역의 마크다운 구조가 깨지는 포맷팅 문제를 디버깅할 수 있었습니다.
i18n 토큰 비용 데이터
27개의 블로그 글을 Claude를 사용하여 6개 언어로 번역했습니다. 번역 품질을 위해 Opus 수준의 모델이 필요했습니다(절대 저렴한 모델을 사용하지 않았습니다 — Haiku가 기계 번역처럼 읽히는 결과물을 생성했을 때 배운 교훈입니다). 언어별 토큰 소비량은 놀라웠습니다:
| 언어 | 평균 토큰/게시물 | 영어 대비 배율 | 문자 체계 |
|---|---|---|---|
| 영어 (원문) | 1,850 | 1.0x | 라틴 |
| 스페인어 | 2,128 | 1.15x | 라틴 |
| 독일어 | 2,220 | 1.20x | 라틴 |
| 프랑스어 | 2,090 | 1.13x | 라틴 |
| 한국어 | 5,180 | 2.80x | 한글 |
| 일본어 | 4,440 | 2.40x | CJK 혼합 |
| 중국어 번체 | 3,885 | 2.10x | CJK |
라틴 문자 체계 언어(스페인어, 독일어, 프랑스어)는 영어의 20% 이내에 머물렀습니다. CJK 및 한글 언어는 2~3배로 급증했습니다. 비용 차이는 27개 게시물 × 6개 언어 = 162건의 번역에 걸쳐 누적됩니다.2
격차가 존재하는 이유
대부분의 토크나이저(Claude와 GPT-4 모두 사용하는 BPE)는 주로 영어 텍스트로 학습됩니다. 영어 단어는 학습 데이터에 다른 어떤 언어보다 많은 영어가 포함되어 있기 때문에 최적화된 토큰 표현을 갖습니다. 일반적인 영어 단어(“the”, “and”, “is”)는 단일 토큰에 매핑됩니다. 한국어 음절 블록, 일본어 한자, 중국어 문자는 학습 중 빈도가 낮았기 때문에 종종 2~3개의 바이트 수준 토큰으로 분할됩니다.3
이 효과는 무작위가 아니라 체계적입니다. 모든 한국어 번역은 영어 동등물의 약 2.8배 비용이 듭니다. 배율이 일관적이기 때문에 정확한 예산 책정이 가능합니다.
토큰화 버그
한국어 번역의 첫 번째 배치에서 번역된 게시물의 모든 마크다운 서식이 손실되었습니다: 각주 참조([^1])가 사라지고, 코드 블록의 언어 태그가 없어지고, 제목 마커(##)가 본문 텍스트에 합쳐졌습니다.
진단에 한 시간이 걸렸습니다. 근본 원인: 번역 프롬프트가 서식 보존을 지정하지 않고 “이 블로그 글을 한국어로 번역하세요”라고만 말했기 때문입니다. 토크나이저가 한국어 맥락에서 마크다운 구문을 영어 맥락과 다르게 토큰 경계에 걸쳐 분할했습니다. 모델은 [^1]을 구조적 마크업이 아닌 번역 가능한 콘텐츠로 처리했습니다.
해결책: 번역 프롬프트에 명시적 제약 조건을 추가했습니다:
Preserve all markdown formatting exactly:
- Keep [^N] footnote references unchanged
- Keep ``` code fences with language tags unchanged
- Keep ## heading markers unchanged
- Keep **bold** and *italic* markers unchanged
각 제약 조건이 하나의 실패 모드를 제거했습니다. 제약 조건 목록은 번역 지시보다 길어졌습니다 — 이 패턴은 OODA 프롬프트 엔지니어링 프레임워크에서 설명하고 있습니다.4
토큰이란 무엇인가
문자에서 토큰으로
텍스트 처리에 대한 단순한 접근법은 각 문자를 입력 단위로 취급하는 것입니다. “Hello world”는 11개의 문자가 됩니다. 문자 수준 처리는 모든 세부 사항을 포착하지만 극도로 긴 시퀀스를 생성합니다: 1,000단어 문서는 약 5,000개의 문자가 됩니다.5
단어 수준 처리는 시퀀스 길이를 줄이지만 미지의 단어에서 실패합니다. 50,000개 항목의 단어 수준 어휘는 정확히 그 단어가 학습에 나타나지 않았다면 “unfathomability”를 처리할 수 없습니다.
서브워드 토큰화는 중간 지점을 찾습니다. 일반적인 단어(“the”, “and”)는 단일 토큰으로 유지됩니다. 흔하지 않은 단어는 서브워드 조각으로 분할됩니다. “Unfathomability”는 [“un”, “fath”, “om”, “ability”]로 분할되며, 각 조각은 학습된 표현을 가질 만큼 충분히 자주 나타납니다.
Byte-Pair Encoding (BPE)
Claude와 GPT-4가 사용하는 BPE는 개별 바이트에서 시작하여 가장 빈번한 인접 쌍을 반복적으로 병합합니다:6
- 개별 문자로 시작:
[l, o, w, e, r] - 가장 빈번한 쌍:
(l, o)→ 병합하여[lo, w, e, r] - 가장 빈번한 쌍:
(e, r)→ 병합하여[lo, w, er] - 가장 빈번한 쌍:
(lo, w)→ 병합하여[low, er] - 가장 빈번한 쌍:
(low, er)→ 병합하여[lower]
최종 어휘에는 모든 원래 바이트와 병합된 모든 토큰이 포함되며, 일반적으로 50,000~100,000개 항목입니다. 영어 단어가 병합된 토큰을 지배하는 이유는 영어가 학습 데이터를 지배하기 때문입니다.
프롬프트 최적화 방법
토큰 비용 격차를 발견한 후, 번역 파이프라인을 최적화하여 비용을 35% 절감했습니다:
최적화 1: 언어 계열별 배치 처리
라틴 문자 체계 언어(스페인어, 프랑스어, 독일어)는 구조적 유사성을 공유합니다. 원본 게시물이 세 개의 출력과 함께 컨텍스트 윈도우에 들어갈 만큼 짧은 경우, 단일 API 호출로 세 가지를 모두 생성하도록 번역 프롬프트를 배치 처리합니다. 공유 컨텍스트(영어 원문)는 세 번이 아닌 한 번만 비용을 지불합니다.7
최적화 2: 제약 조건 중복 제거
원래 번역 프롬프트는 각 언어마다 제약 조건을 반복했습니다. 최적화된 버전은 제약 조건을 한 번 정의하고 모든 출력에 적용합니다:
# Constraints (apply to ALL translations below):
- Preserve markdown structure, footnotes, code blocks
- Keep proper nouns in English
- Adapt idioms, don't transliterate
# Translate the following post into: Spanish, French, German
제약 조건 섹션은 토큰을 한 번만 소비합니다. 대안(언어별로 제약 조건을 반복하는 것)은 3배를 소비합니다.
최적화 3: 간결한 지시문
원래 프롬프트는 340개의 지시 토큰을 사용했습니다. 최적화 후: 180개 토큰. 47%의 감소가 162건의 번역에 걸쳐 누적됩니다.
| 지표 | 이전 | 이후 | 절감 |
|---|---|---|---|
| 지시 토큰 | 340 | 180 | 47% |
| 라틴 배치당 총합 | 6,780 | 4,438 | 35% |
| CJK 언어당 총합 | 5,520 | 5,180 | 6% |
CJK 언어는 프롬프트 최적화의 혜택이 적습니다. 출력 토큰(번역 자체)이 비용을 지배하기 때문입니다. 지시문이 아무리 간결해도 출력은 토큰 기준으로 본질적으로 더 깁니다.8
실용적 활용
비용 추정
영어 텍스트에 대한 대략적인 경험 법칙: 1 토큰은 약 0.75단어, 또는 약 4개의 문자입니다. 1,000단어 문서는 약 1,333개의 토큰을 소비합니다. 비영어 콘텐츠의 경우 위 표의 언어 배율을 적용하면 됩니다.9
코드 토큰화
코드는 산문과 다르게 토큰화됩니다. 일반적인 키워드(def, return, if)는 단일 토큰에 매핑됩니다. 변수 이름은 빈도에 따라 분할됩니다:
# "def calculate_total(items):" splits approximately as:
# ["def", " calculate", "_total", "(", "items", "):", ]
일관된 네이밍 규칙은 토큰 수를 줄입니다. 제 훅 인프라는 verb-noun.sh 규칙(git-safety-guardian, recursion-guard, blog-quality-gate)을 사용합니다. 일관된 패턴은 토크나이저가 공통 서브워드를 효율적으로 예측하고 병합하는 데 도움을 줍니다.
예상치 못한 동작 디버깅
모델이 예상치 못한 출력을 생성할 때, 토큰화가 그 이유를 설명할 수 있습니다. 한국어 포맷팅 버그는 토크나이저가 한국어 맥락에서 [^1]을 영어와 다르게 분할했기 때문에 발생했습니다. 분할 패턴을 이해하는 것이 곧바로 해결책(명시적 보존 제약 조건)으로 이어졌습니다.
핵심 요점
LLM API를 사용하는 엔지니어를 위한 조언: - 다국어 지원을 결정하기 전에 언어별 토큰 비용을 측정하세요; CJK 언어는 의미 단위당 영어보다 2~3배 더 비용이 듭니다 - 프롬프트 지시문을 최적화(간결한 표현, 중복 제거된 제약 조건)하여 대량 번역 파이프라인에서 30~50%의 비용 절감을 달성할 수 있습니다 - 프로덕션 배포 전에 도메인 특화 용어와 마크다운 구문의 토큰화를 테스트하세요; 예상치 못한 분할이 포맷팅 버그를 일으킵니다
AI 기능 예산을 책정하는 프로덕트 매니저를 위한 조언: - 비영어 언어 지원은 API 호출당 영어보다 1.5~3배 더 비용이 듭니다; 다국어 AI 기능의 예산은 언어별 균등 추정이 아닌 언어 배율을 사용하여 책정하세요 - 컨텍스트 윈도우 제한은 CJK 언어에 불균형적으로 영향을 미칩니다; 200K 토큰 윈도우는 영어보다 한국어 콘텐츠를 40% 적게 수용합니다
참고 문헌
-
저자의 i18n 번역 파이프라인. 27개의 게시물을 6개 언어로 번역. 언어별 토큰 소비량을 측정하여 한국어 2.8배 배율을 발견. ↩
-
저자의 번역 비용 데이터. 27개 게시물에 걸친 언어별 평균 토큰, 각각 Claude Opus를 사용하여 독립적으로 번역. ↩
-
Petrov, Aleksandar et al., “Language Model Tokenizers Introduce Unfairness Between Languages,” NeurIPS 2023. ↩
-
저자의 번역 포맷팅 수정. 한국어 번역에서 각주, 코드 블록, 제목 마커가 손실된 후 명시적 마크다운 보존 제약 조건 추가. ↩
-
Sennrich, Rico et al., “Neural Machine Translation of Rare Words with Subword Units,” ACL 2016. ↩
-
Gage, Philip, “A New Algorithm for Data Compression,” The C Users Journal, 12(2), 23-38, 1994. ↩
-
저자의 프롬프트 최적화. 라틴 문자 체계 언어 배치 처리 및 제약 조건 중복 제거로 전체 파이프라인 비용 35% 절감. ↩
-
저자의 프롬프트 최적화 지표. 지시 토큰 340에서 180으로 감소(47%). 배치당 총 절감: 라틴 35%, CJK 6%. ↩
-
Anthropic, “Claude API Pricing,” 2025. 토큰 기반 가격 책정 모델. ↩