├── img ├── 10DownloadOnnx.png ├── 20SampleConsole.gif └── 30SampleVisionConsole.gif ├── src ├── LabsPhi303 │ ├── imgs │ │ ├── foggyday.png │ │ ├── petsmusic.png │ │ └── ultrarunningmug.png │ ├── LabsPhi303.csproj │ └── Program.cs ├── LabsPhi304 │ ├── imgs │ │ ├── foggyday.png │ │ ├── petsmusic.png │ │ ├── foggydaysmall.png │ │ └── ultrarunningmug.png │ ├── LabsPhi304.csproj │ ├── SpectreConsoleOutput.cs │ └── Program.cs ├── LabsPhi3_sk03 │ ├── imgs │ │ ├── foggyday.png │ │ ├── petsmusic.png │ │ └── ultrarunningmug.png │ ├── LabsPhi3_sk03.csproj │ └── Program.cs ├── LabsPhi3_sk_azure02 │ ├── imgs │ │ ├── foggyday.png │ │ ├── petsmusic.png │ │ ├── foggydaysmall.png │ │ └── ultrarunningmug.png │ ├── LabsPhi3_sk_azure02.csproj │ └── Program.cs ├── LabsPhi3_sk02 │ ├── LabsPhi3_sk02.csproj │ └── Program.cs ├── LabsPhi301 │ ├── LabsPhi301.csproj │ └── Program.cs ├── LabsPhi401 │ ├── LabsPhi401.csproj │ └── Program.cs ├── LabsPhi3_sk_azure01 │ ├── LabsPhi3_sk_azure01.csproj │ └── Program.cs ├── LabsPhi3_sk_rag01 │ ├── LabsPhi3_sk_rag01.csproj │ ├── SpectreConsoleOutput.cs │ └── Program.cs ├── LabsPhi3_sk01 │ ├── LabsPhi3_sk01.csproj │ └── Program.cs ├── LabsPhi3_sk_rag02 │ ├── LabsPhi3_sk_rag02.csproj │ └── Program.cs ├── LabsPhi3_sk_rag03 │ ├── LabsPhi3_sk_rag03.csproj │ ├── Program.cs │ └── SpectreConsoleOutput.cs ├── SemanticKernel.Connectors.OnnxRuntimeGenAI │ ├── OnnxRuntimeGenAIKernelBuilderExtensions.cs │ ├── OnnxRuntimeGenAIServiceCollectionExtensions.cs │ ├── Connectors.OnnxRuntimeGenAI.csproj │ ├── Models │ │ └── PromptBuilderResult.cs │ ├── OnnxRuntimeGenAIPromptExecutionSettings.cs │ └── Services │ │ └── OnnxRuntimeGenAIChatCompletionService.cs └── LabsPhi3.sln ├── LICENSE ├── README.md └── .gitignore /img/10DownloadOnnx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/img/10DownloadOnnx.png -------------------------------------------------------------------------------- /img/20SampleConsole.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/img/20SampleConsole.gif -------------------------------------------------------------------------------- /img/30SampleVisionConsole.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/img/30SampleVisionConsole.gif -------------------------------------------------------------------------------- /src/LabsPhi303/imgs/foggyday.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/src/LabsPhi303/imgs/foggyday.png -------------------------------------------------------------------------------- /src/LabsPhi304/imgs/foggyday.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/src/LabsPhi304/imgs/foggyday.png -------------------------------------------------------------------------------- /src/LabsPhi303/imgs/petsmusic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/src/LabsPhi303/imgs/petsmusic.png -------------------------------------------------------------------------------- /src/LabsPhi304/imgs/petsmusic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/src/LabsPhi304/imgs/petsmusic.png -------------------------------------------------------------------------------- /src/LabsPhi3_sk03/imgs/foggyday.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/src/LabsPhi3_sk03/imgs/foggyday.png -------------------------------------------------------------------------------- /src/LabsPhi304/imgs/foggydaysmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/src/LabsPhi304/imgs/foggydaysmall.png -------------------------------------------------------------------------------- /src/LabsPhi3_sk03/imgs/petsmusic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/src/LabsPhi3_sk03/imgs/petsmusic.png -------------------------------------------------------------------------------- /src/LabsPhi303/imgs/ultrarunningmug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/src/LabsPhi303/imgs/ultrarunningmug.png -------------------------------------------------------------------------------- /src/LabsPhi304/imgs/ultrarunningmug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/src/LabsPhi304/imgs/ultrarunningmug.png -------------------------------------------------------------------------------- /src/LabsPhi3_sk03/imgs/ultrarunningmug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/src/LabsPhi3_sk03/imgs/ultrarunningmug.png -------------------------------------------------------------------------------- /src/LabsPhi3_sk_azure02/imgs/foggyday.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/src/LabsPhi3_sk_azure02/imgs/foggyday.png -------------------------------------------------------------------------------- /src/LabsPhi3_sk_azure02/imgs/petsmusic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/src/LabsPhi3_sk_azure02/imgs/petsmusic.png -------------------------------------------------------------------------------- /src/LabsPhi3_sk_azure02/imgs/foggydaysmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/src/LabsPhi3_sk_azure02/imgs/foggydaysmall.png -------------------------------------------------------------------------------- /src/LabsPhi3_sk_azure02/imgs/ultrarunningmug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elbruno/phi3-labs/HEAD/src/LabsPhi3_sk_azure02/imgs/ultrarunningmug.png -------------------------------------------------------------------------------- /src/LabsPhi3_sk02/LabsPhi3_sk02.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/LabsPhi301/LabsPhi301.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/LabsPhi401/LabsPhi401.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/LabsPhi3_sk03/LabsPhi3_sk03.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | 18 | 19 | PreserveNewest 20 | 21 | 22 | PreserveNewest 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/LabsPhi3_sk_azure01/LabsPhi3_sk_azure01.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | b53b47a3-4029-4c27-86f8-c96adca5337f 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/LabsPhi3_sk_rag01/LabsPhi3_sk_rag01.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 El Bruno 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/LabsPhi3_sk01/LabsPhi3_sk01.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/LabsPhi3_sk_rag02/LabsPhi3_sk_rag02.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/LabsPhi303/LabsPhi303.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Always 19 | 20 | 21 | PreserveNewest 22 | 23 | 24 | Always 25 | 26 | 27 | PreserveNewest 28 | 29 | 30 | PreserveNewest 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/LabsPhi3_sk_rag03/LabsPhi3_sk_rag03.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/LabsPhi3_sk_azure01/Program.cs: -------------------------------------------------------------------------------- 1 | #pragma warning disable SKEXP0010 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.SemanticKernel; 4 | using Microsoft.SemanticKernel.ChatCompletion; 5 | 6 | var config = new ConfigurationBuilder().AddUserSecrets().Build(); 7 | var modelId = config["AZURE_AI_PHI3_MODEL"]; 8 | var endPoint = config["AZURE_AI_PHI3_ENDPOINT"]; 9 | var apiKey = config["AZURE_AI_PHI3_APIKEY"]; 10 | 11 | // create kernel 12 | var builder = Kernel.CreateBuilder(); 13 | builder.AddOpenAIChatCompletion(modelId, new Uri(endPoint), apiKey); 14 | var kernel = builder.Build(); 15 | 16 | // create chat 17 | var chat = kernel.GetRequiredService(); 18 | var history = new ChatHistory(); 19 | 20 | // run chat 21 | while (true) 22 | { 23 | Console.Write("Q: "); 24 | var userQ = Console.ReadLine(); 25 | if (string.IsNullOrEmpty(userQ)) 26 | { 27 | break; 28 | } 29 | history.AddUserMessage(userQ); 30 | 31 | Console.Write($"Phi3: "); 32 | var response = ""; 33 | var result = chat.GetStreamingChatMessageContentsAsync(history); 34 | await foreach (var message in result) 35 | { 36 | Console.Write(message.Content); 37 | response += message.Content; 38 | } 39 | history.AddAssistantMessage(response); 40 | Console.WriteLine(""); 41 | } 42 | -------------------------------------------------------------------------------- /src/LabsPhi3_sk_azure02/LabsPhi3_sk_azure02.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | PreserveNewest 21 | 22 | 23 | PreserveNewest 24 | 25 | 26 | PreserveNewest 27 | 28 | 29 | PreserveNewest 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/SemanticKernel.Connectors.OnnxRuntimeGenAI/OnnxRuntimeGenAIKernelBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using Microsoft.Extensions.Logging; 3 | using Microsoft.SemanticKernel.ChatCompletion; 4 | using philabs.SemanticKernel.Connectors.OnnxRuntimeGenAI; 5 | 6 | namespace Microsoft.SemanticKernel; 7 | 8 | /// 9 | /// Extension methods for adding OnnxRuntimeGenAI Text Generation service to the kernel builder. 10 | /// 11 | public static class OnnxRuntimeGenAIKernelBuilderExtensions 12 | { 13 | /// 14 | /// Add OnnxRuntimeGenAI Chat Completion services to the kernel builder. 15 | /// 16 | /// The kernel builder. 17 | /// The generative AI ONNX model path. 18 | /// The optional service ID. 19 | /// The updated kernel builder. 20 | public static IKernelBuilder AddOnnxRuntimeGenAIChatCompletion( 21 | this IKernelBuilder builder, 22 | string modelPath, 23 | string? serviceId = null) 24 | { 25 | builder.Services.AddKeyedSingleton(serviceId, (serviceProvider, _) => 26 | new OnnxRuntimeGenAIChatCompletionService( 27 | modelPath: modelPath, 28 | loggerFactory: serviceProvider.GetService())); 29 | 30 | return builder; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/SemanticKernel.Connectors.OnnxRuntimeGenAI/OnnxRuntimeGenAIServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using Microsoft.Extensions.Logging; 3 | using Microsoft.SemanticKernel.ChatCompletion; 4 | using philabs.SemanticKernel.Connectors.OnnxRuntimeGenAI; 5 | 6 | namespace Microsoft.SemanticKernel; 7 | 8 | /// 9 | /// Extension methods for adding OnnxRuntimeGenAI Text Generation service to the kernel builder. 10 | /// 11 | public static class OnnxRuntimeGenAIServiceCollectionExtensions 12 | { 13 | /// 14 | /// Add OnnxRuntimeGenAI Chat Completion services to the specified service collection. 15 | /// 16 | /// The service collection to add the OnnxRuntimeGenAI Text Generation service to. 17 | /// The generative AI ONNX model path. 18 | /// Optional service ID. 19 | /// The updated service collection. 20 | public static IServiceCollection AddOnnxRuntimeGenAIChatCompletion( 21 | this IServiceCollection services, 22 | string modelPath, 23 | string? serviceId = null) 24 | { 25 | services.AddKeyedSingleton(serviceId, (serviceProvider, _) => 26 | new OnnxRuntimeGenAIChatCompletionService( 27 | modelPath, 28 | loggerFactory: serviceProvider.GetService())); 29 | 30 | return services; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/SemanticKernel.Connectors.OnnxRuntimeGenAI/Connectors.OnnxRuntimeGenAI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | philabs.SemanticKernel.Connectors.OnnxRuntimeGenAI 5 | $(AssemblyName) 6 | netstandard2.1 7 | enable 8 | 10 9 | Debug;Release;Debug_Cuda;Release_Cuda;Debug_DirectML;Release_DirectML; 10 | 11 | 12 | 13 | 14 | Semantic Kernel-Microsoft.ML.OnnxRuntimeGenAI connectors 15 | Semantic Kernel connector for Microsoft.ML.OnnxRuntimeGenAI. 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/LabsPhi3_sk_azure02/Program.cs: -------------------------------------------------------------------------------- 1 | #pragma warning disable SKEXP0010 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.SemanticKernel; 4 | using Microsoft.SemanticKernel.ChatCompletion; 5 | 6 | var config = new ConfigurationBuilder().AddUserSecrets().Build(); 7 | var modelId = config["AZURE_AI_PHI3V_MODEL"]; 8 | var endPoint = config["AZURE_AI_PHI3V_ENDPOINT"]; 9 | var apiKey = config["AZURE_AI_PHI3V_APIKEY"]; 10 | 11 | // create kernel 12 | var builder = Kernel.CreateBuilder(); 13 | builder.AddOpenAIChatCompletion(modelId, new Uri(endPoint), apiKey); 14 | var kernel = builder.Build(); 15 | 16 | // create chat 17 | var chat = kernel.GetRequiredService(); 18 | var history = new ChatHistory(); 19 | 20 | var petsMusicImagePath = Path.Combine(Directory.GetCurrentDirectory(), "imgs", "petsmusic.png"); 21 | 22 | // get the mime type from the image 23 | var mimeType = "image/png"; 24 | 25 | // create chat collection items 26 | var collectionItems = new ChatMessageContentItemCollection 27 | { 28 | new TextContent("What's in the image?"), 29 | //new ImageContent( new Uri(petsMusicImagePath)) 30 | //new ImageContent( new Uri("https://github.com/elbruno/gpt4o-labs-csharp/tree/main/src/GPT4o_AOAI_lab02/imgs/foggyday.png?raw=true")) 31 | new ImageContent(File.ReadAllBytes(petsMusicImagePath), mimeType) 32 | }; 33 | history.AddUserMessage(collectionItems); 34 | 35 | Console.Write($"Phi3: "); 36 | var result = await chat.GetChatMessageContentsAsync(history); 37 | Console.WriteLine(result[^1].Content); 38 | 39 | Console.WriteLine(""); 40 | -------------------------------------------------------------------------------- /src/LabsPhi304/LabsPhi304.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | PreserveNewest 26 | 27 | 28 | PreserveNewest 29 | 30 | 31 | PreserveNewest 32 | 33 | 34 | PreserveNewest 35 | 36 | 37 | PreserveNewest 38 | 39 | 40 | PreserveNewest 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/LabsPhi3_sk01/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 2 | // Author : Bruno Capuano 3 | // Change Log : 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | using Microsoft.SemanticKernel; 26 | using Microsoft.SemanticKernel.ChatCompletion; 27 | 28 | var modelPath = @"D:\phi3\models\Phi-3-mini-4k-instruct-onnx\cpu_and_mobile\cpu-int4-rtn-block-32"; 29 | 30 | // create kernel 31 | var builder = Kernel.CreateBuilder(); 32 | builder.AddOnnxRuntimeGenAIChatCompletion(modelPath: modelPath); 33 | var kernel = builder.Build(); 34 | 35 | // create chat 36 | var chat = kernel.GetRequiredService(); 37 | var history = new ChatHistory(); 38 | 39 | // run chat 40 | while (true) 41 | { 42 | Console.Write("Q: "); 43 | var userQ = Console.ReadLine(); 44 | if (string.IsNullOrEmpty(userQ)) 45 | { 46 | break; 47 | } 48 | history.AddUserMessage(userQ); 49 | 50 | Console.Write($"Phi3: "); 51 | var response = ""; 52 | var result = chat.GetStreamingChatMessageContentsAsync(history); 53 | await foreach (var message in result) 54 | { 55 | Console.Write(message.Content); 56 | response += message.Content; 57 | } 58 | history.AddAssistantMessage(response); 59 | Console.WriteLine(""); 60 | } 61 | -------------------------------------------------------------------------------- /src/SemanticKernel.Connectors.OnnxRuntimeGenAI/Models/PromptBuilderResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | 5 | namespace philabs.SemanticKernel.Connectors.OnnxRuntimeGenAI.Models 6 | { 7 | internal class PromptBuilderResult 8 | { 9 | string _imagePath = ""; 10 | 11 | public string Prompt { get; set; } 12 | public bool ImageFound { get; set; } 13 | public string? ImagePath 14 | { 15 | get 16 | { 17 | 18 | if (Uri != null && Uri.IsFile) 19 | { 20 | _imagePath = Uri.LocalPath; 21 | } 22 | else if (Uri != null && Uri.IsWellFormedUriString(Uri.AbsoluteUri, UriKind.Absolute)) 23 | { 24 | // Check if the URI scheme is HTTP or HTTPS 25 | if (Uri.Scheme == Uri.UriSchemeHttp || Uri.Scheme == Uri.UriSchemeHttps) 26 | { 27 | // Additional validation for image file extensions 28 | string[] imageExtensions = { ".jpg", ".jpeg", ".png", ".gif" }; 29 | string fileExtension = Path.GetExtension(Uri.AbsoluteUri); 30 | 31 | if (imageExtensions.Any(ext => fileExtension.StartsWith(ext))) 32 | { 33 | string tempFilePath = Path.GetTempFileName(); 34 | using (var client = new System.Net.WebClient()) 35 | { 36 | client.DownloadFile(Uri.AbsoluteUri, tempFilePath); 37 | } 38 | _imagePath = tempFilePath; 39 | } 40 | } 41 | } 42 | else if (string.IsNullOrEmpty(_imagePath) && ImageBytes != null && ImageBytes.Length > 0) 43 | { 44 | _imagePath = Path.GetTempFileName(); 45 | if (File.Exists(_imagePath)) 46 | { 47 | File.Delete(_imagePath); 48 | } 49 | File.WriteAllBytes(_imagePath, ImageBytes ?? new byte[0]); 50 | } 51 | return _imagePath; 52 | } 53 | set 54 | { 55 | _imagePath = value; 56 | } 57 | } 58 | public byte[]? ImageBytes { get; internal set; } 59 | public Uri? Uri { get; internal set; } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/LabsPhi3_sk02/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 2 | // Author : Bruno Capuano 3 | // Change Log : 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | #pragma warning disable SKEXP0010 26 | 27 | using Microsoft.SemanticKernel; 28 | using Microsoft.SemanticKernel.ChatCompletion; 29 | 30 | var modelPath = @"D:\phi3\models\Phi-3-mini-4k-instruct-onnx\cpu_and_mobile\cpu-int4-rtn-block-32"; 31 | 32 | var model = "phi3"; 33 | var endpoint = "https://localhost:14141"; 34 | var apiKey = "apiKey"; 35 | 36 | 37 | // create kernel 38 | var builder = Kernel.CreateBuilder(); 39 | builder.AddOpenAIChatCompletion(model, new Uri(endpoint), apiKey); 40 | var kernel = builder.Build(); 41 | 42 | // create chat 43 | var chat = kernel.GetRequiredService(); 44 | var history = new ChatHistory(); 45 | history.AddSystemMessage("You are a useful assistant. You always reply with a short and funny message using emojis. If you don't know an answer, you say 'I don't know that.' You only answers questions relates to math problems. For any other type of questions, explain the user that you only answer math problems questions."); 46 | 47 | // run chat 48 | while (true) 49 | { 50 | Console.Write("Q: "); 51 | var userQ = Console.ReadLine(); 52 | if (string.IsNullOrEmpty(userQ)) 53 | { 54 | break; 55 | } 56 | history.AddUserMessage(userQ); 57 | 58 | Console.Write($"Phi3: "); 59 | var response = ""; 60 | var result = chat.GetStreamingChatMessageContentsAsync(history); 61 | await foreach (var message in result) 62 | { 63 | Console.Write(message.Content); 64 | response += message.Content; 65 | } 66 | history.AddAssistantMessage(response); 67 | Console.WriteLine(""); 68 | } 69 | -------------------------------------------------------------------------------- /src/LabsPhi3_sk03/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 2 | // Author : Bruno Capuano 3 | // Change Log : 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | using Microsoft.ML.OnnxRuntimeGenAI; 26 | using Microsoft.SemanticKernel; 27 | using Microsoft.SemanticKernel.ChatCompletion; 28 | 29 | // path for model and images 30 | var modelPath = @"d:\phi3\models\Phi-3-vision-128k-instruct-onnx-cpu\cpu-int4-rtn-block-32-acc-level-4"; 31 | //var modelPath = @"d:\phi3\models\Phi-3-vision-128k-instruct-onnx-cuda\cuda-fp16"; 32 | //var modelPath = @"d:\phi3\models\Phi-3-vision-128k-instruct-onnx-cuda\cuda-int4-rtn-block-32-bruno"; 33 | 34 | // create kernel 35 | var builder = Kernel.CreateBuilder(); 36 | builder.AddOnnxRuntimeGenAIChatCompletion(modelPath: modelPath); 37 | var kernel = builder.Build(); 38 | 39 | // create chat 40 | var chat = kernel.GetRequiredService(); 41 | var history = new ChatHistory(); 42 | 43 | var petsMusicImagePath = Path.Combine(Directory.GetCurrentDirectory(), "imgs", "petsmusic.png"); 44 | 45 | // get the mime type from the image 46 | var mimeType = "image/png"; 47 | 48 | // create chat collection items 49 | var collectionItems = new ChatMessageContentItemCollection 50 | { 51 | new TextContent("What's in the image?"), 52 | //new ImageContent( new Uri(petsMusicImagePath)) 53 | //new ImageContent( new Uri("https://github.com/elbruno/gpt4o-labs-csharp/tree/main/src/GPT4o_AOAI_lab02/imgs/foggyday.png?raw=true")) 54 | new ImageContent(File.ReadAllBytes(petsMusicImagePath), mimeType) 55 | }; 56 | history.AddUserMessage(collectionItems); 57 | 58 | Console.Write($"Phi3: "); 59 | var result = await chat.GetChatMessageContentsAsync(history); 60 | Console.WriteLine(result[^1].Content); 61 | 62 | Console.WriteLine(""); 63 | -------------------------------------------------------------------------------- /src/LabsPhi301/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 2 | // Author : Bruno Capuano 3 | // Change Log : 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | using Microsoft.ML.OnnxRuntimeGenAI; 26 | 27 | var modelPath = @"C:\src\phi3\models\Phi-3-mini-4k-instruct-onnx\cpu_and_mobile\cpu-int4-rtn-block-32"; 28 | var model = new Model(modelPath); 29 | var tokenizer = new Tokenizer(model); 30 | 31 | var systemPrompt = "You are an AI assistant that helps people find information. Answer questions using a direct style. Do not share more information that the requested by the users."; 32 | 33 | // chat start 34 | Console.WriteLine(@"Ask your question. Type an empty string to Exit."); 35 | 36 | // chat loop 37 | while (true) 38 | { 39 | // Get user question 40 | Console.WriteLine(); 41 | Console.Write(@"Q: "); 42 | var userQ = Console.ReadLine(); 43 | if (string.IsNullOrEmpty(userQ)) 44 | { 45 | break; 46 | } 47 | 48 | // show phi3 response 49 | Console.Write("Phi3: "); 50 | var fullPrompt = $"<|system|>{systemPrompt}<|end|><|user|>{userQ}<|end|><|assistant|>"; 51 | var tokens = tokenizer.Encode(fullPrompt); 52 | 53 | var generatorParams = new GeneratorParams(model); 54 | generatorParams.SetSearchOption("max_length", 2048); 55 | generatorParams.SetSearchOption("past_present_share_buffer", false); 56 | generatorParams.SetInputSequences(tokens); 57 | 58 | var generator = new Generator(model, generatorParams); 59 | while (!generator.IsDone()) 60 | { 61 | generator.ComputeLogits(); 62 | generator.GenerateNextToken(); 63 | var outputTokens = generator.GetSequence(0); 64 | var newToken = outputTokens.Slice(outputTokens.Length - 1, 1); 65 | var output = tokenizer.Decode(newToken); 66 | Console.Write(output); 67 | } 68 | Console.WriteLine(); 69 | } 70 | -------------------------------------------------------------------------------- /src/LabsPhi303/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 2 | // Author : Bruno Capuano 3 | // Change Log : 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | using Microsoft.ML.OnnxRuntime; 26 | using Microsoft.ML.OnnxRuntimeGenAI; 27 | 28 | // path for model and images 29 | var modelPath = @"d:\src\Phi3\models\Phi-3-vision-128k-instruct-onnx-cpu\cpu-int4-rtn-block-32-acc-level-4"; 30 | //var modelPath = @"c:\src\Phi3\models\Phi-3-vision-128k-instruct-onnx-cuda\cuda-int4-rtn-block-32"; 31 | 32 | var foggyDayImagePath = Path.Combine(Directory.GetCurrentDirectory(), "imgs", "foggyday.png"); 33 | var petsMusicImagePath = Path.Combine(Directory.GetCurrentDirectory(), "imgs", "petsmusic.png"); 34 | var img = Images.Load(petsMusicImagePath); 35 | 36 | // define prompts 37 | var systemPrompt = "You are an AI assistant that helps people find information. Answer questions using a direct style. Do not share more information that the requested by the users."; 38 | string userPrompt = "Describe the image, and return the string 'STOP' at the end."; 39 | var fullPrompt = $"<|system|>{systemPrompt}<|end|><|user|><|image_1|>{userPrompt}<|end|><|assistant|>"; 40 | 41 | // load model and create processor 42 | using Model model = new Model(modelPath); 43 | using MultiModalProcessor processor = new MultiModalProcessor(model); 44 | using var tokenizerStream = processor.CreateStream(); 45 | 46 | // create the input tensor with the prompt and image 47 | Console.WriteLine("Full Prompt: " + fullPrompt); 48 | Console.WriteLine("Start processing image and prompt ..."); 49 | var inputTensors = processor.ProcessImages(fullPrompt, img); 50 | using GeneratorParams generatorParams = new GeneratorParams(model); 51 | generatorParams.SetSearchOption("max_length", 3072); 52 | generatorParams.SetInputs(inputTensors); 53 | 54 | // generate response 55 | Console.WriteLine("Generating response ..."); 56 | using var generator = new Generator(model, generatorParams); 57 | while (!generator.IsDone()) 58 | { 59 | generator.ComputeLogits(); 60 | generator.GenerateNextToken(); 61 | var seq = generator.GetSequence(0)[^1]; 62 | Console.Write(tokenizerStream.Decode(seq)); 63 | } 64 | 65 | Console.WriteLine(""); 66 | Console.WriteLine("Done!"); -------------------------------------------------------------------------------- /src/SemanticKernel.Connectors.OnnxRuntimeGenAI/OnnxRuntimeGenAIPromptExecutionSettings.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using Microsoft.SemanticKernel; 3 | 4 | namespace philabs.SemanticKernel.Connectors.OnnxRuntimeGenAI; 5 | 6 | /// 7 | /// OnnxRuntimeGenAI Execution Settings. 8 | /// 9 | public sealed class OnnxRuntimeGenAIPromptExecutionSettings : PromptExecutionSettings 10 | { 11 | public static OnnxRuntimeGenAIPromptExecutionSettings FromExecutionSettings(PromptExecutionSettings? executionSettings) 12 | { 13 | switch (executionSettings) 14 | { 15 | case OnnxRuntimeGenAIPromptExecutionSettings settings: 16 | return settings; 17 | default: 18 | return new OnnxRuntimeGenAIPromptExecutionSettings(); 19 | } 20 | } 21 | 22 | private int _topK = 50; 23 | private float _topP = 0.9f; 24 | private float _temperature = 1; 25 | private float _repetitionPenalty = 1; 26 | private bool _pastPresentShareBuffer = false; 27 | private int _numReturnSequences = 1; 28 | private int _numBeams = 1; 29 | private int _noRepeatNgramSize = 0; 30 | private int _minLength = 0; 31 | private int _maxLength = 200; 32 | private float _lengthPenalty = 1; 33 | private bool _earlyStopping = true; 34 | private bool _doSample = false; 35 | private float _diversityPenalty = 0; 36 | 37 | [JsonPropertyName("top_k")] 38 | public int TopK 39 | { 40 | get { return _topK; } 41 | set { _topK = value; } 42 | } 43 | 44 | [JsonPropertyName("top_p")] 45 | public float TopP 46 | { 47 | get { return _topP; } 48 | set { _topP = value; } 49 | } 50 | 51 | [JsonPropertyName("temperature")] 52 | public float Temperature 53 | { 54 | get { return _temperature; } 55 | set { _temperature = value; } 56 | } 57 | 58 | [JsonPropertyName("repetition_penalty")] 59 | public float RepetitionPenalty 60 | { 61 | get { return _repetitionPenalty; } 62 | set { _repetitionPenalty = value; } 63 | } 64 | 65 | [JsonPropertyName("past_present_share_buffer")] 66 | public bool PastPresentShareBuffer 67 | { 68 | get { return _pastPresentShareBuffer; } 69 | set { _pastPresentShareBuffer = value; } 70 | } 71 | 72 | [JsonPropertyName("num_return_sequences")] 73 | public int NumReturnSequences 74 | { 75 | get { return _numReturnSequences; } 76 | set { _numReturnSequences = value; } 77 | } 78 | 79 | [JsonPropertyName("num_beams")] 80 | public int NumBeams 81 | { 82 | get { return _numBeams; } 83 | set { _numBeams = value; } 84 | } 85 | 86 | [JsonPropertyName("no_repeat_ngram_size")] 87 | public int NoRepeatNgramSize 88 | { 89 | get { return _noRepeatNgramSize; } 90 | set { _noRepeatNgramSize = value; } 91 | } 92 | 93 | [JsonPropertyName("min_length")] 94 | public int MinLength 95 | { 96 | get { return _minLength; } 97 | set { _minLength = value; } 98 | } 99 | 100 | [JsonPropertyName("max_length")] 101 | public int MaxLength 102 | { 103 | get { return _maxLength; } 104 | set { _maxLength = value; } 105 | } 106 | 107 | [JsonPropertyName("length_penalty")] 108 | public float LengthPenalty 109 | { 110 | get { return _lengthPenalty; } 111 | set { _lengthPenalty = value; } 112 | } 113 | 114 | [JsonPropertyName("diversity_penalty")] 115 | public float DiversityPenalty 116 | { 117 | get { return _diversityPenalty; } 118 | set { _diversityPenalty = value; } 119 | } 120 | 121 | [JsonPropertyName("early_stopping")] 122 | public bool EarlyStopping 123 | { 124 | get { return _earlyStopping; } 125 | set { _earlyStopping = value; } 126 | } 127 | 128 | [JsonPropertyName("do_sample")] 129 | public bool DoSample 130 | { 131 | get { return _doSample; } 132 | set { _doSample = value; } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/LabsPhi3_sk_rag03/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 2 | // Author : Bruno Capuano 3 | // Change Log : 4 | // - Sample console application to use a local model hosted in ollama and semantic memory for search 5 | // 6 | // The MIT License (MIT) 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #pragma warning disable SKEXP0001, SKEXP0003, SKEXP0010, SKEXP0011, SKEXP0050, SKEXP0052, SKEXP0070 27 | 28 | using Microsoft.KernelMemory; 29 | using Microsoft.KernelMemory.AI.Ollama; 30 | using Microsoft.SemanticKernel; 31 | 32 | var ollamaEndpoint = "http://localhost:11434"; 33 | var modelIdChat = "deepseek-r1"; 34 | var modelIdEmbeddings = "all-minilm"; 35 | 36 | // questions 37 | var questionEnglish = "What is Bruno's favourite super hero?"; 38 | var questionSpanish = "Cual es el SuperHeroe favorito de Bruno?"; 39 | var questionFrench = "Quel est le super-héros préféré de Bruno?"; 40 | var question = questionEnglish; 41 | 42 | // intro 43 | SpectreConsoleOutput.DisplayTitle(modelIdChat); 44 | SpectreConsoleOutput.DisplayTitleH2($"This program will answer the following question:"); 45 | SpectreConsoleOutput.DisplayTitleH2(question); 46 | SpectreConsoleOutput.DisplayTitleH3("1st approach will be to ask the question directly to the Phi-3 model."); 47 | SpectreConsoleOutput.DisplayTitleH3("2nd approach will be to add facts to a semantic memory and ask the question again"); 48 | Console.WriteLine(""); 49 | 50 | SpectreConsoleOutput.DisplayTitleH2($"{modelIdChat} response (no memory)."); 51 | 52 | // Create a kernel with Azure OpenAI chat completion 53 | var builder = Kernel.CreateBuilder().AddOllamaChatCompletion( 54 | modelId: modelIdChat, 55 | endpoint: new Uri(ollamaEndpoint)); 56 | 57 | Kernel kernel = builder.Build(); 58 | var response = kernel.InvokePromptStreamingAsync(question); 59 | await foreach (var result in response) 60 | { 61 | SpectreConsoleOutput.WriteGreen(result.ToString()); 62 | } 63 | 64 | // separator 65 | Console.WriteLine(""); 66 | SpectreConsoleOutput.DisplaySeparator(); 67 | Console.WriteLine("Press Enter to continue"); 68 | Console.ReadLine(); 69 | SpectreConsoleOutput.DisplayTitleH2($"{modelIdChat} response (using semantic memory)."); 70 | 71 | var configOllamaKernelMemory = new OllamaConfig 72 | { 73 | Endpoint = ollamaEndpoint, 74 | TextModel = new OllamaModelConfig(modelIdChat), 75 | EmbeddingModel = new OllamaModelConfig(modelIdEmbeddings, 2048) 76 | }; 77 | 78 | var memory = new KernelMemoryBuilder() 79 | .WithOllamaTextGeneration(configOllamaKernelMemory) 80 | .WithOllamaTextEmbeddingGeneration(configOllamaKernelMemory) 81 | .Build(); 82 | 83 | await memory.ImportTextAsync("Gisela's favourite super hero is Batman"); 84 | await memory.ImportTextAsync("The last super hero movie watched by Gisela was Guardians of the Galaxy Vol 3"); 85 | await memory.ImportTextAsync("Bruno's favourite super hero is Invincible"); 86 | await memory.ImportTextAsync("The last super hero movie watched by Bruno was Deadpool and Wolverine"); 87 | await memory.ImportTextAsync("Bruno don't like the super hero movie: Eternals"); 88 | 89 | var answer = memory.AskStreamingAsync(question); 90 | await foreach (var result in answer) 91 | { 92 | SpectreConsoleOutput.WriteGreen(result.ToString()); 93 | } 94 | 95 | Console.WriteLine($""); -------------------------------------------------------------------------------- /src/LabsPhi304/SpectreConsoleOutput.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 2 | // Author : Bruno Capuano 3 | // Change Log : 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | #pragma warning disable SKEXP0001, SKEXP0003, SKEXP0010, SKEXP0011, SKEXP0050, SKEXP0052 26 | using Spectre.Console; 27 | 28 | namespace LabsPhi304; 29 | 30 | public static class SpectreConsoleOutput 31 | { 32 | public static void DisplayTitle(string title = ".NET - Phi-3 Vision Sample") 33 | { 34 | AnsiConsole.Write(new FigletText(title).Centered().Color(Color.Purple)); 35 | } 36 | 37 | public static void DisplayTitleH2(string subtitle) 38 | { 39 | AnsiConsole.MarkupLine($"[bold][blue]=== {subtitle} ===[/][/]"); 40 | AnsiConsole.MarkupLine($""); 41 | } 42 | 43 | public static void DisplayTitleH3(string subtitle) 44 | { 45 | AnsiConsole.MarkupLine($"[bold]>> {subtitle}[/]"); 46 | AnsiConsole.MarkupLine($""); 47 | } 48 | 49 | public static void DisplayQuestion(string question) 50 | { 51 | AnsiConsole.MarkupLine($"[bold][blue]>>Q: {question}[/][/]"); 52 | AnsiConsole.MarkupLine($""); 53 | } 54 | public static void DisplayAnswerStart(string answerPrefix) 55 | { 56 | AnsiConsole.Markup($"[bold][blue]>> {answerPrefix}:[/][/]"); 57 | } 58 | 59 | public static void DisplayFilePath(string prefix, string filePath) 60 | { 61 | var path = new TextPath(filePath); 62 | 63 | AnsiConsole.Markup($"[bold][blue]>> {prefix}: [/][/]"); 64 | AnsiConsole.Write(path); 65 | AnsiConsole.MarkupLine($""); 66 | } 67 | 68 | public static void DisplaySubtitle(string prefix, string content) 69 | { 70 | AnsiConsole.Markup($"[bold][blue]>> {prefix}: [/][/]"); 71 | AnsiConsole.WriteLine(content); 72 | AnsiConsole.MarkupLine($""); 73 | } 74 | 75 | 76 | 77 | public static int AskForNumber(string question) 78 | { 79 | var number = AnsiConsole.Ask(@$"[green]{question}[/]"); 80 | return number; 81 | } 82 | 83 | public static string AskForString(string question) 84 | { 85 | var response = AnsiConsole.Ask(@$"[green]{question}[/]"); 86 | return response; 87 | } 88 | 89 | public static List SelectScenarios() 90 | { 91 | // Ask for the user's favorite fruits 92 | var scenarios = AnsiConsole.Prompt( 93 | new MultiSelectionPrompt() 94 | .Title("Select the [green]Phi 3 Vision scenarios[/] to run?") 95 | .PageSize(10) 96 | .Required(true) 97 | .MoreChoicesText("[grey](Move up and down to reveal more scenarios)[/]") 98 | .InstructionsText( 99 | "[grey](Press [blue][/] to toggle a scenario, " + 100 | "[green][/] to accept)[/]") 101 | .AddChoiceGroup("Select an image to be analuyzed", new[] 102 | {"foggyday.png","foggydaysmall.png","petsmusic.png","ultrarunningmug.png", 103 | }) 104 | .AddChoices( new[] { 105 | "Type the image path to be analyzed", 106 | "Type a question" 107 | }) 108 | ); 109 | return scenarios; 110 | } 111 | } -------------------------------------------------------------------------------- /src/LabsPhi3_sk_rag01/SpectreConsoleOutput.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 2 | // Author : Bruno Capuano 3 | // Change Log : 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | #pragma warning disable SKEXP0001, SKEXP0003, SKEXP0010, SKEXP0011, SKEXP0050, SKEXP0052 26 | using Spectre.Console; 27 | 28 | public static class SpectreConsoleOutput 29 | { 30 | public static void DisplayTitle(string modelId = "") 31 | { 32 | var title = $"{modelId} RAG"; 33 | 34 | AnsiConsole.Write(new FigletText(title).Centered().Color(Color.Purple)); 35 | } 36 | 37 | public static void DisplayTitleH2(string subtitle) 38 | { 39 | AnsiConsole.MarkupLine($"[bold][blue]=== {subtitle} ===[/][/]"); 40 | AnsiConsole.MarkupLine($""); 41 | } 42 | 43 | public static void DisplayTitleH3(string subtitle) 44 | { 45 | AnsiConsole.MarkupLine($"[bold]>> {subtitle}[/]"); 46 | AnsiConsole.MarkupLine($""); 47 | } 48 | 49 | public static void DisplaySeparator() 50 | { 51 | AnsiConsole.MarkupLine($""); 52 | AnsiConsole.MarkupLine($"[bold][blue]==============[/][/]"); 53 | AnsiConsole.MarkupLine($""); 54 | } 55 | 56 | public static void WriteGreen(string message) 57 | { 58 | AnsiConsole.Markup($"[green]{message}[/]"); 59 | } 60 | 61 | public static void DisplayQuestion(string question) 62 | { 63 | AnsiConsole.MarkupLine($"[bold][blue]>>Q: {question}[/][/]"); 64 | AnsiConsole.MarkupLine($""); 65 | } 66 | public static void DisplayAnswerStart(string answerPrefix) 67 | { 68 | AnsiConsole.Markup($"[bold][blue]>> {answerPrefix}:[/][/]"); 69 | } 70 | 71 | public static void DisplayFilePath(string prefix, string filePath) 72 | { 73 | var path = new TextPath(filePath); 74 | 75 | AnsiConsole.Markup($"[bold][blue]>> {prefix}: [/][/]"); 76 | AnsiConsole.Write(path); 77 | AnsiConsole.MarkupLine($""); 78 | } 79 | 80 | public static void DisplaySubtitle(string prefix, string content) 81 | { 82 | AnsiConsole.Markup($"[bold][blue]>> {prefix}: [/][/]"); 83 | AnsiConsole.WriteLine(content); 84 | AnsiConsole.MarkupLine($""); 85 | } 86 | 87 | public static int AskForNumber(string question) 88 | { 89 | var number = AnsiConsole.Ask(@$"[green]{question}[/]"); 90 | return number; 91 | } 92 | 93 | public static string AskForString(string question) 94 | { 95 | var response = AnsiConsole.Ask(@$"[green]{question}[/]"); 96 | return response; 97 | } 98 | 99 | public static List SelectScenarios() 100 | { 101 | // Ask for the user's favorite fruits 102 | var scenarios = AnsiConsole.Prompt( 103 | new MultiSelectionPrompt() 104 | .Title("Select the [green]Phi 3 Vision scenarios[/] to run?") 105 | .PageSize(10) 106 | .Required(true) 107 | .MoreChoicesText("[grey](Move up and down to reveal more scenarios)[/]") 108 | .InstructionsText( 109 | "[grey](Press [blue][/] to toggle a scenario, " + 110 | "[green][/] to accept)[/]") 111 | .AddChoiceGroup("Select an image to be analuyzed", new[] 112 | {"foggyday.png","foggydaysmall.png","petsmusic.png","ultrarunningmug.png", 113 | }) 114 | .AddChoices( new[] { 115 | "Type the image path to be analyzed", 116 | "Type a question" 117 | }) 118 | ); 119 | return scenarios; 120 | } 121 | } -------------------------------------------------------------------------------- /src/LabsPhi3_sk_rag03/SpectreConsoleOutput.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 2 | // Author : Bruno Capuano 3 | // Change Log : 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | #pragma warning disable SKEXP0001, SKEXP0003, SKEXP0010, SKEXP0011, SKEXP0050, SKEXP0052 26 | using Spectre.Console; 27 | 28 | public static class SpectreConsoleOutput 29 | { 30 | public static void DisplayTitle(string modelId = "") 31 | { 32 | var title = $"{modelId} RAG"; 33 | 34 | AnsiConsole.Write(new FigletText(title).Centered().Color(Color.Purple)); 35 | } 36 | 37 | public static void DisplayTitleH2(string subtitle) 38 | { 39 | AnsiConsole.MarkupLine($"[bold][blue]=== {subtitle} ===[/][/]"); 40 | AnsiConsole.MarkupLine($""); 41 | } 42 | 43 | public static void DisplayTitleH3(string subtitle) 44 | { 45 | AnsiConsole.MarkupLine($"[bold]>> {subtitle}[/]"); 46 | AnsiConsole.MarkupLine($""); 47 | } 48 | 49 | public static void DisplaySeparator() 50 | { 51 | AnsiConsole.MarkupLine($""); 52 | AnsiConsole.MarkupLine($"[bold][blue]==============[/][/]"); 53 | AnsiConsole.MarkupLine($""); 54 | } 55 | 56 | public static void WriteGreen(string message) 57 | { 58 | try 59 | { 60 | AnsiConsole.Markup($"[green]{message}[/]"); 61 | } 62 | catch 63 | { 64 | AnsiConsole.Write($"{message}"); 65 | } 66 | } 67 | 68 | public static void DisplayQuestion(string question) 69 | { 70 | AnsiConsole.MarkupLine($"[bold][blue]>>Q: {question}[/][/]"); 71 | AnsiConsole.MarkupLine($""); 72 | } 73 | public static void DisplayAnswerStart(string answerPrefix) 74 | { 75 | AnsiConsole.Markup($"[bold][blue]>> {answerPrefix}:[/][/]"); 76 | } 77 | 78 | public static void DisplayFilePath(string prefix, string filePath) 79 | { 80 | var path = new TextPath(filePath); 81 | 82 | AnsiConsole.Markup($"[bold][blue]>> {prefix}: [/][/]"); 83 | AnsiConsole.Write(path); 84 | AnsiConsole.MarkupLine($""); 85 | } 86 | 87 | public static void DisplaySubtitle(string prefix, string content) 88 | { 89 | AnsiConsole.Markup($"[bold][blue]>> {prefix}: [/][/]"); 90 | AnsiConsole.WriteLine(content); 91 | AnsiConsole.MarkupLine($""); 92 | } 93 | 94 | public static int AskForNumber(string question) 95 | { 96 | var number = AnsiConsole.Ask(@$"[green]{question}[/]"); 97 | return number; 98 | } 99 | 100 | public static string AskForString(string question) 101 | { 102 | var response = AnsiConsole.Ask(@$"[green]{question}[/]"); 103 | return response; 104 | } 105 | 106 | public static List SelectScenarios() 107 | { 108 | // Ask for the user's favorite fruits 109 | var scenarios = AnsiConsole.Prompt( 110 | new MultiSelectionPrompt() 111 | .Title("Select the [green]Phi 3 Vision scenarios[/] to run?") 112 | .PageSize(10) 113 | .Required(true) 114 | .MoreChoicesText("[grey](Move up and down to reveal more scenarios)[/]") 115 | .InstructionsText( 116 | "[grey](Press [blue][/] to toggle a scenario, " + 117 | "[green][/] to accept)[/]") 118 | .AddChoiceGroup("Select an image to be analuyzed", new[] 119 | {"foggyday.png","foggydaysmall.png","petsmusic.png","ultrarunningmug.png", 120 | }) 121 | .AddChoices( new[] { 122 | "Type the image path to be analyzed", 123 | "Type a question" 124 | }) 125 | ); 126 | return scenarios; 127 | } 128 | } -------------------------------------------------------------------------------- /src/LabsPhi3_sk_rag01/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 2 | // Author : Bruno Capuano 3 | // Change Log : 4 | // - Sample console application to use a local model hosted in ollama and semantic memory for search 5 | // 6 | // The MIT License (MIT) 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #pragma warning disable SKEXP0001 27 | #pragma warning disable SKEXP0003 28 | #pragma warning disable SKEXP0010 29 | #pragma warning disable SKEXP0011 30 | #pragma warning disable SKEXP0050 31 | #pragma warning disable SKEXP0052 32 | 33 | using Microsoft.Extensions.DependencyInjection; 34 | using Microsoft.SemanticKernel; 35 | using Microsoft.SemanticKernel.Connectors.OpenAI; 36 | using Microsoft.SemanticKernel.Embeddings; 37 | using Microsoft.SemanticKernel.Memory; 38 | using Microsoft.SemanticKernel.Plugins.Memory; 39 | 40 | var modelId = "phi4"; 41 | 42 | // questions 43 | var questionEnglish = "What is Bruno's favourite super hero?"; 44 | var questionSpanish = "Cual es el SuperHeroe favorito de Bruno?"; 45 | var questionFrench = "Quel est le super-héros préféré de Bruno?"; 46 | var questionEnglish1 = "Who likes Batman?"; 47 | var questionSpanish2 = "A quien le gusta Batman?"; 48 | var question = questionEnglish; 49 | 50 | // intro 51 | 52 | SpectreConsoleOutput.DisplayTitle(modelId); 53 | SpectreConsoleOutput.DisplayTitleH2($"This program will answer the following question:"); 54 | SpectreConsoleOutput.DisplayTitleH2(question); 55 | SpectreConsoleOutput.DisplayTitleH3("1st approach will be to ask the question directly to the Phi-3 model."); 56 | SpectreConsoleOutput.DisplayTitleH3("2nd approach will be to add facts to a semantic memory and ask the question again"); 57 | Console.WriteLine(""); 58 | 59 | // Create a chat completion service 60 | var builder = Kernel.CreateBuilder(); 61 | //builder.AddOnnxRuntimeGenAIChatCompletion(modelPath: modelPath); 62 | builder.AddOpenAIChatCompletion( 63 | modelId: modelId, 64 | endpoint: new Uri("http://localhost:11434"), 65 | apiKey: ""); 66 | builder.AddLocalTextEmbeddingGeneration(); 67 | Kernel kernel = builder.Build(); 68 | 69 | SpectreConsoleOutput.DisplayTitleH2($"Phi-3 response (no memory)."); 70 | var response = kernel.InvokePromptStreamingAsync(question); 71 | await foreach (var result in response) 72 | { 73 | SpectreConsoleOutput.WriteGreen(result.ToString()); 74 | } 75 | 76 | // separator 77 | Console.WriteLine(""); 78 | SpectreConsoleOutput.DisplaySeparator(); 79 | Console.WriteLine("Press Enter to continue"); 80 | Console.ReadLine(); 81 | SpectreConsoleOutput.DisplayTitleH2($"Phi-4 response (using semantic memory)."); 82 | 83 | // get the embeddings generator service 84 | var embeddingGenerator = kernel.Services.GetRequiredService(); 85 | var memory = new SemanticTextMemory(new VolatileMemoryStore(), embeddingGenerator); 86 | 87 | // add facts to the collection 88 | const string MemoryCollectionName = "fanFacts"; 89 | 90 | await memory.SaveInformationAsync(MemoryCollectionName, id: "info1", text: "Gisela's favourite super hero is Batman"); 91 | await memory.SaveInformationAsync(MemoryCollectionName, id: "info2", text: "The last super hero movie watched by Gisela was Guardians of the Galaxy Vol 3"); 92 | await memory.SaveInformationAsync(MemoryCollectionName, id: "info3", text: "Bruno's favourite super hero is Invincible"); 93 | await memory.SaveInformationAsync(MemoryCollectionName, id: "info4", text: "The last super hero movie watched by Bruno was Deadpool and Wolverine"); 94 | await memory.SaveInformationAsync(MemoryCollectionName, id: "info5", text: "Bruno don't like the super hero movie: Eternals"); 95 | 96 | TextMemoryPlugin memoryPlugin = new(memory); 97 | 98 | // Import the text memory plugin into the Kernel. 99 | kernel.ImportPluginFromObject(memoryPlugin); 100 | 101 | OpenAIPromptExecutionSettings settings = new() 102 | { 103 | ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions, 104 | }; 105 | 106 | var prompt = @"Question: {{$input}} 107 | Answer the question using the memory content: {{Recall}}"; 108 | 109 | var arguments = new KernelArguments(settings) 110 | { 111 | { "input", question }, 112 | { "collection", MemoryCollectionName } 113 | }; 114 | 115 | response = kernel.InvokePromptStreamingAsync(prompt, arguments); 116 | await foreach (var result in response) 117 | { 118 | SpectreConsoleOutput.WriteGreen(result.ToString()); 119 | } 120 | 121 | Console.WriteLine($""); -------------------------------------------------------------------------------- /src/LabsPhi401/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 2 | // Author : Bruno Capuano 3 | // Change Log : 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | using Microsoft.ML.OnnxRuntimeGenAI; 26 | using System.Reflection.Emit; 27 | using System.Reflection; 28 | using Microsoft.ML.OnnxRuntime; 29 | using Microsoft.ML.OnnxRuntime.Tensors; 30 | using System.Diagnostics; 31 | 32 | //var modelPath = @"D:\phi3\models\Phi-3-mini-4k-instruct-onnx\cpu_and_mobile\cpu-int4-rtn-block-32"; 33 | var modelPath = @"d:\phi3\models\Phi-3.5-mini-instruct-onnx\cpu_and_mobile\cpu-int4-awq-block-128-acc-level-4\phi-3.5-mini-instruct-cpu-int4-awq-block-128-acc-level-4.onnx"; 34 | var session = new InferenceSession(modelPath); 35 | 36 | var systemPrompt = "You are an AI assistant that helps people find information. Answer questions using a direct style. Do not share more information that the requested by the users."; 37 | 38 | // chat start 39 | Console.WriteLine(@"Ask your question. Type an empty string to Exit."); 40 | 41 | // chat loop 42 | while (true) 43 | { 44 | // Get user question 45 | Console.WriteLine(); 46 | Console.Write(@"Q: "); 47 | //var userQ = Console.ReadLine(); 48 | var userQ = "2+2"; 49 | if (string.IsNullOrEmpty(userQ)) 50 | { 51 | break; 52 | } 53 | 54 | // show phi3 response 55 | Console.Write("Phi3: "); 56 | 57 | 58 | // create input tensor (nlp example) 59 | var inputOrtValue = OrtValue.CreateTensorWithEmptyStrings(OrtAllocator.DefaultInstance, new long[] { 1, 1 }); 60 | inputOrtValue.StringTensorSetElementAt(userQ, 0); 61 | 62 | // Create input data for session. Request all outputs in this case. 63 | var inputs = new Dictionary 64 | { 65 | { "input", inputOrtValue } 66 | }; 67 | 68 | var runOptions = new RunOptions(); 69 | 70 | // We are getting a sequence of maps as output. We are interested in the first element (map) of the sequence. 71 | // That result is a Sequence of Maps, and we only need the first map from there. 72 | var outputs = session.Run(runOptions, inputs, session.OutputNames); 73 | Debug.Assert(outputs.Count > 0, "Expecting some output"); 74 | 75 | // We want the last output, which is the sequence of maps 76 | var lastOutput = outputs[outputs.Count - 1]; 77 | 78 | // Optional code to check the output type 79 | { 80 | var outputTypeInfo = lastOutput.GetTypeInfo(); 81 | Debug.Assert(outputTypeInfo.OnnxType == OnnxValueType.ONNX_TYPE_SEQUENCE, "Expecting a sequence"); 82 | 83 | var sequenceTypeInfo = outputTypeInfo.SequenceTypeInfo; 84 | Debug.Assert(sequenceTypeInfo.ElementType.OnnxType == OnnxValueType.ONNX_TYPE_MAP, "Expecting a sequence of maps"); 85 | } 86 | 87 | var elementsNum = lastOutput.GetValueCount(); 88 | Debug.Assert(elementsNum > 0, "Expecting a non empty sequence"); 89 | 90 | // Get the first map in sequence 91 | var firstMap = lastOutput.GetValue(0, OrtAllocator.DefaultInstance); 92 | 93 | // Optional code just checking 94 | { 95 | // Maps always have two elements, keys and values 96 | // We are expecting this to be a map of strings to floats 97 | var mapTypeInfo = firstMap.GetTypeInfo().MapTypeInfo; 98 | Debug.Assert(mapTypeInfo.KeyType == TensorElementType.String, "Expecting keys to be strings"); 99 | Debug.Assert(mapTypeInfo.ValueType.OnnxType == OnnxValueType.ONNX_TYPE_TENSOR, "Values are in the tensor"); 100 | Debug.Assert(mapTypeInfo.ValueType.TensorTypeAndShapeInfo.ElementDataType == TensorElementType.Float, "Result map value is float"); 101 | } 102 | 103 | var inferenceResult = new Dictionary(); 104 | // Let use the visitor to read map keys and values 105 | // Here keys and values are represented with the same number of corresponding entries 106 | // string -> float 107 | firstMap.ProcessMap((keys, values) => { 108 | // Access native buffer directly 109 | var valuesSpan = values.GetTensorDataAsSpan(); 110 | 111 | var entryCount = (int)keys.GetTensorTypeAndShape().ElementCount; 112 | inferenceResult.EnsureCapacity(entryCount); 113 | for (int i = 0; i < entryCount; ++i) 114 | { 115 | inferenceResult.Add(keys.GetStringElement(i), valuesSpan[i]); 116 | } 117 | }, OrtAllocator.DefaultInstance); 118 | 119 | 120 | Console.WriteLine(inferenceResult.Aggregate("", (current, next) => current + $"{next.Key} ")); 121 | 122 | //// Return the inference result as json. 123 | //return new JsonResult(inferenceResult); 124 | 125 | Console.WriteLine(); 126 | } 127 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Labs using Phi-3 and Phi-3-Vision 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](/LICENSE) 4 | [![Twitter: elbruno](https://img.shields.io/twitter/follow/elbruno.svg?style=social)](https://twitter.com/elbruno) 5 | ![GitHub: elbruno](https://img.shields.io/github/followers/elbruno?style=social) 6 | 7 | Welcome to the Phi-3 samples using C#. This repository contains a set of demo projects that showcases how to integrate the powerful different versions of Phi-3 models in a .NET environment. 8 | 9 | ## Prerequisites 10 | 11 | Before running the sample, ensure you have the following installed: 12 | - **.NET 8**: Make sure you have the latest version of .NET installed on your machine. 13 | - **(Optional) Visual Studio or Visual Studio Code**: You will need an IDE or code editor capable of running .NET projects. Visual Studio or Visual Studio Code are recommended. 14 | - Using git, clone locally one of the available Phi-3 versions from Hugging Face. 15 | 16 | - Download the **phi3-mini-4k-instruct-onnx** model to your local machine: 17 | ```bash 18 | # navigate to the folder to store the models 19 | cd c:\phi3\models 20 | 21 | # add support for lfs 22 | git lfs install 23 | 24 | # clone and download mini 4K instruct model 25 | git clone https://huggingface.co/microsoft/Phi-3-mini-4k-instruct-onnx 26 | 27 | # clone and download vision 128K model 28 | git clone https://huggingface.co/microsoft/Phi-3-vision-128k-instruct-onnx-cpu 29 | ``` 30 | ***Important:** The current demos are designed to use the ONNX versions of the model. The previous steps clone the following models.* 31 | ![Download only ONNX models](./img/10DownloadOnnx.png) 32 | 33 | You can learn more about [Phi-3 in Hugging Face](https://huggingface.co/microsoft/Phi-3-mini-4k-instruct-onnx). 34 | 35 | ## About the Samples 36 | 37 | The main solution have several sample projects that demonstrates the capabilities of the Phi-3 models. 38 | 39 | ### Microsoft ML ONNX Runtime Samples 40 | 41 | | Project | Description | Location | 42 | | ------------ | ----------- | -------- | 43 | | LabsPhi301 | This is a sample project that uses a local phi3 model to ask a question. The project load a local ONNX Phi-3 model using the `Microsoft.ML.OnnxRuntime` libraries. | .\src\LabsPhi301\ | 44 | | LabsPhi303 | This is a sample project that uses a local phi3 vision model to analyze images.. The project load a local ONNX Phi-3 Vision model using the `Microsoft.ML.OnnxRuntime` libraries. | .\src\LabsPhi303\ | 45 | | LabsPhi304 | This is a sample project that uses a local phi3 vision model to analyze images.. The project load a local ONNX Phi-3 Vision model using the `Microsoft.ML.OnnxRuntime` libraries. The project also presents a menu with different options to interacti with the user. | .\src\LabsPhi304\ | 46 | 47 | ### Semantic Kernel Samples 48 | 49 | | Project | Description | Location | 50 | | ------------ | ----------- | -------- | 51 | | LabsPhi3_sk01 | This is a sample project that uses a local phi3 model to ask a question. The project uses Semantic Kernel and [SemanticKernel.Connectors.OnnxRuntimeGenAI](https://github.com/feiyun0112/SemanticKernel.Connectors.OnnxRuntimeGenAI) to load a local Phi-3 model and implement a console chat. | .\src\LabsPhi3_sk01\ | 52 | | LabsPhi3_sk02 | This is a sample project that uses a local phi3 model to ask a question. The project uses Semantic Kernel and a local copy of the source code and project [SemanticKernel.Connectors.OnnxRuntimeGenAI](/src/SemanticKernel.Connectors.OnnxRuntimeGenAI/OnnxRuntimeGenAIKernelBuilderExtensions.cs) to load a local Phi-3 model and implement a console chat. | .\src\LabsPhi3_sk02\ | 53 | | LabsPhi3_sk03 | The project uses Semantic Kernel and the local copy of the source code and project [SemanticKernel.Connectors.OnnxRuntimeGenAI](/src/SemanticKernel.Connectors.OnnxRuntimeGenAI/OnnxRuntimeGenAIKernelBuilderExtensions.cs) to load a local Phi-3 Vision model and analyzes and describes an image. | .\src\LabsPhi3_sk03\ | 54 | 55 | 56 | ## How to Run the Projects 57 | 58 | To run the projects, follow these steps: 59 | 1. Clone the repository to your local machine. 60 | 61 | 1. Open a terminal and navigate to the desired project. In example, let's run `LabsPhi301`. 62 | ```bash 63 | cd .\src\LabsPhi301\ 64 | ``` 65 | 66 | 1. Run the project with the command 67 | ```bash 68 | dotnet run 69 | ``` 70 | 71 | 1. The sample project ask for a user input and replies using the local mode. 72 | 73 | The running demo is similar to this one: 74 | 75 | ![Chat running demo](./img/20SampleConsole.gif) 76 | 77 | ***Note:** there is a typo in the 1st question, Phi-3 is cool enough to share the correct answer!* 78 | 79 | 1. The project `LabsPhi304` ask for the user to select different options, and then process the request. In example, analyzing a local image. 80 | 81 | The running demo is similar to this one: 82 | 83 | ![Image Analysis running demo](./img/30SampleVisionConsole.gif) 84 | 85 | ## References 86 | 87 | - [Semantic Kernel main repository](https://github.com/microsoft/semantic-kernel) 88 | - [SemanticKernel.Connectors.OnnxRuntimeGenAI repository by feiyun0112](https://github.com/feiyun0112/SemanticKernel.Connectors.OnnxRuntimeGenAI) 89 | 90 | 91 | ## Author 92 | 93 | 👤 **Bruno Capuano** 94 | 95 | * Website: https://elbruno.com 96 | * Twitter: [@elbruno](https://twitter.com/elbruno) 97 | * Github: [@elbruno](https://github.com/elbruno) 98 | * LinkedIn: [@elbruno](https://linkedin.com/in/elbruno) 99 | 100 | ## 🤝 Contributing 101 | 102 | Contributions, issues and feature requests are welcome! 103 | 104 | Feel free to check [issues page](https://github.com/elbruno/phi3-labs//issues). 105 | 106 | ## Show your support 107 | 108 | Give a ⭐️ if this project helped you! 109 | 110 | 111 | ## 📝 License 112 | 113 | Copyright © 2024 [Bruno Capuano](https://github.com/elbruno). 114 | 115 | This project is [MIT](/LICENSE) licensed. 116 | 117 | *** 118 | -------------------------------------------------------------------------------- /src/LabsPhi3_sk_rag02/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 2 | // Author : Bruno Capuano 3 | // Change Log : 4 | // - Sample console application to use a local model hosted in ollama and semantic memory for search 5 | // 6 | // The MIT License (MIT) 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #pragma warning disable SKEXP0001 27 | #pragma warning disable SKEXP0003 28 | #pragma warning disable SKEXP0010 29 | #pragma warning disable SKEXP0011 30 | #pragma warning disable SKEXP0050 31 | #pragma warning disable SKEXP0052 32 | 33 | using Microsoft.Extensions.DependencyInjection; 34 | using Microsoft.SemanticKernel; 35 | using Microsoft.SemanticKernel.ChatCompletion; 36 | using Microsoft.SemanticKernel.Connectors.OpenAI; 37 | using Microsoft.SemanticKernel.Embeddings; 38 | using Microsoft.SemanticKernel.Memory; 39 | using Microsoft.SemanticKernel.Plugins.Memory; 40 | using SmartComponents.StaticAssets.Inference; 41 | 42 | // system message 43 | var systemMessage = "You are a helpful assistant. You reply in short and precise answers, and you explain your responses. If you don't know an answer, you reply 'I don't know'"; 44 | 45 | // questions 46 | var questionEnglish = "What is Bruno's favourite super hero?"; 47 | var questionSpanish = "Cual es el SuperHeroe favorito de Bruno?"; 48 | var questionFrench = "Quel est le super-héros préféré de Bruno?"; 49 | var questionEnglish1 = "Who likes Batman?"; 50 | var questionSpanish2 = "A quien le gusta Batman?"; 51 | var question = questionSpanish2; 52 | 53 | // intro 54 | SpectreConsoleOutput.DisplayTitle(); 55 | SpectreConsoleOutput.DisplayTitleH2($"This program will answer the following question:"); 56 | SpectreConsoleOutput.DisplayTitleH2(question); 57 | SpectreConsoleOutput.DisplayTitleH3("1st approach will be to ask the question directly to the Phi-3 model."); 58 | SpectreConsoleOutput.DisplayTitleH3("2nd approach will be to add facts to a semantic memory and ask the question again"); 59 | Console.WriteLine(""); 60 | 61 | //var modelPath = @"D:\phi3\models\Phi-3-mini-4k-instruct-onnx\cpu_and_mobile\cpu-int4-rtn-block-32"; 62 | var modelPath = @"d:\phi3\models\Phi-3.5-mini-instruct-onnx-web"; 63 | 64 | // Create a chat completion service 65 | var builder = Kernel.CreateBuilder(); 66 | //builder.AddOnnxRuntimeGenAIChatCompletion(modelPath: modelPath); 67 | builder.AddOpenAIChatCompletion( 68 | modelId: "phi3.5", 69 | endpoint: new Uri("http://localhost:11434"), 70 | apiKey: "apikey"); 71 | builder.AddLocalTextEmbeddingGeneration(); 72 | Kernel kernel = builder.Build(); 73 | var chat = kernel.GetRequiredService(); 74 | 75 | // no memory 76 | SpectreConsoleOutput.DisplayTitleH2($"Phi-3 response (no memory)."); 77 | var history = new ChatHistory(); 78 | history.AddSystemMessage(systemMessage); 79 | 80 | //history.AddUserMessage(question); 81 | //var response = chat.GetStreamingChatMessageContentsAsync(history); 82 | //await foreach (var result in response) 83 | //{ 84 | // SpectreConsoleOutput.WriteGreen(result.ToString()); 85 | //} 86 | 87 | // separator 88 | Console.WriteLine(""); 89 | SpectreConsoleOutput.DisplaySeparator(); 90 | Console.WriteLine("Press Enter to continue"); 91 | Console.ReadLine(); 92 | SpectreConsoleOutput.DisplayTitleH2($"Phi-3 response (using semantic memory)."); 93 | 94 | // Using memory 95 | history = new ChatHistory(); 96 | history.AddSystemMessage(systemMessage); 97 | 98 | // get the embeddings generator service 99 | var embeddingGenerator = kernel.Services.GetRequiredService(); 100 | var memory = new SemanticTextMemory(new VolatileMemoryStore(), embeddingGenerator); 101 | 102 | // add facts to the collection 103 | const string MemoryCollectionName = "fanFacts"; 104 | 105 | await memory.SaveInformationAsync(MemoryCollectionName, id: "info1", text: "Gisela's favourite super hero is Batman"); 106 | await memory.SaveInformationAsync(MemoryCollectionName, id: "info2", text: "The last super hero movie watched by Gisela was Guardians of the Galaxy Vol 3"); 107 | await memory.SaveInformationAsync(MemoryCollectionName, id: "info3", text: "Bruno's favourite super hero is Invincible"); 108 | await memory.SaveInformationAsync(MemoryCollectionName, id: "info4", text: "The last super hero movie watched by Bruno was Deadpool and Wolverine"); 109 | await memory.SaveInformationAsync(MemoryCollectionName, id: "info5", text: "Bruno don't like the super hero movie: Eternals"); 110 | 111 | TextMemoryPlugin memoryPlugin = new(memory); 112 | 113 | // Import the text memory plugin into the Kernel. 114 | kernel.ImportPluginFromObject(memoryPlugin); 115 | 116 | OpenAIPromptExecutionSettings settings = new() 117 | { 118 | ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions, 119 | }; 120 | 121 | var prompt = @"Question: {{$input}} 122 | Answer the question using the memory content: {{Recall}}"; 123 | 124 | history.AddUserMessage(prompt); 125 | 126 | var arguments = new KernelArguments(settings) 127 | { 128 | { "input", question }, 129 | { "collection", MemoryCollectionName }, 130 | { "messages", history } 131 | }; 132 | 133 | var newResponse = kernel.InvokePromptStreamingAsync(prompt, arguments); 134 | await foreach (var result in newResponse) 135 | { 136 | SpectreConsoleOutput.WriteGreen(result.ToString()); 137 | } 138 | 139 | Console.WriteLine($""); -------------------------------------------------------------------------------- /src/LabsPhi304/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 2 | // Author : Bruno Capuano 3 | // Change Log : 4 | // 5 | // The MIT License (MIT) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | using LabsPhi304; 26 | using Microsoft.ML.OnnxRuntimeGenAI; 27 | using Spectre.Console; 28 | using System.Text; 29 | 30 | // path for model and images 31 | var modelPath = @"d:\phi3\models\Phi-3-vision-128k-instruct-onnx-cpu\cpu-int4-rtn-block-32-acc-level-4"; 32 | 33 | // write title 34 | SpectreConsoleOutput.DisplayTitle($".NET - Phi3v"); 35 | 36 | // load model and create processor 37 | using Model model = new Model(modelPath); 38 | using MultiModalProcessor processor = new MultiModalProcessor(model); 39 | using var tokenizerStream = processor.CreateStream(); 40 | var tokenizer = new Tokenizer(model); 41 | 42 | // define prompts 43 | var systemPrompt = "You are an AI assistant that helps people find information. Answer questions using a direct style. Do not share more information that the requested by the users."; 44 | 45 | // user choice scenarios 46 | var scenarios = SpectreConsoleOutput.SelectScenarios(); 47 | var scenario = scenarios[0]; 48 | 49 | // switch between the options for the selected scenario 50 | // options can be file names with extension equal to ".png" or ".jpg" 51 | // or the values "Type the image path to be analyzed" or "Type a question" 52 | switch (scenario) 53 | { 54 | case "foggyday.png": 55 | case "foggydaysmall.png": 56 | case "petsmusic.png": 57 | case "ultrarunningmug.png": 58 | var imagePath = Path.Combine(Directory.GetCurrentDirectory(), "imgs", scenario); 59 | AnalizeImage(imagePath); 60 | break; 61 | case "Type the image path to be analyzed": 62 | scenario = SpectreConsoleOutput.AskForString("Type the image path to be analyzed"); 63 | AnalizeImage(scenario); 64 | break; 65 | case "Type a question": 66 | AnswerQuestion(); 67 | break; 68 | } 69 | SpectreConsoleOutput.DisplayTitleH3("Done !"); 70 | 71 | void AnswerQuestion() 72 | { 73 | var question = SpectreConsoleOutput.AskForString("Type a question"); 74 | SpectreConsoleOutput.DisplayQuestion(question); 75 | SpectreConsoleOutput.DisplayAnswerStart("Phi-3"); 76 | 77 | var fullPrompt = $"<|system|>{systemPrompt}<|end|><|user|>{question}<|end|><|assistant|>"; 78 | var tokens = tokenizer.Encode(fullPrompt); 79 | 80 | var generatorParams = new GeneratorParams(model); 81 | generatorParams.SetSearchOption("max_length", 2048); 82 | generatorParams.SetSearchOption("past_present_share_buffer", false); 83 | generatorParams.SetInputSequences(tokens); 84 | 85 | var generator = new Generator(model, generatorParams); 86 | while (!generator.IsDone()) 87 | { 88 | generator.ComputeLogits(); 89 | generator.GenerateNextToken(); 90 | var outputTokens = generator.GetSequence(0); 91 | var newToken = outputTokens.Slice(outputTokens.Length - 1, 1); 92 | var output = tokenizer.Decode(newToken); 93 | Console.Write(output); 94 | } 95 | Console.WriteLine(); 96 | } 97 | 98 | void AnalizeImage(string imagePath) 99 | { 100 | // display text with the image path 101 | SpectreConsoleOutput.DisplayFilePath("Analizing image", imagePath); 102 | 103 | // Display the image thumbnail 104 | var image = new CanvasImage(imagePath); 105 | image.MaxWidth(16); 106 | AnsiConsole.Write(image); 107 | 108 | StringBuilder phiResponse = new StringBuilder(); 109 | 110 | AnsiConsole.Status() 111 | .Start("Analyzing image ...", ctx => 112 | { 113 | var img = Images.Load(imagePath); 114 | string userPrompt = "Describe the image, and return the string 'STOP' at the end."; 115 | var fullPrompt = $"<|system|>{systemPrompt}<|end|><|user|><|image_1|>{userPrompt}<|end|><|assistant|>"; 116 | 117 | // create the input tensor with the prompt and image 118 | SpectreConsoleOutput.DisplaySubtitle("Full Prompt", fullPrompt); 119 | 120 | // Update the status and spinner 121 | ctx.Status("ONNX image processing ..."); 122 | ctx.Spinner(Spinner.Known.Star); 123 | ctx.SpinnerStyle(Style.Parse("green")); 124 | 125 | 126 | var inputTensors = processor.ProcessImages(fullPrompt, img); 127 | using GeneratorParams generatorParams = new GeneratorParams(model); 128 | generatorParams.SetSearchOption("max_length", 3072); 129 | generatorParams.SetInputs(inputTensors); 130 | 131 | var isProcessingTokenStarted = false; 132 | 133 | // generate response 134 | using var generator = new Generator(model, generatorParams); 135 | while (!generator.IsDone()) 136 | { 137 | generator.ComputeLogits(); 138 | generator.GenerateNextToken(); 139 | 140 | if (!isProcessingTokenStarted) 141 | { 142 | ctx.Status("Processing response tokens ..."); 143 | ctx.Spinner(Spinner.Known.Dots12); 144 | ctx.SpinnerStyle(Style.Parse("blue")); 145 | isProcessingTokenStarted = true; 146 | } 147 | 148 | var seq = generator.GetSequence(0)[^1]; 149 | var tokenString = tokenizerStream.Decode(seq); 150 | AnsiConsole.Markup($"[bold][blue]>> Token:[/][/] {tokenString}"); 151 | phiResponse.Append(tokenString); 152 | } 153 | }); 154 | 155 | // display the response 156 | SpectreConsoleOutput.DisplaySubtitle("Phi-3 Response", phiResponse.ToString()); 157 | } -------------------------------------------------------------------------------- /src/SemanticKernel.Connectors.OnnxRuntimeGenAI/Services/OnnxRuntimeGenAIChatCompletionService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using Microsoft.Extensions.Logging; 6 | using Microsoft.ML.OnnxRuntimeGenAI; 7 | using Microsoft.SemanticKernel; 8 | using Microsoft.SemanticKernel.ChatCompletion; 9 | using Microsoft.SemanticKernel.Services; 10 | using philabs.SemanticKernel.Connectors.OnnxRuntimeGenAI.Models; 11 | 12 | namespace philabs.SemanticKernel.Connectors.OnnxRuntimeGenAI; 13 | 14 | /// 15 | /// Represents a chat completion service using OnnxRuntimeGenAI. 16 | /// 17 | public sealed class OnnxRuntimeGenAIChatCompletionService : IChatCompletionService 18 | { 19 | private readonly Model _model; 20 | private readonly Tokenizer _tokenizer; 21 | private readonly MultiModalProcessor _processor; 22 | private readonly TokenizerStream _tokenizerStream; 23 | private Dictionary AttributesInternal { get; } = new(); 24 | 25 | /// 26 | /// Initializes a new instance of the OnnxRuntimeGenAIChatCompletionService class. 27 | /// 28 | /// The generative AI ONNX model path for the chat completion service. 29 | /// Optional logger factory to be used for logging. 30 | public OnnxRuntimeGenAIChatCompletionService( 31 | string modelPath, 32 | ILoggerFactory? loggerFactory = null) 33 | { 34 | _model = new Model(modelPath); 35 | _tokenizer = new Tokenizer(_model); 36 | 37 | if (modelPath.Contains("vision")) 38 | { 39 | _processor = new MultiModalProcessor(_model); 40 | _tokenizerStream = _processor.CreateStream(); 41 | } 42 | 43 | this.AttributesInternal.Add(AIServiceExtensions.ModelIdKey, _tokenizer); 44 | } 45 | 46 | /// 47 | public IReadOnlyDictionary Attributes => this.AttributesInternal; 48 | 49 | /// 50 | public async Task> GetChatMessageContentsAsync(ChatHistory chatHistory, PromptExecutionSettings? executionSettings = null, Kernel? kernel = null, CancellationToken cancellationToken = default) 51 | { 52 | var result = new StringBuilder(); 53 | 54 | await foreach (var content in RunInferenceAsync(chatHistory, executionSettings, cancellationToken)) 55 | { 56 | result.Append(content); 57 | } 58 | 59 | return new List 60 | { 61 | new( 62 | role: AuthorRole.Assistant, 63 | content: result.ToString()) 64 | }; 65 | } 66 | 67 | /// 68 | public async IAsyncEnumerable GetStreamingChatMessageContentsAsync(ChatHistory chatHistory, PromptExecutionSettings? executionSettings = null, Kernel? kernel = null, CancellationToken cancellationToken = default) 69 | { 70 | await foreach (var content in RunInferenceAsync(chatHistory, executionSettings, cancellationToken)) 71 | { 72 | yield return new StreamingChatMessageContent(AuthorRole.Assistant, content); 73 | } 74 | } 75 | 76 | private async IAsyncEnumerable RunInferenceAsync(ChatHistory chatHistory, PromptExecutionSettings? executionSettings, CancellationToken cancellationToken) 77 | { 78 | OnnxRuntimeGenAIPromptExecutionSettings onnxRuntimeGenAIPromptExecutionSettings = OnnxRuntimeGenAIPromptExecutionSettings.FromExecutionSettings(executionSettings); 79 | 80 | var promptResult = GetPrompt(chatHistory, onnxRuntimeGenAIPromptExecutionSettings); 81 | 82 | Generator generator; 83 | 84 | var generatorParams = new GeneratorParams(_model); 85 | ApplyPromptExecutionSettings(generatorParams, onnxRuntimeGenAIPromptExecutionSettings); 86 | 87 | if (!promptResult.ImageFound) 88 | { 89 | var tokens = _tokenizer.Encode(promptResult.Prompt); 90 | generatorParams.SetInputSequences(tokens); 91 | } 92 | else 93 | { 94 | var img = Images.Load(promptResult.ImagePath); 95 | var inputTensors = _processor.ProcessImages(promptResult.Prompt, img); 96 | generatorParams.SetSearchOption("max_length", 3072); 97 | generatorParams.SetInputs(inputTensors); 98 | } 99 | 100 | generator = new Generator(_model, generatorParams); 101 | 102 | 103 | if (generator is not null) 104 | while (!generator.IsDone()) 105 | { 106 | cancellationToken.ThrowIfCancellationRequested(); 107 | 108 | yield return await Task.Run(() => 109 | { 110 | generator.ComputeLogits(); 111 | generator.GenerateNextToken(); 112 | 113 | var outputTokens = generator.GetSequence(0); 114 | var newToken = outputTokens.Slice(outputTokens.Length - 1, 1); 115 | var output = _tokenizer.Decode(newToken); 116 | return output; 117 | }, cancellationToken); 118 | } 119 | 120 | } 121 | 122 | private PromptBuilderResult GetPrompt(ChatHistory chatHistory, OnnxRuntimeGenAIPromptExecutionSettings onnxRuntimeGenAIPromptExecutionSettings) 123 | { 124 | var result = new PromptBuilderResult(); 125 | var promptBuilder = new StringBuilder(); 126 | foreach (var message in chatHistory) 127 | { 128 | promptBuilder.Append($"<|{message.Role}|>\n{message.Content}"); 129 | 130 | // process sub items 131 | foreach (var item in message.Items) 132 | { 133 | if (item is ImageContent imageContent) 134 | { 135 | result.ImageFound = true; 136 | promptBuilder.Append($"<|image_1|>"); 137 | 138 | var imageItem = item as ImageContent; 139 | 140 | if (imageItem?.Data != null) 141 | { 142 | result.ImageBytes = imageItem.Data.Value.ToArray(); 143 | } 144 | else if (imageItem?.Uri != null) 145 | { 146 | result.Uri = imageItem.Uri; 147 | } 148 | break; 149 | } 150 | } 151 | 152 | } 153 | promptBuilder.Append($"<|end|>\n<|assistant|>"); 154 | 155 | result.Prompt = promptBuilder.ToString(); 156 | 157 | return result; 158 | } 159 | 160 | private void ApplyPromptExecutionSettings(GeneratorParams generatorParams, OnnxRuntimeGenAIPromptExecutionSettings onnxRuntimeGenAIPromptExecutionSettings) 161 | { 162 | generatorParams.SetSearchOption("top_p", onnxRuntimeGenAIPromptExecutionSettings.TopP); 163 | generatorParams.SetSearchOption("top_k", onnxRuntimeGenAIPromptExecutionSettings.TopK); 164 | generatorParams.SetSearchOption("temperature", onnxRuntimeGenAIPromptExecutionSettings.Temperature); 165 | generatorParams.SetSearchOption("repetition_penalty", onnxRuntimeGenAIPromptExecutionSettings.RepetitionPenalty); 166 | generatorParams.SetSearchOption("past_present_share_buffer", onnxRuntimeGenAIPromptExecutionSettings.PastPresentShareBuffer); 167 | generatorParams.SetSearchOption("num_return_sequences", onnxRuntimeGenAIPromptExecutionSettings.NumReturnSequences); 168 | generatorParams.SetSearchOption("no_repeat_ngram_size", onnxRuntimeGenAIPromptExecutionSettings.NoRepeatNgramSize); 169 | generatorParams.SetSearchOption("min_length", onnxRuntimeGenAIPromptExecutionSettings.MinLength); 170 | generatorParams.SetSearchOption("max_length", onnxRuntimeGenAIPromptExecutionSettings.MaxLength); 171 | generatorParams.SetSearchOption("length_penalty", onnxRuntimeGenAIPromptExecutionSettings.LengthPenalty); 172 | generatorParams.SetSearchOption("early_stopping", onnxRuntimeGenAIPromptExecutionSettings.EarlyStopping); 173 | generatorParams.SetSearchOption("do_sample", onnxRuntimeGenAIPromptExecutionSettings.DoSample); 174 | generatorParams.SetSearchOption("diversity_penalty", onnxRuntimeGenAIPromptExecutionSettings.DiversityPenalty); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.tlog 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 298 | *.vbp 299 | 300 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 301 | *.dsw 302 | *.dsp 303 | 304 | # Visual Studio 6 technical files 305 | *.ncb 306 | *.aps 307 | 308 | # Visual Studio LightSwitch build output 309 | **/*.HTMLClient/GeneratedArtifacts 310 | **/*.DesktopClient/GeneratedArtifacts 311 | **/*.DesktopClient/ModelManifest.xml 312 | **/*.Server/GeneratedArtifacts 313 | **/*.Server/ModelManifest.xml 314 | _Pvt_Extensions 315 | 316 | # Paket dependency manager 317 | .paket/paket.exe 318 | paket-files/ 319 | 320 | # FAKE - F# Make 321 | .fake/ 322 | 323 | # CodeRush personal settings 324 | .cr/personal 325 | 326 | # Python Tools for Visual Studio (PTVS) 327 | __pycache__/ 328 | *.pyc 329 | 330 | # Cake - Uncomment if you are using it 331 | # tools/** 332 | # !tools/packages.config 333 | 334 | # Tabs Studio 335 | *.tss 336 | 337 | # Telerik's JustMock configuration file 338 | *.jmconfig 339 | 340 | # BizTalk build output 341 | *.btp.cs 342 | *.btm.cs 343 | *.odx.cs 344 | *.xsd.cs 345 | 346 | # OpenCover UI analysis results 347 | OpenCover/ 348 | 349 | # Azure Stream Analytics local run output 350 | ASALocalRun/ 351 | 352 | # MSBuild Binary and Structured Log 353 | *.binlog 354 | 355 | # NVidia Nsight GPU debugger configuration file 356 | *.nvuser 357 | 358 | # MFractors (Xamarin productivity tool) working folder 359 | .mfractor/ 360 | 361 | # Local History for Visual Studio 362 | .localhistory/ 363 | 364 | # Visual Studio History (VSHistory) files 365 | .vshistory/ 366 | 367 | # BeatPulse healthcheck temp database 368 | healthchecksdb 369 | 370 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 371 | MigrationBackup/ 372 | 373 | # Ionide (cross platform F# VS Code tools) working folder 374 | .ionide/ 375 | 376 | # Fody - auto-generated XML schema 377 | FodyWeavers.xsd 378 | 379 | # VS Code files for those working on multiple tools 380 | .vscode/* 381 | !.vscode/settings.json 382 | !.vscode/tasks.json 383 | !.vscode/launch.json 384 | !.vscode/extensions.json 385 | *.code-workspace 386 | 387 | # Local History for Visual Studio Code 388 | .history/ 389 | 390 | # Windows Installer files from build outputs 391 | *.cab 392 | *.msi 393 | *.msix 394 | *.msm 395 | *.msp 396 | 397 | # JetBrains Rider 398 | *.sln.iml 399 | -------------------------------------------------------------------------------- /src/LabsPhi3.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.10.34928.147 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LabsPhi301", "LabsPhi301\LabsPhi301.csproj", "{22131B1B-1289-41DF-882F-A2E16A63BE9E}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LabsPhi3_sk01", "LabsPhi3_sk01\LabsPhi3_sk01.csproj", "{1254AB34-B99A-4E4C-BD95-18BB22BF478E}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LabsPhi304", "LabsPhi304\LabsPhi304.csproj", "{4EB2FBF6-75D3-4B10-B5B5-675469C24780}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Connectors.OnnxRuntimeGenAI", "SemanticKernel.Connectors.OnnxRuntimeGenAI\Connectors.OnnxRuntimeGenAI.csproj", "{52D662CC-407B-42E6-8446-BEF969FFD30B}" 13 | EndProject 14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ONNX", "ONNX", "{0BC576AC-FDE1-4DF8-BABD-668DBE6E7C9C}" 15 | EndProject 16 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SK", "SK", "{255AD044-4A87-4975-B8EF-016F87277741}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LabsPhi303", "LabsPhi303\LabsPhi303.csproj", "{ED480C58-4355-4430-950B-1D85D3AE9891}" 19 | EndProject 20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LabsPhi3_sk02", "LabsPhi3_sk02\LabsPhi3_sk02.csproj", "{2C14C6E3-AF20-43CB-AECD-F6BBC2B2A858}" 21 | EndProject 22 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LabsPhi3_sk03", "LabsPhi3_sk03\LabsPhi3_sk03.csproj", "{C88880FD-67E0-4A72-BD29-005A8291DF7B}" 23 | EndProject 24 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure AI", "Azure AI", "{EA6E5514-23BD-4B8B-A804-88AD5BF03E06}" 25 | EndProject 26 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LabsPhi3_sk_azure01", "LabsPhi3_sk_azure01\LabsPhi3_sk_azure01.csproj", "{F9835E50-8AB8-4307-A70E-6DD63142CF50}" 27 | EndProject 28 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LabsPhi3_sk_azure02", "LabsPhi3_sk_azure02\LabsPhi3_sk_azure02.csproj", "{84B45833-3D23-4095-ACDD-2C769A0E078C}" 29 | EndProject 30 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RAG", "RAG", "{57EDA879-FEC3-484B-B5A2-CC60B9BADE47}" 31 | EndProject 32 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LabsPhi3_sk_rag01", "LabsPhi3_sk_rag01\LabsPhi3_sk_rag01.csproj", "{046B5598-8DA6-4E49-BBC0-B88620E4CA48}" 33 | EndProject 34 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LabsPhi3_sk_rag02", "LabsPhi3_sk_rag02\LabsPhi3_sk_rag02.csproj", "{813A9EBB-F3CF-434B-AAC6-3058CCF75632}" 35 | EndProject 36 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LabsPhi401", "LabsPhi401\LabsPhi401.csproj", "{0E93E13A-4AC6-48EB-A146-474639B0F7A6}" 37 | EndProject 38 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LabsPhi3_sk_rag03", "LabsPhi3_sk_rag03\LabsPhi3_sk_rag03.csproj", "{BFEF19DC-15C0-4ADD-A672-4337F9A7B95C}" 39 | EndProject 40 | Global 41 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 42 | Debug_Cuda|Any CPU = Debug_Cuda|Any CPU 43 | Debug_DirectML|Any CPU = Debug_DirectML|Any CPU 44 | Debug|Any CPU = Debug|Any CPU 45 | Release_Cuda|Any CPU = Release_Cuda|Any CPU 46 | Release_DirectML|Any CPU = Release_DirectML|Any CPU 47 | Release|Any CPU = Release|Any CPU 48 | EndGlobalSection 49 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 50 | {22131B1B-1289-41DF-882F-A2E16A63BE9E}.Debug_Cuda|Any CPU.ActiveCfg = Debug|Any CPU 51 | {22131B1B-1289-41DF-882F-A2E16A63BE9E}.Debug_Cuda|Any CPU.Build.0 = Debug|Any CPU 52 | {22131B1B-1289-41DF-882F-A2E16A63BE9E}.Debug_DirectML|Any CPU.ActiveCfg = Debug|Any CPU 53 | {22131B1B-1289-41DF-882F-A2E16A63BE9E}.Debug_DirectML|Any CPU.Build.0 = Debug|Any CPU 54 | {22131B1B-1289-41DF-882F-A2E16A63BE9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 55 | {22131B1B-1289-41DF-882F-A2E16A63BE9E}.Debug|Any CPU.Build.0 = Debug|Any CPU 56 | {22131B1B-1289-41DF-882F-A2E16A63BE9E}.Release_Cuda|Any CPU.ActiveCfg = Release|Any CPU 57 | {22131B1B-1289-41DF-882F-A2E16A63BE9E}.Release_Cuda|Any CPU.Build.0 = Release|Any CPU 58 | {22131B1B-1289-41DF-882F-A2E16A63BE9E}.Release_DirectML|Any CPU.ActiveCfg = Release|Any CPU 59 | {22131B1B-1289-41DF-882F-A2E16A63BE9E}.Release_DirectML|Any CPU.Build.0 = Release|Any CPU 60 | {22131B1B-1289-41DF-882F-A2E16A63BE9E}.Release|Any CPU.ActiveCfg = Release|Any CPU 61 | {22131B1B-1289-41DF-882F-A2E16A63BE9E}.Release|Any CPU.Build.0 = Release|Any CPU 62 | {1254AB34-B99A-4E4C-BD95-18BB22BF478E}.Debug_Cuda|Any CPU.ActiveCfg = Debug|Any CPU 63 | {1254AB34-B99A-4E4C-BD95-18BB22BF478E}.Debug_Cuda|Any CPU.Build.0 = Debug|Any CPU 64 | {1254AB34-B99A-4E4C-BD95-18BB22BF478E}.Debug_DirectML|Any CPU.ActiveCfg = Debug|Any CPU 65 | {1254AB34-B99A-4E4C-BD95-18BB22BF478E}.Debug_DirectML|Any CPU.Build.0 = Debug|Any CPU 66 | {1254AB34-B99A-4E4C-BD95-18BB22BF478E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 67 | {1254AB34-B99A-4E4C-BD95-18BB22BF478E}.Debug|Any CPU.Build.0 = Debug|Any CPU 68 | {1254AB34-B99A-4E4C-BD95-18BB22BF478E}.Release_Cuda|Any CPU.ActiveCfg = Release|Any CPU 69 | {1254AB34-B99A-4E4C-BD95-18BB22BF478E}.Release_Cuda|Any CPU.Build.0 = Release|Any CPU 70 | {1254AB34-B99A-4E4C-BD95-18BB22BF478E}.Release_DirectML|Any CPU.ActiveCfg = Release|Any CPU 71 | {1254AB34-B99A-4E4C-BD95-18BB22BF478E}.Release_DirectML|Any CPU.Build.0 = Release|Any CPU 72 | {1254AB34-B99A-4E4C-BD95-18BB22BF478E}.Release|Any CPU.ActiveCfg = Release|Any CPU 73 | {1254AB34-B99A-4E4C-BD95-18BB22BF478E}.Release|Any CPU.Build.0 = Release|Any CPU 74 | {4EB2FBF6-75D3-4B10-B5B5-675469C24780}.Debug_Cuda|Any CPU.ActiveCfg = Debug|Any CPU 75 | {4EB2FBF6-75D3-4B10-B5B5-675469C24780}.Debug_Cuda|Any CPU.Build.0 = Debug|Any CPU 76 | {4EB2FBF6-75D3-4B10-B5B5-675469C24780}.Debug_DirectML|Any CPU.ActiveCfg = Debug|Any CPU 77 | {4EB2FBF6-75D3-4B10-B5B5-675469C24780}.Debug_DirectML|Any CPU.Build.0 = Debug|Any CPU 78 | {4EB2FBF6-75D3-4B10-B5B5-675469C24780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 79 | {4EB2FBF6-75D3-4B10-B5B5-675469C24780}.Debug|Any CPU.Build.0 = Debug|Any CPU 80 | {4EB2FBF6-75D3-4B10-B5B5-675469C24780}.Release_Cuda|Any CPU.ActiveCfg = Release|Any CPU 81 | {4EB2FBF6-75D3-4B10-B5B5-675469C24780}.Release_Cuda|Any CPU.Build.0 = Release|Any CPU 82 | {4EB2FBF6-75D3-4B10-B5B5-675469C24780}.Release_DirectML|Any CPU.ActiveCfg = Release|Any CPU 83 | {4EB2FBF6-75D3-4B10-B5B5-675469C24780}.Release_DirectML|Any CPU.Build.0 = Release|Any CPU 84 | {4EB2FBF6-75D3-4B10-B5B5-675469C24780}.Release|Any CPU.ActiveCfg = Release|Any CPU 85 | {4EB2FBF6-75D3-4B10-B5B5-675469C24780}.Release|Any CPU.Build.0 = Release|Any CPU 86 | {52D662CC-407B-42E6-8446-BEF969FFD30B}.Debug_Cuda|Any CPU.ActiveCfg = Debug_Cuda|Any CPU 87 | {52D662CC-407B-42E6-8446-BEF969FFD30B}.Debug_Cuda|Any CPU.Build.0 = Debug_Cuda|Any CPU 88 | {52D662CC-407B-42E6-8446-BEF969FFD30B}.Debug_DirectML|Any CPU.ActiveCfg = Debug_DirectML|Any CPU 89 | {52D662CC-407B-42E6-8446-BEF969FFD30B}.Debug_DirectML|Any CPU.Build.0 = Debug_DirectML|Any CPU 90 | {52D662CC-407B-42E6-8446-BEF969FFD30B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 91 | {52D662CC-407B-42E6-8446-BEF969FFD30B}.Debug|Any CPU.Build.0 = Debug|Any CPU 92 | {52D662CC-407B-42E6-8446-BEF969FFD30B}.Release_Cuda|Any CPU.ActiveCfg = Release_Cuda|Any CPU 93 | {52D662CC-407B-42E6-8446-BEF969FFD30B}.Release_Cuda|Any CPU.Build.0 = Release_Cuda|Any CPU 94 | {52D662CC-407B-42E6-8446-BEF969FFD30B}.Release_DirectML|Any CPU.ActiveCfg = Release_DirectML|Any CPU 95 | {52D662CC-407B-42E6-8446-BEF969FFD30B}.Release_DirectML|Any CPU.Build.0 = Release_DirectML|Any CPU 96 | {52D662CC-407B-42E6-8446-BEF969FFD30B}.Release|Any CPU.ActiveCfg = Release|Any CPU 97 | {52D662CC-407B-42E6-8446-BEF969FFD30B}.Release|Any CPU.Build.0 = Release|Any CPU 98 | {ED480C58-4355-4430-950B-1D85D3AE9891}.Debug_Cuda|Any CPU.ActiveCfg = Debug|Any CPU 99 | {ED480C58-4355-4430-950B-1D85D3AE9891}.Debug_Cuda|Any CPU.Build.0 = Debug|Any CPU 100 | {ED480C58-4355-4430-950B-1D85D3AE9891}.Debug_DirectML|Any CPU.ActiveCfg = Debug|Any CPU 101 | {ED480C58-4355-4430-950B-1D85D3AE9891}.Debug_DirectML|Any CPU.Build.0 = Debug|Any CPU 102 | {ED480C58-4355-4430-950B-1D85D3AE9891}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 103 | {ED480C58-4355-4430-950B-1D85D3AE9891}.Debug|Any CPU.Build.0 = Debug|Any CPU 104 | {ED480C58-4355-4430-950B-1D85D3AE9891}.Release_Cuda|Any CPU.ActiveCfg = Release|Any CPU 105 | {ED480C58-4355-4430-950B-1D85D3AE9891}.Release_Cuda|Any CPU.Build.0 = Release|Any CPU 106 | {ED480C58-4355-4430-950B-1D85D3AE9891}.Release_DirectML|Any CPU.ActiveCfg = Release|Any CPU 107 | {ED480C58-4355-4430-950B-1D85D3AE9891}.Release_DirectML|Any CPU.Build.0 = Release|Any CPU 108 | {ED480C58-4355-4430-950B-1D85D3AE9891}.Release|Any CPU.ActiveCfg = Release|Any CPU 109 | {ED480C58-4355-4430-950B-1D85D3AE9891}.Release|Any CPU.Build.0 = Release|Any CPU 110 | {2C14C6E3-AF20-43CB-AECD-F6BBC2B2A858}.Debug_Cuda|Any CPU.ActiveCfg = Debug|Any CPU 111 | {2C14C6E3-AF20-43CB-AECD-F6BBC2B2A858}.Debug_Cuda|Any CPU.Build.0 = Debug|Any CPU 112 | {2C14C6E3-AF20-43CB-AECD-F6BBC2B2A858}.Debug_DirectML|Any CPU.ActiveCfg = Debug|Any CPU 113 | {2C14C6E3-AF20-43CB-AECD-F6BBC2B2A858}.Debug_DirectML|Any CPU.Build.0 = Debug|Any CPU 114 | {2C14C6E3-AF20-43CB-AECD-F6BBC2B2A858}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 115 | {2C14C6E3-AF20-43CB-AECD-F6BBC2B2A858}.Debug|Any CPU.Build.0 = Debug|Any CPU 116 | {2C14C6E3-AF20-43CB-AECD-F6BBC2B2A858}.Release_Cuda|Any CPU.ActiveCfg = Release|Any CPU 117 | {2C14C6E3-AF20-43CB-AECD-F6BBC2B2A858}.Release_Cuda|Any CPU.Build.0 = Release|Any CPU 118 | {2C14C6E3-AF20-43CB-AECD-F6BBC2B2A858}.Release_DirectML|Any CPU.ActiveCfg = Release|Any CPU 119 | {2C14C6E3-AF20-43CB-AECD-F6BBC2B2A858}.Release_DirectML|Any CPU.Build.0 = Release|Any CPU 120 | {2C14C6E3-AF20-43CB-AECD-F6BBC2B2A858}.Release|Any CPU.ActiveCfg = Release|Any CPU 121 | {2C14C6E3-AF20-43CB-AECD-F6BBC2B2A858}.Release|Any CPU.Build.0 = Release|Any CPU 122 | {C88880FD-67E0-4A72-BD29-005A8291DF7B}.Debug_Cuda|Any CPU.ActiveCfg = Debug|Any CPU 123 | {C88880FD-67E0-4A72-BD29-005A8291DF7B}.Debug_Cuda|Any CPU.Build.0 = Debug|Any CPU 124 | {C88880FD-67E0-4A72-BD29-005A8291DF7B}.Debug_DirectML|Any CPU.ActiveCfg = Debug|Any CPU 125 | {C88880FD-67E0-4A72-BD29-005A8291DF7B}.Debug_DirectML|Any CPU.Build.0 = Debug|Any CPU 126 | {C88880FD-67E0-4A72-BD29-005A8291DF7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 127 | {C88880FD-67E0-4A72-BD29-005A8291DF7B}.Debug|Any CPU.Build.0 = Debug|Any CPU 128 | {C88880FD-67E0-4A72-BD29-005A8291DF7B}.Release_Cuda|Any CPU.ActiveCfg = Release|Any CPU 129 | {C88880FD-67E0-4A72-BD29-005A8291DF7B}.Release_Cuda|Any CPU.Build.0 = Release|Any CPU 130 | {C88880FD-67E0-4A72-BD29-005A8291DF7B}.Release_DirectML|Any CPU.ActiveCfg = Release|Any CPU 131 | {C88880FD-67E0-4A72-BD29-005A8291DF7B}.Release_DirectML|Any CPU.Build.0 = Release|Any CPU 132 | {C88880FD-67E0-4A72-BD29-005A8291DF7B}.Release|Any CPU.ActiveCfg = Release|Any CPU 133 | {C88880FD-67E0-4A72-BD29-005A8291DF7B}.Release|Any CPU.Build.0 = Release|Any CPU 134 | {F9835E50-8AB8-4307-A70E-6DD63142CF50}.Debug_Cuda|Any CPU.ActiveCfg = Debug|Any CPU 135 | {F9835E50-8AB8-4307-A70E-6DD63142CF50}.Debug_Cuda|Any CPU.Build.0 = Debug|Any CPU 136 | {F9835E50-8AB8-4307-A70E-6DD63142CF50}.Debug_DirectML|Any CPU.ActiveCfg = Debug|Any CPU 137 | {F9835E50-8AB8-4307-A70E-6DD63142CF50}.Debug_DirectML|Any CPU.Build.0 = Debug|Any CPU 138 | {F9835E50-8AB8-4307-A70E-6DD63142CF50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 139 | {F9835E50-8AB8-4307-A70E-6DD63142CF50}.Debug|Any CPU.Build.0 = Debug|Any CPU 140 | {F9835E50-8AB8-4307-A70E-6DD63142CF50}.Release_Cuda|Any CPU.ActiveCfg = Release|Any CPU 141 | {F9835E50-8AB8-4307-A70E-6DD63142CF50}.Release_Cuda|Any CPU.Build.0 = Release|Any CPU 142 | {F9835E50-8AB8-4307-A70E-6DD63142CF50}.Release_DirectML|Any CPU.ActiveCfg = Release|Any CPU 143 | {F9835E50-8AB8-4307-A70E-6DD63142CF50}.Release_DirectML|Any CPU.Build.0 = Release|Any CPU 144 | {F9835E50-8AB8-4307-A70E-6DD63142CF50}.Release|Any CPU.ActiveCfg = Release|Any CPU 145 | {F9835E50-8AB8-4307-A70E-6DD63142CF50}.Release|Any CPU.Build.0 = Release|Any CPU 146 | {84B45833-3D23-4095-ACDD-2C769A0E078C}.Debug_Cuda|Any CPU.ActiveCfg = Debug|Any CPU 147 | {84B45833-3D23-4095-ACDD-2C769A0E078C}.Debug_Cuda|Any CPU.Build.0 = Debug|Any CPU 148 | {84B45833-3D23-4095-ACDD-2C769A0E078C}.Debug_DirectML|Any CPU.ActiveCfg = Debug|Any CPU 149 | {84B45833-3D23-4095-ACDD-2C769A0E078C}.Debug_DirectML|Any CPU.Build.0 = Debug|Any CPU 150 | {84B45833-3D23-4095-ACDD-2C769A0E078C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 151 | {84B45833-3D23-4095-ACDD-2C769A0E078C}.Debug|Any CPU.Build.0 = Debug|Any CPU 152 | {84B45833-3D23-4095-ACDD-2C769A0E078C}.Release_Cuda|Any CPU.ActiveCfg = Release|Any CPU 153 | {84B45833-3D23-4095-ACDD-2C769A0E078C}.Release_Cuda|Any CPU.Build.0 = Release|Any CPU 154 | {84B45833-3D23-4095-ACDD-2C769A0E078C}.Release_DirectML|Any CPU.ActiveCfg = Release|Any CPU 155 | {84B45833-3D23-4095-ACDD-2C769A0E078C}.Release_DirectML|Any CPU.Build.0 = Release|Any CPU 156 | {84B45833-3D23-4095-ACDD-2C769A0E078C}.Release|Any CPU.ActiveCfg = Release|Any CPU 157 | {84B45833-3D23-4095-ACDD-2C769A0E078C}.Release|Any CPU.Build.0 = Release|Any CPU 158 | {046B5598-8DA6-4E49-BBC0-B88620E4CA48}.Debug_Cuda|Any CPU.ActiveCfg = Debug|Any CPU 159 | {046B5598-8DA6-4E49-BBC0-B88620E4CA48}.Debug_Cuda|Any CPU.Build.0 = Debug|Any CPU 160 | {046B5598-8DA6-4E49-BBC0-B88620E4CA48}.Debug_DirectML|Any CPU.ActiveCfg = Debug|Any CPU 161 | {046B5598-8DA6-4E49-BBC0-B88620E4CA48}.Debug_DirectML|Any CPU.Build.0 = Debug|Any CPU 162 | {046B5598-8DA6-4E49-BBC0-B88620E4CA48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 163 | {046B5598-8DA6-4E49-BBC0-B88620E4CA48}.Debug|Any CPU.Build.0 = Debug|Any CPU 164 | {046B5598-8DA6-4E49-BBC0-B88620E4CA48}.Release_Cuda|Any CPU.ActiveCfg = Release|Any CPU 165 | {046B5598-8DA6-4E49-BBC0-B88620E4CA48}.Release_Cuda|Any CPU.Build.0 = Release|Any CPU 166 | {046B5598-8DA6-4E49-BBC0-B88620E4CA48}.Release_DirectML|Any CPU.ActiveCfg = Release|Any CPU 167 | {046B5598-8DA6-4E49-BBC0-B88620E4CA48}.Release_DirectML|Any CPU.Build.0 = Release|Any CPU 168 | {046B5598-8DA6-4E49-BBC0-B88620E4CA48}.Release|Any CPU.ActiveCfg = Release|Any CPU 169 | {046B5598-8DA6-4E49-BBC0-B88620E4CA48}.Release|Any CPU.Build.0 = Release|Any CPU 170 | {813A9EBB-F3CF-434B-AAC6-3058CCF75632}.Debug_Cuda|Any CPU.ActiveCfg = Debug|Any CPU 171 | {813A9EBB-F3CF-434B-AAC6-3058CCF75632}.Debug_Cuda|Any CPU.Build.0 = Debug|Any CPU 172 | {813A9EBB-F3CF-434B-AAC6-3058CCF75632}.Debug_DirectML|Any CPU.ActiveCfg = Debug|Any CPU 173 | {813A9EBB-F3CF-434B-AAC6-3058CCF75632}.Debug_DirectML|Any CPU.Build.0 = Debug|Any CPU 174 | {813A9EBB-F3CF-434B-AAC6-3058CCF75632}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 175 | {813A9EBB-F3CF-434B-AAC6-3058CCF75632}.Debug|Any CPU.Build.0 = Debug|Any CPU 176 | {813A9EBB-F3CF-434B-AAC6-3058CCF75632}.Release_Cuda|Any CPU.ActiveCfg = Release|Any CPU 177 | {813A9EBB-F3CF-434B-AAC6-3058CCF75632}.Release_Cuda|Any CPU.Build.0 = Release|Any CPU 178 | {813A9EBB-F3CF-434B-AAC6-3058CCF75632}.Release_DirectML|Any CPU.ActiveCfg = Release|Any CPU 179 | {813A9EBB-F3CF-434B-AAC6-3058CCF75632}.Release_DirectML|Any CPU.Build.0 = Release|Any CPU 180 | {813A9EBB-F3CF-434B-AAC6-3058CCF75632}.Release|Any CPU.ActiveCfg = Release|Any CPU 181 | {813A9EBB-F3CF-434B-AAC6-3058CCF75632}.Release|Any CPU.Build.0 = Release|Any CPU 182 | {0E93E13A-4AC6-48EB-A146-474639B0F7A6}.Debug_Cuda|Any CPU.ActiveCfg = Debug|Any CPU 183 | {0E93E13A-4AC6-48EB-A146-474639B0F7A6}.Debug_Cuda|Any CPU.Build.0 = Debug|Any CPU 184 | {0E93E13A-4AC6-48EB-A146-474639B0F7A6}.Debug_DirectML|Any CPU.ActiveCfg = Debug|Any CPU 185 | {0E93E13A-4AC6-48EB-A146-474639B0F7A6}.Debug_DirectML|Any CPU.Build.0 = Debug|Any CPU 186 | {0E93E13A-4AC6-48EB-A146-474639B0F7A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 187 | {0E93E13A-4AC6-48EB-A146-474639B0F7A6}.Debug|Any CPU.Build.0 = Debug|Any CPU 188 | {0E93E13A-4AC6-48EB-A146-474639B0F7A6}.Release_Cuda|Any CPU.ActiveCfg = Release|Any CPU 189 | {0E93E13A-4AC6-48EB-A146-474639B0F7A6}.Release_Cuda|Any CPU.Build.0 = Release|Any CPU 190 | {0E93E13A-4AC6-48EB-A146-474639B0F7A6}.Release_DirectML|Any CPU.ActiveCfg = Release|Any CPU 191 | {0E93E13A-4AC6-48EB-A146-474639B0F7A6}.Release_DirectML|Any CPU.Build.0 = Release|Any CPU 192 | {0E93E13A-4AC6-48EB-A146-474639B0F7A6}.Release|Any CPU.ActiveCfg = Release|Any CPU 193 | {0E93E13A-4AC6-48EB-A146-474639B0F7A6}.Release|Any CPU.Build.0 = Release|Any CPU 194 | {BFEF19DC-15C0-4ADD-A672-4337F9A7B95C}.Debug_Cuda|Any CPU.ActiveCfg = Debug|Any CPU 195 | {BFEF19DC-15C0-4ADD-A672-4337F9A7B95C}.Debug_Cuda|Any CPU.Build.0 = Debug|Any CPU 196 | {BFEF19DC-15C0-4ADD-A672-4337F9A7B95C}.Debug_DirectML|Any CPU.ActiveCfg = Debug|Any CPU 197 | {BFEF19DC-15C0-4ADD-A672-4337F9A7B95C}.Debug_DirectML|Any CPU.Build.0 = Debug|Any CPU 198 | {BFEF19DC-15C0-4ADD-A672-4337F9A7B95C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 199 | {BFEF19DC-15C0-4ADD-A672-4337F9A7B95C}.Debug|Any CPU.Build.0 = Debug|Any CPU 200 | {BFEF19DC-15C0-4ADD-A672-4337F9A7B95C}.Release_Cuda|Any CPU.ActiveCfg = Release|Any CPU 201 | {BFEF19DC-15C0-4ADD-A672-4337F9A7B95C}.Release_Cuda|Any CPU.Build.0 = Release|Any CPU 202 | {BFEF19DC-15C0-4ADD-A672-4337F9A7B95C}.Release_DirectML|Any CPU.ActiveCfg = Release|Any CPU 203 | {BFEF19DC-15C0-4ADD-A672-4337F9A7B95C}.Release_DirectML|Any CPU.Build.0 = Release|Any CPU 204 | {BFEF19DC-15C0-4ADD-A672-4337F9A7B95C}.Release|Any CPU.ActiveCfg = Release|Any CPU 205 | {BFEF19DC-15C0-4ADD-A672-4337F9A7B95C}.Release|Any CPU.Build.0 = Release|Any CPU 206 | EndGlobalSection 207 | GlobalSection(SolutionProperties) = preSolution 208 | HideSolutionNode = FALSE 209 | EndGlobalSection 210 | GlobalSection(NestedProjects) = preSolution 211 | {22131B1B-1289-41DF-882F-A2E16A63BE9E} = {0BC576AC-FDE1-4DF8-BABD-668DBE6E7C9C} 212 | {1254AB34-B99A-4E4C-BD95-18BB22BF478E} = {255AD044-4A87-4975-B8EF-016F87277741} 213 | {4EB2FBF6-75D3-4B10-B5B5-675469C24780} = {0BC576AC-FDE1-4DF8-BABD-668DBE6E7C9C} 214 | {52D662CC-407B-42E6-8446-BEF969FFD30B} = {255AD044-4A87-4975-B8EF-016F87277741} 215 | {ED480C58-4355-4430-950B-1D85D3AE9891} = {0BC576AC-FDE1-4DF8-BABD-668DBE6E7C9C} 216 | {2C14C6E3-AF20-43CB-AECD-F6BBC2B2A858} = {255AD044-4A87-4975-B8EF-016F87277741} 217 | {C88880FD-67E0-4A72-BD29-005A8291DF7B} = {255AD044-4A87-4975-B8EF-016F87277741} 218 | {F9835E50-8AB8-4307-A70E-6DD63142CF50} = {EA6E5514-23BD-4B8B-A804-88AD5BF03E06} 219 | {84B45833-3D23-4095-ACDD-2C769A0E078C} = {EA6E5514-23BD-4B8B-A804-88AD5BF03E06} 220 | {046B5598-8DA6-4E49-BBC0-B88620E4CA48} = {57EDA879-FEC3-484B-B5A2-CC60B9BADE47} 221 | {813A9EBB-F3CF-434B-AAC6-3058CCF75632} = {57EDA879-FEC3-484B-B5A2-CC60B9BADE47} 222 | {0E93E13A-4AC6-48EB-A146-474639B0F7A6} = {0BC576AC-FDE1-4DF8-BABD-668DBE6E7C9C} 223 | {BFEF19DC-15C0-4ADD-A672-4337F9A7B95C} = {57EDA879-FEC3-484B-B5A2-CC60B9BADE47} 224 | EndGlobalSection 225 | GlobalSection(ExtensibilityGlobals) = postSolution 226 | SolutionGuid = {EAA25EC1-C5F2-40DC-8080-4DAF13311AEE} 227 | EndGlobalSection 228 | EndGlobal 229 | --------------------------------------------------------------------------------