Kurz: Zkoumání Azure OpenAI v modelech Foundry Microsoft a vyhledávání dokumentů

V tomto kurzu se dozvíte, jak použít rozhraní API Azure OpenAI embeddings k provádění dokumentového vyhledávání. Dotazujete znalostní bázi, abyste našli nejrelevavantnější dokument.

V tomto kurzu se naučíte:

  • Stáhněte si ukázkovou datovou sadu a připravte ji na analýzu.
  • Vytvořte proměnné prostředí pro koncový bod prostředků a API klíč.
  • Použijte jeden z následujících modelů: text-embedding-ada-002 (verze 2), text-embedding-3-large nebo text-embedding-3-small.
  • K řazení výsledků hledání použijte kosinusovou podobnost .

Požadavky

Nastavení

knihovny Python

Pokud jste to ještě neudělali, musíte nainstalovat následující knihovny:

pip install openai num2words matplotlib plotly scipy scikit-learn pandas tiktoken

Stažení datové sady BillSum

BillSum je datová sada USA kongresových a kaliforniových státních faktur. Pro ilustraci se podíváme jenom na faktury v USA. Korpus se skládá ze zákonů z kongresových zasedání 103. až 115. v letech 1993–2018. Data byla rozdělena na 18 949 faktur za vlak a 3 269 zkušebních faktur. Korpus BillSum se zaměřuje na právní předpisy střední délky od 5 000 do 20 000 znaků. Další informace o projektu a původním akademickém dokumentu, ze kterého je tato datová sada odvozena, najdete v úložišti projektu GitHub .

V tomto kurzu se používá soubor bill_sum_data.csv, který si můžete stáhnout z našich ukázkových dat GitHub.

Ukázková data si můžete stáhnout také spuštěním následujícího příkazu na místním počítači:

curl "https://raw.githubusercontent.com/Azure-Samples/Azure-OpenAI-Docs-Samples/main/Samples/Tutorials/Embeddings/data/bill_sum_data.csv" --output bill_sum_data.csv

Poznámka

ověřování na základě Microsoft Entra ID se v současné době nepodporuje pro vkládání pomocí rozhraní API v1.

Načtení klíče a koncového bodu

K úspěšnému volání Azure OpenAI potřebujete endpoint a key.

Název proměnné Hodnota
ENDPOINT Koncový bod služby najdete v Klíče a koncový bod při kontrole vašeho prostředku v portálu Azure. Koncový bod najdete také prostřednictvím stránky Deployments na portálu Microsoft Foundry. Ukázkový koncový bod je: https://docs-test-001.openai.azure.com/.
API-KEY Tuto hodnotu najdete v části Klíče a koncové body při zkoumání svého prostředku z portálu Azure. Můžete použít buď KEY1 nebo KEY2.

Na portálu Azure přejděte ke svému prostředku. Oddíl Klíče a koncové body se nachází v oddílu Správa prostředků. Zkopírujte koncový bod a přístupový klíč, protože budete potřebovat obojí pro ověřování volání rozhraní API. Můžete použít buď KEY1 nebo KEY2. Vždy mít dva klíče vám umožní bezpečně otáčet a znovu vygenerovat klíče, aniž by to způsobilo přerušení služeb.

Screenshot přehledového uživatelského rozhraní pro prostředek Azure OpenAI na portálu Azure s koncovým bodem a umístěním přístupových klíčů zakroužkovaných v red.

Proměnné prostředí

Vytvořte a přiřaďte trvalé proměnné pro váš klíč API.

Důležité

Používejte klíče rozhraní API s opatrností. Nevkládejte klíč rozhraní API přímo do kódu a nikdy ho nezveřejňujte veřejně. Pokud používáte klíč rozhraní API, bezpečně ho uložte do Azure Key Vault. Další informace o bezpečném používání klíčů API v aplikacích najdete v tématu KLÍČEAPI s Azure Key Vault.

Další informace o zabezpečení služeb AI najdete v tématu Autentizace požadavků na služby Azure AI.

setx AZURE_OPENAI_API_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE" 

Po nastavení proměnných prostředí možná budete muset zavřít a znovu otevřít poznámkové bloky Jupyter nebo jakékoli prostředí IDE, které používáte, aby byly proměnné prostředí přístupné. I když důrazně doporučujeme používat poznámkové bloky Jupyter, pokud je z nějakého důvodu nemůžete použít, budete muset upravit jakýkoli kód, který vrací pandas dataframe, použitím print(dataframe_name) namísto pouhého přímého volání dataframe_name, jak se často provádí na konci bloku kódu.

V preferovaném integrovaném vývojovém prostředí (IDE Python) spusťte následující kód:

