Spring AI 使用本地 Ollama Embeddings的操作方法

 更新时间:2024年05月31日 17:08:26   作者:isea533  
使用 OpenAI 的 Embeddings 接口是有费用的,如果想对大量文档进行测试,使用本地部署的 Embeddings 就能省去大量的费用,所以我们尝试使用本地的 Ollama Embeddings,这篇文章主要介绍了Spring AI 使用本地 Ollama Embeddings,需要的朋友可以参考下

使用 OpenAI 的 Embeddings 接口是有费用的,如果想对大量文档进行测试,使用本地部署的 Embeddings 就能省去大量的费用,所以我们尝试使用本地的 Ollama Embeddings。

首先本地安装 Ollama: https://ollama.com/download

即使你电脑没有性能很强的显卡,仅仅依靠 CPU 也能运行一些参数量较小的模型。ollama 中下载量最多的是 llama2 模型,但是这个模型对中文支持不太好,我们可以试试 Google 开源的 gemma 模型:

在这里插入图片描述

https://ollama.com/library/gemma

这个模型包含几个不同的版本,默认为 7b 的版本,可以先试试 7b,如果速度太慢可以换 2b 试试,执行命令 ollama run gemma 时会下载模型并运行,模型默认会下载到用户目录中的 .ollama 中,如果用户目录(一般在C盘)所在盘空间少,可以提前通过环境变量方式修改位置,参考下面的配置(改成自己的路径):

OLLAMA_MODELS=D:\.ollama

如果不会在 Windows 创建 .前缀的目录,也可以用正常目录,也可以打开 git bash,使用命令 mkdir .ollama 创建

配置环境变量后一定打开一个新的 CMD 或者 Terminal,然后执行 ollama rum gemma 下载并启动模型(已经下载到用户目录的模型可以整体移动到新的目录)。启动后可以在控制台进行对话,如下所示:

>ollama run gemma
>>> 你好
你好!我很好,谢谢您的问候。
您想让我做什么呢?我能够帮助您吗?

接下来在 Spring AI 中使用该模型,首先引入Maven依赖:

<dependency>
	<groupId>org.springframework.ai</groupId>
	<artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
</dependency>

通过下面示例代码运行:

var ollamaApi = new OllamaApi();
var chatClient = new OllamaChatClient(ollamaApi).withModel("gemma")
		.withDefaultOptions(OllamaOptions.create()
				.withModel("gemma")
				.withTemperature(0.9f));
Scanner scanner = new Scanner(System.in);
while (true) {
	System.out.print(">>> ");
	String message = scanner.nextLine();
	if (message.equals("exit")) {
		break;
	}
	String resp = chatClient.call(message);
	System.out.println("<<< " + resp);
}

接口使用很简单,下面再看如何使用 Ollama 的 Embeddings。

var ollamaApi = new OllamaApi();
//指定使用的模型
var embeddingClient = new OllamaEmbeddingClient(ollamaApi)
		.withDefaultOptions(OllamaOptions.create().withModel("gemma"));
//测试数据
VectorStore vectorStore = new SimpleVectorStore(embeddingClient);
vectorStore.add(List.of(
		new Document("白日依山尽,黄河入海流。欲穷千里目,更上一层楼。"),
		new Document("青山依旧在,几度夕阳红。白发渔樵江渚上,惯看秋月春风。"),
		new Document("一片孤城万仞山,羌笛何须怨杨柳。春风不度玉门关。"),
		new Document("危楼高百尺,手可摘星辰。不敢高声语,恐惊天上人。")
));
Scanner scanner = new Scanner(System.in);
while (true) {
	System.out.print("请输入关键词: ");
	String message = scanner.nextLine();
	if (message.equals("exit")) {
		break;
	}
	List<Document> documents = vectorStore.similaritySearch(message);
	System.out.println("查询结果: ");
	for (Document doc : documents) {
		System.out.println(doc.getContent());
	}
}

在我本地运行时(靠CPU),解析文档耗时如下:

10:33:10.423 - Calling EmbeddingClient for document id = 44d0114f-62ae-4d05-9e6d-457f157386ce
10:33:16.201 - Calling EmbeddingClient for document id = ac65024a-26a9-4827-af4c-af48a3321a4b
10:33:22.176 - Calling EmbeddingClient for document id = 53747918-8e8e-42e1-b4e6-3792c24b6881
10:33:26.125 - Calling EmbeddingClient for document id = 63123b8d-b475-48b4-b38e-71dbf1b49250

每一条文本耗时在6秒左右。解析完成后输入提示词进行验证:

请输入关键词: 春风
查询结果: 
青山依旧在,几度夕阳红。白发渔樵江渚上,惯看秋月春风。
一片孤城万仞山,羌笛何须怨杨柳。春风不度玉门关。
白日依山尽,黄河入海流。欲穷千里目,更上一层楼。
危楼高百尺,手可摘星辰。不敢高声语,恐惊天上人。

请输入关键词: 黄河
查询结果: 
青山依旧在,几度夕阳红。白发渔樵江渚上,惯看秋月春风。
一片孤城万仞山,羌笛何须怨杨柳。春风不度玉门关。
白日依山尽,黄河入海流。欲穷千里目,更上一层楼。
危楼高百尺,手可摘星辰。不敢高声语,恐惊天上人。

