You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beam.apache.org by da...@apache.org on 2025/01/15 21:41:07 UTC
(beam) branch master updated: Add Vertex embeddings to RAG package. (#33593)
This is an automated email from the ASF dual-hosted git repository.
damccorm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git
The following commit(s) were added to refs/heads/master by this push:
new b5fa8831c03 Add Vertex embeddings to RAG package. (#33593)
b5fa8831c03 is described below
commit b5fa8831c0369c6dff345ef69ab3becfdc02b650
Author: claudevdm <33...@users.noreply.github.com>
AuthorDate: Wed Jan 15 16:40:59 2025 -0500
Add Vertex embeddings to RAG package. (#33593)
Co-authored-by: Claude <cv...@google.com>
---
.../ml/rag/embeddings/huggingface_test.py | 4 +
.../apache_beam/ml/rag/embeddings/vertex_ai.py | 97 ++++++++++++++++++++++
.../{huggingface_test.py => vertex_ai_test.py} | 34 ++++----
3 files changed, 119 insertions(+), 16 deletions(-)
diff --git a/sdks/python/apache_beam/ml/rag/embeddings/huggingface_test.py b/sdks/python/apache_beam/ml/rag/embeddings/huggingface_test.py
index aa63d13025a..f0b9316dcee 100644
--- a/sdks/python/apache_beam/ml/rag/embeddings/huggingface_test.py
+++ b/sdks/python/apache_beam/ml/rag/embeddings/huggingface_test.py
@@ -16,6 +16,7 @@
"""Tests for apache_beam.ml.rag.embeddings.huggingface."""
+import shutil
import tempfile
import unittest
@@ -73,6 +74,9 @@ class HuggingfaceTextEmbeddingsTest(unittest.TestCase):
})
]
+ def tearDown(self) -> None:
+ shutil.rmtree(self.artifact_location)
+
def test_embedding_pipeline(self):
expected = [
Chunk(
diff --git a/sdks/python/apache_beam/ml/rag/embeddings/vertex_ai.py b/sdks/python/apache_beam/ml/rag/embeddings/vertex_ai.py
new file mode 100644
index 00000000000..c960cd66a2a
--- /dev/null
+++ b/sdks/python/apache_beam/ml/rag/embeddings/vertex_ai.py
@@ -0,0 +1,97 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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
+#
+# http://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.
+
+
+# Vertex AI Python SDK is required for this module.
+# Follow https://cloud.google.com/vertex-ai/docs/python-sdk/use-vertex-ai-python-sdk # pylint: disable=line-too-long
+# to install Vertex AI Python SDK.
+
+"""RAG-specific embedding implementations using Vertex AI models."""
+
+from typing import Optional
+
+from google.auth.credentials import Credentials
+
+import apache_beam as beam
+from apache_beam.ml.inference.base import RunInference
+from apache_beam.ml.rag.embeddings.base import create_rag_adapter
+from apache_beam.ml.rag.types import Chunk
+from apache_beam.ml.transforms.base import EmbeddingsManager
+from apache_beam.ml.transforms.base import _TextEmbeddingHandler
+from apache_beam.ml.transforms.embeddings.vertex_ai import DEFAULT_TASK_TYPE
+from apache_beam.ml.transforms.embeddings.vertex_ai import _VertexAITextEmbeddingHandler
+
+try:
+ import vertexai
+except ImportError:
+ vertexai = None
+
+
+class VertexAITextEmbeddings(EmbeddingsManager):
+ def __init__(
+ self,
+ model_name: str,
+ *,
+ title: Optional[str] = None,
+ task_type: str = DEFAULT_TASK_TYPE,
+ project: Optional[str] = None,
+ location: Optional[str] = None,
+ credentials: Optional[Credentials] = None,
+ **kwargs):
+ """Utilizes Vertex AI text embeddings for semantic search and RAG
+ pipelines.
+
+ Args:
+ model_name: Name of the Vertex AI text embedding model
+ title: Optional title for the text content
+ task_type: Task type for embeddings (default: RETRIEVAL_DOCUMENT)
+ project: GCP project ID
+ location: GCP location
+ credentials: Optional GCP credentials
+ **kwargs: Additional arguments passed to EmbeddingsManager including
+ ModelHandler inference_args.
+ """
+ if not vertexai:
+ raise ImportError(
+ "vertexai is required to use VertexAITextEmbeddings. "
+ "Please install it with `pip install google-cloud-aiplatform`")
+
+ super().__init__(type_adapter=create_rag_adapter(), **kwargs)
+ self.model_name = model_name
+ self.title = title
+ self.task_type = task_type
+ self.project = project
+ self.location = location
+ self.credentials = credentials
+
+ def get_model_handler(self):
+ """Returns model handler configured with RAG adapter."""
+ return _VertexAITextEmbeddingHandler(
+ model_name=self.model_name,
+ title=self.title,
+ task_type=self.task_type,
+ project=self.project,
+ location=self.location,
+ credentials=self.credentials,
+ )
+
+ def get_ptransform_for_processing(
+ self, **kwargs
+ ) -> beam.PTransform[beam.PCollection[Chunk], beam.PCollection[Chunk]]:
+ """Returns PTransform that uses the RAG adapter."""
+ return RunInference(
+ model_handler=_TextEmbeddingHandler(self),
+ inference_args=self.inference_args).with_output_types(Chunk)
diff --git a/sdks/python/apache_beam/ml/rag/embeddings/huggingface_test.py b/sdks/python/apache_beam/ml/rag/embeddings/vertex_ai_test.py
similarity index 78%
copy from sdks/python/apache_beam/ml/rag/embeddings/huggingface_test.py
copy to sdks/python/apache_beam/ml/rag/embeddings/vertex_ai_test.py
index aa63d13025a..4e5ad8046a8 100644
--- a/sdks/python/apache_beam/ml/rag/embeddings/huggingface_test.py
+++ b/sdks/python/apache_beam/ml/rag/embeddings/vertex_ai_test.py
@@ -14,15 +14,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-"""Tests for apache_beam.ml.rag.embeddings.huggingface."""
+"""Tests for apache_beam.ml.rag.embeddings.vertex_ai."""
+import shutil
import tempfile
import unittest
-import pytest
-
import apache_beam as beam
-from apache_beam.ml.rag.embeddings.huggingface import HuggingfaceTextEmbeddings
from apache_beam.ml.rag.types import Chunk
from apache_beam.ml.rag.types import Content
from apache_beam.ml.rag.types import Embedding
@@ -31,12 +29,13 @@ from apache_beam.testing.test_pipeline import TestPipeline
from apache_beam.testing.util import assert_that
from apache_beam.testing.util import equal_to
-# pylint: disable=unused-import
+# pylint: disable=ungrouped-imports
try:
- from sentence_transformers import SentenceTransformer
- SENTENCE_TRANSFORMERS_AVAILABLE = True
+ import vertexai # pylint: disable=unused-import
+ from apache_beam.ml.rag.embeddings.vertex_ai import VertexAITextEmbeddings
+ VERTEX_AI_AVAILABLE = True
except ImportError:
- SENTENCE_TRANSFORMERS_AVAILABLE = False
+ VERTEX_AI_AVAILABLE = False
def chunk_approximately_equals(expected, actual):
@@ -52,12 +51,11 @@ def chunk_approximately_equals(expected, actual):
all(isinstance(x, float) for x in actual.embedding.dense_embedding))
-@pytest.mark.uses_transformers
@unittest.skipIf(
- not SENTENCE_TRANSFORMERS_AVAILABLE, "sentence-transformers not available")
-class HuggingfaceTextEmbeddingsTest(unittest.TestCase):
+ not VERTEX_AI_AVAILABLE, "Vertex AI dependencies not available")
+class VertexAITextEmbeddingsTest(unittest.TestCase):
def setUp(self):
- self.artifact_location = tempfile.mkdtemp(prefix='sentence_transformers_')
+ self.artifact_location = tempfile.mkdtemp(prefix='vertex_ai_')
self.test_chunks = [
Chunk(
content=Content(text="This is a test sentence."),
@@ -73,25 +71,29 @@ class HuggingfaceTextEmbeddingsTest(unittest.TestCase):
})
]
+ def tearDown(self) -> None:
+ shutil.rmtree(self.artifact_location)
+
def test_embedding_pipeline(self):
+ # gecko@002 produces 768-dimensional embeddings
expected = [
Chunk(
id="1",
- embedding=Embedding(dense_embedding=[0.0] * 384),
+ embedding=Embedding(dense_embedding=[0.0] * 768),
metadata={
"source": "test.txt", "language": "en"
},
content=Content(text="This is a test sentence.")),
Chunk(
id="2",
- embedding=Embedding(dense_embedding=[0.0] * 384),
+ embedding=Embedding(dense_embedding=[0.0] * 768),
metadata={
"source": "test.txt", "language": "en"
},
content=Content(text="Another example."))
]
- embedder = HuggingfaceTextEmbeddings(
- model_name="sentence-transformers/all-MiniLM-L6-v2")
+
+ embedder = VertexAITextEmbeddings(model_name="textembedding-gecko@002")
with TestPipeline() as p:
embeddings = (