CoolFace
Apppublic

taskswithcode/semantic_search

sourceHugging Facemitupdated 4y agoView on Hugging Face
2likes
twc_openai_search.py125 linesDownload Raw Back to root
1from scipy.spatial.distance import cosine2import argparse3import json4import os5import openai6import pdb7 8def read_text(input_file):9    arr = open(input_file).read().split("\n")10    return arr[:-1]11 12 13class OpenAIQnAModel:14    def __init__(self):15        self.debug = False16        self.q_model_name = None17        self.d_model_name = None18        self.skip_key = True19        print("In OpenAI API constructor")20 21 22    def init_model(self,model_name = None):23        #print("OpenAI: Init model",model_name)24        openai.api_key = os.getenv("OPENAI_API_KEY")25        if (openai.api_key == None):26            openai.api_key = ""27            print("API key not set")28 29        if (len(openai.api_key) == 0 and not self.skip_key):30                print("Open API key not set")31        32        if (model_name is None):33            self.d_model_name = "text-search-ada-doc-001"34        else:35            self.d_model_name = model_name36        self.q_model_name = self.construct_query_model_name(self.d_model_name)37        print(f"OpenAI: Init model complete :query model {self.q_model_name} doc:{self.d_model_name}")38 39    def construct_query_model_name(self,d_model_name):40        return d_model_name.replace('-doc-','-query-')41 42 43    def compute_embeddings(self,input_file_name,input_data,is_file):44        if (len(openai.api_key) == 0 and not self.skip_key):45                print("Open API key not set")46                return [],[]47        #print("In compute embeddings after key check")48        in_file = input_file_name.split('/')[-1]49        in_file = self.d_model_name + '_' +  '.'.join(in_file.split('.')[:-1]) + "_search.json"50        cached = False51        try:52            fp = open(in_file)53            cached = True54            embeddings = json.load(fp)55            q_embeddings = [embeddings[0]]56            d_embeddings = embeddings[1:]57            print("Using cached embeddings")58        except:59            pass60            61        texts = read_text(input_data) if is_file == True else input_data62        queries = [texts[0]]63        docs = texts[1:]64 65        if (not cached):66            print(f"Computing embeddings for {input_file_name} and query model {self.q_model_name}")67            query_embeds = openai.Embedding.create(68                input=queries,69                model=self.q_model_name70            )71            print(f"Computing embeddings for {input_file_name} and doc model {self.q_model_name}")72            doc_embeds = openai.Embedding.create(73                input=docs,74                model=self.d_model_name75            )76            q_embeddings = []77            d_embeddings = []78            for i in range(len(query_embeds['data'])):79                q_embeddings.append(query_embeds['data'][i]['embedding'])80            for i in range(len(doc_embeds['data'])):81                d_embeddings.append(doc_embeds['data'][i]['embedding'])82        if (not cached):83            embeddings = q_embeddings + d_embeddings84            with open(in_file,"w") as fp:85                json.dump(embeddings,fp)86        return texts,(q_embeddings,d_embeddings)87 88    def output_results(self,output_file,texts,embeddings,main_index = 0):89        # Calculate cosine similarities90        # Cosine similarities are in [-1, 1]. Higher means more similar91        query_embeddings = embeddings[0]92        doc_embeddings = embeddings[1]93        cosine_dict = {}94        queries = [texts[0]]95        docs = texts[1:]96        if (self.debug):97            print("Total sentences",len(texts))98        for i in range(len(docs)):99            cosine_dict[docs[i]] = 1 - cosine(query_embeddings[0], doc_embeddings[i])100 101        if (self.debug):102            print("Input sentence:",texts[main_index])103        sorted_dict = dict(sorted(cosine_dict.items(), key=lambda item: item[1],reverse = True))104        if (self.debug):105            for key in sorted_dict:106                print("Cosine similarity with  \"%s\" is: %.3f" % (key, sorted_dict[key]))107        if (output_file is not None):108            with open(output_file,"w") as fp:109                fp.write(json.dumps(sorted_dict,indent=0))110        return sorted_dict111 112 113 114if __name__ == '__main__':115        parser = argparse.ArgumentParser(description='OpenAI model for document search embeddings ',formatter_class=argparse.ArgumentDefaultsHelpFormatter)116        parser.add_argument('-input', action="store", dest="input",required=True,help="Input file with sentences")117        parser.add_argument('-output', action="store", dest="output",default="output.txt",help="Output file with results")118        parser.add_argument('-model', action="store", dest="model",default="text-search-ada-doc-001",help="model name")119 120        results = parser.parse_args()121        obj = OpenAIQnAModel()122        obj.init_model(results.model)123        texts, embeddings = obj.compute_embeddings(results.input,results.input,is_file = True)124        results = obj.output_results(results.output,texts,embeddings)125