Bygg en kontextuell chatbot för finansiella tjänster med Amazon SageMaker JumpStart, Llama 2 och Amazon OpenSearch Serverless med Vector Engine | Amazon webbtjänster

Bygg en kontextuell chatbot för finansiella tjänster med Amazon SageMaker JumpStart, Llama 2 och Amazon OpenSearch Serverless med Vector Engine | Amazon webbtjänster

Branschen för finansiella tjänster (FinServ) har unika generativa AI-krav relaterade till domänspecifika data, datasäkerhet, regulatoriska kontroller och branschefterlevnadsstandarder. Dessutom letar kunderna efter val för att välja den mest effektiva och kostnadseffektiva modellen för maskininlärning (ML) och möjligheten att utföra nödvändig anpassning (finjustering) för att passa deras affärsanvändningsfall. Amazon SageMaker JumpStart är idealiskt lämpad för generativa AI-användningsfall för FinServ-kunder eftersom det tillhandahåller nödvändiga datasäkerhetskontroller och uppfyller kraven på efterlevnadsstandarder.

I det här inlägget demonstrerar vi frågor som svarar på frågor med hjälp av ett Retrieval Augmented Generation (RAG)-baserat tillvägagångssätt med stora språkmodeller (LLM) i SageMaker JumpStart med ett enkelt användningsfall för ekonomisk domän. RAG är ett ramverk för att förbättra kvaliteten på textgenerering genom att kombinera en LLM med ett informationshämtningssystem (IR). Den LLM-genererade texten och IR-systemet hämtar relevant information från en kunskapsbas. Den hämtade informationen används sedan för att utöka LLM:s input, vilket kan bidra till att förbättra noggrannheten och relevansen av den modellgenererade texten. RAG har visat sig vara effektivt för en mängd olika textgenereringsuppgifter, såsom besvara frågor och sammanfattningar. Det är ett lovande tillvägagångssätt för att förbättra kvaliteten och noggrannheten hos textgenereringsmodeller.

Fördelar med att använda SageMaker JumpStart

Med SageMaker JumpStart kan ML-utövare välja från ett brett urval av toppmoderna modeller för användningsfall som innehållsskrivning, bildgenerering, kodgenerering, frågesvar, copywriting, sammanfattning, klassificering, informationssökning och mer. ML-utövare kan distribuera grundmodeller till dedikerade Amazon SageMaker instanser från en nätverksisolerad miljö och anpassa modeller med SageMaker för modellträning och implementering.

SageMaker JumpStart är idealiskt lämpad för generativa AI-användningsfall för FinServ-kunder eftersom den erbjuder följande:

  • Anpassningsfunktioner – SageMaker JumpStart tillhandahåller exempel på anteckningsböcker och detaljerade inlägg för steg-för-steg-vägledning om domänanpassning av grundmodeller. Du kan följa dessa resurser för finjustering, domänanpassning och instruktion av grundmodeller eller för att bygga RAG-baserade applikationer.
  • Datasäkerhet – Att säkerställa säkerheten för slutledningsnyttolastdata är av största vikt. Med SageMaker JumpStart kan du distribuera modeller i nätverksisolering med endpoint-tillhandahållande för enstaka hyresavtal. Dessutom kan du hantera åtkomstkontroll till utvalda modeller genom funktionen för nav för privata modeller, i linje med individuella säkerhetskrav.
  • Regulatoriska kontroller och efterlevnad – Överensstämmelse med standarder som HIPAA BAA, SOC123, PCI och HITRUST CSF är en central egenskap hos SageMaker, vilket säkerställer anpassning till finanssektorns rigorösa regelverk.
  • Modellval – SageMaker JumpStart erbjuder ett urval av toppmoderna ML-modeller som konsekvent rankas bland de bästa i branschens erkända HELM-riktmärken. Dessa inkluderar, men är inte begränsade till, modellerna Llama 2, Falcon 40B, AI21 J2 Ultra, AI21 Summarize, Hugging Face MiniLM och BGE.

I det här inlägget utforskar vi att bygga en kontextuell chatbot för finansiella tjänsteorganisationer med hjälp av en RAG-arkitektur med Llama 2-grundmodellen och Kramande ansikte GPTJ-6B-FP16 inbäddningsmodell, båda tillgängliga i SageMaker JumpStart. Vi använder också Vektormotor för Amazon OpenSearch Serverlös (för närvarande i förhandsvisning) som vektordatalager för att lagra inbäddningar.

