Condividi tramite


Esercitazione: Eseguire una ricerca di somiglianza vettoriale in incorporamenti di Azure OpenAI usando cache di Azure per Redis

In questa esercitazione si esaminerà un caso d'uso di ricerca di somiglianza vettoriale di base. Si useranno incorporamenti generati dal servizio Azure OpenAI e le funzionalità di ricerca vettoriale predefinite del livello Enterprise di cache di Azure per Redis per eseguire query su un set di dati di film per trovare la corrispondenza più pertinente.

L'esercitazione usa il set di dati Wikipedia Movie Plots che include descrizioni dei tracciati di oltre 35.000 film da Wikipedia che coprono gli anni 1901 e 2017. Il set di dati include un riepilogo del tracciato per ogni film, oltre ai metadati come l'anno in cui è stato rilasciato il film, i director, il cast principale e il genere. Si seguiranno i passaggi dell'esercitazione per generare incorporamenti in base al riepilogo del tracciato e usare gli altri metadati per eseguire query ibride.

In questa esercitazione apprenderai a:

  • Creare un'istanza di cache di Azure per Redis configurata per la ricerca vettoriale
  • Installare Azure OpenAI e altre librerie Python necessarie.
  • Scaricare il set di dati del film e prepararlo per l'analisi.
  • Usare il modello text-embedding-ada-002 (versione 2) per generare incorporamenti.
  • Creare un indice vettoriale in cache di Azure per Redis
  • Usare la somiglianza del coseno per classificare i risultati della ricerca.
  • Usare la funzionalità di query ibrida tramite RediSearch per prefiltrare i dati e rendere la ricerca vettoriale ancora più potente.

Importante

Questa esercitazione illustra come creare un notebook di Jupyter. È possibile seguire questa esercitazione con un file di codice Python (.py) e ottenere risultati simili , ma sarà necessario aggiungere tutti i blocchi di codice in questa esercitazione .py ed eseguire una volta per visualizzare i risultati. In altre parole, Jupyter Notebooks fornisce risultati intermedi durante l'esecuzione delle celle, ma questo non è il comportamento previsto quando si lavora in un file di codice Python.

Importante

Se si vuole seguire la procedura in un notebook jupyter completato, scaricare invece il file del notebook jupyter denominato tutorial.ipynb e salvarlo nella nuova cartella redis-vector.

Prerequisiti

  • Una sottoscrizione di Azure: creare un account gratuitamente
  • Accesso concesso ad Azure OpenAI nella sottoscrizione di Azure attualmente desiderata, è necessario richiedere l'accesso ad Azure OpenAI. È possibile richiedere l'accesso a OpenAI di Azure completando il modulo all'indirizzo https://aka.ms/oai/access.
  • Python 3.7.1 o versione successiva
  • Notebook di Jupyter (facoltativo)
  • Una risorsa OpenAI di Azure con il modello text-embedding-ada-002 (versione 2) distribuito. Questo modello è attualmente disponibile solo in determinate aree. Vedere la guida alla distribuzione delle risorse per istruzioni su come distribuire il modello.

Creare un'istanza di cache di Azure per Redis

  1. Seguire la Guida introduttiva: Creare una cache Redis Enterprise. Nella pagina Avanzate assicurarsi di aver aggiunto il modulo RediSearch e di aver scelto i Criteri cluster aziendali. Tutte le altre impostazioni possono corrispondere all'impostazione predefinita descritta nella guida introduttiva.

    La creazione della cache richiede alcuni minuti. È possibile passare al passaggio successivo nel frattempo.

Screenshot showing the Enterprise tier Basics tab filled out.

Configurare l'ambiente di sviluppo

  1. Creare una cartella nel computer locale denominato redis-vector nel percorso in cui in genere si salvano i progetti.

  2. Creare un nuovo file Python (tutorial.py) o jupyter notebook (tutorial.ipynb) nella cartella .

  3. Installare i pacchetti Python necessari:

    pip install "openai==1.6.1" num2words matplotlib plotly scipy scikit-learn pandas tiktoken redis langchain
    

Scaricare il set di dati

  1. In un Web browser accedere a https://www.kaggle.com/datasets/jrobischon/wikipedia-movie-plots.

  2. Accedere o registrarsi con Kaggle. La registrazione è necessaria per scaricare il file.

  3. Selezionare il collegamento Download in Kaggle per scaricare il file archive.zip .

  4. Estrarre il file archive.zip e spostare il wiki_movie_plots_deduped.csv nella cartella redis-vector .

