变压器(ONNX)嵌入
TransformersEmbeddingClient
是一个EmbeddingClient
实现,通过选择的句子转换器在本地计算句子嵌入。
它使用预训练的变压器模型,序列化为Open Neural Network Exchange(ONNX)格式。
使用Deep Java Library和微软的ONNX Java Runtime库来运行ONNX模型并在Java中计算嵌入。
序列化 Tokenizer 和 Transformer 模型
使用 optimal-cli 进行序列化
optimum-cli命令行工具。
optimum-cli
序列化(导出)指定的模型:
python3 -m venv venv
source ./venv/bin/activate
(venv) pip install --upgrade pip
(venv) pip install optimum onnx onnxruntime
(venv) optimum-cli export onnx --generative sentence-transformers/all-MiniLM-L6-v2 onnx-output-folder
sentence-transformers/all-MiniLM-L6-v2转换器导出到
onnx-output-folder
文件夹中。稍后包括由嵌入客户端使用的
tokenizer.json
和
model.onnx
文件。
将spring-ai-transformers
项目添加到您的maven依赖项中:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-transformers</artifactId>
</dependency>
请参考依赖管理部分将Spring AI BOM添加到您的构建文件中。 |
然后创建一个新的TransformersEmbeddingClient
实例,并使用setTokenizerResource(tokenizerJsonUri)
和setModelResource(modelOnnxUri)
方法来设置导出的tokenizer.json
和model.onnx
文件的URI(支持classpath:
、file:
或https:
URI模式)。
如果未显式设置模型,则TransformersEmbeddingClient
默认为sentence-transformers/all-MiniLM-L6-v2:
维度 |
384 |
平均性能 |
58.80 |
速度 |
每秒14200句 |
大小 |
80MB |
以下片段说明了如何手动使用TransformersEmbeddingClient
:
TransformersEmbeddingClient embeddingClient = new TransformersEmbeddingClient();
// (可选)默认为classpath:/onnx/all-MiniLM-L6-v2/tokenizer.json
embeddingClient.setTokenizerResource("classpath:/onnx/all-MiniLM-L6-v2/tokenizer.json");
// (可选)默认为classpath:/onnx/all-MiniLM-L6-v2/model.onnx
embeddingClient.setModelResource("classpath:/onnx/all-MiniLM-L6-v2/model.onnx");
// (可选)默认为${java.io.tmpdir}/spring-ai-onnx-model
// 默认仅缓存http/https资源。
embeddingClient.setResourceCacheDirectory("/tmp/onnx-zoo");
// (可选)如果看到像以下错误一样的错误,请设置分词器填充:
// "ai.onnxruntime.OrtException: Supplied array is ragged, ..."
embeddingClient.setTokenizerOptions(Map.of("padding", "true"));
embeddingClient.afterPropertiesSet();
List<List<Double>> embeddings = embeddingClient.embed(List.of("Hello world", "World is big"));
手动创建时,必须在设置属性后使用客户端之前调用afterPropertiesSet() 。 |
第一个embed()
调用会下载大型ONNX模型并将其缓存在本地文件系统上。因此,第一次调用可能比平常花费更长的时间。可以使用#setResourceCacheDirectory(<path>)
方法设置存储ONNX模型的本地文件夹。默认的缓存文件夹是${java.io.tmpdir}/spring-ai-onnx-model
。
将TransformersEmbeddingClient创建为Bean
是更方便(也是更推荐的)。这样你就不必手动调用afterPropertiesSet()
了。
@Bean
public EmbeddingClient embeddingClient() {
return new TransformersEmbeddingClient();
}
Transformers Embedding Spring Boot Starter
您可以使用以下Spring Boot starter为TransformersEmbeddingClient
进行引导和自动装配:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-transformers-spring-boot-starter</artifactId>
</dependency>
请参考依赖管理部分,将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.embedding.transformer.enabled |
启用 Transformer 嵌入客户端。 |
true |
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'。留空以回退到默认设置。 |
空 |
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.gpuDeviceId |
要执行的 GPU 设备 ID。仅当 >= 0 时适用。否则忽略。 |
-1 |
spring.ai.embedding.transformer.metadataMode |
指定将用于计算嵌入的文档内容和元数据的哪些部分。 |
无 |
如果你看到类似 Caused by: ai.onnxruntime.OrtException: Supplied array is ragged,.. 的错误,请按以下方式在 application.properties 中启用分词器填充: |
spring.ai.embedding.transformer.tokenizer.options.padding=true