Zephyrnet-logo

Bouw een krachtige bot voor het beantwoorden van vragen met Amazon SageMaker, Amazon OpenSearch Service, Streamlit en LangChain | Amazon-webservices

Datum:

Een van de meest voorkomende toepassingen van generatieve AI en grote taalmodellen (LLM's) in een bedrijfsomgeving is het beantwoorden van vragen op basis van het kenniscorpus van de onderneming. Amazon-Lex biedt het kader voor het bouwen Op AI gebaseerde chatbots. Vooraf getrainde basismodellen (FM's) presteren goed bij het begrijpen van natuurlijke taal (NLU), zoals samenvattingen, het genereren van tekst en het beantwoorden van vragen over een breed scala aan onderwerpen, maar hebben ofwel moeite om nauwkeurige (zonder hallucinaties) antwoorden te geven of slagen er helemaal niet in om vragen over inhoud die ze niet hebben gezien als onderdeel van hun trainingsgegevens. Bovendien worden FM's getraind met een momentopname van gegevens en hebben ze geen inherente mogelijkheid om toegang te krijgen tot nieuwe gegevens op het moment van inferentie; zonder dit vermogen kunnen ze antwoorden geven die mogelijk onjuist of ontoereikend zijn.

Een veelgebruikte benadering om dit probleem aan te pakken, is het gebruik van een techniek genaamd Retrieval Augmented Generation (RAG). In de op RAG gebaseerde benadering zetten we de gebruikersvraag om in vectorinbeddingen met behulp van een LLM en zoeken we vervolgens naar overeenkomsten voor deze inbeddingen in een vooraf ingevulde vectordatabase die de inbeddingen voor het bedrijfskenniscorpus bevat. Een klein aantal vergelijkbare documenten (meestal drie) wordt als context toegevoegd samen met de gebruikersvraag aan de "prompt" die aan een andere LLM wordt verstrekt en vervolgens genereert die LLM een antwoord op de gebruikersvraag met behulp van informatie die als context in de prompt wordt verstrekt. RAG-modellen werden geïntroduceerd door Lewis et al. in 2020 als een model waarbij parametrisch geheugen een vooraf getraind seq2seq-model is en het niet-parametrische geheugen een dichte vectorindex van Wikipedia is, toegankelijk met een vooraf getrainde neurale retriever. Om de algemene structuur van een op RAG gebaseerde benadering te begrijpen, raadpleegt u Vraag beantwoorden met behulp van Retrieval Augmented Generation met basismodellen in Amazon SageMaker JumpStart.

In dit bericht bieden we een stapsgewijze handleiding met alle bouwstenen voor het maken van een enterprise-ready RAG-applicatie, zoals een bot voor het beantwoorden van vragen. We gebruiken een combinatie van verschillende AWS-diensten, open-source basismodellen (FLAN-T5 XXL voor het genereren van tekst en GPT-j-6B voor inbeddingen) en pakketten zoals LangChain voor interface met alle componenten en Gestroomlijnd voor het bouwen van de bot-frontend.

We bieden een AWS Cloud Formation-sjabloon om alle middelen op te zetten die nodig zijn voor het bouwen van deze oplossing. Vervolgens laten we zien hoe je LangChain kunt gebruiken om alles aan elkaar te knopen:

  • Interactie met LLM's gehost op Amazon SageMaker.
  • Chunking van kennisbankdocumenten.
  • Inbedding van documenten opnemen in Amazon OpenSearch Service.
  • Implementatie van de vraag-antwoordtaak.

We kunnen dezelfde architectuur gebruiken om de open-source modellen te verwisselen met de Amazone Titan modellen. Na Amazonebodem lanceringen, zullen we een vervolgpost publiceren die laat zien hoe vergelijkbare generatieve AI-applicaties kunnen worden geïmplementeerd met Amazon Bedrock, dus houd het in de gaten.

Overzicht oplossingen

We maken gebruik van de SageMaker-documenten als het kenniscorpus voor deze post. We zetten de HTML-pagina's op deze site om in kleinere overlappende brokken informatie (om enige contextcontinuïteit tussen brokken te behouden) en zetten deze brokken vervolgens om in inbeddingen met behulp van het gpt-j-6b-model en slaan de inbeddingen op in OpenSearch Service. We implementeren de RAG-functionaliteit in een AWS Lambda-functie met Amazon API Gateway om alle verzoeken naar de Lambda te routeren. We implementeren een chatbot-applicatie in Streamlit die de functie oproept via de API Gateway en de functie zoekt naar overeenkomsten in de OpenSearch Service-index voor de inbedding van de gebruikersvraag. De overeenkomende documenten (chunks) worden als context aan de prompt toegevoegd door de Lambda-functie en vervolgens gebruikt de functie het flan-t5-xxl-model dat is geïmplementeerd als een SageMaker-eindpunt om een ​​antwoord op de gebruikersvraag te genereren. Alle code voor dit bericht is beschikbaar in de GitHub repo.