Importare le librerie e configurare le informazioni di connessione

Per effettuare correttamente una chiamata ad Azure OpenAI, è necessario un endpoint e una chiave. È anche necessario un endpoint e una chiave per connettersi a cache di Azure per Redis.

  1. Passare alla risorsa OpenAI di Azure nella portale di Azure.

  2. Individuare endpoint e chiavi nella sezione Gestione risorse. Copiare l'endpoint e la chiave di accesso perché saranno necessari entrambi per l'autenticazione delle chiamate API. Un endpoint di esempio è: https://docs-test-001.openai.azure.com. Puoi usare entrambi KEY1 o KEY2.

  3. Passare alla pagina Panoramica della risorsa cache di Azure per Redis nella portale di Azure. Copiare l'endpoint.

  4. Individuare chiavi di accesso nella sezione Impostazioni. Copiare la chiave di accesso. Puoi usare entrambi Primary o Secondary.

  5. Aggiungere il codice seguente a una nuova cella di codice:

    # Code cell 2
    
    import re
    from num2words import num2words
    import os
    import pandas as pd
    import tiktoken
    from typing import List
    from langchain.embeddings import AzureOpenAIEmbeddings
    from langchain.vectorstores.redis import Redis as RedisVectorStore
    from langchain.document_loaders import DataFrameLoader
    
    API_KEY = "<your-azure-openai-key>"
    RESOURCE_ENDPOINT = "<your-azure-openai-endpoint>"
    DEPLOYMENT_NAME = "<name-of-your-model-deployment>"
    MODEL_NAME = "text-embedding-ada-002"
    REDIS_ENDPOINT = "<your-azure-redis-endpoint>"
    REDIS_PASSWORD = "<your-azure-redis-password>"
    
  6. Aggiornare il valore di e RESOURCE_ENDPOINT con i valori della API_KEY chiave e dell'endpoint dalla distribuzione di Azure OpenAI. DEPLOYMENT_NAME deve essere impostato sul nome della distribuzione usando il text-embedding-ada-002 (Version 2) modello di incorporamento e MODEL_NAME deve essere il modello di incorporamento specifico usato.

  7. Aggiornare REDIS_ENDPOINT e REDIS_PASSWORD con l'endpoint e il valore della chiave dall'istanza di cache di Azure per Redis.

    Importante

    È consigliabile usare variabili di ambiente o un gestore dei segreti come Azure Key Vault per passare le informazioni sulla chiave API, sull'endpoint e sul nome della distribuzione. Queste variabili vengono impostate in testo non crittografato per motivi di semplicità.

  8. Eseguire la cella di codice 2.

Importare un set di dati in pandas ed elaborare i dati

Successivamente, si leggerà il file CSV in un dataframe pandas.

  1. Aggiungere il codice seguente a una nuova cella di codice:

    # Code cell 3
    
    df=pd.read_csv(os.path.join(os.getcwd(),'wiki_movie_plots_deduped.csv'))
    df
    
  2. Eseguire la cella di codice 3. Verrà visualizzato l'output seguente:

    Screenshot of results from executing code cell 3, displaying eight columns and a sampling of 10 rows of data.

  3. Successivamente, elaborare i dati aggiungendo un id indice, rimuovendo gli spazi dai titoli delle colonne e filtrando i film per prendere solo i film realizzati dopo il 1970 e dai paesi di lingua inglese. Questo passaggio di filtro riduce il numero di film nel set di dati, riducendo il costo e il tempo necessari per generare incorporamenti. È possibile modificare o rimuovere i parametri di filtro in base alle preferenze.

    Per filtrare i dati, aggiungere il codice seguente a una nuova cella di codice:

    # Code cell 4
    
    df.insert(0, 'id', range(0, len(df)))
    df['year'] = df['Release Year'].astype(int)
    df['origin'] = df['Origin/Ethnicity'].astype(str)
    del df['Release Year']
    del df['Origin/Ethnicity']
    df = df[df.year > 1970] # only movies made after 1970
    df = df[df.origin.isin(['American','British','Canadian'])] # only movies from English-speaking cinema
    df
    
  4. Eseguire la cella di codice 4. Dovresti vedere i seguenti risultati:

    Screenshot of results from executing code cell 4, displaying nine columns and a sampling of 10 rows of data.

  5. Creare una funzione per pulire i dati rimuovendo spazi vuoti e punteggiatura, quindi usarla sul dataframe contenente il tracciato.

    Aggiungere il codice seguente a una nuova cella di codice ed eseguirlo:

    # Code cell 5
    
    pd.options.mode.chained_assignment = None
    
    # s is input text
    def normalize_text(s, sep_token = " \n "):
        s = re.sub(r'\s+',  ' ', s).strip()
        s = re.sub(r". ,","",s)
        # remove all instances of multiple spaces
        s = s.replace("..",".")
        s = s.replace(". .",".")
        s = s.replace("\n", "")
        s = s.strip()
    
        return s
    
    df['Plot']= df['Plot'].apply(lambda x : normalize_text(x))
    
  6. Rimuovere infine tutte le voci che contengono descrizioni dei tracciati troppo lunghe per il modello di incorporamento. In altre parole, richiedono più token rispetto al limite di token 8192. e quindi calcolare i numeri di token necessari per generare incorporamenti. Questo influisce anche sui prezzi per la generazione di incorporamento.

    Aggiungere il codice seguente a una nuova cella di codice:

    # Code cell 6
    
    tokenizer = tiktoken.get_encoding("cl100k_base")
    df['n_tokens'] = df["Plot"].apply(lambda x: len(tokenizer.encode(x)))
    df = df[df.n_tokens<8192]
    print('Number of movies: ' + str(len(df)))
    print('Number of tokens required:' + str(df['n_tokens'].sum()))
    
  7. Eseguire la cella di codice 6. Dovrebbe essere visualizzato questo output:

    Number of movies: 11125
    Number of tokens required:7044844
    

    Importante

    Fare riferimento ai prezzi del servizio OpenAI di Azure per indicare il costo della generazione di incorporamenti in base al numero di token necessari.

