深入理解Spring AI中的向量嵌入:原理与实战

后端 潘老师 2个月前 (02-20) 97 ℃ (0) 扫码查看

在人工智能的领域中,向量嵌入技术在文本处理和信息检索等方面发挥着关键作用。本文主要围绕Spring AI的EmbeddingModel展开,详细介绍向量嵌入的概念、在语义搜索中的应用,以及如何使用OpenAI模型生成向量嵌入,同时会结合具体代码示例,帮助大家更好地理解和掌握这一技术。

一、向量嵌入是什么?

在大语言模型(LLMs)的世界里,向量(也叫嵌入向量)是一组用来表示某个对象的数字数组。这里的对象可以是一个单词、一个句子、一段音频或视频,甚至像产品描述这样的结构化数据。向量主要通过计算两个向量之间的距离,来判断对象之间的相关性。简单来说,向量间距离小,就表示两个对象相关性高;距离大,则相关性低。

在向量(也就是数字数组)中,每个数字都被称作一个分量,它对应着高维空间中的一个维度。每个维度都代表了数据的一个独特特征或属性。

比如说“happiness”这个单词,它的向量嵌入可能是[2.5, 1.3, 0.8] 。向量中的每个分量都代表了这个单词在语言层面的一个特征:

  • 第一个分量2.5,可以理解为对单词情感积极性的量化。
  • 第二个分量1.3,体现了情感强度。
  • 第三个分量0.8,表示这个单词使用的语境。

要知道,向量里的这些数字单独拿出来看,并没有什么特别的意义,真正重要的是它们之间的相对大小和相互关系,这些才蕴含了语义信息。借助这样的向量,大语言模型就能更好地理解和处理“happiness”这个单词了。而且,同一个单词在不同的语境中,向量嵌入可能是不一样的。当然,使用的模型类型对向量嵌入结果的质量起着关键作用。

二、语义搜索(相似性搜索)

向量最主要的用途就是进行相似性搜索,也就是在嵌入空间里找出向量之间的相近程度。语义搜索可不依赖于单词的精确匹配,它能够理解查询的上下文和语义,所以往往能给出更好的搜索结果。

相似性搜索在很多应用场景中都有广泛的应用,比如检索增强生成(RAG)、搜索引擎、推荐引擎、文档管理系统等。就拿谷歌搜索来说,语义搜索让它能够执行智能搜索,直接给出答案,或者把我们带到网页上能找到答案的地方,而且有时候搜索结果和我们输入的查询词表面上看可能没什么关系,但实际上是符合语义的。

三、EmbeddingModel接口详解

在Spring AI中,EmbeddingModel接口是所有向量嵌入功能的核心。它的主要职责就是把文本转化为数值向量(也就是向量嵌入)。这个接口提供了多个方法,其中embed()方法比较常用,它可以接受不同类型的输入(比如文本、文档等),调用配置好的后端嵌入模型,然后返回生成的向量。EmbeddingModel接口的定义如下:

public interface EmbeddingModel extends Model<EmbeddingRequest, EmbeddingResponse> {
    List<Double> embed(String text);
    List<Double> embed(Document document);
    EmbeddingResponse embedForResponse(List<String> texts);
    EmbeddingResponse call(EmbeddingRequest request);
    //...
}

embedForResponse()方法会返回更全面的输出,除了向量,还包含关于向量嵌入的一些额外信息。

假设有了EmbeddingModel的Bean,调用它的方法就很简单,示例代码如下:

String text = "...";
List<Double> embeddings = embeddingModel.embed(text);

如果想要通过编程的方式覆盖默认值,可以像下面这样提供参数:

String text = "...";
List<Double> embeddings = embeddingModel.call(
        new EmbeddingRequest(List.of(text), OpenAiEmbeddingOptions.builder()
                .withModel("text-embedding-3-small")
                .withUser("jon.snow")
                .build()))
        .getResult().getOutput();

四、EmbeddingModel的实现类

Spring AI支持多种嵌入模型,针对每个模型,都有对应的EmbeddingModel接口实现类。如果想获取完整且最新的支持供应商和模型列表,可以参考官方指南。下面列举一些常见的供应商、实现类和支持的模型:

  • OpenAI:实现类是OpenAiEmbeddingModel,支持text-embedding-ada-002text-embedding-3-largetext-embedding-3-small等模型。
  • Azure OpenAI:实现类为AzureOpenAiEmbeddingModel,支持text-embedding-ada-002模型。
  • OllamaOllamaEmbeddingModel是其实现类,支持mistral模型。
  • PostgresML:对应的实现类是PostgresMlEmbeddingModel,支持distilbert-base-uncased模型 。
  • Mistral AI:实现类MistralAiEmbeddingModel,支持mistral-embed模型。
  • MiniMaxMiniMaxEmbeddingModel为实现类,支持embo-01模型。
  • QianFanQianFanEmbeddingModel是其实现类,支持bge_large_zh模型。
  • Amazon Bedrock Titan:实现类是BedrockTitanEmbeddingModel,支持amazon.titan-embed-image-v1模型。
  • Amazon Bedrock Cohere:对应的实现类为BedrockCohereEmbeddingModel,支持cohere.embed-multilingual-v3模型。

