Spaces:
Sleeping
Sleeping
import json | |
from collections import OrderedDict | |
from pathlib import Path | |
import streamlit as st | |
SEEKER_ICON = "https://github.com/McGill-NLP/FaithDial/raw/gh-pages/assets/img/seeker.png" | |
EXPERT_ICON = "https://github.com/McGill-NLP/FaithDial/raw/gh-pages/assets/img/expert.png" | |
begin_badges = { | |
"Entailment": "success", | |
"Hallucination": "danger", | |
"Partial Hallucination": "warning", | |
"Generic": "secondary", | |
"Uncooperative": "secondary", | |
} | |
st.set_page_config(page_title="FaithDial Explorer", page_icon=":stars:", layout="wide") | |
st.markdown( | |
""" | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" /> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script> | |
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha256-DF7Zhf293AJxJNTmh5zhoYYIMs2oXitRfBjY+9L//AY=" crossorigin="anonymous"> | |
<link rel="preconnect" href="https://fonts.googleapis.com"> | |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
<link href="https://fonts.googleapis.com/css2?family=Permanent+Marker&display=swap" rel="stylesheet"> | |
<style> | |
.dataset-title { | |
font-family: 'Permanent Marker', cursive; | |
font-size: 3.5rem; | |
} | |
.speaker-icon { | |
width: 20px; | |
} | |
p { | |
font-size: 1.5vmin; | |
} | |
span { | |
font-size: 1.5vmin; | |
} | |
.fa-flip-style { | |
--fa-animation-duration: 10s; | |
} | |
.faith-edit { | |
background-color: #d0f0c0; | |
} | |
</style>""", | |
unsafe_allow_html=True, | |
) | |
st.sidebar.write( | |
"""<center><p class="dataset-title"> | |
<a href="https://mcgill-nlp.github.io/FaithDial/">FaithDial</a> | |
</p></center>""", | |
unsafe_allow_html=True, | |
) | |
# st.sidebar.image("datasets_logo_name.png", width=300) | |
st.sidebar.subheader("A Faithful Benchmark for Information-Seeking Dialogue") | |
def load_dialogues(): | |
""" | |
Loads the samples from the data folder. | |
""" | |
samples_path = Path(__file__).parent / "faithdial-samples.jsonl" | |
with samples_path.open("r") as f: | |
samples = [json.loads(line) for line in f] | |
topics = OrderedDict() | |
for i, sample in enumerate(samples): | |
if sample.get("topic", None): | |
if sample["topic"] not in topics: | |
key = sample["topic"] | |
else: | |
key = f"{sample['topic']} (dialogue {i + 1})" | |
else: | |
key = f"Dialogue {i + 1}" | |
topics[key] = sample | |
return topics | |
dialogues = load_dialogues() | |
topics = tuple(dialogues.keys()) | |
st.sidebar.markdown( | |
"FaithDial contains 50,761 turns spanning 5649 conversations. Below you can choose a topic and visualize the conversation on the right hand side. Download the data from [here](https://huggingface.co/datasets/McGill-NLP/FaithDial)." | |
) | |
selected_topic = st.sidebar.radio("Pick a topic", topics, help="", key="topic_picker") | |
st.sidebar.markdown( | |
"<div class='mt-5'>Proudly collected at <a href='https://mcgill-nlp.github.io/'>McGill-NLP</a> in collaboration with <a href='https://www.amii.ca/'>Amii</a> & IBM</div>", | |
unsafe_allow_html=True | |
) | |
if selected_topic is not None: | |
selected_dialogue = dialogues[selected_topic] | |
st.write( | |
f"""<i class="far fa-comments fa-2x fa-flip fa-flip-style"></i> <span class="h1">{selected_topic}</span>""", | |
unsafe_allow_html=True) | |
st.markdown("***") | |
for i, exchange in enumerate(selected_dialogue["exchanges"]): | |
turn = i + 1 | |
# if exchange["history"]: | |
# history_template = """ | |
# <div class="card"> | |
# <div class="card-header">History</div> | |
# <div class="card-body"> | |
# """ | |
# for i, history in enumerate(exchange["history"]): | |
# icon = SEEKER_ICON if i % 2 == 0 else EXPERT_ICON | |
# history_template += ( | |
# f""" <p class="card-text"><img src="{icon}" class="rounded speaker-icon" /> {history}</p>""" | |
# ) | |
# history_template += """</div></div>""" | |
# st.write(history_template, unsafe_allow_html=True) | |
# st.write(f"""<h3>Turn {turn}</h3>""", unsafe_allow_html=True) | |
evidence_col, exchange_col = st.columns((0.7, 1)) | |
evidence_template = f""" | |
<div class="alert alert-secondary" role="alert"> | |
<h6 class="alert-heading"><span class="font-weight-bold" id="knowledge-{turn}">Knowledge</h6> | |
<p class="card-text mb-1">{exchange["evidence"]}</p> | |
</div> | |
<br/> | |
""" | |
evidence_col.write(evidence_template, unsafe_allow_html=True) | |
parallel_template = """ | |
<div class="container"> | |
<div class="row mb-3"> | |
<div class="col"> | |
{seeker} | |
</div> | |
</div> | |
<div class="row mb-4"> | |
<div class="col"> | |
{expert} | |
</div> | |
</div> | |
</div> | |
""" | |
seeker = exchange["seeker"] | |
is_seeker_modified = bool(seeker.get("OldText", None)) | |
expert = exchange["expert"] | |
is_expert_modified = bool(expert.get("OldText", None)) | |
exchange_pane = exchange_col.empty() | |
seeker_template = f"""<img src="{SEEKER_ICON}" class="rounded" style="text-align:center; width: 20px"/> | |
<span class="font-weight-bold">Seeker:</span> <span>{seeker["Text"]}</span>""" | |
expert_template = f"""<img src="{EXPERT_ICON}" class="rounded" style="text-align:center; width: 20px"/> | |
<span class="font-weight-bold">Wizard:</span> <span>{expert["Text"]}</span>""" | |
exchange_pane.write( | |
parallel_template.format( | |
seeker=seeker_template, | |
expert=expert_template, | |
), | |
unsafe_allow_html=True, | |
) | |
show_original = exchange_col.checkbox("Show original", key=f"show-{selected_topic}-{turn}") | |
if show_original: | |
apprentice_template = f"<span class='font-weight-bold'>Apprentice:</span> <span class='font-italic'>{seeker.get('OldText', None) or seeker['Text']}</span>" | |
badges = f"""<span class='badge badge-{begin_badges[expert['BEGIN']]}'>{expert['BEGIN']}</span> | |
{" ".join("<span class='badge badge-light'>{}</span>".format(v) for v in sorted(expert['VRM']))}""" | |
wizard_template = f"""<span class="font-weight-bold">Wizard:</span> | |
<span class="font-italic">{expert.get("OldText", None) or expert["Text"]}</span> {badges}""" | |
original_template = """<div class="card card-body bg-secondary text-white"> | |
<div class="row mb-3"> | |
<div class="col"> | |
{apprentice} | |
</div> | |
</div> | |
<div class="row"> | |
<div class="col"> | |
{wizard} | |
</div> | |
</div> | |
</div> | |
""" | |
exchange_col.write( | |
original_template.format(apprentice=apprentice_template, wizard=wizard_template, turn=turn), | |
unsafe_allow_html=True, | |
) | |
seeker_template = f"""<img src="{SEEKER_ICON}" class="rounded" style="text-align:center; width: 20px"/> | |
<span class="font-weight-bold">Seeker:</span> {"<span class='faith-edit'>" if is_seeker_modified else "<span>"}{seeker["Text"]}</span>""" | |
expert_template = f"""<img src="{EXPERT_ICON}" class="rounded" style="text-align:center; width: 20px"/> | |
<span class="font-weight-bold">Wizard:</span> {"<span class='faith-edit'>" if is_expert_modified else "<span>"}{expert["Text"]}</span>""" | |
exchange_pane.write( | |
parallel_template.format( | |
seeker=seeker_template, | |
expert=expert_template, | |
), | |
unsafe_allow_html=True, | |
) | |
exchange_col.markdown('') | |
exchange_col.markdown("""***""") | |