localaiforum
Iniciar sesión
Guía › Fundamentos

Tokens y tokenizadores

Los modelos nunca ven palabras ni letras. Ven IDs de token — enteros que indexan un vocabulario fijo de piezas de subpalabra, construido con codificación de pares de bytes (BPE) o una variante cercana. La tokenización es el paso fronterizo de todo: tu prompt, la respuesta, la ventana de contexto, el medidor de tokens por segundo, las facturas de API. En cuanto piensas en tokens, la mitad del folclore sobre el comportamiento de los LLM se disuelve.

Cómo se construye un vocabulario

BPE parte de bytes crudos y fusiona repetidamente el par adyacente más frecuente hasta que el vocabulario alcanza su presupuesto. El resultado: las palabras comunes se vuelven tokens únicos, las raras se vuelven 2–5 piezas, y nada es irrepresentable — el respaldo a bytes cubre cualquier cadena, incluidos errores tipográficos y emoji. Los vocabularios van desde ~30k entradas (modelos antiguos) hasta ~250k (multilingües modernos):

Tokenizador Tamaño de vocab Nota
GPT-2 ~50k Inglés/web dominante
Llama 2 ~32k El coreano se divide dolorosamente
Llama 3 ~128k Gran salto multilingüe
Qwen 2 / 2.5 / 3 ~151k Fusiones CJK fuertes
Gemma ~256k El vocabulario común más grande

Un tokenizador entrenado mayormente con inglés fusiona fragmentos en inglés con agresividad; los pares de sílabas coreanas obtienen muchas menos fusiones útiles. El vocabulario decide tu impuesto coreano mucho antes de que el modelo mismo sea bueno o malo en coreano.

Ejemplo resuelto: inglés

"Tokenization turns text into pieces."

→ ["Token", "ization", " turns", " text", " into", " pieces", "."]
→ 37 characters → 7 tokens ≈ 5.3 chars/token

Observa los detalles: la palabra común "Token" es una sola pieza; el sufijo tiene la suya propia; y el espacio inicial pertenece al token siguiente (" turns", no "turns"). Por eso "hello", " hello" y "Hello" son tokens distintos — prompts que difieren en un espacio o una mayúscula se tokenizan diferente.

Ejemplo resuelto: coreano

La misma oración, peor economía. El hangul se escribe en bloques de sílaba y las fusiones del coreano son más raras en vocabularios dominados por el inglés (las divisiones de abajo son plausibles, no exactas):

"안녕하세요, 만나서 반가워요."        # 17 caracteres

vocabulario multilingüe fuerte (~150k entradas):
["안녕", "하세요", ",", " 만나", "서", " 반", "가", "워", "요", "."]
→ ~10 tokens ≈ 1.7 caracteres/token

vocabulario débil (~32k entradas, divisiones a nivel de jamo):
["안", "녕", "하", "세", "요", ",", " 만", "나", "서", ...]
→ 15+ tokens ≈ 1.1 caracteres/token

El inglés promedia ~4 caracteres/token. El coreano suele quedar en 1–1.5. Mismo significado, 3–4× los tokens. Por eso:

  • Los prompts en escritura CJK consumen las ventanas de contexto alarmantemente rápido — una ventana de 8k tokens sostiene aproximadamente 3–4× más inglés que coreano.
  • La generación «se siente» más lenta en coreano con idénticos tok/s: más tokens por oración, menos texto por token.
  • El coreano cuesta más en APIs con tarifa por token, y las trazas de razonamiento escritas en coreano queman presupuesto igual.

Por qué fallan las preguntas de contar letras

Pregunta «cuántas erres tiene strawberry» y hasta los modelos grandes tropiezan. Razón: el modelo nunca ve letras. "strawberry" llega aproximadamente como ["straw", "berry"] — dos enteros. Dentro de un entero no hay ningún recuento de letras, igual que un número de página no te dice cómo se escribe esa página. El modelo puede recitar ortografías memorizadas o razonar paso a paso, y ambas cosas son poco fiables. Si necesitas que se haga: obliga al modelo a deletrear la palabra una letra por línea primero, y luego cuenta las líneas.

El vocabulario viene con el modelo

  • Los archivos del tokenizador (vocab, merges) son parte del lanzamiento; GGUF los incrusta, los repos de safetensors los llevan junto a los pesos.
  • Los motores (llama.cpp, LM Studio, vLLM, ...) cargan el tokenizador correcto automáticamente. Nunca eliges uno.
  • Los recuentos de tokens son relativos al modelo: el mismo texto puede ser 1,000 tokens con el vocabulario de una familia y 1,150 con el de otra. Nunca codifiques presupuestos de tokens a través de modelos.
  • La calidad del vocabulario y la del modelo son ejes separados: un modelo de vocab 32k puede manejar coreano (entiende sus tokens); simplemente gasta más tokens por oración.

Todo se tarifa en tokens

Lo que te importa Denominado en
Ventana de contexto (4k → 128k+) tokens de entrada + tokens de salida juntos
Velocidad de generación tokens por segundo
Memoria de la caché KV crece por token en contexto (caché KV)
Precios de API por millón de tokens
Límites de longitud de salida tokens máximos de salida
Presupuestos de razonamiento/pensamiento tokens que el modelo puede gastar antes de responder
Incrustar documentos para RAG fragmentado y contado por millón de tokens

Tokens especiales y plantilla de chat

Además de las piezas de texto, el vocabulario reserva IDs de control: comienzo de secuencia, fin de secuencia y marcadores de rol. Cuando tu UI de chat envía un mensaje, no está enviando texto crudo — rellena una plantilla de chat que entrelaza tokens especiales como <|im_start|>user ... <|im_end|> alrededor de tus palabras. Ese envoltorio es la razón de que el recuento de tokens que reporta el motor siempre sea un poco mayor que el texto de tu mensaje solo, y de que mezclar plantillas de familias distintas confunda a los modelos.

Reglas de estimación: caracteres en inglés ÷ 4. Caracteres en coreano ÷ 1.0–1.5 — asume lo peor. El simulador usa la aproximación de ~4 caracteres/token y está calibrado para inglés; multiplícalo mentalmente para el coreano.

Contar tokens por tu cuenta

pip install tiktoken
python -c "import tiktoken as t; e = t.get_encoding('o200k_base'); print(len(e.encode('hello world')))"
  • tiktoken (https://github.com/openai/tiktoken) cubre las codificaciones de la familia OpenAI; otras familias difieren pero quedan dentro de aproximadamente ±15% para inglés.
  • Las páginas de modelo de Hugging Face incluyen un visor de tokenizador; los patios de recreo de tokenizadores te dejan pegar texto y ver las divisiones en vivo.
  • Los motores locales imprimen recuentos de tokens del prompt en sus registros — comprueba una vez contra tus prompts reales, y luego estima por proporción.

Relacionados: el interior del transformer · prefill vs decodificación · caché KV