Skip to content

Commit 8c6138e

Browse files
authored
Merge pull request #210280 from orenmichaely/ormichae/localinfqs
Ormichae/localinfqs
2 parents 8bc39c7 + 9ad9bbd commit 8c6138e

File tree

3 files changed

+320
-0
lines changed

3 files changed

+320
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
title: How to use local inference with the Personalizer SDK
3+
description: Learn how to use local inference to improve latency.
4+
services: cognitive-services
5+
author: jcodella
6+
ms.author: jacodel
7+
manager: nitinme
8+
ms.service: cognitive-services
9+
ms.subservice: personalizer
10+
ms.topic: quickstart
11+
ms.date: 09/06/2022
12+
---
13+
14+
# Get started with the local inference SDK for Azure Personalizer
15+
16+
The Personalizer local inference SDK (Preview) downloads the Personalizer model locally, and thus significantly reduces the latency of Rank calls by eliminating network calls. Every minute the client will download the most recent model in the background and use it for inference.
17+
18+
In this guide, you'll learn how to use the Personalizer local inference SDK.
19+
20+
[!INCLUDE [Try local inference with C#](./includes/quickstart-local-inference-csharp.md)]
Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
---
2+
title: include file
3+
description: include file
4+
services: cognitive-services
5+
author: jcodella
6+
ms.author: jacodel
7+
manager: nitinme
8+
ms.service: cognitive-services
9+
ms.subservice: personalizer
10+
ms.topic: include
11+
ms.date: 09/06/2022
12+
---
13+
14+
You will need to install the Personalizer client library for .NET to:
15+
* Authenticate the quickstart example client with a Personalizer resource in Azure.
16+
* Send context and action features to the Reward API, which will return the best action from the Personalizer model
17+
* Send a reward score to the Rank API and train the Personalizer model.
18+
19+
[Reference documentation](/dotnet/api/Microsoft.Azure.CognitiveServices.Personalizer) | [Library source code](https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/personalizer) | [Package (NuGet)](https://www.nuget.org/packages/Azure.AI.Personalizer/2.0.0-beta.2)
20+
21+
## Prerequisites
22+
23+
* Azure subscription - [Create one for free](https://azure.microsoft.com/free/cognitive-services)
24+
* The current version of [.NET Core](https://dotnet.microsoft.com/download/dotnet-core).
25+
* Once you have your Azure subscription, <a href="https://portal.azure.com/#create/Microsoft.CognitiveServicesPersonalizer" title="Create a Personalizer resource" target="_blank">create a Personalizer resource </a> in the Azure portal to get your key and endpoint. After it deploys, click **Go to resource**.
26+
* You will need the key and endpoint from the resource you create to connect your application to the Personalizer API. You'll paste your key and endpoint into the code below later in the quickstart.
27+
* You can use the free pricing tier (`F0`) to try the service, and upgrade later to a paid tier for production.
28+
29+
## Setting up
30+
31+
[!INCLUDE [Change model frequency](change-model-frequency.md)]
32+
33+
[!INCLUDE [Change reward wait time](change-reward-wait-time.md)]
34+
35+
### Create a new C# application
36+
37+
Create a new .NET Core application in your preferred editor or IDE.
38+
39+
In a console window (such as cmd, PowerShell, or Bash), use the dotnet `new` command to create a new console app with the name `personalizer-quickstart`. This command creates a simple "Hello World" C# project with a single source file: `Program.cs`.
40+
41+
```console
42+
dotnet new console -n personalizer-quickstart
43+
```
44+
45+
Change your directory to the newly created app folder. You can build the application with:
46+
47+
```console
48+
dotnet build
49+
```
50+
51+
The build output should contain no warnings or errors.
52+
53+
```console
54+
...
55+
Build succeeded.
56+
0 Warning(s)
57+
0 Error(s)
58+
...
59+
```
60+
61+
### Install the client library
62+
63+
Within the application directory, install the Personalizer client library for .NET with the following command:
64+
65+
```console
66+
dotnet add package Azure.AI.Personalizer --version 2.0.0-beta.2
67+
```
68+
69+
> [!TIP]
70+
> If you're using the Visual Studio IDE, the client library is available as a downloadable NuGet package.
71+
72+
From the project directory, open the `Program.cs` file in your preferred editor or IDE. Add the following using directives:
73+
74+
```csharp
75+
using Azure;
76+
using Azure.AI.Personalizer;
77+
using System;
78+
using System.Collections.Generic;
79+
using System.Linq;
80+
```
81+
82+
## Object model
83+
84+
The Personalizer client is a [PersonalizerClient](/dotnet/api/azure.ai.personalizer.personalizerclient?view=azure-dotnet-preview&branch=main) object that authenticates to Azure using Azure.AzureKeyCredential, which contains your key.
85+
86+
To ask for the single best item to show th user, create a [PersonalizerRankOptions](/dotnet/api/azure.ai.personalizer.personalizerrankoptions?view=azure-dotnet-preview&branch=main), then pass it to [PersonalizerClient.Rank](/dotnet/api/azure.ai.personalizer.personalizerclient.rank?view=azure-dotnet-preview&branch=main#azure-ai-personalizer-personalizerclient-rank(azure-ai-personalizer-personalizerrankoptions-system-threading-cancellationtoken)) method. The Rank method returns a [PersonalizerRankResult](/dotnet/api/azure.ai.personalizer.personalizerrankresult?view=azure-dotnet-preview&branch=main).
87+
88+
To send a reward score to Personalizer, pass the event ID and the reward score to the [PersonalizerClient.Reward](/dotnet/api/azure.ai.personalizer.personalizerclient.reward?view=azure-dotnet-preview&branch=main#azure-ai-personalizer-personalizerclient-reward(system-string-system-single-system-threading-cancellationtoken) method.
89+
90+
Determining the reward score, in this quickstart is trivial. In a production system, the determination of what impacts the [reward score](../concept-rewards.md) and by how much can be a complex process, that you may decide to change over time. This design decision should be one of the primary decisions in your Personalizer architecture.
91+
92+
93+
## Code examples
94+
95+
These code snippets show you how to do the following tasks with the Personalizer client library for .NET:
96+
97+
* [Create a Personalizer client](#authenticate-the-client)
98+
* Multi-Slot Rank API
99+
* Multi-Slot Reward API
100+
101+
102+
## Authenticate the client
103+
104+
In this section you'll do two things:
105+
* Specify your key and endpoint
106+
* Create a Personalizer client
107+
108+
Start by adding the following lines to your Program class. Make sure to add your key and endpoint from your Personalizer resource.
109+
110+
[!INCLUDE [Personalizer find resource info](find-azure-resource-info.md)]
111+
112+
```csharp
113+
private const string ServiceEndpoint = "https://REPLACE-WITH-YOUR-PERSONALIZER-RESOURCE-NAME.cognitiveservices.azure.com";
114+
private const string ResourceKey = "<REPLACE-WITH-YOUR-PERSONALIZER-KEY>";
115+
```
116+
117+
Next, construct the Rank and Reward URLs.
118+
119+
```csharp
120+
static PersonalizerClient InitializePersonalizerClient(Uri url)
121+
{
122+
return new PersonalizerClient(url, new AzureKeyCredential(ResourceKey));
123+
}
124+
```
125+
126+
## Get content choices represented as actions
127+
128+
Actions represent the content choices from which you want Personalizer to select the best content item. Add the following methods to the Program class to represent the set of actions and their features.
129+
130+
```csharp
131+
static IList<PersonalizerRankableAction> GetActions()
132+
{
133+
IList<PersonalizerRankableAction> actions = new List<PersonalizerRankableAction>
134+
{
135+
new PersonalizerRankableAction(
136+
id: "pasta",
137+
features: new List<object>() { new { taste = "salty", spiceLevel = "medium" }, new { nutritionLevel = 5, cuisine = "italian" } }
138+
),
139+
140+
new PersonalizerRankableAction(
141+
id: "ice cream",
142+
features: new List<object>() { new { taste = "sweet", spiceLevel = "none" }, new { nutritionalLevel = 2 } }
143+
),
144+
145+
new PersonalizerRankableAction(
146+
id: "juice",
147+
features: new List<object>() { new { taste = "sweet", spiceLevel = "none" }, new { nutritionLevel = 5 }, new { drink = true } }
148+
),
149+
150+
new PersonalizerRankableAction(
151+
id: "salad",
152+
features: new List<object>() { new { taste = "salty", spiceLevel = "low" }, new { nutritionLevel = 8 } }
153+
)
154+
};
155+
156+
return actions;
157+
}
158+
```
159+
160+
## Get user preferences for context
161+
162+
Add the following methods to the Program class to get a user's input from the command line for the time of day and user taste preference. These will be used as context features.
163+
164+
```csharp
165+
static string GetTimeOfDayForContext()
166+
{
167+
string[] timeOfDayFeatures = new string[] { "morning", "afternoon", "evening", "night" };
168+
169+
Console.WriteLine("\nWhat time of day is it (enter number)? 1. morning 2. afternoon 3. evening 4. night");
170+
if (!int.TryParse(GetKey(), out int timeIndex) || timeIndex < 1 || timeIndex > timeOfDayFeatures.Length)
171+
{
172+
Console.WriteLine("\nEntered value is invalid. Setting feature value to " + timeOfDayFeatures[0] + ".");
173+
timeIndex = 1;
174+
}
175+
176+
return timeOfDayFeatures[timeIndex - 1];
177+
}
178+
```
179+
180+
```csharp
181+
static string GetUsersTastePreference()
182+
{
183+
string[] tasteFeatures = new string[] { "salty", "sweet" };
184+
var random = new Random();
185+
var taste = random.Next(1, 2);
186+
187+
Console.WriteLine("\nWhat type of food would you prefer (enter number)? 1. salty 2. sweet");
188+
if (!int.TryParse(GetKey(), out int tasteIndex) || tasteIndex < 1 || tasteIndex > tasteFeatures.Length)
189+
{
190+
Console.WriteLine("\nEntered value is invalid. Setting feature value to " + tasteFeatures[0] + ".");
191+
tasteIndex = 1;
192+
}
193+
194+
return tasteFeatures[taste - 1];
195+
}
196+
```
197+
198+
Both methods use the `GetKey` method to read the user's selection from the command line.
199+
200+
```csharp
201+
private static string GetKey()
202+
{
203+
return Console.ReadKey().Key.ToString().Last().ToString().ToUpper();
204+
}
205+
```
206+
207+
```csharp
208+
private static IList<object> GetContext(string time, string taste)
209+
{
210+
return new List<object>()
211+
{
212+
new { time = time },
213+
new { taste = taste }
214+
};
215+
}
216+
```
217+
218+
## Create the learning loop
219+
220+
The Personalizer learning loop is a cycle of Rank and Reward calls. In this quickstart, each Rank call, to personalize the content, is followed by a Reward call to tell Personalizer how well the service performed.
221+
222+
The following code loops through a cycle of asking the user their preferences through the command line, sending that information to Personalizer to select the best action for each slot, presenting the selection to the customer to choose from among the list, then sending a reward score to Personalizer signaling how well the service did in its selection.
223+
224+
```csharp
225+
static void Main(string[] args)
226+
{
227+
Console.WriteLine($"Welcome to this Personalizer Quickstart!\n" +
228+
$"This code will help you understand how to use the Personalizer APIs (rank and reward).\n" +
229+
$"Each iteration represents a user interaction and will demonstrate how context, actions, and rewards work.\n" +
230+
$"Note: Personalizer AI models learn from a large number of user interactions:\n" +
231+
$"You won't be able to tell the difference in what Personalizer returns by simulating a few events by hand.\n" +
232+
$"If you want a sample that focuses on seeing how Personalizer learns, see the Python Notebook sample.");
233+
234+
int iteration = 1;
235+
bool runLoop = true;
236+
237+
IList<PersonalizerRankableAction> actions = GetActions();
238+
PersonalizerClient client = InitializePersonalizerClient(new Uri(ServiceEndpoint));
239+
240+
do
241+
{
242+
Console.WriteLine("\nIteration: " + iteration++);
243+
244+
string timeOfDayFeature = GetTimeOfDayForContext();
245+
string deviceFeature = GetUsersTastePreference();
246+
247+
IList<object> currentContext = GetContext(timeOfDayFeature, deviceFeature);
248+
249+
string eventId = Guid.NewGuid().ToString();
250+
251+
var rankOptions = new PersonalizerRankOptions(actions: actions, contextFeatures: currentContext, eventId: eventId);
252+
PersonalizerRankResult rankResult = client.Rank(rankOptions);
253+
254+
Console.WriteLine("\nPersonalizer service thinks you would like to have: " + rankResult.RewardActionId + ". Is this correct? (y/n)");
255+
256+
float reward = 0.0f;
257+
string answer = GetKey();
258+
259+
if (answer == "Y")
260+
{
261+
reward = 1.0f;
262+
Console.WriteLine("\nGreat! Enjoy your food.");
263+
}
264+
else if (answer == "N")
265+
{
266+
reward = 0.0f;
267+
Console.WriteLine("\nYou didn't like the recommended food choice.");
268+
}
269+
else
270+
{
271+
Console.WriteLine("\nEntered choice is invalid. Service assumes that you didn't like the recommended food choice.");
272+
}
273+
274+
client.Reward(rankResult.EventId, reward);
275+
276+
Console.WriteLine("\nPress q to break, any other key to continue:");
277+
runLoop = !(GetKey() == "Q");
278+
279+
} while (runLoop);
280+
}
281+
```
282+
283+
## Run the program
284+
285+
Run the application with the dotnet `run` command from your application directory.
286+
287+
```console
288+
dotnet run
289+
```
290+
291+
![The quickstart program asks a couple of questions to gather user preferences, known as features, then provides the top action.](../media/csharp-quickstart-commandline-feedback-loop/quickstart-program-feedback-loop-example.png)

articles/cognitive-services/personalizer/index.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ landingContent:
5757
links:
5858
- text: Using SDK
5959
url: ./quickstart-personalizer-sdk.md
60+
- linkListType: quickstart
61+
links:
62+
- text: Use multi-slot Personalization
63+
url: ./how-to-multi-slot.md
64+
- linkListType: quickstart
65+
links:
66+
- text: Use local inference
67+
url: ./how-to-thick-client.md
68+
6069
- title: Developing with Personalizer
6170
linkLists:
6271
- linkListType: get-started

0 commit comments

Comments
 (0)