Vectorizers#

In this notebook, we will show how to use RedisVL to create embeddings using the built-in text embedding vectorizers. Today RedisVL supports:

  1. OpenAI

  2. HuggingFace

  3. Vertex AI

  4. Cohere

  5. Mistral AI

  6. Amazon Bedrock

  7. Bringing your own vectorizer

  8. VoyageAI

Before running this notebook, be sure to

  1. Have installed redisvl and have that environment active for this notebook.

  2. Have a running Redis Stack instance with RediSearch > 2.4 active.

For example, you can run Redis Stack locally with Docker:

docker run -d -p 6379:6379 -p 8001:8001 redis/redis-stack:latest

This will run Redis on port 6379 and RedisInsight at http://localhost:8001.

# import necessary modules
import os

Creating Text Embeddings#

This example will show how to create an embedding from 3 simple sentences with a number of different text vectorizers in RedisVL.

  • “That is a happy dog”

  • “That is a happy person”

  • “Today is a nice day”

OpenAI#

The OpenAITextVectorizer makes it simple to use RedisVL with the embeddings models at OpenAI. For this you will need to install openai.

pip install openai
import getpass

# setup the API Key
api_key = os.environ.get("OPENAI_API_KEY") or getpass.getpass("Enter your OpenAI API key: ")
from redisvl.utils.vectorize import OpenAITextVectorizer

# create a vectorizer
oai = OpenAITextVectorizer(
    model="text-embedding-ada-002",
    api_config={"api_key": api_key},
)

test = oai.embed("This is a test sentence.")
print("Vector dimensions: ", len(test))
test[:10]
Vector dimensions:  1536
[-0.0010508307022973895,
 -0.0031670420430600643,
 0.0023781107738614082,
 -0.004539588466286659,
 -0.010320774279534817,
 0.012868634425103664,
 -0.0054513863287866116,
 -0.002984359161928296,
 -0.0072814482264220715,
 -0.033704183995723724]
# Create many embeddings at once
sentences = [
    "That is a happy dog",
    "That is a happy person",
    "Today is a sunny day"
]

embeddings = oai.embed_many(sentences)
embeddings[0][:10]
[-0.01749197021126747,
 -5.238811718299985e-05,
 0.0013331907102838159,
 -0.025576923042535782,
 -0.019907286390662193,
 0.016106342896819115,
 -0.003756451653316617,
 0.0009971122490242124,
 0.006661186460405588,
 -0.024954024702310562]
# openai also supports asyncronous requests, which we can use to speed up the vectorization process.
embeddings = await oai.aembed_many(sentences)
print("Number of Embeddings:", len(embeddings))
Number of Embeddings: 3

Azure OpenAI#

The AzureOpenAITextVectorizer is a variation of the OpenAI vectorizer that calls OpenAI models within Azure. If you’ve already installed openai, then you’re ready to use Azure OpenAI.

The only practical difference between OpenAI and Azure OpenAI is the variables required to call the API.

# additionally to the API Key, setup the API endpoint and version
api_key = os.environ.get("AZURE_OPENAI_API_KEY") or getpass.getpass("Enter your AzureOpenAI API key: ")
api_version = os.environ.get("OPENAI_API_VERSION") or getpass.getpass("Enter your AzureOpenAI API version: ")
azure_endpoint = os.environ.get("AZURE_OPENAI_ENDPOINT") or getpass.getpass("Enter your AzureOpenAI API endpoint: ")
deployment_name = os.environ.get("AZURE_OPENAI_DEPLOYMENT_NAME", "text-embedding-ada-002")
from redisvl.utils.vectorize import AzureOpenAITextVectorizer

# create a vectorizer
az_oai = AzureOpenAITextVectorizer(
    model=deployment_name, # Must be your CUSTOM deployment name
    api_config={
        "api_key": api_key,
        "api_version": api_version,
        "azure_endpoint": azure_endpoint
    },
)

test = az_oai.embed("This is a test sentence.")
print("Vector dimensions: ", len(test))
test[:10]
Vector dimensions:  1536
[-0.0010088568087667227,
 -0.003142790636047721,
 0.0024922797456383705,
 -0.004522906616330147,
 -0.010369433090090752,
 0.012739036232233047,
 -0.005365503951907158,
 -0.0029668458737432957,
 -0.007141091860830784,
 -0.03383301943540573]
