Temperatura, top-k y top-p: generación de texto con Grandes Modelos de Lenguaje

En este artículo veremos cómo controlar la aleatoriedad del texto generado por los Grandes Modelos de Lenguaje usando la temperatura y los muestreos top-k y top-p.

¡Así que listo, comencemos!

Video

Como siempre, en el canal de YouTube se encuentra el video de este post:

Introducción

Los Grandes Modelos de Lenguaje (o LLMs por sus siglas en Inglés: Large Language Models) contienen una serie de parámetros que permiten controlar la calidad y la creatividad del texto generado.

Estos parámetros son la temperatura, el muestreo top-k y el muestreo top-p y son valores que nosotros podemos definir al momento de solicitarle al modelo la generación de texto, así que es clave conocer estos parámetros al momento de construir aplicaciones basadas en estos Grandes Modelos de Lenguaje.

Entonces que en este artículo veremos qué son la temperatura y los muestreos top-k y top-p y el efecto que estos valores tienen en el texto generado por los Grandes Modelos de Lenguaje.

¿Cómo generan texto los LLMs?

Para entender qué son la temperatura y los muestreos top-k y top-p debemos entender el principio de generación de texto de los Grandes Modelos de Lenguaje.

Estos modelos son entrenados, entre otras cosas, para generar texto en lenguaje natural, que consiste en predecir manera recursiva la siguiente palabra en una secuencia de texto.

Por ejemplo, supongamos que introducimos a uno de estos modelos la frase “a los gatos les gusta” y que queremos que el modelo prediga la siguiente palabra.

Tanto a la entrada como a la salida el modelo utiliza una representación intermedia del texto, que se conoce como tokens. Pero para no confundirnos con este detalle nos enfocaremos únicamente en el texto de entrada y el texto generado por el modelo, obviando este procesamiento intermedio a través de tokens.

Cuando el modelo recibe el texto de entrada lo procesa a través de una Red Transformer y a la salida realmente no genera una única palabra sino un conjunto de palabras, y cada palabra tiene asociada una probabilidad de ocurrencia.

Por ejemplo, volviendo a la frase de entrada “a los gatos les gusta”, tras procesarla el modelo genera por ejemplo un total de 18 palabras candidatas (comer, jugar, dormir, abrazar, ronronear, etc.) cada una de las cuales tiene una probabilidad asociada, como vemos a continuación:

Palabra Probabilidad
comer 0,135
jugar 0,125
dormir 0,115
abrazar 0,095
ronronear 0,085
maullar 0,075
acariciar 0,065
acostarse 0,045

Estas probabilidades son simplemente valores numéricos entre 0 y 1 y si sumamos todas estas probabilidades obtendremos un resultado exactamente igual a 1.

Cada uno de estos valores nos indica qué tan probable es encontrar cada palabra candidata en el lenguaje natural y para calcular estas probabilidades el modelo tiene en cuenta el significado completo de la frase introducida por el usuario.

Así, una probabilidad cercana a 1 nos indica que es altamente probable encontrar esa palabra en el lenguaje natural, mientras que una probabilidad muy cercana a 0 indica que es poco común encontrar esa palabra junto al texto de entrada.

Y luego la idea es que el modelo debe seleccionar una de estas palabras candidatas la cual corresponderá a la palabra predicha.

En este último paso podríamos pensar que esta selección equivaldría simplemente a aquella palabra más probable ( que en nuestro ejemplo sería la palabra “comer”, pues tiene la probabilidad de ocurrencia más alta).

Sin embargo esto no es del todo cierto y aquí es donde entran en juego el parámetro temperatura y los muestreos top-k y top-p que en últimas determinarán cuál de todas las palabras candidatas será elegida y por tanto generada por el modelo.

Así que teniendo esto en cuenta, entendamos qué son estos parámetros y cómo afectan la generación de texto.

La temperatura

La temperatura es simplemente un número mayor que 0 y menor que 1 que permite escalar la distribución de probabilidades de la que hablamos hace un momento.

Un valor de temperatura cercano a 0 hace que la palabra con la probabilidad más alta en la distribución original tenga, tras el escalamiento, un valor muy cercano a 1 mientras que las palabras restantes tendrán valores cercanos a 0.

Por ejemplo, si volvemos a nuestro listado de 18 palabras candidatas, originalmente la palabra “comer” era la más probable con una probabilidad de 0.135. Pero ahora, usando una temperatura muy cercana a 0, la probabilidad es de 0.9999 y todas las demás palabras tienen una probabilidad de prácticamente igual a 0.

¿Y qué quiere decir que una de las palabras candidatas tenga una probabilidad de ocurrencia tan alta, es decir muy cercana a 1? Pues que al momento de escoger la palabra para completar el texto de entrada lo más probable es que el modelo seleccione precisamente la palabra “comer”.