De volgende afbeelding geeft de architectuur op hoog niveau van de voorgestelde oplossing weer.

Architectuur

Figuur 1: Architectuur

Stap voor stap uitleg:

  1. De Gebruiker stelt een vraag via de Streamlit webapplicatie.
  2. De Streamlit-toepassing roept de API Gateway-eindpunt REST API aan.
  3. De API Gateway roept de Lambda-functie aan.
  4. De functie roept het SageMaker-eindpunt aan om gebruikersvragen om te zetten in insluitingen.
  5. De functie roept een OpenSearch Service API aan om documenten te vinden die vergelijkbaar zijn met de vraag van de gebruiker.
  6. De functie creëert een "prompt" met de gebruikersquery en de "soortgelijke documenten" als context en vraagt ​​het SageMaker-eindpunt om een ​​antwoord te genereren.
  7. Het antwoord wordt geleverd door de functie aan de API Gateway.
  8. De API Gateway zorgt voor het antwoord op de Streamlit-applicatie.
  9. De gebruiker kan het antwoord op de Streamlit-applicatie bekijken,

Zoals geïllustreerd in het architectuurdiagram, gebruiken we de volgende AWS-services:

In termen van open-sourcepakketten die in deze oplossing worden gebruikt, gebruiken we LangChain voor interfacing met OpenSearch Service en SageMaker, en FastAPI voor het implementeren van de REST API-interface in de Lambda.

De workflow voor het instantiëren van de oplossing die in dit bericht wordt gepresenteerd in uw eigen AWS-account is als volgt:

  1. Voer de CloudFormation-sjabloon uit die bij dit bericht is geleverd in uw account. Hiermee worden alle benodigde infrastructuurbronnen gecreëerd die nodig zijn voor deze oplossing:
    • SageMaker-eindpunten voor de LLM's
    • OpenSearch Service-cluster
    • API-gateway
    • Lambda-functie
    • SageMaker-notitieboekje
    • IAM-rollen
  2. Voer de ... uit data_ingestion_to_vectordb.ipynb notebook in het SageMaker-notebook om gegevens van op te nemen SageMaker-documenten in een OpenSearch Service-index.
  3. Start de Streamlit-applicatie op een terminal in Studio en open de URL voor de applicatie in een nieuw browsertabblad.
  4. Stel uw vragen over SageMaker via de chatinterface van de Streamlit-app en bekijk de antwoorden die door de LLM zijn gegenereerd.

Deze stappen worden in detail besproken in de volgende secties.

Voorwaarden

Om de oplossing in dit bericht te implementeren, moet u een AWS-account en bekendheid met LLM's, OpenSearch Service en SageMaker.

