Transformers(ONNX)嵌入模型

本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。

TransformersEmbeddingModel 是一个嵌入模型实现,用于通过本地运行的选定句子转换器( Sentence Transformer)计算 文本嵌入向量

可使用任意 HuggingFace 嵌入模型

使用经 预训练 并以 开放神经网络交换(Open Neural Network Exchange,ONNX) 格式序列化的转换器模型。

通过 Deep Java Library 和微软 ONNX Java 运行时库在 Java 中运行 ONNX 模型并计算嵌入向量。

先决条件

需将分词器与转换器模型(Transformer Model)序列化为 ONNX 格式以在 Java 中运行。

使用 optimum-cli 命令行工具快速实现序列化。以下代码片段创建 Python 虚拟环境,安装必要包并通过 optimum-cli 导出指定模型:

python3 -m venv venv
source ./venv/bin/activate
(venv) pip install --upgrade pip
(venv) pip install optimum onnx onnxruntime sentence-transformers
(venv) optimum-cli export onnx --model sentence-transformers/all-MiniLM-L6-v2 onnx-output-folder

该代码片段将 sentence-transformers/all-MiniLM-L6-v2 转换器导出到 onnx-output-folder 文件夹,其中包含嵌入模型所需的 tokenizer.jsonmodel.onnx 文件。

可替换 all-MiniLM-L6-v2 为任意 HuggingFace 转换器标识符或直接文件路径。

自动配置

Spring AI 自动配置及 starter 模块的构件命名已发生重大变更,详情请参阅 升级说明文档

Spring AI 为 ONNX Transformer 嵌入模型提供 Spring Boot 自动配置。启用该功能需在项目的 Maven pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-transformers</artifactId>
</dependency>

或添加到你的 Gradle build.gradle 构建文件中。

dependencies {
    implementation 'org.springframework.ai:spring-ai-starter-model-transformers'
}
请参考 “依赖管理” 章节将 Spring AI BOM 添加到你的构建文件。请参考 “构件仓库” 章节将这些仓库添加到你的构建系统中。

使用 spring.ai.embedding.transformer.* 属性进行配置。

例如,在 application.properties 文件中添加以下配置以使用 intfloat/e5-small-v2 文本嵌入模型:

spring.ai.embedding.transformer.onnx.modelUri=https://huggingface.co/intfloat/e5-small-v2/resolve/main/model.onnx
spring.ai.embedding.transformer.tokenizer.uri=https://huggingface.co/intfloat/e5-small-v2/raw/main/tokenizer.json

支持的完整属性列表如下:

嵌入配置

嵌入自动配置的启用与禁用现在通过顶级属性配置,前缀为 spring.ai.model.embedding

  • 启用:spring.ai.model.embedding=transformers(默认启用)

  • 禁用:spring.ai.model.embedding=none(或任何不匹配 transformers 的值)

此变更是为了支持多模型配置。

属性 说明 默认值

spring.ai.embedding.transformer.enabled (已移除且不再有效)

启用 Transformer 嵌入模型。

true

spring.ai.model.embedding

启用 Transformer 嵌入模型。

transformers

spring.ai.embedding.transformer.tokenizer.uri

预训练的 HuggingFaceTokenizer URI(由 ONNX 引擎生成,如 tokenizer.json)。

onnx/all-MiniLM-L6-v2/tokenizer.json

spring.ai.embedding.transformer.tokenizer.options

HuggingFaceTokenizer 选项,包括 addSpecialTokensmodelMaxLengthtruncationpaddingmaxLengthstridepadToMultipleOf。留空则使用默认值。

empty

spring.ai.embedding.transformer.cache.enabled

启用远程资源缓存。

true

spring.ai.embedding.transformer.cache.directory

缓存远程资源(如 ONNX 模型)的目录路径。

${java.io.tmpdir}/spring-ai-onnx-model

spring.ai.embedding.transformer.onnx.modelUri

预训练的现有 ONNX 模型。

onnx/all-MiniLM-L6-v2/model.onnx

spring.ai.embedding.transformer.onnx.modelOutputName

用于嵌入计算的 ONNX 模型输出节点名称。

last_hidden_state

spring.ai.embedding.transformer.onnx.gpuDeviceId

执行所用的 GPU 设备 ID。仅当值 >= 0 时生效,否则忽略(需额外添加 onnxruntime_gpu 依赖)。

-1

spring.ai.embedding.transformer.metadataMode