Caricare un dataframe in LangChain

Caricare il dataframe in LangChain usando la DataFrameLoader classe . Una volta che i dati si trovano nei documenti LangChain, è molto più facile usare le librerie LangChain per generare incorporamenti ed eseguire ricerche di somiglianza. Impostare Plot come in page_content_column modo che gli incorporamenti vengano generati in questa colonna.

  1. Aggiungere il codice seguente a una nuova cella di codice ed eseguirlo:

    # Code cell 7
    
    loader = DataFrameLoader(df, page_content_column="Plot" )
    movie_list = loader.load()
    

Generare incorporamenti e caricarli in Redis

Ora che i dati sono stati filtrati e caricati in LangChain, si creeranno incorporamenti in modo da poter eseguire query sul tracciato per ogni filmato. Il codice seguente configura Azure OpenAI, genera incorporamenti e carica i vettori di incorporamento in cache di Azure per Redis.

  1. Aggiungere il codice seguente una nuova cella di codice:

    # Code cell 8
    
    embedding = AzureOpenAIEmbeddings(
        deployment=DEPLOYMENT_NAME,
        model=MODEL_NAME,
        azure_endpoint=RESOURCE_ENDPOINT,
        openai_api_type="azure",
        openai_api_key=API_KEY,
        openai_api_version="2023-05-15",
        show_progress_bar=True,
        chunk_size=16 # current limit with Azure OpenAI service. This will likely increase in the future.
        )
    
    # name of the Redis search index to create
    index_name = "movieindex"
    
    # create a connection string for the Redis Vector Store. Uses Redis-py format: https://redis-py.readthedocs.io/en/stable/connections.html#redis.Redis.from_url
    # This example assumes TLS is enabled. If not, use "redis://" instead of "rediss://
    redis_url = "rediss://:" + REDIS_PASSWORD + "@"+ REDIS_ENDPOINT
    
    # create and load redis with documents
    vectorstore = RedisVectorStore.from_documents(
        documents=movie_list,
        embedding=embedding,
        index_name=index_name,
        redis_url=redis_url
    )
    
    # save index schema so you can reload in the future without re-generating embeddings
    vectorstore.write_schema("redis_schema.yaml")
    
  2. Eseguire la cella di codice 8. Il completamento di questa operazione può richiedere più di 30 minuti. Viene generato anche un redis_schema.yaml file. Questo file è utile se si desidera connettersi all'indice nell'istanza di cache di Azure per Redis senza generare nuovamente incorporamenti.

Importante

La velocità con cui vengono generati gli incorporamenti dipende dalla quota disponibile per il modello OpenAI di Azure. Con una quota di 240.000 token al minuto, l'elaborazione dei token 7M nel set di dati richiede circa 30 minuti.

Eseguire query di ricerca vettoriale