Begränsningar av stora språkmodeller

LLM:er har utbildats i stora volymer ostrukturerad data och utmärker sig i allmän textgenerering. Genom denna utbildning skaffar och lagrar LLM faktakunskaper. Däremot har standardiserade LLM:er begränsningar:

  • Deras offlineutbildning gör dem omedvetna om aktuell information.
  • Deras utbildning på övervägande generaliserade data minskar deras effektivitet i domänspecifika uppgifter. Till exempel kan ett finansföretag föredra att sin Q&A-bot hämtar svar från sina senaste interna dokument, vilket säkerställer noggrannhet och efterlevnad av sina affärsregler.
  • Deras beroende av inbäddad information äventyrar tolkningsbarheten.

För att använda specifik data i LLM finns tre vanliga metoder:

  • Inbäddning av data i modellens prompter, vilket gör att den kan använda detta sammanhang under generering av utdata. Detta kan vara nollskott (inga exempel), fåskott (begränsade exempel) eller många skott (rikliga exempel). Sådana kontextuella motiveringar styr modeller mot mer nyanserade resultat.
  • Finjustera modellen med hjälp av par av uppmaningar och kompletteringar.
  • RAG, som hämtar extern data (icke-parametrisk) och integrerar denna data i prompterna, vilket berikar sammanhanget.

Den första metoden brottas dock med modellbegränsningar för kontextstorlek, vilket gör det svårt att mata in långa dokument och eventuellt ökar kostnaderna. Finjusteringsmetoden, även om den är potent, är resurskrävande, särskilt med ständigt föränderlig extern data, vilket leder till försenade implementeringar och ökade kostnader. RAG kombinerat med LLM erbjuder en lösning på de tidigare nämnda begränsningarna.

Retrieval Augmented Generation

RAG hämtar extern data (icke-parametrisk) och integrerar denna data i ML-prompter, vilket berikar sammanhanget. Lewis et al. introducerade RAG-modeller 2020, och konceptualiserade dem som en fusion av en förtränad sekvens-till-sekvens-modell (parametriskt minne) och ett tätt vektorindex av Wikipedia (icke-parametriskt minne) som nås via en neural retriever.

Så här fungerar RAG:

  • Datakällor – RAG kan hämta från olika datakällor, inklusive dokumentförråd, databaser eller API:er.
  • Dataformatering – Både användarens fråga och dokumenten omvandlas till ett format som lämpar sig för relevansjämförelser.
  • inbäddningar – För att underlätta denna jämförelse omvandlas frågan och dokumentsamlingen (eller kunskapsbiblioteket) till numeriska inbäddningar med hjälp av språkmodeller. Dessa inbäddningar kapslar numeriskt in textkoncept.
  • Relevanssökning – Användarfrågans inbäddning jämförs med dokumentsamlingens inbäddningar, vilket identifierar relevant text genom en likhetssökning i inbäddningsutrymmet.
  • Kontextberikning – Den identifierade relevanta texten läggs till i användarens ursprungliga uppmaning, vilket förstärker dess sammanhang.
  • LLM-bearbetning – Med det berikade sammanhanget matas uppmaningen till LLM, som, på grund av inkluderingen av relevant extern data, producerar relevanta och exakta utdata.
  • Asynkrona uppdateringar – För att säkerställa att referensdokumenten förblir aktuella kan de uppdateras asynkront tillsammans med deras inbäddningsrepresentationer. Detta säkerställer att framtida modellsvar grundas på den senaste informationen, vilket garanterar noggrannhet.

I huvudsak erbjuder RAG en dynamisk metod för att ge LLM:er relevant information i realtid, vilket säkerställer generering av exakta och snabba utdata.

Följande diagram visar det konceptuella flödet av att använda RAG med LLM.

Bygg en kontextuell chatbot för finansiella tjänster med Amazon SageMaker JumpStart, Llama 2 och Amazon OpenSearch Serverless med Vector Engine | Amazon Web Services PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.

Lösningsöversikt

Följande steg krävs för att skapa en kontextuell fråga som besvarar chatbot för en applikation för finansiella tjänster:

  1. Använd SageMaker JumpStart GPT-J-6B inbäddningsmodell för att generera inbäddningar för varje PDF-dokument i Amazon enkel lagringstjänst (Amazon S3) uppladdningskatalog.
  2. Identifiera relevanta dokument genom att använda följande steg:
    • Skapa en inbäddning för användarens fråga med samma modell.
    • Använd OpenSearch Serverless med vektormotorfunktionen för att söka efter de K mest relevanta dokumentindexen i inbäddningsutrymmet.
    • Hämta motsvarande dokument med de identifierade indexen.
  3. Kombinera de hämtade dokumenten som sammanhang med användarens uppmaning och fråga. Vidarebefordra detta till SageMaker LLM för svarsgenerering.

Vi använder LangChain, ett populärt ramverk, för att orkestrera denna process. LangChain är speciellt utformad för att stärka applikationer som drivs av LLMs, och erbjuder ett universellt gränssnitt för olika LLMs. Det effektiviserar integreringen av flera LLM, vilket säkerställer sömlös tillståndsbeständighet mellan samtal. Dessutom ökar det utvecklarens effektivitet med funktioner som anpassningsbara promptmallar, omfattande applikationsbyggande agenter och specialiserade index för sökning och hämtning. För en fördjupad förståelse, se LangChain dokumentation.

Förutsättningar

Du behöver följande förutsättningar för att bygga vår kontextmedvetna chatbot:

För instruktioner om hur du ställer in en OpenSearch Serverless vektormotor, se Vi introducerar vektormotorn för Amazon OpenSearch Serverless, nu i förhandsvisning.

För en omfattande genomgång av följande lösning, klona GitHub repo och hänvisa till Jupyter anteckningsbok.

Distribuera ML-modellerna med SageMaker JumpStart

Utför följande steg för att distribuera ML-modellerna:

  1. Distribuera Llama 2 LLM från SageMaker JumpStart:
    from sagemaker.jumpstart.model import JumpStartModel
    llm_model = JumpStartModel(model_id = "meta-textgeneration-llama-2-7b-f")
    llm_predictor = llm_model.deploy()
    llm_endpoint_name = llm_predictor.endpoint_name

  2. Implementera GPT-J-inbäddningsmodellen:
    embeddings_model = JumpStartModel(model_id = "huggingface-textembedding-gpt-j-6b-fp16")
    embed_predictor = embeddings_model.deploy()
    embeddings_endpoint_name = embed_predictor.endpoint_name
    

Dela data och skapa ett dokumentinbäddningsobjekt

I det här avsnittet delar du upp data i mindre dokument. Chunking är en teknik för att dela upp stora texter i mindre bitar. Det är ett viktigt steg eftersom det optimerar sökfrågans relevans för vår RAG-modell, vilket i sin tur förbättrar kvaliteten på chatboten. Bitstorleken beror på faktorer som dokumenttyp och vilken modell som används. En chunk chunk_size=1600 har valts eftersom detta är den ungefärliga storleken på ett stycke. När modellerna förbättras kommer deras kontextfönsterstorlek att öka, vilket möjliggör större bitstorlekar.

