Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asymmetric embeddings #2123

Merged
merged 7 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.opensearch.ml.common.dataset.MLInputDataset;
import org.opensearch.ml.common.dataset.TextDocsInputDataSet;
import org.opensearch.ml.common.input.MLInput;
import org.opensearch.ml.common.input.parameter.MLAlgoParams;
import org.opensearch.ml.common.output.model.ModelResultFilter;

import java.io.IOException;
Expand All @@ -22,7 +23,7 @@
import static org.opensearch.core.xcontent.XContentParserUtils.ensureExpectedToken;

/**
* ML input class which supports a list fo text docs.
* ML input class which supports a list of text docs.
* This class can be used for TEXT_EMBEDDING model.
*/
@org.opensearch.ml.common.annotation.MLInput(functionNames = {FunctionName.TEXT_EMBEDDING, FunctionName.SPARSE_ENCODING, FunctionName.SPARSE_TOKENIZE})
Expand Down Expand Up @@ -124,6 +125,9 @@
case RESULT_FILTER_FIELD:
resultFilter = ModelResultFilter.parse(parser);
break;
case ML_PARAMETERS_FIELD:
br3no marked this conversation as resolved.
Show resolved Hide resolved
this.parameters = parser.namedObject(MLAlgoParams.class, functionName.name(), null);
break;

Check warning on line 130 in common/src/main/java/org/opensearch/ml/common/input/nlp/TextDocsMLInput.java

View check run for this annotation

Codecov / codecov/patch

common/src/main/java/org/opensearch/ml/common/input/nlp/TextDocsMLInput.java#L129-L130

Added lines #L129 - L130 were not covered by tests
default:
parser.skipChildren();
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,25 @@
public static final String POOLING_MODE_FIELD = "pooling_mode";
public static final String NORMALIZE_RESULT_FIELD = "normalize_result";
public static final String MODEL_MAX_LENGTH_FIELD = "model_max_length";
public static final String QUERY_PREFIX = "query_prefix";
public static final String PASSAGE_PREFIX = "passage_prefix";

private final Integer embeddingDimension;
private final FrameworkType frameworkType;
private final PoolingMode poolingMode;
private final boolean normalizeResult;
private final Integer modelMaxLength;
private final String queryPrefix;
private final String passagePrefix;

public TextEmbeddingModelConfig(String modelType, Integer embeddingDimension, FrameworkType frameworkType, String allConfig,
PoolingMode poolingMode, boolean normalizeResult, Integer modelMaxLength) {
this(modelType, embeddingDimension, frameworkType, allConfig, poolingMode, normalizeResult, modelMaxLength, null, null);
}

@Builder(toBuilder = true)
public TextEmbeddingModelConfig(String modelType, Integer embeddingDimension, FrameworkType frameworkType, String allConfig,
PoolingMode poolingMode, boolean normalizeResult, Integer modelMaxLength) {
PoolingMode poolingMode, boolean normalizeResult, Integer modelMaxLength, String queryPrefix, String passagePrefix) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not add a check function here to ensure at least one of the new parameters is not Null? It looks like this check can avoid problems later in loading the asymmetric model.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TextEmbeddingModelConfig is used for both asymmetric and symmetric models. Symmetric models don't have prefixes. The alternative would be to create a new TextEmbeddingModelConfig class for asymmetric models. I don't think this would be a cleaner solution, tbh.

super(modelType, allConfig);
if (embeddingDimension == null) {
throw new IllegalArgumentException("embedding dimension is null");
Expand All @@ -59,6 +68,8 @@
this.poolingMode = poolingMode;
this.normalizeResult = normalizeResult;
this.modelMaxLength = modelMaxLength;
this.queryPrefix = queryPrefix;
this.passagePrefix = passagePrefix;
}

public static TextEmbeddingModelConfig parse(XContentParser parser) throws IOException {
Expand All @@ -69,6 +80,8 @@
PoolingMode poolingMode = null;
boolean normalizeResult = false;
Integer modelMaxLength = null;
String queryPrefix = null;
String passagePrefix = null;

ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.currentToken(), parser);
while (parser.nextToken() != XContentParser.Token.END_OBJECT) {
Expand Down Expand Up @@ -97,12 +110,18 @@
case MODEL_MAX_LENGTH_FIELD:
modelMaxLength = parser.intValue();
break;
case QUERY_PREFIX:
queryPrefix = parser.text();
break;

Check warning on line 115 in common/src/main/java/org/opensearch/ml/common/model/TextEmbeddingModelConfig.java

View check run for this annotation

Codecov / codecov/patch

common/src/main/java/org/opensearch/ml/common/model/TextEmbeddingModelConfig.java#L114-L115

Added lines #L114 - L115 were not covered by tests
br3no marked this conversation as resolved.
Show resolved Hide resolved
case PASSAGE_PREFIX:
passagePrefix = parser.text();
break;

Check warning on line 118 in common/src/main/java/org/opensearch/ml/common/model/TextEmbeddingModelConfig.java

View check run for this annotation

Codecov / codecov/patch

common/src/main/java/org/opensearch/ml/common/model/TextEmbeddingModelConfig.java#L117-L118

Added lines #L117 - L118 were not covered by tests
br3no marked this conversation as resolved.
Show resolved Hide resolved
default:
parser.skipChildren();
break;
}
}
return new TextEmbeddingModelConfig(modelType, embeddingDimension, frameworkType, allConfig, poolingMode, normalizeResult, modelMaxLength);
return new TextEmbeddingModelConfig(modelType, embeddingDimension, frameworkType, allConfig, poolingMode, normalizeResult, modelMaxLength, queryPrefix, passagePrefix);
}