Ora che il set di dati, l'API del servizio Azure OpenAI e l'istanza di Redis sono configurati, è possibile eseguire ricerche usando i vettori. In questo esempio vengono restituiti i primi 10 risultati per una determinata query.

  1. Aggiungere il codice seguente al file di codice Python:

    # Code cell 9
    
    query = "Spaceships, aliens, and heroes saving America"
    results = vectorstore.similarity_search_with_score(query, k=10)
    
    for i, j in enumerate(results):
        movie_title = str(results[i][0].metadata['Title'])
        similarity_score = str(round((1 - results[i][1]),4))
        print(movie_title + ' (Score: ' + similarity_score + ')')
    
  2. Eseguire la cella di codice 9. Verrà visualizzato l'output seguente:

    Independence Day (Score: 0.8348)
    The Flying Machine (Score: 0.8332)
    Remote Control (Score: 0.8301)
    Bravestarr: The Legend (Score: 0.83)
    Xenogenesis (Score: 0.8291)
    Invaders from Mars (Score: 0.8291)
    Apocalypse Earth (Score: 0.8287)
    Invasion from Inner Earth (Score: 0.8287)
    Thru the Moebius Strip (Score: 0.8283)
    Solar Crisis (Score: 0.828)
    

    Il punteggio di somiglianza viene restituito insieme alla classificazione ordinale dei film in base alla somiglianza. Si noti che le query più specifiche hanno punteggi di somiglianza diminuiscono più rapidamente verso il basso nell'elenco.

Ricerche ibride

  1. Poiché RediSearch include anche funzionalità di ricerca avanzate sulla ricerca vettoriale, è possibile filtrare i risultati in base ai metadati nel set di dati, ad esempio genere di film, cast, anno di rilascio o regista. In questo caso, filtrare in base al genere comedy.

    Aggiungere il codice seguente a una nuova cella di codice:

    # Code cell 10
    
    from langchain.vectorstores.redis import RedisText
    
    query = "Spaceships, aliens, and heroes saving America"
    genre_filter = RedisText("Genre") == "comedy"
    results = vectorstore.similarity_search_with_score(query, filter=genre_filter, k=10)
    for i, j in enumerate(results):
        movie_title = str(results[i][0].metadata['Title'])
        similarity_score = str(round((1 - results[i][1]),4))
        print(movie_title + ' (Score: ' + similarity_score + ')')
    
  2. Eseguire la cella di codice 10. Verrà visualizzato l'output seguente:

    Remote Control (Score: 0.8301)
    Meet Dave (Score: 0.8236)
    Elf-Man (Score: 0.8208)
    Fifty/Fifty (Score: 0.8167)
    Mars Attacks! (Score: 0.8165)
    Strange Invaders (Score: 0.8143)
    Amanda and the Alien (Score: 0.8136)
    Suburban Commando (Score: 0.8129)
    Coneheads (Score: 0.8129)
    Morons from Outer Space (Score: 0.8121)
    

Con cache di Azure per Redis e il servizio Azure OpenAI, è possibile usare incorporamenti e ricerca vettoriale per aggiungere potenti funzionalità di ricerca all'applicazione.

Pulire le risorse

Per continuare a usare le risorse create in questo articolo, mantenere il gruppo di risorse.

In caso contrario, se le risorse sono state completate, è possibile eliminare il gruppo di risorse di Azure creato per evitare addebiti.

Importante

L'eliminazione di un gruppo di risorse è irreversibile. Quando si elimina un gruppo di risorse, tutte le risorse in esso contenute vengono eliminate in modo permanente. Assicurarsi di non eliminare accidentalmente il gruppo di risorse sbagliato o le risorse errate. Se sono state create le risorse all'interno di un gruppo di risorse esistente che contiene le risorse da mantenere, è possibile eliminare ogni risorsa singolarmente anziché eliminare il gruppo di risorse.

Per eliminare un gruppo di risorse

  1. Accedere al portale di Azure e selezionare Gruppi di risorse.

  2. Scegliere il gruppo di risorse da eliminare.

    Se sono presenti molti gruppi di risorse, usare la casella Filtro per qualsiasi campo... digitare il nome del gruppo di risorse creato per questo articolo. Selezionare il gruppo di risorse nell'elenco dei risultati.

    Screenshot showing a list of resource groups to delete in the working pane.

  3. Selezionare Elimina gruppo di risorse.

  4. Verrà chiesto di confermare l'eliminazione del gruppo di risorse. Digitare il nome del gruppo di risorse per confermare e quindi selezionare Elimina.

    Screenshot showing a form that requires the resource name to confirm deletion.

Dopo qualche istante, il gruppo di risorse e tutte le risorse che contiene vengono eliminati.