前言

上一篇文章介绍了使用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。

使用方法见:https://github.com/BLaZeKiLL/Codeblaze.SemanticKernel/tree/main/dotnet/Codeblaze.SemanticKernel.Connectors.Ollama

大佬实现了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);

相关度太高一条数据也找不到,太低又容易找到不相关的数据,需要通过实践,调整成一个能满足需求的设置。

参考

1、https://medium.com/@johnkane24/local-memory-c-semantic-kernel-ollama-and-sqlite-to-manage-chat-memories-locally-9b779fc56432

2、https://github.com/BLaZeKiLL/Codeblaze.SemanticKernel

SemanticKernel/C#:使用Ollama中的对话模型与嵌入模型用于本地离线场景的更多相关文章

  1. C#开发中使用配置文件对象简化配置的本地保存

    C#开发中使用配置文件对象简化配置的本地保存 0x00 起因 程序的核心是数据和逻辑,开发过程中免不了要对操作的数据进行设置,而有些数据在程序执行过程中被用户或程序做出的修改是应该保存下来的,这样程序 ...

  2. 熟练掌握js中this的用法,解析this在不同应用场景的作用

    由于其运行期绑定的特性,JavaScript 中的 this 含义要丰富得多,它可以是全局对象.当前对象或者任意对象,这完全取决于函数的调用方式. JavaScript 中函数的调用有以下几种方式:作 ...

  3. osg中使用MatrixTransform来实现模型的平移/旋转/缩放

    osg中使用MatrixTransform来实现模型的平移/旋转/缩放 转自:http://www.cnblogs.com/kekec/archive/2011/08/15/2139893.html# ...

  4. [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中 ...

  5. 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. ...

  6. LoadRunner中Action的迭代次数的设置和运行场景中设置

    LoadRunner中Action的迭代次数的设置和运行场景中设置 LoadRunner是怎么重复迭代和怎么增加并发运行的呢? 另外,在参数化时,对于一次压力测试中均只能用一次的资源应该怎么参数化呢? ...

  7. pandas中df.ix, df.loc, df.iloc 的使用场景以及区别

    pandas中df.ix, df.loc, df.iloc 的使用场景以及区别: https://stackoverflow.com/questions/31593201/pandas-iloc-vs ...

  8. TensorFlow Object Detection API中的Faster R-CNN /SSD模型参数调整

    关于TensorFlow Object Detection API配置,可以参考之前的文章https://becominghuman.ai/tensorflow-object-detection-ap ...

  9. MVC中Model BLL层Model模型互转

    MVC中Model BLL层Model模型互转 一. 模型通常可以做2种:充血模型和失血模型,一般做法是模型就是模型,不具备方法来操作,只具有属性,这种叫做失血模型(可能不准确):具备对模型一定的简单 ...

  10. Three.js中的div标签跟随(模型弹框)

    目录 Three.js中的div标签跟随(模型弹框) 参考官方案例 核心渲染器 用法 注意事项 Three.js中的div标签跟随(模型弹框) 参考官方案例 核心渲染器 three.js-master ...

随机推荐

  1. 面试必问:MySQL死锁 是什么,如何解决?(史上最全)

    MySQL死锁接触少,但面试又经常被问到怎么办? 最近有小伙伴在面试的时候,被问了MySQL死锁,如何解决? 虽然也回答出来了,但是不够全面体系化, 所以,小北给大家做一下系统化.体系化的梳理,帮助大 ...

  2. C# .NET 生成国密私钥公钥对

    使用的工具类: using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.GM; using Org.BouncyCastle.Asn1.X9; ...

  3. work02

    第一题: 看程序说答案 int a = 10; int b = 3; int c = a + b;//13 int d = a - b;//7 int e = a * b; //30 int f = ...

  4. webpack-bundle-analyzer 分析打包模块大小优化

    安装 webpack-bundle-analyzer npm i webpack-bundle-analyzer -D 配置vue.config.js module.exports = defineC ...

  5. 根据两个日期之间获取LocalDate日历列表和LocalDate和LocalDateTime数据格式转换

    根据两个日期之间获取LocalDate日历列表和LocalDate和LocalDateTime数据格式转换 package com.example.core.mydemo.localdatetime; ...

  6. iOS开发之弹窗管理

    前言 "千淘万漉虽辛苦,吹尽狂沙始到金."在这快速变化的互联网行业,身边的朋友有的选择了勇敢创业,有的则在技术的海洋中默默耕耘.时常在深夜反思,作为一个开发者,我们的价值何在?答案 ...

  7. unity持久化数据之XML和Excel

    unity持久化数据之XML public class XMLDataMananger: Singleton<XMLDataMananger> { protected XMLDataMan ...

  8. Java面试知识点(六)hashmap深度理解

    1.hashmap 的数据结构 要知道 hashmap 是什么,首先要搞清楚它的数据结构,在 java 编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用 ...

  9. 英特尔 Gaudi 加速辅助生成

    随着模型规模的增长,生成式人工智能的实现需要大量的推理资源.这不仅增加了每次生成的成本,而且还增加了用于满足此类请求的功耗.因此,文本生成的推理优化对于降低延迟.基础设施成本以及功耗都至关重要,其可以 ...

  10. Python 潮流周刊#58:最快运行原型的语言(摘要)

    本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...