e768098d0e
tools_continuous_delivery / Private PyPI non-main branch release (push) Has been skipped
tools_continuous_delivery / Private PyPI main branch release (push) Failing after 2m42s
Publish Promptflow Doc / Build (push) Has been cancelled
Publish Promptflow Doc / Deploy (push) Has been cancelled
Flake8 Lint / flake8 (push) Has been cancelled
Spell check CI / Spell_Check (push) Has been cancelled
179 lines
5.9 KiB
Python
179 lines
5.9 KiB
Python
import unittest
|
|
import os
|
|
import time
|
|
import traceback
|
|
|
|
|
|
class BaseTest(unittest.TestCase):
|
|
def setUp(self):
|
|
root = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../")
|
|
self.flow_path = os.path.join(root, "chat-with-pdf")
|
|
self.data_path = os.path.join(
|
|
self.flow_path, "data/bert-paper-qna-3-line.jsonl"
|
|
)
|
|
self.eval_groundedness_flow_path = os.path.join(
|
|
root, "../evaluation/eval-groundedness"
|
|
)
|
|
self.eval_perceived_intelligence_flow_path = os.path.join(
|
|
root, "../evaluation/eval-perceived-intelligence"
|
|
)
|
|
self.all_runs_generated = []
|
|
self.config_3k_context = {
|
|
"EMBEDDING_MODEL_DEPLOYMENT_NAME": "text-embedding-ada-002",
|
|
"CHAT_MODEL_DEPLOYMENT_NAME": "gpt-35-turbo",
|
|
"PROMPT_TOKEN_LIMIT": 3000,
|
|
"MAX_COMPLETION_TOKENS": 256,
|
|
"VERBOSE": True,
|
|
"CHUNK_SIZE": 1024,
|
|
"CHUNK_OVERLAP": 64,
|
|
}
|
|
self.config_2k_context = {
|
|
"EMBEDDING_MODEL_DEPLOYMENT_NAME": "text-embedding-ada-002",
|
|
"CHAT_MODEL_DEPLOYMENT_NAME": "gpt-35-turbo",
|
|
"PROMPT_TOKEN_LIMIT": 2000,
|
|
"MAX_COMPLETION_TOKENS": 256,
|
|
"VERBOSE": True,
|
|
"CHUNK_SIZE": 1024,
|
|
"CHUNK_OVERLAP": 64,
|
|
}
|
|
|
|
# Switch current working directory to the folder of this file
|
|
self.cwd = os.getcwd()
|
|
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
def tearDown(self):
|
|
# Switch back to the original working directory
|
|
os.chdir(self.cwd)
|
|
|
|
for run in self.all_runs_generated:
|
|
try:
|
|
self.pf.runs.archive(run.name)
|
|
except Exception as e:
|
|
print(e)
|
|
traceback.print_exc()
|
|
|
|
def create_chat_run(
|
|
self,
|
|
data=None,
|
|
column_mapping=None,
|
|
connections=None,
|
|
display_name="chat_run",
|
|
stream=True,
|
|
):
|
|
if column_mapping is None:
|
|
column_mapping = {
|
|
"chat_history": "${data.chat_history}",
|
|
"pdf_url": "${data.pdf_url}",
|
|
"question": "${data.question}",
|
|
"config": self.config_2k_context,
|
|
}
|
|
data = self.data_path if data is None else data
|
|
|
|
run = self.pf.run(
|
|
flow=self.flow_path,
|
|
data=data,
|
|
column_mapping=column_mapping,
|
|
connections=connections,
|
|
display_name=display_name,
|
|
tags={"unittest": "true"},
|
|
stream=stream,
|
|
)
|
|
self.all_runs_generated.append(run)
|
|
self.check_run_basics(run, display_name)
|
|
return run
|
|
|
|
def create_eval_run(
|
|
self,
|
|
eval_flow_path,
|
|
base_run,
|
|
column_mapping,
|
|
connections=None,
|
|
display_name_postfix="",
|
|
):
|
|
display_name = eval_flow_path.split("/")[-1] + display_name_postfix
|
|
eval = self.pf.run(
|
|
flow=eval_flow_path,
|
|
run=base_run,
|
|
column_mapping=column_mapping,
|
|
connections=connections,
|
|
display_name=display_name,
|
|
tags={"unittest": "true"},
|
|
stream=True,
|
|
)
|
|
self.all_runs_generated.append(eval)
|
|
self.check_run_basics(eval, display_name)
|
|
return eval
|
|
|
|
def check_run_basics(self, run, display_name=None):
|
|
self.assertTrue(run is not None)
|
|
if display_name is not None:
|
|
self.assertTrue(run.display_name.find(display_name) != -1)
|
|
self.assertEqual(run.tags["unittest"], "true")
|
|
|
|
def run_eval_with_config(self, config: dict, display_name: str = None):
|
|
run = self.create_chat_run(
|
|
column_mapping={
|
|
"question": "${data.question}",
|
|
"pdf_url": "${data.pdf_url}",
|
|
"chat_history": "${data.chat_history}",
|
|
"config": config,
|
|
},
|
|
display_name=display_name,
|
|
)
|
|
self.pf.stream(run) # wait for completion
|
|
self.check_run_basics(run)
|
|
|
|
eval_groundedness = self.create_eval_run(
|
|
self.eval_groundedness_flow_path,
|
|
run,
|
|
{
|
|
"question": "${run.inputs.question}",
|
|
"answer": "${run.outputs.answer}",
|
|
"context": "${run.outputs.context}",
|
|
},
|
|
display_name_postfix="_" + display_name,
|
|
)
|
|
self.pf.stream(eval_groundedness) # wait for completion
|
|
self.check_run_basics(eval_groundedness)
|
|
|
|
details = self.pf.get_details(eval_groundedness)
|
|
self.assertGreater(details.shape[0], 2)
|
|
|
|
metrics, elapsed = self.wait_for_metrics(eval_groundedness)
|
|
self.assertGreaterEqual(metrics["groundedness"], 0.0)
|
|
self.assertLessEqual(elapsed, 5) # metrics should be available within 5 seconds
|
|
|
|
eval_pi = self.create_eval_run(
|
|
self.eval_perceived_intelligence_flow_path,
|
|
run,
|
|
{
|
|
"question": "${run.inputs.question}",
|
|
"answer": "${run.outputs.answer}",
|
|
"context": "${run.outputs.context}",
|
|
},
|
|
display_name_postfix="_" + display_name,
|
|
)
|
|
self.pf.stream(eval_pi) # wait for completion
|
|
self.check_run_basics(eval_pi)
|
|
|
|
details = self.pf.get_details(eval_pi)
|
|
self.assertGreater(details.shape[0], 2)
|
|
|
|
metrics, elapsed = self.wait_for_metrics(eval_pi)
|
|
self.assertGreaterEqual(metrics["perceived_intelligence_score"], 0.0)
|
|
self.assertLessEqual(elapsed, 5) # metrics should be available within 5 seconds
|
|
|
|
return run, eval_groundedness, eval_pi
|
|
|
|
def wait_for_metrics(self, run):
|
|
start = time.time()
|
|
metrics = self.pf.get_metrics(run)
|
|
cnt = 3
|
|
while len(metrics) == 0 and cnt > 0:
|
|
time.sleep(5)
|
|
metrics = self.pf.get_metrics(run)
|
|
cnt -= 1
|
|
|
|
end = time.time()
|
|
return metrics, end - start
|