首页 > 其他分享 >Semantic Kernel 通过 LocalAI 集成本地模型

Semantic Kernel 通过 LocalAI 集成本地模型

时间:2024-01-25 20:12:01浏览次数:27  
标签:Kernel Semantic kernelSettings LocalAI OpenAI new content kernelBuilder

本文是基于 LLama 2是由Meta 开源的大语言模型,通过LocalAI 来集成LLama2 来演示Semantic kernel(简称SK) 和 本地大模型的集成示例。
SK 可以支持各种大模型,在官方示例中多是OpenAI 和 Azure OpenAI service 的GPT 3.5+。今天我们就来看一看如何把SK 和 本地部署的开源大模型集成起来。我们使用MIT协议的开源项目“LocalAI“:https://github.com/go-skynet/LocalAI
LocalAI 是一个本地推理框架,提供了 RESTFul API,与 OpenAI API 规范兼容。它允许你在消费级硬件上本地或者在自有服务器上运行 LLM(和其他模型),支持与 ggml 格式兼容的多种模型家族。不需要 GPU。LocalAI 使用 C++ 绑定来优化速度。 它基于用于音频转录的 llama.cpp、gpt4all、rwkv.cpp、ggml、whisper.cpp 和用于嵌入的 bert.cpp。

 image


可参考官方 Getting Started 进行部署,通过LocalAI我们将本地部署的大模型转换为OpenAI的格式,通过SK 的OpenAI 的Connector 访问,这里需要做的是把openai的Endpoint 指向 LocalAI,这个我们可以通过一个自定义的HttpClient来完成这项工作,例如下面的这个示例:

internal class OpenAIHttpclientHandler : HttpClientHandler

{

    private  KernelSettings _kernelSettings;

    public OpenAIHttpclientHandler(KernelSettings settings)

