Improve SpringAI models AOT support

- Fix various issues for bedrok/llama2/titan/choere,palm2,openai,azure-openai and vertex
 - Addd demo tests: https://github.com/tzolov/spring-ai-aot-tests
 - Fix broken Ollama AOT configuration
 - Code style & doc improvements for onnx transformer client

 Part of #360
This commit is contained in:
Christian Tzolov
2024-02-25 23:28:23 +01:00
parent 4e270ac75a
commit 21fc676fba
20 changed files with 279 additions and 40 deletions

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2024-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.azure.openai.aot;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.azure.ai.openai.OpenAIClient;
import com.azure.ai.openai.models.ChatChoice;
import org.springframework.ai.aot.AiRuntimeHints;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
/**
* @author Christian Tzolov
*/
public class AzureOpenAiRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(@NonNull RuntimeHints hints, @Nullable ClassLoader classLoader) {
var mcs = MemberCategory.values();
hints.reflection().registerType(OpenAIClient.class, mcs);
hints.reflection().registerType(OpenAIAsyncClient.class, mcs);
// Register all com.azure.ai.openai.models.* classes
AiRuntimeHints
.findClassesInPackage(ChatChoice.class.getPackageName(), (metadataReader, metadataReaderFactory) -> true)
.forEach(clazz -> hints.reflection().registerType(clazz, mcs));
hints.proxies().registerJdkProxy(com.azure.ai.openai.implementation.OpenAIClientImpl.OpenAIClientService.class);
try {
var resolver = new PathMatchingResourcePatternResolver();
for (var resourceMatch : resolver.getResources("/azure-ai-openai.properties"))
hints.resources().registerResource(resourceMatch);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,2 @@
org.springframework.aot.hint.RuntimeHintsRegistrar=\
org.springframework.ai.azure.openai.aot.AzureOpenAiRuntimeHints

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2024-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.azure.openai.aot;
import java.util.Set;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.azure.ai.openai.OpenAIClient;
import com.azure.ai.openai.models.ChatChoice;
import org.junit.jupiter.api.Test;
import org.springframework.ai.aot.AiRuntimeHints;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.TypeReference;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection;
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.resource;
class AzureOpenAiRuntimeHintsTests {
@Test
void registerHints() {
RuntimeHints runtimeHints = new RuntimeHints();
AzureOpenAiRuntimeHints openAiRuntimeHints = new AzureOpenAiRuntimeHints();
openAiRuntimeHints.registerHints(runtimeHints, null);
Set<TypeReference> azureModelTypes = AiRuntimeHints.findClassesInPackage(ChatChoice.class.getPackageName(),
(metadataReader, metadataReaderFactory) -> true);
for (TypeReference modelType : azureModelTypes) {
assertThat(runtimeHints).matches(reflection().onType(modelType));
}
assertThat(runtimeHints).matches(reflection().onType(OpenAIClient.class));
assertThat(runtimeHints).matches(reflection().onType(OpenAIAsyncClient.class));
assertThat(runtimeHints).matches(resource().forResource("/azure-ai-openai.properties"));
}
}

View File

@@ -44,6 +44,12 @@
<groupId>software.amazon.awssdk</groupId>
<artifactId>bedrockruntime</artifactId>
<version>${bedrockruntime.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- test dependencies -->

View File

@@ -1,10 +1,16 @@
package org.springframework.ai.bedrock.aot;
import org.springframework.ai.bedrock.anthropic.AnthropicChatOptions;
import org.springframework.ai.bedrock.anthropic.api.AnthropicChatBedrockApi;
import org.springframework.ai.bedrock.api.AbstractBedrockApi;
import org.springframework.ai.bedrock.cohere.BedrockCohereChatOptions;
import org.springframework.ai.bedrock.cohere.BedrockCohereEmbeddingOptions;
import org.springframework.ai.bedrock.cohere.api.CohereChatBedrockApi;
import org.springframework.ai.bedrock.cohere.api.CohereEmbeddingBedrockApi;
import org.springframework.ai.bedrock.jurassic2.api.Ai21Jurassic2ChatBedrockApi;
import org.springframework.ai.bedrock.llama2.BedrockLlama2ChatOptions;
import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi;
import org.springframework.ai.bedrock.titan.BedrockTitanChatOptions;
import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi;
import org.springframework.ai.bedrock.titan.api.TitanEmbeddingBedrockApi;
import org.springframework.aot.hint.MemberCategory;
@@ -26,20 +32,36 @@ public class BedrockRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
var mcs = MemberCategory.values();
for (var tr : findJsonAnnotatedClassesInPackage(AbstractBedrockApi.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClassesInPackage(Ai21Jurassic2ChatBedrockApi.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClassesInPackage(CohereChatBedrockApi.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClassesInPackage(BedrockCohereChatOptions.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClassesInPackage(CohereEmbeddingBedrockApi.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClassesInPackage(BedrockCohereEmbeddingOptions.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClassesInPackage(Llama2ChatBedrockApi.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClassesInPackage(BedrockLlama2ChatOptions.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClassesInPackage(TitanChatBedrockApi.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClassesInPackage(BedrockTitanChatOptions.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClassesInPackage(TitanEmbeddingBedrockApi.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClassesInPackage(AnthropicChatBedrockApi.class))
hints.reflection().registerType(tr, mcs);
for (var tr : findJsonAnnotatedClassesInPackage(AnthropicChatOptions.class))
hints.reflection().registerType(tr, mcs);
}
}

View File

@@ -1,2 +1,2 @@
org.springframework.aot.hint.RuntimeHintsRegistrar=\
org.springframework.ai.vertex.aot.OllamaRuntimeHints
org.springframework.ai.ollama.aot.OllamaRuntimeHints

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2024-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.openai.aot;
import org.junit.jupiter.api.Test;

View File

@@ -197,6 +197,10 @@ public class VertexAiApi {
return response != null ? response.embedding() : null;
}
@JsonInclude(Include.NON_NULL)
record BatchEmbeddingResponse(List<Embedding> embeddings) {
}
/**
* Generates a response from the model given an input.
* @param texts List of texts to embed.
@@ -205,9 +209,6 @@ public class VertexAiApi {
public List<Embedding> batchEmbedText(List<String> texts) {
Assert.notNull(texts, "The texts can not be null.");
@JsonInclude(Include.NON_NULL)
record BatchEmbeddingResponse(List<Embedding> embeddings) {
}
BatchEmbeddingResponse response = this.restClient.post()
.uri("/models/{model}:batchEmbedText?key={apiKey}", this.embeddingModel, this.apiKey)

View File

@@ -7,6 +7,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.aot.hint.TypeReference;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import java.lang.reflect.Executable;
import java.util.*;
@@ -24,9 +25,8 @@ public class AiRuntimeHints {
private static final Logger log = LoggerFactory.getLogger(AiRuntimeHints.class);
public static Set<TypeReference> findJsonAnnotatedClassesInPackage(String packageName) {
var classPathScanningCandidateComponentProvider = new ClassPathScanningCandidateComponentProvider(false);
var annotationTypeFilter = new AnnotationTypeFilter(JsonInclude.class);
classPathScanningCandidateComponentProvider.addIncludeFilter((metadataReader, metadataReaderFactory) -> {
TypeFilter typeFilter = (metadataReader, metadataReaderFactory) -> {
try {
var clazz = Class.forName(metadataReader.getClassMetadata().getClassName());
return annotationTypeFilter.match(metadataReader, metadataReaderFactory)
@@ -35,7 +35,18 @@ public class AiRuntimeHints {
catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
});
};
return findClassesInPackage(packageName, typeFilter);
}
public static Set<TypeReference> findJsonAnnotatedClassesInPackage(Class<?> packageClass) {
return findJsonAnnotatedClassesInPackage(packageClass.getPackageName());
}
public static Set<TypeReference> findClassesInPackage(String packageName, TypeFilter typeFilter) {
var classPathScanningCandidateComponentProvider = new ClassPathScanningCandidateComponentProvider(false);
classPathScanningCandidateComponentProvider.addIncludeFilter(typeFilter);
return classPathScanningCandidateComponentProvider//
.findCandidateComponents(packageName)//
.stream()//
@@ -45,11 +56,6 @@ public class AiRuntimeHints {
log.debug("registering [" + tr.getName() + ']');
})
.collect(Collectors.toUnmodifiableSet());
}
public static Set<TypeReference> findJsonAnnotatedClassesInPackage(Class<?> packageClass) {
return findJsonAnnotatedClassesInPackage(packageClass.getPackageName());
}
private static boolean hasJacksonAnnotations(Class<?> type) {

View File

@@ -1,23 +1,39 @@
package org.springframework.ai.aot;
import org.springframework.ai.chat.messages.*;
import org.springframework.ai.model.function.FunctionCallback;
import org.springframework.ai.model.function.FunctionCallbackContext;
import org.springframework.ai.model.function.FunctionCallbackWrapper;
import org.springframework.aot.hint.ExecutableMode;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.core.io.ClassPathResource;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;
import java.util.Set;
public class SpringAiCoreRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
public void registerHints(@NonNull RuntimeHints hints, @Nullable ClassLoader classLoader) {
var chatTypes = Set.of(AbstractMessage.class, AssistantMessage.class, ChatMessage.class, FunctionMessage.class,
Message.class, MessageType.class, UserMessage.class, SystemMessage.class);
Message.class, MessageType.class, UserMessage.class, SystemMessage.class, FunctionCallbackContext.class,
FunctionCallback.class, FunctionCallbackWrapper.class);
for (var c : chatTypes) {
hints.reflection().registerType(c);
}
Method getDescription = ReflectionUtils.findMethod(FunctionCallback.class, "getDescription");
hints.reflection().registerMethod(getDescription, ExecutableMode.INVOKE);
Method getInputTypeSchema = ReflectionUtils.findMethod(FunctionCallback.class, "getInputTypeSchema");
hints.reflection().registerMethod(getInputTypeSchema, ExecutableMode.INVOKE);
Method getName = ReflectionUtils.findMethod(FunctionCallback.class, "getName");
hints.reflection().registerMethod(getName, ExecutableMode.INVOKE);
for (var r : Set.of("antlr4/org/springframework/ai/vectorstore/filter/antlr4/Filters.g4",
"embedding/embedding-model-dimensions.properties"))
hints.resources().registerResource(new ClassPathResource(r));

View File

@@ -1,17 +1,32 @@
/*
* Copyright 2024-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.aot;
import java.util.Set;
import java.util.stream.Collectors;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.commons.logging.LogFactory;
import org.junit.jupiter.api.Test;
import org.springframework.aot.hint.TypeReference;
import org.springframework.util.Assert;
import java.util.Set;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
class AiRuntimeHintsTests {
@JsonInclude

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2024-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.aot;
import org.junit.jupiter.api.Test;

View File

@@ -1,9 +1,28 @@
/*
* Copyright 2024-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.aot;
import org.junit.jupiter.api.Test;
import org.springframework.ai.model.function.FunctionCallback;
import org.springframework.aot.hint.RuntimeHints;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection;
import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.resource;
class SpringAiCoreRuntimeHintsTest {
@@ -11,9 +30,13 @@ class SpringAiCoreRuntimeHintsTest {
@Test
void core() {
var runtimeHints = new RuntimeHints();
var knuddels = new SpringAiCoreRuntimeHints();
knuddels.registerHints(runtimeHints, null);
var springAiCore = new SpringAiCoreRuntimeHints();
springAiCore.registerHints(runtimeHints, null);
assertThat(runtimeHints).matches(resource().forResource("embedding/embedding-model-dimensions.properties"));
assertThat(runtimeHints).matches(reflection().onMethod(FunctionCallback.class, "getDescription"));
assertThat(runtimeHints).matches(reflection().onMethod(FunctionCallback.class, "getInputTypeSchema"));
assertThat(runtimeHints).matches(reflection().onMethod(FunctionCallback.class, "getName"));
}
}

View File

@@ -81,7 +81,7 @@ List<List<Double>> embeddings = embeddingClient.embed(List.of("Hello world", "Wo
----
Note that when created manually, you must call the `afterPropertiesSet()` after setting the properties and before using the client.
NOTE: that when created manually, you must call the `afterPropertiesSet()` after setting the properties and before using the client.
The first `embed()` call downloads the large ONNX model and caches it on the local file system.
Therefore, the first call might take longer than usual.

View File

@@ -19,6 +19,7 @@ package org.springframework.ai.autoconfigure.azure.openai;
import org.springframework.ai.azure.openai.AzureOpenAiEmbeddingOptions;
import org.springframework.ai.document.MetadataMode;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.util.Assert;
@ConfigurationProperties(AzureOpenAiEmbeddingProperties.CONFIG_PREFIX)
@@ -31,6 +32,7 @@ public class AzureOpenAiEmbeddingProperties {
*/
private boolean enabled = true;
@NestedConfigurationProperty
private AzureOpenAiEmbeddingOptions options = AzureOpenAiEmbeddingOptions.builder()
.withModel("text-embedding-ada-002")
.build();

View File

@@ -44,7 +44,7 @@ public class BedrockCohereChatAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public CohereChatBedrockApi cohereApi(AwsCredentialsProvider credentialsProvider,
public CohereChatBedrockApi cohereChatApi(AwsCredentialsProvider credentialsProvider,
BedrockCohereChatProperties properties, BedrockAwsConnectionProperties awsProperties) {
return new CohereChatBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(),
new ObjectMapper());

View File

@@ -46,7 +46,7 @@ public class BedrockCohereEmbeddingAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public CohereEmbeddingBedrockApi cohereApi(AwsCredentialsProvider credentialsProvider,
public CohereEmbeddingBedrockApi cohereEmbeddingApi(AwsCredentialsProvider credentialsProvider,
BedrockCohereEmbeddingProperties properties, BedrockAwsConnectionProperties awsProperties) {
return new CohereEmbeddingBedrockApi(properties.getModel(), credentialsProvider, awsProperties.getRegion(),
new ObjectMapper());

View File

@@ -16,7 +16,8 @@
package org.springframework.ai.autoconfigure.openai;
import org.springframework.ai.embedding.EmbeddingClient;
import java.util.List;
import org.springframework.ai.model.function.FunctionCallback;
import org.springframework.ai.model.function.FunctionCallbackContext;
import org.springframework.ai.openai.OpenAiChatClient;
@@ -37,8 +38,6 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestClient;
import java.util.List;
@AutoConfiguration(after = { RestClientAutoConfiguration.class })
@ConditionalOnClass(OpenAiApi.class)
@EnableConfigurationProperties({ OpenAiConnectionProperties.class, OpenAiChatProperties.class,
@@ -82,7 +81,7 @@ public class OpenAiAutoConfiguration {
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = OpenAiEmbeddingProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
matchIfMissing = true)
public EmbeddingClient openAiEmbeddingClient(OpenAiConnectionProperties commonProperties,
public OpenAiEmbeddingClient openAiEmbeddingClient(OpenAiConnectionProperties commonProperties,
OpenAiEmbeddingProperties embeddingProperties, RestClient.Builder restClientBuilder) {
String apiKey = StringUtils.hasText(embeddingProperties.getApiKey()) ? embeddingProperties.getApiKey()

View File

@@ -40,7 +40,7 @@ public class TransformersEmbeddingClientAutoConfiguration {
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = TransformersEmbeddingClientProperties.CONFIG_PREFIX, name = "enabled",
havingValue = "true", matchIfMissing = true)
public EmbeddingClient embeddingClient(TransformersEmbeddingClientProperties properties) {
public TransformersEmbeddingClient embeddingClient(TransformersEmbeddingClientProperties properties) {
TransformersEmbeddingClient embeddingClient = new TransformersEmbeddingClient(properties.getMetadataMode());

View File

@@ -73,10 +73,11 @@ public class TransformersEmbeddingClientProperties {
* 'truncation', 'padding', 'maxLength', 'stride' and 'padToMultipleOf'. Leave
* empty to fall back to the defaults.
*/
@NestedConfigurationProperty
private Map<String, String> options = new HashMap<>();
public String getUri() {
return uri;
return this.uri;
}
public void setUri(String uri) {
@@ -84,7 +85,7 @@ public class TransformersEmbeddingClientProperties {
}
public Map<String, String> getOptions() {
return options;
return this.options;
}
public void setOptions(Map<String, String> options) {
@@ -111,7 +112,7 @@ public class TransformersEmbeddingClientProperties {
private String directory = DEFAULT_CACHE_DIRECTORY;
public boolean isEnabled() {
return enabled;
return this.enabled;
}
public void setEnabled(boolean enabled) {
@@ -119,7 +120,7 @@ public class TransformersEmbeddingClientProperties {
}
public String getDirectory() {
return directory;
return this.directory;
}
public void setDirectory(String directory) {
@@ -135,7 +136,7 @@ public class TransformersEmbeddingClientProperties {
private final Cache cache = new Cache();
public Cache getCache() {
return cache;
return this.cache;
}
public static class Onnx {
@@ -161,7 +162,7 @@ public class TransformersEmbeddingClientProperties {
private int gpuDeviceId = -1;
public String getModelUri() {
return modelUri;
return this.modelUri;
}
public void setModelUri(String modelUri) {
@@ -169,7 +170,7 @@ public class TransformersEmbeddingClientProperties {
}
public int getGpuDeviceId() {
return gpuDeviceId;
return this.gpuDeviceId;
}
public void setGpuDeviceId(int gpuDeviceId) {
@@ -177,7 +178,7 @@ public class TransformersEmbeddingClientProperties {
}
public String getModelOutputName() {
return modelOutputName;
return this.modelOutputName;
}
public void setModelOutputName(String modelOutputName) {
@@ -190,7 +191,7 @@ public class TransformersEmbeddingClientProperties {
private final Onnx onnx = new Onnx();
public Onnx getOnnx() {
return onnx;
return this.onnx;
}
/**
@@ -204,11 +205,11 @@ public class TransformersEmbeddingClientProperties {
private MetadataMode metadataMode = MetadataMode.NONE;
public Tokenizer getTokenizer() {
return tokenizer;
return this.tokenizer;
}
public MetadataMode getMetadataMode() {
return metadataMode;
return this.metadataMode;
}
public void setMetadataMode(MetadataMode metadataMode) {