from transformers import BlenderbotTokenizer, BlenderbotForConditionalGeneration import torch import gradio as gr import os import csv from gradio import inputs, outputs from datetime import datetime import fastapi from typing import List, Dict import httpx import pandas as pd import datasets as ds UseMemory=True HF_TOKEN=os.environ.get("HF_TOKEN") def SaveResult(text, outputfileName): basedir = os.path.dirname(__file__) savePath = outputfileName print("Saving: " + text + " to " + savePath) from os.path import exists file_exists = exists(savePath) if file_exists: with open(outputfileName, "a") as f: #append f.write(str(text.replace("\n"," "))) f.write('\n') else: with open(outputfileName, "w") as f: #write f.write(str("time, message, text\n")) # one time only to get column headers for CSV file f.write(str(text.replace("\n"," "))) f.write('\n') return def store_message(name: str, message: str, outputfileName: str): basedir = os.path.dirname(__file__) savePath = outputfileName if name and message: with open(savePath, "a") as csvfile: writer = csv.DictWriter(csvfile, fieldnames=[ "time", "message", "name", ]) writer.writerow( {"time": str(datetime.now()), "message": message.strip(), "name": name.strip() } ) df = pd.read_csv(savePath) df = df.sort_values(df.columns[0],ascending=False) return df mname = "facebook/blenderbot-400M-distill" model = BlenderbotForConditionalGeneration.from_pretrained(mname) tokenizer = BlenderbotTokenizer.from_pretrained(mname) def take_last_tokens(inputs, note_history, history): if inputs['input_ids'].shape[1] > 128: inputs['input_ids'] = torch.tensor([inputs['input_ids'][0][-128:].tolist()]) inputs['attention_mask'] = torch.tensor([inputs['attention_mask'][0][-128:].tolist()]) note_history = [' '.join(note_history[0].split(' ')[2:])] history = history[1:] return inputs, note_history, history def add_note_to_history(note, note_history):# good example of non async since we wait around til we know it went okay. note_history.append(note) note_history = ' '.join(note_history) return [note_history] title = "💬ChatBack🧠💾" description = """Chatbot With persistent memory dataset allowing multiagent system AI to access a shared dataset as memory pool with stored interactions. Current Best SOTA Chatbot: https://huggingface.co/facebook/blenderbot-400M-distill?text=Hey+my+name+is+ChatBack%21+Are+you+ready+to+rock%3F """ def get_base(filename): basedir = os.path.dirname(__file__) loadPath = basedir + "\\" + filename return loadPath def chat(message, history): history = history or [] if history: history_useful = [' '.join([str(a[0])+' '+str(a[1]) for a in history])] else: history_useful = [] history_useful = add_note_to_history(message, history_useful) inputs = tokenizer(history_useful, return_tensors="pt") inputs, history_useful, history = take_last_tokens(inputs, history_useful, history) reply_ids = model.generate(**inputs) response = tokenizer.batch_decode(reply_ids, skip_special_tokens=True)[0] history_useful = add_note_to_history(response, history_useful) list_history = history_useful[0].split(' ') history.append((list_history[-2], list_history[-1])) df=pd.DataFrame() if UseMemory: outputfileName = 'ChatbotMemory.csv' df = store_message(message, response, outputfileName) # Save to dataset basedir = get_base(outputfileName) return history, df, basedir with gr.Blocks() as demo: gr.Markdown("

🍰Gradio chatbot backed by dataframe CSV memory🎨

") with gr.Row(): t1 = gr.Textbox(lines=1, default="", label="Chat Text:") b1 = gr.Button("Respond and Retrieve Messages") with gr.Row(): # inputs and buttons s1 = gr.State([]) df1 = gr.Dataframe(wrap=True, max_rows=1000, overflow_row_behaviour= "paginate") with gr.Row(): # inputs and buttons file = gr.File(label="File") s2 = gr.Markdown() b1.click(fn=chat, inputs=[t1, s1], outputs=[s1, df1, file]) demo.launch(debug=True, show_error=True)