mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-10 22:41:41 +00:00
fix(vertex_ai): keep all embeddings in multimodal embedding response
An instance that carries both `text` and `image` makes Vertex return `textEmbedding` and `imageEmbedding` in the same prediction, but transform_embedding_response_to_openai chained the branches with `elif`, so only the first match was emitted and every other embedding was silently dropped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
491eda319c
commit
f22e9b09c4
3 changed files with 51 additions and 4 deletions
|
|
@ -287,14 +287,14 @@ class VertexAIMultimodalEmbeddingConfig(BaseEmbeddingConfig):
|
|||
object="embedding",
|
||||
)
|
||||
openai_embeddings.append(openai_embedding_object)
|
||||
elif "imageEmbedding" in _prediction:
|
||||
if "imageEmbedding" in _prediction:
|
||||
openai_embedding_object = Embedding(
|
||||
embedding=_prediction["imageEmbedding"],
|
||||
index=idx,
|
||||
object="embedding",
|
||||
)
|
||||
openai_embeddings.append(openai_embedding_object)
|
||||
elif "videoEmbeddings" in _prediction:
|
||||
if "videoEmbeddings" in _prediction:
|
||||
for video_embedding in _prediction["videoEmbeddings"]:
|
||||
openai_embedding_object = Embedding(
|
||||
embedding=video_embedding["embedding"],
|
||||
|
|
|
|||
|
|
@ -1880,8 +1880,9 @@ async def test_vertexai_multimodal_embedding():
|
|||
|
||||
assert args_to_vertexai == expected_payload
|
||||
assert response.model == "multimodalembedding@001"
|
||||
assert len(response.data) == 1
|
||||
response_data = response.data[0]
|
||||
assert len(response.data) == 2
|
||||
assert response.data[0]["embedding"] == [0.4, 0.5, 0.6]
|
||||
assert response.data[1]["embedding"] == [0.1, 0.2, 0.3]
|
||||
|
||||
# Optional: Print for debugging
|
||||
print("Arguments passed to Vertex AI:", args_to_vertexai)
|
||||
|
|
|
|||
|
|
@ -179,3 +179,49 @@ class TestVertexMultimodalEmbedding:
|
|||
headers={},
|
||||
)
|
||||
assert "parameters" not in request
|
||||
|
||||
def test_response_keeps_both_text_and_image_embeddings(self):
|
||||
predictions = {
|
||||
"predictions": [
|
||||
{
|
||||
"textEmbedding": [0.4, 0.5, 0.6],
|
||||
"imageEmbedding": [0.1, 0.2, 0.3],
|
||||
}
|
||||
]
|
||||
}
|
||||
result = self.config.transform_embedding_response_to_openai(predictions)
|
||||
assert [e["embedding"] for e in result] == [[0.4, 0.5, 0.6], [0.1, 0.2, 0.3]]
|
||||
assert [e["index"] for e in result] == [0, 0]
|
||||
|
||||
def test_response_keeps_text_and_video_embeddings(self):
|
||||
predictions = {
|
||||
"predictions": [
|
||||
{
|
||||
"textEmbedding": [0.4, 0.5, 0.6],
|
||||
"videoEmbeddings": [
|
||||
{
|
||||
"startOffsetSec": 0,
|
||||
"endOffsetSec": 5,
|
||||
"embedding": [0.7, 0.8, 0.9],
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
result = self.config.transform_embedding_response_to_openai(predictions)
|
||||
assert [e["embedding"] for e in result] == [[0.4, 0.5, 0.6], [0.7, 0.8, 0.9]]
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"prediction, expected",
|
||||
[
|
||||
({"textEmbedding": [0.1, 0.2]}, [[0.1, 0.2]]),
|
||||
({"imageEmbedding": [0.3, 0.4]}, [[0.3, 0.4]]),
|
||||
(
|
||||
{"videoEmbeddings": [{"startOffsetSec": 0, "endOffsetSec": 5, "embedding": [0.5]}]},
|
||||
[[0.5]],
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_response_single_modality_unchanged(self, prediction, expected):
|
||||
result = self.config.transform_embedding_response_to_openai({"predictions": [prediction]})
|
||||
assert [e["embedding"] for e in result] == expected
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue