add query generation
This commit is contained in:
parent
83ad2b88c0
commit
c9ac8b436e
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1,3 @@
|
||||
.env
|
||||
data
|
||||
__pycache__
|
||||
|
||||
@ -1,11 +1,86 @@
|
||||
import json
|
||||
import os
|
||||
import requests
|
||||
import tqdm
|
||||
import faiss
|
||||
import numpy
|
||||
import importlib
|
||||
from openai import OpenAI
|
||||
from dotenv import load_dotenv
|
||||
import re
|
||||
import random
|
||||
|
||||
|
||||
def import_lib(path, file_name, package_name):
|
||||
file_path = path + "/" + file_name + ".py"
|
||||
spec = importlib.util.spec_from_file_location(file_name, file_path)
|
||||
imported_file = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(imported_file)
|
||||
return getattr(imported_file, package_name)
|
||||
|
||||
|
||||
OpenAIResponder = import_lib(os.path.dirname(__file__) , "openai_responder", "OpenAIResponder")
|
||||
|
||||
|
||||
class Configuration:
|
||||
def __init__(self):
|
||||
pass
|
||||
self.file_path = os.path.dirname(__file__)
|
||||
self.session = requests.Session()
|
||||
load_dotenv()
|
||||
|
||||
def get_config_prompt(self, passage, character, language):
|
||||
config_prompt = f"""Given a **Passage** and **Character**, select the appropriate option from
|
||||
|
||||
def load_all_persona(self):
|
||||
data = []
|
||||
with open(self.file_path + "/../data/proj-persona/PersonaHub/persona.jsonl", "r", encoding="utf-8") as f:
|
||||
for line in f:
|
||||
data.append(json.loads(line))
|
||||
all_persona = [data[i]["persona"] for i in range(len(data))]
|
||||
return all_persona
|
||||
|
||||
def get_embedding(self, sentece, prompt_name):
|
||||
embedding_url = "http://localhost:5011/embed"
|
||||
headers = {"accept": "application/json"}
|
||||
headers["Content-Type"] = "application/json"
|
||||
|
||||
data = {}
|
||||
data["inputs"] = sentece
|
||||
data["normalize"] = True
|
||||
data["prompt_name"] = prompt_name
|
||||
data["truncate"] = False
|
||||
data["truncation_direction"] = "Right"
|
||||
|
||||
response = self.session.post(embedding_url, headers=headers, data=json.dumps(data), timeout=600)
|
||||
|
||||
return response.json()
|
||||
|
||||
|
||||
def embedding_persona(self):
|
||||
all_persona = self.load_all_persona()
|
||||
|
||||
prompt_name = "document"
|
||||
|
||||
all_embeddings = []
|
||||
batch_size = 64
|
||||
for i in tqdm.trange(0, len(all_persona), batch_size):
|
||||
start_idx = i
|
||||
stop_idx = min(len(all_persona), start_idx+batch_size)
|
||||
all_embeddings += self.get_embedding(all_persona[start_idx:stop_idx], prompt_name)
|
||||
|
||||
xb = numpy.array(all_embeddings).astype('float32')
|
||||
index = faiss.IndexFlatL2(len(all_embeddings[0]))
|
||||
index.add(xb)
|
||||
|
||||
faiss.write_index(index, self.file_path + "/../data/faiss.index")
|
||||
|
||||
|
||||
def get_config_prompt(self, passage, selected_persona, language):
|
||||
character = "".join([f"- {selected_persona[i]}\n" for i in range(len(selected_persona))])
|
||||
|
||||
example1 = "{'passage': 'چیپست اسنپدراگون نام خانواده\\u200cای از SoCها یا «سیستم بر روی یک تراشه» است که توسط شرکت تراشه\\u200cساز آمریکایی کوالکام Qualcomm ساخته می شود. هدف از ساخت این تراشه\\u200cها استفاده از آنها در گوشی\\u200cهای همراه هوشمند و تبلت\\u200cهاست. هر تراشه\\u200cی اسنپ\\u200cدراگون شامل واحدهای پردازنده\\u200cی مرکزی، پردازنده\\u200cی گرافیکی Adreno، کنترلر دوربین، سیستم ناوبری جهانی GPS، مودم داخلی برای اتصال به شبکه\\u200cهای 5G و اتصال Wi-Fi است. در واقع در این تراشه\\u200cها تمام ابزارهای لازم برای توانمندسازی یک دستگاه هوشمند یکجا جمع شده است. البته تمام پردازنده های اسنپدراگون توانایی\\u200cهای برابری ندارد.', 'Character': 'A widely acclaimed microprocessor scientist passionate about creating next generation mobile chipsets', 'Question_Type': 'keywords', 'Difficulty': 'university'}"
|
||||
example2 = '{\'passage\': \'امام علی(ع) پس از خلیفه سوم، به اصرار مسلمانان خلافت و حکومت را پذیرفت. او در دوران حکومتش اهمیت ویژه\\u200cای برای عدالت قائل بود و در برابر روش خلفا که بیت\\u200cالمال را بر اساس سوابق افراد تقسیم می\\u200cکردند، ایستاد. وی دستور داد که عرب و عجم و هر مسلمانی از هر تیره و تبار که باشد، در سهم بیت\\u200cالمال یکسان\\u200cاند و تمام زمین\\u200cهایی که عثمان به افراد مختلف واگذار کرده بود، به بیت\\u200cالمال بازگرداند. در دوره کوتاه حکومت امام علی(ع) سه جنگ سنگین داخلی جمل، صفین و نهروان درگرفت.\', \'Character\': "a devout Shi\'a Muslim scholar who has spent years studying Islamic scriptures and the life of Imam Ali.", \'Question_Type\': \'keywords\', \'Difficulty\': \'university\'}'
|
||||
example3 = "{'passage': 'همه موجودات زنده بر اساس ویژگی های بسیار اساسی و مشترک طبقه بندی می شوند. سپس موجودات درون هر گروه به گروههای کوچکتر تقسیم می شوند. این گروه های کوچکتر بر اساس شباهت های دقیق تر در هر گروه بزرگتر هستند. این سیستم گروه بندی ، مطالعه گروه های خاصی از موجودات را برای دانشمندان آسان می کند. ویژگی هایی مانند ظاهر ، تولید مثل ، تحرک و عملکرد تنها چند روش برای گروه بندی موجودات زنده است. این گروه های تخصصی را طبقه بندی موجودات زنده می نامند. طبقه بندی موجودات زنده شامل ۷ سطح است: فرمانروا، شاخه، رده، راسته، خانواده، جنس و گونه', 'Character': 'a classification biologists who is slightly impatient with imprecise information.', 'Question_Type': 'acquire_knowledge', 'Difficulty': 'high_school'}"
|
||||
|
||||
config_prompt = f"""Given a **Passage** and **Character**, select the appropriate option from
|
||||
three fields: Character, Question_Type, Difficulty, and return the output
|
||||
in JSON format.
|
||||
First, select the Character who are likely to be interested in the Passage
|
||||
@ -25,15 +100,79 @@ Difficulty:
|
||||
- university: ...
|
||||
- phd: ...
|
||||
Here are some examples
|
||||
<Example1> <Example2> <Example3>
|
||||
Example1: {example1}
|
||||
Example2: {example2}
|
||||
Example3: {example3}
|
||||
|
||||
Now, generate the **output** based on the **Passage** and **Character** from
|
||||
user, the **Passage** will be in {language} language and the **Character**
|
||||
will be in English.
|
||||
,→
|
||||
,→
|
||||
|
||||
|
||||
Ensure to generate only the JSON output with content in English.
|
||||
**Passage**:
|
||||
{passage}
|
||||
**Character**:
|
||||
{character}"""
|
||||
return config_prompt
|
||||
return config_prompt
|
||||
|
||||
|
||||
def init_persona(self):
|
||||
self.index = faiss.read_index(self.file_path + "/../data/faiss.index")
|
||||
self.all_persona = self.load_all_persona()
|
||||
client = OpenAI(base_url=os.environ["OPENAI_BASE_URL"] ,api_key=os.environ["OPENAI_API_KEY"])
|
||||
self.openai_responder = OpenAIResponder(client=client, model=os.environ["OPENAI_MODEL"], price_per_1m_input_tokens=0, price_per_1m_output_tokens=0)
|
||||
|
||||
|
||||
def get_persona(self, passage):
|
||||
query_embedding = self.get_embedding(passage, "query")
|
||||
query = numpy.array(query_embedding, dtype='float32')
|
||||
|
||||
|
||||
k = 5
|
||||
distances, indices = self.index.search(query, k)
|
||||
|
||||
selected_persona = [self.all_persona[indices[0][i]] for i in range(len(indices[0]))]
|
||||
return selected_persona
|
||||
|
||||
|
||||
def get_messages(self, text):
|
||||
messages = [
|
||||
# {"role": "system", "content": ""},
|
||||
{"role": "user", "content": text}
|
||||
]
|
||||
return messages
|
||||
|
||||
|
||||
def run(self, passage):
|
||||
selected_persona = self.get_persona(passage)
|
||||
|
||||
language = "persian"
|
||||
|
||||
|
||||
prompt = self.get_config_prompt(passage, selected_persona, language)
|
||||
messages = self.get_messages(prompt)
|
||||
all_content, price = self.openai_responder.run(messages)
|
||||
|
||||
json_text = re.search(r"```json(.*?)```", all_content, re.DOTALL).group(1).strip()
|
||||
|
||||
config = json.loads(json_text)
|
||||
|
||||
# example = {"passage": passage}
|
||||
# for key in data:
|
||||
# example[key] = data[key]
|
||||
|
||||
config["length"] = random.choice([20, 40, 80, 160])
|
||||
|
||||
|
||||
return config
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
configuration = Configuration()
|
||||
# configuration.embedding_persona()
|
||||
configuration.init_persona()
|
||||
|
||||
passage = """همه موجودات زنده بر اساس ویژگی های بسیار اساسی و مشترک طبقه بندی می شوند. سپس موجودات درون هر گروه به گروههای کوچکتر تقسیم می شوند. این گروه های کوچکتر بر اساس شباهت های دقیق تر در هر گروه بزرگتر هستند. این سیستم گروه بندی ، مطالعه گروه های خاصی از موجودات را برای دانشمندان آسان می کند. ویژگی هایی مانند ظاهر ، تولید مثل ، تحرک و عملکرد تنها چند روش برای گروه بندی موجودات زنده است. این گروه های تخصصی را طبقه بندی موجودات زنده می نامند. طبقه بندی موجودات زنده شامل ۷ سطح است: فرمانروا، شاخه، رده، راسته، خانواده، جنس و گونه"""
|
||||
config = configuration.run(passage)
|
||||
98
src/query_generator.py
Normal file
98
src/query_generator.py
Normal file
@ -0,0 +1,98 @@
|
||||
import json
|
||||
import os
|
||||
import requests
|
||||
import tqdm
|
||||
import faiss
|
||||
import numpy
|
||||
import importlib
|
||||
from openai import OpenAI
|
||||
from dotenv import load_dotenv
|
||||
import re
|
||||
|
||||
def import_lib(path, file_name, package_name):
|
||||
file_path = path + "/" + file_name + ".py"
|
||||
spec = importlib.util.spec_from_file_location(file_name, file_path)
|
||||
imported_file = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(imported_file)
|
||||
return getattr(imported_file, package_name)
|
||||
|
||||
|
||||
OpenAIResponder = import_lib(os.path.dirname(__file__) , "openai_responder", "OpenAIResponder")
|
||||
|
||||
|
||||
class QueryGenerator:
|
||||
def __init__(self):
|
||||
client = OpenAI(base_url=os.environ["OPENAI_BASE_URL"] ,api_key=os.environ["OPENAI_API_KEY"])
|
||||
|
||||
self.openai_responder = OpenAIResponder(client=client, model=os.environ["OPENAI_MODEL"], price_per_1m_input_tokens=0, price_per_1m_output_tokens=0)
|
||||
|
||||
def get_prompt(self, passage, character, corpus_language, queries_language, difficulty, length, language, question_type):
|
||||
|
||||
example = "{'passage': 'چیپست اسنپدراگون نام خانواده\\u200cای از SoCها یا «سیستم بر روی یک تراشه» است که توسط شرکت تراشه\\u200cساز آمریکایی کوالکام Qualcomm ساخته می شود. هدف از ساخت این تراشه\\u200cها استفاده از آنها در گوشی\\u200cهای همراه هوشمند و تبلت\\u200cهاست. هر تراشه\\u200cی اسنپ\\u200cدراگون شامل واحدهای پردازنده\\u200cی مرکزی، پردازنده\\u200cی گرافیکی Adreno، کنترلر دوربین، سیستم ناوبری جهانی GPS، مودم داخلی برای اتصال به شبکه\\u200cهای 5G و اتصال Wi-Fi است. در واقع در این تراشه\\u200cها تمام ابزارهای لازم برای توانمندسازی یک دستگاه هوشمند یکجا جمع شده است. البته تمام پردازنده های اسنپدراگون توانایی\\u200cهای برابری ندارد.', 'Character': 'A widely acclaimed microprocessor scientist passionate about creating next generation mobile chipsets', 'Question_Type': 'keywords', 'Difficulty': 'university'}"
|
||||
example2 = '{\'passage\': \'امام علی(ع) پس از خلیفه سوم، به اصرار مسلمانان خلافت و حکومت را پذیرفت. او در دوران حکومتش اهمیت ویژه\\u200cای برای عدالت قائل بود و در برابر روش خلفا که بیت\\u200cالمال را بر اساس سوابق افراد تقسیم می\\u200cکردند، ایستاد. وی دستور داد که عرب و عجم و هر مسلمانی از هر تیره و تبار که باشد، در سهم بیت\\u200cالمال یکسان\\u200cاند و تمام زمین\\u200cهایی که عثمان به افراد مختلف واگذار کرده بود، به بیت\\u200cالمال بازگرداند. در دوره کوتاه حکومت امام علی(ع) سه جنگ سنگین داخلی جمل، صفین و نهروان درگرفت.\', \'Character\': "a devout Shi\'a Muslim scholar who has spent years studying Islamic scriptures and the life of Imam Ali.", \'Question_Type\': \'keywords\', \'Difficulty\': \'university\'}'
|
||||
example3 = "{'passage': 'همه موجودات زنده بر اساس ویژگی های بسیار اساسی و مشترک طبقه بندی می شوند. سپس موجودات درون هر گروه به گروههای کوچکتر تقسیم می شوند. این گروه های کوچکتر بر اساس شباهت های دقیق تر در هر گروه بزرگتر هستند. این سیستم گروه بندی ، مطالعه گروه های خاصی از موجودات را برای دانشمندان آسان می کند. ویژگی هایی مانند ظاهر ، تولید مثل ، تحرک و عملکرد تنها چند روش برای گروه بندی موجودات زنده است. این گروه های تخصصی را طبقه بندی موجودات زنده می نامند. طبقه بندی موجودات زنده شامل ۷ سطح است: فرمانروا، شاخه، رده، راسته، خانواده، جنس و گونه', 'Character': 'a classification biologists who is slightly impatient with imprecise information.', 'Question_Type': 'acquire_knowledge', 'Difficulty': 'high_school'}"
|
||||
|
||||
prompt = f"""Given a **Character**, **Passage**, and **Requirement**, generate a query from the **Character**'s perspective that satisfies the **Requirement** and can be used to retrieve the **Passage**. Please return the result in JSON format.
|
||||
|
||||
|
||||
|
||||
Here is an example:
|
||||
<example>
|
||||
Now, generate the **output** based on the **Character**, **Passage** and **Requirement** from user, the **Passage** will be in {corpus_language} language, the **Character** and **Requirement** will be in English.
|
||||
|
||||
|
||||
Ensure to generate only the JSON output, with the key in English and the value, in {queries_language} language.
|
||||
**Character**
|
||||
{character}
|
||||
**Passage**
|
||||
{passage}
|
||||
**Requirment**
|
||||
- Question_Type: {question_type};
|
||||
- Difficulty: {difficulty};
|
||||
- Length: the length of the generated sentences should be {length} words;
|
||||
- Languange: the language in which the results are generated should be, {language} language;"""
|
||||
return prompt
|
||||
|
||||
def get_messages(self, text):
|
||||
messages = [
|
||||
# {"role": "system", "content": ""},
|
||||
{"role": "user", "content": text}
|
||||
]
|
||||
return messages
|
||||
|
||||
|
||||
def run(self, passage, config):
|
||||
language = "persian"
|
||||
corpus_language = "persian"
|
||||
queries_language = "persian"
|
||||
|
||||
prompt = self.get_prompt(passage, config["Character"], corpus_language, queries_language, config["Difficulty"], config["length"], language, config["Question_Type"])
|
||||
messages = self.get_messages(prompt)
|
||||
|
||||
all_content, price = self.openai_responder.run(messages)
|
||||
|
||||
json_text = re.search(r"```json(.*?)```", all_content, re.DOTALL).group(1).strip()
|
||||
|
||||
data = json.loads(json_text)
|
||||
|
||||
# example = {"passage": passage}
|
||||
# for key in data:
|
||||
# example[key] = data[key]
|
||||
|
||||
return data
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
configuration = Configuration()
|
||||
configuration.init_persona()
|
||||
passage = """همه موجودات زنده بر اساس ویژگی های بسیار اساسی و مشترک طبقه بندی می شوند. سپس موجودات درون هر گروه به گروههای کوچکتر تقسیم می شوند. این گروه های کوچکتر بر اساس شباهت های دقیق تر در هر گروه بزرگتر هستند. این سیستم گروه بندی ، مطالعه گروه های خاصی از موجودات را برای دانشمندان آسان می کند. ویژگی هایی مانند ظاهر ، تولید مثل ، تحرک و عملکرد تنها چند روش برای گروه بندی موجودات زنده است. این گروه های تخصصی را طبقه بندی موجودات زنده می نامند. طبقه بندی موجودات زنده شامل ۷ سطح است: فرمانروا، شاخه، رده، راسته، خانواده، جنس و گونه"""
|
||||
config = configuration.run(passage)
|
||||
query_generator = QueryGenerator()
|
||||
|
||||
data = query_generator.run(passage, config)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
Configuration = import_lib(os.path.dirname(__file__) , "configuration", "Configuration")
|
||||
main()
|
||||
Loading…
x
Reference in New Issue
Block a user