Referera till Jupyter anteckningsbok i GitHub-repo för den kompletta lösningen.

  1. Förläng LangChain SageMakerEndpointEmbeddings klass för att skapa en anpassad inbäddningsfunktion som använder gpt-j-6b-fp16 SageMaker-slutpunkten som du skapade tidigare (som en del av att använda inbäddningsmodellen):
    from langchain.embeddings import SagemakerEndpointEmbeddings
    from langchain.embeddings.sagemaker_endpoint import EmbeddingsContentHandler logger = logging.getLogger(__name__) # extend the SagemakerEndpointEmbeddings class from langchain to provide a custom embedding function
    class SagemakerEndpointEmbeddingsJumpStart(SagemakerEndpointEmbeddings): def embed_documents( self, texts: List[str], chunk_size: int = 1 ) → List[List[float]]: """Compute doc embeddings using a SageMaker Inference Endpoint. Args: texts: The list of texts to embed. chunk_size: The chunk size defines how many input texts will be grouped together as request. If None, will use the chunk size specified by the class. Returns: List of embeddings, one for each text. """ results = [] _chunk_size = len(texts) if chunk_size > len(texts) else chunk_size st = time.time() for i in range(0, len(texts), _chunk_size): response = self._embedding_func(texts[i : i + _chunk_size]) results.extend(response) time_taken = time.time() - st logger.info( f"got results for {len(texts)} in {time_taken}s, length of embeddings list is {len(results)}" ) print( f"got results for {len(texts)} in {time_taken}s, length of embeddings list is {len(results)}" ) return results # class for serializing/deserializing requests/responses to/from the embeddings model
    class ContentHandler(EmbeddingsContentHandler): content_type = "application/json" accepts = "application/json" def transform_input(self, prompt: str, model_kwargs={}) → bytes: input_str = json.dumps({"text_inputs": prompt, **model_kwargs}) return input_str.encode("utf-8") def transform_output(self, output: bytes) → str: response_json = json.loads(output.read().decode("utf-8")) embeddings = response_json["embedding"] if len(embeddings) == 1: return [embeddings[0]] return embeddings def create_sagemaker_embeddings_from_js_model( embeddings_endpoint_name: str, aws_region: str
    ) → SagemakerEndpointEmbeddingsJumpStart: content_handler = ContentHandler() embeddings = SagemakerEndpointEmbeddingsJumpStart( endpoint_name=embeddings_endpoint_name, region_name=aws_region, content_handler=content_handler, ) return embeddings 

  2. Skapa inbäddningsobjektet och skapa en grupp av dokumentinbäddningarna:
    embeddings = create_sagemaker_embeddings_from_js_model(embeddings_endpoint_name, aws_region)

  3. Dessa inbäddningar lagras i vektormotorn med hjälp av LangChain OpenSearchVectorSearch. Dessa inbäddningar lagrar du i nästa avsnitt. Lagra dokumentinbäddningen i OpenSearch Serverless. Du är nu redo att iterera över de bitade dokumenten, skapa inbäddningarna och lagra dessa inbäddningar i OpenSearch Serverless vektorindex som skapats i vektorsökningssamlingar. Se följande kod:
    docsearch = OpenSearchVectorSearch.from_texts(
    texts = [d.page_content for d in docs],
    embedding=embeddings,
    opensearch_url=[{'host': _aoss_host, 'port': 443}],
    http_auth=awsauth,
    timeout = 300,
    use_ssl = True,
    verify_certs = True,
    connection_class = RequestsHttpConnection,
    index_name=_aos_index
    )

Frågor och svar över dokument

Hittills har du delat upp ett stort dokument i mindre, skapat vektorinbäddningar och lagrat dem i en vektormotor. Nu kan du svara på frågor om dessa dokumentdata. Eftersom du skapade ett index över data kan du göra en semantisk sökning; På detta sätt skickas endast de mest relevanta dokumenten som krävs för att besvara frågan via prompten till LLM. Detta gör att du kan spara tid och pengar genom att bara skicka relevanta dokument till LLM. För mer information om hur du använder dokumentkedjor, se Dokument.

Utför följande steg för att svara på frågor med hjälp av dokumenten:

  1. För att använda SageMaker LLM-slutpunkten med LangChain använder du langchain.llms.sagemaker_endpoint.SagemakerEndpoint, som abstraherar SageMaker LLM-slutpunkten. Du utför en transformation för begäran och svarsnyttolasten som visas i följande kod för LangChain SageMaker-integrationen. Observera att du kan behöva justera koden i ContentHandler baserat på content_type och accepterar formatet för den LLM-modell du väljer att använda.
    content_type = "application/json"
    accepts = "application/json"
    def transform_input(self, prompt: str, model_kwargs: dict) → bytes: payload = { "inputs": [ [ { "role": "system", "content": prompt, }, {"role": "user", "content": prompt}, ], ], "parameters": { "max_new_tokens": 1000, "top_p": 0.9, "temperature": 0.6, }, } input_str = json.dumps( payload, ) return input_str.encode("utf-8") def transform_output(self, output: bytes) → str: response_json = json.loads(output.read().decode("utf-8")) content = response_json[0]["generation"]["content"] return content content_handler = ContentHandler() sm_jumpstart_llm=SagemakerEndpoint( endpoint_name=llm_endpoint_name, region_name=aws_region, model_kwargs={"max_new_tokens": 300}, endpoint_kwargs={"CustomAttributes": "accept_eula=true"}, content_handler=content_handler, )

