File size: 4,400 Bytes
502ce12
54798ef
a03b7d2
523912b
ae849b8
6cf8d92
a4271da
f1d3df8
 
3580c45
d433048
714920c
d433048
 
 
7bb103a
d433048
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f1d3df8
 
bd7e9a6
714920c
bd7e9a6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
371c283
 
 
 
f1d3df8
 
 
371c283
 
 
881deef
7bb103a
 
 
 
726e3a7
c216254
a4822fb
 
6842b3b
 
a4822fb
605e11c
569befd
 
 
605e11c
c216254
 
 
d1905ae
c216254
 
 
b567a38
c216254
 
 
 
 
83b13ed
726e3a7
 
 
 
 
 
c216254
c5421d9
 
726e3a7
 
c5421d9
c216254
 
 
726e3a7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import gradio as gr
import os
import spacy
import time
import torch
from spacy.cli.download import download
from transformers import pipeline
from transformers import GPT2LMHeadModel, GPT2Tokenizer


# define function to generate chatbot response
def generate_response(user_input):
  # add tokens to user input text
  user_input = (' '.join(['[BOS]', user_input.strip().lower(), '[BOT]']))
  # encode input
  input_ids = tokenizer.encode(user_input, return_tensors='pt', add_special_tokens=True).to(device)
  # generate top_p (nucleus) sampling
  sample_outputs = model.generate(
      input_ids,
      do_sample=True,
      max_length=50,
      top_k=30,
      top_p=0.95,
      num_return_sequences=1,
      no_repeat_ngram_size=2,
      early_stopping=True,
      temperature=.7,
      num_beams=6
  )

  for i, sample_output in enumerate(sample_outputs):
    # obtain list of tokens
    output_tokens = sample_outputs[0].tolist()
    # find location of [BOT] token
    bot_token_id = 50263
    try:
        bot_token_index = output_tokens.index(bot_token_id)
        # print decoded text after the [BOT] token
        decoded_text = tokenizer.decode(output_tokens[bot_token_index + 1:], skip_special_tokens=True)
        response = (postprocess_text(decoded_text)) # call function to postprocess response
        return(response) # return chatbot response
    # if [BOT] token is not found    
    except ValueError:
        print('Unable to find [BOT] token.')


# define function to postprocess generated chatbot text
def postprocess_text(text):
    try:
        # construct doc object and create list of sentences
        doc = nlp(text)
        sentences = list(doc.sents)
        
        # capitalize first letter of each sentence
        # only consider a sentence if greater than 3 chars
        capitalized_sentences = []
        for sent in sentences:
            if len(sent.text.strip()) >= 3:
                sentence = sent.text.strip()
                if not sentence.endswith('.') and not sentence.endswith('?'):
                    sentence += '.'
                capitalized_sentences.append(sentence.capitalize())

        # if response is more than one sentence, only return first two sentences
        if len(capitalized_sentences) == 1:
            response = capitalized_sentences[0]
        elif len(capitalized_sentences) > 1:
            response = ' '.join(capitalized_sentences[:2])
        else:
            response = "Sorry, I don't understand your question. Can you try asking it in another way?"
        
        # return response
        return response.strip()

    except:
        return "Sorry, I don't understand your question. Can you try asking it in another way?"


# load english language model
nlp = spacy.load('en_core_web_sm')

# saved model location
saved_model = "jeraimondi/chatbot-ubuntu-gpt2"

# load previously trained model and tokenizer
tokenizer = GPT2Tokenizer.from_pretrained(saved_model)
model = GPT2LMHeadModel.from_pretrained(saved_model)

# set model to use GPUs if available in runtime session
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model.to(device)

# define and launch gradio interface
with gr.Blocks() as demo:
    chatbot = gr.Chatbot(
        bubble_full_width=False,
        avatar_images=(None, (os.path.join(os.path.dirname(__file__), "avatar.png"))),
        avatar_css={"width": "150px", "height": "150px"}
    )
    msg = gr.Textbox(
        show_label=False,
        placeholder="Enter question and press enter",
        container=False
    )
    clear = gr.Button("Clear")

    def user(user_message, history):
        return "", history + [[user_message, None]]

    def bot(history):
        user_message = history[-1][0]
        bot_message = generate_response(user_message)
        history[-1][1] = ""
        for character in bot_message:
            history[-1][1] += character
            time.sleep(0.05)
            yield history
        
    def vote(data: gr.LikeData):
        if data.liked:
            print("You upvoted this response: " + data.value)
        else:
            print("You downvoted this response: " + data.value)

    msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(
        bot, chatbot, chatbot        
    )

    chatbot.like(vote, None, None)
    
    clear.click(lambda: None, None, chatbot, queue=False)
    
demo.queue()
demo.launch()