    {

        this._kernelSettings = settings;

    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

    {

        if (request.RequestUri.LocalPath == "/v1/chat/completions")

        {

            UriBuilder uriBuilder = new UriBuilder(request.RequestUri)

            {

                Scheme = this._kernelSettings.Scheme,

                Host = this._kernelSettings.Host,

                Port = this._kernelSettings.Port

            };

            request.RequestUri = uriBuilder.Uri;

        }

        return await base.SendAsync(request, cancellationToken);

    }

}

上面我们做好了所有的准备工作,接下来就是要把所有的组件组装起来,让它们协同工作。因此打开Visual studio code 创建一个c# 项目sk-csharp-hello-world,其中Program.cs 内容如下:

using System.Reflection;

using config;

using Microsoft.Extensions.DependencyInjection;

using Microsoft.Extensions.Logging;

using Microsoft.SemanticKernel;

using Microsoft.SemanticKernel.ChatCompletion;

using Microsoft.SemanticKernel.Connectors.OpenAI;

using Microsoft.SemanticKernel.PromptTemplates.Handlebars;

using Plugins;

var kernelSettings = KernelSettings.LoadSettings();

var handler = new OpenAIHttpclientHandler(kernelSettings);

IKernelBuilder builder = Kernel.CreateBuilder();

builder.Services.AddLogging(c => c.SetMinimumLevel(LogLevel.Information).AddDebug());

builder.AddChatCompletionService(kernelSettings,handler);

builder.Plugins.AddFromType<LightPlugin>();

Kernel kernel = builder.Build();

// Load prompt from resource

using StreamReader reader = new(Assembly.GetExecutingAssembly().GetManifestResourceStream("prompts.Chat.yaml")!);

KernelFunction prompt = kernel.CreateFunctionFromPromptYaml(

    reader.ReadToEnd(),

    promptTemplateFactory: new HandlebarsPromptTemplateFactory()

);

// Create the chat history

ChatHistory chatMessages = [];

// Loop till we are cancelled

while (true)

{

    // Get user input

    System.Console.Write("User > ");

    chatMessages.AddUserMessage(Console.ReadLine()!);

    // Get the chat completions

    OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()

    {

    };

    var result = kernel.InvokeStreamingAsync<StreamingChatMessageContent>(

        prompt,

        arguments: new KernelArguments(openAIPromptExecutionSettings) {

            { "messages", chatMessages }

        });

    // Print the chat completions

    ChatMessageContent? chatMessageContent = null;

    await foreach (var content in result)

    {

        System.Console.Write(content);

        if (chatMessageContent == null)

        {

            System.Console.Write("Assistant > ");

            chatMessageContent = new ChatMessageContent(

                content.Role ?? AuthorRole.Assistant,

                content.ModelId!,

                content.Content!,

                content.InnerContent,

                content.Encoding,

                content.Metadata);

        }

        else

        {

            chatMessageContent.Content += content;

        }

    }

    System.Console.WriteLine();

    chatMessages.Add(chatMessageContent!);

}

首先,我们做的第一件事是导入一堆必要的命名空间,使一切正常(第 1 行到第 9 行)。

然后,我们创建一个内核构建器的实例(通过模式,而不是因为它是构造函数),这将有助于塑造我们的内核。

IKernelBuilder builder = Kernel.CreateBuilder();

你需要知道每时每刻都在发生什么吗?答案是肯定的!让我们在内核中添加一个日志。我们在第14行添加了日志的支持。

我们想使用Azure,OpenAI中使用Microsoft的AI模型,以及我们LocalAI 集成的本地大模型,我们可以将它们包含在我们的内核中。正如我们在15行看到的那样:

internal static class ServiceCollectionExtensions
{
     /// <summary>
     /// Adds a chat completion service to the list. It can be either an OpenAI or Azure OpenAI backend service.
     /// </summary>
     /// <param name="kernelBuilder"></param>
     /// <param name="kernelSettings"></param>
     /// <exception cref="ArgumentException"></exception>
     internal static IKernelBuilder AddChatCompletionService(this IKernelBuilder kernelBuilder, KernelSettings kernelSettings, HttpClientHandler handler)
     {
       
         switch (kernelSettings.ServiceType.ToUpperInvariant())
         {
             case ServiceTypes.AzureOpenAI:
                 kernelBuilder = kernelBuilder.AddAzureOpenAIChatCompletion(kernelSettings.DeploymentId,  endpoint: kernelSettings.Endpoint, apiKey: kernelSettings.ApiKey, serviceId: kernelSettings.ServiceId, kernelSettings.ModelId);
                 break;

            case ServiceTypes.OpenAI:
                 kernelBuilder = kernelBuilder.AddOpenAIChatCompletion(modelId: kernelSettings.ModelId, apiKey: kernelSettings.ApiKey, orgId: kernelSettings.OrgId, serviceId: kernelSettings.ServiceId);
                 break;

            case ServiceTypes.HunyuanAI:               
                 kernelBuilder = kernelBuilder.AddOpenAIChatCompletion(modelId: kernelSettings.ModelId, apiKey: kernelSettings.ApiKey, httpClient: new HttpClient(handler));
                 break;
             case ServiceTypes.LocalAI:
                 kernelBuilder = kernelBuilder.AddOpenAIChatCompletion(modelId: kernelSettings.ModelId, apiKey: kernelSettings.ApiKey, httpClient: new HttpClient(handler));
                 break;
             default:
                 throw new ArgumentException($"Invalid service type value: {kernelSettings.ServiceType}");
         }

        return kernelBuilder;
     }
}

接下来开启一个聊天循环,使用SK的流式传输 InvokeStreamingAsync,如第42行到46行代码所示,运行起来就可以体验下列的效果:

image

本文示例源代码:https://github.com/geffzhang/sk-csharp-hello-world


参考文章:

标签:Kernel,Semantic,kernelSettings,LocalAI,OpenAI,new,content,kernelBuilder
From: https://www.cnblogs.com/shanyou/p/17988059

相关文章

