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

[ML] Passing input type through to cohere request #104781

Merged
merged 8 commits into from
Jan 30, 2024

Conversation

jonathan-buttner
Copy link
Contributor

@jonathan-buttner jonathan-buttner commented Jan 25, 2024

This PR passes the input type from the initial request through to cohere.

When a REST request is made externally to the inference API for inference, the input_type is set to UNSPECIFIED. This is to indicate that we don't know if it is for ingest or search. If a user performs a search request (e.g. via a knn search) then the input_type field of the request to elasticsearch will internally be set to SEARCH. If a user ingests some documents via an inference ingest processor then the the internal requests to the inferences service will have the input_type field set to INGEST.

If the input_type field is passed via the inference request it will always override what is stored in the task settings of the model and the task settings passed in as part of the request, as long as the input_type is valid (currently that means any value other than UNSPECIFIED).

Testing

Setup the cohere service


PUT _inference/text_embedding/cohere
{
    "service": "cohere",
    "service_settings": {
        "api_key": "<api key>",
        "max_input_tokens": 20000,
        "model": "embed-english-light-v3.0",
        "embedding_type": "int8"
    },
    "task_settings": {
    }
}

Send and ingest request

POST _inference/text_embedding/cohere
{
  "input": ["hello"],
  "task_settings": {
    "input_type": "ingest"
  }
}

Ensure that the ingest pipeline ingest request results in the same values. This should set input_type to ingest

PUT _ingest/pipeline/cohere
{
  "processors": [
    {
      "inference": {
        "model_id": "cohere",
        "input_output": [
            {
                "input_field": "column2",
                "output_field": "text_embedding"
            }
        ]
      }
    }
  ]
}


POST _ingest/pipeline/cohere/_simulate
{
  "docs": [
    {
      "_index": "msmarco-passage-collection",
      "_id": "4760000",
      "_source": {
        "id": "4760000",
        "column2": "hello"
      }
    }
  ]
}

@jonathan-buttner jonathan-buttner added :ml Machine learning Team:ML Meta label for the ML team cloud-deploy Publish cloud docker image for Cloud-First-Testing v8.13.0 labels Jan 25, 2024

public static String NAME = "input_type";
SEARCH,
UNSPECIFIED;
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 open to other names for this. Maybe UNKNOWN?

Copy link
Member

Choose a reason for hiding this comment

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

UNSPECIFIED is what it is, it's a good name

@@ -140,11 +141,22 @@ public void writeTo(StreamOutput out) throws IOException {
out.writeString(input.get(0));
}
out.writeGenericMap(taskSettings);
// in version ML_INFERENCE_REQUEST_INPUT_TYPE_ADDED the input type enum was added, so we only want to write the enum if we're
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Double check this code.

Copy link
Member

Choose a reason for hiding this comment

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

LGTM