Nu är du redo att interagera med det finansiella dokumentet.

  1. Använd följande fråge- och promptmall för att ställa frågor om dokumentet:
    from langchain import PromptTemplate, SagemakerEndpoint
    from langchain.llms.sagemaker_endpoint import LLMContentHandler query = "Summarize the earnings report and also what year is the report for"
    prompt_template = """Only use context to answer the question at the end. {context} Question: {question}
    Answer:""" prompt = PromptTemplate( template=prompt_template, input_variables=["context", "question"]
    ) class ContentHandler(LLMContentHandler): content_type = "application/json" accepts = "application/json" def transform_input(self, prompt: str, model_kwargs: dict) → bytes: payload = { "inputs": [ [ { "role": "system", "content": prompt, }, {"role": "user", "content": prompt}, ], ], "parameters": { "max_new_tokens": 1000, "top_p": 0.9, "temperature": 0.6, }, } input_str = json.dumps( payload, ) return input_str.encode("utf-8") def transform_output(self, output: bytes) → str: response_json = json.loads(output.read().decode("utf-8")) content = response_json[0]["generation"]["content"] return content content_handler = ContentHandler() chain = load_qa_chain( llm=SagemakerEndpoint( endpoint_name=llm_endpoint_name, region_name=aws_region, model_kwargs={"max_new_tokens": 300}, endpoint_kwargs={"CustomAttributes": "accept_eula=true"}, content_handler=content_handler, ), prompt=prompt,
    )
    sim_docs = docsearch.similarity_search(query, include_metadata=False)
    chain({"input_documents": sim_docs, "question": query}, return_only_outputs=True)
    

Städa

För att undvika framtida kostnader, ta bort SageMaker slutpunkterna som du skapade i den här anteckningsboken. Du kan göra det genom att köra följande i din SageMaker Studio-anteckningsbok:

# Delete LLM
llm_predictor.delete_model()
llm_predictor.delete_predictor(delete_endpoint_config=True) # Delete Embeddings Model
embed_predictor.delete_model()
embed_predictor.delete_predictor(delete_endpoint_config=True)

Om du skapade en OpenSearch Serverless-samling för det här exemplet och inte längre behöver den, kan du ta bort den via OpenSearch Serverless-konsolen.

Slutsats

I det här inlägget diskuterade vi att använda RAG som ett tillvägagångssätt för att tillhandahålla domänspecifik kontext till LLM:er. Vi visade hur man använder SageMaker JumpStart för att bygga en RAG-baserad kontextuell chatbot för en finansiell tjänsteorganisation som använder Llama 2 och OpenSearch Serverless med en vektormotor som vektordatalager. Denna metod förfinar textgenerering med Llama 2 genom att dynamiskt hämta relevant sammanhang. Vi är glada över att se dig ta med din anpassade data och förnya dig med denna RAG-baserade strategi på SageMaker JumpStart!


Om författarna

Bygg en kontextuell chatbot för finansiella tjänster med Amazon SageMaker JumpStart, Llama 2 och Amazon OpenSearch Serverless med Vector Engine | Amazon Web Services PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.Sunil Padmanabhan är en Startup Solutions Architect på AWS. Som tidigare grundare och CTO brinner han för maskininlärning och fokuserar på att hjälpa startups att utnyttja AI/ML för sina affärsresultat och designa och distribuera ML/AI-lösningar i stor skala.

Bygg en kontextuell chatbot för finansiella tjänster med Amazon SageMaker JumpStart, Llama 2 och Amazon OpenSearch Serverless med Vector Engine | Amazon Web Services PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.Suleman Patel är senior lösningsarkitekt på Amazon Web Services (AWS), med särskilt fokus på maskininlärning och modernisering. Genom att utnyttja sin expertis inom både affärer och teknik hjälper Suleman kunder att designa och bygga lösningar som tar itu med verkliga affärsproblem. När han inte är fördjupad i sitt arbete, älskar Suleman att utforska naturen, göra roadtrips och laga läckra rätter i köket.

Tidsstämpel:

Mer från AWS maskininlärning