# Just like OpenAI, AzureOpenAI supports batching embeddings and asynchronous requests.
sentences = [
    "That is a happy dog",
    "That is a happy person",
    "Today is a sunny day"
]

embeddings = await az_oai.aembed_many(sentences)
embeddings[0][:10]
[-0.017460526898503304,
 -6.895032856846228e-05,
 0.0013909287517890334,
 -0.025688467547297478,
 -0.019813183695077896,
 0.016087085008621216,
 -0.003729278687387705,
 0.0009211922879330814,
 0.006606514099985361,
 -0.025128915905952454]

Huggingface#

Huggingface is a popular NLP platform that has a number of pre-trained models you can use off the shelf. RedisVL supports using Huggingface “Sentence Transformers” to create embeddings from text. To use Huggingface, you will need to install the sentence-transformers library.

pip install sentence-transformers
os.environ["TOKENIZERS_PARALLELISM"] = "false"
from redisvl.utils.vectorize import HFTextVectorizer


# create a vectorizer
# choose your model from the huggingface website
hf = HFTextVectorizer(model="sentence-transformers/all-mpnet-base-v2")

# embed a sentence
test = hf.embed("This is a test sentence.")
test[:10]
[0.0003780885017476976,
 -0.05080340430140495,
 -0.035147231072187424,
 -0.02325103059411049,
 -0.04415831342339516,
 0.02048780582845211,
 0.0014618589775636792,
 0.03126184269785881,
 0.05605152249336243,
 0.018815429881215096]
# You can also create many embeddings at once
embeddings = hf.embed_many(sentences, as_buffer=True, dtype="float32")

VertexAI#

VertexAI is GCP’s fully-featured AI platform including a number of pretrained LLMs. RedisVL supports using VertexAI to create embeddings from these models. To use VertexAI, you will first need to install the google-cloud-aiplatform library.

pip install google-cloud-aiplatform>=1.26
  1. Then you need to gain access to a Google Cloud Project and provide access to credentials. This is accomplished by setting the GOOGLE_APPLICATION_CREDENTIALS environment variable pointing to the path of a JSON key file downloaded from your service account on GCP.

  2. Lastly, you need to find your project ID and geographic region for VertexAI.

Make sure the following env vars are set:

GOOGLE_APPLICATION_CREDENTIALS=<path to your gcp JSON creds>
GCP_PROJECT_ID=<your gcp project id>
GCP_LOCATION=<your gcp geo region for vertex ai>
from redisvl.utils.vectorize import VertexAITextVectorizer


# create a vectorizer
vtx = VertexAITextVectorizer(api_config={
    "project_id": os.environ.get("GCP_PROJECT_ID") or getpass.getpass("Enter your GCP Project ID: "),
    "location": os.environ.get("GCP_LOCATION") or getpass.getpass("Enter your GCP Location: "),
    "google_application_credentials": os.environ.get("GOOGLE_APPLICATION_CREDENTIALS") or getpass.getpass("Enter your Google App Credentials path: ")
})

# embed a sentence
test = vtx.embed("This is a test sentence.")
test[:10]
[0.04373306408524513,
 -0.05040992051362991,
 -0.011946038343012333,
 -0.043528858572244644,
 0.021510830149054527,
 0.028604144230484962,
 0.014770914800465107,
 -0.01610461436212063,
 -0.0036560404114425182,
 0.013746795244514942]

Cohere#

Cohere allows you to implement language AI into your product. The CohereTextVectorizer makes it simple to use RedisVL with the embeddings models at Cohere. For this you will need to install cohere.

pip install cohere
import getpass
# setup the API Key
api_key = os.environ.get("COHERE_API_KEY") or getpass.getpass("Enter your Cohere API key: ")

Special attention needs to be paid to the input_type parameter for each embed call. For example, for embedding queries, you should set input_type='search_query'; for embedding documents, set input_type='search_document'. See more information here

from redisvl.utils.vectorize import CohereTextVectorizer

# create a vectorizer
co = CohereTextVectorizer(
    model="embed-english-v3.0",
    api_config={"api_key": api_key},
)

