Package: anchor-gpt
Find hallucination prone prompts and use them to fine-tune / ground your LLMWhy Anchor GPT ?Because you can't get groundtruth answers for every prompt and fine-tuning / grounding with the right data gives much better results. We compared side by side fine-tuning with prompts sampled randomly and with CoreSet (the core algo of anchor-gpt) and the results speak for themselves 👇Accuracy on a sample of the MMLU test dataset of a fine tuned LLama with 1000 datapoints sampled from the Alpaca dataset using either Random sampling or CoreSetInstallationpipinstallanchor-gptStep by StepUse prompt logger to log your prompts and their grouding scoresfromanchor_gptimportPromptLogger,Prompt# Your regular grounding processprompt_embeddings=embedding_model.encode(prompt)index_response=my_index_endpoint.find_neighbors(queries=prompt_embeddings,num_neighbors=10,)grounding_data=[]grounding_distances=[]forgrounding_index,grounding_distanceinindex_response:grounding_data.append(my_index_endpoint.get(grounding_index))grounding_distances.append(grounding_distance)grounded_prompt=build_prompt(prompt,grounding_data)# Call your LLMchat_response=my_llm.chat(grounded_prompt,temperature=0.1)# Log the promptprompt_logger=PromptLogger()my_prompt=prompt_logger.log(Prompt(text=prompt,response=chat_response,scores={'grounding_distances':grounding_distances},embeddings=prompt_embeddings,))Add additional scores like user feedback asynchronouslymy_prompt.update_scores({'user_feedback':0.8})Retreive the worst performing prompts to fine-tune your model or improve your grounding database# Define a custom prompt scoring methoddefretriever(store,threshold):defprompt_average_score(prompt):return0.2*prompt.scores['grounding_distances'][0]+0.8*prompt.scores['user_feedback']returnlist(filter(lambdax:prompt_average_score(x)>threshold,store.select_prompts()))# Retreive the ones above a thresholdworst_prompts=prompt_logger.retrieve(retriever,0.5)# Remove near duplicates to only keep what mattersdeduped_prompts=prompt_logger.deduplicate(worst_prompts,100)# Add the right answers to your grounding DB to better answer those prompts next timeExample in a chat servicefromanchor_gptimportPromptLogger,Promptprompt_logger=PromptLogger()# Your regular chat endpoint with logging enabeled@app.route("/chat",methods=["POST"])defchat():# Do your grounding as normal:prompt_embeddings=model.encode(request.json["prompt"])vector_store_results=vector_store.query(prompt_embeddings,top_k=10)grounded_prompt=build_prompt(prompt,vector_store_results)chat_response=my_llm.chat(grounded_prompt,temperature=0.1)# Then log the prompt with the response, scores and embeddings.# Prompts are stored locally in a SQLite database.prompt_logger.log(Prompt(text=request.json["prompt"],response=chat_response,scores={'grounding_distances':[r.distanceforrinvector_store_results]},embeddings=prompt_embeddings,))returnchat_response# A new hallucination retreival endpoint to get the worst prompts from your LLM@app.route("/hallucinations",methods=["GET"])defhallucinations():defretriever(store,threshold):defprompt_average_score(prompt):returnprompt.scores['grounding_distances'][0]returnlist(filter(lambdax:prompt_average_score(x)>threshold,store.select_prompts()))# Retrieve a list of the prompts with the greated distance from your grounding dataworst_prompts=prompt_logger.retrieve_n(0.5)# Remove near duplicates and only keep 10 promptsdeduped_prompts=prompt_logger.deduplicate(worst_prompts,10)# Clean up the storeprompt_logger.store.purge()returnjsonify([{'text':p.text,'response':p.response}forpindeduped_prompts])