Transformers (ONNX) 嵌入
你可以使用任意 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.json 和 model.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.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.options | HuggingFaceTokenizer 的选项,例如 '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.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
:::
:::注意
如果你遇到类似 生成式输出名称不包含预期的: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.onnx 和 model.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.json 和 model.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();
}