@Override
Expand All @@ -121,6 +140,8 @@
}
normalizeResult = in.readBoolean();
modelMaxLength = in.readOptionalInt();
queryPrefix = in.readOptionalString();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can focus more on the feature itself in this PR. But later when we release this in new version. We should add version check. @b4sjoo Can you help when release new version.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both queryPrefix and passagePrefix are optional, so this shouldn't break compatibility. Are you sure there is need for a version check?

passagePrefix = in.readOptionalString();
}

@Override
Expand All @@ -136,6 +157,8 @@
}
out.writeBoolean(normalizeResult);
out.writeOptionalInt(modelMaxLength);
out.writeOptionalString(queryPrefix);
out.writeOptionalString(passagePrefix);
}

@Override
Expand All @@ -162,6 +185,12 @@
if (normalizeResult) {
builder.field(NORMALIZE_RESULT_FIELD, normalizeResult);
}
if (queryPrefix != null) {
builder.field(QUERY_PREFIX, queryPrefix);

Check warning on line 189 in common/src/main/java/org/opensearch/ml/common/model/TextEmbeddingModelConfig.java

View check run for this annotation

Codecov / codecov/patch

common/src/main/java/org/opensearch/ml/common/model/TextEmbeddingModelConfig.java#L189

Added line #L189 was not covered by tests
}
if (passagePrefix != null) {
builder.field(PASSAGE_PREFIX, passagePrefix);

Check warning on line 192 in common/src/main/java/org/opensearch/ml/common/model/TextEmbeddingModelConfig.java

View check run for this annotation

Codecov / codecov/patch

common/src/main/java/org/opensearch/ml/common/model/TextEmbeddingModelConfig.java#L192

Added line #L192 was not covered by tests
}
builder.endObject();
return builder;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@
case TextEmbeddingModelConfig.MODEL_MAX_LENGTH_FIELD:
configBuilder.modelMaxLength(((Double) configEntry.getValue()).intValue());
break;
case TextEmbeddingModelConfig.QUERY_PREFIX:
configBuilder.queryPrefix(configEntry.getValue().toString());
break;

Check warning on line 140 in ml-algorithms/src/main/java/org/opensearch/ml/engine/ModelHelper.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/ModelHelper.java#L139-L140

Added lines #L139 - L140 were not covered by tests
br3no marked this conversation as resolved.
Show resolved Hide resolved
case TextEmbeddingModelConfig.PASSAGE_PREFIX:
configBuilder.passagePrefix(configEntry.getValue().toString());
break;

Check warning on line 143 in ml-algorithms/src/main/java/org/opensearch/ml/engine/ModelHelper.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/ModelHelper.java#L142-L143

