Ir al contenido
wannacode

Los límites del modelo

En resumen: Un modelo de lenguaje alucina: escribe con seguridad cosas plausibles pero falsas, porque predice texto probable en lugar de comprobar la verdad; por eso la respuesta se contrasta con la fuente.

Problema

Treinta días que no existen

El asistente de soporte le responde a un cliente: «La chaqueta se puede devolver dentro de 30 días desde la entrega». La respuesta es amable, fluida y segura. La política de la tienda dice 14 días.

El día veinte el cliente envía la chaqueta de vuelta. El almacén rechaza la devolución, y el cliente escribe una reseña de una estrella citando al asistente.

Nadie programó «30 días». ¿De dónde salió el número y cómo te proteges del siguiente?

La idea

El modelo escribe texto probable, no hechos comprobados

Un modelo de lenguaje se entrena para continuar un texto con una palabra siguiente probable. No guarda una tabla de hechos y no comprueba su respuesta. Si en su texto de entrenamiento a «en» le sigue siempre un número, pondrá un número ahí. Cuál, lo decide la probabilidad, no la política de la tienda.

Una respuesta fluida y segura que es falsa o inventada se llama alucinación. No es un error que un solo parche arregle. Viene de la propia forma en que el modelo escribe: para él, la frase verdadera y la falsa son solo texto más probable y menos probable.

Míralo

Un modelo pequeño que promete lo que no es

El modelo de la lección sobre el siguiente token, en su forma más pequeña: para cada palabra guarda las palabras que la siguieron en el texto. Las repeticiones se quedan, así que una palabra más frecuente se sortea más a menudo.

# para cada palabra: las palabras que la siguieron en el texto
def train(corpus):
follows = {}
for sentence in corpus:
words = (sentence + " .").split(" ")
for word, after in zip(words, words[1:]):
follows.setdefault(word, []).append(after)
return follows

El texto son diez frases del soporte de la tienda:

corpus = [
"la devolución es en 14 días",
"la entrega a valencia es en 2 días",
"el reembolso es en 5 días hábiles",
"la garantía es de 24 meses",
"el pago con tarjeta es seguro",
"un pedido de más de 50 euros se envía gratis",
"un paquete rechazado vuelve en 7 días",
"la entrega a sevilla es en 3 días",
"el mensajero llama antes de la entrega",
"la entrega a madrid es en 2 días",
]

La palabra más probable cada vez:

# la más común (en caso de empate, la primera del texto)
def most_common(options):
return max(options, key=options.count)
def greedy(follows, start):
words = start.split(" ")
while len(words) < 12:
last = words[-1]
word = most_common(follows[last])
if word == ".":
break
words.append(word)
return " ".join(words)

Y sorteada por probabilidad, con un generador de números aleatorios de semilla fija, para que la salida sea la misma en cada ejecución:

def sample(follows, start, rng):
words = start.split(" ")
while len(words) < 12:
options = follows[words[-1]]
word = options[int(rng.next() * len(options))]
if word == ".":
break
words.append(word)
return " ".join(words)
follows = train(corpus)
print("la palabra más probable cada vez:")
print(" " + greedy(follows, "la devolución"))
print("seis ejecuciones, la palabra se sortea por probabilidad:")
rng = Rng(3876)
for i in range(1, 7):
answer = sample(follows, "la devolución", rng)
mark = "está en el texto" if answer in corpus else "no está en el texto"
print(f" {i}. {answer} ({mark})")
Salida
la palabra más probable cada vez:
la devolución es en 2 días
seis ejecuciones, la palabra se sortea por probabilidad:
1. la devolución es seguro (no está en el texto)
2. la devolución es en 2 días (no está en el texto)
3. la devolución es en 14 días (está en el texto)
4. la devolución es en 5 días (no está en el texto)
5. la devolución es seguro (no está en el texto)
6. la devolución es de 24 meses (no está en el texto)

La respuesta más probable es «la devolución es en 2 días», y el texto dice 14. De las seis respuestas sorteadas solo una es una frase del texto (la tercera). Las otras cinco son falsas, y suenan bien casi todas: «en 5 días» es del reembolso, «de 24 meses» de la garantía, «en 2 días» de la entrega, y «es seguro» (salió dos veces) viene del pago con tarjeta, aunque ni siquiera concuerda con «la devolución».

Míralo

De dónde salió el número

# la más común (en caso de empate, la primera del texto)
def most_common(options):
return max(options, key=options.count)
def greedy(follows, start):
words = start.split(" ")
while len(words) < 12:
last = words[-1]
word = most_common(follows[last])
if word == ".":
break
words.append(word)
return " ".join(words)
Paso a paso, en palabras
  1. El modelo continúa «la devolución» cada vez con la palabra siguiente más común.
  2. «es en» está en 5 frases, una de ellas sobre la devolución. Hasta aquí es verdad.
  3. Después de «en» la palabra más común es «2»: viene de las dos frases sobre la entrega.
  4. Luego el punto. Una frase fluida que no está en el texto: «la devolución es en 2 días».
  5. La comprobación toma los números de la respuesta y de la política de devoluciones.
  6. 2 no está en la política. Dice 14 días.
  7. Cada par de palabras sale del texto de la tienda. La frase entera es falsa, y suena tan segura como una verdadera.