五、实战演示:用OpenAI生成向量嵌入

接下来通过一个示例,看看如何使用OpenAiEmbeddingModel类,借助OpenAI的text-embedding-ada-002模型来生成向量嵌入。其实,使用其他供应商和模型的步骤也大致相同。

(一)添加Maven依赖

首先,在项目的pom.xml文件里添加spring-ai-openai-spring-boot-starter依赖,添加这个依赖后,Spring Boot会自动为OpenAI嵌入模型进行配置。如果是从零开始搭建项目,可以参考Spring AI的入门指南获取完整信息。添加的依赖代码如下:

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

别忘了在属性文件里添加OpenAI的API密钥,配置如下:

spring.ai.openai.api-key=${OPENAI_API_KEY}

(二)配置OpenAiEmbeddingModel Bean

添加完spring-ai-openai-spring-boot-starter依赖后,Spring Boot的自动配置功能会创建一个带有默认配置的OpenAiEmbeddingModel Bean。我们可以把这个Bean注入到Spring管理的类中,然后就能使用它了。示例代码如下:

import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.web.bind.annotation.RestController;

// 定义一个RestController
@RestController 
class EmbeddingController {
    // 注入EmbeddingModel实例
    private final EmbeddingModel embeddingModel; 

    // 通过构造函数注入EmbeddingModel
    EmbeddingController(EmbeddingModel embeddingModel) {
        this.embeddingModel = embeddingModel;
    }
    // 其他代码...
}

如果想要修改默认配置,可以在application.properties文件里指定相应的属性。比如:

spring.ai.openai.embedding.options.model=text-embedding-3
spring.ai.openai.embedding.options.encodingFormat=base64 # 也可以是float
spring.ai.openai.embedding.options.user=howtodoinjava # 用于监测和防止滥用,代表终端用户
spring.ai.openai.embedding.options.dimensions=3000 # 仅在text-embedding-3及后续模型中支持

如果想查看完整的属性列表和默认值,可以参考相关的属性说明部分。

(三)生成嵌入向量

OpenAiEmbeddingModel Bean初始化完成后,就可以使用它的embed()方法,从输入的文本或文档生成向量了。通常,这些向量会存储在向量数据库中。默认情况下,text-embedding-3-small模型生成的嵌入向量长度是1536,text-embedding-3-large模型生成的向量长度是3072。示例代码如下:

import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

// 定义一个RestController
@RestController 
class EmbeddingController {
    // 自动注入EmbeddingModel实例
    @Autowired 
    EmbeddingModel embeddingModel; 

    // 处理POST请求,路径为/embed
    @PostMapping("/embed") 
    Response embed(@RequestBody String message) {
        // 调用embed方法生成向量
        var embeddings = embeddingModel.embed(message); 
        // 返回包含向量维度和向量数据的Response对象
        return new Response(embeddings.size(), embeddings); 
    }
}

// 定义Response记录类,包含向量维度和向量数据
record Response(int dimension, List<Double> vector){} 

最后,可以用任何REST测试工具调用这个API,验证返回的结果。比如在工具里发送请求:

POST http:/localhost:8080/embed
请求体:
{
    "message":"The quality of the item is poor and unreliable."
}

得到的响应可能类似这样:

{
    "dimension":1536, 
    "vector":[
        -0.017181374, 0.009984727, -0.028008185, 0.004044133, -0.0038955295, 0.019658094, -0.012595899, -0.011555676
    ]
}

六、总结

本文详细介绍了Spring AI中的向量嵌入相关知识:

  • 向量嵌入是一组数字数组,用于表示单词、句子、音视频片段等对象。
  • 语义搜索就是在多维嵌入空间中寻找向量的相近程度。
  • 讲解了EmbeddingModel接口及其方法的基本原理。
  • 介绍了常见的嵌入模型,以及访问这些模型的实现类。
  • 说明了EmbeddingModel Bean如何通过默认配置初始化,以及如何在属性文件中修改配置。
  • 最后通过示例,展示了如何使用OpenAI的text-embedding-3-small模型和OpenAiEmbeddingModel Bean生成向量嵌入。

希望通过本文的介绍,大家对Spring AI的向量嵌入有更深入的理解,在实际项目中能够灵活运用这一技术。如果在学习过程中有任何问题,欢迎一起交流探讨!

归属教程 Spring AI 快速入门教程汇总

文章目录 Spring AI是什么?有啥优势? 如何在项目中使用Spring AI? Spring AI详细功 […]


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/back/14811.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】