I have made this simple model creator in python : import tkinter as tk
from tkinter import filedialog
from keras.models import Sequential
from keras.layers import Embedding, LSTM, Dense
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.utils import to_categorical
import numpy as np
import os

# Data loader and preprocessor function
def preprocess_data(file_path, sequence_length=5):
    # Initialize the tokenizer
    tokenizer = Tokenizer()
    # Load your dataset
    with open(file_path, 'r', encoding='utf-8') as file:
        text = file.read()

    # Split by lines or sentences (customize based on how your data is formatted)
    sentences = text.split('\n')

    # Fit the tokenizer on the sentences
    tokenizer.fit_on_texts(sentences)

    # Convert sentences to sequences
    sequences = tokenizer.texts_to_sequences(sentences)

    # Flatten the list of sequences into one big sequence and create input-output pairs
    big_sequence = [token for seq in sequences for token in seq]
    input_sequences, output_words = [], []
    for i in range(0, len(big_sequence) - sequence_length):
        input_sequences.append(big_sequence[i:i + sequence_length])
        output_words.append(big_sequence[i + sequence_length])
        
    # Pad the sequences
    input_sequences = pad_sequences(input_sequences, maxlen=sequence_length)
    
    # Get the total number of unique tokens
    vocab_size = len(tokenizer.word_index) + 1  # Plus 1 for zero padding
    
    # Convert output words to one-hot encoding
    output_words = np.array(output_words)
    output_words = to_categorical(output_words, num_classes=vocab_size)
    
    return input_sequences, output_words, vocab_size

# Function to train and save the model
def train_model():
    # Get input values
    num_layers = int(entry_layers.get())
    layer_size = int(entry_size.get())
    model_name = entry_name.get()
    epochs = int(entry_epochs.get())
    data_path = entry_data_path.get()
    
    # Preprocess the data
    input_sequences, output_words, vocab_size = preprocess_data(data_path)
    
    # Define the model architecture
    model = Sequential()
    model.add(Embedding(input_dim=vocab_size, output_dim=layer_size, input_length=input_sequences.shape[1]))
    for _ in range(num_layers - 1):  # -1 because the last layer is added after the loop
        model.add(LSTM(units=layer_size, return_sequences=True))
    model.add(LSTM(units=layer_size))
    model.add(Dense(vocab_size, activation='softmax'))  # Multiclass classification for next word prediction

    # Compile the model
    model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

    # Train the model
    model.fit(input_sequences, output_words, epochs=epochs)

    # Save the model
    if not os.path.exists('models'):
        os.makedirs('models')
    model.save(os.path.join('models', f'{model_name}.h5'))
    print(f"Model {model_name} trained and saved successfully!")

# UI Setup
root = tk.Tk()
root.title("Chatbot Language Model Trainer")

# Number of layers
lbl_layers = tk.Label(root, text="Number of layers:")
lbl_layers.pack()
entry_layers = tk.Entry(root)
entry_layers.pack()

# Layer size
lbl_size = tk.Label(root, text="Size of each layer:")
lbl_size.pack()
entry_size = tk.Entry(root)
entry_size.pack()

# Model name
lbl_name = tk.Label(root, text="Model name:")
lbl_name.pack()
entry_name = tk.Entry(root)
entry_name.pack()

# Number of epochs
lbl_epochs = tk.Label(root, text="Number of epochs:")
lbl_epochs.pack()
entry_epochs = tk.Entry(root)
entry_epochs.pack()

# Data file path
lbl_data_path = tk.Label(root, text="Data file path:")
lbl_data_path.pack()
entry_data_path = tk.Entry(root)
entry_data_path.pack()

def select_file():
    file_path = filedialog.askopenfilename()
    entry_data_path.delete(0, tk.END)
    entry_data_path.insert(0, file_path)

btn_browse = tk.Button(root, text="Browse...", command=select_file)
btn_browse.pack()

# Train button
btn_train = tk.Button(root, text="Train Model", command=train_model)
btn_train.pack()

# Start the tkinter loop
root.mainloop()  and i also made an app to run the created model inside a chat interface, but i need a tokenizer to make it functional, please use the same tokenizer used in the first app and add it to the chat app, here is the code for the chat app: import tkinter as tk
from tkinter import filedialog
from keras.models import load_model
from keras.preprocessing.sequence import pad_sequences
import numpy as np
import pickle

# Initialize global variables
tokenizer = None
model = None
max_sequence_length = 5  # Change based on your model training configuration

# Function for model inference
def generate_text(input_text):
    global model, tokenizer
    if not model or not tokenizer:
        output_text.set("Please load a model and select a tokenizer first.")
        return
    
    try:
        sequence = tokenizer.texts_to_sequences([input_text])[0]
        sequence = pad_sequences([sequence], maxlen=max_sequence_length-1, padding='pre')
        
        prediction = model.predict(sequence, verbose=0)
        predicted_index = np.argmax(prediction, axis=-1)
        predicted_word = tokenizer.index_word.get(predicted_index[0], "UNK")

        output_text.set(predicted_word)
    except Exception as e:
        output_text.set(f"Error generating text: {e}")

# Function to load the model
def load_trained_model():
    global model
    model_path = filedialog.askopenfilename(title="Select model file", filetypes=[("HDF5 File", "*.h5")])
    if model_path:
        try:
            model = load_model(model_path)
            model_status.set("Model loaded successfully.")
        except Exception as e:
            model_status.set(f"Error loading model: {e}")

# Function to load the tokenizer object
def set_tokenizer(tokenizer_name):
    global tokenizer
    try:
        # Adjust the path to where you store your tokenizers
        with open(f'tokenizers/{tokenizer_name}.pickle', 'rb') as handle:
            tokenizer = pickle.load(handle)
            tokenizer_status.set("Tokenizer loaded successfully.")
    except Exception as e:
        tokenizer_status.set(f"Error loading tokenizer: {e}")

# GUI setup
root = tk.Tk()
root.title("Chatbot Inference")

model_status = tk.StringVar(root, value="No model loaded.")
tokenizer_status = tk.StringVar(root, value="No tokenizer selected.")
output_text = tk.StringVar(root)

# Input text field
input_label = tk.Label(root, text="Input text:")
input_label.pack()
input_entry = tk.Entry(root)
input_entry.pack()

# Load model button
load_model_button = tk.Button(root, text="Load Model", command=load_trained_model)
load_model_button.pack()
model_status_label = tk.Label(root, textvariable=model_status)
model_status_label.pack()

# Tokenizer dropdown menu
tokenizer_label = tk.Label(root, text="Select tokenizer:")
tokenizer_label.pack()
# Replace these with the actual names of your tokenizers
available_tokenizers = ["tokenizer1", "tokenizer2", "tokenizer3"]
tokenizer_var = tk.StringVar(root)
tokenizer_var.set(available_tokenizers[0])  # Set default value
tokenizer_menu = tk.OptionMenu(root, tokenizer_var, *available_tokenizers, command=set_tokenizer)
tokenizer_menu.pack()
tokenizer_status_label = tk.Label(root, textvariable=tokenizer_status)
tokenizer_status_label.pack()

# Generate text button
generate_button = tk.Button(root, text="Generate", command=lambda: generate_text(input_entry.get()))
generate_button.pack()

# Display the generated text
output_label = tk.Label(root, text="Generated text:")
output_label.pack()
output_text_label = tk.Label(root, textvariable=output_text)
output_text_label.pack()

# Run the GUI loop
root.mainloop()