An NLP-based generative chatbot that speaks like a character from a classic 1940's Film Noir.
To create the chatbot I used a corpus of Film Noir screenplays to fine-tune Hugging Face's version of Microsoft's DialoGPT NLP model.
Even though the training corpus was fairly small (10,000 lines of dialogue) the fine-tuned model has picked up quite a lot of Film Noir style and content. Conversations tend to veer towards themes of crime and betrayal, and the vocabulary contains quite a bit of 1940's slang. The chatbot has no concept of character, so it will sometimes abruptly shift personas between detective and femme fatale, or address the user with different names.
The current model does tend to suffer from overfitting – the chatbot will sometimes retrieve a memorized line of dialogue straight from a screenplay instead of coming up with a novel response. I plan to redo the fine-tuning using more data and a less-complex base model in order to address this problem.
To complete the project, I set up a Flask application that runs the NLP model and exposes a Rest API. My frontend, which I wrote in React, uses the API to send messages from the user to the model and get the responses back. The frontend also uses SQLite database to enable the user to save chats and load them again later.
I thought the user interface should be as simple as possible, and really focus the user on the chat experience itself. Ideally I wanted the conversation with the bot to be the interface, not the text and buttons on the screen.
When the app first loads the chat window is already active, and the user can just jump in and start chatting. But if the user hesitates for more than 10 seconds, the bot takes the initiative and starts talking to the user.
These messages aren't generated by the model, they're a pre-scripted sequence designed to invite the user into the experience. The longer the user goes without typing anything, the more specific the prompts get. As soon as the user starts typing, the sequence ends and the model takes over the conversation.
The user can save the current chat, view their saved chats, and load saved chats into the current chat window in case they want to resume the conversation. The saved chat dialogue is loaded into the model as well as the frontend UI, so that the chatbot is aware of the context of the conversation and can pick up where it left off.