We hebben toegang nodig tot versnelde instanties (GPU's) voor het hosten van de LLM's. Deze oplossing gebruikt één exemplaar van ml.g5.12xlarge en ml.g5.24xlarge; u kunt de beschikbaarheid van deze instanties in uw AWS-account controleren en deze indien nodig aanvragen via een verzoek om verhoging van het servicequotum, zoals weergegeven in de volgende schermafbeelding.

Verhoging van het servicequotum

Afbeelding 2: Verzoek om verhoging van het servicequotum

Gebruik AWS Cloud Formation om de oplossingsstapel te maken

We gebruiken AWS CloudFormation om een ​​SageMaker-notebook te maken met de naam aws-llm-apps-blog en een IAM-rol genoemd LLMAppsBlogIAMRole. Kiezen Start Stack voor de regio waarnaar u middelen wilt inzetten. Alle parameters die nodig zijn voor de CloudFormation-sjabloon hebben standaardwaarden die al zijn ingevuld, behalve het OpenSearch Service-wachtwoord dat u moet opgeven. Noteer de gebruikersnaam en het wachtwoord van de OpenSearch Service, deze gebruiken we in volgende stappen. Dit sjabloon duurt ongeveer 15 minuten om te voltooien.

AWS-regio Link
us-east-1
us-west-2
eu-west-1
ap-northeast-1

Nadat de stapel met succes is gemaakt, navigeert u naar het tabblad Uitvoer van de stapel op de AWS CloudFormation-console en noteert u de waarden voor OpenSearchDomainEndpoint en LLMAppAPIEndpoint. Die gebruiken we in de volgende stappen.

CloudFormation-stapeluitvoer

Figuur 3: Cloud Formation Stack-uitvoer

Neem de gegevens op in OpenSearch Service

Voer de volgende stappen uit om de gegevens op te nemen:

  1. Kies op de SageMaker-console Notitieboekjes in het navigatievenster.
  2. Selecteer het notitieboek aws-llm-apps-blog En kies JupyterLab openen.
    JupyterLab openen

    Afbeelding 4: Open JupyterLab

  3. Kies data_ingestion_to_vectordb.ipynb om het te openen in JupyterLab. Deze notebook neemt de SageMaker-documenten naar een OpenSearch Service-index genaamd llm_apps_workshop_embeddings.
    Notebook-pad

    Afbeelding 5: Notitieblok voor gegevensopname openen

  4. Wanneer de notebook is geopend, kiest u in het menu Uitvoeren Voer alle cellen uit om de code in dit notitieblok uit te voeren. Hiermee wordt de dataset lokaal naar de notebook gedownload en vervolgens opgenomen in de OpenSearch Service-index. Deze notebook heeft ongeveer 20 minuten nodig om te werken. De notebook neemt de gegevens ook op in een andere vectordatabase genaamd FAISS. De FAISS-indexbestanden worden lokaal opgeslagen en geüpload naar Amazon Simple Storage Service (S3), zodat ze optioneel kunnen worden gebruikt door de Lambda-functie als illustratie van het gebruik van een alternatieve vectordatabase.
    Voer alle cellen uit

    Afbeelding 6: Notebook voert alle cellen uit

Nu zijn we klaar om de documenten op te splitsen in stukken, die vervolgens kunnen worden omgezet in inbeddingen die kunnen worden opgenomen in OpenSearch. Wij gebruiken de LangChain RecursiveCharacterTextSplitter klasse om de documenten in stukjes te verdelen en vervolgens de LangChain SagemakerEndpointEmbeddingsJumpStart class om deze chunks om te zetten in inbeddingen met behulp van de gpt-j-6b LLM. We slaan de inbeddingen op in OpenSearch Service via de LangChain OpenSearchVectorSearch klas. We verpakken deze code in Python-scripts die via een aangepaste container aan de SageMaker-verwerkingstaak worden geleverd. Zie de data_ingestion_to_vectordb.ipynb notebook voor de volledige code.

  1. Maak een aangepaste container en installeer daarin de LangChain- en opensearch-py Python-pakketten.
  2. Upload deze containerafbeelding naar Amazon Elastic Container Registry (ECR).
  3. We gebruiken de SageMaker ScriptProcessor-klasse om een ​​SageMaker Processing-taak te maken die op meerdere knooppunten wordt uitgevoerd.
    • De gegevensbestanden die beschikbaar zijn in Amazon S3 worden automatisch verdeeld over de SageMaker Processing-taakexemplaren door instelling s3_data_distribution_type='ShardedByS3Key' kader van de ProcessingInput verstrekt aan de verwerkingstaak.
    • Elk knooppunt verwerkt een subset van de bestanden en dit vermindert de totale tijd die nodig is om de gegevens in OpenSearch Service op te nemen.
    • Elk knooppunt gebruikt ook Python-multiprocessing om intern ook de bestandsverwerking te parallelliseren. Daarom, er vinden twee niveaus van parallellisatie plaats, een op clusterniveau waar individuele knooppunten het werk (bestanden) onderling verdelen en een ander op knooppuntniveau waar de bestanden in een knooppunt ook worden opgesplitst over meerdere processen die op het knooppunt draaien.
       # setup the ScriptProcessor with the above parameters
      processor = ScriptProcessor(base_job_name=base_job_name, image_uri=image_uri, role=aws_role, instance_type=instance_type, instance_count=instance_count, command=["python3"], tags=tags) # setup input from S3, note the ShardedByS3Key, this ensures that # each instance gets a random and equal subset of the files in S3.
      inputs = [ProcessingInput(source=f"s3://{bucket}/{app_name}/{DOMAIN}", destination='/opt/ml/processing/input_data', s3_data_distribution_type='ShardedByS3Key', s3_data_type='S3Prefix')] logger.info(f"creating an opensearch index with name={opensearch_index}")
      # ready to run the processing job
      st = time.time()
      processor.run(code="container/load_data_into_opensearch.py", inputs=inputs, outputs=[], arguments=["--opensearch-cluster-domain", opensearch_domain_endpoint, "--opensearch-secretid", os_creds_secretid_in_secrets_manager, "--opensearch-index-name", opensearch_index, "--aws-region", aws_region, "--embeddings-model-endpoint-name", embeddings_model_endpoint_name, "--chunk-size-for-doc-split", str(CHUNK_SIZE_FOR_DOC_SPLIT), "--chunk-overlap-for-doc-split", str(CHUNK_OVERLAP_FOR_DOC_SPLIT), "--input-data-dir", "/opt/ml/processing/input_data", "--create-index-hint-file", CREATE_OS_INDEX_HINT_FILE, "--process-count", "2"])

  4. Sluit de notebook nadat alle cellen foutloos zijn uitgevoerd. Uw gegevens zijn nu beschikbaar in OpenSearch Service. Voer de volgende URL in de adresbalk van uw browser in om het aantal documenten in de llm_apps_workshop_embeddings inhoudsopgave. Gebruik het OpenSearch Service-domeineindpunt van de CloudFormation-stackuitvoer in de onderstaande URL. U wordt gevraagd om de gebruikersnaam en het wachtwoord van de OpenSearch Service, deze zijn beschikbaar via de CloudFormations-stack.
    https://your-opensearch-domain-endpoint/llm_apps_workshop_embeddings/_count

Het browservenster zou een uitvoer moeten tonen die lijkt op het volgende. Deze uitvoer laat zien dat er 5,667 documenten zijn opgenomen in het llm_apps_workshop_embeddings index. {"count":5667,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0}}

