Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: chatgpt prompt arg #904

Merged
merged 3 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 0 additions & 41 deletions apps/youtube_channel_qa/questions.txt
Original file line number Diff line number Diff line change
@@ -1,41 +0,0 @@
"What are the steps for custom painting a motorcycle?",
"What is the process for Plasti Dipping motorcycle rims?",
"How do you paint a motorcycle gas tank?",
"What are the steps for painting a motorcycle?",
"How do you perform a basecoat prep for painting a motorcycle?",
"What is the recipe for Canh Rau Muong (Vietnamese Water Spinach Soup)?",
"Who was Howard Thurston?",
"How does the Aero Garden Seed Pod Kit work?",
"What are the ingredients for making Blueberry Muffins with Crumb Topping?",
"How do you make a DIY Homemade Exfoliating Peppermint Sugar Body Scrub?",
"What is the process for creating a DIY Mesh Water Ring Sling?",
"What are the instructions for using the EASY Sleepy Wrap (baby wrap)?",
"How do you make Ravioli Soup with Zucchini and Spinach?",
"What are the instructions for using the Eco Cub Baby Wrap Carrier for newborns?",
"How do you make Fresh Peach Muffins?",
"What are the steps to seed start German Chamomile indoors for garden flowers?",
"How do you perform the Card from Thin Air trick in coin and card magic?",
"What are the tips for growing Basil?",
"How do you make an origami balloon?",
"How do you make an origami balloon frog? (Part 2)",
"What is the process for making an origami glass?",
"How do you build an outdoor jungle gym?",
"How do you produce a Half Dollar from a napkin in coin tricks?",
"How do you recharge the AC system on an AUDI A4 B6?",
"What are the steps for setting up a primitive slackline?",
"How do you tie a moby wrap?",
"How do you wear your baby using a baby wrap or Moby?",
"What is the tutorial for the Incredible Coin Through Table magic trick?",
"How do you position a newborn in the JJ Cole Agility Baby Carrier?",
"What is the technique for maintaining balance in slacklining?",
"How can you protect a motorcycle tank bag with paint?",
"How do you create a window herb garden with Burpee Seeds?",
"What are the folding instructions for an Origami Balloon?",
"How do you make an Origami Iris (Lily version 2)?",
"How do you make an Origami Mikan and Kotatsu for display?",
"What are the beginner tips for setting up a Play Line in slacklining?",
"How can you create a pop-up poster presentation?",
"What is the process for recharging a car air conditioner in a Ford Taurus?",
"How does the Shaffali Pineapple + Peppermint Exfoliant detoxify the skin and spirit?",
"What are the tips for slacklining in a room?",
"How do you set up a slackline and what are some helpful tips?"
8 changes: 4 additions & 4 deletions apps/youtube_channel_qa/youtube_channel_qa.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ def download_youtube_video_transcript(video_link: str):
title = YouTube(video_link).streams[0].title
print(f"Video Title : {title}")
video_id = extract.video_id(video_link)
print(f"Video id : {video_id} ")
transcript = [{}]
transcript = YouTubeTranscriptApi.get_transcript(video_id)
transcript.insert(0, {"text": "Title : '" + title + "', Summary : "})
Expand Down Expand Up @@ -188,11 +189,13 @@ def generate_response(cursor: evadb.EvaDBCursor, question: str) -> str:
ORDER BY Similarity(embedding('{question}'), features) DESC
LIMIT 3;
"""

cursor.query(text_summarization_query).execute()

start = time.time()
prompt = "Answer the questions based on context alone. Do no generate responses on your own."
generate_chatgpt_response_rel = cursor.table("EMBED_TEXT").select(
f"ChatGPT('{question}', text)"
f"ChatGPT('{question}', text, '{prompt}')"
)
responses = generate_chatgpt_response_rel.df()["chatgpt.response"]
print(f"Answer (generated in {time.time() - start} seconds):")
Expand Down Expand Up @@ -343,9 +346,6 @@ def cleanup():
if_not_exists=True,
impl_path=SENTENCE_FEATURE_EXTRACTOR_UDF_PATH,
).execute()
cursor.create_udf(
"ChatGPT", if_not_exists=True, impl_path=CHATGPT_UDF_PATH
).execute()

cursor.drop_table("embedding_table", if_exists=True).execute()
est = time.time()
Expand Down
36 changes: 27 additions & 9 deletions evadb/udfs/chatgpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,13 @@ def setup(
@forward(
input_signatures=[
PandasDataframe(
columns=["prompt", "query"],
columns=["query", "content", "prompt"],
column_types=[
NdArrayType.STR,
NdArrayType.STR,
NdArrayType.STR,
],
column_shapes=[(1,), (1,)],
column_shapes=[(1,), (1,), (None,)],
)
],
output_signatures=[
Expand Down Expand Up @@ -95,30 +96,47 @@ def completion_with_backoff(**kwargs):
len(openai.api_key) != 0
), "Please set your OpenAI API key in evadb.yml file (third_party, open_api_key) or environment variable (OPENAI_KEY)"

prompts = text_df[text_df.columns[0]]
queries = text_df[text_df.columns[0]]
content = text_df[text_df.columns[0]]
if len(text_df.columns) > 1:
queries = text_df[text_df.columns[1]]
queries = text_df.iloc[:, 0]
content = text_df.iloc[:, 1]

prompt = None
if len(text_df.columns) > 2:
prompt = text_df.iloc[0, 2]

# openai api currently supports answers to a single prompt only
# so this udf is designed for that
results = []

for prompt, query in zip(prompts, queries):
for query, content in zip(queries, content):
params = {
"model": self.model,
"temperature": self.temperature,
"messages": [
"messages": [],
}

def_sys_prompt_message = {
"role": "system",
"content": prompt
if prompt is not None
else "You are a helpful assistant that accomplishes user tasks.",
}

params["messages"].append(def_sys_prompt_message)
params["messages"].extend(
[
{
"role": "user",
"content": f"Context to answer the question : {query}",
"content": f"Here is some context : {content}",
},
{
"role": "user",
"content": f"Answer the question based on context : {prompt}",
"content": f"Complete the following task: {query}",
},
],
}
)

answer = completion_with_backoff(**params)
results.append(answer)
Expand Down
59 changes: 59 additions & 0 deletions test/app_tests/test_youtube_channel_qa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# coding=utf-8
# Copyright 2018-2023 EvaDB
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import subprocess
import unittest
from pathlib import Path
from test.util import get_evadb_for_testing, shutdown_ray


class YoutubeChannelQATest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.evadb = get_evadb_for_testing()
cls.evadb.catalog().reset()
os.environ["ray"] = str(cls.evadb.config.get_value("experimental", "ray"))

@classmethod
def tearDownClass(cls):
pass

def setUp(self):
pass

def tearDown(self) -> None:
shutdown_ray()

def test_should_run_youtube_channel_qa_app(self):
app_path = Path("apps", "youtube_channel_qa", "youtube_channel_qa.py")
input1 = "\n\n\n" # Download just one video from the default channel in the default order.
# Assuming that OPENAI_KEY is already set as an environment variable
input2 = "What is this video about?\n" # Question
input3 = "exit\n" # Exit
inputs = input1 + input2 + input3
command = ["python", app_path]

process = subprocess.Popen(
command,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
stdout, stderr = process.communicate(inputs.encode())

decoded_stdout = stdout.decode()
assert "keyboards" or "AliExpress" or "Rate limit" in decoded_stdout
print(decoded_stdout)
print(stderr.decode())