Comenzar con el SDK de inferencia local para Personalizador de Azure AI

Importante

A partir del 20 de septiembre de 2023, no podrá crear nuevos recursos de Personalizer. El servicio Personalizer se va a retirar el 1 de octubre de 2026.

El SDK de inferencia local de Personalizer (versión preliminar) descarga el modelo de Personalizer de manera local y, por tanto, reduce significativamente la latencia de las llamadas Rank al eliminar las llamadas de red. Cada minuto, el cliente descargará el modelo más reciente en segundo plano y lo usará para la inferencia.

En esta guía aprenderá a usar el SDK de inferencia local de Personalizer.

Tendrá que instalar la biblioteca cliente de Personalizer para .NET para:

  • Autenticar el cliente de ejemplo de inicio rápido con un recurso de Personalizer en Azure.
  • Enviar características de contexto y acción a la API Reward, que devolverán la mejor acción del modelo de Personalizer
  • Enviar una puntuación de recompensa a la API Rank y entrene el modelo de Personalizer.

Documentación de referencia | Código fuente de la biblioteca | Paquete (NuGet)

Prerrequisitos

  • Una suscripción a Azure: cree una cuenta gratuita
  • La versión actual de .NET Core.
  • Cuando tenga la suscripción de Azure, cree un recurso de Personalizer en Azure Portal para obtener la clave y el punto de conexión. Tras su implementación, seleccione Ir al recurso.
    • Necesitará la clave y el punto de conexión del recurso que cree para conectar la aplicación a API Personalizer. En una sección posterior de este mismo inicio rápido pegará la clave y el punto de conexión en el código siguiente.
    • Puede usar el plan de tarifa gratis (F0) para probar el servicio y actualizarlo más adelante a un plan de pago para producción.

Instalación

Cambio de la frecuencia de actualización del modelo

En el Azure Portal, vaya a la página Configuración del recurso Personalizer y cambie el valor de Frecuencia de actualización del modelo a 30 segundos. Con esta duración breve, el modelo se entrenará rápidamente, lo que permite ver cómo cambia la acción recomendada en cada iteración.

Change model update frequency

Cambio del tiempo de espera de recompensa

En el Azure Portal, vaya a la página Configuración del recurso de Personalizer y cambie el valor de Tiempo de espera de recompensa a 10 minutos. Esto determina cuánto tiempo esperará el modelo después de enviar una recomendación para recibir los comentarios de recompensa de esa recomendación. El entrenamiento no se producirá hasta que haya transcurrido el tiempo de espera de las recompensas.

Change reward wait time

Creación de una aplicación de C#

Cree una nueva aplicación de consola de .NET Core en el IDE o editor que prefiera.

En una ventana de consola (por ejemplo, cmd, PowerShell o Bash), use el comando new dotnet para crear una nueva aplicación de consola con el nombre personalizer-quickstart. Este comando crea un sencillo proyecto "Hola mundo" de C# con un solo archivo de origen: Program.cs.

dotnet new console -n personalizer-quickstart

Cambie el directorio a la carpeta de aplicaciones recién creada. Para compilar la aplicación:

dotnet build

La salida de la compilación no debe contener advertencias ni errores.

...
Build succeeded.
 0 Warning(s)
 0 Error(s)
...

Instalación de la biblioteca cliente

Dentro del directorio de aplicaciones, instale la biblioteca cliente de Personalizer para .NET con el siguiente comando:

dotnet add package Azure.AI.Personalizer --version 2.0.0-beta.2

Sugerencia

Si usa el IDE de Visual Studio, la biblioteca cliente estará disponible como un paquete de NuGet descargable.

En el directorio del proyecto, abra el archivo Program.cs en el entorno de desarrollo integrado o en el editor que prefiera. Agregue lo siguiente mediante directivas:

using Azure;
using Azure.AI.Personalizer;
using System;
using System.Collections.Generic;
using System.Linq;

Modelo de objetos

El cliente de Personalizer es un objeto PersonalizerClient que se autentica en Azure mediante Azure.AzureKeyCredential, que contiene la clave.

A fin de solicitar el mejor elemento para mostrar al usuario, cree un PersonalizerRankOptions y, a continuación, páselo al método PersonalizerClient.Rank. El método Rank devuelve un PersonalizerRankResult.

Para enviar una puntuación de recompensa a Personalizer, pase el identificador de evento y la puntuación de recompensa al método PersonalizerClient.Reward.

La determinación de la puntuación de recompensa en este inicio rápido no es importante. En un sistema de producción, la determinación de lo que afecta a la puntuación de recompensa y cuánto le afecta, puede ser un proceso complejo que decida cambiar con el tiempo. Esta debe ser una de las decisiones de diseño principales en la arquitectura de Personalizer.

Ejemplos de código

Estos fragmentos de código muestran cómo realizar las siguientes tareas con la biblioteca cliente de Personalizer para .NET:

Autenticar el cliente

En esta sección, hará dos cosas:

  • Especificar la clave y el punto de conexión
  • Creación de un cliente de Personalizer

Para comenzar, agregue las líneas siguientes a la clase Program. Asegúrese de agregar la clave y el punto de conexión del recurso de Personalizer.

Importante

Vaya a Azure Portal. Si el recurso de Personalizer que ha creado en la sección Requisitos previos se ha implementado correctamente, haga clic en el botón Ir al recurso en Pasos siguientes. Puede encontrar su clave y punto de conexión en la página de clave y punto de conexión del recurso, en Administración de recursos.

Recuerde quitar la clave del código cuando haya terminado y no hacerla nunca pública. En el caso de producción, considere la posibilidad de usar alguna forma segura de almacenar las credenciales, y acceder a ellas. Por ejemplo, Azure Key Vault.

private const string ServiceEndpoint  = "https://REPLACE-WITH-YOUR-PERSONALIZER-RESOURCE-NAME.cognitiveservices.azure.com";
private const string ResourceKey = "<REPLACE-WITH-YOUR-PERSONALIZER-KEY>";

A continuación, cree las direcciones URL Rank y Reward. Tenga en cuenta que es necesario establecer useLocalInference: true como parámetro para PersonalizerClientOptions a fin de habilitar la inferencia local.

static PersonalizerClient InitializePersonalizerClient(Uri url)
{
    // Set the local inference flag to true when initializing the client.
    return new PersonalizerClient(url, new AzureKeyCredential(ResourceKey), new PersonalizerClientOptions(useLocalInference: true));
}

Obtención de opciones de contenido representadas como acciones

Las acciones representan las opciones de contenido entre las que quiere que Personalizer seleccione el mejor elemento de contenido. Agregue los métodos siguientes a la clase Program para representar el conjunto de acciones y sus características.

static IList<PersonalizerRankableAction> GetActions()
{
    IList<PersonalizerRankableAction> actions = new List<PersonalizerRankableAction>
    {
        new PersonalizerRankableAction(
            id: "pasta",
            features: new List<object>() { new { taste = "salty", spiceLevel = "medium" }, new { nutritionLevel = 5, cuisine = "italian" } }
        ),

        new PersonalizerRankableAction(
            id: "ice cream",
            features: new List<object>() { new { taste = "sweet", spiceLevel = "none" }, new { nutritionalLevel = 2 } }
        ),

        new PersonalizerRankableAction(
            id: "juice",
            features: new List<object>() { new { taste = "sweet", spiceLevel = "none" }, new { nutritionLevel = 5 }, new { drink = true } }
        ),

        new PersonalizerRankableAction(
            id: "salad",
            features: new List<object>() { new { taste = "salty", spiceLevel = "low" }, new { nutritionLevel = 8 } }
        )
    };

    return actions;
}

Obtención de las preferencias del usuario para el contexto

Agregue los métodos siguientes a la clase Program para obtener una entrada de usuario desde la línea de comandos para la hora del día y la preferencia de gusto del usuario. Se usarán como características de contexto.

static string GetTimeOfDayForContext()
{
    string[] timeOfDayFeatures = new string[] { "morning", "afternoon", "evening", "night" };

    Console.WriteLine("\nWhat time of day is it (enter number)? 1. morning 2. afternoon 3. evening 4. night");
    if (!int.TryParse(GetKey(), out int timeIndex) || timeIndex < 1 || timeIndex > timeOfDayFeatures.Length)
    {
        Console.WriteLine("\nEntered value is invalid. Setting feature value to " + timeOfDayFeatures[0] + ".");
        timeIndex = 1;
    }

    return timeOfDayFeatures[timeIndex - 1];
}
static string GetUsersTastePreference()
{
    string[] tasteFeatures = new string[] { "salty", "sweet" };
    var random = new Random();
    var taste = random.Next(1, 2);

    Console.WriteLine("\nWhat type of food would you prefer (enter number)? 1. salty 2. sweet");
    if (!int.TryParse(GetKey(), out int tasteIndex) || tasteIndex < 1 || tasteIndex > tasteFeatures.Length)
    {
        Console.WriteLine("\nEntered value is invalid. Setting feature value to " + tasteFeatures[0] + ".");
        tasteIndex = 1;
    }

    return tasteFeatures[taste - 1];
}

Ambos métodos usan el método GetKey para leer la selección del usuario desde la línea de comandos.

private static string GetKey()
{
    return Console.ReadKey().Key.ToString().Last().ToString().ToUpper();
}
private static IList<object> GetContext(string time, string taste)
{
    return new List<object>()
    {
        new { time = time },
        new { taste = taste }
    };
}

Creación del bucle de aprendizaje

El bucle de aprendizaje de Personalizer es un ciclo de llamadas Rank y Reward. En este inicio rápido, cada llamada Rank para personalizar el contenido, va seguida de una llamada Reward para indicar a Personalizer cómo es de eficaz el funcionamiento del servicio.

El siguiente código pasa por un ciclo en el que se pregunta al usuario sus preferencias en la línea de comandos, se envía esa información a Personalizer para que seleccione la mejor acción para cada ranura, se presenta la selección al cliente para que elija entre las opciones de la lista y, después, se envía una puntuación de recompensa a Personalizer en la que se señala el grado de acierto que ha tenido el servicio en su selección.

static void Main(string[] args)
{
    Console.WriteLine($"Welcome to this Personalizer Quickstart!\n" +
    $"This code will help you understand how to use the Personalizer APIs (rank and reward).\n" +
    $"Each iteration represents a user interaction and will demonstrate how context, actions, and rewards work.\n" +
    $"Note: Personalizer AI models learn from a large number of user interactions:\n" +
    $"You won't be able to tell the difference in what Personalizer returns by simulating a few events by hand.\n" +
    $"If you want a sample that focuses on seeing how Personalizer learns, see the Python Notebook sample.");

    int iteration = 1;
    bool runLoop = true;

    IList<PersonalizerRankableAction> actions = GetActions();
    PersonalizerClient client = InitializePersonalizerClient(new Uri(ServiceEndpoint));

    do
    {
        Console.WriteLine("\nIteration: " + iteration++);

        string timeOfDayFeature = GetTimeOfDayForContext();
        string deviceFeature = GetUsersTastePreference();

        IList<object> currentContext = GetContext(timeOfDayFeature, deviceFeature);

        string eventId = Guid.NewGuid().ToString();

        var rankOptions = new PersonalizerRankOptions(actions: actions, contextFeatures: currentContext, eventId: eventId);
        PersonalizerRankResult rankResult = client.Rank(rankOptions);

        Console.WriteLine("\nPersonalizer service thinks you would like to have: " + rankResult.RewardActionId + ". Is this correct? (y/n)");

        float reward = 0.0f;
        string answer = GetKey();

        if (answer == "Y")
        {
            reward = 1.0f;
            Console.WriteLine("\nGreat! Enjoy your food.");
        }
        else if (answer == "N")
        {
            reward = 0.0f;
            Console.WriteLine("\nYou didn't like the recommended food choice.");
        }
        else
        {
            Console.WriteLine("\nEntered choice is invalid. Service assumes that you didn't like the recommended food choice.");
        }

        client.Reward(rankResult.EventId, reward);

        Console.WriteLine("\nPress q to break, any other key to continue:");
        runLoop = !(GetKey() == "Q");

    } while (runLoop);
}

Ejecución del programa

Ejecute la aplicación con el comando run dotnet desde el directorio de aplicaciones.

dotnet run

The quickstart program asks a couple of questions to gather user preferences, known as features, then provides the top action.