From 86713239dd32c1c9e0c0c70aa80da91f3297590c Mon Sep 17 00:00:00 2001 From: Catherine Brooks Date: Tue, 12 Mar 2024 23:26:56 -0500 Subject: [PATCH 1/4] Evaluates gold datasets --- .../evaluate/test_evaluate_gold_dataset.py | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 packages/googlecloud/functions/getanswer/evaluate/test_evaluate_gold_dataset.py diff --git a/packages/googlecloud/functions/getanswer/evaluate/test_evaluate_gold_dataset.py b/packages/googlecloud/functions/getanswer/evaluate/test_evaluate_gold_dataset.py new file mode 100644 index 0000000..6cb2c32 --- /dev/null +++ b/packages/googlecloud/functions/getanswer/evaluate/test_evaluate_gold_dataset.py @@ -0,0 +1,108 @@ +""" +usage: 'deepeval test run test_evaluate_gold_dataset.py' + + +This will read test queries from file inputted by user, then evaluate the responses according +to several metrics as implemented by the deepeval library and gpt-3.5-turbo-1106 + +All hyperparameters used by current model are logged in deepeval login + +""" +import pytest +import deepeval +import logging +import sys +import os + +sys.path.append(os.path.join(os.path.dirname(__file__), "../")) + +from deepeval import assert_test +from deepeval.dataset import EvaluationDataset +from deepeval.metrics import AnswerRelevancyMetric, BiasMetric, ContextualRelevancyMetric, FaithfulnessMetric, GEval, ContextualPrecisionMetric, ContextualRecallMetric +from deepeval.test_case import LLMTestCase, LLMTestCaseParams +from inquirer import route_question +from helper import get_dbs +from inquirer import INDEPTH_RESPONSE_LLM, INDEPTH_RESPONSE_PROMPT_TEMPLATE, INDEPTH_RESPONSE_K +from api import RESPONSE_TYPE_DEPTH + +logger = logging.getLogger(__name__) + + +# model to use for evaluating responses +MODEL = 'gpt-3.5-turbo-1106' + + +def get_test_cases(): + """ + Run sawt on all test queries and create LLMTestCases for each. + """ + test_cases = [] + db_fc, db_cj, db_pdf, db_pc, db_news, voting_roll_df = get_dbs() + + csv_file_name = input("Enter the name or path of your csv file of queries (ex: queries.csv):") + if not os.path.exists(csv_file_name): + print("\nThe file ", csv_file_name, " doesn't exist, check the path or name.") + sys.exit() + logger.info('generating answers to all test queries...') + + + for row in open(csv_file_name): + query, expected_output = row.strip().split(',') #read in line split by comma + actual_output, retrieval_context = route_question( + voting_roll_df, + db_fc, + db_cj, + db_pdf, + db_pc, + db_news, + query, + RESPONSE_TYPE_DEPTH, + k=5, + return_context=True + ) + # get single string for text response. + actual_output = ' '.join(i['response'] for i in actual_output['responses']) + test_cases.append(LLMTestCase(input=query, actual_output=actual_output, expected_output=expected_output, retrieval_context=[retrieval_context])) + + return EvaluationDataset(test_cases=test_cases) + +dataset = get_test_cases() + + +@pytest.mark.parametrize( + "test_case", + dataset, +) +def test_dataset(test_case: LLMTestCase): + contextual_precision = ContextualPrecisionMetric(threshold=0.2, model=MODEL) + contextual_recall = ContextualRecallMetric(threshold=0.2, model=MODEL) + + answer_relevancy = AnswerRelevancyMetric(threshold=0.2, model=MODEL) + bias = BiasMetric(threshold=0.5, model=MODEL) + contextual_relevancy = ContextualRelevancyMetric(threshold=0.7, include_reason=True, model=MODEL) + faithfulness = FaithfulnessMetric(threshold=0.7, include_reason=True, model=MODEL) + + readability = GEval(name="Readability", + criteria="Determine whether the text in 'actual output' is easy to read for those with a high school reading level.", + evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT], + model=MODEL) + + + punctuation = GEval(name="Punctuation", + criteria="Determine whether the text in 'actual output' has proper punctuation.", + evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT], + model=MODEL) + + opinions = GEval(name="Number of Opinions", + criteria="Determine whether the text in 'actual output' expresses more than one opinion on the topic of the query.", + evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT], + model=MODEL) + + assert_test(test_case, [contextual_recall, contextual_precision, answer_relevancy, bias, contextual_relevancy, faithfulness,readability, punctuation, opinions]) + + +# Log hyperparameters so we can compare across different test runs in deepeval login +@deepeval.log_hyperparameters(model=INDEPTH_RESPONSE_LLM.model_name, prompt_template=INDEPTH_RESPONSE_PROMPT_TEMPLATE.template) +def hyperparameters(): + return {'k': INDEPTH_RESPONSE_K} + From 9b6b9f46925085a8acf1e2a6abb8038a0ca13c43 Mon Sep 17 00:00:00 2001 From: hayden outlaw Date: Sat, 16 Mar 2024 12:09:13 -0500 Subject: [PATCH 2/4] collapsing csv and test_gold_data test scrips into one file called test_evaluate_tsv --- .../getanswer/evaluate/small_data.tsv | 3 + .../getanswer/evaluate/test_evaluate_csv.py | 105 ------------------ ...e_gold_dataset.py => test_evaluate_tsv.py} | 49 ++++---- .../googlecloud/functions/getanswer/helper.py | 10 +- 4 files changed, 36 insertions(+), 131 deletions(-) create mode 100644 packages/googlecloud/functions/getanswer/evaluate/small_data.tsv delete mode 100644 packages/googlecloud/functions/getanswer/evaluate/test_evaluate_csv.py rename packages/googlecloud/functions/getanswer/evaluate/{test_evaluate_gold_dataset.py => test_evaluate_tsv.py} (73%) diff --git a/packages/googlecloud/functions/getanswer/evaluate/small_data.tsv b/packages/googlecloud/functions/getanswer/evaluate/small_data.tsv new file mode 100644 index 0000000..fce4a45 --- /dev/null +++ b/packages/googlecloud/functions/getanswer/evaluate/small_data.tsv @@ -0,0 +1,3 @@ +Query Expected Response +What is a Proviso? A proviso is a condition or stipulation added to an agreement or statement, often to clarify or restrict its application or meaning. It's commonly used to specify certain terms or requirements that must be met for something to be valid or applicable. In legal documents, contracts, and agreements, provisos are frequently included to define exceptions, limitations, or special circumstances that affect the overall terms or obligations outlined in the document. Essentially, a proviso serves as a qualifier or caveat within a larger context. +Where is New Orleans? \ No newline at end of file diff --git a/packages/googlecloud/functions/getanswer/evaluate/test_evaluate_csv.py b/packages/googlecloud/functions/getanswer/evaluate/test_evaluate_csv.py deleted file mode 100644 index 432a527..0000000 --- a/packages/googlecloud/functions/getanswer/evaluate/test_evaluate_csv.py +++ /dev/null @@ -1,105 +0,0 @@ -""" -usage: 'deepeval test run test_evaluate_csv.py - - -This will read test queries from file inputted by user, then evaluate the responses according -to several metrics as implemented by the deepeval library and gpt-3.5-turbo-1106 - -All hyperparameters used by current model are logged in deepeval login - -""" -import pytest -import deepeval -import logging -import sys -import os - -sys.path.append(os.path.join(os.path.dirname(__file__), "../")) - -from deepeval import assert_test -from deepeval.dataset import EvaluationDataset -from deepeval.metrics import AnswerRelevancyMetric, BiasMetric, ContextualRelevancyMetric, FaithfulnessMetric, GEval -from deepeval.test_case import LLMTestCase, LLMTestCaseParams -from inquirer import route_question -from helper import get_dbs -from inquirer import INDEPTH_RESPONSE_LLM, INDEPTH_RESPONSE_PROMPT_TEMPLATE, INDEPTH_RESPONSE_K -from api import RESPONSE_TYPE_DEPTH - -logger = logging.getLogger(__name__) - - -# model to use for evaluating responses -MODEL = 'gpt-3.5-turbo-1106' - - -def get_test_cases(): - """ - Run sawt on all test queries and create LLMTestCases for each. - """ - test_cases = [] - db_fc, db_cj, db_pdf, db_pc, db_news, voting_roll_df = get_dbs() - - csv_file_name = input("Enter the name or path of your csv file of queries (ex: queries.csv):") - if not os.path.exists(csv_file_name): - print("\nThe file ", csv_file_name, " doesn't exist, check the path or name.") - sys.exit() - logger.info('generating answers to all test queries...') - - - for query in open(csv_file_name): - query = query.strip() - actual_output, retrieval_context = route_question( - voting_roll_df, - db_fc, - db_cj, - db_pdf, - db_pc, - db_news, - query, - RESPONSE_TYPE_DEPTH, - k=5, - return_context=True - ) - # get single string for text response. - actual_output = ' '.join(i['response'] for i in actual_output['responses']) - test_cases.append(LLMTestCase(input=query, actual_output=actual_output, retrieval_context=[retrieval_context])) - - return EvaluationDataset(test_cases=test_cases) - -dataset = get_test_cases() - - -@pytest.mark.parametrize( - "test_case", - dataset, -) -def test_dataset(test_case: LLMTestCase): - ansRel = AnswerRelevancyMetric(threshold=0.2, model=MODEL) - bias = BiasMetric(threshold=0.5, model=MODEL) - contRel = ContextualRelevancyMetric(threshold=0.7, include_reason=True, model=MODEL) - faithMet = FaithfulnessMetric(threshold=0.7, include_reason=True, model=MODEL) - - readability = GEval(name="Readability", - criteria="Determine whether the text in 'actual output' is easy to read for those with a high school reading level.", - evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT], - model=MODEL) - - - punctuation = GEval(name="Punctuation", - criteria="Determine whether the text in 'actual output' has proper punctuation.", - evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT], - model=MODEL) - - opinions = GEval(name="Number of Opinions", - criteria="Determine whether the text in 'actual output' expresses more than one opinion on the topic of the query.", - evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT], - model=MODEL) - - assert_test(test_case, [ansRel, bias, contRel, faithMet,readability, punctuation, opinions]) - - -# Log hyperparameters so we can compare across different test runs in deepeval login -@deepeval.log_hyperparameters(model=INDEPTH_RESPONSE_LLM.model_name, prompt_template=INDEPTH_RESPONSE_PROMPT_TEMPLATE.template) -def hyperparameters(): - return {'k': INDEPTH_RESPONSE_K} - diff --git a/packages/googlecloud/functions/getanswer/evaluate/test_evaluate_gold_dataset.py b/packages/googlecloud/functions/getanswer/evaluate/test_evaluate_tsv.py similarity index 73% rename from packages/googlecloud/functions/getanswer/evaluate/test_evaluate_gold_dataset.py rename to packages/googlecloud/functions/getanswer/evaluate/test_evaluate_tsv.py index 6cb2c32..1d8c3e0 100644 --- a/packages/googlecloud/functions/getanswer/evaluate/test_evaluate_gold_dataset.py +++ b/packages/googlecloud/functions/getanswer/evaluate/test_evaluate_tsv.py @@ -39,30 +39,37 @@ def get_test_cases(): test_cases = [] db_fc, db_cj, db_pdf, db_pc, db_news, voting_roll_df = get_dbs() - csv_file_name = input("Enter the name or path of your csv file of queries (ex: queries.csv):") - if not os.path.exists(csv_file_name): - print("\nThe file ", csv_file_name, " doesn't exist, check the path or name.") + tsv_file_name = input("Enter the name or path of your tsv file of queries (ex: queries.tsv):") + if not os.path.exists(tsv_file_name): + print("\nThe file ", tsv_file_name, " doesn't exist, check the path or name.") sys.exit() logger.info('generating answers to all test queries...') - - for row in open(csv_file_name): - query, expected_output = row.strip().split(',') #read in line split by comma - actual_output, retrieval_context = route_question( - voting_roll_df, - db_fc, - db_cj, - db_pdf, - db_pc, - db_news, - query, - RESPONSE_TYPE_DEPTH, - k=5, - return_context=True - ) - # get single string for text response. - actual_output = ' '.join(i['response'] for i in actual_output['responses']) - test_cases.append(LLMTestCase(input=query, actual_output=actual_output, expected_output=expected_output, retrieval_context=[retrieval_context])) + with open(tsv_file_name) as file: + next(file) + for row in file: + row_obj = row.strip().split('\t') + if len(row_obj) == 1: + query = row_obj[0] + expected_output = '' + else: + query, expected_output = row_obj + + actual_output, retrieval_context = route_question( + voting_roll_df, + db_fc, + db_cj, + db_pdf, + db_pc, + db_news, + query, + RESPONSE_TYPE_DEPTH, + k=5, + return_context=True + ) + # get single string for text response + actual_output = ' '.join(i['response'] for i in actual_output['responses']) + test_cases.append(LLMTestCase(input=query, actual_output=actual_output, expected_output=expected_output, retrieval_context=[retrieval_context])) return EvaluationDataset(test_cases=test_cases) diff --git a/packages/googlecloud/functions/getanswer/helper.py b/packages/googlecloud/functions/getanswer/helper.py index e97989b..b1a4b70 100644 --- a/packages/googlecloud/functions/getanswer/helper.py +++ b/packages/googlecloud/functions/getanswer/helper.py @@ -39,11 +39,11 @@ def get_dbs(): faiss_news_index_path = dir.joinpath("cache/faiss_index_in_depth_news") # Loading new FAISS indices for each document type - db_fc = FAISS.load_local(faiss_fc_index_path, in_depth_embeddings) - db_cj = FAISS.load_local(faiss_cj_index_path, in_depth_embeddings) - db_pdf = FAISS.load_local(faiss_pdf_index_path, in_depth_embeddings) - db_pc = FAISS.load_local(faiss_pc_index_path, in_depth_embeddings) - db_news = FAISS.load_local(faiss_news_index_path, in_depth_embeddings) + db_fc = FAISS.load_local(faiss_fc_index_path, in_depth_embeddings, allow_dangerous_deserialization=True) + db_cj = FAISS.load_local(faiss_cj_index_path, in_depth_embeddings, allow_dangerous_deserialization=True) + db_pdf = FAISS.load_local(faiss_pdf_index_path, in_depth_embeddings, allow_dangerous_deserialization=True) + db_pc = FAISS.load_local(faiss_pc_index_path, in_depth_embeddings, allow_dangerous_deserialization=True) + db_news = FAISS.load_local(faiss_news_index_path, in_depth_embeddings, allow_dangerous_deserialization=True) voting_roll_df_path = dir.joinpath("cache/parsed_voting_rolls.csv") voting_roll_df = pd.read_csv(voting_roll_df_path) From 6c70c57f9245fd07b4c27018f68ebb4f27a78f7e Mon Sep 17 00:00:00 2001 From: Catherine Brooks Date: Tue, 16 Apr 2024 19:53:17 -0500 Subject: [PATCH 3/4] Updated README and deleted unneeded files --- .../functions/getanswer/evaluate/README.MD | 18 ++++++++++-------- .../functions/getanswer/evaluate/gpt4.xlsx | Bin 71292 -> 0 bytes .../getanswer/evaluate/small_data.tsv | 3 --- .../getanswer/evaluate/test_evaluate_live.py | 2 +- .../getanswer/evaluate/test_evaluate_tsv.py | 9 ++++++--- 5 files changed, 17 insertions(+), 15 deletions(-) delete mode 100644 packages/googlecloud/functions/getanswer/evaluate/gpt4.xlsx delete mode 100644 packages/googlecloud/functions/getanswer/evaluate/small_data.tsv diff --git a/packages/googlecloud/functions/getanswer/evaluate/README.MD b/packages/googlecloud/functions/getanswer/evaluate/README.MD index 8dfd760..b432287 100644 --- a/packages/googlecloud/functions/getanswer/evaluate/README.MD +++ b/packages/googlecloud/functions/getanswer/evaluate/README.MD @@ -8,25 +8,27 @@ Requires installation of deepeval library over pip: For windows: -'export OPENAI_API_KEY=xxx' +'set OPENAI_API_KEY=xxx' For OS: -'set OPENAI_API_KEY=xxx' +'export OPENAI_API_KEY=xxx' To run tests: test_evaluate_live.py - reads in a live test query from user input, gets the sawt response, evaluates the response according - to several metrics as implemented by the deepeval library and gpt-3.5-turbo-1106 + reads in a live test query from user input, gets the sawt response, evaluates the response according to several metrics as implemented by the deepeval library and gpt-3.5-turbo-1106 usage: 'deepeval test run test_evaluate_live.py' -test_evaluate_csv.py - reads test queries from file inputted by user, gets the sawt response, evaluates the responses according - to several metrics as implemented by the deepeval library and gpt-3.5-turbo-1106 +test_evaluate_tsv.py + reads test queries from tsv file inputted by user, gets the sawt responses, evaluates the responses according to several metrics as implemented by the deepeval library and gpt-3.5-turbo-1106 + + This file can contain be a gold data set with feature 'expected response', a list of queries without expected responses, or a mix of both. Queries with specified expected responses will be eveluated on 2 more metrics than queries without expected responses. usage: - 'deepeval test run test_evaluate_csv.py' + 'deepeval test run test_evaluate_tsv.py' + +Test results and hyperparameters used by current model are logged in deepeval login \ No newline at end of file diff --git a/packages/googlecloud/functions/getanswer/evaluate/gpt4.xlsx b/packages/googlecloud/functions/getanswer/evaluate/gpt4.xlsx deleted file mode 100644 index b315af85dc0a100baac4c7272d14fcc8d34f2db0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71292 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⪻#<&zM}62Wz2R`$dMvB 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%0DQyB~sTK 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 and gpt-3.5-turbo-1106 -All hyperparameters used by current model are logged in deepeval login +Test results and hyperparameters used by current model are logged in deepeval login. """ import pytest diff --git a/packages/googlecloud/functions/getanswer/evaluate/test_evaluate_tsv.py b/packages/googlecloud/functions/getanswer/evaluate/test_evaluate_tsv.py index 1d8c3e0..e992d19 100644 --- a/packages/googlecloud/functions/getanswer/evaluate/test_evaluate_tsv.py +++ b/packages/googlecloud/functions/getanswer/evaluate/test_evaluate_tsv.py @@ -1,11 +1,12 @@ """ usage: 'deepeval test run test_evaluate_gold_dataset.py' +Reads test queries from tsv file inputted by user, gets the sawt responses, evaluates the responses according to several metrics as implemented by the deepeval library and gpt-3.5-turbo-1106 -This will read test queries from file inputted by user, then evaluate the responses according -to several metrics as implemented by the deepeval library and gpt-3.5-turbo-1106 +This file can contain be a gold data set with feature 'expected response', a list of queries without expected responses, or a mix of both. +Queries with specified expected responses will be eveluated on 2 more metrics than queries without expected responses. -All hyperparameters used by current model are logged in deepeval login +Test results and hyperparameters used by current model are logged in deepeval login. """ import pytest @@ -81,9 +82,11 @@ def get_test_cases(): dataset, ) def test_dataset(test_case: LLMTestCase): + #require expected_output contextual_precision = ContextualPrecisionMetric(threshold=0.2, model=MODEL) contextual_recall = ContextualRecallMetric(threshold=0.2, model=MODEL) + #don't require expected_output answer_relevancy = AnswerRelevancyMetric(threshold=0.2, model=MODEL) bias = BiasMetric(threshold=0.5, model=MODEL) contextual_relevancy = ContextualRelevancyMetric(threshold=0.7, include_reason=True, model=MODEL) From 161d294f6a919600993f2d8ae96066ab784c06e5 Mon Sep 17 00:00:00 2001 From: Catherine Brooks Date: Tue, 16 Apr 2024 20:04:23 -0500 Subject: [PATCH 4/4] Updated README --- .../functions/getanswer/evaluate/README.MD | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/googlecloud/functions/getanswer/evaluate/README.MD b/packages/googlecloud/functions/getanswer/evaluate/README.MD index b432287..29b04da 100644 --- a/packages/googlecloud/functions/getanswer/evaluate/README.MD +++ b/packages/googlecloud/functions/getanswer/evaluate/README.MD @@ -1,34 +1,34 @@ -Using [confident-ai/deepeval](https://github.com/confident-ai/deepeval) LLM evaluation framework. +Using [confident-ai/deepeval](https://github.com/confident-ai/deepeval) LLM evaluation framework. Requires installation of deepeval library over pip: -'pip install -U deepeval' +'pip install -U deepeval' For windows: -'set OPENAI_API_KEY=xxx' +'set OPENAI_API_KEY=xxx' For OS: -'export OPENAI_API_KEY=xxx' +'export OPENAI_API_KEY=xxx' To run tests: -test_evaluate_live.py - reads in a live test query from user input, gets the sawt response, evaluates the response according to several metrics as implemented by the deepeval library and gpt-3.5-turbo-1106 +test_evaluate_live.py:
+ reads in a live test query from user input, gets the sawt response, evaluates the response according to several metrics as implemented by the deepeval library and gpt-3.5-turbo-1106. usage: 'deepeval test run test_evaluate_live.py' -test_evaluate_tsv.py - reads test queries from tsv file inputted by user, gets the sawt responses, evaluates the responses according to several metrics as implemented by the deepeval library and gpt-3.5-turbo-1106 +test_evaluate_tsv.py:
+ reads test queries from tsv file inputted by user, gets the sawt responses, evaluates the responses according to several metrics as implemented by the deepeval library and gpt-3.5-turbo-1106. - This file can contain be a gold data set with feature 'expected response', a list of queries without expected responses, or a mix of both. Queries with specified expected responses will be eveluated on 2 more metrics than queries without expected responses. + This file can contain be a gold data set with feature 'expected response', a list of queries without expected responses, or a mix of both. Queries with specified expected responses will be eveluated on 2 more metrics than queries without expected responses. - usage: - 'deepeval test run test_evaluate_tsv.py' + usage: + 'deepeval test run test_evaluate_tsv.py' -Test results and hyperparameters used by current model are logged in deepeval login \ No newline at end of file +Test results and hyperparameters used by current model are logged in deepeval login. \ No newline at end of file