Added lines #L142 - L143 were not covered by tests
default:
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ public abstract class DLModel implements Predictable {
protected Device[] devices;
protected AtomicInteger nextDevice = new AtomicInteger(0);

protected MLModelConfig modelConfig;

@Override
public MLOutput predict(MLInput mlInput, MLModel model) {
throw new IllegalArgumentException("model not deployed");
Expand Down Expand Up @@ -183,6 +185,7 @@ protected void doLoadModel(
IOException,
TranslateException {
devices = Engine.getEngine(engine).getDevices();
this.modelConfig = modelConfig;
for (int i = 0; i < devices.length; i++) {
log.debug("load model {} to device {}: {}", modelId, i, devices[i]);
ZooModel<Input, Output> model;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,35 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.opensearch.ml.common.dataset.MLInputDataset;
import org.opensearch.ml.common.dataset.TextDocsInputDataSet;
import org.opensearch.ml.common.input.MLInput;
import org.opensearch.ml.common.input.parameter.MLAlgoParams;
import org.opensearch.ml.common.model.MLModelConfig;
import org.opensearch.ml.common.model.TextEmbeddingModelConfig;
import org.opensearch.ml.common.output.model.ModelResultFilter;
import org.opensearch.ml.common.output.model.ModelTensorOutput;
import org.opensearch.ml.common.output.model.ModelTensors;
import org.opensearch.ml.engine.algorithms.text_embedding.AsymmetricTextEmbeddingParameters;
import org.opensearch.ml.engine.algorithms.text_embedding.AsymmetricTextEmbeddingParameters.EmbeddingContentType;

import ai.djl.inference.Predictor;
import ai.djl.modality.Input;
import ai.djl.modality.Output;
import ai.djl.translate.TranslateException;

public abstract class TextEmbeddingModel extends DLModel {

@Override
public ModelTensorOutput predict(String modelId, MLInput mlInput) throws TranslateException {
MLInputDataset inputDataSet = mlInput.getInputDataset();
MLAlgoParams mlParams = mlInput.getParameters();

MLInputDataset inputDataSet = isAsymmetricModel(mlParams)
? addPrefixesToData((AsymmetricTextEmbeddingParameters) mlParams, (TextDocsInputDataSet) mlInput.getInputDataset())
: mlInput.getInputDataset();

List<ModelTensors> tensorOutputs = new ArrayList<>();
Output output;
TextDocsInputDataSet textDocsInput = (TextDocsInputDataSet) inputDataSet;
Expand All @@ -36,6 +46,52 @@
return new ModelTensorOutput(tensorOutputs);
}

private boolean isAsymmetricModel(MLAlgoParams mlParams) {
if (mlParams instanceof AsymmetricTextEmbeddingParameters) {
// Check for the necessary prefixes in modelConfig
if (modelConfig == null
br3no marked this conversation as resolved.
Show resolved Hide resolved
|| ((TextEmbeddingModelConfig) modelConfig).getPassagePrefix() == null
&& ((TextEmbeddingModelConfig) modelConfig).getQueryPrefix() == null) {
throw new IllegalArgumentException(
"When passing AsymmetricTextEmbeddingParameters, the model requires to be "
+ "registered with at least one of `query_prefix` or `passage_prefix`."
);
}
// Passed all checks
return true;
} else if (mlParams != null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will it cause any problem if remove this checking ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, tbh. I don't understand fully how the MLAlgoParams are instantiated and used throughout the code base. I just wanted to be sure the failure case is covered, in case it does happen.

// mlParams is not null and not an instance of AsymmetricTextEmbeddingParameters.
// Should never happen.
throw new IllegalArgumentException("TEXT_EMBEDDING algorithm only supports AsymmetricTextEmbeddingParameters.");
br3no marked this conversation as resolved.
Show resolved Hide resolved
}

// mlParams is null, but the model is asymmetric.
if (modelConfig != null
&& (((TextEmbeddingModelConfig) modelConfig).getPassagePrefix() != null
|| ((TextEmbeddingModelConfig) modelConfig).getQueryPrefix() != null)) {
throw new IllegalArgumentException(
"The embedding model chosen is asymmetric. To use it, you must declare whether the input is a query or a passage."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error message seems telling user to input a boolean to define it's query or passage, I think you mean user should input either query_prefix or passage_prefix?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the error message to be clearer. What do you think?

Please note, that the parameter is not query_prefix or passage_prefix but rather QUERY or PARAMETER. The prefixes are defined on model registration, not usage.

);
}

return false;
}

private TextDocsInputDataSet addPrefixesToData(AsymmetricTextEmbeddingParameters mlParams, TextDocsInputDataSet inputDataSet) {
// Asymmetric embedding models typically work with "mini-prompts" that prime the model to embed a text
// as a query or as a passage. Here we apply the prompt as defined in the model configuration. We default
// to passage embedding.
br3no marked this conversation as resolved.
Show resolved Hide resolved
TextEmbeddingModelConfig modelConfig = (TextEmbeddingModelConfig) this.modelConfig;
String prefix = mlParams.getEmbeddingContentType() == EmbeddingContentType.QUERY
? modelConfig.getQueryPrefix()
: modelConfig.getPassagePrefix();
if (prefix != null) {
List<String> prefixedDocs = inputDataSet.getDocs().stream().map(s -> prefix + s).collect(Collectors.toList());
return TextDocsInputDataSet.builder().docs(prefixedDocs).build();
}
return inputDataSet;

Check warning on line 92 in ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/TextEmbeddingModel.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/TextEmbeddingModel.java#L92

Added line #L92 was not covered by tests
}

public void warmUp(Predictor predictor, String modelId, MLModelConfig modelConfig) throws TranslateException {
TextEmbeddingModelConfig textEmbeddingModelConfig = (TextEmbeddingModelConfig) modelConfig;
String warmUpSentence = "warm up sentence";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.ml.engine.algorithms.text_embedding;

import static org.opensearch.core.xcontent.XContentParserUtils.ensureExpectedToken;

import java.io.IOException;
import java.util.Locale;

import org.opensearch.core.ParseField;
import org.opensearch.core.common.io.stream.StreamInput;
import org.opensearch.core.common.io.stream.StreamOutput;
import org.opensearch.core.xcontent.NamedXContentRegistry;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.core.xcontent.XContentParser;
import org.opensearch.ml.common.FunctionName;
import org.opensearch.ml.common.annotation.MLAlgoParameter;
import org.opensearch.ml.common.input.parameter.MLAlgoParams;

import lombok.Builder;
import lombok.Data;

/**
* This class defines the modes of operation of an asymmetric text embedding algorithm. The algorithm can be used to embed either a query or a passage.
*/
@Data
@MLAlgoParameter(algorithms = { FunctionName.TEXT_EMBEDDING })
public class AsymmetricTextEmbeddingParameters implements MLAlgoParams {

public enum EmbeddingContentType {
QUERY,
PASSAGE
}

public static final String PARSE_FIELD_NAME = FunctionName.TEXT_EMBEDDING.name();
public static final NamedXContentRegistry.Entry XCONTENT_REGISTRY = new NamedXContentRegistry.Entry(
MLAlgoParams.class,
new ParseField(PARSE_FIELD_NAME),
it -> parse(it)

Check warning on line 42 in ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java#L42

Added line #L42 was not covered by tests
);

@Builder(toBuilder = true)
public AsymmetricTextEmbeddingParameters(EmbeddingContentType embeddingContentType) {
this.embeddingContentType = embeddingContentType;
}

public AsymmetricTextEmbeddingParameters(StreamInput in) throws IOException {
this.embeddingContentType = EmbeddingContentType.valueOf(in.readOptionalString());
}

Check warning on line 52 in ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java#L50-L52

Added lines #L50 - L52 were not covered by tests

public static MLAlgoParams parse(XContentParser parser) throws IOException {
EmbeddingContentType embeddingContentType = null;

Check warning on line 55 in ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java#L55

Added line #L55 was not covered by tests

ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.currentToken(), parser);

Check warning on line 57 in ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java#L57

Added line #L57 was not covered by tests
while (parser.nextToken() != XContentParser.Token.END_OBJECT) {
String fieldName = parser.currentName();
parser.nextToken();

Check warning on line 60 in ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java#L59-L60

Added lines #L59 - L60 were not covered by tests

switch (fieldName) {
case EMBEDDING_CONTENT_TYPE_FIELD:
String contentType = parser.text();
embeddingContentType = EmbeddingContentType.valueOf(contentType.toUpperCase(Locale.ROOT));
break;

Check warning on line 66 in ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java#L64-L66

Added lines #L64 - L66 were not covered by tests
default:
parser.skipChildren();

Check warning on line 68 in ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java#L68

Added line #L68 was not covered by tests
break;
}
}
return new AsymmetricTextEmbeddingParameters(embeddingContentType);

Check warning on line 72 in ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java#L71-L72

Added lines #L71 - L72 were not covered by tests
}

public static final String EMBEDDING_CONTENT_TYPE_FIELD = "content_type";

// The type of the content to be embedded
private EmbeddingContentType embeddingContentType;

@Override
public int getVersion() {
return 1;

Check warning on line 82 in ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java#L82

Added line #L82 was not covered by tests
}

@Override
public String getWriteableName() {
return PARSE_FIELD_NAME;

Check warning on line 87 in ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java#L87

Added line #L87 was not covered by tests
}

@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeOptionalString(embeddingContentType.name());
}

Check warning on line 93 in ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java#L92-L93

Added lines #L92 - L93 were not covered by tests

@Override
public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params) throws IOException {
xContentBuilder.startObject();

Check warning on line 97 in ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java#L97

Added line #L97 was not covered by tests
if (embeddingContentType != null) {
xContentBuilder.field(EMBEDDING_CONTENT_TYPE_FIELD, embeddingContentType.name());

Check warning on line 99 in ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java#L99

Added line #L99 was not covered by tests
}
xContentBuilder.endObject();
return xContentBuilder;

Check warning on line 102 in ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java

View check run for this annotation

Codecov / codecov/patch

ml-algorithms/src/main/java/org/opensearch/ml/engine/algorithms/text_embedding/AsymmetricTextEmbeddingParameters.java#L101-L102

Added lines #L101 - L102 were not covered by tests
}

public EmbeddingContentType getEmbeddingContentType() {
return embeddingContentType;
}
}
Loading
Loading