Cada par de palabras de la respuesta es verdadero en algún lugar del texto. La frase entera no es verdadera en ninguno. Los modelos grandes miran mucho más que una palabra atrás y se equivocan bastante menos, pero el principio es el mismo: escriben lo probable, no lo comprobado.

Pruébalo

Predice la salida

El modelo se entrena con tres frases. ¿Qué escribirá con la palabra más probable cada vez, si empieza por las palabras de la entrega?

corpus = [
"la entrega a madrid es en 2 días",
"la entrega a sevilla es en 3 días",
"el cambio de talla es en 3 días",
]
print(greedy(train(corpus), "la entrega"))
Respuesta

La idea

La misma pregunta, otra respuesta

Cuando la palabra se sortea por probabilidad, cada ejecución puede dar otra respuesta. En el programa las seis ejecuciones dieron cinco frases distintas. Eso es el no determinismo: la misma entrada, otra salida. Las pruebas, los registros y las quejas de clientes se vuelven más difíciles, porque «en mi máquina funciona» ya no significa nada.

La temperatura 0 (la palabra más probable cada vez) hace la respuesta repetible, pero no correcta. Con la palabra más probable, el programa dio «la devolución es en 2 días» cada vez. Con proveedores reales, ni la temperatura 0 promete una respuesta del todo idéntica: los cálculos en el servidor no siempre se ejecutan en el mismo orden.

La idea

La fecha de corte del conocimiento

El modelo solo conoce el texto con el que se entrenó. Ese texto se reunió hasta cierta fecha, la fecha de corte del conocimiento. Lo que pasó después, el modelo no lo sabe: la política de devoluciones nueva, el producto nuevo, el precio de hoy.

Y no sabe nada de lo que nunca estuvo en su texto: el estado del pedido 1042 está en la base de datos de la tienda, no en el modelo. Por defecto el modelo no dice «No lo sé». Escribe una respuesta probable, y de ahí sale un «llega mañana» que nadie comprobó.

Por eso los hechos van en la petición: la política como texto en el prompt, el estado del pedido desde el programa. Cómo pide el modelo el estado por sí mismo está en la lección sobre tool use.

La idea

Comprobar la respuesta con la fuente

Cuando la respuesta debe apoyarse en un documento, el programa puede comprobar al menos una parte. La comprobación más tosca: cada número de la respuesta debe estar en la fuente.

# cada número de la respuesta debe estar en la fuente
def check(answer, source):
known = numbers(source)
claimed = numbers(answer)
if not claimed:
return "? no hay número que comprobar"
for n in claimed:
if n not in known:
return f"✗ {n} no está en la fuente"
return "✓ los números están en la fuente"
def numbers(text):
words = [w.strip(".,") for w in text.split(" ")]
return [w for w in words if w.isdigit()]

Las seis respuestas del programa anterior contra la política de devoluciones:

source = "La devolución es en 14 días. El reembolso es en 5 días hábiles."
answers = [
"la devolución es seguro",
"la devolución es en 2 días",
"la devolución es en 14 días",
"la devolución es en 5 días",
"la devolución es seguro",
"la devolución es de 24 meses",
]
for a in answers:
print(f"{a} → {check(a, source)}")
Salida
la devolución es seguro → ? no hay número que comprobar
la devolución es en 2 días → ✗ 2 no está en la fuente
la devolución es en 14 días → ✓ los números están en la fuente
la devolución es en 5 días → ✓ los números están en la fuente
la devolución es seguro → ? no hay número que comprobar
la devolución es de 24 meses → ✗ 24 no está en la fuente

La comprobación atrapó dos respuestas falsas: la de 2 días (segunda ejecución) y la de 24 meses (sexta). Pero dejó pasar «la devolución es en 5 días» (cuarta ejecución): el 5 está en la política, solo que es para el reembolso. Esa ejecución pasa la comprobación por la razón equivocada. Y sobre «la devolución es seguro» (primera y quinta) no puede decir nada, porque no tiene ningún número. Solo la tercera ejecución (14) pasa con razón. Una comprobación tosca baja el riesgo sin eliminarlo. Por eso los sistemas reales tienen varias comprobaciones, y donde un error sale caro, mira una persona.

Pruébalo

Encuentra el error

Un colega simplifica la comprobación. Ahora la respuesta «la devolución es en 4 días» pasa como correcta, aunque la política dice 14. ¿Qué línea tiene el error?

Elige la línea con el error.

Pruébalo

Completa

El modelo termina la frase cuando la palabra siguiente más probable es el final. ¿Cómo se ve el final en el texto de entrenamiento?

def greedy(follows, start):
    words = start.split(" ")
    while len(words) < 12:
        last = words[-1]
        word = most_common(follows[last])
        if word == :
            break
        words.append(word)
    return " ".join(words)

