파운데이션 모델 엔지니어링

6.2 토큰화의 과학

토크나이저는 버전이 있는 모델 인터페이스입니다. 시퀀스 길이, 임베딩 식별자, 문서 경계, 손실 위치, 언어·도메인별 연산 배분을 결정합니다. 사전 학습이 시작된 뒤 토크나이저를 바꾸는 일은 단순한 전처리 수정이 아니라 아키텍처 마이그레이션입니다.

엔지니어링 목표는 평균 압축률이 가장 높은 토크나이저가 아닙니다. 지원하는 모든 입력을 표현하고, 정규화와 특수 토큰 아래에서 일관되게 동작하며, 중요 슬라이스에 허용 가능한 시퀀스 예산을 배분하고, 올바른 체크포인트·서비스 스택과 묶이는 토크나이저가 목표입니다.

1. 서브워드와 바이트 표현

단어 수준 어휘에는 끝이 없는 미등록 토큰 문제가 있습니다. 문자·바이트 표현은 임의 입력을 포괄하지만 시퀀스가 길어지기 쉽습니다. 서브워드 토큰화는 빈번한 문자열을 유지하고 드문 문자열을 분해하여 임베딩 표 크기와 시퀀스 길이 사이를 조절합니다.

  • BPE 는 학습한 규칙에 따라 기호 쌍을 반복 병합합니다. 바이트 수준 BPE는 256개 바이트 값에서 시작하므로 임의 바이트 입력을 표현할 폴백 경로가 있습니다 [1].
  • WordPiece 는 우도에 기반한 병합 점수를 사용하며 BERT 같은 모델과 연결됩니다 [2].
  • SentencePiece 는 언어별 사전 토크나이저 없이 원시 문장에서 Unigram이나 BPE 모델을 학습할 수 있는 토크나이저 도구 모음입니다 [3]. 흔히 쓰는 공백 표시는 밑줄이 아니라 입니다.

“바이트 수준 모델”과 “상태 공간 모델”은 서로 다른 축을 설명합니다. Mamba는 아키텍처이며 본질적으로 바이트 수준인 것은 아닙니다. 바이트를 사용한다고 분할 정책이 사라지는 것도 아닙니다. 패치, 풀링, 시퀀스 길이 제한이 모델이 처리하는 대상을 계속 결정합니다. MEGABYTE 같은 바이트 수준 시스템은 더 긴 시퀀스를 다루기 위해 아키텍처 고유의 계층 구조를 사용합니다 [4].

2. 어휘와 연산의 트레이드오프

은닉 차원 dd, 어휘 크기 VV인 모델에서 묶이지 않은 입력 임베딩과 출력 프로젝션은 약 2Vd2Vd개의 파라미터를 가집니다. 큰 어휘는 시퀀스 길이를 줄일 수 있지만 파라미터, 옵티마이저, 체크포인트, 소프트맥스 비용을 늘리고 드문 행은 업데이트가 부족할 수 있습니다. 작은 어휘는 이 행렬을 줄이지만 일부 언어, 코드 형식, 식별자에 훨씬 많은 토큰과 어텐션·활성화 연산을 배분할 수 있습니다.

영어 평균 하나가 아니라 전체 분포를 측정합니다.

  • 바이트/문자당 토큰, 문서당 토큰의 p50/p95/p99
  • 한국어와 지원 언어, 코드, 수학, URL, 식별자, 전문 용어의 분절
  • 모든 어휘 행의 빈도와 문서 커버리지
  • 바이트 폴백 또는 미등록 토큰 비율과 이를 유발한 입력
  • 목표 컨텍스트 창에서의 시퀀스 절단률
  • 선택한 정밀도·샤딩에서 임베딩/출력 파라미터와 옵티마이저 상태 비용

“글리치 토큰”은 특정 말뭉치에 대한 보편적 서사가 아니라 운영 증상입니다. 예약되거나 잘못 형성됐거나 매우 드문 토큰 ID는 임베딩 학습이 부족하고 특이한 동작을 보일 수 있습니다. 실제 사전 학습 매니페스트에서 토큰 빈도를 감사하고 실행 전에 희귀·특수 토큰을 조사합니다.

3. 정규화와 특수 토큰 계약

정규화는 코드, 식별자, 악센트, 보안상 민감한 텍스트의 중요한 차이를 지울 수 있습니다. 유니코드 정규화, 공백 처리, 제어 문자 정책, 바이트 폴백, 잘못된 입력 처리 방식을 기록합니다. 바이트 또는 선언한 텍스트 정규화 수준에서 인코딩 → 디코딩 왕복을 시험하고, 원문 위치를 가리키는 과업을 위해 오프셋 매핑을 보존합니다.