Import knihoven

import os
import re
import requests
import sys
from num2words import num2words
import os
import pandas as pd
import numpy as np
import tiktoken
from openai import OpenAI

Teď potřebujeme přečíst soubor CSV a vytvořit datový rámec pandas. Po vytvoření počátečního datového rámce můžeme zobrazit obsah tabulky spuštěním dfpříkazu .

df=pd.read_csv(os.path.join(os.getcwd(),'bill_sum_data.csv')) # This assumes that you have placed the bill_sum_data.csv in the same directory you are running Jupyter Notebooks
df

Výstup:

Snímek obrazovky s počáteční tabulkou datového rámce ze souboru CSV

Počáteční tabulka obsahuje více sloupců, než potřebujeme, vytvoříme nový menší datový rámec, df_bills který bude obsahovat pouze sloupce pro text, summarya title.

df_bills = df[['text', 'summary', 'title']]
df_bills

Výstup:

Snímek obrazovky s menšími výsledky tabulky datového rámce, s textovými, souhrnnými a záhlavími sloupci zobrazenými pouze.

V dalším kroku provedeme čištění lehkých dat odebráním nadbytečných prázdných znaků a vyčištěním interpunkce pro přípravu dat na tokenizaci.

pd.options.mode.chained_assignment = None #https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#evaluation-order-matters

# 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_bills['text']= df_bills["text"].apply(lambda x : normalize_text(x))

Teď potřebujeme odebrat všechny faktury, které jsou pro limit tokenu příliš dlouhé (8 192 tokenů).

tokenizer = tiktoken.get_encoding("cl100k_base")
df_bills['n_tokens'] = df_bills["text"].apply(lambda x: len(tokenizer.encode(x)))
df_bills = df_bills[df_bills.n_tokens<8192]
len(df_bills)
20

Poznámka

V tomto případě jsou všechny faktury pod limitem vstupního tokenu modelu vložení, ale výše uvedenou techniku můžete použít k odebrání položek, které by jinak způsobily selhání vkládání. Pokud se setkáte s obsahem, který překračuje limit vkládání, můžete obsah také zakládat na menší části a pak je vložit po jednom.

Znovu prozkoumáme df_bills.

df_bills

Výstup:

Snímek obrazovky datového rámce s novým sloupcem s názvem n_tokens

Pokud chcete porozumět n_tokens sloupci trochu víc a zjistit, jak se text nakonec tokenizuje, může být užitečné spustit následující kód:

sample_encode = tokenizer.encode(df_bills.text[0]) 
decode = tokenizer.decode_tokens_bytes(sample_encode)
decode

Pro naše dokumenty záměrně zkracujeme výstup, ale spuštění tohoto příkazu ve vašem prostředí vrátí celý text od indexu nula, rozdělený do bloků. Vidíte, že v některých případech je celé slovo reprezentováno jedním tokenem, zatímco v jiných částech slov jsou rozdělené mezi více tokenů.

