Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
118 commits
Select commit Hold shift + click to select a range
7a97484
Update required dependencies
nghtctrl Jun 19, 2023
c9d93ce
Updated documentation for the genQuestion function
nghtctrl Jun 19, 2023
50f43fa
Modularize back-end logic
nghtctrl Jun 19, 2023
235da4e
Import modularized backend
nghtctrl Jun 19, 2023
a0633c6
Update deprecated code
nghtctrl Jun 19, 2023
748f7cb
Removed imports and dependencies that are not actually used
nghtctrl Jun 19, 2023
d8aa585
Removed silly typo
nghtctrl Jun 19, 2023
a933690
Edited to better fit the PEP 8 standards
nghtctrl Jun 19, 2023
7d23b8a
Added useful directions to launch the app
nghtctrl Jun 19, 2023
086e1f2
Merge project README into one
nghtctrl Jun 19, 2023
2bd06b3
Merge info from Project into README.
kcarnold Jun 20, 2023
d961117
Initial commit
nghtctrl Jun 21, 2023
1947cb1
Add generate_questions function
nghtctrl Jun 22, 2023
30c4ab9
Add CUDA support
nghtctrl Jun 22, 2023
b658510
Specify the dependencies required
nghtctrl Jun 22, 2023
2d49843
Update dependencies
nghtctrl Jun 22, 2023
8c885b3
Add load_contexts_from function
nghtctrl Jun 22, 2023
4d32368
Add get_contexts_and_questions function
nghtctrl Jun 22, 2023
bce32e0
Clean up testing code
nghtctrl Jun 22, 2023
6e5ed39
Add backend server
nghtctrl Jun 22, 2023
12f9bed
Generate JSON using the get_contexts_and_questions function from the …
nghtctrl Jun 22, 2023
d42a278
Allow users to enter custom port number when testing the server
nghtctrl Jun 22, 2023
82b2775
Add goal and instructions on how to run
nghtctrl Jun 22, 2023
17d2112
Make the instruction more friendly (for now)
nghtctrl Jun 22, 2023
4ba4d46
Replace the function with a simpler method from Path that does the sa…
nghtctrl Jun 24, 2023
da88540
Drop specific torch configuration as a requirement
nghtctrl Jun 24, 2023
e7a6902
Add CORS headers
kcarnold Jun 26, 2023
fd559b0
Add demo data
kcarnold Jun 26, 2023
11fadda
Merge branch 'jk-dev' of github.com:AIToolsLab/questions into jk-dev
nghtctrl Jun 27, 2023
23776dd
Rename module containing NLP methods to a more appropriate name
nghtctrl Jun 28, 2023
cefd556
Rename to interview_ai
nghtctrl Jun 28, 2023
5109085
Removing because text file opeartions are no longer relevant
nghtctrl Jun 28, 2023
0341f50
Removed the testing text file
nghtctrl Jun 28, 2023
6218a48
Use Huggingface Pipeline
nghtctrl Jun 28, 2023
7f51cd6
Configure function output to be a list of questions
nghtctrl Jun 28, 2023
5f94934
Allow control of the number of questions to generate
nghtctrl Jun 28, 2023
b514d59
Add interface method to communicate with the back-end server
nghtctrl Jun 28, 2023
4aa1e9e
Remove unncessary imports
nghtctrl Jun 28, 2023
b93a5dd
Clean up imports
nghtctrl Jun 28, 2023
39ebc22
Fix silly mistake
nghtctrl Jun 28, 2023
3177054
Document possible risk
nghtctrl Jun 28, 2023
14ad653
Use pydantic instead of json
nghtctrl Jun 28, 2023
5c4983e
Add pseudo database
nghtctrl Jun 28, 2023
f378e77
Add POST and GET methods
nghtctrl Jun 28, 2023
0ca8356
Generate question while appending
nghtctrl Jun 28, 2023
2229666
Clean up
nghtctrl Jun 28, 2023
376878c
Use GPU
nghtctrl Jun 28, 2023
fb7ab45
Update README
nghtctrl Jun 28, 2023
052a5d9
Remove type annotations for now
nghtctrl Jun 28, 2023
d79459b
Use type annotation from typing package
nghtctrl Jun 28, 2023
fb63812
Configure to return only one question for now
nghtctrl Jun 28, 2023
ed94d94
Initial commit
nghtctrl Jun 30, 2023
aedac98
Simplified UI into one run button for now
nghtctrl Jun 30, 2023
38d73fb
Add getComment function
nghtctrl Jun 30, 2023
abf1633
Create .gitignore
RayHCai Jul 1, 2023
b05673f
Added openai approach
RayHCai Jul 1, 2023
6adb4de
Separate operations that are purely for comments extraction
nghtctrl Jul 3, 2023
9a2ed4a
Return comments as an array
nghtctrl Jul 3, 2023
3b6f661
Add getReplies function
nghtctrl Jul 3, 2023
d358ebc
Add getContext function
nghtctrl Jul 3, 2023
d5d5c00
Put eveything under main function
nghtctrl Jul 3, 2023
18bdd0c
Create getCommentReplies and getCommentContexts functions
nghtctrl Jul 5, 2023
693fee2
Edited getCommentContexts function to use map for better readability
nghtctrl Jul 5, 2023
08c6ce8
Move the main function to the bottom for better readability
nghtctrl Jul 5, 2023
3cd1679
Add a way to extract the contexts and replies collected
nghtctrl Jul 5, 2023
e065ce4
Add post function which handles HTTP POST request
nghtctrl Jul 5, 2023
c04e849
Merge branch 'jk-dev' of https://github.com/AIToolsLab/questions into…
nghtctrl Jul 5, 2023
b69b623
Initial commit
nghtctrl Jul 5, 2023
6008721
Add CORS mechanism
nghtctrl Jul 5, 2023
d60765c
Added TODO comments
nghtctrl Jul 5, 2023
e0e17e8
Can get the document paragraphs and make cards.
kcarnold Jul 10, 2023
b56f2d5
Made an API endpoint for requesting Chat-based reflections
kcarnold Jul 10, 2023
6e2d173
ignores
kcarnold Jul 10, 2023
f70976f
ignore database
kcarnold Jul 10, 2023
b0185eb
Can now show a reflection made by the server.
kcarnold Jul 10, 2023
b6d573c
Use custom prompt, for current paragraph
kcarnold Jul 10, 2023
6fce707
Preset prompts
kcarnold Jul 10, 2023
d5f1ea5
Tweak prompt display
kcarnold Jul 10, 2023
3793097
Fix display
kcarnold Jul 10, 2023
c9ebc7c
Fix partially completed line of code
kcarnold Jul 10, 2023
afd65ed
TODO
kcarnold Jul 10, 2023
32ae14f
Merge branch 'main' into jk-dev
kcarnold Jul 10, 2023
62d7c90
Merge pull request #13 from AIToolsLab/jk-dev
kcarnold Jul 10, 2023
be40006
Another prompt, inspired by Vic Norman
kcarnold Jul 10, 2023
9b2cc91
One .gitignore to rule them all
nghtctrl Jul 11, 2023
b785ad0
Remove gitignore in favor of keeping on gitignore
nghtctrl Jul 11, 2023
aa6a377
Remove project level server codes (not related to Ray's code)
nghtctrl Jul 11, 2023
2950970
Simple reformatting
nghtctrl Jul 11, 2023
3380527
Update dependency list
nghtctrl Jul 11, 2023
3370987
Simple reformatting
nghtctrl Jul 11, 2023
6fab308
Use a variable to refer to database file
nghtctrl Jul 11, 2023
265f890
Use db_file
nghtctrl Jul 11, 2023
91f1973
Merge pull request #15 from AIToolsLab/jk-dev
kcarnold Jul 11, 2023
82898f9
Try switching to React
kcarnold Jul 11, 2023
4a8d6fa
Merge highlighting from Sophia. This makes requests for each paragrap…
kcarnold Jul 11, 2023
a10bb02
Request multiple feedback cards in JSON format from the API.
kcarnold Jul 11, 2023
9bfa80a
Minor schema fixes
kcarnold Jul 11, 2023
80d82d7
Show multiple cards
kcarnold Jul 11, 2023
68d38bf
Compact display of cards
kcarnold Jul 11, 2023
33acd7a
Redundant with later sanitize()
kcarnold Jul 11, 2023
24270c3
TODOs
kcarnold Jul 11, 2023
9567d36
Fix mistaken deletion
kcarnold Jul 11, 2023
6eba0b3
backoff to avoid rate limits (untested)
kcarnold Jul 11, 2023
bde7de0
Experimental tweaks to the JSON schema
kcarnold Jul 11, 2023
47c1d0d
sort imports
kcarnold Jul 11, 2023
e997f89
drop nest_asyncio (only needed for the notebook)
kcarnold Jul 11, 2023
7eb5ba2
somebody added these exclusions in a live share
kcarnold Jul 11, 2023
948122e
move 2022 files into seperate 2022 folder
RayHCai Jul 12, 2023
695420b
Prettier
RayHCai Jul 12, 2023
c04a56c
rename to reflectia
RayHCai Jul 12, 2023
1908f06
Update index.tsx
RayHCai Jul 12, 2023
80e364c
Switched to function based components and removed unneeded files
RayHCai Jul 12, 2023
440cb98
functionality migrated
RayHCai Jul 12, 2023
3455c32
remove old code
RayHCai Jul 12, 2023
4e34598
Remove icons in assets folder
RayHCai Jul 12, 2023
ba0f618
Merge branch 'main' of https://github.com/AIToolsLab/questions into r…
RayHCai Jul 13, 2023
301a4c9
Remove unneeded files + reorganized
RayHCai Jul 13, 2023
1ffe747
Revert "move 2022 files into seperate 2022 folder"
kcarnold Jul 14, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# General
.DS_Store
__pycache__/

# VS Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
.history/
*.vsix

# Dependency directories
node_modules/

# Database files
requests.db

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
57 changes: 54 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,56 @@
# InterviewAI
A system that encourages writers to think deeply by asking them questions.

With the advent of machine learning, it has become increasingly clear that AI is capable of completing tasks that were hitherto considered only possible by human minds. We are now pushing the boundaries of what AI can do with natural language processing (NLP), from summarizing pages of text to keeping up a conversation with a human. Our project aims to join those on the frontier of machine learning by creating an AI Interviewer. There are two main problems to address here: first, whether creating such an interviewer will be possible, and second, whether it will be any good.
## Flourishing in this project looks like

See our [project website](https://haramkoo.github.io/InterviewAI/) for more information.
- Playful experimentation with user interfaces and question generation approaches
- A shared place where we're running quantitative evaluations (perhaps quick-and-dirty) of different approaches
- Eagerness to have writers try out this system
- A draft of a paper coming together (perhaps starting with the formative study writing)
- A presentation coming together, where we copy and paste examples of cool stuff (and broken stuff)



## DAISI (Deep Artificial Intelligence System for Interviews)

### About

With the advent of machine learning, it has become increasingly clear that AI is capable of completing tasks that were hitherto considered only possible by human minds. We hope to join those on the frontier of machine learning by creating an AI Interviewer, temporarily named DAISI. There are two main problems to address here: first, whether creating such an interviewer will be possible, and second, whether it will be any good. We have managed thus far to create prototype models that are capable of asking questions, and we have created qualitative metrics to score the models' performance. We have also created some quantitative metrics based on those qualitative metrics, and hope to expand our quantitative metrics further with more research. Our next step as of the writing of this About section is to iteratively create more models that will hopefully perform better than our current prototypes.

___

### Project

This is a research project; the focus is less on developing new software and more on refining pre-existing ones to suit our needs. Our research objective is first and foremost to see whether modern AI models can replicate the job of an interviewer to a satisfactory enough degree that we could feasibly use it for actual interviews. Should we succeed, there could be a use for the AI Interviewer, such as replacing journalists in dangerous locations like warzones. Moreover, the success of our AI Interviewer could aid in other research projects, such as AI to help writers, AI call center representatives, or any other position that involves asking questions or guiding conversations based on context.

___

### The Team

#### Hyechan Jun

Hyechan Jun is a Senior Computer Science (BCS) major with a double major in Writing. He plans to continue studying AI into graduate school, with the goal of obtaining a Ph.D.

#### Ha-Ram Koo

Ha-Ram Koo is a Senior Computer Science (BCS) major with a minor in Spanish. He is in charge of data collection and data wrangling procedures for this project.

#### Advait Scaria

Advait Scaria is a Senior Computer Science (BCS) major with a minor in Data Science. He is the main analyst and judge of the models' performance.

___

### Project Materials

- [Project Website](https://haramkoo.github.io/InterviewAI/)
- [Proposal](https://docs.google.com/document/d/1jYFH2y0SFvw5K9eVFQRNMO-UazR5w9YKnHaMpmKdFhk/edit?usp=sharing)
- [Project Repo](https://github.com/haramkoo/InterviewAI)
- [Research Paper/Report](https://drive.google.com/file/d/1tUyPhk9ePAeYYJh_T6nqyXttOsvmFExE/view?usp=sharing)
- [Status Report Presentation](https://docs.google.com/presentation/d/1yWd4C6-0VyIv4WeSGReReajeSNEWJ7VndQVG7goXSJk/edit?usp=sharing)
- [Web App](https://huggingface.co/spaces/calvininterview/interview-streamlit)

<!-- Add link to final presentation -->

### Other Links

- [Calvin Computer Science Department](https://computing.calvin.edu/)
57 changes: 57 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Issues

- Need Error handling

## Prompts need improvement

1. Fix ChatGPT prompt so that it is confined to text only provided by the user
2. Find the prompt kca had written for question summaries

Overall: try the prompt evaluation tool https://github.com/typpo/promptfoo

We can test for hallucination by asserting that the response *doesn't* include some things that we know are not in the text.

Don't bother asking about paragraphs that are too short (3 sentences or less?).

Rate limiting on the server side.

Only request reflections on parapgrahs right around the current one.

- Put back in "phrase_from_paragraph": "..."
- Ensure that it actually matches a phrase from the parapgraph
- fuzzy match w/ regex?? (Ray)



## Card display

- Would be nice to show more than just the current paragraph (maybe the previous and next paragraph as well)
- Response formatting: lists should show up as lists (Markdown?? Ask for a JSON response??)
- See the OpenAI "function calling" example for how to specify the response format
- Ask for the response in HTML? (Cheating...?)
- Affordances
- Thumbs up and thumbs down buttons??
- Thumbs down regenerates? bust the cache somehow
- just log the thumbs-down?
- Thumbs up saves to a comment? log this somehow too


## Two-way mapping

- When you hover over a card, highlight the corresponding text in the document. (At least the corresponding paragraph.)
- When you click on a paragraph, highlight the corresponding card. (Sophia has code that might work already.)

## Controls

- More preset prompts
- Clearer way to edit the prompt?
- Use FabricUI styles so it matches Word?
- Maybe request multiple responses? Pick best of...?



Alternative highlighting approach:


Rewrite the following paragraph, put square brackets around the phrases that are relevant to "...".

43 changes: 0 additions & 43 deletions index.md

This file was deleted.

28 changes: 16 additions & 12 deletions interview-streamlit/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
---
title: Interview Streamlit
emoji: 📉
colorFrom: pink
colorTo: green
sdk: streamlit
sdk_version: 1.2.0
app_file: app.py
pinned: false
---

Check out the configuration reference at https://huggingface.co/docs/hub/spaces#reference
# Interview AI Test Website

This is an Interview AI testing stack designed by the [Senior Project 2021](https://haramkoo.github.io/InterviewAI/) team using the [Streamlit](https://streamlit.io/) framework. The production is meant to be live [here](https://huggingface.co/spaces/calvininterview/interview-streamlit), but it is currently down for unknown reasons.

Run the following commands to run the front-end in your machine:

*It is highly recommended that you run these commands in some sort of [Python virtual environment](https://www.youtube.com/watch?v=N5vscPTWKOk).*

```
pip install -r requirements.txt
```
```
streamlit run app.py
```

The last command should launch the app in your favorite browser.
76 changes: 12 additions & 64 deletions interview-streamlit/app.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import streamlit as st
import torch
from pandas import options
from transformers import BartForConditionalGeneration, BartTokenizer

# initialize model + tok variables
model = None
tok = None
from backend import genQuestion

# Examples for each models
context_example = ''
Expand All @@ -17,50 +12,6 @@
"I think things out well. When I speak, I speak with conviction. If I feel like it's something that best suits me and my person, I deal with it. I say it. I have no problem speaking out publicly about issues. But for personal things, and for things about personal selfishness, or wanting more money, I don't do that. Once I give my word, that's it. I don't go back to renegotiate. I don't renegotiate my contracts."
]


# pass in Strings of model choice and input text for context
@st.cache
def genQuestion(model_choice, context, tag):
# global descriptions
if model_choice=="Base model":
model = BartForConditionalGeneration.from_pretrained("hyechanjun/interview-question-remake")
tok = BartTokenizer.from_pretrained("hyechanjun/interview-question-remake")
elif model_choice=="Lengthed model":
model = BartForConditionalGeneration.from_pretrained("hyechanjun/interview-length-tagged")
tok = BartTokenizer.from_pretrained("hyechanjun/interview-length-tagged")
if (tag == '1-10'):
context += ' <TEN>'
elif (tag == '11-20'):
context += ' <TWENTY>'
elif (tag == '21-30'):
context += ' <THIRTY>'
elif (tag == '31-40'):
context += ' <FORTY>'
elif (tag == '51-60'):
context += ' <FIFTY>'
elif (tag == '61-70'):
context += ' <SIXTY>'
elif (tag == '71-80'):
context += ' <SEVENTY>'
elif (tag == '81-90'):
context += ' <EIGHTY>'
elif (tag == '81-90'):
context += ' <NINETY>'
elif (tag == '91+'):
context += ' <HUNDRED>'
elif model_choice=="Reverse model":
model = BartForConditionalGeneration.from_pretrained("hyechanjun/reverse-interview-question")
tok = BartTokenizer.from_pretrained("hyechanjun/reverse-interview-question")

inputs = tok(context, return_tensors="pt")
output = model.generate(inputs["input_ids"], num_beams=4, max_length=64, min_length=9, num_return_sequences=4, diversity_penalty=1.0, num_beam_groups=4)
final_output = ''
for i in range(4):
final_output += [tok.decode(beam, skip_special_tokens=True, clean_up_tokenization_spaces=False) for beam in output][i] + "\n\n"

return final_output


# Wide page layout
st.set_page_config(layout="wide")

Expand All @@ -75,8 +26,8 @@ def genQuestion(model_choice, context, tag):
col1, col2, col3 = st.columns(3)

context_option = col2.selectbox(
'Feel free to choose one of our premade contexts',
('Select one','Elon Musk', 'Fashion designer', 'Young entrepreneur', 'Michael Jordan')
'Feel free to choose one of our premade contexts',
('Select one','Elon Musk', 'Fashion designer', 'Young entrepreneur', 'Michael Jordan')
)

if context_option == 'Select one':
Expand All @@ -91,10 +42,9 @@ def genQuestion(model_choice, context, tag):
context_example = examples[3]

option = col1.selectbox(
'Please select a model.',
('Base model', 'Lengthed model', 'Reverse model'))


'Please select a model.',
('Base model', 'Lengthed model', 'Reverse model')
)

if option == 'Base model':
st.write("This is the re-fine-tuned base model for our interview AI. It returns strings terminating in a question mark (?).")
Expand All @@ -104,20 +54,18 @@ def genQuestion(model_choice, context, tag):
st.write("This model asks a question that would have resulted in the context you provide (a.k.a. it traverses backward through the interview)")

if option == 'Lengthed model':
context_length = col3.selectbox('Length of response',
('1-10', '11-20', '21-30', '31-40', '41-50', '51-60', '61-70', '71-80', '81-90', '91+'))

context_length = col3.selectbox(
'Length of response',
('1-10', '11-20', '21-30', '31-40', '41-50', '51-60', '61-70', '71-80', '81-90', '91+')
)

# Input fields
input = st.text_area('Context', value=context_example) # user inputs context to construct a response (str)

# user inputs context to construct a response (str)
input = st.text_area('Context', value=context_example)

if st.button('Submit') or st.session_state.button_sent:
with st.spinner('Generating a response...'):
output = genQuestion(option, input, context_length)
print(output)
st.session_state.button_sent = True
st.text_area(label="Generated Responses:", value=output, height=200)



62 changes: 62 additions & 0 deletions interview-streamlit/backend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from transformers import BartForConditionalGeneration, BartTokenizer
import streamlit as st

@st.cache_data
def genQuestion(model_choice, context, tag):
"""Generate interview questions.

Args:
model_choice: specify which BART model to use.
context: input text for the model.
tag: specify the length of the generated question (only if model_choice is 'Lengthed model').

Returns:
final_output: the four decoded generated sequences, separated by two newlines.
"""

model, tok = None, None

# Checks which BART model to use based on the value of model_choice
# Then loads a pre-trained BART model and tokenizer accordingly
if model_choice=="Base model":
model = BartForConditionalGeneration.from_pretrained("hyechanjun/interview-question-remake")
tok = BartTokenizer.from_pretrained("hyechanjun/interview-question-remake")
elif model_choice=="Lengthed model":
model = BartForConditionalGeneration.from_pretrained("hyechanjun/interview-length-tagged")
tok = BartTokenizer.from_pretrained("hyechanjun/interview-length-tagged")
if (tag == '1-10'):
context += ' <TEN>'
elif (tag == '11-20'):
context += ' <TWENTY>'
elif (tag == '21-30'):
context += ' <THIRTY>'
elif (tag == '31-40'):
context += ' <FORTY>'
elif (tag == '51-60'):
context += ' <FIFTY>'
elif (tag == '61-70'):
context += ' <SIXTY>'
elif (tag == '71-80'):
context += ' <SEVENTY>'
elif (tag == '81-90'):
context += ' <EIGHTY>'
elif (tag == '81-90'):
context += ' <NINETY>'
elif (tag == '91+'):
context += ' <HUNDRED>'
elif model_choice=="Reverse model":
model = BartForConditionalGeneration.from_pretrained("hyechanjun/reverse-interview-question")
tok = BartTokenizer.from_pretrained("hyechanjun/reverse-interview-question")

# Tokenize context parameter using the selected tokenizer
inputs = tok(context, return_tensors="pt")

# Generate text using the selected pre-trained BART model
output = model.generate(inputs["input_ids"], num_beams=4, max_length=64, min_length=9, num_return_sequences=4, diversity_penalty=1.0, num_beam_groups=4)

# Decode the generated text, then format it into a single string
final_output = ''
for i in range(4):
final_output += [tok.decode(beam, skip_special_tokens=True, clean_up_tokenization_spaces=False) for beam in output][i] + "\n\n"

return final_output
Loading