BOS, EOS, 패딩, 미등록/폴백, 마스크, 역할, 도구, 문서 경계 토큰을 의도적으로 예약합니다. 동일한 숫자 ID가 토크나이저 버전마다 다른 의미를 가져서는 안 됩니다. 모델이 BOS를 요구하는지, EOS가 모든 문서·대화를 닫는지, 패딩과 EOS가 같은지, 어떤 토큰이 손실에 기여하는지 확인합니다. 나중에 인스트럭션 튜닝할 베이스 모델에도 채팅 템플릿은 이 계약의 일부입니다.

4. 토크나이저 수용 시험

토크나이저를 학습하기 전에 수용 말뭉치를 만듭니다. 지원하는 모든 언어·도메인에서 라이선스가 확인되고 사람이 감사한 고정 표본과 빈 문자열, 공백 변형, 결합 문자, 이모지, 선언한 정책 아래의 잘못된 바이트, 긴 식별자, 코드 들여쓰기, 수식, URL, 모든 특수 토큰을 포함합니다. 공개 벤치마크와 비공개 릴리스 프롬프트는 평가 격리 영역에 둡니다. 보호된 평가 항목을 복사하지 않고 같은 현상을 시험하는 예제를 사용해야 합니다.

다음의 의도적으로 작은 테스트는 이미 로드한 토크나이저의 인터페이스 불변식을 확인합니다. 프로덕션 수용 시험에는 큰 슬라이스 보고서와 수동 검사도 필요합니다.

from collections import Counter

def audit_tokenizer(tokenizer, samples):
    lengths = []
    token_counts = Counter()
    unk_id = tokenizer.unk_token_id

    for sample in samples:
        encoded = tokenizer(
            sample,
            add_special_tokens=False,
            return_offsets_mapping=True,
        )
        ids = encoded["input_ids"]
        offsets = encoded["offset_mapping"]
        decoded = tokenizer.decode(ids, skip_special_tokens=False)

        assert len(ids) == len(offsets)
        assert all(0 <= start <= end <= len(sample) for start, end in offsets)
        assert unk_id is None or unk_id not in ids, f"unexpected UNK: {sample!r}"
        # 토크나이저가 명시한 정규화 결과와 비교해야 합니다.
        assert decoded == sample, (sample, decoded)

        lengths.append(len(ids))
        token_counts.update(ids)

    assert lengths and max(lengths) > 0
    return {"lengths": lengths, "token_counts": token_counts}

samples = ["한국어와 English", "def f(x):\n    return x + 1", "é é 🙂"]
# report = audit_tokenizer(tokenizer, samples)

일부 토크나이저는 의도적으로 텍스트를 정규화하므로 정확한 왕복 단언을 문서화된 정규화 결과와의 비교로 바꿔야 합니다. 테스트를 조용히 약화하지 말고 정책을 명시적으로 코드화합니다. 프레임워크가 오프셋을 문자와 바이트 중 어떤 단위로 반환하는지도 확인합니다.

어휘를 선택하기 전에 슬라이스별 게이트를 정합니다. 같은 말뭉치에서 후보 토크나이저를 비교하고, 표본이 적으면 불확실성이나 여러 표본을 포함합니다. 예상하지 못한 미등록/폴백 실패, 특수 토큰 충돌, 중요 슬라이스의 과도한 절단, 오프셋 부재, 심각한 꼬리 fertility, 노출이 지나치게 적은 어휘 행이 있으면 후보를 거부합니다.

5. 체크포인트 호환성 계약

모델, 토크나이저, 템플릿은 하나의 불변 아티팩트 묶음입니다. 토크나이저 파일과 해시, 어휘 크기, 토큰-ID 매핑 해시, 특수 토큰 ID, 정규화 정책, 채팅 템플릿, BOS/EOS/패딩 정책, 모델 임베딩·출력 형상을 저장합니다. 서비스에서는 이 식별자가 맞지 않을 때 닫힌 방식으로 실패해야 합니다.

지속 사전 학습이나 미세 조정에서는 원래 토크나이저 유지가 기본값입니다. 토큰 추가는 측정된 커버리지나 효율 결함이 있을 때만 정당화됩니다. 기존 ID를 재배정하지 않고 새 ID를 뒤에 추가하며, 입력·출력 행을 의도적으로 초기화하고 resize_token_embeddings를 호출하여 새 행을 학습 가능하게 만듭니다. Hugging Face도 어휘 확장 뒤 모델 임베딩 크기 조정을 명시적으로 요구합니다 [5].