春风的结果还可以,但是黄河的结果就不对了。

如何使用其他模型进行 Embedding 呢?

只要启动了任何一个模型,我们通过修改上面的 withModel("gemma") 中的参数即可使用其他模型,如果本地下载过 llama2 模型,就可以直接改这里的参数,不需要重新执行 ollama run llama2 命令,这个命令影响 chat 功能的使用,不影响 embedding。如果指定的模型不存在,会提示如下信息:

[404] Not Found - {"error":"model 'llama2' not found, try pulling it first"}

可以通过 ollama pull llama2 进行下载。

我们还可以搜专门的 embedding 模型,搜索时注意下图搜索的位置:

在这里插入图片描述

顶部可以搜索全局的模型,不限于官方 library 下面的模型,搜索 embedding 结果如下:

在这里插入图片描述

我们可以试试 mofanke/dmeta-embedding-zh 这个模型,还有一个 mofanke/acge_text_embedding 是我联系作者后,作者新提供的模型,后面文章也会以这个为例介绍如何将 huggingface 上的模型转换为 ollama 的模型来使用。

使用命令 ollama pull mofanke/dmeta-embedding-zh 下载模型,这个模型不能通过 ollama run xxx 启动,需要通过其他模型启动后来引用,还使用前面的 ollama run gemma,下载完模型后修改 withModel("mofanke/dmeta-embedding-zh"),然后进行测试即可。

Ollama 的存在使得 Java 调用各种开源大模型变得更统一更简单,就好比大部分商业大模型都参考 OpenAI 的 API,方便我们调用一样。通过 Ollama 的扩展方式,还可以方便我们导入官方仓库不存在的其他模型,后续文章会以 acge_text_embedding 为例介绍如何自定义基于 PyTorch 的模型。

到此这篇关于Spring AI 使用本地 Ollama Embeddings的文章就介绍到这了,更多相关Spring AI Ollama Embeddings内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 教你利用SpringBoot写一个属于自己的Starter

    教你利用SpringBoot写一个属于自己的Starter

    如果我们将可独立于业务代码之外的功配置模块封装成一个个starter,复用的时候只需要将其在pom中引用依赖即可,SpringBoot为我们完成自动装配,简直不要太爽,这篇文章主要给大家介绍了关于如何利用SpringBoot写一个属于自己的Starter,需要的朋友可以参考下
    2022-03-03
  • Java中Stream流去除List重复元素的方法

    Java中Stream流去除List重复元素的方法

    这篇文章主要为大家详细介绍了Java中Stream流去除List重复元素的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Java消息队列RabbitMQ之消息模式详解

    Java消息队列RabbitMQ之消息模式详解

    这篇文章主要介绍了Java消息队列RabbitMQ之消息模式详解,RabbitMQ提供了一种qos(服务质量保证)功能,即在非自动确认消息的前提下,如果一定数目的消息(通过基于Consumer或者Channel设置Qos的值)未被确认前,不进行消费新的消息,需要的朋友可以参考下
    2023-07-07
  • Java学习25个JAVA常见代码示例-值得收藏的笔记

    Java学习25个JAVA常见代码示例-值得收藏的笔记

    本文列举了25个Java常用代码示例,涵盖了基础语法、面向对象编程、高级编程概念等内容,旨在帮助Java初学者掌握编程技能,从入门到成长为架构师
    2025-11-11
  • Java调用Python代码实现Word转化为PDF格式

    Java调用Python代码实现Word转化为PDF格式

    这篇文章主要为大家详细介绍了Java如何实现调用Python代码实现Word转化为PDF格式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2026-03-03
  • Java根据日期截取字符串的多种实现方法

    Java根据日期截取字符串的多种实现方法

    在实际开发中,我们经常会遇到需要根据日期来截取字符串的需求,例如从文件名中提取日期信息,Java 提供了多种方法来实现根据日期来截取字符串的功能,本文将给大家介绍了Java根据日期截取字符串的多种实现方法,需要的朋友可以参考下
    2024-11-11
  • Scala小程序详解及实例代码

    Scala小程序详解及实例代码

    这篇文章主要介绍了Scala 第一个Scala小程序详解的相关资料,需要的朋友可以参考下
    2017-01-01
  • SpringCloud Gateway的使用 + Nacos动态路由实践指南

    SpringCloud Gateway的使用 + Nacos动态路由实践指南

    SpringCloudGateway是一个基于Spring5.0、SpringBoot2.0和ProjectReactor等技术开发的网关,本文介绍SpringCloud Gateway的使用+Nacos动态路由实践指南,感兴趣的朋友跟随小编一起看看吧
    2026-01-01
  • SpringCloud Gateway自动装配实现流程详解

    SpringCloud Gateway自动装配实现流程详解

    Spring Cloud Gateway旨在为微服务架构提供一种简单有效的、统一的 API 路由管理方式。Spring Cloud Gateway 作为 Spring Cloud 生态系中的网关,它不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全、监控/埋点和限流等
    2022-10-10
  • Java线程状态运行原理解析

    Java线程状态运行原理解析

    这篇文章主要介绍了Java线程状态运行原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12

最新评论