do_sample.
Un forward de un decoder devuelve logits: un número por cada token del
vocabulario. Ahí termina el modelo. Todo lo que hacen temperature,
top_k, top_p y compañía ocurre entre los logits y el token
elegido. Ninguno toca los pesos.
do_sample | Qué hace | Consecuencia |
|---|---|---|
False |
Coge el token de máxima probabilidad (greedy) | Determinista: la misma entrada da siempre la misma salida |
True |
Muestrea de la distribución | Estocástico: la misma entrada da salidas distintas |
Y aquí el error que más tiempo cuesta: con do_sample=False,
temperature, top_k y top_p no hacen
nada. Recortar y reescalar una distribución de la que solo vas a coger el máximo
no cambia cuál es el máximo.
Esquema del mecanismo, no la salida de ningún modelo.
temperature divide los logits antes del softmax. Menor
que 1 acentúa las diferencias; mayor que 1 las aplana. Tendiendo a cero, equivale a
greedy.top_k se queda con los k más probables.
Conjunto de tamaño fijo.top_p se queda con el conjunto más pequeño cuya
probabilidad acumulada llegue a p. Tamaño variable: pocos
candidatos cuando el modelo está seguro, muchos cuando duda.Si pones los dos, se aplican los dos y el conjunto final es la intersección. No son alternativas.
| Parámetro | Mecanismo | Efecto secundario |
|---|---|---|
repetition_penalty |
Penaliza el logit de los tokens ya aparecidos | Suave; también penaliza palabras que deben repetirse |
no_repeat_ngram_size=n |
Prohíbe repetir cualquier n-grama ya visto | Duro; bloquea repeticiones legítimas (nombres, términos técnicos) |
Uno inclina la balanza, el otro corta. En texto con vocabulario técnico —donde el mismo término aparece muchas veces— la prohibición dura hace más daño que el bucle que venía a evitar.
max_length cuenta el prompt incluido. max_new_tokens
no. Con un prompt de 60 tokens y max_length=50, la generación
termina sin producir nada nuevo y sin lanzar ningún error: devuelve algo que parece
truncado. max_new_tokens es el que hace lo que casi siempre quieres decir.
set_seed solo importa con do_sample=True. En
greedy ya era determinista. Y para comparar dos configuraciones honestamente
hay que fijarla antes de cada generación, no una vez al principio del script.
La guía describe la generación como un bucle de cuatro pasos cuyo tercero es «Muestreo:
elige una palabra basada en configuraciones de creatividad (temperature)»,
pero no activa do_sample en su primer ejemplo. Si el muestreo no está
activo, ese paso 3 no ocurre y la temperatura es decorativa. ¿El texto describe lo que
hace el código, o lo que el autor cree que hace?
Su troubleshooting dice «el texto se repite en bucle → repetition_penalty
no configurado». Los bucles degenerados son el síntoma clásico de la decodificación
greedy. La causa que la tabla no menciona es la primera que hay que mirar, y el
remedio que propone tapa el síntoma sin tocarla.
Sus umbrales: «para tareas lógicas usa temperatura baja (<0.3), para creativas alta (>0.7)». ¿Umbrales de qué modelo? La temperatura opera sobre los logits de una red concreta con un vocabulario concreto: el mismo 0.7 no significa lo mismo en dos modelos distintos. Punto de partida para medir, no constante.
Y la propia guía usa max_length=50 en un ejemplo y
max_new_tokens en los siguientes sin decir nunca que cuentan cosas
distintas. Es el tipo de detalle que se paga con media hora de depurar «por qué no
genera nada».
Antes de mover ningún valor, haz una sola comprobación: genera dos veces con
do_sample=False y dos veces con do_sample=True, misma entrada y
sin cambiar nada más. Anota cuántas de las cuatro salidas son idénticas entre sí. Eso te
fija la línea base.
Después, en el ejercicio del módulo vas a barrer temperature,
top_k, top_p y do_sample y documentar el efecto.
Dos condiciones para que ese barrido signifique algo: fija la semilla antes de cada
generación, y cambia un parámetro cada vez. Un barrido con dos variables
moviéndose a la vez no se puede leer.