Using a text embedding model locally with semantic kernel

题意:在本地使用带有语义核(Semantic Kernel)的文本嵌入模型

问题背景:

I've been reading Stephen Toub's blog post about building a simple console-based .NET chat application from the ground up with semantic-kernel. I'm following the examples but instead of OpenAI I want to use microsoft Phi 3 and the nomic embedding model. The first examples in the blog post I could recreate using the semantic kernel huggingface plugin. But I can't seem to run the text embedding example.

我一直在阅读Stephen Toub的博客文章,文章讲述了如何使用语义核(semantic-kernel)从头开始构建一个基于控制台的简单.NET聊天应用程序。我按照示例操作,但我想使用微软的Phi 3和nomic嵌入模型,而不是OpenAI。我能够使用语义核的huggingface插件重现博客文章中的第一个示例。但是,我似乎无法运行文本嵌入的示例。

I've downloaded Phi and nomic embed text and are running them on a local server with lm studio.

我已经下载了Phi和nomic嵌入文本模型,并正在使用lm studio在本地服务器上运行它们。

Here's the code I came up with that uses the huggingface plugin:

这里是我编写的使用huggingface插件的代码

using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Embeddings;
using Microsoft.SemanticKernel.Memory;
using System.Numerics.Tensors;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel.ChatCompletion;

#pragma warning disable SKEXP0070, SKEXP0003, SKEXP0001, SKEXP0011, SKEXP0052, SKEXP0055, SKEXP0050  // Type is for evaluation purposes only and is subject to change or removal in future updates. 

internal class Program
{
    private static async Task Main(string[] args)
    {
        //Suppress this diagnostic to proceed.
        // Initialize the Semantic kernel
        IKernelBuilder kernelBuilder = Kernel.CreateBuilder();
        kernelBuilder.Services.ConfigureHttpClientDefaults(c => c.AddStandardResilienceHandler());
        var kernel = kernelBuilder
            .AddHuggingFaceTextEmbeddingGeneration("nomic-ai/nomic-embed-text-v1.5-GGUF/nomic-embed-text-v1.5.Q8_0.gguf",
            new Uri("http://localhost:1234/v1"),
            apiKey: "lm-studio",
            serviceId: null)
            .Build();

        var embeddingGenerator = kernel.GetRequiredService<ITextEmbeddingGenerationService>();
        var memoryBuilder = new MemoryBuilder();
        memoryBuilder.WithTextEmbeddingGeneration(embeddingGenerator);
        memoryBuilder.WithMemoryStore(new VolatileMemoryStore());
        var memory = memoryBuilder.Build();
        // Download a document and create embeddings for it
        string input = "What is an amphibian?";
        string[] examples = [ "What is an amphibian?",
                              "Cos'è un anfibio?",
                              "A frog is an amphibian.",
                              "Frogs, toads, and salamanders are all examples.",
                              "Amphibians are four-limbed and ectothermic vertebrates of the class Amphibia.",
                              "They are four-limbed and ectothermic vertebrates.",
                              "A frog is green.",
                              "A tree is green.",
                              "It's not easy bein' green.",
                              "A dog is a mammal.",
                              "A dog is a man's best friend.",
                              "You ain't never had a friend like me.",
                              "Rachel, Monica, Phoebe, Joey, Chandler, Ross"];
        for (int i = 0; i < examples.Length; i++)
            await memory.SaveInformationAsync("net7perf", examples[i], $"paragraph{i}");
        var embed = await embeddingGenerator.GenerateEmbeddingsAsync([input]);
        ReadOnlyMemory<float> inputEmbedding = (embed)[0];
        // Generate embeddings for each chunk.
        IList<ReadOnlyMemory<float>> embeddings = await embeddingGenerator.GenerateEmbeddingsAsync(examples);
        // Print the cosine similarity between the input and each example
        float[] similarity = embeddings.Select(e => TensorPrimitives.CosineSimilarity(e.Span, inputEmbedding.Span)).ToArray();
        similarity.AsSpan().Sort(examples.AsSpan(), (f1, f2) => f2.CompareTo(f1));
        Console.WriteLine("Similarity Example");
        for (int i = 0; i < similarity.Length; i++)
            Console.WriteLine($"{similarity[i]:F6}   {examples[i]}");
    }
}

At the line:   这部分代码存在问题

for (int i = 0; i < examples.Length; i++)
    await memory.SaveInformationAsync("net7perf", examples[i], $"paragraph{i}");

I get the following exception:        得到了下面的异常信息

JsonException: The JSON value could not be converted to Microsoft.SemanticKernel.Connectors.HuggingFace.Core.TextEmbeddingResponse

Does anybody know what I'm doing wrong?        有人知道我错在哪里吗?

I've downloaded the following nuget packages into the project:

我已经将以下NuGet包下载到项目中:

Id Versions ProjectName
Microsoft.SemanticKernel.Core {1.15.0} LocalLlmApp
Microsoft.SemanticKernel.Plugins.Memory {1.15.0-alpha} LocalLlmApp
Microsoft.Extensions.Http.Resilience {8.6.0} LocalLlmApp
Microsoft.Extensions.Logging {8.0.0} LocalLlmApp
Microsoft.SemanticKernel.Connectors.HuggingFace {1.15.0-preview} LocalLlmApp
Newtonsoft.Json {13.0.3} LocalLlmApp
Microsoft.Extensions.Logging.Console {8.0.0} LocalLlmApp

问题解决:

I think you cannot use AddHuggingFaceTextEmbeddingGeneration with an embedding model from LM Studio out of the box. The reason is that the HuggingFaceClient internally changes the url and adds:

我认为你不能直接使用AddHuggingFaceTextEmbeddingGeneration与LM Studio中的嵌入模型,因为HuggingFaceClient内部会更改URL并添加:

pipeline/feature-extraction/

private Uri GetEmbeddingGenerationEndpoint(string modelId)
     => new($"{this.Endpoint}{this.Separator}pipeline/feature-extraction/{modelId}");

that's the same as the Error Message I get in the LM Studio Console:

这与我在LM Studio控制台中收到的错误信息相同:

[2024-07-03 22:18:19.898] [ERROR] Unexpected endpoint or method. (POST /v1/embedding/pipeline/feature-extraction/nomic-ai/nomic-embed-text-v1.5-GGUF/nomic-embed-text-v1.5.Q5_K_M.gguf). Returning 200 anyway

In order to get this working the url would have to be changed.

为了使这个工作正常进行,URL必须被更改。

相关推荐

最近更新

  1. 交换机(Switches)和桥(Bridges)的区别

    2024-07-09 18:06:07       0 阅读
  2. 测试面试宝典(二十一)—— get和post的区别

    2024-07-09 18:06:07       0 阅读
  3. ESP8266AT指令查看有哪些指令可用(3)

    2024-07-09 18:06:07       0 阅读

热门阅读

  1. django学习入门系列之第四点《案例 登录》

    2024-07-09 18:06:07       13 阅读
  2. Rust破界:前端革新与Vite重构的深度透视(中)

    2024-07-09 18:06:07       8 阅读
  3. uniapp中微信小程序——蓝牙连接并通信

    2024-07-09 18:06:07       9 阅读
  4. 被裁了(9年)

    2024-07-09 18:06:07       8 阅读
  5. 3D 可视化大数据

    2024-07-09 18:06:07       10 阅读
  6. 部署LVS-DR群集

    2024-07-09 18:06:07       6 阅读
  7. Vue项目使用mockjs模拟后端接口

    2024-07-09 18:06:07       8 阅读
  8. python的魔法方法

    2024-07-09 18:06:07       9 阅读