指定文档内容和元数据中哪些部分将用于计算嵌入向量。

NONE

错误与特殊情况

若出现类似 Caused by: ai.onnxruntime.OrtException: Supplied array is ragged 的错误,需在 application.properties 中启用分词器填充功能:

spring.ai.embedding.transformer.tokenizer.options.padding=true

若出现类似 The generative output names don’t contain expected: last_hidden_state. Consider one of the available model outputs: token_embeddings, …​ 的错误,需根据模型将输出节点名称设置为正确的值(参考错误消息中列出的名称)。例如:

spring.ai.embedding.transformer.onnx.modelOutputName=token_embeddings

若出现类似 ai.onnxruntime.OrtException: Error code - ORT_FAIL - message: Deserialize tensor onnx::MatMul_10319 failed.GetFileLength for ./model.onnx_data failed:Invalid fd was supplied: -1 的错误,表明模型超过 2GB 且被序列化为两个文件:model.onnxmodel.onnx_data

model.onnx_data 作为 外部数据 文件,需与 model.onnx 置于同一目录下。

当前唯一解决方案是将大型 model.onnx_data 文件复制到运行 Boot 应用的目录中。

若出现类似 ai.onnxruntime.OrtException: Error code - ORT_EP_FAIL - message: Failed to find CUDA shared provider 的错误,表明你使用了 GPU 参数 spring.ai.embedding.transformer.onnx.gpuDeviceId 但未添加 onnxruntime_gpu 依赖。

<dependency>
    <groupId>com.microsoft.onnxruntime</groupId>
    <artifactId>onnxruntime_gpu</artifactId>
</dependency>

请根据 CUDA 版本选择对应版本的 onnxruntime_gpu 依赖(参考 ONNX Java Runtime 文档)。

手动配置

若不使用 Spring Boot,可手动配置 ONNX Transformers 嵌入模型。为此需在项目的 Maven pom.xml 文件中添加 spring-ai-transformers 依赖:

<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-transformers</artifactId>
</dependency>
请参考 “依赖管理” 章节将 Spring AI BOM 添加到你的构建文件。

随后创建新的 TransformersEmbeddingModel 实例,并通过 setTokenizerResource(tokenizerJsonUri)setModelResource(modelOnnxUri) 方法设置导出的 tokenizer.jsonmodel.onnx 文件路径(支持 classpath:file:https: URI 协议)。

若未显式设置模型,TransformersEmbeddingModel 默认使用 sentence-transformers/all-MiniLM-L6-v2

Dimensions

384

Avg. performance

58.80

Speed

14200 sentences/sec

Size

80MB

以下代码片段展示如何手动使用 TransformersEmbeddingModel

TransformersEmbeddingModel embeddingModel = new TransformersEmbeddingModel();

// (optional) defaults to classpath:/onnx/all-MiniLM-L6-v2/tokenizer.json
embeddingModel.setTokenizerResource("classpath:/onnx/all-MiniLM-L6-v2/tokenizer.json");

// (optional) defaults to classpath:/onnx/all-MiniLM-L6-v2/model.onnx
embeddingModel.setModelResource("classpath:/onnx/all-MiniLM-L6-v2/model.onnx");

// (optional) defaults to ${java.io.tmpdir}/spring-ai-onnx-model
// Only the http/https resources are cached by default.
embeddingModel.setResourceCacheDirectory("/tmp/onnx-zoo");

// (optional) Set the tokenizer padding if you see an errors like:
// "ai.onnxruntime.OrtException: Supplied array is ragged, ..."
embeddingModel.setTokenizerOptions(Map.of("padding", "true"));

embeddingModel.afterPropertiesSet();

List<List<Double>> embeddings = this.embeddingModel.embed(List.of("Hello world", "World is big"));
若手动创建 TransformersEmbeddingModel 实例,必须在设置属性后、使用客户端前调用 afterPropertiesSet() 方法。

首次调用 embed() 方法时会下载大型 ONNX 模型并缓存至本地文件系统,因此首次调用可能耗时较长。可通过 #setResourceCacheDirectory(<路径>) 方法设置 ONNX 模型存储目录,默认缓存路径为 ${java.io.tmpdir}/spring-ai-onnx-model

更推荐(且便捷)的方式是将 TransformersEmbeddingModel 声明为 Bean,如此便无需手动调用 afterPropertiesSet() 方法。

@Bean
public EmbeddingModel embeddingModel() {
   return new TransformersEmbeddingModel();
}