# embed a search query
test = co.embed("This is a test sentence.", input_type='search_query')
print("Vector dimensions: ", len(test))
print(test[:10])

# embed a document
test = co.embed("This is a test sentence.", input_type='search_document')
print("Vector dimensions: ", len(test))
print(test[:10])
Vector dimensions:  1024
[-0.010856628, -0.019683838, -0.0062179565, 0.003545761, -0.047943115, 0.0009365082, -0.005924225, 0.016174316, -0.03289795, 0.049194336]
Vector dimensions:  1024
[-0.009712219, -0.016036987, 2.8073788e-05, -0.022491455, -0.041259766, 0.002281189, -0.033294678, -0.00057029724, -0.026260376, 0.0579834]

Learn more about using RedisVL and Cohere together through this dedicated user guide.

VoyageAI#

VoyageAI allows you to implement language AI into your product. The VoyageAITextVectorizer makes it simple to use RedisVL with the embeddings models at VoyageAI. For this you will need to install voyageai.

pip install voyageai
import getpass
# setup the API Key
api_key = os.environ.get("VOYAGE_API_KEY") or getpass.getpass("Enter your VoyageAI API key: ")

Special attention needs to be paid to the input_type parameter for each embed call. For example, for embedding queries, you should set input_type='query'; for embedding documents, set input_type='document'. See more information here

from redisvl.utils.vectorize import VoyageAITextVectorizer

# create a vectorizer
vo = VoyageAITextVectorizer(
    model="voyage-law-2",  # Please check the available models at https://docs.voyageai.com/docs/embeddings
    api_config={"api_key": api_key},
)

# embed a search query
test = vo.embed("This is a test sentence.", input_type='query')
print("Vector dimensions: ", len(test))
print(test[:10])

# embed a document
test = vo.embed("This is a test sentence.", input_type='document')
print("Vector dimensions: ", len(test))
print(test[:10])
Vector dimensions:  1024
[0.015814896672964096, 0.046988241374492645, -0.00518248463049531, -0.05383478105068207, -0.015586535446345806, -0.0837097093462944, 0.03744547441601753, -0.007797810714691877, 0.00717928446829319, 0.06857716292142868]
Vector dimensions:  1024
[0.006725038401782513, 0.01441393606364727, -0.030212024226784706, -0.06782275438308716, -0.021446991711854935, -0.07667966187000275, 0.01804908737540245, -0.015767497941851616, -0.02152789570391178, 0.049741245806217194]

Mistral AI#

Mistral offers LLM and embedding APIs for you to implement into your product. The MistralAITextVectorizer makes it simple to use RedisVL with their embeddings model. You will need to install mistralai.

pip install mistralai
from redisvl.utils.vectorize import MistralAITextVectorizer

mistral = MistralAITextVectorizer()

# embed a sentence using their asyncronous method
test = await mistral.aembed("This is a test sentence.")
print("Vector dimensions: ", len(test))
print(test[:10])
Vector dimensions:  1024
[-0.02801513671875, 0.02532958984375, 0.04278564453125, 0.0185699462890625, 0.041015625, 0.006053924560546875, 0.03607177734375, -0.0030155181884765625, 0.0033893585205078125, -0.01390838623046875]

Amazon Bedrock#

Amazon Bedrock provides fully managed foundation models for text embeddings. Install the required dependencies:

pip install 'redisvl[bedrock]'  # Installs boto3

Configure AWS credentials:#

import os
import getpass

if "AWS_ACCESS_KEY_ID" not in os.environ:
    os.environ["AWS_ACCESS_KEY_ID"] = getpass.getpass("Enter AWS Access Key ID: ")
if "AWS_SECRET_ACCESS_KEY" not in os.environ:
    os.environ["AWS_SECRET_ACCESS_KEY"] = getpass.getpass("Enter AWS Secret Key: ")

os.environ["AWS_REGION"] = "us-east-1"  # Change as needed

Create embeddings:#

from redisvl.utils.vectorize import BedrockTextVectorizer

bedrock = BedrockTextVectorizer(
    model="amazon.titan-embed-text-v2:0"
)

