Semantic Kernel 通过 LocalAI 集成本地模型
本文是基于 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
参考文章:
- Docker部署LocalAI 实现本地私有化 文本转语音(TTS) 语音转文本 GPT功能 | Mr.Pu 个站博客 (putianhui.cn)
- LocalAI 自托管、社区驱动的本地 OpenAI API 兼容替代方案
Semantic Kernel 通过 LocalAI 集成本地模型的更多相关文章
- Semantic Kernel 知多少 | 开启面向AI编程新篇章
引言 在ChatGPT 火热的当下, 即使没有上手亲自体验,想必也对ChatGPT的强大略有耳闻.当一些人在对ChatGPT犹犹豫豫之时,一些敏锐的企业主和开发者们已经急不可耐的开展基于ChatGPT ...
- Semantic Kernel 入门系列:💬Semantic Function
如果把提示词也算作一种代码的话,那么语义技能所带来的将会是全新编程方式,自然语言编程. 通常情况下一段prompt就可以构成一个Semantic Function,如此这般简单,如果我们提前可以组织好 ...
- LangChain vs Semantic Kernel
每当向他人介绍 Semantic Kernel, 会得到的第一个问题就是 Semantic Kernel 类似于LangChain吗,或者是c# 版本的LangChain吗? 为了全面而不想重复的回答 ...
- Semantic Kernel 入门系列:🛸LLM降临的时代
不论你是否关心,不可否认,AGI的时代即将到来了. 在这个突如其来的时代中,OpenAI的ChatGPT无疑处于浪潮之巅.而在ChatGPT背后,我们不能忽视的是LLM(Large Language ...
- Semantic Kernel 入门系列:🔥Kernel 内核和🧂Skills 技能
理解了LLM的作用之后,如何才能构造出与LLM相结合的应用程序呢? 首先我们需要把LLM AI的能力和原生代码的能力区分开来,在Semantic Kernel(以下简称SK),LLM的能力称为 sem ...
- Semantic Kernel 入门系列:🥑突破提示词的限制
无尽的上下文 LLM的语言理解和掌握能力在知识内容的解读和总结方面提供了强大的能力. 但是由于训练数据本身来自于公共领域,也就注定了无法在一些小众或者私有的领域能够足够的好的应答. 因此如何给LLM ...
- Semantic Kernel 入门系列:🥑Memory内存
了解的运作原理之后,就可以开始使用Semantic Kernel来制作应用了. Semantic Kernel将embedding的功能封装到了Memory中,用来存储上下文信息,就好像电脑的内存一样 ...
- Linux Kernel ‘/net/socket.c’本地信息泄露漏洞
漏洞名称: Linux Kernel ‘/net/socket.c’本地信息泄露漏洞 CNNVD编号: CNNVD-201312-037 发布时间: 2013-12-04 更新时间: 2013-12- ...
- Linux Kernel ‘/bcm/Bcmchar.c’本地信息泄露漏洞
漏洞名称: Linux Kernel ‘/bcm/Bcmchar.c’本地信息泄露漏洞 CNNVD编号: CNNVD-201311-053 发布时间: 2013-11-06 更新时间: 2013-11 ...
- 机器学习之路:python 集成回归模型 随机森林回归RandomForestRegressor 极端随机森林回归ExtraTreesRegressor GradientBoostingRegressor回归 预测波士顿房价
python3 学习机器学习api 使用了三种集成回归模型 git: https://github.com/linyi0604/MachineLearning 代码: from sklearn.dat ...
随机推荐
- DevCloud加持下的青软,让教育“智”上云端
摘要:构建多体系人才云实践环境,提供企业所需人才培养平台,构建以学习为中心的全新教育生态. 本文分享自华为云社区<[云享·伙伴]第5期:华为云DevCloud加持下的青软,让教育"智& ...
- DarkMode(4):css滤镜 颜色反转实现深色模式
在<DarkMode(1):产品应用深色模式分析>提过,单纯反转是不行的.但是,把不需要反转的,在反转过来.或者用js,给想要反转的,加上反转样式,再对其他的做微调.这样个人觉得,开发成本 ...
- 一文读懂火山引擎A/B测试的实验类型(1)——编程实验
一. 概述 编程实验:指的是通过代码编程进行AB实验,广泛使用于前端优化.策略优化和后端算法优化多种实验场景,包含客户端和服务端实验. 前置条件:接入客户端SDK或者服务端SDK,详见:应用接入 二. ...
- Vue2--入门学习
看了慕课网的教学视频,觉得挺不错的,在此做个随堂记录,有兴趣的可以去看视频 vue版本:2.5 文档链接:https://v2.cn.vuejs.org/v2/guide/installation.h ...
- Java基础知识整理,驼峰规则、流程控制、自增自减
写在开头 本文接着上一篇文章续写哈.[Java基础知识整理,注释.关键字.运算符](https://blog.csdn.net/qq_43506040/article/details/13563332 ...
- JSP | IDEA中部署tomcat,运行JSP文件,编译后的JSP文件存放地点总结
首先保证你正常部署了Tomcat,并且正常在浏览器中运行了JSP文件. 参考博客:Here 那么Tomcat编译后的JSP文件(_jsp.class 和 _jsp.java)的存放地点: (一)一般存 ...
- asp.net 程序员常用工具
1 写作工具: Typora 2. 远程工具 ToDesk 3. 思维整理工具 XimindZen 4. 数据库客户端工具 Navicat Premium 15 5. 录音工具 楼月免费MP3录音软 ...
- 通过设置 Chrome 解决开发调用跨域问题
转载请注明出处: 项目采用的是前后端分离的方式,前端本地访问方式是 localhost:8080,访问本地后台服务时,通过 localhost:9000 进行访问 本地后端服务.在本地通过chrome ...
- 云计算&虚拟化 技术名词汇总
云计算&虚拟化 技术名词汇总 目录 云计算&虚拟化 技术名词汇总 虚拟化方向 QEMU/qemu VMM virtual machine monitor (虚拟机监管器) Hyperv ...
- 【Hash】字符串哈希
Hash 的核心思想在于,将输入映射到一个值域较小.可以方便比较的范围,典型的用法就是将资源紧张的设备中的不定长字符串转化为定长整数,以达到节省空间的目的 如:printf("This is ...