행렬 형상이 맞는다는 이유만으로 재정렬된 어휘에 오래된 체크포인트를 불러오면 안 됩니다. 같은 행이 다른 문자열을 뜻하게 됩니다. 임베딩을 묶었다면 크기 조정 후에도 묶임이 유지되는지 확인하고, 묶지 않았다면 두 행렬 모두 초기화·저장합니다. 어댑터·양자화 모델은 크기 변경을 위해 적절한 부동소수점 베이스 아티팩트로 돌아가야 할 수 있으므로 병합·내보내기 동작을 기록합니다.

6. 학습과 릴리스 실행 절차

대규모 실행 전에 다음을 수행합니다.

  1. 토크나이저 학습 데이터 매니페스트, 코드/설정, 시드, 라이선스/PII 결정을 고정합니다.
  2. 비교 가능한 데이터에서 여러 어휘·정규화 후보를 학습합니다.
  3. 언어·도메인별 수용 보고서를 실행하고 꼬리·희귀 토큰을 수동 감사가 검토합니다.
  4. 파라미터, 옵티마이저, 활성화, 시퀀스 길이, 체크포인트, 서비스 비용을 추정합니다.
  5. 작은 사전 학습 파일럿에서 슬라이스별 검증 손실, 희귀 토큰 노출, 처리량, 절단률, 다운스트림 프로브를 측정합니다.
  6. 최종 토큰화 샤드를 만들기 전에 선택한 토크나이저 해시를 고정합니다.
  7. 모든 모델 로드·배포를 토크나이저/템플릿 아티팩트 식별자로 게이트합니다.

중요 도메인이 미등록 토큰에 의존하거나, 특수 ID가 충돌하거나, 선언한 정규화 아래에서 원문 복원이 실패하거나, 토큰 예산이 연산 계획을 크게 위반하거나, 서비스 아티팩트의 호환성을 증명할 수 없으면 확장 전에 중단하고 다시 토큰화합니다. 대형 모델이 토큰 식별자를 학습한 뒤에는 토크나이저 교체가 다소 불완전한 토크나이저를 유지하는 것보다 대개 더 비싸고 위험합니다.

Quizzes

Quiz 1: 평균 문자당 토큰 수가 가장 작은 토크나이저가 자동으로 최선이 아닌 이유는 무엇인가요? 평균은 심각한 언어·도메인 꼬리, 드물고 학습이 부족한 행, 특수 토큰 오류, 더 큰 임베딩·소프트맥스 비용, 정규화 변경을 숨길 수 있습니다. 슬라이스 분포, 정확성, 연산, 호환성 게이트로 선택해야 합니다.

Quiz 2: SentencePiece는 BPE와 대립하는 하나의 알고리즘인가요? 아닙니다. SentencePiece는 BPE와 Unigram 등을 지원하는 도구 모음이자 원시 문장 학습 방식입니다. 알고리즘, 정규화, 바이트 폴백, 어휘, 특수 토큰 설정을 모두 식별해야 합니다.

Quiz 3: 벤치마크 프롬프트가 토크나이저 수용 말뭉치에 들어가면 안 되는 이유는 무엇인가요? 그 말뭉치가 토크나이저 학습이나 선택에 사용될 수 있기 때문입니다. 보호된 평가 텍스트가 토큰화 결정에 새지 않도록 공개 벤치마크와 비공개 릴리스 자료를 격리하고, 같은 현상을 다룬 별도의 예제로 커버리지를 시험합니다.

Quiz 4: 어휘를 1,000개 확장했고 기존 ID가 모두 들어가므로 모델이 로드됩니다. 이 외에 무엇이 필요한가요? 입력·출력 임베딩 크기를 조정하고 새 행을 의도적으로 초기화·학습하며, 기존 ID와 가중치 묶임을 보존하고, 토크나이저와 모델을 함께 버전 관리하며, 오래된 토크나이저를 쓰는 서비스를 거부해야 합니다.

Quiz 5: 인코딩/디코딩 시험에 정규화 정책을 명시해야 하는 이유는 무엇인가요? 일부 토크나이저는 입력을 의도적으로 정규화하므로 바이트 단위 동일성이 항상 계약은 아닙니다. 문서화된 정규화 결과와 비교하고 오프셋을 검증해야 하며, 임의의 차이를 조용히 허용하면 데이터 손실이 숨겨집니다.

References

  1. Radford, A., et al. (2019). Language Models are Unsupervised Multitask Learners. OpenAI 보고서.
  2. Devlin, J., et al. (2019). BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. ACL Anthology.
  3. Kudo, T., & Richardson, J. (2018). SentencePiece: A Simple and Language Independent Subword Tokenizer and Detokenizer for Neural Text Processing. ACL Anthology.
  4. Yu, L., et al. (2023). MEGABYTE: Predicting Million-byte Sequences with Multiscale Transformers. arXiv:2305.07185.
  5. Hugging Face. Tokenizer documentation. Transformers 문서.