[b'SECTION',
 b' ',
 b'1',
 b'.',
 b' SHORT',
 b' TITLE',
 b'.',
 b' This',
 b' Act',
 b' may',
 b' be',
 b' cited',
 b' as',
 b' the',
 b' ``',
 b'National',
 b' Science',
 b' Education',
 b' Tax',
 b' In',
 b'cent',
 b'ive',
 b' for',
 b' Businesses',
 b' Act',
 b' of',
 b' ',
 b'200',
 b'7',
 b"''.",
 b' SEC',
 b'.',
 b' ',
 b'2',
 b'.',
 b' C',
 b'RED',
 b'ITS',
 b' FOR',
 b' CERT',
 b'AIN',
 b' CONTRIBUT',
 b'IONS',
 b' BEN',
 b'EF',
 b'IT',
 b'ING',
 b' SC',

Pokud pak zkontrolujete délku decode proměnné, zjistíte, že odpovídá prvnímu číslu ve sloupci n_tokens.

len(decode)
1466

Teď, když rozumíme tomu, jak tokenizace funguje, můžeme přejít na vkládání. Je důležité si uvědomit, že jsme ve skutečnosti ještě dokumenty netokenizovali. Sloupec n_tokens je jednoduše způsob, jak zajistit, aby žádná data, která předáme modelu pro tokenizaci a vkládání, překročila limit vstupního tokenu 8 192. Když dokumenty předáme embeddingovému modelu, rozdělí je na tokeny podobné (i když nemusí být nutně identické) výše uvedeným příkladům, a poté převede tyto tokeny na řadu čísel s plovoucí desetinnou čárkou, která budou přístupná prostřednictvím vektorového vyhledávání. Tyto vkládání je možné ukládat místně nebo v databázi Azure pro podporu vektorového vyhledávání. V důsledku toho bude mít každý faktura svůj vlastní odpovídající vektor vložení do nového ada_v2 sloupce na pravé straně datového rámce.

V následujícím příkladu voláme model vkládání jednou pro každou položku, kterou chceme vložit. Při práci s velkými projekty vkládání můžete alternativně předat model pole vstupů pro vložení místo jednoho vstupu najednou. Když předáte modelu pole vstupů, maximální počet vstupních položek na jedno volání koncového bodu vkládání je 2048.

client = OpenAI(
  api_key = os.getenv("AZURE_OPENAI_API_KEY"),  
  base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/"
)

def generate_embeddings(text, model="text-embedding-ada-002"): # model = "deployment_name"
    return client.embeddings.create(input = [text], model=model).data[0].embedding

df_bills['ada_v2'] = df_bills["text"].apply(lambda x : generate_embeddings (x, model = 'text-embedding-ada-002')) # model should be set to the deployment name you chose when you deployed the text-embedding-ada-002 (Version 2) model
df_bills

Výstup:

Snímek obrazovky s formátovanými výsledky z příkazu df_bills

Když níže spustíme blok vyhledávacího kódu, vložíme vyhledávací dotaz "Můžu získat informace o daňových výnosech kabelové společnosti?" se stejným modelem vkládání textu ada-002 (verze 2). V dalším kroku najdeme nejbližší vložení faktury k nově vloženému textu z dotazu seřazeného podle kosinusové podobnosti.

def cosine_similarity(a, b):
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

def get_embedding(text, model="text-embedding-ada-002"): # model = "deployment_name"
    return client.embeddings.create(input = [text], model=model).data[0].embedding

def search_docs(df, user_query, top_n=4, to_print=True):
    embedding = get_embedding(
        user_query,
        model="text-embedding-ada-002" # model should be set to the deployment name you chose when you deployed the text-embedding-ada-002 (Version 2) model
    )
    df["similarities"] = df.ada_v2.apply(lambda x: cosine_similarity(x, embedding))

    res = (
        df.sort_values("similarities", ascending=False)
        .head(top_n)
    )
    if to_print:
        display(res)
    return res

res = search_docs(df_bills, "Can I get information on cable company tax revenue?", top_n=4)

Výstup:

Snímek obrazovky s formátovanými výsledky res po spuštění vyhledávacího dotazu

Nakonec zobrazíme nejlepší výsledek hledání dokumentů na základě uživatelského dotazu na celou znalostní bázi. Vrátí nejlepší výsledek podle "Taxpayer's Right to View Act of 1993". Tento dokument má skóre kosinové podobnosti 0,76 mezi dotazem a dokumentem.

res["summary"][9]
"Taxpayer's Right to View Act of 1993 - Amends the Communications Act of 1934 to prohibit a cable operator from assessing separate charges for any video programming of a sporting, theatrical, or other entertainment event if that event is performed at a facility constructed, renovated, or maintained with tax revenues or by an organization that receives public financial support. Authorizes the Federal Communications Commission and local franchising authorities to make determinations concerning the applicability of such prohibition. Sets forth conditions under which a facility is considered to have been constructed, maintained, or renovated with tax revenues. Considers events performed by nonprofit or public organizations that receive tax subsidies to be subject to this Act if the event is sponsored by, or includes the participation of a team that is part of, a tax exempt organization."

Pomocí tohoto přístupu můžete vkládání použít jako vyhledávací mechanismus napříč dokumenty ve znalostní bázi. Uživatel pak může převzít hlavní výsledek hledání a použít ho pro svůj následný úkol, což vyvolalo jejich počáteční dotaz.

Řešení potíží

  • 401/403: Ověřte, že AZURE_OPENAI_API_KEY je nastavený a odpovídá vašemu klíči prostředku.
  • 404: Ověřte, že AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT odpovídá vašemu názvu nasazení.
  • Neplatná adresa URL: Ověřte, že AZURE_OPENAI_ENDPOINT je koncový bod vašeho prostředku, například https://<resource-name>.openai.azure.com.

Vyčištění prostředků

Pokud jste vytvořili prostředek Azure OpenAI výhradně pro dokončení tohoto kurzu a chcete vyčistit a odebrat prostředek Azure OpenAI, odstraňte nasazené modely. Potom odstraňte prostředek nebo přidruženou skupinu prostředků, pokud je vyhrazená pro testovací prostředek. Odstraněním skupiny prostředků se odstraní také všechny ostatní prostředky, které jsou k ní přidružené.

Další kroky

Další informace o modelech OpenAI Azure: