Todos los desafíos
Intermedio 0 resueltos 0% de aceptación

Muestreo con temperatura y top-k

Elige el siguiente token como un modelo de lenguaje: conserva los k logits más altos, aplica la temperatura y muestrea.

Lo que aprenderás

  • Quedarse con los k mejores tokens candidatos
  • Controlar la aleatoriedad con la temperatura
  • Muestrear de una distribución de probabilidad

Problema

Ver original (inglés)

Los modelos de lenguaje eligen el siguiente token a partir de una distribución de probabilidad. Dos ajustes le dan forma:

  • 'Top-k: conserva solo los k tokens con los logits más altos (con logits iguales, el índice menor queda por delante).'
  • 'Temperatura T: divide los logits conservados entre T antes del softmax. Una T baja hace la elección más predecible y una T alta, más aleatoria.'

Para que el muestreo se pueda probar, el número aleatorio se proporciona:

  1. Conserva los tokens del top-k y lístalos por su índice original (ascendente).
  2. Calcula softmax(logit / T) sobre los tokens conservados (resta el mayor antes de calcular e^x).
  3. Recorre la lista sumando probabilidades; devuelve el índice del primer token en el que el total acumulado supera random_value. Si eso nunca ocurre (redondeo), devuelve el último token conservado.

Con k = 1 esto es decodificación voraz: siempre el token más probable.

Implementa sample_token(logits, temperature, k, random_value).

Entrada

logits: Una puntuación por token del vocabulario.

temperature: T, mayor que 0.

k: Cuántos de los mejores tokens conservar.

random_value: Un número aleatorio en [0, 1).

Salida

Devuelve el índice del token elegido.

Restricciones

1 ≤ k ≤ número de logits ≤ 1.000

0 < temperature ≤ 100, 0 ≤ random_value < 1

-100 ≤ cada logit ≤ 100

Ejemplos

Ejemplo 1
Entrada:
k = 1
logits = [1.0, 3.0, 2.0, 0.5]
temperature = 1.0
random_value = 0.99

Salida esperada:
expected = 1
Entrada:
long long k = 1;
std::vector<double> logits = {1.0, 3.0, 2.0, 0.5};
double temperature = 1.0;
double random_value = 0.99;

Salida esperada:
long long expected = 1;
Entrada:
long k = 1;
double[] logits = new double[] {1.0, 3.0, 2.0, 0.5};
double temperature = 1.0;
double random_value = 0.99;

Salida esperada:
long expected = 1;

Explicación

k = 1 conserva solo el logit más alto, 3.0 en el índice 1. Su probabilidad es 1, así que se elige sin importar el número aleatorio: decodificación voraz.

Ejemplo 2
Entrada:
k = 2
logits = [2.0, 1.0, 0.0]
temperature = 1.0
random_value = 0.8

Salida esperada:
expected = 1
Entrada:
long long k = 2;
std::vector<double> logits = {2.0, 1.0, 0.0};
double temperature = 1.0;
double random_value = 0.8;

Salida esperada:
long long expected = 1;
Entrada:
long k = 2;
double[] logits = new double[] {2.0, 1.0, 0.0};
double temperature = 1.0;
double random_value = 0.8;

Salida esperada:
long expected = 1;

Explicación

El top-2 conserva los índices 0 y 1 (logits 2 y 1). El softmax da aproximadamente 0.731 y 0.269. El total acumulado es 0.731 después del índice 0 (no supera 0.8) y 1 después del índice 1, así que se elige el índice 1.

Referencias

Este reto está adaptado para CodeUtility. Sigue el enunciado y las restricciones indicadas arriba.

Aprende de otros

Soluciones de la comunidad

Aún no hay soluciones publicadas. Resuelve este reto para compartir la primera.