跳到主要内容

Transformers (ONNX) 嵌入

Deepseek 3.2 中英对照 (ONNX) Transformers Transformers (ONNX) Embeddings

TransformersEmbeddingModel 是一个 EmbeddingModel 实现,它使用选定的 句子转换器 在本地计算 句子嵌入

你可以使用任意 HuggingFace 嵌入模型

它使用了预训练的 transformer 模型,这些模型被序列化为 Open Neural Network Exchange (ONNX) 格式。

Deep Java Library 与 Microsoft ONNX Java Runtime 库被应用于在 Java 中运行 ONNX 模型并计算嵌入向量。

先决条件

要在Java环境中运行,我们需要将分词器和Transformer模型序列化ONNX格式。

使用optimum-cli进行序列化 - 一个快速实现此目的的方法是使用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 transformer 标识符或提供直接的文件路径。

自动配置

备注

Spring AI 的自动配置和 starter 模块的 artifact 名称发生了重大变化。更多信息请参阅升级说明

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 Embedding 模型。true
spring.ai.model.embedding启用 Transformer Embedding 模型。transformers
spring.ai.embedding.transformer.tokenizer.uri由 ONNX 引擎创建的预训练 HuggingFaceTokenizer 的 URI (例如 tokenizer.json)。onnx/all-MiniLM-L6-v2/tokenizer.json
spring.ai.embedding.transformer.tokenizer.optionsHuggingFaceTokenizer 的选项,例如 'addSpecialTokens'、'modelMaxLength'、'truncation'、'padding'、'maxLength'、'stride'、'padToMultipleOf'。留空则回退到默认值。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.modelOutputNameONNX 模型的输出节点名称,将用于嵌入计算。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

:::

:::注意
如果你遇到类似 生成式输出名称不包含预期的:last_hidden_state。请考虑使用可用的模型输出之一: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 运行时)。
:::

手动配置

若未使用 Spring Boot,您可以手动配置 Onnx Transformers 嵌入模型。为此,请将 spring-ai-transformers 依赖项添加至您项目的 Maven pom.xml 文件中:

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

:::提示
请参考依赖管理部分,将Spring AI BOM添加到您的构建文件中。
:::

然后创建一个新的 TransformersEmbeddingModel 实例,并使用 setTokenizerResource(tokenizerJsonUri)setModelResource(modelOnnxUri) 方法来设置导出的 tokenizer.jsonmodel.onnx 文件的 URI。(支持 classpath:file:https: URI 模式)。

如果模型未明确设置,TransformersEmbeddingModel 默认使用 sentence-transformers/all-MiniLM-L6-v2

维度384
平均性能58.80
速度14200 句子/秒
大小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(<path>) 方法可以设置存储 ONNX 模型的本地文件夹。默认的缓存文件夹是 ${java.io.tmpdir}/spring-ai-onnx-model

创建 TransformersEmbeddingModel 作为 Bean 会更加方便(也更推荐)。这样你就不需要手动调用 afterPropertiesSet() 方法了。

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