Todo esto quiere decir que con una temperatura cercana a 0 tendremos un modelo más determinístico: es decir poco aleatorio, lo cual quiere decir que el modelo no será tan “creativo” en el uso del lenguaje.

Analicemos ahora la otra situación extrema: supongamos ahora que la temperatura tiene un valor muy cercano a 1.

De nuevo, al generar la distribución de probabilidades tendremos las 18 palabras pero ahora observamos que sus probabilidades son muy similares. Así que al momento de determinar la siguiente palabra a predecir, el modelo tendrá más opciones para escoger, pues buena parte de las palabras candidatas tienen probabilidades similares.

Esto quiere decir que con una temperatura cercana a 1 tendremos un modelo más aleatorio: es decir que el modelo será más “creativo” al momento de generar el texto porque al momento de predecir cada palabra considerará un mayor grupo de palabras candidatas.

Entonces, en resumen: con una temperatura cercana a 0 tendremos un modelo que genera texto de forma más determinística (es decir más predecible) mientras que con una temperatura cercana a 1 la generación de texto será más aleatoria (es decir más impredecible).

Pero además, este parámetro de la temperatura lo podemos mezclar por ejemplo con el muestreo top-k, del cual hablaremos a continuación.

El muestreo top-k

Para entender en qué consiste el muestreo top-k volvamos a la distribución de probabilidades de las palabras candidatas que teníamos originalmente cuando ingresamos la frase “a los gatos les gusta”:

Palabra Probabilidad
comer 0,135
jugar 0,125
dormir 0,115
abrazar 0,095
ronronear 0,085
maullar 0,075
acariciar 0,065
acostarse 0,045

En principio esta distribución contiene un total de 18 palabras, así que el modelo tendría, en principio, la libertad de escoger cualquiera de estas.

Pero resulta que podemos también limitar ese listado de palabras candidatas a sólo unas cuantas. Por ejemplo, podemos indicarle que en lugar de considerar las 18 palabras tenga en cuenta únicamente las 5 más probables al momento de la generación.

¿Y cómo controlamos este comportamiento? Pues precisamente usando el muestreo top-k que hace referencia a que el modelo escogerá las “k” mejores palabras a partir de la distribución de probabilidad original.

Entonces, cuando usamos el muestreo top-k lo que hace el modelo es:

  1. Generar la distribución de probabilidad para un valor específico de temperatura
  2. Organizar de manera descendente cada palabra de acuerdo a su probabilidad de ocurrencia
  3. Seleccionar las primeras k palabras de dicha distribución
  4. Seleccionar aleatoriamente una de estas k palabras

Por ejemplo, si fijamos el parámetro k con un valor de 5 el nuevo conjunto de palabras candidatas sería comer, jugar, dormir, abrazar y ronronear y el modelo hará la predicción de la siguiente palabra escogiendo aleatoriamente una de estas 5 palabras candidatas.

Y acá vemos que aunque la selección de la palabra generada es aleatoria realmente estamos limitando esta selección a las palabras más probables, así que la generación de texto no es del todo aleatoria.

Y con esto podemos ver que dependiendo del valor que escojamos para el parámetro k podremos controlar la aleatoriedad del texto generado.

Por ejemplo, si escogemos un valor extremo de k=1 el modelo siempre escogerá la palabra con la probabilidad más alta y por tanto la generación de texto será determinística.

Por otra parte, si para nuestro ejemplo fijamos el valor de k en 18 el modelo podrá escoger cualquiera de las 18 palabras candidatas al momento de generar el texto, es decir que la generación tendrá un comportamiento totalmente aleatorio.

El muestreo top-p

Una tercera forma de controlar esta aleatoriedad es usando el muestreo top-p.

En este caso lo que hacemos es definir un umbral, es decir un valor entre 0 y 1, que corresponde a una probabilidad acumulada. Y las palabras candidatas cuyas probabilidades sumen al menos esa probabilidad acumulada serán las únicas tenidas en cuenta por el modelo al momento de generar la siguiente palabra.

Entendamos esto con un ejemplo: volvamos a la distribución original de probabilidades que teníamos para un valor determinado de temperatura:

Palabra Probabilidad
comer 0,135
jugar 0,125
dormir 0,115
abrazar 0,095
ronronear 0,085
maullar 0,075
acariciar 0,065
acostarse 0,045

Y supongamos que definimos un umbral p = 0.3 con base en el cual haremos el muestreo top-p. Esto quiere decir que, para generar la siguiente palabra, el modelo debe hacer lo siguiente:

  1. Tomar la distribución original y organizarla de manera descendente: de la palabra más probable a la menos probable.
  2. Crear un nuevo listado de palabras candidatas, que inicialmente estará vacío. Para ello se añaden iterativamente una a una las palabras sumando en cada iteración el valor correspondiente de la probabilidad. Las iteraciones se detienen cuando se sobrepasa el valor de p definido anteriormente.

Así por ejemplo, en la primera iteración se añade la palabra “comer” al nuevo listado de candidatas, y la suma de probabilidades será en este caso 0.135. Com este valor es inferior a p=0.3 continuarán las iteraciones

En la segunda iteración se añade la palabra “jugar” cuya probabilidad es 0.125. Esto quiere decir que ahora la probabilidad acumulada es 0.135 + 0.125 = 0.26. Como este valor sigue siendo menor que p = 0.3, continuarán las iteraciones.

En la tercera iteración se añade la palabra “dormir” con una probabilidad de 0.115. Ahora la probabilidad acumulada será de 0.135 + 0.125 + 0.115 = 0.375. Como este valor sobrepasa el límite de p = 0.3 en este punto se detienen las iteraciones.

Entonces, como resultado de este muestreo top-p tendremos ahora sólo tres palabras candidatas: comer, jugar y dormir. Y para finalizar, la palabra generada se escoge aleatoriamente de este nuevo listado.

Entonces vemos que el muestreo top-p es otra una manera de controlar la aleatoriedad del texto generado por el modelo.

En esencia: si el valor de “p” es pequeño (cercano a 0) las palabras candidatas consideradas por el modelo serán muy pocas y por tanto el modelo terminará escogiendo casi siempre las mismas palabras. Es decir tendremos una generación de texto determinística.

Y por el contrario, si el valor de “p” es relativamente grande (cercano a 1) el modelo tendrá en cuenta prácticamente todas las palabras candidatas al momento de la generación y por tanto la generación de texto será mucho más aleatoria.

Así que en este punto ya tenemos claro el significado y el impacto que tienen la temperatura y los muestreos top-k y top-p en la generación de texto de los modelos.

En la práctica podemos jugar un poco con estos parámetros para controlar el nivel de aleatoriedad en el texto generado por el modelo, como lo vamos a ver a continuación.

Ejemplo: controlando la aleatoriedad del texto generado

Tanto la temperatura como los valores de k y p los podemos definir bien sea en la solicitud (o prompt) hecha a la aplicación (en caso de que estemos usando por ejemplo ChatGPT o Bard) o en el mismo código que estemos desarrollando si nosotros mismos estamos construyendo la aplicación con base en alguno de los Grandes Modelos de Lenguaje disponibles.

Por ejemplo, supongamos que usamos Bard (de Google) para generar una corta estrofa de una canción, comenzando con la frase “la luna oculta” y supongamos además que usamos diferentes valores de temperatura, de k y de p.

En un primer caso le podemos decir por ejemplo al modelo: “Escriba una corta estrofa de una canción comenzando con la frase “la luna oculta…”. Use una temperatura de 0.2, un muestreo top-k con un valor de k=2 y un muestreo top-p con un valor de p=0.1”

Observemos que estamos usando valores relativamente bajos para estos tres parámetros, así que el texto generado será más determinista. Como resultado de esto obtenemos esta estrofa:

“La luna oculta tras las nubes Su luz brumosa ilumina la noche Un secreto que guarda para nosotros Un misterio que nos hace soñar”

Vemos que sí tiene algo de lírica pero que el texto es bastante descriptivo y, digámoslo así, poco creativo: la luna oculta tras las nubes, la luz de la luna que ilumina la noche.

Ahora incrementemos los valores de temperatura y de los parámetros k y p para generar un texto un poco más aleatorio (es decir más creativo). Escribamos el siguiente prompt:

“Ahora escriba una nueva estrofa corta de una canción comenzando con la frase “la luna oculta…” pero en este caso use una temperatura de 0.9, un muestreo top-k con un valor de k=15 y un muestreo top-p con un valor de p=0.8”.

En este caso la estrofa generada por Bard es la siguiente:

“La luna oculta tras el velo de la noche Su luz tenue baña el mundo de sombras Como un sueño que se desvanece Como un deseo que nunca se cumple”

Observemos que aparecen términos como “el velo de la noche” o “el mundo de sombras” o “el sueño que se desvanece”. Definitivamente se trata de un texto mucho más creativo!

Conclusión

Bien, acabamos de entender estos tres sencillos conceptos de temperatura y muestreo top-k y top-p que nos permiten controlar la aleatoriedad del texto generado por estos modelos de lenguaje.

En últimas vimos que valores relativamente pequeños para la temperatura, k y p hacen que el texto sea más determinista, mientras que al incrementar estos valores haremos que el texto generado sea más aleatorio.

Y estos parámetros los podemos definir directamente al momento de introducir el prompt o la solicitud que hagamos al modelo, o en el código que estemos implementando al momento de desarrollar la aplicación, mientras que los valores que escojamos para estos parámetros dependerán de las características que queramos para ese texto generado por el modelo de lenguaje.