GlobEnc / app.py
mohsenfayyaz's picture
Update app.py
7e95840
import gradio as gr
import torch
import numpy as np
from transformers import AutoTokenizer
from src.modeling.modeling_bert import BertForSequenceClassification
from src.modeling.modeling_electra import ElectraForSequenceClassification
from src.attention_rollout import AttentionRollout
import seaborn as sns
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import matplotlib.backends.backend_pdf
def inference(text, model):
if model == "bert-base-uncased-cls-sst2":
config = {
# As of now, BERT and ELECTRA are supported. You can choose any checkpoing of these models.
### BERT-base
"MODEL": "TehranNLP-org/bert-base-uncased-cls-sst2"
# "MODEL": "TehranNLP-org/bert-base-uncased-cls-mnli"
# "MODEL": "TehranNLP-org/bert-base-uncased-cls-hatexplain"
### BERT-large
# "MODEL": "TehranNLP-org/bert-large-sst2"
# "MODEL": "TehranNLP-org/bert-large-mnli"
# "MODEL": "TehranNLP-org/bert-large-hateXplain"
### ELECTRA
# "MODEL": "TehranNLP-org/electra-base-sst2"
# "MODEL": "TehranNLP-org/electra-base-mnli"
# "MODEL": "TehranNLP-org/electra-base-hateXplain"
}
elif model == "bert-large-sst2":
config = {
# As of now, BERT and ELECTRA are supported. You can choose any checkpoing of these models.
### BERT-base
#"MODEL": "TehranNLP-org/bert-base-uncased-cls-sst2"
# "MODEL": "TehranNLP-org/bert-base-uncased-cls-mnli"
# "MODEL": "TehranNLP-org/bert-base-uncased-cls-hatexplain"
### BERT-large
"MODEL": "TehranNLP-org/bert-large-sst2"
# "MODEL": "TehranNLP-org/bert-large-mnli"
# "MODEL": "TehranNLP-org/bert-large-hateXplain"
### ELECTRA
# "MODEL": "TehranNLP-org/electra-base-sst2"
# "MODEL": "TehranNLP-org/electra-base-mnli"
# "MODEL": "TehranNLP-org/electra-base-hateXplain"
}
else:
config = {
# As of now, BERT and ELECTRA are supported. You can choose any checkpoing of these models.
### BERT-base
#"MODEL": "TehranNLP-org/bert-base-uncased-cls-sst2"
# "MODEL": "TehranNLP-org/bert-base-uncased-cls-mnli"
# "MODEL": "TehranNLP-org/bert-base-uncased-cls-hatexplain"
### BERT-large
#"MODEL": "TehranNLP-org/bert-large-sst2"
# "MODEL": "TehranNLP-org/bert-large-mnli"
# "MODEL": "TehranNLP-org/bert-large-hateXplain"
### ELECTRA
"MODEL": "TehranNLP-org/electra-base-sst2"
# "MODEL": "TehranNLP-org/electra-base-mnli"
# "MODEL": "TehranNLP-org/electra-base-hateXplain"
}
SENTENCE = text
tokenizer = AutoTokenizer.from_pretrained(config["MODEL"])
tokenized_sentence = tokenizer.encode_plus(SENTENCE, return_tensors="pt")
if "bert" in config["MODEL"]:
model = BertForSequenceClassification.from_pretrained(config["MODEL"])
elif "electra" in config["MODEL"]:
model = ElectraForSequenceClassification.from_pretrained(config["MODEL"])
else:
raise Exception(f"Not implented model: {config['MODEL']}")
# Extract single layer attentions
with torch.no_grad():
logits, attentions, norms = model(**tokenized_sentence, output_attentions=True, output_norms=True, return_dict=False)
num_layers = len(attentions)
norm_nenc = torch.stack([norms[i][4] for i in range(num_layers)]).squeeze().cpu().numpy()
print("Single layer N-Enc token attribution:", norm_nenc.shape)
# Aggregate and compute GlobEnc
globenc = AttentionRollout().compute_flows([norm_nenc], output_hidden_states=True)[0]
globenc = np.array(globenc)
print("Aggregated N-Enc token attribution (GlobEnc):", globenc.shape)
tokenized_text = tokenizer.convert_ids_to_tokens(tokenized_sentence["input_ids"][0])
plt.figure(figsize=(14, 8))
norm_cls = globenc[:, 0, :]
norm_cls = np.flip(norm_cls, axis=0)
row_sums = norm_cls.max(axis=1)
norm_cls = norm_cls / row_sums[:, np.newaxis]
df = pd.DataFrame(norm_cls, columns=tokenized_text, index=range(len(norm_cls), 0, -1))
ax = sns.heatmap(df, cmap="Reds", square=True)
bottom, top = ax.get_ylim()
ax.set_ylim(bottom + 0.5, top - 0.5)
plt.title("GlobEnc", fontsize=16)
plt.ylabel("Layer", fontsize=16)
plt.xticks(rotation = 90, fontsize=16)
plt.yticks(fontsize=13)
plt.gcf().subplots_adjust(bottom=0.2)
print("logits:", logits)
return plt
demo = gr.Blocks()
with demo:
gr.Markdown(
"""
## Please check out [DecompX](https://huggingface.co/spaces/mohsenfayyaz/DecompX) for a more faithful approach.
## Gradio Demo for [mohsenfayyaz/GlobEnc](https://github.com/mohsenfayyaz/GlobEnc), GlobEnc: Quantifying Global Token Attribution by Incorporating the Whole Encoder Layer in Transformers
""")
inp = [gr.Textbox(),gr.Dropdown(choices=['bert-base-uncased-cls-sst2','bert-large-sst2','electra-base-sst2'])]
out = gr.Plot()
button = gr.Button(value="Run")
gr.Examples([["A deep and meaningful film.", "bert-base-uncased-cls-sst2"], ["A deep and meaningful film.", "bert-large-sst2"]], inp, out, inference)
button.click(fn=inference,
inputs=inp,
outputs=out)
demo.launch()