La idea

Cuándo un modelo de lenguaje es la herramienta equivocada

  • Hay una respuesta exacta que se puede calcular. El total del pedido, el IVA, el saldo de una cuenta. Una línea de código no se equivoca; el modelo puede equivocarse en un dígito.
  • Los datos están en vivo. El estado del pedido, el stock, el precio de hoy. Están en la base de datos. El modelo puede pedirlos mediante una herramienta, pero no debe «recordarlos».
  • La regla es firme. «Devolución en 14 días» es un if, no un prompt. Lo que siempre debe ser igual se escribe en el código.
  • La decisión debe poder explicarse y revisarse después. Un pago o un préstamo rechazado necesita una razón que se repita. Para esas decisiones hay modelos como la regresión logística, y las reglas se escriben de forma explícita.
  • Un error cuesta más que el silencio. Respuestas médicas, legales o financieras a un cliente. Entonces el modelo escribe un borrador y una persona decide.

Donde el modelo es fuerte: borradores, resúmenes, traducción, clasificar texto libre (para qué área es el correo), extraer datos de un texto, respuestas a partir de un documento que se comprueban. Tareas donde una pequeña imprecisión se detecta fácilmente y no cuesta mucho.

Más precisamente, para curiosos

Por qué alucinan también los modelos grandes. Se entrenan con un texto enorme, y después un poco más para seguir instrucciones y decir «No lo sé». Eso baja los errores pero no los elimina: el modelo sigue eligiendo texto probable. Son especialmente peligrosos los datos raros (el número de un artículo de ley, una cita, el nombre de una función en una biblioteca pequeña), de los que el texto de entrenamiento tiene pocos ejemplos.

Qué ayuda, por capas. Hechos en la petición (la política como texto; el módulo posterior del curso sobre búsqueda semántica y RAG hace justamente eso). Salida con un esquema y una comprobación en el código (salida estructurada). Un conjunto de pruebas de preguntas con respuestas correctas, que se ejecuta en cada cambio (evaluación). Una respuesta «No lo sé, te paso con un colega» cuando la comprobación falla. Y una persona donde un error sale caro.

Qué tan pequeño es el modelo de aquí. El modelo de bigramas recuerda una palabra hacia atrás y está entrenado con diez frases. Un modelo grande mira miles de tokens hacia atrás y está entrenado con billones. Por eso rara vez arma «la devolución es en 2 días» a partir de dos frases. Pero cuando el contexto no tiene respuesta, igual escribe la continuación más probable, no «No lo sé».

Medir las alucinaciones. La proporción de respuestas falsas depende de la tarea y de los datos. Los números de pruebas ajenas no dicen nada de tu asistente. Los mides tú, con tus preguntas, como en la lección sobre evaluación.

Ejercicio

Las respuestas sobre la entrega

Resuelve la tarea en tu editor.

El asistente responde sobre la entrega, y la fuente dice: «La entrega a Madrid tarda hasta 2 días hábiles. A Sevilla tarda hasta 3 días hábiles. Desde 50 euros la entrega es gratis». Comprueba cinco respuestas con la misma regla (cada número de la respuesta debe estar en la fuente) e imprime el veredicto de cada una:

  • La entrega a Madrid tarda hasta 2 días.
  • La entrega a Sevilla tarda hasta 4 días.
  • La entrega es gratis desde 30 euros.
  • La entrega a Valencia tarda hasta 1 día.
  • La entrega es gratis para todos los pedidos.
Salida
La entrega a Madrid tarda hasta 2 días. → ✓ los números están en la fuente
La entrega a Sevilla tarda hasta 4 días. → ✗ 4 no está en la fuente
La entrega es gratis desde 30 euros. → ✗ 30 no está en la fuente
La entrega a Valencia tarda hasta 1 día. → ✗ 1 no está en la fuente
La entrega es gratis para todos los pedidos. → ? no hay número que comprobar

La última respuesta es falsa, y la comprobación no puede atraparla: no tiene ningún número.

Más tareas

  • El número en su lugar. Comprueba no solo que el número esté, sino también la palabra anterior: «hasta 2» para Madrid. ¿Qué respuestas atrapa ahora?
  • Rechazo. Cuando la comprobación falla, el programa devuelve «Te comunico con un colega.» en lugar de la respuesta del modelo.

Test

Ponte a prueba

1. ¿Qué es una alucinación de un modelo de lenguaje?
2. Pones la temperatura en 0 y el asistente da la misma respuesta cada vez. ¿Significa eso que la respuesta es correcta?
3. La política de devoluciones cambió ayer. ¿Por qué el modelo todavía dice la anterior?
4. La comprobación «¿están los números de la respuesta en la fuente?» dejó pasar «la devolución es en 5 días». ¿Por qué?
5. ¿Para qué tarea un modelo de lenguaje es la herramienta equivocada?

Creado por Ivo Gergov como parte de la campaña de Evo Tech por una educación accesible en programación ·