@@ -29,14 +31,6 @@ public record CohereEmbeddingsRequestEntity(

private static final String SEARCH_DOCUMENT = "search_document";
private static final String SEARCH_QUERY = "search_query";
/**
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 going to go with a switch case here instead because that seems a little cleaner now that we have a value we don't want to allow.

@@ -174,6 +176,6 @@ private CohereEmbeddingsModel updateModelWithEmbeddingDetails(CohereEmbeddingsMo

@Override
public TransportVersion getMinimalSupportedVersion() {
return TransportVersions.ML_INFERENCE_COHERE_EMBEDDINGS_ADDED;
return TransportVersions.ML_INFERENCE_REQUEST_INPUT_TYPE_UNSPECIFIED_ADDED;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Bumping the cohere service min version just in case.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not quite sure what the implication of increasing the minimal supported version of a class is. Do you know what happens when we change this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, it means that if a cluster has nodes with different versions and one of the nodes is on ML_INFERENCE_REQUEST_INPUT_TYPE_UNSPECIFIED_ADDED and a user attempts to create the cohere entity, it will fail until all the nodes are on the version ML_INFERENCE_REQUEST_INPUT_TYPE_UNSPECIFIED_ADDED. Essentially users will have to wait until an upgrade process is complete before creating this inference entity.

*/
public record CohereEmbeddingsTaskSettings(@Nullable InputType inputType, @Nullable CohereTruncation truncation) implements TaskSettings {
public class CohereEmbeddingsTaskSettings implements TaskSettings {
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 switched this to a class because I thought we'd need to do some if-blocks for the transport version. Turns out I don't think we need to but double check me here.

return;
}

assert VALID_INPUT_VALUES_LIST.contains(inputType) : invalidInputTypeMessage(inputType);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We shouldn't allow storing the UNSPECIFIED value or reading it from the task_settings.

Copy link
Member

Choose a reason for hiding this comment

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

For non-test runtime validations, we should be throwing an exception rather than using assert, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should be a programmatic error if UNSPECIFIED is passed to this class in the constructor. I'm happy to make it an exception if that's people's preference. From a quick search, seems like there are examples of assertions similar to this at least in the ml plugin 🤷‍♂️

@@ -290,11 +318,11 @@ public void testGetEmbeddingSize_ReturnsError_WhenTextEmbeddingResults_IsEmpty()

doAnswer(invocation -> {
@SuppressWarnings("unchecked")
ActionListener<InferenceServiceResults> listener = (ActionListener<InferenceServiceResults>) invocation.getArguments()[3];
ActionListener<InferenceServiceResults> listener = (ActionListener<InferenceServiceResults>) invocation.getArguments()[4];
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We're passing another parameter for the getEmbeddingSize function to do inference so incrementing this to get the listener correctly.


return new CohereEmbeddingsTaskSettings(inputTypeToUse, truncationToUse);
}

/**
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The primary functionality on how to handle the passed in input type based on the current task settings state.

@jonathan-buttner jonathan-buttner marked this pull request as ready for review January 26, 2024 17:18
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/ml-core (Team:ML)

Copy link
Member

@maxhniebergall maxhniebergall left a comment

Choose a reason for hiding this comment

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

Overall looks good, but I have a few concerns

@@ -140,11 +141,22 @@ public void writeTo(StreamOutput out) throws IOException {
out.writeString(input.get(0));
}
out.writeGenericMap(taskSettings);
// in version ML_INFERENCE_REQUEST_INPUT_TYPE_ADDED the input type enum was added, so we only want to write the enum if we're
Copy link
Member

Choose a reason for hiding this comment

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

LGTM

@@ -203,7 +215,7 @@ public Builder setTaskSettings(Map<String, Object> taskSettings) {
}

public Request build() {
return new Request(taskType, inferenceEntityId, input, taskSettings, InputType.INGEST);
return new Request(taskType, inferenceEntityId, input, taskSettings, InputType.UNSPECIFIED);
Copy link
Member

Choose a reason for hiding this comment

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

why do we directly use UNSPECIFIED in this constructor?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. It'd probably be clearer if we add a setter on the builder. Currently the builder is only used in the rest code path. We don't expose the input type parameter to rest requests (only internal requests) so it'll always be unspecified.

@@ -174,6 +176,6 @@ private CohereEmbeddingsModel updateModelWithEmbeddingDetails(CohereEmbeddingsMo

@Override
public TransportVersion getMinimalSupportedVersion() {
return TransportVersions.ML_INFERENCE_COHERE_EMBEDDINGS_ADDED;
return TransportVersions.ML_INFERENCE_REQUEST_INPUT_TYPE_UNSPECIFIED_ADDED;
Copy link
Member

Choose a reason for hiding this comment

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

I'm not quite sure what the implication of increasing the minimal supported version of a class is. Do you know what happens when we change this?

return;
}

assert VALID_INPUT_VALUES_LIST.contains(inputType) : invalidInputTypeMessage(inputType);
Copy link
Member

Choose a reason for hiding this comment

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

For non-test runtime validations, we should be throwing an exception rather than using assert, right?

if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CohereEmbeddingsTaskSettings that = (CohereEmbeddingsTaskSettings) o;
return inputType == that.inputType && truncation == that.truncation;
Copy link
Member

Choose a reason for hiding this comment

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

can we use object equals here?

Comment on lines 150 to 159
public CohereEmbeddingsTaskSettings overrideWith(CohereEmbeddingsTaskSettings requestTaskSettings) {
var inputTypeToUse = requestTaskSettings.inputType() == null ? inputType : requestTaskSettings.inputType();
var truncationToUse = requestTaskSettings.truncation() == null ? truncation : requestTaskSettings.truncation();
if (requestTaskSettings.equals(EMPTY_SETTINGS)) {
return this;
}

var inputTypeToUse = requestTaskSettings.getInputType() == null ? inputType : requestTaskSettings.getInputType();
var truncationToUse = requestTaskSettings.getTruncation() == null ? truncation : requestTaskSettings.getTruncation();

return new CohereEmbeddingsTaskSettings(inputTypeToUse, truncationToUse);
}
Copy link
Member

Choose a reason for hiding this comment

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

Is this "overrideWith" method an instance of some type of common pattern? I've never seen this before and I find its behaviour with regards to object referencing to be unintuitive. Its weird to me that an object would have a method which takes an instance of the same class and creates a whole new instance of the same class with the copied attributes.

I suppose this is required because the attributes of CohereEmbeddingsTaskSettings are final and so this class is effectively immutable, but then, if we already have an instance of CohereEmbeddingsTaskSettings with the required attributes, why do we need to create a copy of it?

Overall, perhaps this function can just be renamed to copy or override clone, or create a copy-constructor?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair points, I'm going to combine the set and overrideWith into a single static method of. I think a static method might be a better fit than a copy constructor because of the logic around figuring out which field to use from each of the objects passed in. Copy constructors seems like a better if we were only passing in a single CohereEmbeddingsTaskSettings object to simply copy every field.

Comment on lines 166 to 167
public CohereEmbeddingsTaskSettings setInputType(InputType inputType) {
if (VALID_INPUT_VALUES_LIST.contains(inputType) == false) {
Copy link
Member

Choose a reason for hiding this comment

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

since CohereEmbeddingsTaskSettings is effectively immutable, I would prefer if we used a verb other than set for methods like this. Really, I think I would prefer to just add a copy constructor with InputType as a second parameter.

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'll collapse this into a static method that handles the input type and overridden fields from the request since we always want to do both at the same time I believe.

@@ -135,4 +139,76 @@ protected InferenceAction.Request mutateInstance(InferenceAction.Request instanc
default -> throw new UnsupportedOperationException();
};
}

@Override
protected InferenceAction.Request mutateInstanceForVersion(InferenceAction.Request instance, TransportVersion version) {
Copy link
Member

Choose a reason for hiding this comment

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

I'm not exactly sure how the mutateInstanceForVersion function is supposed to work, but I am a bit confused.

Why do we use UNSPECIFIED in the first two cases, since it was just added now?

Why don't we have any cases after ML_INFERENCE_REQUEST_INPUT_TYPE_UNSPECIFIED_ADDED?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah the mutate backwards compatibility stuff always makes me scratch me head 😅

Why do we use UNSPECIFIED in the first two cases, since it was just added now?

The problem here is around backwards compatibility. This function is executed by the parent abstract class when it tests serializing the class from one transport version to another. So for the version INFERENCE_MULTIPLE_INPUTS, the test first generates a random instance (regardless of version, the creation function doesn't take a version, so it'll generate an instance with a random input type). Then the test writes and then reads the instance for version INFERENCE_MULTIPLE_INPUTS. Then it compares the written/read instance with the mutated instance. The reason we want to mutate the original created instance is we need to tell it what the final instance should look like once it was written/read at a specific protocol version.

So for INFERENCE_MULTIPLE_INPUTS this was prior to the InputType being added so when the class's constructor that takes a StreamInput reads the fields off the wire it does not try to read the inputType and instead defaults it to UNSPECIFIED. So the mutate function needs to match that by forcing the inputType to be UNSPECIFIED. That way when the tests do the equals check it'll succeed.

The mutate function is essentially telling the tests what the end result should look like after serializing and deserializing the instance at a particular version.

Why don't we have any cases after ML_INFERENCE_REQUEST_INPUT_TYPE_UNSPECIFIED_ADDED?

We don't need cases after ML_INFERENCE_REQUEST_INPUT_TYPE_UNSPECIFIED_ADDED because the instance will remain the same when serialized and deserialized, so we can just return the same instance that was passed to us. When there is another change to the transport version for that particular class we'll add another if block.

Copy link
Member

@davidkyle davidkyle left a comment

Choose a reason for hiding this comment

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

LGTM


public static String NAME = "input_type";
SEARCH,
UNSPECIFIED;
Copy link
Member

Choose a reason for hiding this comment

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

UNSPECIFIED is what it is, it's a good name

}

return null;
}

private static <T> void validateEnumValue(T enumValue, T[] validValues) {
if (Arrays.asList(validValues).contains(enumValue) == false) {
Copy link
Member

Choose a reason for hiding this comment

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

Can you achieve the same by passing an EnumSet<T> instead of T[] validValues? It would make the lookup easier.

Nit: in the docs a generic enum parameter is referred to as E

https://docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html


public static final String NAME = "cohere_embeddings_task_settings";
public static final CohereEmbeddingsTaskSettings EMPTY_SETTINGS = new CohereEmbeddingsTaskSettings(null, null);
static final String INPUT_TYPE = "input_type";
private static final InputType[] VALID_REQUEST_VALUES = { InputType.INGEST, InputType.SEARCH };
private static final List<InputType> VALID_INPUT_VALUES_LIST = Arrays.asList(VALID_REQUEST_VALUES);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
private static final List<InputType> VALID_INPUT_VALUES_LIST = Arrays.asList(VALID_REQUEST_VALUES);
private static final EnumSet<InputType> VALID_INPUT_VALUES_LIST = EnumSet.of(InputType.INGEST, InputType.SEARCH );

Copy link
Member

@maxhniebergall maxhniebergall left a comment

Choose a reason for hiding this comment

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

LGTM!

@@ -21,6 +21,15 @@

public class OpenAiEmbeddingsModel extends OpenAiModel {

public static OpenAiEmbeddingsModel of(OpenAiEmbeddingsModel model, Map<String, Object> taskSettings) {
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for this change! I think this implementation is much clearer with regards to the object references

@jonathan-buttner jonathan-buttner merged commit 92dd213 into elastic:main Jan 30, 2024
16 checks passed
@jonathan-buttner jonathan-buttner deleted the ml-cohere-input-type branch January 30, 2024 18:46
benwtrent added a commit that referenced this pull request Jan 31, 2024
* Change release version lookup to an instance method (#104902)

* Upgrade to Lucene 9.9.2 (#104753)

This commit upgrades to Lucene 9.9.2.

* Improve `CANNOT_REBALANCE_CAN_ALLOCATE` explanation (#104904)

Clarify that in this situation there is a rebalancing move that would
improve the cluster balance, but there's some reason why rebalancing is
not happening. Also points at the `can_rebalance_cluster_decisions` as
well as the node-by-node decisions since the action needed could be
described in either place.

* Get from translog fails with large dense_vector (#104700)

This change fixes the engine to apply the current codec when retrieving documents from the translog.
We need to use the same codec than the main index in order to ensure that all the source data is indexable.
The internal codec treats some fields differently than the default one, for instance dense_vectors are limited to 1024 dimensions.
This PR ensures that these customizations are applied when indexing document for translog retrieval.

Closes #104639

Co-authored-by: Elastic Machine <[email protected]>

* [Connector Secrets] Add delete API endpoint (#104815)

* Add DELETE endpoint for /_connector/_secret/{id}
* Add endpoint to write_connector_secrets cluster privilege

* Merge Aggregations into InternalAggregations (#104896)

This commit merges Aggregations into InternalAggregations in order to remove the unnecessary hierarchy.

* [Profiling] Simplify cost calculation (#104816)

* [Profiling] Add the number of cores to HostMetadata

* Update AWS pricelist (remove cost_factor, add usd_per_hour)

* Switch cost calculations from 'cost_factor' to 'usd_per_hour'

* Remove superfluous CostEntry.toXContent()

* Check for Number type in CostEntry.fromSource()

* Add comment

* Retry get_from_translog during relocations (#104579)

During a promotable relocation, a `get_from_translog` sent by the
unpromotable  shard to handle a real-time get might encounter
`ShardNotFoundException` or  `IndexNotFoundException`. In these cases,
we should retry.

This is just for `GET`. I'll open a second PR for `mGET`.  The relevant
IT is in the  Stateless PR.

Relates ES-5727

* indicating fix for 8.12.1 for int8_hnsw (#104912)

* Removing the assumption from some tests that the request builder's request() method always returns the same object (#104881)

* [DOCS] Adds get setting and update settings asciidoc files to security API index (#104916)

* [DOCS] Adds get setting and update settings asciidoc files to security API index.

* [DOCS] Fixes references in docs.

* Reuse APMMeterService of APMTelemetryProvider (#104906)

* Mute more tests that tend to leak searchhits (#104922)

* ESQL: Fix SearchStats#count(String) to count values not rows (#104891)

SearchStats#count incorrectly counts the number of documents (or rows)
 in which a document appears instead of the actual number of values.
This PR fixes this by looking at the term frequency instead of the doc
 count.

Fix #104795

* Adding request source for cohere (#104926)

* Fixing a broken javadoc comment in ReindexDocumentationIT (#104930)

This fixes a javadoc comment that was broken by #104881

* Fix enabling / disabling of APM agent "recording" in APMAgentSettings (#104324)

* Add `type` parameter support, for sorting, to the Query API Key API (#104625)

This adds support for the `type` parameter, for sorting, to the Query API key API.
The type for an API Key can currently be either `rest` or `cross_cluster`.
This was overlooked in #103695 when support for the `type` parameter
was first introduced only for querying.

* Apply publish plugin to es-opensaml-security-api project (#104933)

* Support `match` for the Query API Key API (#104594)

This adds support for the `match` query type to the Query API key Information API.
Note that since string values associated to API Keys are mapped as `keywords`,
a `match` query with no analyzer parameter is effectively equivalent to a `term` query
for such fields (e.g. `name`, `username`, `realm_name`).

Relates: #101691

* [Connectors API] Relax strict response parsing for get/list operations (#104909)

* Limit concurrent shards per node for ESQL (#104832)

Today, we allow ESQL to execute against an unlimited number of shards 
concurrently on each node. This can lead to cases where we open and hold
too many shards, equivalent to opening too many file descriptors or
using too much memory for FieldInfos in ValuesSourceReaderOperator.

This change limits the number of concurrent shards to 10 per node. This 
number was chosen based on the _search API, which limits it to 5.
Besides the primary reason stated above, this change has other
implications:

We might execute fewer shards for queries with LIMIT only, leading to 
scenarios where we execute only some high-priority shards then stop. 
For now, we don't have a partial reduce at the node level, but if we
introduce one in the future, it might not be as efficient as executing
all shards at the same time.  There are pauses between batches because
batches are executed sequentially one by one.  However, I believe the
performance of queries executing against many shards (after can_match)
is less important than resiliency.

Closes #103666

* [DOCS] Support for nested functions in ES|QL STATS...BY (#104788)

* Document nested expressions for stats

* More docs

* Apply suggestions from review

- count-distinct.asciidoc
  - Content restructured, moving the section about approximate counts to end of doc.

- count.asciidoc
  - Clarified that omitting the `expression` parameter in `COUNT` is equivalent to `COUNT(*)`, which counts the number of rows.

- percentile.asciidoc
  - Moved the note about `PERCENTILE` being approximate and non-deterministic to end of doc.

- stats.asciidoc
  - Clarified the `STATS` command
  -  Added a note indicating that individual `null` values are skipped during aggregation

* Comment out mentioning a buggy behavior

* Update sum with inline function example, update test file

* Fix typo

* Delete line

* Simplify wording

* Fix conflict fix typo

---------

Co-authored-by: Liam Thompson <[email protected]>
Co-authored-by: Liam Thompson <[email protected]>

* [ML] Passing input type through to cohere request (#104781)

* Pushing input type through to cohere request

* switching logic to allow request to always override

* Fixing failure

* Removing getModelId calls

* Addressing feedback

* Switching to enumset

* [Transform] Unmute 2 remaining continuous tests: HistogramGroupByIT and TermsGroupByIT (#104898)

* Adding ActionRequestLazyBuilder implementation of RequestBuilder (#104927)

This introduces a second implementation of RequestBuilder (#104778). As opposed
to ActionRequestBuilder, ActionRequestLazyBuilder does not create its request
until the request() method is called, and does not hold onto that request (so each
call to request() gets a new request instance).
This PR also updates BulkRequestBuilder to inherit from ActionRequestLazyBuilder
as an example of its use.

* Update versions to skip after backport to 8.12 (#104953)

* Update/Cleanup references to old tracing.apm.* legacy settings in favor of the telemetry.* settings (#104917)

* Exclude tests that do not work in a mixed cluster scenario (#104935)

* ES|QL: Improve type validation in aggs for UNSIGNED_LONG and better support for VERSION (#104911)

* [Connector API] Make update configuration action non-additive (#104615)

* Save allocating enum values array in two hot spots (#104952)

Our readEnum code instantiates/clones enum value arrays on read.
Normally, this doesn't matter much but the two spots adjusted here are
visibly hot during bulk indexing, causing GBs of allocations during e.g.
the http_logs indexing run.

* ESQL: Correct out-of-range filter pushdowns (#99961)

Fix pushed down filters for binary comparisons that compare a
byte/short/int/long with an out of range value, like
WHERE some_int_field < 1E300.

* [DOCS] Dense vector element type should be float for OpenAI (#104966)

* Fix test assertions (#104963)

* Move functions that generate lucene geometries under a utility class (#104928)

We have functions that generate lucene geometries scattered in different places of the code. This commit moves 
everything under a utility class.

* fixing index versions

---------

Co-authored-by: Simon Cooper <[email protected]>
Co-authored-by: Chris Hegarty <[email protected]>
Co-authored-by: David Turner <[email protected]>
Co-authored-by: Jim Ferenczi <[email protected]>
Co-authored-by: Elastic Machine <[email protected]>
Co-authored-by: Navarone Feekery <[email protected]>
Co-authored-by: Ignacio Vera <[email protected]>
Co-authored-by: Tim Rühsen <[email protected]>
Co-authored-by: Pooya Salehi <[email protected]>
Co-authored-by: Keith Massey <[email protected]>
Co-authored-by: István Zoltán Szabó <[email protected]>
Co-authored-by: Moritz Mack <[email protected]>
Co-authored-by: Costin Leau <[email protected]>
Co-authored-by: Jonathan Buttner <[email protected]>
Co-authored-by: Albert Zaharovits <[email protected]>
Co-authored-by: Mark Vieira <[email protected]>
Co-authored-by: Jedr Blaszyk <[email protected]>
Co-authored-by: Nhat Nguyen <[email protected]>
Co-authored-by: Abdon Pijpelink <[email protected]>
Co-authored-by: Liam Thompson <[email protected]>
Co-authored-by: Liam Thompson <[email protected]>
Co-authored-by: Przemysław Witek <[email protected]>
Co-authored-by: Joe Gallo <[email protected]>
Co-authored-by: Lorenzo Dematté <[email protected]>
Co-authored-by: Luigi Dell'Aquila <[email protected]>
Co-authored-by: Armin Braun <[email protected]>
Co-authored-by: Alexander Spies <[email protected]>
Co-authored-by: David Kyle <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cloud-deploy Publish cloud docker image for Cloud-First-Testing :ml Machine learning >non-issue Team:ML Meta label for the ML team v8.13.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants