Viju Sudhi
commited on
Commit
·
2a15960
1
Parent(s):
c4727bc
refactor: updated application
Browse files- app.py +20 -233
- requirements.txt +1 -1
- src/ui/css/demo.css +211 -0
- src/ui/explainer_ui.py +240 -0
- src/ui/images/iais.svg +91 -0
- src/utils/visualizer.py +2 -2
app.py
CHANGED
@@ -1,240 +1,27 @@
|
|
1 |
-
import
|
2 |
-
from typing import List, Optional
|
3 |
|
4 |
-
|
5 |
-
from gradio.components import Markdown
|
6 |
-
|
7 |
-
from src.dto.dto import ExplanationGranularity, ExplanationDto
|
8 |
-
from src.utils.registry import EXPLAINERS, MODELS, PERTURBERS, COMPARATORS
|
9 |
-
from src.utils.segregate import PercentileBasedSegregator
|
10 |
from src.utils.visualizer import Visualizer
|
11 |
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
logo_path: str,
|
17 |
-
css_path: str,
|
18 |
-
visualizer: Visualizer,
|
19 |
-
window_title: str,
|
20 |
-
title: str,
|
21 |
-
examples: Optional[List[str]] = None,
|
22 |
-
):
|
23 |
-
self.__logo_path = logo_path
|
24 |
-
self.__css_path = css_path
|
25 |
-
self.__examples = examples
|
26 |
-
self.__window_title = window_title
|
27 |
-
self.__title = title
|
28 |
-
self.__visualizer = visualizer
|
29 |
-
|
30 |
-
self.app: gr.Blocks = self.build_app()
|
31 |
-
|
32 |
-
def build_app(self):
|
33 |
-
with gr.Blocks(
|
34 |
-
theme=gr.themes.Monochrome().set(
|
35 |
-
button_primary_background_fill="#009374",
|
36 |
-
button_primary_background_fill_hover="#009374C4",
|
37 |
-
checkbox_label_background_fill_selected="#028A6EFF",
|
38 |
-
),
|
39 |
-
css=self.__css_path,
|
40 |
-
title=self.__window_title,
|
41 |
-
) as demo:
|
42 |
-
self.__build_app_title()
|
43 |
-
(
|
44 |
-
user_input,
|
45 |
-
system_response,
|
46 |
-
granularity,
|
47 |
-
upper_percentile,
|
48 |
-
middle_percentile,
|
49 |
-
lower_percentile,
|
50 |
-
explainer_name,
|
51 |
-
model_name,
|
52 |
-
perturber_name,
|
53 |
-
comparator_name,
|
54 |
-
generator_vis,
|
55 |
-
submit_btn,
|
56 |
-
) = self.__build_chat_and_explain()
|
57 |
-
|
58 |
-
submit_btn.click(
|
59 |
-
fn=self.run,
|
60 |
-
inputs=[
|
61 |
-
user_input,
|
62 |
-
granularity,
|
63 |
-
upper_percentile,
|
64 |
-
middle_percentile,
|
65 |
-
lower_percentile,
|
66 |
-
explainer_name,
|
67 |
-
model_name,
|
68 |
-
perturber_name,
|
69 |
-
comparator_name,
|
70 |
-
],
|
71 |
-
outputs=[system_response, generator_vis],
|
72 |
-
)
|
73 |
-
|
74 |
-
return demo
|
75 |
-
|
76 |
-
def run(
|
77 |
-
self,
|
78 |
-
user_input: str,
|
79 |
-
granularity: ExplanationGranularity,
|
80 |
-
upper_percentile: str,
|
81 |
-
middle_percentile: str,
|
82 |
-
lower_percentile: str,
|
83 |
-
explainer_name: str,
|
84 |
-
model_name: str,
|
85 |
-
perturber_name: str,
|
86 |
-
comparator_name: str,
|
87 |
-
):
|
88 |
-
print(user_input)
|
89 |
-
with open(
|
90 |
-
"data/en_q_001.json",
|
91 |
-
"r",
|
92 |
-
) as f:
|
93 |
-
data = json.load(f)
|
94 |
-
data = data[0]
|
95 |
-
explanation_dto = ExplanationDto.parse_obj(data)
|
96 |
-
user_input = explanation_dto.input_text
|
97 |
-
|
98 |
-
system_response = explanation_dto.output_text
|
99 |
-
generator_vis = self.__visualize_explanations(
|
100 |
-
user_input=user_input,
|
101 |
-
system_response=system_response,
|
102 |
-
generator_explanations=explanation_dto,
|
103 |
-
upper_percentile=int(upper_percentile),
|
104 |
-
middle_percentile=int(middle_percentile),
|
105 |
-
lower_percentile=int(lower_percentile),
|
106 |
-
)
|
107 |
-
return system_response, generator_vis
|
108 |
-
|
109 |
-
def __build_app_title(self):
|
110 |
-
with gr.Row():
|
111 |
-
with gr.Column(min_width=50, scale=1):
|
112 |
-
gr.Image(
|
113 |
-
value=self.__logo_path,
|
114 |
-
width=50,
|
115 |
-
height=50,
|
116 |
-
show_download_button=False,
|
117 |
-
container=False,
|
118 |
-
)
|
119 |
-
with gr.Column(scale=2):
|
120 |
-
Markdown(
|
121 |
-
f'<p style="text-align: left; font-size:200%; font-weight: bold"'
|
122 |
-
f">{self.__title}"
|
123 |
-
f"</p>"
|
124 |
-
)
|
125 |
-
|
126 |
-
def __build_chat_and_explain(self):
|
127 |
-
with gr.Row():
|
128 |
-
with gr.Column(scale=2):
|
129 |
-
gr.Textbox(
|
130 |
-
label="Attention!",
|
131 |
-
value="This is a demo version of the tool! For running the full version, please follow the instructions in ...",
|
132 |
-
container=False,
|
133 |
-
interactive=False,
|
134 |
-
)
|
135 |
-
|
136 |
-
with gr.Row():
|
137 |
-
with gr.Column(scale=2):
|
138 |
-
user_input = gr.Radio(
|
139 |
-
# placeholder="Type your question here and press Enter.",
|
140 |
-
label="Question",
|
141 |
-
container=True,
|
142 |
-
choices=["Question 1 EN", "Question 1 DE"],
|
143 |
-
)
|
144 |
-
with gr.Column(scale=1):
|
145 |
-
granularity = gr.Radio(
|
146 |
-
choices=[e for e in ExplanationGranularity],
|
147 |
-
value=ExplanationGranularity.SENTENCE_LEVEL,
|
148 |
-
label="Explanation Granularity",
|
149 |
-
)
|
150 |
-
|
151 |
-
with gr.Accordion(label="Settings", open=False, elem_id="accordion"):
|
152 |
-
with gr.Row(variant="compact"):
|
153 |
-
explainer_name = gr.Radio(
|
154 |
-
label="Explainer",
|
155 |
-
choices=list(EXPLAINERS.keys()),
|
156 |
-
value=list(EXPLAINERS.keys())[0],
|
157 |
-
container=True,
|
158 |
-
)
|
159 |
-
with gr.Row(variant="compact"):
|
160 |
-
upper_percentile = gr.Textbox(label="Upper", value="85", container=True)
|
161 |
-
middle_percentile = gr.Textbox(
|
162 |
-
label="Middle", value="75", container=True
|
163 |
-
)
|
164 |
-
lower_percentile = gr.Textbox(label="Lower", value="10", container=True)
|
165 |
-
|
166 |
-
with gr.Row(variant="compact"):
|
167 |
-
model_name = gr.Radio(
|
168 |
-
label="Model",
|
169 |
-
choices=list(MODELS.keys()),
|
170 |
-
value=list(MODELS.keys())[0],
|
171 |
-
container=True,
|
172 |
-
)
|
173 |
-
with gr.Row(variant="compact"):
|
174 |
-
perturber_name = gr.Radio(
|
175 |
-
label="Perturber",
|
176 |
-
choices=list(PERTURBERS.keys()),
|
177 |
-
value=list(PERTURBERS.keys())[0],
|
178 |
-
container=True,
|
179 |
-
)
|
180 |
-
with gr.Row(variant="compact"):
|
181 |
-
comparator_name = gr.Radio(
|
182 |
-
label="Comparator",
|
183 |
-
choices=list(COMPARATORS.keys()),
|
184 |
-
value=list(COMPARATORS.keys())[0],
|
185 |
-
container=True,
|
186 |
-
)
|
187 |
-
with gr.Row(variant="compact"):
|
188 |
-
# passing "elem_id" to use a custom style for the component
|
189 |
-
# in the CSS passed.
|
190 |
-
submit_btn = gr.Button(
|
191 |
-
value="🛠 Submit",
|
192 |
-
variant="secondary",
|
193 |
-
elem_id="button",
|
194 |
-
interactive=True,
|
195 |
-
)
|
196 |
-
|
197 |
-
with gr.Row():
|
198 |
-
generator_vis = gr.HTML(label="Explanations")
|
199 |
|
200 |
-
with gr.Row():
|
201 |
-
system_response = gr.Textbox(
|
202 |
-
label="System Response",
|
203 |
-
container=True,
|
204 |
-
interactive=False,
|
205 |
-
)
|
206 |
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
comparator_name,
|
218 |
-
generator_vis,
|
219 |
-
submit_btn,
|
220 |
-
)
|
221 |
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
upper_percentile: Optional[int],
|
228 |
-
middle_percentile: Optional[int],
|
229 |
-
lower_percentile: Optional[int],
|
230 |
-
) -> str:
|
231 |
-
segregator = PercentileBasedSegregator(
|
232 |
-
upper_bound_percentile=upper_percentile,
|
233 |
-
middle_bound_percentile=middle_percentile,
|
234 |
-
lower_bound_percentile=lower_percentile,
|
235 |
-
)
|
236 |
-
return self.__visualizer.visualize(
|
237 |
-
segregator=segregator,
|
238 |
-
explanations=generator_explanations,
|
239 |
-
output_from_explanations=user_input,
|
240 |
-
)
|
|
|
1 |
+
import sys
|
|
|
2 |
|
3 |
+
from src.ui.explainer_ui import MockExplainerUI
|
|
|
|
|
|
|
|
|
|
|
4 |
from src.utils.visualizer import Visualizer
|
5 |
|
6 |
|
7 |
+
def load_visualizer() -> Visualizer:
|
8 |
+
visualizer = Visualizer(show_mid_features=True, show_low_features=True)
|
9 |
+
return visualizer
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
|
12 |
+
if __name__ == "__main__":
|
13 |
+
interface = MockExplainerUI(
|
14 |
+
logo_path="src/ui/images/iais.svg",
|
15 |
+
css_path="src/ui/css/demo.css",
|
16 |
+
visualizer=load_visualizer(),
|
17 |
+
window_title="RAG-Ex",
|
18 |
+
title="✳️ RAG-Ex: Towards Generic Explainability",
|
19 |
+
)
|
20 |
+
app = interface.build_app()
|
21 |
+
app.queue()
|
|
|
|
|
|
|
|
|
22 |
|
23 |
+
platform = sys.platform
|
24 |
+
print("Platform: ", platform)
|
25 |
+
host = "127.0.0.1" if "win" in platform else "0.0.0.0"
|
26 |
+
port = 8001
|
27 |
+
app.launch(server_name=host, server_port=port)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
requirements.txt
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
gradio==4.17.0
|
2 |
-
pydantic~=
|
3 |
numpy~=1.22.4
|
|
|
1 |
gradio==4.17.0
|
2 |
+
pydantic~=2.6.1
|
3 |
numpy~=1.22.4
|
src/ui/css/demo.css
ADDED
@@ -0,0 +1,211 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#button {background-color: #009374}
|
2 |
+
#accordion {color: #0066b1}
|
3 |
+
#examples {color: #000000}
|
4 |
+
footer{display:none !important}
|
5 |
+
|
6 |
+
|
7 |
+
.dark {
|
8 |
+
--fhg-green: #009374;
|
9 |
+
--fhg-green-light: rgba(0, 147, 116, 0.77);
|
10 |
+
--primary-50: #fafafa;
|
11 |
+
--primary-100: #f5f5f5;
|
12 |
+
--primary-200: #e5e5e5;
|
13 |
+
--primary-300: #d4d4d4;
|
14 |
+
--primary-400: #a3a3a3;
|
15 |
+
--primary-500: #737373;
|
16 |
+
--primary-600: #525252;
|
17 |
+
--primary-700: #404040;
|
18 |
+
--primary-800: #262626;
|
19 |
+
--primary-900: #171717;
|
20 |
+
--primary-950: #0f0f0f;
|
21 |
+
--secondary-50: #fafafa;
|
22 |
+
--secondary-100: #f5f5f5;
|
23 |
+
--secondary-200: #e5e5e5;
|
24 |
+
--secondary-300: #d4d4d4;
|
25 |
+
--secondary-400: #a3a3a3;
|
26 |
+
--secondary-500: #737373;
|
27 |
+
--secondary-600: #525252;
|
28 |
+
--secondary-700: #404040;
|
29 |
+
--secondary-800: #262626;
|
30 |
+
--secondary-900: #171717;
|
31 |
+
--secondary-950: #0f0f0f;
|
32 |
+
--neutral-50: #fafafa;
|
33 |
+
--neutral-100: #f5f5f5;
|
34 |
+
--neutral-200: #e5e5e5;
|
35 |
+
--neutral-300: #d4d4d4;
|
36 |
+
--neutral-400: #a3a3a3;
|
37 |
+
--neutral-500: #737373;
|
38 |
+
--neutral-600: #525252;
|
39 |
+
--neutral-700: #404040;
|
40 |
+
--neutral-800: #262626;
|
41 |
+
--neutral-900: #171717;
|
42 |
+
--neutral-950: #0f0f0f;
|
43 |
+
--spacing-xxs: 2px;
|
44 |
+
--spacing-xs: 4px;
|
45 |
+
--spacing-sm: 6px;
|
46 |
+
--spacing-md: 8px;
|
47 |
+
--spacing-lg: 10px;
|
48 |
+
--spacing-xl: 14px;
|
49 |
+
--spacing-xxl: 28px;
|
50 |
+
--radius-xxs: 0px;
|
51 |
+
--radius-xs: 0px;
|
52 |
+
--radius-sm: 0px;
|
53 |
+
--radius-md: 0px;
|
54 |
+
--radius-lg: 0px;
|
55 |
+
--radius-xl: 0px;
|
56 |
+
--radius-xxl: 0px;
|
57 |
+
--text-xxs: 9px;
|
58 |
+
--text-xs: 10px;
|
59 |
+
--text-sm: 12px;
|
60 |
+
--text-md: 14px;
|
61 |
+
--text-lg: 16px;
|
62 |
+
--text-xl: 22px;
|
63 |
+
--text-xxl: 26px;
|
64 |
+
--font: 'Quicksand', 'ui-sans-serif', 'system-ui', sans-serif;
|
65 |
+
--font-mono: 'IBM Plex Mono', 'ui-monospace', 'Consolas', monospace;
|
66 |
+
--body-background-fill: var(--background-fill-primary);
|
67 |
+
--body-text-color: var(--neutral-900);
|
68 |
+
--body-text-size: var(--text-md);
|
69 |
+
--body-text-weight: 400;
|
70 |
+
--embed-radius: var(--radius-lg);
|
71 |
+
--color-accent: var(--primary-500);
|
72 |
+
--color-accent-soft: var(--primary-50);
|
73 |
+
--background-fill-primary: white;
|
74 |
+
--background-fill-secondary: var(--neutral-50);
|
75 |
+
--border-color-accent: var(--primary-300);
|
76 |
+
--border-color-primary: var(--neutral-200);
|
77 |
+
--link-text-color: var(--secondary-600);
|
78 |
+
--link-text-color-active: var(--secondary-600);
|
79 |
+
--link-text-color-hover: var(--secondary-700);
|
80 |
+
--link-text-color-visited: var(--secondary-500);
|
81 |
+
--body-text-color-subdued: var(--neutral-700);
|
82 |
+
--shadow-drop: rgba(0,0,0,0.05) 0px 1px 2px 0px;
|
83 |
+
--shadow-drop-lg: 0 1px 4px 0 rgb(0 0 0 / 0.1);
|
84 |
+
--shadow-inset: rgba(0,0,0,0.05) 0px 2px 4px 0px inset;
|
85 |
+
--shadow-spread: 3px;
|
86 |
+
--block-background-fill: var(--background-fill-primary);
|
87 |
+
--block-border-color: var(--border-color-primary);
|
88 |
+
--block-border-width: 0px;
|
89 |
+
--block-info-text-color: var(--body-text-color-subdued);
|
90 |
+
--block-info-text-size: var(--text-sm);
|
91 |
+
--block-info-text-weight: 400;
|
92 |
+
--block-label-background-fill: var(--background-fill-primary);
|
93 |
+
--block-label-border-color: var(--border-color-primary);
|
94 |
+
--block-label-border-width: 1px;
|
95 |
+
--block-label-shadow: var(--block-shadow);
|
96 |
+
--block-label-text-color: var(--body-text-color);
|
97 |
+
--block-label-margin: 0;
|
98 |
+
--block-label-padding: var(--spacing-sm) var(--spacing-lg);
|
99 |
+
--block-label-radius: calc(var(--radius-lg) - 1px) 0 calc(var(--radius-lg) - 1px) 0;
|
100 |
+
--block-label-right-radius: 0 calc(var(--radius-lg) - 1px) 0 calc(var(--radius-lg) - 1px);
|
101 |
+
--block-label-text-size: var(--text-md);
|
102 |
+
--block-label-text-weight: 600;
|
103 |
+
--block-padding: var(--spacing-xl) calc(var(--spacing-xl) + 2px);
|
104 |
+
--block-radius: var(--radius-lg);
|
105 |
+
--block-shadow: var(--shadow-drop-lg);
|
106 |
+
--block-title-background-fill: none;
|
107 |
+
--block-title-border-color: none;
|
108 |
+
--block-title-border-width: 0px;
|
109 |
+
--block-title-text-color: var(--body-text-color);
|
110 |
+
--block-title-padding: 0;
|
111 |
+
--block-title-radius: none;
|
112 |
+
--block-title-text-size: var(--text-md);
|
113 |
+
--block-title-text-weight: 600;
|
114 |
+
--container-radius: var(--radius-lg);
|
115 |
+
--form-gap-width: 0px;
|
116 |
+
--layout-gap: var(--spacing-xxl);
|
117 |
+
--panel-background-fill: var(--background-fill-secondary);
|
118 |
+
--panel-border-color: var(--border-color-primary);
|
119 |
+
--panel-border-width: 0;
|
120 |
+
--section-header-text-size: var(--text-md);
|
121 |
+
--section-header-text-weight: 400;
|
122 |
+
--border-color-accent-subdued: var(--border-color-accent);
|
123 |
+
--chatbot-code-background-color: var(--neutral-100);
|
124 |
+
--checkbox-background-color: var(--background-fill-primary);
|
125 |
+
--checkbox-background-color-focus: var(--checkbox-background-color);
|
126 |
+
--checkbox-background-color-hover: var(--checkbox-background-color);
|
127 |
+
--checkbox-background-color-selected: var(--neutral-600);
|
128 |
+
--checkbox-border-color: var(--neutral-300);
|
129 |
+
--checkbox-border-color-focus: var(--secondary-500);
|
130 |
+
--checkbox-border-color-hover: var(--neutral-300);
|
131 |
+
--checkbox-border-color-selected: var(--secondary-600);
|
132 |
+
--checkbox-border-radius: var(--radius-sm);
|
133 |
+
--checkbox-border-width: var(--input-border-width);
|
134 |
+
--checkbox-label-background-fill: var(--button-primary-background-fill);
|
135 |
+
--checkbox-label-background-fill-hover: var(--button-primary-background-fill-hover);
|
136 |
+
--checkbox-label-background-fill-selected: var(--checkbox-label-background-fill);
|
137 |
+
--checkbox-label-border-color: var(--border-color-primary);
|
138 |
+
--checkbox-label-border-color-hover: var(--checkbox-label-border-color);
|
139 |
+
--checkbox-label-border-width: var(--input-border-width);
|
140 |
+
--checkbox-label-gap: var(--spacing-lg);
|
141 |
+
--checkbox-label-padding: var(--spacing-md);
|
142 |
+
--checkbox-label-shadow: none;
|
143 |
+
--checkbox-label-text-size: var(--text-md);
|
144 |
+
--checkbox-label-text-weight: 400;
|
145 |
+
--checkbox-check: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
|
146 |
+
--radio-circle: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e");
|
147 |
+
--checkbox-shadow: var(--input-shadow);
|
148 |
+
--checkbox-label-text-color: var(--button-primary-text-color);
|
149 |
+
--checkbox-label-text-color-selected: var(--checkbox-label-text-color);
|
150 |
+
--error-background-fill: #fef2f2;
|
151 |
+
--error-border-color: #b91c1c;
|
152 |
+
--error-border-width: 1px;
|
153 |
+
--error-text-color: #b91c1c;
|
154 |
+
--error-icon-color: #b91c1c;
|
155 |
+
--input-background-fill: var(--neutral-100);
|
156 |
+
--input-background-fill-focus: var(--secondary-500);
|
157 |
+
--input-background-fill-hover: var(--input-background-fill);
|
158 |
+
--input-border-color: var(--border-color-primary);
|
159 |
+
--input-border-color-focus: var(--secondary-300);
|
160 |
+
--input-border-color-hover: var(--input-border-color);
|
161 |
+
--input-border-width: 0px;
|
162 |
+
--input-padding: var(--spacing-xl);
|
163 |
+
--input-placeholder-color: var(--neutral-400);
|
164 |
+
--input-radius: var(--radius-lg);
|
165 |
+
--input-shadow: none;
|
166 |
+
--input-shadow-focus: var(--input-shadow);
|
167 |
+
--input-text-size: var(--text-md);
|
168 |
+
--input-text-weight: 400;
|
169 |
+
--loader-color: var(--color-accent);
|
170 |
+
--prose-text-size: var(--text-md);
|
171 |
+
--prose-text-weight: 400;
|
172 |
+
--prose-header-text-weight: 600;
|
173 |
+
--slider-color: var(--neutral-900);
|
174 |
+
--stat-background-fill: var(--primary-300);
|
175 |
+
--table-border-color: var(--neutral-300);
|
176 |
+
--table-even-background-fill: white;
|
177 |
+
--table-odd-background-fill: var(--neutral-50);
|
178 |
+
--table-radius: var(--radius-lg);
|
179 |
+
--table-row-focus: var(--color-accent-soft);
|
180 |
+
--button-border-width: var(--input-border-width);
|
181 |
+
--button-cancel-background-fill: var(--button-primary-background-fill);
|
182 |
+
--button-cancel-background-fill-hover: var(--button-primary-background-fill-hover);
|
183 |
+
--button-cancel-border-color: var(--button-secondary-border-color);
|
184 |
+
--button-cancel-border-color-hover: var(--button-cancel-border-color);
|
185 |
+
--button-cancel-text-color: var(--button-primary-text-color);
|
186 |
+
--button-cancel-text-color-hover: var(--button-cancel-text-color);
|
187 |
+
--button-large-padding: var(--spacing-lg);
|
188 |
+
--button-large-radius: var(--radius-lg);
|
189 |
+
--button-large-text-size: var(--text-lg);
|
190 |
+
--button-large-text-weight: 600;
|
191 |
+
--button-primary-background-fill: #028a6e;
|
192 |
+
--button-primary-background-fill-hover: rgba(0, 147, 116, 0.77);
|
193 |
+
--button-primary-border-color: var(--primary-200);
|
194 |
+
--button-primary-border-color-hover: var(--button-primary-border-color);
|
195 |
+
--button-primary-text-color: white;
|
196 |
+
--button-primary-text-color-hover: var(--button-primary-text-color);
|
197 |
+
--button-secondary-background-fill: var(--button-primary-background-fill);
|
198 |
+
--button-secondary-background-fill-hover: var(--button-primary-background-fill-hover);
|
199 |
+
--button-secondary-border-color: var(--neutral-200);
|
200 |
+
--button-secondary-border-color-hover: var(--button-secondary-border-color);
|
201 |
+
--button-secondary-text-color: var(--button-primary-text-color);
|
202 |
+
--button-secondary-text-color-hover: var(--button-secondary-text-color);
|
203 |
+
--button-shadow: none;
|
204 |
+
--button-shadow-active: none;
|
205 |
+
--button-shadow-hover: none;
|
206 |
+
--button-small-padding: var(--spacing-sm);
|
207 |
+
--button-small-radius: var(--radius-lg);
|
208 |
+
--button-small-text-size: var(--text-md);
|
209 |
+
--button-small-text-weight: 400;
|
210 |
+
--button-transition: background-color 0.2s ease;
|
211 |
+
}
|
src/ui/explainer_ui.py
ADDED
@@ -0,0 +1,240 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
from typing import List, Optional
|
3 |
+
|
4 |
+
import gradio as gr
|
5 |
+
from gradio.components import Markdown
|
6 |
+
|
7 |
+
from src.dto.dto import ExplanationGranularity, ExplanationDto
|
8 |
+
from src.utils.registry import EXPLAINERS, MODELS, PERTURBERS, COMPARATORS
|
9 |
+
from src.utils.segregate import PercentileBasedSegregator
|
10 |
+
from src.utils.visualizer import Visualizer
|
11 |
+
|
12 |
+
|
13 |
+
class MockExplainerUI:
|
14 |
+
def __init__(
|
15 |
+
self,
|
16 |
+
logo_path: str,
|
17 |
+
css_path: str,
|
18 |
+
visualizer: Visualizer,
|
19 |
+
window_title: str,
|
20 |
+
title: str,
|
21 |
+
examples: Optional[List[str]] = None,
|
22 |
+
):
|
23 |
+
self.__logo_path = logo_path
|
24 |
+
self.__css_path = css_path
|
25 |
+
self.__examples = examples
|
26 |
+
self.__window_title = window_title
|
27 |
+
self.__title = title
|
28 |
+
self.__visualizer = visualizer
|
29 |
+
|
30 |
+
self.app: gr.Blocks = self.build_app()
|
31 |
+
|
32 |
+
def build_app(self):
|
33 |
+
with gr.Blocks(
|
34 |
+
theme=gr.themes.Monochrome().set(
|
35 |
+
button_primary_background_fill="#009374",
|
36 |
+
button_primary_background_fill_hover="#009374C4",
|
37 |
+
checkbox_label_background_fill_selected="#028A6EFF",
|
38 |
+
),
|
39 |
+
css=self.__css_path,
|
40 |
+
title=self.__window_title,
|
41 |
+
) as demo:
|
42 |
+
self.__build_app_title()
|
43 |
+
(
|
44 |
+
user_input,
|
45 |
+
system_response,
|
46 |
+
granularity,
|
47 |
+
upper_percentile,
|
48 |
+
middle_percentile,
|
49 |
+
lower_percentile,
|
50 |
+
explainer_name,
|
51 |
+
model_name,
|
52 |
+
perturber_name,
|
53 |
+
comparator_name,
|
54 |
+
generator_vis,
|
55 |
+
submit_btn,
|
56 |
+
) = self.__build_chat_and_explain()
|
57 |
+
|
58 |
+
submit_btn.click(
|
59 |
+
fn=self.run,
|
60 |
+
inputs=[
|
61 |
+
user_input,
|
62 |
+
granularity,
|
63 |
+
upper_percentile,
|
64 |
+
middle_percentile,
|
65 |
+
lower_percentile,
|
66 |
+
explainer_name,
|
67 |
+
model_name,
|
68 |
+
perturber_name,
|
69 |
+
comparator_name,
|
70 |
+
],
|
71 |
+
outputs=[system_response, generator_vis],
|
72 |
+
)
|
73 |
+
|
74 |
+
return demo
|
75 |
+
|
76 |
+
def run(
|
77 |
+
self,
|
78 |
+
user_input: str,
|
79 |
+
granularity: ExplanationGranularity,
|
80 |
+
upper_percentile: str,
|
81 |
+
middle_percentile: str,
|
82 |
+
lower_percentile: str,
|
83 |
+
explainer_name: str,
|
84 |
+
model_name: str,
|
85 |
+
perturber_name: str,
|
86 |
+
comparator_name: str,
|
87 |
+
):
|
88 |
+
print(user_input)
|
89 |
+
with open(
|
90 |
+
"data/en_q_001.json",
|
91 |
+
"r",
|
92 |
+
) as f:
|
93 |
+
data = json.load(f)
|
94 |
+
data = data[0]
|
95 |
+
explanation_dto = ExplanationDto.parse_obj(data)
|
96 |
+
user_input = explanation_dto.input_text
|
97 |
+
|
98 |
+
system_response = explanation_dto.output_text
|
99 |
+
generator_vis = self.__visualize_explanations(
|
100 |
+
user_input=user_input,
|
101 |
+
system_response=system_response,
|
102 |
+
generator_explanations=explanation_dto,
|
103 |
+
upper_percentile=int(upper_percentile),
|
104 |
+
middle_percentile=int(middle_percentile),
|
105 |
+
lower_percentile=int(lower_percentile),
|
106 |
+
)
|
107 |
+
return system_response, generator_vis
|
108 |
+
|
109 |
+
def __build_app_title(self):
|
110 |
+
with gr.Row():
|
111 |
+
with gr.Column(min_width=50, scale=1):
|
112 |
+
gr.Image(
|
113 |
+
value=self.__logo_path,
|
114 |
+
width=50,
|
115 |
+
height=50,
|
116 |
+
show_download_button=False,
|
117 |
+
container=False,
|
118 |
+
)
|
119 |
+
with gr.Column(scale=2):
|
120 |
+
Markdown(
|
121 |
+
f'<p style="text-align: left; font-size:200%; font-weight: bold"'
|
122 |
+
f">{self.__title}"
|
123 |
+
f"</p>"
|
124 |
+
)
|
125 |
+
|
126 |
+
def __build_chat_and_explain(self):
|
127 |
+
with gr.Row():
|
128 |
+
with gr.Column(scale=2):
|
129 |
+
gr.Textbox(
|
130 |
+
label="Attention!",
|
131 |
+
value="This is a demo version of the tool! For running the full version, please follow the instructions in ...",
|
132 |
+
container=False,
|
133 |
+
interactive=False,
|
134 |
+
)
|
135 |
+
|
136 |
+
with gr.Row():
|
137 |
+
with gr.Column(scale=2):
|
138 |
+
user_input = gr.Radio(
|
139 |
+
# placeholder="Type your question here and press Enter.",
|
140 |
+
label="Question",
|
141 |
+
container=True,
|
142 |
+
choices=["Question 1 EN", "Question 1 DE"],
|
143 |
+
)
|
144 |
+
with gr.Column(scale=1):
|
145 |
+
granularity = gr.Radio(
|
146 |
+
choices=[e for e in ExplanationGranularity],
|
147 |
+
value=ExplanationGranularity.SENTENCE_LEVEL,
|
148 |
+
label="Explanation Granularity",
|
149 |
+
)
|
150 |
+
|
151 |
+
with gr.Accordion(label="Settings", open=False, elem_id="accordion"):
|
152 |
+
with gr.Row(variant="compact"):
|
153 |
+
explainer_name = gr.Radio(
|
154 |
+
label="Explainer",
|
155 |
+
choices=list(EXPLAINERS.keys()),
|
156 |
+
value=list(EXPLAINERS.keys())[0],
|
157 |
+
container=True,
|
158 |
+
)
|
159 |
+
with gr.Row(variant="compact"):
|
160 |
+
upper_percentile = gr.Textbox(label="Upper", value="85", container=True)
|
161 |
+
middle_percentile = gr.Textbox(
|
162 |
+
label="Middle", value="75", container=True
|
163 |
+
)
|
164 |
+
lower_percentile = gr.Textbox(label="Lower", value="10", container=True)
|
165 |
+
|
166 |
+
with gr.Row(variant="compact"):
|
167 |
+
model_name = gr.Radio(
|
168 |
+
label="Model",
|
169 |
+
choices=list(MODELS.keys()),
|
170 |
+
value=list(MODELS.keys())[0],
|
171 |
+
container=True,
|
172 |
+
)
|
173 |
+
with gr.Row(variant="compact"):
|
174 |
+
perturber_name = gr.Radio(
|
175 |
+
label="Perturber",
|
176 |
+
choices=list(PERTURBERS.keys()),
|
177 |
+
value=list(PERTURBERS.keys())[0],
|
178 |
+
container=True,
|
179 |
+
)
|
180 |
+
with gr.Row(variant="compact"):
|
181 |
+
comparator_name = gr.Radio(
|
182 |
+
label="Comparator",
|
183 |
+
choices=list(COMPARATORS.keys()),
|
184 |
+
value=list(COMPARATORS.keys())[0],
|
185 |
+
container=True,
|
186 |
+
)
|
187 |
+
with gr.Row(variant="compact"):
|
188 |
+
# passing "elem_id" to use a custom style for the component
|
189 |
+
# in the CSS passed.
|
190 |
+
submit_btn = gr.Button(
|
191 |
+
value="🛠 Submit",
|
192 |
+
variant="secondary",
|
193 |
+
elem_id="button",
|
194 |
+
interactive=True,
|
195 |
+
)
|
196 |
+
|
197 |
+
with gr.Row():
|
198 |
+
generator_vis = gr.HTML(label="Explanations")
|
199 |
+
|
200 |
+
with gr.Row():
|
201 |
+
system_response = gr.Textbox(
|
202 |
+
label="System Response",
|
203 |
+
container=True,
|
204 |
+
interactive=False,
|
205 |
+
)
|
206 |
+
|
207 |
+
return (
|
208 |
+
user_input,
|
209 |
+
system_response,
|
210 |
+
granularity,
|
211 |
+
upper_percentile,
|
212 |
+
middle_percentile,
|
213 |
+
lower_percentile,
|
214 |
+
explainer_name,
|
215 |
+
model_name,
|
216 |
+
perturber_name,
|
217 |
+
comparator_name,
|
218 |
+
generator_vis,
|
219 |
+
submit_btn,
|
220 |
+
)
|
221 |
+
|
222 |
+
def __visualize_explanations(
|
223 |
+
self,
|
224 |
+
user_input: str,
|
225 |
+
system_response: Optional[str],
|
226 |
+
generator_explanations: ExplanationDto,
|
227 |
+
upper_percentile: Optional[int],
|
228 |
+
middle_percentile: Optional[int],
|
229 |
+
lower_percentile: Optional[int],
|
230 |
+
) -> str:
|
231 |
+
segregator = PercentileBasedSegregator(
|
232 |
+
upper_bound_percentile=upper_percentile,
|
233 |
+
middle_bound_percentile=middle_percentile,
|
234 |
+
lower_bound_percentile=lower_percentile,
|
235 |
+
)
|
236 |
+
return self.__visualizer.visualize(
|
237 |
+
segregator=segregator,
|
238 |
+
explanations=generator_explanations,
|
239 |
+
output_from_explanations=user_input,
|
240 |
+
)
|
src/ui/images/iais.svg
ADDED
|
src/utils/visualizer.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
-
from
|
2 |
-
from
|
3 |
|
4 |
|
5 |
UPPER_COLOR = "#D4EFDF" # green
|
|
|
1 |
+
from src.utils.segregate import Segregator
|
2 |
+
from src.dto.dto import ExplanationDto
|
3 |
|
4 |
|
5 |
UPPER_COLOR = "#D4EFDF" # green
|