本文是基于 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。

可参考官方 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行代码所示,运行起来就可以体验下列的效果:

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

参考文章:

Semantic Kernel 通过 LocalAI 集成本地模型的更多相关文章

  1. Semantic Kernel 知多少 | 开启面向AI编程新篇章

    引言 在ChatGPT 火热的当下, 即使没有上手亲自体验,想必也对ChatGPT的强大略有耳闻.当一些人在对ChatGPT犹犹豫豫之时,一些敏锐的企业主和开发者们已经急不可耐的开展基于ChatGPT ...

  2. Semantic Kernel 入门系列:💬Semantic Function

    如果把提示词也算作一种代码的话,那么语义技能所带来的将会是全新编程方式,自然语言编程. 通常情况下一段prompt就可以构成一个Semantic Function,如此这般简单,如果我们提前可以组织好 ...

  3. LangChain vs Semantic Kernel

    每当向他人介绍 Semantic Kernel, 会得到的第一个问题就是 Semantic Kernel 类似于LangChain吗,或者是c# 版本的LangChain吗? 为了全面而不想重复的回答 ...

  4. Semantic Kernel 入门系列:🛸LLM降临的时代

    不论你是否关心,不可否认,AGI的时代即将到来了. 在这个突如其来的时代中,OpenAI的ChatGPT无疑处于浪潮之巅.而在ChatGPT背后,我们不能忽视的是LLM(Large Language ...

  5. Semantic Kernel 入门系列:🔥Kernel 内核和🧂Skills 技能

    理解了LLM的作用之后,如何才能构造出与LLM相结合的应用程序呢? 首先我们需要把LLM AI的能力和原生代码的能力区分开来,在Semantic Kernel(以下简称SK),LLM的能力称为 sem ...

  6. Semantic Kernel 入门系列:🥑突破提示词的限制

    无尽的上下文 LLM的语言理解和掌握能力在知识内容的解读和总结方面提供了强大的能力. 但是由于训练数据本身来自于公共领域,也就注定了无法在一些小众或者私有的领域能够足够的好的应答. 因此如何给LLM ...

  7. Semantic Kernel 入门系列:🥑Memory内存

    了解的运作原理之后,就可以开始使用Semantic Kernel来制作应用了. Semantic Kernel将embedding的功能封装到了Memory中,用来存储上下文信息,就好像电脑的内存一样 ...

  8. Linux Kernel ‘/net/socket.c’本地信息泄露漏洞

    漏洞名称: Linux Kernel ‘/net/socket.c’本地信息泄露漏洞 CNNVD编号: CNNVD-201312-037 发布时间: 2013-12-04 更新时间: 2013-12- ...

  9. Linux Kernel ‘/bcm/Bcmchar.c’本地信息泄露漏洞

    漏洞名称: Linux Kernel ‘/bcm/Bcmchar.c’本地信息泄露漏洞 CNNVD编号: CNNVD-201311-053 发布时间: 2013-11-06 更新时间: 2013-11 ...

  10. 机器学习之路:python 集成回归模型 随机森林回归RandomForestRegressor 极端随机森林回归ExtraTreesRegressor GradientBoostingRegressor回归 预测波士顿房价

    python3 学习机器学习api 使用了三种集成回归模型 git: https://github.com/linyi0604/MachineLearning 代码: from sklearn.dat ...

随机推荐

  1. 提升80%上云集成效率, TA是如何做到的

    摘要:基于华为云开天aPaaS,提升80%上云集成效率,降低50%集成成本 没有充足资金,没有足够的项目规划和过渡时间,也没有经验丰富的IT团队支持,中小企业的上云路可谓是困难重重.如何帮助企业高效上 ...

  2. 火山引擎 DataTester 应用故事:一个 A/B 测试,将产品 DAU 提升了数十万

      更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 疫情让线下的需求大量转移到线上,催生出了远程办公.网络授课.线上健身等新的生态现象.如何更好地为用户服务,提升 ...

  3. 火山引擎 DataLeap 下 Notebook 系列文章二:技术路线解析

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 在 Jupyter 的生态下,除了 Notebook 本身,火山引擎 DataLeap 研发团队还注意到了很多其他 ...

  4. Hadoop面试题总结(二)——HDFS

    1. HDFS 中的 block 默认保存几份? 默认保存3份 2.HDFS 默认 BlockSize 是多大? 默认64MB 3.负责HDFS数据存储的是哪一部分? DataNode负责数据存储 4 ...

  5. auth认证模块 auth_user表扩展

    目录 auth认证模块前戏 django后台管理功能 创建超级管理员 auth认证相关模块及操作 用户注册 用户登录 网站首页效果 校验用户登录的装饰器 用户修改密码 用户注销登录 auth_user ...

  6. anaconda学习(未完成)

    1.Anaconda安装教程(以32.7.4为例)官网地址:https://www.anaconda.com/download(如无法下载可跳转清华源下载)下载完成后点击打开即可安装点击Next选择I ...

  7. OOALV 分割屏幕

    1功能说明 需要开发一个报表,分为上下两个部分,下边需要再分割为左右两个部分,点击上边部分的行,下边两个报表信息发生变化. 效果如下: 2代码实现 1.数据查询 分别查询MARA.MARC.MAKT三 ...

  8. Java解析上传的zip文件--包含Excel解析与图片上传

    Java解析上传的zip文件--包含Excel解析与图片上传 前言:今天遇到一个需求:上传一个zip格式的压缩文件,该zip中包含人员信息的excel以及excel中每行对应的人的图片,现在需要将该z ...

  9. 你真的了解MySQL日期函数吗?

    MySQL提供了丰富的日期和时间函数,用于处理和操作日期时间数据.本篇博文将深入介绍一些常用的MySQL日期函数,通过详细的例子带你了解这些函数的用法和实际应用. 1. CURDATE() - 获取当 ...

  10. window对象的常见事件

    2.1 窗口加载事件 window.onload = function() { } 或者 window.addEventListener("load", function(){}) ...