psaiops 0.1.0__py3-none-any.whl → 0.2.0__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/common/dropdown.py +19 -0
- psaiops/compose/contrast/app.py +178 -0
- psaiops/compose/contrast/lib.py +175 -0
- psaiops/reverse/__init__.py +0 -0
- psaiops/score/attention/app.py +3 -3
- {psaiops-0.1.0.dist-info → psaiops-0.2.0.dist-info}/METADATA +4 -1
- psaiops-0.2.0.dist-info/RECORD +19 -0
- {psaiops-0.1.0.dist-info → psaiops-0.2.0.dist-info}/WHEEL +1 -1
- psaiops-0.1.0.dist-info/RECORD +0 -15
- /psaiops/{elements → common}/__init__.py +0 -0
- /psaiops/{elements → common}/data.py +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import gradio
|
|
2
|
+
|
|
3
|
+
import psaiops.elements.data
|
|
4
|
+
|
|
5
|
+
# AUTO-COMPLETE ################################################################
|
|
6
|
+
|
|
7
|
+
def update_dropdown(label: str, data: gradio.KeyUpData):
|
|
8
|
+
# model_dropdown.key_up(fn=update_dropdown, inputs=[model_dropdown, gradio.State("model")], outputs=model_dropdown, queue=False, show_progress="hidden")
|
|
9
|
+
datasets = psaiops.elements.data.query_huggingface(target=data.input_value, label=label, limit=16)
|
|
10
|
+
return gradio.update(choices=datasets, visible=True)
|
|
11
|
+
|
|
12
|
+
# with gradio.Blocks() as demo:
|
|
13
|
+
# model_dropdown = gradio.Dropdown(label="Models Auto-Complete", choices=[""], allow_custom_value=True)
|
|
14
|
+
# dataset_dropdown = gradio.Dropdown(label="Datasets Auto-Complete", choices=[""], allow_custom_value=True)
|
|
15
|
+
# spaces_dropdown = gradio.Dropdown(label="Spaces Auto-Complete", choices=[""], allow_custom_value=True)
|
|
16
|
+
# model_dropdown.key_up(fn=update_dropdown, inputs=[gradio.State("model")], outputs=model_dropdown, queue=False, show_progress="hidden")
|
|
17
|
+
# dataset_dropdown.key_up(fn=update_dropdown, inputs=[gradio.State("dataset")], outputs=dataset_dropdown, queue=False, show_progress="hidden")
|
|
18
|
+
# spaces_dropdown.key_up(fn=update_dropdown, inputs=[gradio.State("space")], outputs=spaces_dropdown, queue=False, show_progress="hidden")
|
|
19
|
+
# demo.launch(share=True, debug=True)
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
|
|
3
|
+
import gradio
|
|
4
|
+
import torch
|
|
5
|
+
import torch.cuda
|
|
6
|
+
|
|
7
|
+
import psaiops.compose.contrast.lib
|
|
8
|
+
|
|
9
|
+
# META #########################################################################
|
|
10
|
+
|
|
11
|
+
TITLE = '''Contrastive Steering'''
|
|
12
|
+
INTRO = '''Add a delta of activation to a prompt to steer the model output in a specific latent direction.'''
|
|
13
|
+
STYLE = '''.giga-text input { font-size: 32px; }'''
|
|
14
|
+
|
|
15
|
+
MODEL = 'openai/gpt-oss-20b'
|
|
16
|
+
|
|
17
|
+
# COLORS #######################################################################
|
|
18
|
+
|
|
19
|
+
def create_color_map() -> dict:
|
|
20
|
+
return {
|
|
21
|
+
'-1': '#004444',
|
|
22
|
+
**{str(__i): '#{:02x}0000'.format(int(2.55 * __i)) for __i in range(101)}}
|
|
23
|
+
|
|
24
|
+
# INTRO ########################################################################
|
|
25
|
+
|
|
26
|
+
def create_intro_block(intro: str) -> dict:
|
|
27
|
+
__intro = gradio.Markdown(intro)
|
|
28
|
+
return {'intro_block': __intro}
|
|
29
|
+
|
|
30
|
+
# MODEL ########################################################################
|
|
31
|
+
|
|
32
|
+
def create_model_block() -> dict:
|
|
33
|
+
__model = gradio.Dropdown(label='Model ID', value='openai/gpt-oss-20b', choices=['openai/gpt-oss-20b'], scale=1, allow_custom_value=False, multiselect=False, interactive=True) # 'openai/gpt-oss-120b'
|
|
34
|
+
__layer = gradio.Slider(label='Layer Depth', value=12, minimum=0, maximum=23, step=1, scale=1, interactive=True)
|
|
35
|
+
return {
|
|
36
|
+
'model_block': __model,
|
|
37
|
+
'layer_block': __layer,}
|
|
38
|
+
|
|
39
|
+
# SAMPLING #####################################################################
|
|
40
|
+
|
|
41
|
+
def create_sampling_block() -> dict:
|
|
42
|
+
__tokens = gradio.Slider(label='Tokens', value=16, minimum=1, maximum=128, step=1, scale=1, interactive=True)
|
|
43
|
+
__topk = gradio.Slider(label='Top K', value=4, minimum=1, maximum=8, step=1, scale=1, interactive=True)
|
|
44
|
+
__topp = gradio.Slider(label='Top P', value=0.9, minimum=0.0, maximum=1.0, step=0.1, scale=1, interactive=True)
|
|
45
|
+
return {
|
|
46
|
+
'tokens_block': __tokens,
|
|
47
|
+
'topk_block': __topk,
|
|
48
|
+
'topp_block': __topp,}
|
|
49
|
+
|
|
50
|
+
# REDUCTION ####################################################################
|
|
51
|
+
|
|
52
|
+
def create_reduction_block() -> dict:
|
|
53
|
+
__from = gradio.Slider(label='Average From', value=0, minimum=0, maximum=256, step=1, scale=1, interactive=True)
|
|
54
|
+
__to = gradio.Slider(label='Average To', value=256, minimum=0, maximum=256, step=1, scale=1, interactive=True)
|
|
55
|
+
return {
|
|
56
|
+
'from_block': __from,
|
|
57
|
+
'to_block': __to,}
|
|
58
|
+
|
|
59
|
+
# INPUTS #######################################################################
|
|
60
|
+
|
|
61
|
+
def create_inputs_row(operation: str='', index: int=0, label: bool=False) -> dict:
|
|
62
|
+
# __operation = gradio.Button(value=operation, variant='primary', size='lg', elem_classes='white-text', scale=1, interactive=False)
|
|
63
|
+
__operation = gradio.Dropdown(label=f'Operation', value=operation, choices=['', '+', '-', 'x', '.', '='], elem_classes='giga-text', scale=1, show_label=label, allow_custom_value=False, multiselect=False, interactive=False)
|
|
64
|
+
__alpha = gradio.Slider(label='Factor', value=1.0, minimum=0.0, maximum=16.0, step=0.1, scale=1, show_label=label, interactive=True)
|
|
65
|
+
__input = gradio.Textbox(label=f'Prompt', value='', placeholder='Some text.', lines=2, max_lines=2, scale=8, show_label=label, show_copy_button=True, interactive=True)
|
|
66
|
+
return {
|
|
67
|
+
f'operation_{index}_block': __operation,
|
|
68
|
+
f'factor_{index}_block': __alpha,
|
|
69
|
+
f'prompt_{index}_block': __input,}
|
|
70
|
+
|
|
71
|
+
# OUTPUTS ######################################################################
|
|
72
|
+
|
|
73
|
+
def create_outputs_block() -> dict:
|
|
74
|
+
__output = gradio.Textbox(label='= Total', value='', placeholder='Some text.', lines=2, max_lines=8, scale=1, show_label=True, show_copy_button=True, interactive=False)
|
|
75
|
+
return {'output_block': __output}
|
|
76
|
+
|
|
77
|
+
# ACTIONS ######################################################################
|
|
78
|
+
|
|
79
|
+
def create_actions_block() -> dict:
|
|
80
|
+
__process = gradio.Button(value='Process', variant='primary', size='lg', scale=1, interactive=True)
|
|
81
|
+
return {'process_block': __process,}
|
|
82
|
+
|
|
83
|
+
# TABLE ########################################################################
|
|
84
|
+
|
|
85
|
+
def create_table_block() -> dict:
|
|
86
|
+
__table = gradio.DataFrame(label='Summary', type='numpy', headers=None, row_count=4, col_count=256, scale=1, interactive=False)
|
|
87
|
+
return {'table_block': __table,}
|
|
88
|
+
|
|
89
|
+
# STATE ########################################################################
|
|
90
|
+
|
|
91
|
+
def create_state() -> dict:
|
|
92
|
+
return {}
|
|
93
|
+
|
|
94
|
+
# LAYOUT #######################################################################
|
|
95
|
+
|
|
96
|
+
def create_layout(intro: str=INTRO) -> dict:
|
|
97
|
+
__fields = {}
|
|
98
|
+
__fields.update(create_intro_block(intro=intro))
|
|
99
|
+
with gradio.Tabs():
|
|
100
|
+
with gradio.Tab('Equation') as __main_tab:
|
|
101
|
+
__fields.update({'main_tab': __main_tab})
|
|
102
|
+
with gradio.Row(equal_height=True):
|
|
103
|
+
__fields.update(create_inputs_row(operation='', index=0, label=True))
|
|
104
|
+
with gradio.Row(equal_height=True):
|
|
105
|
+
__fields.update(create_inputs_row(operation='-', index=1, label=False))
|
|
106
|
+
with gradio.Row(equal_height=True):
|
|
107
|
+
__fields.update(create_inputs_row(operation='+', index=2, label=False))
|
|
108
|
+
with gradio.Row(equal_height=True):
|
|
109
|
+
__fields.update(create_outputs_block())
|
|
110
|
+
with gradio.Row(equal_height=True):
|
|
111
|
+
__fields.update(create_actions_block())
|
|
112
|
+
with gradio.Tab('Details') as __details_tab:
|
|
113
|
+
with gradio.Row(equal_height=True):
|
|
114
|
+
__fields.update(create_table_block())
|
|
115
|
+
with gradio.Tab('Settings') as __settings_tab:
|
|
116
|
+
__fields.update({'settings_tab': __settings_tab})
|
|
117
|
+
with gradio.Column(scale=1):
|
|
118
|
+
with gradio.Row(equal_height=True):
|
|
119
|
+
__fields.update(create_model_block())
|
|
120
|
+
with gradio.Row(equal_height=True):
|
|
121
|
+
__fields.update(create_sampling_block())
|
|
122
|
+
with gradio.Row(equal_height=True):
|
|
123
|
+
__fields.update(create_reduction_block())
|
|
124
|
+
# __fields.update(create_display_block())
|
|
125
|
+
return __fields
|
|
126
|
+
|
|
127
|
+
# EVENTS #######################################################################
|
|
128
|
+
|
|
129
|
+
def update_layer_range(value: float, model: str) -> dict:
|
|
130
|
+
return gradio.update(maximum=35, value=min(35, int(value))) if '120b' in model else gradio.update(maximum=23, value=min(23, int(value)))
|
|
131
|
+
|
|
132
|
+
def update_table_data(positive: str, negative: str, prompt: str, output: str, tokenizer: object) -> list:
|
|
133
|
+
__outputs = tokenizer([positive, negative, prompt, output], padding=True)
|
|
134
|
+
return [tokenizer.convert_ids_to_tokens(__s) for __s in __outputs['input_ids']]
|
|
135
|
+
|
|
136
|
+
# APP ##########################################################################
|
|
137
|
+
|
|
138
|
+
def create_app(title: str=TITLE, intro: str=INTRO, style: str=STYLE, model: str=MODEL) -> gradio.Blocks:
|
|
139
|
+
__fields = {}
|
|
140
|
+
with gradio.Blocks(theme=gradio.themes.Soft(), title=title, css=style) as __app:
|
|
141
|
+
# load the model
|
|
142
|
+
__device = 'cuda' if torch.cuda.is_available() else 'cpu'
|
|
143
|
+
__model = psaiops.compose.contrast.lib.get_model(name=model, device=__device)
|
|
144
|
+
__tokenizer = psaiops.compose.contrast.lib.get_tokenizer(name=model, device=__device)
|
|
145
|
+
# adapt the computing functions
|
|
146
|
+
__compute = functools.partial(psaiops.compose.contrast.lib.steer_model_output, model_obj=__model, tokenizer_obj=__tokenizer, device_str=__device)
|
|
147
|
+
__format = functools.partial(update_table_data, tokenizer=__tokenizer)
|
|
148
|
+
# create the UI
|
|
149
|
+
__fields.update(create_layout(intro=intro))
|
|
150
|
+
# init the state
|
|
151
|
+
__fields.update(create_state())
|
|
152
|
+
# wire the input fields
|
|
153
|
+
__fields['model_block'].change(
|
|
154
|
+
fn=update_layer_range,
|
|
155
|
+
inputs=[__fields[__k] for __k in ['layer_block', 'model_block']],
|
|
156
|
+
outputs=__fields['layer_block'],
|
|
157
|
+
queue=False,
|
|
158
|
+
show_progress='hidden')
|
|
159
|
+
__fields['output_block'].change(
|
|
160
|
+
fn=__format,
|
|
161
|
+
inputs=[__fields[__k] for __k in ['prompt_0_block', 'prompt_1_block', 'prompt_2_block', 'output_block']],
|
|
162
|
+
outputs=__fields['table_block'],
|
|
163
|
+
queue=False,
|
|
164
|
+
show_progress='hidden')
|
|
165
|
+
__fields['process_block'].click(
|
|
166
|
+
fn=__compute,
|
|
167
|
+
inputs=[__fields[__k] for __k in ['prompt_0_block', 'prompt_1_block', 'prompt_2_block', 'factor_0_block', 'factor_1_block', 'factor_2_block', 'tokens_block', 'topk_block', 'topp_block', 'layer_block']],
|
|
168
|
+
outputs=__fields['output_block'],
|
|
169
|
+
queue=False,
|
|
170
|
+
show_progress='full')
|
|
171
|
+
# gradio application
|
|
172
|
+
return __app
|
|
173
|
+
|
|
174
|
+
# MAIN #########################################################################
|
|
175
|
+
|
|
176
|
+
if __name__ == '__main__':
|
|
177
|
+
__app = create_app()
|
|
178
|
+
__app.launch(share=True, debug=True)
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
|
|
3
|
+
import torch
|
|
4
|
+
import torch.nn
|
|
5
|
+
import torch.nn.modules
|
|
6
|
+
import transformers
|
|
7
|
+
|
|
8
|
+
import deformers.models.openai.gptoss
|
|
9
|
+
import mlable.shapes
|
|
10
|
+
|
|
11
|
+
# LOAD #########################################################################
|
|
12
|
+
|
|
13
|
+
@functools.lru_cache(maxsize=4)
|
|
14
|
+
def get_tokenizer(name: str, device: str='cpu'):
|
|
15
|
+
return transformers.AutoTokenizer.from_pretrained(
|
|
16
|
+
name,
|
|
17
|
+
use_fast=True,
|
|
18
|
+
dtype='auto',
|
|
19
|
+
device_map=device)
|
|
20
|
+
|
|
21
|
+
@functools.lru_cache(maxsize=2)
|
|
22
|
+
def get_model(name: str, device: str='cpu'):
|
|
23
|
+
__model = deformers.models.openai.gptoss.GptOssForCausalInference.from_pretrained(
|
|
24
|
+
name,
|
|
25
|
+
dtype='auto',
|
|
26
|
+
device_map=device)
|
|
27
|
+
# toggle the inference mode (not training)
|
|
28
|
+
__model.eval()
|
|
29
|
+
# transformers model
|
|
30
|
+
return __model
|
|
31
|
+
|
|
32
|
+
# PREPROCESS #####################################################################
|
|
33
|
+
|
|
34
|
+
@functools.lru_cache(maxsize=4)
|
|
35
|
+
def preprocess_token_ids(
|
|
36
|
+
tokenizer: object,
|
|
37
|
+
prompts: list,
|
|
38
|
+
device: str='cpu'
|
|
39
|
+
) -> dict:
|
|
40
|
+
# tokenize
|
|
41
|
+
__inputs = tokenizer(prompts, return_tensors='pt', padding=True)
|
|
42
|
+
# move to the main device
|
|
43
|
+
return {__k: __v.to(device) for __k, __v in __inputs.items()}
|
|
44
|
+
|
|
45
|
+
# HOOK #########################################################################
|
|
46
|
+
|
|
47
|
+
def capture_hidden_activation(
|
|
48
|
+
module: torch.nn.modules.Module,
|
|
49
|
+
inputs: torch.Tensor,
|
|
50
|
+
outputs: torch.Tensor,
|
|
51
|
+
index: int,
|
|
52
|
+
captured: dict,
|
|
53
|
+
) -> None:
|
|
54
|
+
captured[index] = outputs # (B, S, E)
|
|
55
|
+
|
|
56
|
+
# MASKS ########################################################################
|
|
57
|
+
|
|
58
|
+
def compute_sequence_mask(
|
|
59
|
+
tokens: torch.Tensor, # (B, S)
|
|
60
|
+
masks: torch.Tensor, # (B, S)
|
|
61
|
+
) -> torch.Tensor:
|
|
62
|
+
# keep the intersection of the masks
|
|
63
|
+
__masks = masks.prod(dim=0, keepdim=False)
|
|
64
|
+
# and only the positions that differ between positive and negative prompts
|
|
65
|
+
return __masks * (tokens[0] != tokens[1])
|
|
66
|
+
|
|
67
|
+
# REDUCTION ####################################################################
|
|
68
|
+
|
|
69
|
+
def compute_delta_activation(
|
|
70
|
+
data: torch.Tensor, # (B, S, E)
|
|
71
|
+
masks: torch.Tensor, # (S,)
|
|
72
|
+
signs: torch.Tensor, # (B,)
|
|
73
|
+
keepdim: bool=True,
|
|
74
|
+
) -> torch.Tensor:
|
|
75
|
+
__dtype = data.dtype
|
|
76
|
+
__device = data.device
|
|
77
|
+
# sign each sample along the batch axis
|
|
78
|
+
__shape = tuple(mlable.shapes.filter(data.shape, axes=[0]))
|
|
79
|
+
__signs = signs.to(dtype=__dtype, device=__device).view(__shape)
|
|
80
|
+
# combine along the batch axis to keep the shortest mask on the sequence axis
|
|
81
|
+
__shape = tuple(mlable.shapes.filter(data.shape, axes=[1]))
|
|
82
|
+
__masks = masks.to(dtype=__dtype, device=__device).view(__shape)
|
|
83
|
+
# mean factor: half the signs size along the batch axis and the number of positions kept along the sequence axis
|
|
84
|
+
__factor = (0.5 * float(len(__signs)) * __masks.sum()).clamp(min=1e-8)
|
|
85
|
+
# take the difference along the batch axis and the average along the sequence axis
|
|
86
|
+
return (data * __signs * __masks).sum(dim=[0, 1], keepdim=keepdim) / __factor
|
|
87
|
+
|
|
88
|
+
# DELTA ########################################################################
|
|
89
|
+
|
|
90
|
+
def add_delta_activation(
|
|
91
|
+
module: torch.nn.modules.Module,
|
|
92
|
+
inputs: torch.Tensor,
|
|
93
|
+
outputs: torch.Tensor,
|
|
94
|
+
delta: torch.Tensor,
|
|
95
|
+
alpha: torch.Tensor,
|
|
96
|
+
beta: torch.Tensor,
|
|
97
|
+
) -> torch.Tensor:
|
|
98
|
+
# expand the single feature axis of the delta
|
|
99
|
+
__shape = mlable.shapes.filter(outputs.shape, axes=[-1])
|
|
100
|
+
# rescale the delta
|
|
101
|
+
return alpha * outputs + beta * delta.view(__shape)
|
|
102
|
+
|
|
103
|
+
# MAIN #########################################################################
|
|
104
|
+
|
|
105
|
+
def steer_model_output(
|
|
106
|
+
positive_str: str,
|
|
107
|
+
negative_str: str,
|
|
108
|
+
prompt_str: str,
|
|
109
|
+
positive_rate: float,
|
|
110
|
+
negative_rate: float,
|
|
111
|
+
prompt_rate: float,
|
|
112
|
+
token_num: int,
|
|
113
|
+
topk_num: int,
|
|
114
|
+
topp_num: float,
|
|
115
|
+
layer_idx: int,
|
|
116
|
+
device_str: str,
|
|
117
|
+
model_obj: object,
|
|
118
|
+
tokenizer_obj: object,
|
|
119
|
+
) -> str:
|
|
120
|
+
# parse & sanitize
|
|
121
|
+
__prompt0 = positive_str.strip()
|
|
122
|
+
__prompt1 = negative_str.strip()
|
|
123
|
+
__prompt2 = prompt_str.strip()
|
|
124
|
+
__alpha0 = max(0.0, float(positive_rate))
|
|
125
|
+
__alpha1 = max(0.0, float(negative_rate))
|
|
126
|
+
__alpha2 = max(0.0, float(prompt_rate))
|
|
127
|
+
__count = max(1, int(token_num))
|
|
128
|
+
__topk = max(1, int(topk_num))
|
|
129
|
+
__topp = max(0.0, float(topp_num))
|
|
130
|
+
__index = max(0, int(layer_idx))
|
|
131
|
+
# store hidden states
|
|
132
|
+
__captured = {}
|
|
133
|
+
# stop if inputs are missing
|
|
134
|
+
if not (__prompt0 and __prompt1 and __prompt2):
|
|
135
|
+
return ''
|
|
136
|
+
# tokenize the 2 prompts and pad to same length
|
|
137
|
+
__inputs = preprocess_token_ids(tokenizer=tokenizer_obj, prompts=(__prompt0, __prompt1), device=device_str)
|
|
138
|
+
# forward hook to capture output hidden state
|
|
139
|
+
__hook = functools.partial(capture_hidden_activation, index=__index, captured=__captured)
|
|
140
|
+
# attach to the model
|
|
141
|
+
__handle = model_obj.model.layers[__index].register_forward_hook(__hook)
|
|
142
|
+
with torch.no_grad():
|
|
143
|
+
# inference mode
|
|
144
|
+
model_obj.eval().to(device_str)
|
|
145
|
+
# prefill with a single forward
|
|
146
|
+
__outputs = model_obj(**__inputs, use_cache=True, output_attentions=False, output_hidden_states=False, return_dict=True)
|
|
147
|
+
# stop capturing activations
|
|
148
|
+
__handle.remove()
|
|
149
|
+
# select only the positions where the tokens differ
|
|
150
|
+
__masks = compute_sequence_mask(tokens=__inputs['input_ids'], masks=__inputs['attention_mask'])
|
|
151
|
+
# activation delta at layer L
|
|
152
|
+
__delta = compute_delta_activation(data=__captured[__index], masks=__masks, signs=torch.Tensor([1, -1]), keepdim=False)
|
|
153
|
+
# add the delta on every forward pass
|
|
154
|
+
__hook = functools.partial(add_delta_activation, alpha=__alpha2, beta=0.5 * (__alpha0 + __alpha1), delta=__delta)
|
|
155
|
+
# attach to the model
|
|
156
|
+
__handle = model_obj.model.layers[__index].register_forward_hook(__hook)
|
|
157
|
+
# now process the user input
|
|
158
|
+
__inputs = preprocess_token_ids(tokenizer=tokenizer_obj, prompts=(prompt_str,), device=device_str)
|
|
159
|
+
# generate the new with tampered activations
|
|
160
|
+
with torch.no_grad():
|
|
161
|
+
__outputs = model_obj.generate(
|
|
162
|
+
**__inputs,
|
|
163
|
+
max_new_tokens=__count,
|
|
164
|
+
do_sample=(0.0 < __topp < 1.0) or (__topk > 0),
|
|
165
|
+
top_k=__topk if (__topk > 0) else None,
|
|
166
|
+
top_p=__topp if (0.0 < __topp <= 1.0) else None,
|
|
167
|
+
return_dict_in_generate=True,
|
|
168
|
+
output_hidden_states=False,
|
|
169
|
+
output_attentions=False,
|
|
170
|
+
output_scores=False,
|
|
171
|
+
use_cache=True)
|
|
172
|
+
# stop altering the activations
|
|
173
|
+
__handle.remove()
|
|
174
|
+
# single string
|
|
175
|
+
return tokenizer_obj.decode(__outputs.sequences[0], skip_special_tokens=True)
|
|
File without changes
|
psaiops/score/attention/app.py
CHANGED
|
@@ -18,7 +18,7 @@ MODEL = 'openai/gpt-oss-20b'
|
|
|
18
18
|
|
|
19
19
|
def create_color_map() -> dict:
|
|
20
20
|
return {
|
|
21
|
-
'-1': '#
|
|
21
|
+
'-1': '#004444',
|
|
22
22
|
**{str(__i): '#{:02x}0000'.format(int(2.55 * __i)) for __i in range(101)}}
|
|
23
23
|
|
|
24
24
|
# INTRO ########################################################################
|
|
@@ -65,13 +65,13 @@ def create_inputs_block() -> dict:
|
|
|
65
65
|
# OUTPUTS ######################################################################
|
|
66
66
|
|
|
67
67
|
def create_outputs_block() -> dict:
|
|
68
|
-
__output = gradio.HighlightedText(label='Scores', value='', scale=1, interactive=False, show_legend=False, show_inline_category=False, combine_adjacent=
|
|
68
|
+
__output = gradio.HighlightedText(label='Scores', value='', scale=1, interactive=False, show_legend=False, show_inline_category=False, combine_adjacent=False, color_map=create_color_map(), elem_classes='white-text')
|
|
69
69
|
return {'output_block': __output}
|
|
70
70
|
|
|
71
71
|
# SELECT #######################################################################
|
|
72
72
|
|
|
73
73
|
def create_selection_block() -> dict:
|
|
74
|
-
__position = gradio.Slider(label='Position', value=-1, minimum=-1, maximum=15, step=1, scale=1, interactive=True) # info='-1 to average on all tokens'
|
|
74
|
+
__position = gradio.Slider(label='Token Position', value=-1, minimum=-1, maximum=15, step=1, scale=1, interactive=True) # info='-1 to average on all tokens'
|
|
75
75
|
__layer = gradio.Slider(label='Layer Depth', value=12, minimum=-1, maximum=23, step=1, scale=1, interactive=True) # info='-1 to average on all layers'
|
|
76
76
|
__head = gradio.Slider(label='Attention Head', value=-1, minimum=-1, maximum=63, step=1, scale=1, interactive=True) # info='-1 to average on all heads'
|
|
77
77
|
return {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: psaiops
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Web apps to inspect & engineer NN activations.
|
|
5
5
|
License: .github/LICENSE.md
|
|
6
6
|
Author: apehex
|
|
@@ -12,9 +12,12 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Requires-Dist: accelerate (>=1.10)
|
|
15
16
|
Requires-Dist: deformers (>=0.0)
|
|
16
17
|
Requires-Dist: gradio (>=5.0)
|
|
18
|
+
Requires-Dist: kernels (==0.10)
|
|
17
19
|
Requires-Dist: requests (>=2.0)
|
|
20
|
+
Requires-Dist: triton (==3.4)
|
|
18
21
|
Description-Content-Type: text/markdown
|
|
19
22
|
|
|
20
23
|
# psAI ops <img src="images/logo.png" alt="apehex logo" width="32" height="32">
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
psaiops/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
psaiops/combine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
psaiops/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
psaiops/common/data.py,sha256=vGYeMN11uP9gs8rV6aSDffE_TeIX5PmdzWGwUpdGE2Y,906
|
|
5
|
+
psaiops/common/dropdown.py,sha256=KA3wrfz4UlCpeoDvFAeURGK3YmVg6TBVhybaqTZa1M0,1332
|
|
6
|
+
psaiops/compose/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
psaiops/compose/contrast/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
psaiops/compose/contrast/app.py,sha256=hecqh2yuUpAQMaesjIVlG-QxSJhm595Thm0CHEirZ64,8737
|
|
9
|
+
psaiops/compose/contrast/lib.py,sha256=lBw-0VNvmEiY_zs9-e1TFYmOdlIbvEc7aB-9ZiZFyBU,6543
|
|
10
|
+
psaiops/edit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
psaiops/reverse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
psaiops/score/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
+
psaiops/score/attention/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
psaiops/score/attention/app.py,sha256=7MwFp70W0zpIcxllM2hKHN7TW3WH-BGFNK3r9a1ISr0,13444
|
|
15
|
+
psaiops/score/attention/lib.py,sha256=j9p7ZXhkh5Y9VDeIe6TPUUrHRkwp1Y6P22iciaaKdL4,6932
|
|
16
|
+
psaiops/steer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
+
psaiops-0.2.0.dist-info/METADATA,sha256=JQ_Pu17L6AwFA3J_dxVggdzHk_iMDiLc78TDAHT9sUM,1318
|
|
18
|
+
psaiops-0.2.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
19
|
+
psaiops-0.2.0.dist-info/RECORD,,
|
psaiops-0.1.0.dist-info/RECORD
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
psaiops/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
psaiops/combine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
psaiops/compose/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
psaiops/compose/contrast/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
-
psaiops/edit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
psaiops/elements/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
psaiops/elements/data.py,sha256=vGYeMN11uP9gs8rV6aSDffE_TeIX5PmdzWGwUpdGE2Y,906
|
|
8
|
-
psaiops/score/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
psaiops/score/attention/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
psaiops/score/attention/app.py,sha256=PlpbhEIJ4zcaqOWJM0V6rFi7HsIhQyDdqhNBltB4dRY,13437
|
|
11
|
-
psaiops/score/attention/lib.py,sha256=j9p7ZXhkh5Y9VDeIe6TPUUrHRkwp1Y6P22iciaaKdL4,6932
|
|
12
|
-
psaiops/steer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
psaiops-0.1.0.dist-info/METADATA,sha256=GtW5Nj6cjS2KX4oIEXiZQ98pkYMVpPb1bP7ky0f9U4M,1221
|
|
14
|
-
psaiops-0.1.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
15
|
-
psaiops-0.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|