volver al blog

Tokenización: por qué tu LLM no sabe contar letras

llmtokenizacionpython

El fallo que lo delata todo

Pídele a un LLM que cuente cuántas veces aparece la letra “r” en “ferrocarril” y verás cómo, cada cierto tiempo, falla. No es que sea tonto. Es que no ve la palabra como tú: no ve once letras, ve dos o tres bloques. Y contar letras dentro de un bloque que no puede abrir es como contar los ladrillos de una casa mirando la foto de la fachada.

Ese detalle, la tokenización, es la capa más olvidada del stack y la que más comportamientos raros explica: el coste de tus llamadas, el límite de contexto, por qué el modelo tropieza con el español y hasta por qué a veces se inventa palabras. Entenderla no es opcional si vas a llevar un LLM a producción.

Qué es un token, de verdad

Un token es la unidad mínima que el modelo procesa. No es una letra ni una palabra: es un trozo de texto, normalmente entre uno y varios caracteres, que el tokenizador ha decidido tratar como una pieza única.

La regla mental que funciona: en inglés, un token equivale más o menos a cuatro caracteres, o a unas tres cuartas partes de una palabra. En español, peor, y ahora veremos por qué.

Las palabras frecuentes suelen caber en un solo token. Las raras se parten en varios. Y los espacios cuentan: para casi todos los tokenizadores modernos, ” casa” (con espacio delante) y “casa” son tokens distintos.

Cómo se parte el texto: BPE en dos frases

El algoritmo dominante se llama BPE (byte pair encoding). La idea es sencilla: empieza tratando cada byte como una pieza y, mirando un corpus enorme, va fundiendo los pares de piezas que más veces aparecen juntos. Repite miles de veces. El resultado es un vocabulario donde “the”, “ing” o “ción” acaban siendo una sola pieza porque aparecen sin parar, mientras que una palabra rara sigue troceada.

La consecuencia es directa: el modelo está optimizado para el texto que más vio al entrenarse, y ese texto es mayoritariamente inglés. El español paga el peaje.

Míralo tú mismo

La mejor forma de quitarle la magia es contar tokens con las mismas herramientas que usa la API. Con tiktoken, el tokenizador de los modelos de OpenAI:

import tiktoken

# El mismo codificador que usan los modelos GPT recientes
enc = tiktoken.get_encoding("o200k_base")

def inspeccionar(texto: str) -> None:
    ids = enc.encode(texto)
    # Decodificamos token a token para ver los trozos reales
    trozos = [enc.decode([i]) for i in ids]
    print(f"{len(texto):>3} caracteres → {len(ids):>2} tokens  {trozos}")

inspeccionar("ferrocarril")
inspeccionar("railway")
inspeccionar("responsabilidad")
inspeccionar("responsibility")

Salida (los trozos exactos dependen de la versión del vocabulario):

 11 caracteres →  3 tokens  ['fer', 'roc', 'arril']
  7 caracteres →  1 tokens  ['railway']
 15 caracteres →  4 tokens  ['respons', 'abil', 'idad', ...]
 14 caracteres →  1 tokens  ['responsibility']

Ahí está el problema entero en cuatro líneas. “railway” es un token; su equivalente español, tres. “responsibility” cabe en uno; “responsabilidad” necesita varios. El modelo no ve “ferrocarril”, ve fer + roc + arril, y por eso contar las erres le cuesta: la información de las letras está diluida entre trozos.

Por qué esto te afecta en producción

No es una curiosidad académica. La tokenización toca directamente la factura y el diseño del sistema.

Lo que creesLo que pasa de verdad
Pago por palabrasPagas por tokens, y el español gasta más por idea
El límite de contexto es en caracteresEs en tokens; un texto en español “ocupa” más
Un prompt en español cuesta lo mismo que en inglésPuede costar entre un 30 y un 50 % más en tokens
Truncar por caracteres es seguroPuedes cortar a mitad de token y ensuciar la entrada

Tres implicaciones prácticas. La primera, el coste: si tu producto opera en español, presupuesta más tokens por la misma cantidad de información. La segunda, el contexto: cuando calcules cuánto cabe en la ventana, cuenta tokens con el tokenizador real, no estimes por caracteres. La tercera, los límites raros: si troceas documentos para un RAG, hazlo por tokens, no por número de caracteres, o acabarás partiendo trozos por sitios absurdos.

Trucos que dejan de ser magia

Con el modelo mental correcto, varios comportamientos se vuelven predecibles.

Los números se tokenizan de forma irregular: “2025” puede ser un token y “2026” partirse en dos. Por eso la aritmética con cifras largas es frágil; si necesitas cuentas exactas, dáselas hechas o usa una herramienta.

Los emojis y caracteres poco comunes pueden gastar varios tokens cada uno. Un mensaje corto lleno de emojis puede costar más de lo que parece.

El espacio inicial importa. Al construir prompts o few-shot examples, sé consistente con los espacios: un ” Python” y un “Python” son entradas distintas para el modelo, y esa inconsistencia se paga en calidad.

Y el clásico de contar letras o invertir palabras: no es un fallo de razonamiento, es que la letra individual no es su unidad de trabajo. Si de verdad necesitas operar carácter a carácter, esa lógica va en tu código, no en el prompt.

La regla que me llevo al día a día

Antes de estimar coste, límite de contexto o tamaño de chunk, cuenta tokens con el tokenizador real del modelo que vas a usar. Un len(texto) te miente, sobre todo en español. Son tres líneas de código y te ahorran sorpresas en la factura y recortes a destiempo.

La tokenización no es glamurosa, pero es la lente por la que el modelo mira tu texto. Cuando entiendes cómo parte las palabras, dejas de pelearte con síntomas —cuentas que no cuadran, contextos que se llenan antes de tiempo, respuestas que tropiezan con letras— y empiezas a diseñar contando con ellos.