  • Understanding the linux kernel Chapter3 Processes
    ProcessDescriptorHowProcessesAreOrganizedtheprocessinstate:TASK_RUNNINGorganizedinrunqueuelistgroupTASK_STROPPED\EXIT_ZOMBIE\EXIT_DEADThereisnoneedtogroupprocessesinanyofthesethreestates,becausestopped,zombie,andd......
  • Linux修复kernel时钟异常的问题
    发现与ntp服务器同步后,间隔10秒再同步,系统时间与ntp服务器已经相差0.6秒,因此怀疑系统时钟被修改了使用adjtimex调整sudoaptinstalladjtimex对比当前系统时钟sudoadjtimex--compareWARNING:CMOStimeis53.38minbehindsystemclock---current-----suggeste......
  • Google的Jax框架的JAX-Triton目前只能成功运行在TPU设备上(使用Pallas为jax编写kernel
    使用Pallas为jax编写kernel扩展,需要使用JAX-Triton扩展包。由于Google的深度学习框架Jax主要是面向自己的TPU进行开发的,虽然也同时支持NVIDIA的GPU,但是支持力度有限,目前JAX-Triton只能在TPU设备上正常运行,无法保证在GPU上正常运行。该结果使用kaggle上的TPU和GPU进行测试获得。......
  • 基于融合语义信息改进的内容推荐算法。Improved content recommendation algorithm in
    引言路漫漫其修远兮,吾将上下而求索。每天一篇论文,做更好的自己。本文读的这篇论文为发表于2023年5月28日的一篇名为《基于融合语义信息改进的内容推荐算法》(基于融合语义信息改进的内容推荐算法)的文章,文章主要介绍了基于内容的推荐技术在电子商务和教育领域的广泛应用,以及传统基......
  • 通过 KernelUtil.dll 劫持 QQ / TIM 客户端 QQClientkey / QQKey 详细教程(附源码)
    前言由于QQ9.7.20版本后已经不能通过模拟网页快捷登录来截取QQClientkey/QQKey,估计是针对访问的程序做了限制,然而经过多方面测试,诸多的地区、环境、机器也针对这种获取方法做了相应的措施,导致模拟网页快捷登录来截取数据被彻底的和谐,为了解决这个问题我们只能更改思路对......
  • Kernel Memory 入门系列:Semantic Kernel 插件
    KernelMemory入门系列:SemanticKernel插件KernelMemory本身提供了完整的RAG能力,这部分能力如果通过SemanticKernelMemory的话,也是可以实现的,但是整体的管理成本会比较高。因此通过KernelMemory构建知识库管理,然后通过插件的方式,将KernelMemory接入到SemanticKernel......
  • lk uboot传参到Kernel
    记录一下内核和uboot的传参MTK传参 1.在app/mt_boot/mt_boot.c使用cmdline_append(buf); snprintf(buf,10,"vcom=%s",vcom_str);pal_log_err("%s\n",buf);cmdline_append(buf); 2.在kernel中读取br_ptr=strstr(saved_command_line,"vcom="......
  • Kernel Memory 入门系列:生成并获取文档摘要
    KernelMemory入门系列:生成并获取文档摘要前面在RAG和文档预处理的流程中,我们得到一个解决方案,可以让用户直接获取最终的问题答案。但是实际的业务场景中,仍然存在一些基础的场景,不需要我们获取文档的所有详情的,而只是了解的文档的大概信息,得到文章整体的摘要或者总结,此时仍然可......
  • Semantic Kernel 正式发布 v1.0.1 版本
    微软在2023年12月19日在博客上(SayhellotoSemanticKernelV1.0.1)发布了Semantickernel的.NET正式1.0.1版本。新版本提供了新的文档,以解释SDK创建AI代理的能力,这些代理可以与用户交互、回答问题、调用现有代码、自动化流程和执行各种其他任务。SemanticKernel是一个开源......
  • Kernel Memory 入门系列: Embedding 简介
    KernelMemory入门系列:Embedding简介在RAG模式其实留了一个问题。我们对于的用户问题的理解和文档的检索并没有提供合适的方法。当然我们可以通过相对比较传统的方法。例如对用户的问题进行关键词提取,然后通过关键词检索文档。这样的话,就需要我们提前对文档做好相关关键......