SemanticKernel/C#:使用Ollama中的对话模型与嵌入模型用于本地离线场景
前言
上一篇文章介绍了使用SemanticKernel/C#的RAG简易实践,在上篇文章中我使用的是兼容OpenAI格式的在线API,但实际上会有很多本地离线的场景。今天跟大家介绍一下在SemanticKernel/C#中如何使用Ollama中的对话模型与嵌入模型用于本地离线场景。
开始实践
本文使用的对话模型是gemma2:2b,嵌入模型是all-minilm:latest,可以先在Ollama中下载好。

2024年2月8号,Ollama中的兼容了OpenAI Chat Completions API,具体见https://ollama.com/blog/openai-compatibility。
因此在SemanticKernel/C#中使用Ollama中的对话模型就比较简单了。
var kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(modelId: "gemma2:2b", apiKey: null, endpoint: new Uri("http://localhost:11434")).Build();
这样构建kernel即可。
简单尝试一下效果:
public async Task<string> Praise()
{
var skPrompt = """
你是一个夸人的专家,回复一句话夸人。
你的回复应该是一句话,不要太长,也不要太短。
""";
var result = await _kernel.InvokePromptAsync(skPrompt);
var str = result.ToString();
return str;
}

就这样设置就成功在SemanticKernel中使用Ollama的对话模型了。
现在来看看嵌入模型,由于Ollama并没有兼容OpenAI的格式,所以直接用是不行的。
Ollama的格式是这样的:

OpenAI的请求格式是这样的:
curl https://api.openai.com/v1/embeddings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"input": "Your text string goes here",
"model": "text-embedding-3-small"
}'
OpenAI的返回格式是这样的:
{
"object": "list",
"data": [
{
"object": "embedding",
"index": 0,
"embedding": [
-0.006929283495992422,
-0.005336422007530928,
... (omitted for spacing)
-4.547132266452536e-05,
-0.024047505110502243
],
}
],
"model": "text-embedding-3-small",
"usage": {
"prompt_tokens": 5,
"total_tokens": 5
}
}
因此通过请求转发的方式是不行的。
之前也有人在ollama的issue提了这个问题:

似乎也有准备实现嵌入接口的兼容:

目前试了一下还没有兼容。
在SemanticKernel中需要自己实现一些接口来使用Ollama的嵌入模型,但是经过搜索,我发现已经有大佬做了这个事,github地址:https://github.com/BLaZeKiLL/Codeblaze.SemanticKernel。
大佬实现了ChatCompletion、EmbeddingGeneration与TextGenerationService,如果你只使用到EmbeddingGeneration可以看大佬的代码,在项目里自己添加一些类,来减少项目中的包。
这里为了方便,直接安装大佬的包:

构建ISemanticTextMemory:
public async Task<ISemanticTextMemory> GetTextMemory3()
{
var builder = new MemoryBuilder();
var embeddingEndpoint = "http://localhost:11434";
var cancellationTokenSource = new System.Threading.CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;
builder.WithHttpClient(new HttpClient());
builder.WithOllamaTextEmbeddingGeneration("all-minilm:latest", embeddingEndpoint);
IMemoryStore memoryStore = await SqliteMemoryStore.ConnectAsync("memstore.db");
builder.WithMemoryStore(memoryStore);
var textMemory = builder.Build();
return textMemory;
}
现在开始试试效果,基于昨天的分享做改进,今天上传一个txt文档。
一个私有文档如下所示,隐私信息已替换:
各位同学:
你好,为了帮助大家平安、顺利地度过美好的大学时光,学校专门引进“互联网+”高校安全教育服务平台,可通过手机端随时随地学习安全知识的网络微课程。大学生活多姿多彩,牢固掌握安全知识,全面提升安全技能和素质。请同学们务必在规定的学习时间完成该课程的学习与考试。
请按如下方式自主完成学习和考试:
1、手机端学习平台入口:请关注微信公众号“XX大学”或扫描下方二维码,进入后点击公众号菜单栏【学术导航】→【XX微课】,输入账号(学号)、密码(学号),点【登录】后即可绑定信息,进入学习平台。
2、网页端学习平台入口:打开浏览器,登录www.xxx.cn,成功进入平台后,即可进行安全知识的学习。
3、平台开放时间:2024年4月1日—2024年4月30日,必须完成所有的课程学习后才能进行考试,试题共计50道,满分为100分,80分合格,有3次考试机会,最终成绩取最优分值。
4、答疑qq群号:123123123。
学习平台登录流程
1. 手机端学习平台入口:
请扫描下方二维码,关注微信公众号“XX大学”;
公众号菜单栏【学术导航】→【XX微课】,选择学校名称,输入账号(学号)、密码(学号),点【登录】后即可绑定信息,进入学习平台;
遇到问题请点【在线课服】或【常见问题】,进行咨询(咨询时间:周一至周日8:30-17:00)。
2. 网页端学习平台入口:
打开浏览器,登录www.xxx.cn,成功进入平台后,即可进行安全知识的学习。
3. 安全微课学习、考试
1) 微课学习
点击首页【学习任务中】的【2024年春季安全教育】,进入课程学习;
展开微课列表,点击微课便可开始学习;
大部分微课是点击继续学习,个别微课是向上或向左滑动学习;
微课学习完成后会有“恭喜,您已完成本微课的学习”的提示,需点击【确定】,再点击【返回课程列表】,方可记录微课完成状态;
2) 结课考试
完成该项目的所有微课学习后,点击【考试安排】→【参加考试】即可参加结课考试。
上传文档:

切割为三段:

存入数据:

回一个问题,比如“答疑qq群号是多少?”:

虽然耗时有点久,大概几十秒,但是回答对了:


再尝试回答一个问题:

回答效果不是很好,而且由于配置不行,本地跑也很慢,如果有条件可以换一个模型,如果没有条件并且不是一定要离线运行的话,可以接一个免费的api,在结合本地的嵌入模型。
换成在线api的Qwen/Qwen2-7B-Instruct,效果还不错:


总结
本次实践的主要收获是如何在SemanticKernel中使用Ollama中的对话模型与嵌入模型用于本地离线场景。在实践RAG的过程中,发现影响效果的最主要在两个地方。
第一个地方是切片大小的确定:
var lines = TextChunker.SplitPlainTextLines(input, 20);
var paragraphs = TextChunker.SplitPlainTextParagraphs(lines, 100);
第二个地方是要获取几条相关数据与相关度的设定:
var memoryResults = textMemory.SearchAsync(index, input, limit: 3, minRelevanceScore: 0.3);
相关度太高一条数据也找不到,太低又容易找到不相关的数据,需要通过实践,调整成一个能满足需求的设置。
参考
2、https://github.com/BLaZeKiLL/Codeblaze.SemanticKernel
SemanticKernel/C#:使用Ollama中的对话模型与嵌入模型用于本地离线场景的更多相关文章
- C#开发中使用配置文件对象简化配置的本地保存
C#开发中使用配置文件对象简化配置的本地保存 0x00 起因 程序的核心是数据和逻辑,开发过程中免不了要对操作的数据进行设置,而有些数据在程序执行过程中被用户或程序做出的修改是应该保存下来的,这样程序 ...
- 熟练掌握js中this的用法,解析this在不同应用场景的作用
由于其运行期绑定的特性,JavaScript 中的 this 含义要丰富得多,它可以是全局对象.当前对象或者任意对象,这完全取决于函数的调用方式. JavaScript 中函数的调用有以下几种方式:作 ...
- osg中使用MatrixTransform来实现模型的平移/旋转/缩放
osg中使用MatrixTransform来实现模型的平移/旋转/缩放 转自:http://www.cnblogs.com/kekec/archive/2011/08/15/2139893.html# ...
- [Unity3D][Vuforia][IOS]vuforia在unity3d中添加自己的动态模型,识别自己的图片,添加GUI,播放视频
使用环境 unity3D 5 pro vuforia 4 ios 8.1(6.1) xcode 6.1(6.2) 1.新建unity3d工程,添加vuforia 4.0的工程包 Hierarchy中 ...
- 008.Adding a model to an ASP.NET Core MVC app --【在 asp.net core mvc 中添加一个model (模型)】
Adding a model to an ASP.NET Core MVC app在 asp.net core mvc 中添加一个model (模型)2017-3-30 8 分钟阅读时长 本文内容1. ...
- LoadRunner中Action的迭代次数的设置和运行场景中设置
LoadRunner中Action的迭代次数的设置和运行场景中设置 LoadRunner是怎么重复迭代和怎么增加并发运行的呢? 另外,在参数化时,对于一次压力测试中均只能用一次的资源应该怎么参数化呢? ...
- pandas中df.ix, df.loc, df.iloc 的使用场景以及区别
pandas中df.ix, df.loc, df.iloc 的使用场景以及区别: https://stackoverflow.com/questions/31593201/pandas-iloc-vs ...
- TensorFlow Object Detection API中的Faster R-CNN /SSD模型参数调整
关于TensorFlow Object Detection API配置,可以参考之前的文章https://becominghuman.ai/tensorflow-object-detection-ap ...
- MVC中Model BLL层Model模型互转
MVC中Model BLL层Model模型互转 一. 模型通常可以做2种:充血模型和失血模型,一般做法是模型就是模型,不具备方法来操作,只具有属性,这种叫做失血模型(可能不准确):具备对模型一定的简单 ...
- Three.js中的div标签跟随(模型弹框)
目录 Three.js中的div标签跟随(模型弹框) 参考官方案例 核心渲染器 用法 注意事项 Three.js中的div标签跟随(模型弹框) 参考官方案例 核心渲染器 three.js-master ...
随机推荐
- C++笔记(6) 指针
1.指针和数组 指针和数组基本等价的原因在于指针算数和C++内部处理数组的方式.在很多情况下,可以用相同的方式使用数组名和指针名. 在多数情况下,C++将数组名视为数组的第一个元素的地址.指针p的值为 ...
- 开源一站式敏捷测试管理,极简项目管理平台 itest(爱测试) 6.6.2 发布,便捷迫切功能增强
(一)itest 简介及更新说明 itest 开源敏捷测试管理,testOps 践行者,极简的任务管理,测试管理,缺陷管理,测试环境管理,接口测试5合1,又有丰富的统计分析.可按测试包分配测试用例执行 ...
- k8s——statefulset
statefulset基础模版 [root@master statefulset]# cat web.yaml --- apiVersion: v1 kind: Service metadata: n ...
- OPA Gatekeeper:Kubernetes的策略和管理
目录 一.系统环境 二.前言 三.OPA Gatekeeper简介 四.在kubernetes上安装OPA Gatekeeper 五.gatekeeper规则 5.1 使用gatekeeper禁止某些 ...
- 用C++ Qt实现类似Photoshop的钢笔工具
因为工作上的需求,需要实现一个类似Photoshop里面的钢笔工具, 分析一下它的功能,包括: 1. 有两种点:节点和控制点,节点是构成图形的基本端点,控制点是影响贝塞尔曲线的系数. 2. 创建节点: ...
- 设计模式:命令模式(Command Pattern)及实例
好家伙, 0.什么是命令模式 在软件系统中,"行为请求者"与"行为实现者"通常呈现一种"紧耦合". 但在某些场合,比如要对行为进行&q ...
- 如何解决系统报错:nf_conntrack: table full, dropping packets
问题 在系统日志中(/var/log/messages),有时会看到大面积的下面的报错: nf_conntrack: table full, dropping packet 这说明系统接到了大量的连接 ...
- Java实际工作里用到的几种加密方式
1.Base64加密 最简单的加密方式,甚至可以说不是加密,只是一种用64个字符表示任意二进制数据的方法.Base64编码原理是将输入字符串按字节切分,取得每个字节对应的二进制值(若不足8比特则高位补 ...
- fs.1.10 ON rockeylinux8 dockerfile模式
概述 freeswitch是一款简单好用的VOIP开源软交换平台. rockeylinux8 docker上编译安装fs.1.10的流程记录,本文使用dockerfile模式. 环境 docker e ...
- Nuxt.js 深入浅出:目录结构与文件组织详解
title: Nuxt.js 深入浅出:目录结构与文件组织详解 date: 2024/6/18 updated: 2024/6/18 author: cmdragon excerpt: 摘要:本文详述 ...