Voer de Streamlit-toepassing uit in Studio

Nu zijn we klaar om de Streamlit-webtoepassing uit te voeren voor onze bot voor het beantwoorden van vragen. Met deze applicatie kan de gebruiker een vraag stellen en vervolgens het antwoord ophalen via de /llm/rag REST API-eindpunt geleverd door de Lambda-functie.

Studio biedt een handig platform om de Streamlit-webtoepassing te hosten. In de volgende stappen wordt beschreven hoe u de Streamlit-app in Studio uitvoert. U kunt ook dezelfde procedure volgen om de app op uw laptop uit te voeren.

  1. Open Studio en open vervolgens een nieuwe terminal.
  2. Voer de volgende opdrachten uit op de terminal om de coderepository voor dit bericht te klonen en installeer de Python-pakketten die de toepassing nodig heeft:
    git clone https://github.com/aws-samples/llm-apps-workshop
    cd llm-apps-workshop/blogs/rag/app
    pip install -r requirements.txt

  3. De API Gateway-eindpunt-URL die beschikbaar is via de CloudFormation-stackuitvoer moet worden ingesteld in het webapp.py-bestand. Dit wordt gedaan door het volgende uit te voeren sed commando. Vervang de replace-with-LLMAppAPIEndpoint-value-from-cloudformation-stack-outputs in de shell-commando's met de waarde van de LLMAppAPIEndpoint veld uit de CloudFormation-stackuitvoer en voer vervolgens de volgende opdrachten uit om een ​​Streamlit-app op Studio te starten.
    
    EP=replace-with-LLMAppAPIEndpoint-value-from-cloudformation-stack-outputs
    # replace __API_GW_ENDPOINT__ with output from the cloud formation stack
    sed -i "s|__API_GW_ENDPOINT__|$EP|g" webapp.py
    streamlit run webapp.py

  4. Wanneer de toepassing met succes wordt uitgevoerd, ziet u een uitvoer die lijkt op het volgende (de IP-adressen die u ziet, verschillen van de adressen die in dit voorbeeld worden getoond). Noteer het poortnummer (meestal 8501) van de uitvoer om te gebruiken als onderdeel van de URL voor de app in de volgende stap.
    sagemaker-user@studio$ streamlit run webapp.py Collecting usage statistics. To deactivate, set browser.gatherUsageStats to False. You can now view your Streamlit app in your browser. Network URL: http://169.255.255.2:8501
    External URL: http://52.4.240.77:8501

  5. Je hebt toegang tot de app in een nieuw browsertabblad met een URL die vergelijkbaar is met de URL van je Studio-domein. Als uw Studio-URL bijvoorbeeld https://d-randomidentifier.studio.us-east-1.sagemaker.aws/jupyter/default/lab? dan is de URL voor uw Streamlit-app https://d-randomidentifier.studio.us-east-1.sagemaker.aws/jupyter/default/proxy/8501/webapp (Let erop dat lab is vervangen door proxy/8501/webapp). Als het in de vorige stap genoteerde poortnummer anders is dan 8501, gebruik dat dan in plaats van 8501 in de URL voor de Streamlit-app.

