psaiops 0.0.14__py3-none-any.whl → 0.0.16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of psaiops might be problematic. Click here for more details.
psaiops/score/attention/app.py
CHANGED
|
@@ -121,57 +121,77 @@ def create_layout(intro: str=INTRO) -> dict:
|
|
|
121
121
|
def update_layer_range(value: float, model: str) -> dict:
|
|
122
122
|
return gradio.update(maximum=35, value=min(35, int(value))) if '120b' in model else gradio.update(maximum=23, value=min(23, int(value)))
|
|
123
123
|
|
|
124
|
-
def update_position_range(value: float, tokens:
|
|
125
|
-
return gradio.update(maximum=
|
|
124
|
+
def update_position_range(value: float, tokens: float) -> dict:
|
|
125
|
+
return gradio.update(maximum=int(tokens) - 1, value=min(int(tokens) - 1, int(value)))
|
|
126
126
|
|
|
127
127
|
def update_computation_state(
|
|
128
128
|
token_num: float,
|
|
129
129
|
topk_num: float,
|
|
130
130
|
topp_num: float,
|
|
131
|
+
token_idx: float,
|
|
132
|
+
layer_idx: float,
|
|
133
|
+
head_idx: float,
|
|
131
134
|
prompt_str: str,
|
|
132
135
|
device_str: str,
|
|
133
136
|
model_obj: object,
|
|
134
137
|
tokenizer_obj: object,
|
|
135
138
|
) -> tuple:
|
|
136
139
|
# sanitize the inputs
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
__token_num = max(1, min(128, int(token_num)))
|
|
141
|
+
__topk_num = max(1, min(8, int(topk_num)))
|
|
142
|
+
__topp_num = max(0.0, min(1.0, float(topp_num)))
|
|
143
|
+
__token_idx = max(-1, min(__token_num, int(token_idx)))
|
|
144
|
+
__layer_idx = max(-1, int(layer_idx))
|
|
145
|
+
__head_idx = max(-1, int(head_idx))
|
|
146
|
+
__prompt_str = prompt_str.strip()
|
|
147
|
+
__device_str = device_str if (device_str in ['cpu', 'cuda']) else 'cpu'
|
|
148
|
+
# exit if some values are missing
|
|
149
|
+
if (not __prompt_str) or (model_obj is None) or (tokenizer_obj is None):
|
|
150
|
+
return ([], [], [], torch.empty(0))
|
|
142
151
|
# handle all exceptions at once
|
|
143
152
|
try:
|
|
144
153
|
# dictionary {'input_ids': _, 'attention_mask': _}
|
|
145
|
-
|
|
154
|
+
__input_data = psaiops.score.attention.lib.preprocess_token_ids(
|
|
146
155
|
tokenizer_obj=tokenizer_obj,
|
|
147
|
-
prompt_str=
|
|
148
|
-
device_str=
|
|
156
|
+
prompt_str=__prompt_str,
|
|
157
|
+
device_str=__device_str)
|
|
149
158
|
# parse the inputs
|
|
150
|
-
__input_dim = int(
|
|
159
|
+
__input_dim = int(__input_data['input_ids'].shape[-1])
|
|
151
160
|
# tensor (1, T)
|
|
152
|
-
|
|
161
|
+
__output_data = psaiops.score.attention.lib.generate_token_ids(
|
|
153
162
|
model_obj=model_obj,
|
|
154
|
-
input_args=
|
|
155
|
-
token_num=
|
|
156
|
-
topk_num=
|
|
157
|
-
topp_num=
|
|
163
|
+
input_args=__input_data,
|
|
164
|
+
token_num=__token_num,
|
|
165
|
+
topk_num=__topk_num,
|
|
166
|
+
topp_num=__topp_num)
|
|
158
167
|
# tensor (L, S, H, T, T)
|
|
159
|
-
|
|
168
|
+
__attention_data = psaiops.score.attention.lib.compute_attention_weights(
|
|
160
169
|
model_obj=model_obj,
|
|
161
|
-
token_obj=
|
|
170
|
+
token_obj=__output_data)
|
|
171
|
+
# reduce the layer, sample, head and output token axes => tensor (T,)
|
|
172
|
+
__score_data = psaiops.score.attention.lib.reduce_attention_weights(
|
|
173
|
+
attention_data=__attention_data,
|
|
174
|
+
token_idx=__token_idx,
|
|
175
|
+
layer_idx=__layer_idx,
|
|
176
|
+
head_idx=__head_idx,
|
|
177
|
+
input_dim=__input_dim)
|
|
178
|
+
# translate the scores into integer labels
|
|
179
|
+
__labels = psaiops.score.attention.lib.postprocess_attention_scores(
|
|
180
|
+
attention_data=__score_data,
|
|
181
|
+
input_dim=__input_dim,
|
|
182
|
+
token_idx=__token_idx)
|
|
162
183
|
# detokenize the IDs
|
|
163
184
|
__tokens = psaiops.score.attention.lib.postprocess_token_ids(
|
|
164
185
|
tokenizer_obj=tokenizer_obj,
|
|
165
|
-
token_obj=
|
|
166
|
-
# update each component => (input, output, attention) states
|
|
186
|
+
token_obj=__output_data)
|
|
187
|
+
# update each component => (input, output, attention, highligh) states
|
|
167
188
|
return (
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
189
|
+
list(zip(__tokens, __labels)),
|
|
190
|
+
__tokens[:__input_dim],
|
|
191
|
+
__tokens[__input_dim:],
|
|
192
|
+
__attention_data,)
|
|
171
193
|
except:
|
|
172
194
|
raise Exception('Attention generation aborted with an error.')
|
|
173
|
-
finally:
|
|
174
|
-
return (gradio.update(), gradio.update(), gradio.update())
|
|
175
195
|
|
|
176
196
|
def update_text_highlight(
|
|
177
197
|
token_idx: float,
|
|
@@ -180,15 +200,16 @@ def update_text_highlight(
|
|
|
180
200
|
input_data: list,
|
|
181
201
|
output_data: list,
|
|
182
202
|
attention_data: torch.Tensor,
|
|
183
|
-
) ->
|
|
203
|
+
) -> list:
|
|
184
204
|
# sanitize the inputs
|
|
185
205
|
__input_data = input_data or []
|
|
186
206
|
__output_data = output_data or []
|
|
187
|
-
__attention_data =
|
|
207
|
+
__attention_data = torch.empty(0) if (attention_data is None) else attention_data
|
|
188
208
|
__input_dim = len(__input_data)
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
209
|
+
__output_dim = len(__output_data)
|
|
210
|
+
__token_idx = max(-1, min(__output_dim, int(token_idx)))
|
|
211
|
+
__layer_idx = max(-1, int(layer_idx))
|
|
212
|
+
__head_idx = max(-1, int(head_idx))
|
|
192
213
|
# exit if the data has not yet been computed
|
|
193
214
|
if (not __input_data) or (not __output_data) or (attention_data is None) or (len(attention_data) == 0):
|
|
194
215
|
return gradio.update()
|
|
@@ -209,11 +230,9 @@ def update_text_highlight(
|
|
|
209
230
|
input_dim=__input_dim,
|
|
210
231
|
token_idx=__token_idx)
|
|
211
232
|
# update the component with [(token, label), ...]
|
|
212
|
-
return
|
|
233
|
+
return list(zip(__tokens, __labels))
|
|
213
234
|
except:
|
|
214
235
|
raise Exception('Attention reduction aborted with an error.')
|
|
215
|
-
finally:
|
|
216
|
-
return gradio.update()
|
|
217
236
|
|
|
218
237
|
# APP ##########################################################################
|
|
219
238
|
|
|
@@ -230,32 +249,23 @@ def create_app(title: str=TITLE, intro: str=INTRO, style: str=STYLE, model: str=
|
|
|
230
249
|
__fields.update(create_layout(intro=intro))
|
|
231
250
|
# init the state
|
|
232
251
|
__fields.update(create_state())
|
|
233
|
-
# fetch the relevant fields
|
|
234
|
-
__button_block, __position_block, __output_block = (__fields['process_block'], __fields['position_block'], __fields['output_block'])
|
|
235
|
-
__output_state, __attention_state = (__fields['output_state'], __fields['attention_state'])
|
|
236
252
|
# wire the input fields
|
|
237
|
-
|
|
253
|
+
__fields['process_block'].click(
|
|
238
254
|
fn=__compute,
|
|
239
|
-
inputs=[__fields[__k] for __k in ['tokens_block', 'topk_block', 'topp_block', 'input_block']],
|
|
240
|
-
outputs=[__fields[__k] for __k in ['input_state', 'output_state', 'attention_state']],
|
|
255
|
+
inputs=[__fields[__k] for __k in ['tokens_block', 'topk_block', 'topp_block', 'position_block', 'layer_block', 'head_block', 'input_block']],
|
|
256
|
+
outputs=[__fields[__k] for __k in ['output_block', 'input_state', 'output_state', 'attention_state']],
|
|
241
257
|
queue=False,
|
|
242
258
|
show_progress='full')
|
|
243
|
-
|
|
259
|
+
__fields['tokens_block'].change(
|
|
244
260
|
fn=update_position_range,
|
|
245
|
-
inputs=[
|
|
246
|
-
outputs=
|
|
247
|
-
queue=False,
|
|
248
|
-
show_progress='hidden')
|
|
249
|
-
__attention_state.change(
|
|
250
|
-
fn=update_text_highlight,
|
|
251
|
-
inputs=[__fields[__k] for __k in ['position_block', 'layer_block', 'head_block', 'input_state', 'output_state', 'attention_state']],
|
|
252
|
-
outputs=__output_block,
|
|
261
|
+
inputs=[__fields[__k] for __k in ['position_block', 'tokens_block']],
|
|
262
|
+
outputs=__fields['position_block'],
|
|
253
263
|
queue=False,
|
|
254
264
|
show_progress='hidden')
|
|
255
|
-
|
|
265
|
+
__fields['position_block'].change(
|
|
256
266
|
fn=update_text_highlight,
|
|
257
267
|
inputs=[__fields[__k] for __k in ['position_block', 'layer_block', 'head_block', 'input_state', 'output_state', 'attention_state']],
|
|
258
|
-
outputs=
|
|
268
|
+
outputs=__fields['output_block'],
|
|
259
269
|
queue=False,
|
|
260
270
|
show_progress='hidden')
|
|
261
271
|
# gradio application
|
psaiops/score/attention/lib.py
CHANGED
|
@@ -119,7 +119,7 @@ def postprocess_attention_scores(
|
|
|
119
119
|
__output_range = list(range(__output_dim - input_dim)) if (__token_idx < 0) else [__token_idx]
|
|
120
120
|
__output_mask = torch.BoolTensor([__i in __output_range for __i in range(__output_dim - input_dim)])
|
|
121
121
|
# normalize the scores
|
|
122
|
-
__input_scores = attention_data[__input_slice] / (attention_data[__input_slice].
|
|
122
|
+
__input_scores = attention_data[__input_slice] / (attention_data[__input_slice].mean() + 1e-5)
|
|
123
123
|
# round to obtain integer labels from 0 to 100
|
|
124
124
|
__input_scores = torch.round(100.0 * __input_scores, decimals=0).type(torch.int32)
|
|
125
125
|
# the generated tokens are not scored
|
|
@@ -7,9 +7,9 @@ psaiops/elements/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
|
|
|
7
7
|
psaiops/elements/data.py,sha256=vGYeMN11uP9gs8rV6aSDffE_TeIX5PmdzWGwUpdGE2Y,906
|
|
8
8
|
psaiops/score/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
psaiops/score/attention/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
psaiops/score/attention/app.py,sha256=
|
|
11
|
-
psaiops/score/attention/lib.py,sha256=
|
|
10
|
+
psaiops/score/attention/app.py,sha256=nmjYjbLJG5icbOLm3WTk91H-3GBQcj_8KE4DNIEIhN8,12446
|
|
11
|
+
psaiops/score/attention/lib.py,sha256=vyJrp6BK2LvKfmq4JkkmvlsqE4_OcIeBmlq_YMq9jN4,6929
|
|
12
12
|
psaiops/steer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
psaiops-0.0.
|
|
14
|
-
psaiops-0.0.
|
|
15
|
-
psaiops-0.0.
|
|
13
|
+
psaiops-0.0.16.dist-info/METADATA,sha256=b91j3iHFy9G3sVCOkQo8B7xhnSBlkyw8i2G0ed6wy9s,1222
|
|
14
|
+
psaiops-0.0.16.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
15
|
+
psaiops-0.0.16.dist-info/RECORD,,
|
|
File without changes
|