Σημείωμα
Η πρόσβαση σε αυτήν τη σελίδα απαιτεί εξουσιοδότηση. Μπορείτε να δοκιμάσετε να εισέλθετε ή να αλλάξετε καταλόγους.
Η πρόσβαση σε αυτήν τη σελίδα απαιτεί εξουσιοδότηση. Μπορείτε να δοκιμάσετε να αλλάξετε καταλόγους.
Αυτό το εκπαιδευτικό βοήθημα δείχνει πώς μπορείτε να χρησιμοποιήσετε το Fabric για να αξιολογήσετε την απόδοση της εφαρμογής RAG. Η αξιολόγηση εστιάζει σε δύο κύρια στοιχεία RAG: το retriever (Azure AI Search) και τη γεννήτρια απόκρισης (ένα LLM που χρησιμοποιεί το ερώτημα του χρήστη, το ανακτημένο περιβάλλον και μια προτροπή για τη δημιουργία μιας απάντησης). Εδώ είναι τα κύρια βήματα:
- Ρύθμιση των υπηρεσιών αναζήτησης Azure OpenAI και Azure AI
- Φορτώστε δεδομένα από το σύνολο δεδομένων QA της CMU των άρθρων της Wikipedia για να δημιουργήσετε ένα σημείο αναφοράς
- Εκτελέστε μια δοκιμή καπνού με ένα ερώτημα για να επιβεβαιώσετε ότι το σύστημα RAG λειτουργεί από άκρο σε άκρο
- Ορισμός ντετερμινιστικών και υποβοηθούμενων από AI μετρήσεων για αξιολόγηση
- Check-in 1: Αξιολογήστε την απόδοση του retriever χρησιμοποιώντας ακρίβεια top-N
- Check-in 2: Αξιολογήστε την απόδοση της γεννήτριας απόκρισης χρησιμοποιώντας μετρήσεις γείωσης, συνάφειας και ομοιότητας
- Οπτικοποιήστε και αποθηκεύστε τα αποτελέσματα αξιολόγησης στο OneLake για μελλοντική αναφορά και συνεχή αξιολόγηση
Προαπαιτούμενα
Πριν ξεκινήσετε αυτό το πρόγραμμα εκμάθησης, ολοκληρώστε τον οδηγό βήμα προς βήμα για την επαυξημένη δημιουργία ανάκτησης κτιρίων στο Fabric.
Χρειάζεστε αυτές τις υπηρεσίες για να εκτελέσετε το σημειωματάριο:
- Microsoft Fabric
- Προσθέστε ένα lakehouse σε αυτό το σημειωματάριο (περιέχει τα δεδομένα που προσθέσατε στο προηγούμενο πρόγραμμα εκμάθησης).
- Azure AI Studio για OpenAI
- Αναζήτηση Azure AI (περιέχει τα δεδομένα που ευρετηριάσατε στο προηγούμενο πρόγραμμα εκμάθησης).
Στο προηγούμενο σεμινάριο, αποστείλατε δεδομένα στο lakehouse σας και δημιουργήσατε ένα ευρετήριο εγγράφων που χρησιμοποιείται από το σύστημα RAG. Χρησιμοποιήστε το ευρετήριο σε αυτήν την άσκηση για να μάθετε βασικές τεχνικές για την αξιολόγηση της απόδοσης του RAG και τον εντοπισμό πιθανών προβλημάτων. Εάν δεν δημιουργήσατε ευρετήριο ή το καταργήσατε, ακολουθήστε τον οδηγό γρήγορης εκκίνησης για να ολοκληρώσετε την προϋπόθεση.
Ρύθμιση πρόσβασης στο Azure OpenAI και την Αναζήτηση Azure AI
Καθορίστε τα τελικά σημεία και τα απαιτούμενα κλειδιά. Εισαγάγετε τις απαιτούμενες βιβλιοθήκες και συναρτήσεις. Δημιουργήστε πελάτες για το Azure OpenAI και το Azure AI Search. Ορίστε ένα περιτύλιγμα συνάρτησης με μια προτροπή για υποβολή ερωτήματος στο σύστημα RAG.
# Enter your Azure OpenAI service values
aoai_endpoint = "https://<your-resource-name>.openai.azure.com" # TODO: Provide the Azure OpenAI resource endpoint (replace <your-resource-name>)
aoai_key = "" # TODO: Fill in your API key from Azure OpenAI
aoai_deployment_name_embeddings = "text-embedding-ada-002"
aoai_model_name_query = "gpt-4-32k"
aoai_model_name_metrics = "gpt-4-32k"
aoai_api_version = "2024-02-01"
# Setup key accesses to Azure AI Search
aisearch_index_name = "" # TODO: Create a new index name: must only contain lowercase, numbers, and dashes
aisearch_api_key = "" # TODO: Fill in your API key from Azure AI Search
aisearch_endpoint = "https://.search.windows.net" # TODO: Provide the url endpoint for your created Azure AI Search
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
import os, requests, json
from datetime import datetime, timedelta
from azure.core.credentials import AzureKeyCredential
from azure.search.documents import SearchClient
from pyspark.sql import functions as F
from pyspark.sql.functions import to_timestamp, current_timestamp, concat, col, split, explode, udf, monotonically_increasing_id, when, rand, coalesce, lit, input_file_name, regexp_extract, concat_ws, length, ceil
from pyspark.sql.types import StructType, StructField, StringType, IntegerType, TimestampType, ArrayType, FloatType
from pyspark.sql import Row
import pandas as pd
from azure.search.documents.indexes import SearchIndexClient
from azure.search.documents.models import (
VectorizedQuery,
)
from azure.search.documents.indexes.models import (
SearchIndex,
SearchField,
SearchFieldDataType,
SimpleField,
SearchableField,
SemanticConfiguration,
SemanticPrioritizedFields,
SemanticField,
SemanticSearch,
VectorSearch,
HnswAlgorithmConfiguration,
HnswParameters,
VectorSearchProfile,
VectorSearchAlgorithmKind,
VectorSearchAlgorithmMetric,
)
import openai
from openai import AzureOpenAI
import uuid
import matplotlib.pyplot as plt
from synapse.ml.featurize.text import PageSplitter
import ipywidgets as widgets
from IPython.display import display as w_display
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 6, Finished, Available, Finished)
# Configure access to OpenAI endpoint
openai.api_type = "azure"
openai.api_key = aoai_key
openai.api_base = aoai_endpoint
openai.api_version = aoai_api_version
# Create client for accessing embedding endpoint
embed_client = AzureOpenAI(
api_version=aoai_api_version,
azure_endpoint=aoai_endpoint,
api_key=aoai_key,
)
# Create client for accessing chat endpoint
chat_client = AzureOpenAI(
azure_endpoint=aoai_endpoint,
api_key=aoai_key,
api_version=aoai_api_version,
)
# Configure access to Azure AI Search
search_client = SearchClient(
aisearch_endpoint,
aisearch_index_name,
credential=AzureKeyCredential(aisearch_api_key)
)
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 7, Finished, Available, Finished)
Οι ακόλουθες λειτουργίες υλοποιούν τα δύο κύρια στοιχεία RAG - retriever (get_context_source) και γεννήτρια απόκρισης (get_answer). Ο κώδικας είναι παρόμοιος με τον προηγούμενο οδηγό. Η topN παράμετρος σάς επιτρέπει να ορίσετε πόσους σχετικούς πόρους θα ανακτήσετε (αυτό το εκπαιδευτικό βοήθημα χρησιμοποιεί 3, αλλά η βέλτιστη τιμή μπορεί να διαφέρει ανάλογα με το σύνολο δεδομένων):
# Implement retriever
def get_context_source(question, topN=3):
"""
Retrieves contextual information and sources related to a given question using embeddings and a vector search.
Parameters:
question (str): The question for which the context and sources are to be retrieved.
topN (int, optional): The number of top results to retrieve. Default is 3.
Returns:
List: A list containing two elements:
1. A string with the concatenated retrieved context.
2. A list of retrieved source paths.
"""
embed_client = openai.AzureOpenAI(
api_version=aoai_api_version,
azure_endpoint=aoai_endpoint,
api_key=aoai_key,
)
query_embedding = embed_client.embeddings.create(input=question, model=aoai_deployment_name_embeddings).data[0].embedding
vector_query = VectorizedQuery(vector=query_embedding, k_nearest_neighbors=topN, fields="Embedding")
results = search_client.search(
vector_queries=[vector_query],
top=topN,
)
retrieved_context = ""
retrieved_sources = []
for result in results:
retrieved_context += result['ExtractedPath'] + "\n" + result['Chunk'] + "\n\n"
retrieved_sources.append(result['ExtractedPath'])
return [retrieved_context, retrieved_sources]
# Implement response generator
def get_answer(question, context):
"""
Generates a response to a given question using provided context and an Azure OpenAI model.
Parameters:
question (str): The question that needs to be answered.
context (str): The contextual information related to the question that will help generate a relevant response.
Returns:
str: The response generated by the Azure OpenAI model based on the provided question and context.
"""
messages = [
{
"role": "system",
"content": "You are a chat assistant. Use provided text to ground your response. Give a one-word answer when possible ('yes'/'no' is OK where appropriate, no details). Unnecessary words incur a $500 penalty."
}
]
messages.append(
{
"role": "user",
"content": question + "\n" + context,
},
)
chat_client = openai.AzureOpenAI(
azure_endpoint=aoai_endpoint,
api_key=aoai_key,
api_version=aoai_api_version,
)
chat_completion = chat_client.chat.completions.create(
model=aoai_model_name_query,
messages=messages,
)
return chat_completion.choices[0].message.content
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 8, Finished, Available, Finished)
Σύνολο δεδομένων
Η έκδοση 1.2 του συνόλου δεδομένων Question-Answer του Πανεπιστημίου Carnegie Mellon είναι ένα σώμα άρθρων της Wikipedia με πραγματικές ερωτήσεις και απαντήσεις γραμμένες χειροκίνητα. Φιλοξενείται στο Azure Blob Storage υπό την GFDL. Το σύνολο δεδομένων χρησιμοποιεί έναν πίνακα με αυτά τα πεδία:
-
ArticleTitle: Όνομα του άρθρου της Wikipedia από το οποίο προέρχονται οι ερωτήσεις και οι απαντήσεις -
Question: Χειροκίνητη γραπτή ερώτηση σχετικά με το άρθρο -
Answer: Χειροκίνητη γραπτή απάντηση με βάση το άρθρο -
DifficultyFromQuestioner: Δυσκολία βαθμολόγησης της ερώτησης που αναθέτει ο συγγραφέας -
DifficultyFromAnswerer: Βαθμός δυσκολίας που αναθέτει ο αξιολογητής. μπορεί να διαφέρει απόDifficultyFromQuestioner -
ExtractedPath: Διαδρομή προς το αρχικό άρθρο (ένα άρθρο μπορεί να έχει πολλά ζεύγη ερωτήσεων-απαντήσεων) -
text: Καθαρισμένο κείμενο άρθρου της Βικιπαίδειας
Κατεβάστε τα αρχεία LICENSE-S08 και LICENSE-S09 από την ίδια τοποθεσία για λεπτομέρειες άδειας χρήσης.
Ιστορία και παραπομπή
Χρησιμοποιήστε αυτήν την παραπομπή για το σύνολο δεδομένων:
CMU Question/Answer Dataset, Release 1.2
August 23, 2013
Noah A. Smith, Michael Heilman, and Rebecca Hwa
Question Generation as a Competitive Undergraduate Course Project
In Proceedings of the NSF Workshop on the Question Generation Shared Task and Evaluation Challenge, Arlington, VA, September 2008.
Available at http://www.cs.cmu.edu/~nasmith/papers/smith+heilman+hwa.nsf08.pdf.
Original dataset acknowledgments:
This research project was supported by NSF IIS-0713265 (to Smith), an NSF Graduate Research Fellowship (to Heilman), NSF IIS-0712810 and IIS-0745914 (to Hwa), and Institute of Education Sciences, U.S. Department of Education R305B040063 (to Carnegie Mellon).
cmu-qa-08-09 (modified version)
June 12, 2024
Amir Jafari, Alexandra Savelieva, Brice Chung, Hossein Khadivi Heris, Journey McDowell
This release uses the GNU Free Documentation License (GFDL) (http://www.gnu.org/licenses/fdl.html).
The GNU license applies to all copies of the dataset.
Δημιουργία σημείου αναφοράς
Εισαγάγετε το σημείο αναφοράς. Για αυτήν την επίδειξη, χρησιμοποιήστε ένα υποσύνολο ερωτήσεων από τους S08/set1 κάδους και S08/set2 . Για να κρατήσετε μία ερώτηση ανά άρθρο, κάντε αίτηση df.dropDuplicates(["ExtractedPath"]). Αφήστε διπλές ερωτήσεις. Η διαδικασία επιμέλειας προσθέτει ετικέτες δυσκολίας. Αυτό το παράδειγμα τα περιορίζει σε medium.
df = spark.sql("SELECT * FROM data_load_tests.cmu_qa")
# Filter the DataFrame to include the specified paths
df = df.filter((col("ExtractedPath").like("S08/data/set1/%")) | (col("ExtractedPath").like("S08/data/set2/%")))
# Keep only medium-difficulty questions.
df = df.filter(col("DifficultyFromQuestioner") == "medium")
# Drop duplicate questions and source paths.
df = df.dropDuplicates(["Question"])
df = df.dropDuplicates(["ExtractedPath"])
num_rows = df.count()
num_columns = len(df.columns)
print(f"Number of rows: {num_rows}, Number of columns: {num_columns}")
# Persist the DataFrame
df.persist()
display(df)
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 9, Finished, Available, Finished)Number of rows: 20, Number of columns: 7SynapseWidget(Synapse.DataFrame, 47aff8cb-72f8-4a36-885c-f4f3bb830a91)
Το αποτέλεσμα είναι ένα DataFrame με 20 σειρές - το σημείο αναφοράς επίδειξης. Τα βασικά πεδία είναι Question, Answer (απάντηση βασικής αλήθειας επιμελημένη από τον άνθρωπο) και ExtractedPath (το έγγραφο πηγής). Προσαρμόστε τα φίλτρα για να συμπεριλάβετε άλλες ερωτήσεις και διαφοροποιήστε τη δυσκολία για ένα πιο ρεαλιστικό παράδειγμα. Δοκίμασέ το.
Εκτελέστε μια απλή δοκιμή από άκρο σε άκρο
Ξεκινήστε με μια δοκιμή καπνού από άκρο σε άκρο της επαυξημένης παραγωγής ανάκτησης (RAG).
question = "How many suborders are turtles divided into?"
retrieved_context, retrieved_sources = get_context_source(question)
answer = get_answer(question, retrieved_context)
print(answer)
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 10, Finished, Available, Finished)Three
Αυτή η δοκιμή καπνού σάς βοηθά να βρείτε ζητήματα στην υλοποίηση RAG, όπως λανθασμένα διαπιστευτήρια, διανυσματικό ευρετήριο που λείπει ή είναι κενό ή μη συμβατές διεπαφές συναρτήσεων. Εάν η δοκιμή αποτύχει, ελέγξτε για προβλήματα. Αναμενόμενη παραγωγή: Three. Εάν η δοκιμή καπνού περάσει, μεταβείτε στην επόμενη ενότητα για να αξιολογήσετε περαιτέρω το RAG.
Καθιέρωση μετρήσεων
Ορίστε μια ντετερμινιστική μέτρηση για την αξιολόγηση του ριτρίβερ. Είναι εμπνευσμένο από τις μηχανές αναζήτησης. Ελέγχει εάν η λίστα πηγών που ανακτήθηκαν περιλαμβάνει την πηγή της βασικής αλήθειας. Αυτή η μέτρηση είναι μια κορυφαία βαθμολογία ακρίβειας, επειδή η topN παράμετρος ορίζει τον αριθμό των πηγών που ανακτώνται.
def get_retrieval_score(target_source, retrieved_sources):
if target_source in retrieved_sources:
return 1
else:
return 0
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 11, Finished, Available, Finished)
Σύμφωνα με το σημείο αναφοράς, η απάντηση περιέχεται στην πηγή με αναγνωριστικό "S08/data/set1/a9". Η δοκιμή της συνάρτησης στο παράδειγμα που εκτελέσαμε παραπάνω επιστρέφει 1, όπως αναμενόταν, επειδή ήταν στα τρία πρώτα σχετικά κομμάτια κειμένου.
print("Retrieved sources:", retrieved_sources)
get_retrieval_score("S08/data/set1/a9", retrieved_sources)
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 12, Finished, Available, Finished)Retrieved sources: ['S08/data/set1/a9', 'S08/data/set1/a9', 'S08/data/set1/a5']1
Αυτή η ενότητα ορίζει μετρήσεις με τη βοήθεια AI. Το πρότυπο προτροπής περιλαμβάνει μερικά παραδείγματα εισόδου (CONTEXT και ANSWER) και προτεινόμενης εξόδου - γνωστό και ως μοντέλο λίγων λήψεων. Είναι η ίδια προτροπή που χρησιμοποιείται στο Azure AI Studio. Μάθετε περισσότερα στην ενότητα Ενσωματωμένα μετρικά αξιολόγησης. Αυτή η επίδειξη χρησιμοποιεί τις groundedness μετρήσεις και relevance - αυτές είναι συνήθως οι πιο χρήσιμες και αξιόπιστες για την αξιολόγηση μοντέλων GPT. Άλλες μετρήσεις μπορεί να είναι χρήσιμες, αλλά παρέχουν λιγότερη διαίσθηση - για παράδειγμα, οι απαντήσεις δεν χρειάζεται να είναι παρόμοιες για να είναι σωστές, επομένως similarity οι βαθμολογίες μπορεί να είναι παραπλανητικές. Η κλίμακα για όλες τις μετρήσεις είναι από το 1 έως το 5. Όσο πιο ψηλά τόσο καλύτερα. Η γείωση λαμβάνει μόνο δύο εισόδους (πλαίσιο και παραγόμενη απάντηση), ενώ οι άλλες δύο μετρήσεις χρησιμοποιούν επίσης τη βασική αλήθεια για αξιολόγηση.
def get_groundedness_metric(context, answer):
"""Get the groundedness score from the LLM using the context and answer."""
groundedness_prompt_template = """
You are presented with a CONTEXT and an ANSWER about that CONTEXT. Decide whether the ANSWER is entailed by the CONTEXT by choosing one of the following ratings:
1. 5: The ANSWER follows logically from the information contained in the CONTEXT.
2. 1: The ANSWER is logically false from the information contained in the CONTEXT.
3. an integer score between 1 and 5 and if such integer score does not exist, use 1: It is not possible to determine whether the ANSWER is true or false without further information. Read the passage of information thoroughly and select the correct answer from the three answer labels. Read the CONTEXT thoroughly to ensure you know what the CONTEXT entails. Note the ANSWER is generated by a computer system, it can contain certain symbols, which should not be a negative factor in the evaluation.
Independent Examples:
## Example Task #1 Input:
"CONTEXT": "Some are reported as not having been wanted at all.", "QUESTION": "", "ANSWER": "All are reported as being completely and fully wanted."
## Example Task #1 Output:
1
## Example Task #2 Input:
"CONTEXT": "Ten new television shows appeared during the month of September. Five of the shows were sitcoms, three were hourlong dramas, and two were news-magazine shows. By January, only seven of these new shows were still on the air. Five of the shows that remained were sitcoms.", "QUESTION": "", "ANSWER": "At least one of the shows that were cancelled was an hourlong drama."
## Example Task #2 Output:
5
## Example Task #3 Input:
"CONTEXT": "In Quebec, an allophone is a resident, usually an immigrant, whose mother tongue or home language is neither French nor English.", "QUESTION": "", "ANSWER": "In Quebec, an allophone is a resident, usually an immigrant, whose mother tongue or home language is not French."
5
## Example Task #4 Input:
"CONTEXT": "Some are reported as not having been wanted at all.", "QUESTION": "", "ANSWER": "All are reported as being completely and fully wanted."
## Example Task #4 Output:
1
## Actual Task Input:
"CONTEXT": {context}, "QUESTION": "", "ANSWER": {answer}
Reminder: The return values for each task should be correctly formatted as an integer between 1 and 5. Do not repeat the context and question. Don't explain the reasoning. The answer should include only a number: 1, 2, 3, 4, or 5.
Actual Task Output:
"""
metric_client = openai.AzureOpenAI(
api_version=aoai_api_version,
azure_endpoint=aoai_endpoint,
api_key=aoai_key,
)
messages = [
{
"role": "system",
"content": "You are an AI assistant. You will be given the definition of an evaluation metric for assessing the quality of an answer in a question-answering task. Your job is to compute an accurate evaluation score using the provided evaluation metric."
},
{
"role": "user",
"content": groundedness_prompt_template.format(context=context, answer=answer)
}
]
metric_completion = metric_client.chat.completions.create(
model=aoai_model_name_metrics,
messages=messages,
temperature=0,
)
return metric_completion.choices[0].message.content
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 13, Finished, Available, Finished)
def get_relevance_metric(context, question, answer):
relevance_prompt_template = """
Relevance measures how well the answer addresses the main aspects of the question, based on the context. Consider whether all and only the important aspects are contained in the answer when evaluating relevance. Given the context and question, score the relevance of the answer between one to five stars using the following rating scale:
One star: the answer completely lacks relevance
Two stars: the answer mostly lacks relevance
Three stars: the answer is partially relevant
Four stars: the answer is mostly relevant
Five stars: the answer has perfect relevance
This rating value should always be an integer between 1 and 5. So the rating produced should be 1 or 2 or 3 or 4 or 5.
context: Marie Curie was a Polish-born physicist and chemist who pioneered research on radioactivity and was the first woman to win a Nobel Prize.
question: What field did Marie Curie excel in?
answer: Marie Curie was a renowned painter who focused mainly on impressionist styles and techniques.
stars: 1
context: The Beatles were an English rock band formed in Liverpool in 1960, and they are widely regarded as the most influential music band in history.
question: Where were The Beatles formed?
answer: The band The Beatles began their journey in London, England, and they changed the history of music.
stars: 2
context: The recent Mars rover, Perseverance, was launched in 2020 with the main goal of searching for signs of ancient life on Mars. The rover also carries an experiment called MOXIE, which aims to generate oxygen from the Martian atmosphere.
question: What are the main goals of Perseverance Mars rover mission?
answer: The Perseverance Mars rover mission focuses on searching for signs of ancient life on Mars.
stars: 3
context: The Mediterranean diet is a commonly recommended dietary plan that emphasizes fruits, vegetables, whole grains, legumes, lean proteins, and healthy fats. Studies have shown that it offers numerous health benefits, including a reduced risk of heart disease and improved cognitive health.
question: What are the main components of the Mediterranean diet?
answer: The Mediterranean diet primarily consists of fruits, vegetables, whole grains, and legumes.
stars: 4
context: The Queen's Royal Castle is a well-known tourist attraction in the United Kingdom. It spans over 500 acres and contains extensive gardens and parks. The castle was built in the 15th century and has been home to generations of royalty.
question: What are the main attractions of the Queen's Royal Castle?
answer: The main attractions of the Queen's Royal Castle are its expansive 500-acre grounds, extensive gardens, parks, and the historical castle itself, which dates back to the 15th century and has housed generations of royalty.
stars: 5
Don't explain the reasoning. The answer should include only a number: 1, 2, 3, 4, or 5.
context: {context}
question: {question}
answer: {answer}
stars:
"""
metric_client = openai.AzureOpenAI(
api_version=aoai_api_version,
azure_endpoint=aoai_endpoint,
api_key=aoai_key,
)
messages = [
{
"role": "system",
"content": "You are an AI assistant. You are given the definition of an evaluation metric for assessing the quality of an answer in a question-answering task. Compute an accurate evaluation score using the provided evaluation metric."
},
{
"role": "user",
"content": relevance_prompt_template.format(context=context, question=question, answer=answer)
}
]
metric_completion = metric_client.chat.completions.create(
model=aoai_model_name_metrics,
messages=messages,
temperature=0,
)
return metric_completion.choices[0].message.content
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 14, Finished, Available, Finished)
def get_similarity_metric(question, ground_truth, answer):
similarity_prompt_template = """
Equivalence, as a metric, measures the similarity between the predicted answer and the correct answer. If the information and content in the predicted answer is similar or equivalent to the correct answer, then the value of the Equivalence metric should be high, else it should be low. Given the question, correct answer, and predicted answer, determine the value of Equivalence metric using the following rating scale:
One star: the predicted answer is not at all similar to the correct answer
Two stars: the predicted answer is mostly not similar to the correct answer
Three stars: the predicted answer is somewhat similar to the correct answer
Four stars: the predicted answer is mostly similar to the correct answer
Five stars: the predicted answer is completely similar to the correct answer
This rating value should always be an integer between 1 and 5. So the rating produced should be 1 or 2 or 3 or 4 or 5.
The examples below show the Equivalence score for a question, a correct answer, and a predicted answer.
question: What is the role of ribosomes?
correct answer: Ribosomes are cellular structures responsible for protein synthesis. They interpret the genetic information carried by messenger RNA (mRNA) and use it to assemble amino acids into proteins.
predicted answer: Ribosomes participate in carbohydrate breakdown by removing nutrients from complex sugar molecules.
stars: 1
question: Why did the Titanic sink?
correct answer: The Titanic sank after it struck an iceberg during its maiden voyage in 1912. The impact caused the ship's hull to breach, allowing water to flood into the vessel. The ship's design, lifeboat shortage, and lack of timely rescue efforts contributed to the tragic loss of life.
predicted answer: The sinking of the Titanic was a result of a large iceberg collision. This caused the ship to take on water and eventually sink, leading to the death of many passengers due to a shortage of lifeboats and insufficient rescue attempts.
stars: 2
question: What causes seasons on Earth?
correct answer: Seasons on Earth are caused by the tilt of the Earth's axis and its revolution around the Sun. As the Earth orbits the Sun, the tilt causes different parts of the planet to receive varying amounts of sunlight, resulting in changes in temperature and weather patterns.
predicted answer: Seasons occur because of the Earth's rotation and its elliptical orbit around the Sun. The tilt of the Earth's axis causes regions to be subjected to different sunlight intensities, which leads to temperature fluctuations and alternating weather conditions.
stars: 3
question: How does photosynthesis work?
correct answer: Photosynthesis is a process by which green plants and some other organisms convert light energy into chemical energy. This occurs as light is absorbed by chlorophyll molecules, and then carbon dioxide and water are converted into glucose and oxygen through a series of reactions.
predicted answer: In photosynthesis, sunlight is transformed into nutrients by plants and certain microorganisms. Light is captured by chlorophyll molecules, followed by the conversion of carbon dioxide and water into sugar and oxygen through multiple reactions.
stars: 4
question: What are the health benefits of regular exercise?
correct answer: Regular exercise can help maintain a healthy weight, increase muscle and bone strength, and reduce the risk of chronic diseases. It also promotes mental well-being by reducing stress and improving overall mood.
predicted answer: Routine physical activity can contribute to maintaining ideal body weight, enhancing muscle and bone strength, and preventing chronic illnesses. In addition, it supports mental health by alleviating stress and augmenting general mood.
stars: 5
Don't explain the reasoning. The answer should include only a number: 1, 2, 3, 4, or 5.
question: {question}
correct answer:{ground_truth}
predicted answer: {answer}
stars:
"""
metric_client = openai.AzureOpenAI(
api_version=aoai_api_version,
azure_endpoint=aoai_endpoint,
api_key=aoai_key,
)
messages = [
{
"role": "system",
"content": "You are an AI assistant. You will be given the definition of an evaluation metric for assessing the quality of an answer in a question-answering task. Your job is to compute an accurate evaluation score using the provided evaluation metric."
},
{
"role": "user",
"content": similarity_prompt_template.format(question=question, ground_truth=ground_truth, answer=answer)
}
]
metric_completion = metric_client.chat.completions.create(
model=aoai_model_name_metrics,
messages=messages,
temperature=0,
)
return metric_completion.choices[0].message.content
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 15, Finished, Available, Finished)
Δοκιμάστε τη μέτρηση συνάφειας:
get_relevance_metric(retrieved_context, question, answer)
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 16, Finished, Available, Finished)'2'
Η βαθμολογία 5 σημαίνει ότι η απάντηση είναι σχετική. Ο παρακάτω κώδικας λαμβάνει τη μέτρηση ομοιότητας:
get_similarity_metric(question, 'three', answer)
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 17, Finished, Available, Finished)'5'
Η βαθμολογία 5 σημαίνει ότι η απάντηση ταιριάζει με την απάντηση της βασικής αλήθειας που επιμελήθηκε ένας ανθρώπινος ειδικός. Οι βαθμολογίες μετρήσεων με τη βοήθεια AI μπορεί να κυμαίνονται με την ίδια είσοδο. Είναι πιο γρήγοροι από τη χρήση ανθρώπινων κριτών.
Αξιολογήστε την απόδοση των RAG στις ερωτήσεις και απαντήσεις αναφοράς
Δημιουργήστε περιτυλίγματα συναρτήσεων για εκτέλεση σε κλίμακα. Αναδιπλώστε κάθε συνάρτηση που τελειώνει σε _udf (συντομογραφία του user-defined function) ώστε να συμμορφώνεται με τις απαιτήσεις του Spark (@udf(returnType=StructType([ ... ]))) και να εκτελεί υπολογισμούς σε μεγάλα δεδομένα πιο γρήγορα σε όλο το σύμπλεγμα.
# UDF wrappers for RAG components
@udf(returnType=StructType([
StructField("retrieved_context", StringType(), True),
StructField("retrieved_sources", ArrayType(StringType()), True)
]))
def get_context_source_udf(question, topN=3):
return get_context_source(question, topN)
@udf(returnType=StringType())
def get_answer_udf(question, context):
return get_answer(question, context)
# UDF wrapper for retrieval score
@udf(returnType=StringType())
def get_retrieval_score_udf(target_source, retrieved_sources):
return get_retrieval_score(target_source, retrieved_sources)
# UDF wrappers for AI-assisted metrics
@udf(returnType=StringType())
def get_groundedness_metric_udf(context, answer):
return get_groundedness_metric(context, answer)
@udf(returnType=StringType())
def get_relevance_metric_udf(context, question, answer):
return get_relevance_metric(context, question, answer)
@udf(returnType=StringType())
def get_similarity_metric_udf(question, ground_truth, answer):
return get_similarity_metric(question, ground_truth, answer)
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 18, Finished, Available, Finished)
Check-in #1: απόδοση του ριτρίβερ
Ο παρακάτω κώδικας δημιουργεί τις result στήλες και retrieval_score στο DataFrame συγκριτικής αξιολόγησης. Αυτές οι στήλες περιλαμβάνουν την απάντηση που δημιουργήθηκε από το RAG και έναν δείκτη για το εάν το πλαίσιο που παρέχεται στο LLM περιλαμβάνει το άρθρο στο οποίο βασίζεται η ερώτηση.
df = df.withColumn("result", get_context_source_udf(df.Question)).select(df.columns+["result.*"])
df = df.withColumn('retrieval_score', get_retrieval_score_udf(df.ExtractedPath, df.retrieved_sources))
print("Aggregate Retrieval score: {:.2f}%".format((df.where(df["retrieval_score"] == 1).count() / df.count()) * 100))
display(df.select(["question", "retrieval_score", "ExtractedPath", "retrieved_sources"]))
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 19, Finished, Available, Finished)Aggregate Retrieval score: 100.00%SynapseWidget(Synapse.DataFrame, 14efe386-836a-4765-bd88-b121f32c7cfc)
Για όλες τις ερωτήσεις, το ριτρίβερ ανακτά το σωστό πλαίσιο και στις περισσότερες περιπτώσεις είναι η πρώτη καταχώρηση. Το Azure AI Search έχει καλή απόδοση. Ίσως αναρωτιέστε γιατί, σε ορισμένες περιπτώσεις, το πλαίσιο έχει δύο ή τρεις ίδιες τιμές. Αυτό δεν είναι λάθος - σημαίνει ότι το ριτρίβερ ανακτά θραύσματα του ίδιου άρθρου που δεν χωρούν σε ένα κομμάτι κατά τη διάσπαση.
Check-in #2: απόδοση της γεννήτριας απόκρισης
Περάστε την ερώτηση και το πλαίσιο στο LLM για να δημιουργήσετε μια απάντηση. Αποθηκεύστε το generated_answer στη στήλη του DataFrame:
df = df.withColumn('generated_answer', get_answer_udf(df.Question, df.retrieved_context))
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 20, Finished, Available, Finished)
Χρησιμοποιήστε την απάντηση που δημιουργήθηκε, την απάντηση βάσης-αλήθειας, την ερώτηση και το πλαίσιο για να υπολογίσετε μετρήσεις. Εμφάνιση αποτελεσμάτων αξιολόγησης για κάθε ζεύγος ερωτήσεων-απαντήσεων:
df = df.withColumn('gpt_groundedness', get_groundedness_metric_udf(df.retrieved_context, df.generated_answer))
df = df.withColumn('gpt_relevance', get_relevance_metric_udf(df.retrieved_context, df.Question, df.generated_answer))
df = df.withColumn('gpt_similarity', get_similarity_metric_udf(df.Question, df.Answer, df.generated_answer))
display(df.select(["question", "answer", "generated_answer", "retrieval_score", "gpt_groundedness","gpt_relevance", "gpt_similarity"]))
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 21, Finished, Available, Finished)SynapseWidget(Synapse.DataFrame, 22b97d27-91e1-40f3-b888-3a3399de9d6b)
Τι δείχνουν αυτές οι αξίες; Για να διευκολύνετε την ερμηνεία τους, σχεδιάστε ιστογράμματα γείωσης, συνάφειας και ομοιότητας. Το LLM είναι πιο αναλυτικό από τις ανθρώπινες απαντήσεις βασικής αλήθειας, γεγονός που μειώνει τη μέτρηση ομοιότητας - περίπου οι μισές απαντήσεις είναι σημασιολογικά σωστές, αλλά λαμβάνουν τέσσερα αστέρια ως ως επί το πλείστον παρόμοιες. Οι περισσότερες τιμές και για τις τρεις μετρήσεις είναι 4 ή 5, γεγονός που υποδηλώνει ότι η απόδοση του RAG είναι καλή. Υπάρχουν μερικές ακραίες τιμές - για παράδειγμα, για την ερώτηση How many species of otter are there?, το μοντέλο που δημιουργήθηκε There are 13 species of otter, το οποίο είναι σωστό με υψηλή συνάφεια και ομοιότητα (5). Για κάποιο λόγο, το GPT το θεώρησε κακώς θεμελιωμένο στο παρεχόμενο πλαίσιο και του έδωσε ένα αστέρι. Στις άλλες τρεις περιπτώσεις με τουλάχιστον μία μέτρηση ενός αστεριού με τη βοήθεια τεχνητής νοημοσύνης, η χαμηλή βαθμολογία δείχνει κακή απάντηση. Το LLM περιστασιακά βαθμολογεί λάθος, αλλά συνήθως βαθμολογείται με ακρίβεια.
# Convert Spark DataFrame to Pandas DataFrame
pandas_df = df.toPandas()
selected_columns = ['gpt_groundedness', 'gpt_relevance', 'gpt_similarity']
trimmed_df = pandas_df[selected_columns].astype(int)
# Define a function to plot histograms for the specified columns
def plot_histograms(dataframe, columns):
# Set up the figure size and subplots
plt.figure(figsize=(15, 5))
for i, column in enumerate(columns, 1):
plt.subplot(1, len(columns), i)
# Filter the dataframe to only include rows with values 1, 2, 3, 4, 5
filtered_df = dataframe[dataframe[column].isin([1, 2, 3, 4, 5])]
filtered_df[column].hist(bins=range(1, 7), align='left', rwidth=0.8)
plt.title(f'Histogram of {column}')
plt.xlabel('Values')
plt.ylabel('Frequency')
plt.xticks(range(1, 6))
plt.yticks(range(0, 20, 2))
# Call the function to plot histograms for the specified columns
plot_histograms(trimmed_df, selected_columns)
# Show the plots
plt.tight_layout()
plt.show()
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 24, Finished, Available, Finished)
Ως τελευταίο βήμα, αποθηκεύστε τα αποτελέσματα συγκριτικής αξιολόγησης σε έναν πίνακα στο lakehouse σας. Αυτό το βήμα είναι προαιρετικό αλλά συνιστάται ιδιαίτερα - κάνει τα ευρήματά σας πιο χρήσιμα. Όταν αλλάζετε κάτι στο RAG (για παράδειγμα, τροποποιείτε την προτροπή, ενημερώνετε το ευρετήριο ή χρησιμοποιείτε διαφορετικό μοντέλο GPT στη γεννήτρια απόκρισης), μετράτε τον αντίκτυπο, ποσοτικοποιείτε τις βελτιώσεις και εντοπίζετε παλινδρομήσεις.
# create name of experiment that is easy to refer to
friendly_name_of_experiment = "rag_tutorial_experiment_1"
# Note the current date and time
time_of_experiment = current_timestamp()
# Generate a unique GUID for all rows
experiment_id = str(uuid.uuid4())
# Add two new columns to the Spark DataFrame
updated_df = df.withColumn("execution_time", time_of_experiment) \
.withColumn("experiment_id", lit(experiment_id)) \
.withColumn("experiment_friendly_name", lit(friendly_name_of_experiment))
# Store the updated DataFrame in the default lakehouse as a table named 'rag_experiment_runs'
table_name = "rag_experiment_run_demo1"
updated_df.write.format("parquet").mode("append").saveAsTable(table_name)
Έξοδος κυψέλης:StatementMeta(, 21cb8cd3-7742-4c1f-8339-265e2846df1d, 28, Finished, Available, Finished)
Επιστρέψτε στα αποτελέσματα του πειράματος ανά πάσα στιγμή, για να τα ελέγξετε, να τα συγκρίνετε με νέα πειράματα και να επιλέξετε τη διαμόρφωση που λειτουργεί καλύτερα για την παραγωγή.
Summary
Χρησιμοποιήστε μετρήσεις με τη βοήθεια AI και ποσοστό ανάκτησης top-N για να δημιουργήσετε τη λύση ανάκτησης επαυξημένης γενιάς (RAG).