File size: 4,152 Bytes
fbd20b5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from flask import Flask, request, jsonify, send_from_directory
from flask_cors import CORS
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
from datasets import load_dataset
from sklearn.metrics.pairwise import cosine_similarity
from sentence_transformers import SentenceTransformer

app = Flask(__name__)
CORS(app)

# Load the DialoGPT model and tokenizer
tokenizer = AutoTokenizer.from_pretrained("microsoft/DialoGPT-medium")
model = AutoModelForCausalLM.from_pretrained("microsoft/DialoGPT-medium")

# Load the Bitext Travel Dataset
try:
    dataset = load_dataset("bitext/Bitext-travel-llm-chatbot-training-dataset")
    print("Bitext dataset loaded successfully.")
except Exception as e:
    print(f"Error loading Bitext dataset: {str(e)}")
    dataset = None

# Load a pre-trained sentence transformer model for semantic similarity
sentence_model = SentenceTransformer('all-MiniLM-L6-v2')


def find_closest_response(user_input):
    if dataset is None:
        return "I'm sorry, but I couldn't load the travel dataset. Please try again later."

    try:
        # Precompute embeddings for all instructions in the dataset
        instructions = [example['instruction'] for example in dataset['train']]
        instruction_embeddings = sentence_model.encode(instructions)

        # Encode the user input
        user_embedding = sentence_model.encode([user_input])

        # Compute cosine similarity between the user input and all instructions
        similarities = cosine_similarity(
            user_embedding, instruction_embeddings)
        closest_index = similarities.argmax()

        # Return the closest response
        return dataset['train'][closest_index]['response']
    except Exception as e:
        print(f"Error finding closest response: {str(e)}")
        return "I'm sorry, but I couldn't find a suitable response. Please try again."


def chat_with_bot(user_input, chat_history_ids=None):
    try:
        # Find the closest response from the Bitext dataset
        closest_response = find_closest_response(user_input)
        print(f"Closest response: {closest_response}")  # Debugging statement

        # Generate a response using DialoGPT
        new_user_input_ids = tokenizer.encode(
            user_input + tokenizer.eos_token, return_tensors='pt')
        bot_input_ids = torch.cat([chat_history_ids, new_user_input_ids],
                                  dim=-1) if chat_history_ids is not None else new_user_input_ids
        chat_history_ids = model.generate(
            bot_input_ids, max_length=1000, pad_token_id=tokenizer.eos_token_id)
        bot_reply = tokenizer.decode(
            chat_history_ids[:, bot_input_ids.shape[-1]:][0], skip_special_tokens=True)
        print(f"DialoGPT response: {bot_reply}")  # Debugging statement

        # Combine the Bitext response and DialoGPT response
        combined_response = f"{closest_response}\n\n{bot_reply}"

        return combined_response, chat_history_ids
    except Exception as e:
        print(f"Exception: {str(e)}")  # Print the full exception
        return "Sorry, an unexpected error occurred. Please try again.", None

# Serve the HTML file


@app.route("/")
def serve_html():
    return send_from_directory(".", "index.html")

# Chat route


@app.route("/chat", methods=["POST"])
def chat():
    user_input = request.json.get("message")
    if not user_input:
        return jsonify({"error": "No message provided"}), 400

    # Get the chat history from the session (if any)
    chat_history_ids = request.json.get("chat_history_ids")
    if chat_history_ids:
        chat_history_ids = torch.tensor(
            chat_history_ids)  # Convert back to a tensor

    # Get the bot's response
    bot_response, chat_history_ids = chat_with_bot(
        user_input, chat_history_ids)

    # Convert chat_history_ids to a list for JSON serialization
    chat_history_ids_list = chat_history_ids.tolist(
    ) if chat_history_ids is not None else None

    return jsonify({
        "response": bot_response,
        "chat_history_ids": chat_history_ids_list
    })


if __name__ == "__main__":
    app.run(debug=True)