# Single embedding
text = "This is a test sentence."
embedding = bedrock.embed(text)
print(f"Vector dimensions: {len(embedding)}")

# Multiple embeddings
sentences = [
    "That is a happy dog",
    "That is a happy person",
    "Today is a sunny day"
]
embeddings = bedrock.embed_many(sentences)
Vector dimensions: 1024

Custom Vectorizers#

RedisVL supports the use of other vectorizers and provides a class to enable compatibility with any function that generates a vector or vectors from string data

from redisvl.utils.vectorize import CustomTextVectorizer

def generate_embeddings(text_input, **kwargs):
    return [0.101] * 768

custom_vectorizer = CustomTextVectorizer(generate_embeddings)

custom_vectorizer.embed("This is a test sentence.")[:10]
[0.101, 0.101, 0.101, 0.101, 0.101, 0.101, 0.101, 0.101, 0.101, 0.101]

This enables the use of custom vectorizers with other RedisVL components

from redisvl.extensions.llmcache import SemanticCache

cache = SemanticCache(name="custom_cache", vectorizer=custom_vectorizer)

cache.store("this is a test prompt", "this is a test response")
cache.check("this is also a test prompt")
11:04:14 redisvl.index.index INFO   Index already exists, not overwriting.
[{'id': 'llmcache:78bd2446a37a0c6ab62652af9b7e53845145c4471ea83ff9fb4280a528d36bbb',
  'vector_distance': '6.13927841187e-06',
  'prompt': 'this is a test prompt',
  'response': 'this is a test response',
  'prompt_vector': '\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17=\x17='}]

Search with Provider Embeddings#

Now that we’ve created our embeddings, we can use them to search for similar sentences. We will use the same 3 sentences from above and search for similar sentences.

First, we need to create the schema for our index.

Here’s what the schema for the example looks like in yaml for the HuggingFace vectorizer:

version: '0.1.0'

index:
    name: vectorizers
    prefix: doc
    storage_type: hash

fields:
    - name: sentence
      type: text
    - name: embedding
      type: vector
      attrs:
        dims: 768
        algorithm: flat
        distance_metric: cosine
from redisvl.index import SearchIndex

# construct a search index from the schema
index = SearchIndex.from_yaml("./schema.yaml")

# connect to local redis instance
index.connect("redis://localhost:6379")

# create the index (no data yet)
index.create(overwrite=True)
# use the CLI to see the created index
!rvl index listall
20:22:42 [RedisVL] INFO   Indices:
20:22:42 [RedisVL] INFO   1. vectorizers
# load expects an iterable of dictionaries where
# the vector is stored as a bytes buffer
from redisvl.redis.utils import array_to_buffer

data = [{"text": t,
         "embedding": array_to_buffer(v, dtype="float32")}
        for t, v in zip(sentences, embeddings)]

index.load(data)
['doc:17c401b679ce43cb82f3ab2280ad02f2',
 'doc:3fc0502bec434b17a3f06e20824b2e59',
 'doc:199f17b0e5d24dcaa1fd4fb41558150c']
from redisvl.query import VectorQuery

# use the HuggingFace vectorizer again to create a query embedding
query_embedding = hf.embed("That is a happy cat")

query = VectorQuery(
    vector=query_embedding,
    vector_field_name="embedding",
    return_fields=["text"],
    num_results=3
)

results = index.query(query)
for doc in results:
    print(doc["text"], doc["vector_distance"])
That is a happy dog 0.160862326622
That is a happy person 0.273598492146
Today is a sunny day 0.744559407234

Selecting your float data type#

When embedding text as byte arrays RedisVL supports 4 different floating point data types, float16, float32, float64 and bfloat16. Your dtype set for your vectorizer must match what is defined in your search index. If one is not explicitly set the default is float32.

vectorizer = HFTextVectorizer(dtype="float16")

# subsequent calls to embed('', as_buffer=True) and embed_many('', as_buffer=True) will now encode as float16
float16_bytes = vectorizer.embed('test sentence', as_buffer=True)

# you can override this setting on each individual method call
float64_bytes = vectorizer.embed('test sentence', as_buffer=True, dtype="float64")

float16_bytes != float64_bytes
True
# cleanup
index.delete()