De volgende schermafbeelding toont de app met een aantal gebruikersvragen.

Streamlit-app

Een nadere blik op de RAG-implementatie in de Lambda-functie

Nu we de applicatie end-to-end hebben laten werken, laten we de Lambda-functie eens nader bekijken. De Lambda-functie gebruikt FastAPI om de REST API voor RAG en de Mangom pakket om de API te verpakken met een handler die we verpakken en implementeren in de functie. We gebruiken de API Gateway om alle inkomende verzoeken te routeren om de functie aan te roepen en de routering intern binnen onze applicatie af te handelen.

Het volgende codefragment laat zien hoe we documenten vinden in de OpenSearch-index die vergelijkbaar zijn met de gebruikersvraag en vervolgens een prompt maken door de vraag en de vergelijkbare documenten te combineren. Deze prompt wordt vervolgens aan de LLM verstrekt voor het genereren van een antwoord op de gebruikersvraag.

@router.post("/rag")
async def rag_handler(req: Request) -> Dict[str, Any]: # dump the received request for debugging purposes logger.info(f"req={req}") # initialize vector db and SageMaker Endpoint _init(req) # Use the vector db to find similar documents to the query # the vector db call would automatically convert the query text # into embeddings docs = _vector_db.similarity_search(req.q, k=req.max_matching_docs) logger.info(f"here are the {req.max_matching_docs} closest matching docs to the query="{req.q}"") for d in docs: logger.info(f"---------") logger.info(d) logger.info(f"---------") # now that we have the matching docs, lets pack them as a context # into the prompt and ask the LLM to generate a response prompt_template = """Answer based on context:nn{context}nn{question}""" prompt = PromptTemplate( template=prompt_template, input_variables=["context", "question"] ) logger.info(f"prompt sent to llm = "{prompt}"") chain = load_qa_chain(llm=_sm_llm, prompt=prompt) answer = chain({"input_documents": docs, "question": req.q}, return_only_outputs=True)['output_text'] logger.info(f"answer received from llm,nquestion: "{req.q}"nanswer: "{answer}"") resp = {'question': req.q, 'answer': answer} if req.verbose is True: resp['docs'] = docs return resp

Opruimen

Verwijder de resources om toekomstige kosten te voorkomen. U kunt dit doen door de CloudFormation-stack te verwijderen, zoals weergegeven in de volgende schermafbeelding.

Verwijder CloudFormation-stapel

Figuur 7: Opruimen

Conclusie

In dit bericht hebben we laten zien hoe u een bedrijfsklare RAG-oplossing kunt maken met behulp van een combinatie van AWS-service, open-source LLM's en open-source Python-pakketten.

We moedigen u aan om meer te leren door te verkennen snelle start, Amazone Titan modellen Amazonebodem en OpenSearch-service en het bouwen van een oplossing met behulp van de voorbeeldimplementatie in dit bericht en een dataset die relevant is voor uw bedrijf. Als je vragen of suggesties hebt, laat dan een reactie achter.


Over de auteurs

Amit Arora is een AI- en ML-specialistarchitect bij Amazon Web Services, die zakelijke klanten helpt bij het gebruik van cloudgebaseerde machine learning-services om hun innovaties snel op te schalen. Hij is ook adjunct-docent in het MS data science and analytics-programma aan de Georgetown University in Washington DC

Xin HuangDr Xin Huang is een Senior Applied Scientist voor Amazon SageMaker JumpStart en Amazon SageMaker ingebouwde algoritmen. Hij richt zich op het ontwikkelen van schaalbare machine learning-algoritmen. Zijn onderzoeksinteresses liggen op het gebied van natuurlijke taalverwerking, verklaarbaar diep leren op tabelgegevens en robuuste analyse van niet-parametrische ruimte-tijd clustering. Hij heeft veel artikelen gepubliceerd in ACL-, ICDM-, KDD-conferenties en Royal Statistical Society: Series A.

Navneet Tuteja is dataspecialist bij Amazon Web Services. Voordat hij bij AWS kwam, werkte Navneet als facilitator voor organisaties die hun data-architecturen wilden moderniseren en uitgebreide AI/ML-oplossingen wilden implementeren. Ze heeft een ingenieursdiploma van de Thapar University en een master in statistiek van de Texas A&M University.

spot_img

Laatste intelligentie

spot_img