diff --git a/mjc_notes.md b/mjc_notes.md index 01fc2d6..ea341e8 100644 --- a/mjc_notes.md +++ b/mjc_notes.md @@ -2100,6 +2100,8 @@ TODO: - [ ] maybe I can use my intervention as an importance matrix for the VAE loss? - [ ] maybe I can do that codebook VAE? How big? +Wait I'm calibrating on the positive vs negative.... so yes my intervention will flip it. But it's not on truth or lie or deception! + OK I can't load all my hs into mem, that's not ideal.... and I tried the mean diff intervention since eluther like it, but the truthfull llama one seems broken @@ -2183,7 +2185,14 @@ git fetch upstream git rebase upstream/main git push --force-with-lease ``` +ok I wasn't even applying the activation right? I was adding, mean to multiply... +Definitly time to simplify +plan +- So delete rep_readers +- intervention_meta_fn2 +- activations +- src.datasets.intervene create_cache_interventions # Phi-2 @@ -2196,3 +2205,5 @@ maybe for padding use 50256? Rather than 0? "torch_dtype": "float16", "transformers_version": "4.37.0.dev0", + + diff --git a/notebooks/104_check_intervention.ipynb b/notebooks/104_check_intervention.ipynb index e699f73..fd799c5 100644 --- a/notebooks/104_check_intervention.ipynb +++ b/notebooks/104_check_intervention.ipynb @@ -120,78 +120,99 @@ "execution_count": 4, "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ExtractConfig(datasets=('amazon_polarity', 'super_glue:boolq', 'glue:qnli', 'imdb'), model='wassname/phi-2-GPTQ_w_hidden_states', batch_size=5, pad_token_id=50256, prompt_format='phi', data_dirs=(), max_examples=(400, 400), num_shots=2, num_variants=-1, seed=42, template_path=None, max_length=1000, disable_ds_cache=False, intervention_direction_method='cluster_mean', intervention_fit_examples=160, intervention_layer_name_template='transformer.h.{}')\n" + ] + }, { "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m2023-12-16 10:14:43.517\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36msrc.models.load\u001b[0m:\u001b[36mverbose_change_param\u001b[0m:\u001b[36m24\u001b[0m - \u001b[1mchanging use_cache from True to False\u001b[0m\n", - "2023-12-16T10:14:43.517976+0800 INFO changing use_cache from True to False\n", + "\u001b[32m2023-12-16 11:51:16.540\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36msrc.models.load\u001b[0m:\u001b[36mverbose_change_param\u001b[0m:\u001b[36m24\u001b[0m - \u001b[1mchanging use_cache from True to False\u001b[0m\n", + "2023-12-16T11:51:16.540903+0800 INFO changing use_cache from True to False\n", "Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.\n", - "\u001b[32m2023-12-16 10:14:43.853\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36msrc.models.load\u001b[0m:\u001b[36mverbose_change_param\u001b[0m:\u001b[36m24\u001b[0m - \u001b[1mchanging pad_token_id from None to 50256\u001b[0m\n", - "2023-12-16T10:14:43.853595+0800 INFO changing pad_token_id from None to 50256\n", - "\u001b[32m2023-12-16 10:14:43.854\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36msrc.models.load\u001b[0m:\u001b[36mverbose_change_param\u001b[0m:\u001b[36m24\u001b[0m - \u001b[1mchanging padding_side from right to left\u001b[0m\n", - "2023-12-16T10:14:43.854275+0800 INFO changing padding_side from right to left\n", - "\u001b[32m2023-12-16 10:14:43.854\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36msrc.models.load\u001b[0m:\u001b[36mverbose_change_param\u001b[0m:\u001b[36m24\u001b[0m - \u001b[1mchanging truncation_side from right to left\u001b[0m\n", - "2023-12-16T10:14:43.854771+0800 INFO changing truncation_side from right to left\n", - "Generating train split: 0 examples [00:00, ? examples/s]" + "\u001b[32m2023-12-16 11:51:16.902\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36msrc.models.load\u001b[0m:\u001b[36mverbose_change_param\u001b[0m:\u001b[36m24\u001b[0m - \u001b[1mchanging pad_token_id from None to 50256\u001b[0m\n", + "2023-12-16T11:51:16.902047+0800 INFO changing pad_token_id from None to 50256\n", + "\u001b[32m2023-12-16 11:51:16.902\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36msrc.models.load\u001b[0m:\u001b[36mverbose_change_param\u001b[0m:\u001b[36m24\u001b[0m - \u001b[1mchanging padding_side from right to left\u001b[0m\n", + "2023-12-16T11:51:16.902868+0800 INFO changing padding_side from right to left\n", + "\u001b[32m2023-12-16 11:51:16.903\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36msrc.models.load\u001b[0m:\u001b[36mverbose_change_param\u001b[0m:\u001b[36m24\u001b[0m - \u001b[1mchanging truncation_side from right to left\u001b[0m\n", + "2023-12-16T11:51:16.903473+0800 INFO changing truncation_side from right to left\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Extracting 11 variants of each prompt\n" + "PhiForCausalLM(\n", + " (transformer): PhiModel(\n", + " (embd): Embedding(\n", + " (wte): Embedding(51200, 2560)\n", + " (drop): Dropout(p=0.0, inplace=False)\n", + " )\n", + " (h): ModuleList(\n", + " (0-31): 32 x ParallelBlock(\n", + " (ln): LayerNorm((2560,), eps=1e-05, elementwise_affine=True)\n", + " (resid_dropout): Dropout(p=0.1, inplace=False)\n", + " (mixer): MHA(\n", + " (rotary_emb): RotaryEmbedding()\n", + " (inner_attn): SelfAttention(\n", + " (drop): Dropout(p=0.0, inplace=False)\n", + " )\n", + " (inner_cross_attn): CrossAttention(\n", + " (drop): Dropout(p=0.0, inplace=False)\n", + " )\n", + " (Wqkv): QuantLinear()\n", + " (out_proj): QuantLinear()\n", + " )\n", + " (mlp): MLP(\n", + " (act): NewGELUActivation()\n", + " (fc1): QuantLinear()\n", + " (fc2): QuantLinear()\n", + " )\n", + " )\n", + " )\n", + " )\n", + " (lm_head): CausalLMHead(\n", + " (ln): LayerNorm((2560,), eps=1e-05, elementwise_affine=True)\n", + " (linear): Linear(in_features=2560, out_features=51200, bias=True)\n", + " )\n", + " (loss): CausalLMLoss(\n", + " (loss_fct): CrossEntropyLoss()\n", + " )\n", + ")\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Generating train split: 242 examples [00:40, 5.91 examples/s]\n", - "format_prompt: 100%|██████████| 242/242 [00:00<00:00, 7027.58 examples/s]\n", - "tokenize: 100%|██████████| 242/242 [00:00<00:00, 1284.35 examples/s]\n", - "truncated: 100%|██████████| 242/242 [00:00<00:00, 2526.02 examples/s]\n", - "truncated: 100%|██████████| 242/242 [00:00<00:00, 2476.92 examples/s]\n", - "prompt_truncated: 100%|██████████| 242/242 [00:00<00:00, 307.85 examples/s]\n", - "choice_ids: 100%|██████████| 242/242 [00:00<00:00, 6967.33 examples/s]\n", - "\u001b[32m2023-12-16 10:15:28.371\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36msrc.prompts.prompt_loading\u001b[0m:\u001b[36mload_preproc_dataset\u001b[0m:\u001b[36m368\u001b[0m - \u001b[1mtruncation rate: 0.0 on amazon_polarity\u001b[0m\n", - "2023-12-16T10:15:28.371476+0800 INFO truncation rate: 0.0 on amazon_polarity\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "median token length: 440.0 for amazon_polarity. max_length=1000\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Filter: 100%|██████████| 242/242 [00:00<00:00, 2223.43 examples/s]\n", - "Filter: 100%|██████████| 242/242 [00:00<00:00, 2118.60 examples/s]" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "num_rows (after filtering out truncated rows) 242=>242\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n" + "Generating train split: 0 examples [00:00, ? examples/s]\u001b[32m2023-12-16 11:51:22.526\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36msrc.prompts.prompt_loading\u001b[0m:\u001b[36mload_prompts\u001b[0m:\u001b[36m120\u001b[0m - \u001b[1mExtracting 11 variants of each prompt\u001b[0m\n", + "2023-12-16T11:51:22.526803+0800 INFO Extracting 11 variants of each prompt\n", + "Generating train split: 2402 examples [05:52, 6.82 examples/s]\n", + "format_prompt: 100%|██████████| 2402/2402 [00:00<00:00, 7939.78 examples/s]\n", + "tokenize: 100%|██████████| 2402/2402 [00:01<00:00, 1312.50 examples/s]\n", + "truncated: 100%|██████████| 2402/2402 [00:00<00:00, 2617.70 examples/s]\n", + "truncated: 100%|██████████| 2402/2402 [00:00<00:00, 2537.01 examples/s]\n", + "prompt_truncated: 100%|██████████| 2402/2402 [00:07<00:00, 322.85 examples/s]\n", + "choice_ids: 100%|██████████| 2402/2402 [00:00<00:00, 4870.83 examples/s]\n", + "\u001b[32m2023-12-16 11:57:23.152\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36msrc.prompts.prompt_loading\u001b[0m:\u001b[36mload_preproc_dataset\u001b[0m:\u001b[36m364\u001b[0m - \u001b[1mmedian token length: 433.0 for amazon_polarity. max_length=1000\u001b[0m\n", + "2023-12-16T11:57:23.152948+0800 INFO median token length: 433.0 for amazon_polarity. max_length=1000\n", + "\u001b[32m2023-12-16 11:57:23.154\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36msrc.prompts.prompt_loading\u001b[0m:\u001b[36mload_preproc_dataset\u001b[0m:\u001b[36m368\u001b[0m - \u001b[1mtruncation rate: 0.00% on amazon_polarity\u001b[0m\n", + "2023-12-16T11:57:23.154377+0800 INFO truncation rate: 0.00% on amazon_polarity\n", + "Filter: 100%|██████████| 2402/2402 [00:01<00:00, 2283.72 examples/s]\n", + "Filter: 100%|██████████| 2402/2402 [00:01<00:00, 2201.41 examples/s]\n", + "\u001b[32m2023-12-16 11:57:25.313\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36msrc.prompts.prompt_loading\u001b[0m:\u001b[36mload_preproc_dataset\u001b[0m:\u001b[36m377\u001b[0m - \u001b[1mnum_rows (after filtering out truncated rows) 2402=>2402\u001b[0m\n", + "2023-12-16T11:57:25.313993+0800 INFO num_rows (after filtering out truncated rows) 2402=>2402\n" ] } ], "source": [ "ds_name='amazon_polarity'\n", - "cfg = ExtractConfig(max_examples=(40, 40),\n", - " intervention_fit_examples=10,\n", + "cfg = ExtractConfig(max_examples=(400, 400),\n", + " intervention_fit_examples=160,\n", " )\n", "print(cfg)\n", "batch_size = cfg.batch_size\n", @@ -211,20 +232,308 @@ "outputs": [], "source": [] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Intervention" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m2023-12-16 11:57:25.647\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36msrc.datasets.intervene\u001b[0m:\u001b[36mcreate_cache_interventions\u001b[0m:\u001b[36m138\u001b[0m - \u001b[1mLoaded interventions from /media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/data/interventions/wassname-phi-2-GPTQ_w_hidden_states_+_cluster_mean_481.pkl\u001b[0m\n", + "2023-12-16T11:57:25.647973+0800 INFO Loaded interventions from /media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/data/interventions/wassname-phi-2-GPTQ_w_hidden_states_+_cluster_mean_481.pkl\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "honesty_rep_reader = create_cache_interventions(model, tokenizer, cfg)\n", + "honesty_rep_reader\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "honesty_rep_reader\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[-0.1623942 , -0.05915324, 0.08666992, ..., 0.04361978,\n", + " 0.13239542, 0.11653644]], dtype=float32)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "layer = 6\n", + "honesty_rep_reader.directions[layer]\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{6: [-1],\n", + " 7: [-1],\n", + " 8: [-1],\n", + " 9: [-1],\n", + " 10: [-1],\n", + " 11: [-1],\n", + " 12: [-1],\n", + " 13: [-1],\n", + " 14: [-1],\n", + " 15: [-1],\n", + " 16: [-1],\n", + " 17: [-1],\n", + " 18: [-1],\n", + " 19: [-1],\n", + " 20: [-1],\n", + " 21: [-1],\n", + " 22: [-1],\n", + " 23: [-1],\n", + " 24: [-1],\n", + " 25: [-1],\n", + " 26: [-1],\n", + " 27: [-1],\n", + " 28: [-1],\n", + " 29: [-1],\n", + " 30: [-1],\n", + " 31: [-1]}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "honesty_rep_reader.direction_signs\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Generate answers\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "rep-reading is already registered. Overwriting pipeline for task rep-reading...\n", + "rep-control2 is already registered. Overwriting pipeline for task rep-control2...\n", + "\u001b[32m2023-12-16 11:57:25.760\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36msrc.datasets.intervene\u001b[0m:\u001b[36mcreate_cache_interventions\u001b[0m:\u001b[36m138\u001b[0m - \u001b[1mLoaded interventions from /media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/data/interventions/wassname-phi-2-GPTQ_w_hidden_states_+_cluster_mean_481.pkl\u001b[0m\n", + "2023-12-16T11:57:25.760677+0800 INFO Loaded interventions from /media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/data/interventions/wassname-phi-2-GPTQ_w_hidden_states_+_cluster_mean_481.pkl\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "from src.repe import repe_pipeline_registry\n", + "from transformers import pipeline\n", + "# from src.datasets.intervene import test_intervention_quality, intervention_metrics\n", + "repe_pipeline_registry()\n", + "\n", + "honesty_rep_reader = create_cache_interventions(model, tokenizer, cfg)\n", + "hidden_layers = sorted(honesty_rep_reader.directions.keys())\n", + "coeff=1.\n", + "\n", + "activations = {}\n", + "for layer in hidden_layers:\n", + " activations[layer] = torch.tensor(coeff * honesty_rep_reader.directions[layer] * honesty_rep_reader.direction_signs[layer]).to(model.device).half()\n", + "assert torch.isfinite(torch.concat(list(activations.values()))).all()\n", + "\n", + "activations_neg_i = {k:-v for k,v in activations.items()}\n", + "activations_neut = {k:v*0 for k,v in activations.items()}\n", + "\n", + "rep_control_pipeline2 = pipeline(\n", + " \"rep-control2\", \n", + " model=model, \n", + " tokenizer=tokenizer, \n", + " layers=hidden_layers, \n", + " max_length=cfg.max_length, layer_name_tmpl=cfg.intervention_layer_name_template)\n", + "rep_control_pipeline2\n" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "def top_toke_probs(o, N=20):\n", + " data = {}\n", + " for i in range(o['end_logits'].shape[1]):\n", + " probs = torch.softmax(o['end_logits'][:, i], -1)\n", + " top = probs.argsort(0, descending=True)\n", + " top_probs = probs[top]\n", + " tokens_top20 = tokenizer.batch_decode(top[:N], skip_special_tokens=False , clean_up_tokenization_spaces=False)\n", + " tokens_top20 = [f\"`{t}`\" for t in tokens_top20] \n", + " data.update({f'prob_{i}':top_probs[:N], f'tokens_{i}':tokens_top20, f'id_{i}':top[:N]})\n", + " return pd.DataFrame(data)\n", + "\n", + "from IPython.display import display, HTML\n", + "\n", + "def print_pipeline_r(o):\n", + " choices = [tokenizer.batch_decode(cc) for cc in o['choice_ids']]\n", + " index = [o[0] for o in choices]\n", + " d = pd.DataFrame(o['choice_probs'].numpy(), columns=['edit=None', 'edit=+'], index=index)\n", + " print('choice probs')\n", + " display(d)\n", + "\n", + " d1 = top_toke_probs(o)\n", + " print('top token probs')\n", + " display(d1)\n", + " top1 = o['end_logits'][:, 0].argsort(0, descending=True)[:10]\n", + " top2 = o['end_logits'][:, 1].argsort(0, descending=True)[:10]\n", + "\n", + " max_prob1 = torch.softmax(o['end_logits'][:, 0], -1).max()\n", + " max_prob2 = torch.softmax(o['end_logits'][:, 1], -1).max()\n", + " print(top1)\n", + " print(top2)\n", + " print('top choices no intervention', tokenizer.batch_decode(top1, skip_special_tokens=False , clean_up_tokenization_spaces=False))\n", + " print('top choices pos intervention', tokenizer.batch_decode(top2))\n", + " \n", + " mean_prob = o['choice_probs'].sum(0)\n", + " print(f\"\\tchoice_cov=\\t{mean_prob[0]:2.2%} max_prob={max_prob1} (no edit) - Our choices accounted for a mean probability of this\")\n", + " print(f\"\\tchoice_cov=\\t{mean_prob[1]:2.2%} max_prob={max_prob2} (+ edit) - Our choices accounted for a mean probability of this\")\n", + " \n", + " print('choices', choices)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "ename": "RuntimeError", + "evalue": "1D tensors expected, but got 3D and 1D tensors", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/notebooks/104_check_intervention.ipynb Cell 18\u001b[0m line \u001b[0;36m5\n\u001b[1;32m 1\u001b[0m ds \u001b[39m=\u001b[39m ds_tokens\u001b[39m.\u001b[39mselect(\u001b[39mrange\u001b[39m(\u001b[39m3\u001b[39m))\u001b[39m.\u001b[39mto_iterable_dataset()\n\u001b[1;32m 2\u001b[0m r1 \u001b[39m=\u001b[39m rep_control_pipeline2(model_inputs\u001b[39m=\u001b[39mds,\n\u001b[1;32m 3\u001b[0m activations\u001b[39m=\u001b[39mactivations_neg_i,\n\u001b[1;32m 4\u001b[0m batch_size\u001b[39m=\u001b[39mbatch_size,)\n\u001b[0;32m----> 5\u001b[0m r \u001b[39m=\u001b[39m \u001b[39mlist\u001b[39;49m(r1)\n\u001b[1;32m 6\u001b[0m o \u001b[39m=\u001b[39m r[\u001b[39m0\u001b[39m]\n\u001b[1;32m 7\u001b[0m print_pipeline_r(o)\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/.venv/lib/python3.10/site-packages/transformers/pipelines/pt_utils.py:124\u001b[0m, in \u001b[0;36mPipelineIterator.__next__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 121\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mloader_batch_item()\n\u001b[1;32m 123\u001b[0m \u001b[39m# We're out of items within a batch\u001b[39;00m\n\u001b[0;32m--> 124\u001b[0m item \u001b[39m=\u001b[39m \u001b[39mnext\u001b[39;49m(\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49miterator)\n\u001b[1;32m 125\u001b[0m processed \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39minfer(item, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39m\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mparams)\n\u001b[1;32m 126\u001b[0m \u001b[39m# We now have a batch of \"inferred things\".\u001b[39;00m\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/.venv/lib/python3.10/site-packages/transformers/pipelines/pt_utils.py:125\u001b[0m, in \u001b[0;36mPipelineIterator.__next__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 123\u001b[0m \u001b[39m# We're out of items within a batch\u001b[39;00m\n\u001b[1;32m 124\u001b[0m item \u001b[39m=\u001b[39m \u001b[39mnext\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39miterator)\n\u001b[0;32m--> 125\u001b[0m processed \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49minfer(item, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49m\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mparams)\n\u001b[1;32m 126\u001b[0m \u001b[39m# We now have a batch of \"inferred things\".\u001b[39;00m\n\u001b[1;32m 127\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mloader_batch_size \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m 128\u001b[0m \u001b[39m# Try to infer the size of the batch\u001b[39;00m\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/.venv/lib/python3.10/site-packages/transformers/pipelines/base.py:1046\u001b[0m, in \u001b[0;36mPipeline.forward\u001b[0;34m(self, model_inputs, **forward_params)\u001b[0m\n\u001b[1;32m 1044\u001b[0m \u001b[39mwith\u001b[39;00m inference_context():\n\u001b[1;32m 1045\u001b[0m model_inputs \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_ensure_tensor_on_device(model_inputs, device\u001b[39m=\u001b[39m\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdevice)\n\u001b[0;32m-> 1046\u001b[0m model_outputs \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_forward(model_inputs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mforward_params)\n\u001b[1;32m 1047\u001b[0m model_outputs \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_ensure_tensor_on_device(model_outputs, device\u001b[39m=\u001b[39mtorch\u001b[39m.\u001b[39mdevice(\u001b[39m\"\u001b[39m\u001b[39mcpu\u001b[39m\u001b[39m\"\u001b[39m))\n\u001b[1;32m 1048\u001b[0m \u001b[39melse\u001b[39;00m:\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/src/repe/rep_control_pipeline_baukit.py:124\u001b[0m, in \u001b[0;36mRepControlPipeline2._forward\u001b[0;34m(self, inputs, activations)\u001b[0m\n\u001b[1;32m 120\u001b[0m \u001b[39mwith\u001b[39;00m torch\u001b[39m.\u001b[39mno_grad():\n\u001b[1;32m 121\u001b[0m \u001b[39mwith\u001b[39;00m TraceDict(\n\u001b[1;32m 122\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mmodel, layers_names, detach\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m, edit_output\u001b[39m=\u001b[39medit_fn_pos\n\u001b[1;32m 123\u001b[0m ) \u001b[39mas\u001b[39;00m ret:\n\u001b[0;32m--> 124\u001b[0m outputs_pos \u001b[39m=\u001b[39m transform_model_output(\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mmodel(\u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mmodel_in))\n\u001b[1;32m 126\u001b[0m \u001b[39mwith\u001b[39;00m TraceDict(\n\u001b[1;32m 127\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mmodel, layers_names, detach\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m, edit_output\u001b[39m=\u001b[39medit_fn_neu\n\u001b[1;32m 128\u001b[0m ) \u001b[39mas\u001b[39;00m ret:\n\u001b[1;32m 129\u001b[0m outputs_neg \u001b[39m=\u001b[39m transform_model_output(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mmodel(\u001b[39m*\u001b[39m\u001b[39m*\u001b[39mmodel_in))\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/.venv/lib/python3.10/site-packages/torch/nn/modules/module.py:1518\u001b[0m, in \u001b[0;36mModule._wrapped_call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1516\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_compiled_call_impl(\u001b[39m*\u001b[39margs, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs) \u001b[39m# type: ignore[misc]\u001b[39;00m\n\u001b[1;32m 1517\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m-> 1518\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_call_impl(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/.venv/lib/python3.10/site-packages/torch/nn/modules/module.py:1527\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1522\u001b[0m \u001b[39m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m 1523\u001b[0m \u001b[39m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m 1524\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m (\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_pre_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m 1525\u001b[0m \u001b[39mor\u001b[39;00m _global_backward_pre_hooks \u001b[39mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m 1526\u001b[0m \u001b[39mor\u001b[39;00m _global_forward_hooks \u001b[39mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1527\u001b[0m \u001b[39mreturn\u001b[39;00m forward_call(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 1529\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m 1530\u001b[0m result \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/.venv/lib/python3.10/site-packages/accelerate/hooks.py:165\u001b[0m, in \u001b[0;36madd_hook_to_module..new_forward\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 163\u001b[0m output \u001b[39m=\u001b[39m old_forward(\u001b[39m*\u001b[39margs, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs)\n\u001b[1;32m 164\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m--> 165\u001b[0m output \u001b[39m=\u001b[39m old_forward(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 166\u001b[0m \u001b[39mreturn\u001b[39;00m module\u001b[39m.\u001b[39m_hf_hook\u001b[39m.\u001b[39mpost_forward(module, output)\n", + "File \u001b[0;32m~/.cache/huggingface/modules/transformers_modules/wassname/phi-2-GPTQ_w_hidden_states/e39f09ffdefdb011e32b1cad1175c952a5a0f88d/modeling_phi.py:957\u001b[0m, in \u001b[0;36mPhiForCausalLM.forward\u001b[0;34m(self, input_ids, past_key_values, attention_mask, labels, **kwargs)\u001b[0m\n\u001b[1;32m 949\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mforward\u001b[39m(\n\u001b[1;32m 950\u001b[0m \u001b[39mself\u001b[39m,\n\u001b[1;32m 951\u001b[0m input_ids: torch\u001b[39m.\u001b[39mLongTensor,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 955\u001b[0m \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs,\n\u001b[1;32m 956\u001b[0m ) \u001b[39m-\u001b[39m\u001b[39m>\u001b[39m CausalLMOutputWithPast:\n\u001b[0;32m--> 957\u001b[0m outputs \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mtransformer(input_ids, past_key_values\u001b[39m=\u001b[39;49mpast_key_values, attention_mask\u001b[39m=\u001b[39;49mattention_mask)\n\u001b[1;32m 958\u001b[0m lm_logits \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mlm_head(outputs\u001b[39m.\u001b[39mlast_hidden_state)\n\u001b[1;32m 960\u001b[0m loss \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/.venv/lib/python3.10/site-packages/torch/nn/modules/module.py:1518\u001b[0m, in \u001b[0;36mModule._wrapped_call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1516\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_compiled_call_impl(\u001b[39m*\u001b[39margs, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs) \u001b[39m# type: ignore[misc]\u001b[39;00m\n\u001b[1;32m 1517\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m-> 1518\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_call_impl(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/.venv/lib/python3.10/site-packages/torch/nn/modules/module.py:1527\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1522\u001b[0m \u001b[39m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m 1523\u001b[0m \u001b[39m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m 1524\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m (\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_pre_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m 1525\u001b[0m \u001b[39mor\u001b[39;00m _global_backward_pre_hooks \u001b[39mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m 1526\u001b[0m \u001b[39mor\u001b[39;00m _global_forward_hooks \u001b[39mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1527\u001b[0m \u001b[39mreturn\u001b[39;00m forward_call(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 1529\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m 1530\u001b[0m result \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n", + "File \u001b[0;32m~/.cache/huggingface/modules/transformers_modules/wassname/phi-2-GPTQ_w_hidden_states/e39f09ffdefdb011e32b1cad1175c952a5a0f88d/modeling_phi.py:917\u001b[0m, in \u001b[0;36mPhiModel.forward\u001b[0;34m(self, input_ids, past_key_values, attention_mask)\u001b[0m\n\u001b[1;32m 915\u001b[0m all_hidden_states \u001b[39m=\u001b[39m [hidden_states]\n\u001b[1;32m 916\u001b[0m \u001b[39mfor\u001b[39;00m layer \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mh:\n\u001b[0;32m--> 917\u001b[0m hidden_states, attn_outputs \u001b[39m=\u001b[39m layer_outputs \u001b[39m=\u001b[39m layer(\n\u001b[1;32m 918\u001b[0m hidden_states,\n\u001b[1;32m 919\u001b[0m past_key_values\u001b[39m=\u001b[39;49mpast_key_values,\n\u001b[1;32m 920\u001b[0m attention_mask\u001b[39m=\u001b[39;49mattention_mask,\n\u001b[1;32m 921\u001b[0m )\n\u001b[1;32m 922\u001b[0m all_hidden_states\u001b[39m.\u001b[39mappend(hidden_states)\n\u001b[1;32m 923\u001b[0m all_self_attns\u001b[39m.\u001b[39mappend(attn_outputs)\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/.venv/lib/python3.10/site-packages/torch/nn/modules/module.py:1518\u001b[0m, in \u001b[0;36mModule._wrapped_call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1516\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_compiled_call_impl(\u001b[39m*\u001b[39margs, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs) \u001b[39m# type: ignore[misc]\u001b[39;00m\n\u001b[1;32m 1517\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m-> 1518\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_call_impl(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/.venv/lib/python3.10/site-packages/torch/nn/modules/module.py:1581\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1579\u001b[0m hook_result \u001b[39m=\u001b[39m hook(\u001b[39mself\u001b[39m, args, kwargs, result)\n\u001b[1;32m 1580\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m-> 1581\u001b[0m hook_result \u001b[39m=\u001b[39m hook(\u001b[39mself\u001b[39;49m, args, result)\n\u001b[1;32m 1583\u001b[0m \u001b[39mif\u001b[39;00m hook_result \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m 1584\u001b[0m result \u001b[39m=\u001b[39m hook_result\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/.venv/lib/python3.10/site-packages/baukit/nethook.py:73\u001b[0m, in \u001b[0;36mTrace.__init__..retain_hook\u001b[0;34m(m, inputs, output)\u001b[0m\n\u001b[1;32m 71\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mretain_hook\u001b[39m(m, inputs, output):\n\u001b[1;32m 72\u001b[0m \u001b[39mif\u001b[39;00m edit_output:\n\u001b[0;32m---> 73\u001b[0m output \u001b[39m=\u001b[39m invoke_with_optional_args(\n\u001b[1;32m 74\u001b[0m edit_output, output\u001b[39m=\u001b[39;49moutput, layer\u001b[39m=\u001b[39;49m\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mlayer, inputs\u001b[39m=\u001b[39;49minputs\n\u001b[1;32m 75\u001b[0m )\n\u001b[1;32m 76\u001b[0m \u001b[39mif\u001b[39;00m retain_input:\n\u001b[1;32m 77\u001b[0m retainer\u001b[39m.\u001b[39minput \u001b[39m=\u001b[39m recursive_copy(\n\u001b[1;32m 78\u001b[0m inputs[\u001b[39m0\u001b[39m] \u001b[39mif\u001b[39;00m \u001b[39mlen\u001b[39m(inputs) \u001b[39m==\u001b[39m \u001b[39m1\u001b[39m \u001b[39melse\u001b[39;00m inputs,\n\u001b[1;32m 79\u001b[0m clone\u001b[39m=\u001b[39mclone,\n\u001b[1;32m 80\u001b[0m detach\u001b[39m=\u001b[39mdetach,\n\u001b[1;32m 81\u001b[0m retain_grad\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m,\n\u001b[1;32m 82\u001b[0m ) \u001b[39m# retain_grad applies to output only.\u001b[39;00m\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/.venv/lib/python3.10/site-packages/baukit/nethook.py:471\u001b[0m, in \u001b[0;36minvoke_with_optional_args\u001b[0;34m(fn, *args, **kwargs)\u001b[0m\n\u001b[1;32m 469\u001b[0m \u001b[39mif\u001b[39;00m argspec\u001b[39m.\u001b[39mvarargs \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m 470\u001b[0m pass_args \u001b[39m+\u001b[39m\u001b[39m=\u001b[39m \u001b[39mlist\u001b[39m(args[used_pos:])\n\u001b[0;32m--> 471\u001b[0m \u001b[39mreturn\u001b[39;00m fn(\u001b[39m*\u001b[39;49mpass_args, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mpass_kw)\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/src/datasets/intervene.py:52\u001b[0m, in \u001b[0;36mintervention_meta_fn2\u001b[0;34m(outputs, layer_name, activations)\u001b[0m\n\u001b[1;32m 41\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"see\u001b[39;00m\n\u001b[1;32m 42\u001b[0m \u001b[39m- honest_llama: https://github.com/likenneth/honest_llama/blob/e010f82bfbeaa4326cef8493b0dd5b8b14c6da67/validation/validate_2fold.py#L114\u001b[39;00m\n\u001b[1;32m 43\u001b[0m \u001b[39m- baukit: https://github.com/davidbau/baukit/blob/main/baukit/nethook.py#L42C1-L45C56\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 48\u001b[0m \u001b[39m ...\u001b[39;00m\n\u001b[1;32m 49\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 50\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mtype\u001b[39m(outputs) \u001b[39mis\u001b[39;00m \u001b[39mtuple\u001b[39m:\n\u001b[1;32m 51\u001b[0m \u001b[39m# just edit the first one, and put it back in the tuple\u001b[39;00m\n\u001b[0;32m---> 52\u001b[0m output0 \u001b[39m=\u001b[39m intervene(outputs[\u001b[39m0\u001b[39;49m], activations[layer_name])\n\u001b[1;32m 53\u001b[0m \u001b[39mreturn\u001b[39;00m (output0, \u001b[39m*\u001b[39moutputs[\u001b[39m1\u001b[39m:])\n\u001b[1;32m 54\u001b[0m \u001b[39melif\u001b[39;00m \u001b[39mtype\u001b[39m(outputs) \u001b[39mis\u001b[39;00m torch\u001b[39m.\u001b[39mTensor:\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/src/datasets/intervene.py:33\u001b[0m, in \u001b[0;36mintervene\u001b[0;34m(output, activation)\u001b[0m\n\u001b[1;32m 30\u001b[0m \u001b[39m# assert torch.isfinite(output).all(), 'model output nan'\u001b[39;00m\n\u001b[1;32m 31\u001b[0m output2 \u001b[39m=\u001b[39m output \u001b[39m+\u001b[39m activation\u001b[39m.\u001b[39mto(output\u001b[39m.\u001b[39mdevice)[\u001b[39mNone\u001b[39;00m, :]\n\u001b[0;32m---> 33\u001b[0m output2 \u001b[39m=\u001b[39m project_onto_direction(output, activation)\n\u001b[1;32m 34\u001b[0m \u001b[39m# assert torch.isfinite(output2).all(), 'intervention lead to nan'\u001b[39;00m\n\u001b[1;32m 35\u001b[0m \u001b[39mreturn\u001b[39;00m output2\n", + "File \u001b[0;32m/media/wassname/SGIronWolf/projects5/elk/discovering_latent_knowledge/src/repe/rep_readers.py:15\u001b[0m, in \u001b[0;36mproject_onto_direction\u001b[0;34m(H, direction)\u001b[0m\n\u001b[1;32m 13\u001b[0m mag \u001b[39m=\u001b[39m torch\u001b[39m.\u001b[39mlinalg\u001b[39m.\u001b[39mnorm(direction)\u001b[39m.\u001b[39mto(H\u001b[39m.\u001b[39mdevice)\n\u001b[1;32m 14\u001b[0m \u001b[39massert\u001b[39;00m torch\u001b[39m.\u001b[39misfinite(mag)\n\u001b[0;32m---> 15\u001b[0m \u001b[39mreturn\u001b[39;00m H\u001b[39m.\u001b[39;49mdot(direction) \u001b[39m/\u001b[39m mag\n", + "\u001b[0;31mRuntimeError\u001b[0m: 1D tensors expected, but got 3D and 1D tensors" + ] + } + ], + "source": [ + "ds = ds_tokens.select(range(3)).to_iterable_dataset()\n", + "r1 = rep_control_pipeline2(model_inputs=ds,\n", + " activations=activations_neg_i,\n", + " batch_size=batch_size,)\n", + "r = list(r1)\n", + "o = r[0]\n", + "print_pipeline_r(o)\n" + ] + }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "honesty_rep_reader = create_cache_interventions(model, tokenizer, cfg)\n" + "ds = ds_tokens.select(range(3)).to_iterable_dataset()\n", + "r1 = rep_control_pipeline2(model_inputs=ds,\n", + " activations=activations,\n", + " batch_size=batch_size,)\n", + "r = list(r1)\n", + "print_pipeline_r(r[0])\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Generate\n" + "## Scratch choice ids\n" ] }, { @@ -232,6 +541,86 @@ "execution_count": null, "metadata": {}, "outputs": [], + "source": [ + "from src.datasets.scores import choice2id\n", + "\n", + "choice2id(tokenizer, 'Positive')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Generate long form with and without intervention" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# get a row\n", + "bi = 20\n", + "inputs = ds_tokens.with_format('torch')[bi]\n", + "\n", + "# tokenize if needed\n", + "if 'input_ids' not in inputs:\n", + " model_inputs = self.tokenizer(inputs['question'], return_tensors=True, return_attention_mask=True, add_special_tokens=True, truncation=True, padding=\"max_length\", max_length=cfg.max_length, **tokenize_kwargs)\n", + " inputs = {**inputs, **model_inputs}\n", + "\n", + "inputs.keys()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# generate\n", + "# https://huggingface.co/docs/transformers/v4.34.1/en/main_classes/text_generation#transformers.GenerationConfig\n", + "# model = exllama_set_max_input_length(model, 4096)\n", + "@torch.no_grad()\n", + "def gen(model):\n", + " s = model.generate(inputs['input_ids'][None, :], attention_mask=inputs['attention_mask'][None, :], use_cache=False, max_new_tokens=20, min_new_tokens=20, do_sample=False, early_stopping=False)\n", + " input_l = inputs['input_ids'].shape[0]\n", + " old = tokenizer.decode(s[0, :input_l], clean_up_tokenization_spaces=False, skip_special_tokens=False)\n", + " new = tokenizer.decode(s[0, input_l:], clean_up_tokenization_spaces=False, skip_special_tokens=False)\n", + " display(HTML(f\"
{old}
{new}
\"))\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "gen(model)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from baukit.nethook import Trace, TraceDict, recursive_copy\n", + "from functools import partial\n", + "from src.repe.rep_control_pipeline_baukit import intervention_meta_fn2, Activations\n", + "layers_names = [rep_control_pipeline2.layer_name_tmpl.format(i) for i in activations.keys()] \n", + "activations_pos_i = Activations({rep_control_pipeline2.layer_name_tmpl.format(k):1. * v for k,v in activations.items()})\n", + "edit_fn_pos = partial(intervention_meta_fn2, activations=activations_pos_i)\n", + "with torch.no_grad():\n", + " with TraceDict(\n", + " model, layers_names, detach=True, edit_output=edit_fn_pos\n", + " ) as ret:\n", + " gen(model)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, "source": [] } ], diff --git a/src/datasets/batch.py b/src/datasets/batch.py deleted file mode 100644 index 23632cd..0000000 --- a/src/datasets/batch.py +++ /dev/null @@ -1,68 +0,0 @@ - -# from tqdm.auto import tqdm -# import torch -# from torch.utils.data import DataLoader -# from datasets.arrow_dataset import Dataset -# import hashlib -# import pickle -# import numpy as np -# from typing import List, Dict, Any, Union, NewType, Optional - -# from src.datasets.hs import ExtractHiddenStates -# from src.helpers.typing import float_to_int16, int16_to_float -# from src.helpers.ds import ds_keep_cols, clear_mem -# from src.datasets.intervene import InterventionDict - - -# def batch_hidden_states(model, tokenizer, intervention_dicts: Optional[InterventionDict], data: Dataset, batch_size=2, layer_padding=3, layer_stride=4): -# """ -# Given an encoder-decoder model, a list of data, computes the contrast hidden states on n random examples. -# Returns numpy arrays of shape (n, hidden_dim) for each candidate label, along with a boolean numpy array of shape (n,) -# with the ground truth labels - -# This is deliberately simple so that it's easy to understand, rather than being optimized for efficiency -# """ -# ehs = ExtractHiddenStates(model, tokenizer, intervention_dicts=intervention_dicts, layer_stride=layer_stride, layer_padding=layer_padding) - -# torch_cols = ['input_ids', 'attention_mask', 'choice_ids'] -# ds_t_subset = ds_keep_cols(data, torch_cols) -# ds_t_subset.set_format(type='torch') - -# ds_p_subset = data.remove_columns(torch_cols) - -# dl = DataLoader(ds_t_subset, batch_size=batch_size, shuffle=False) -# for i, batch in enumerate(tqdm(dl, desc='get hidden states')): -# input_ids, attention_mask, choice_ids = batch["input_ids"], batch["attention_mask"], batch["choice_ids"] -# nn = len(input_ids) -# index = i*batch_size+np.arange(nn) - -# # different due to dropout -# hsl = ehs.get_batch_of_hidden_states(input_ids=input_ids, attention_mask=attention_mask, choice_ids=choice_ids) - -# for j in range(nn): -# # let's add the non torch metadata like label, prompt, lie, etc -# k = i*batch_size + j -# info = ds_p_subset[k] - -# large_arrays_keys = [k for k,v in hsl.items() if isinstance(v, torch.Tensor) and v.ndim>2] - -# # TODO deal with multiple lists of hs in hs0 -# large_arrays = {k:hsl[k][j] for k in large_arrays_keys} - -# yield dict( - -# # large_arrays_keys=large_arrays_keys, -# scores0=hsl["scores"][j], -# # layer_names=hsl["layers"][j] if k==0 else [], # just in the first one, to save space - -# ds_index=index[j], - -# # int16 makes our storage much smaller -# **large_arrays, - -# **info -# ) - -# info = large_arrays = hsl = None -# clear_mem() - diff --git a/src/datasets/hs.py b/src/datasets/hs.py deleted file mode 100644 index db21c4a..0000000 --- a/src/datasets/hs.py +++ /dev/null @@ -1,220 +0,0 @@ -# from dataclasses import dataclass -# import lightning as pl -# from loguru import logger -# from transformers import ( -# AutoTokenizer, -# AutoModelForSeq2SeqLM, -# AutoModelForMaskedLM, -# AutoModelForCausalLM, -# AutoConfig, -# AutoModel, -# PreTrainedTokenizer, -# PreTrainedModel -# ) -# from typing import Optional, List, Tuple, Dict, NewType -# from transformers import LogitsProcessorList -# import functools -# from src.helpers.torch import to_numpy -# from src.datasets.dropout import enable_dropout -# import re - -# from tqdm.auto import tqdm -# # from src.datasets.hs import ExtractHiddenStates -# from torch.utils.data import DataLoader -# from datasets import Dataset -# import numpy as np -# import torch -# import torch.nn.functional as F -# from baukit.nethook import Trace, TraceDict, recursive_copy -# from einops import rearrange, reduce, repeat -# from src.datasets.scores import choice2id, choice2ids -# from src.helpers.torch import clear_mem, detachcpu -# from collections import defaultdict -# from dataclasses import field -# from src.datasets.intervene import InterventionDict, intervention_meta_fn -# from functools import partial - - -# # def noise_for_embeds(inputs_embeds, seed=42, std = 2e-2): -# # B, S, embed_dim = inputs_embeds.shape -# # with torch.random.fork_rng(devices=[inputs_embeds.device.index]): -# # torch.manual_seed(seed) -# # noise = torch.normal(0., std, (embed_dim, )) -# # noise = repeat(noise, 't -> b s t', b=B, s=S).to(inputs_embeds.device).to(inputs_embeds.dtype) -# # return noise - -# def tcopy(x: torch.Tensor): -# return x.clone().detach().cpu() - -# def counterfactual_loss(model, scores, token_y, token_n): -# """do a backwards pass where the loss is the distance to the opposite scores""" -# eps = 1e-4 -# model.zero_grad() -# assert token_y.shape[1]<2, 'FIXME just use the first token for now' -# score_y = torch.index_select(scores, 1, token_y[:, 0]) -# score_n = torch.index_select(scores, 1, token_n[:, 0]) -# # this loss would be zero if the logits of the positive and negative tokens werre flipped -# loss = F.l1_loss(score_y, score_n) + F.l1_loss(score_n, score_y) -# return loss - - -# def stack_trace_returns(ret: TraceDict, names: List[str]) -> torch.Tensor: -# hs = [ret[h].output for h in names] -# hs = [h[0] if isinstance(h, tuple) else h for h in hs] # from a head it's a tuple -# return rearrange(hs, 'layers b s hs -> b layers s hs')[:, :, -1] - -# # def stack_trace_grad_returns(ret: TraceDict, names: List[str]) -> torch.Tensor: -# # hs = [ret[h].output.grad.detach() for h in names] -# # return rearrange(hs, 'layers b s hs -> b layers s hs')[:, :, -1] - -# # def select_weight_grads(weight_grads: Dict[str, torch.Tensor], pattern:str= ".+attn.c_proj.weight", mean_axis:int=1): -# # grads = [g.mean(mean_axis) for k,g in weight_grads.items() if re.match(pattern, k)] -# # assert len(grads), f"non of pattern='{pattern}' found in {weight_grads.keys()}" -# # return rearrange(grads, "lyrs b hs -> b lyrs hs") - - - -# @dataclass -# class ExtractHiddenStates: - -# model: PreTrainedModel -# tokenizer: PreTrainedTokenizer -# intervention_dicts: Optional[InterventionDict] = None -# layer_stride: int = 8 -# layer_padding: int = 3 - -# def get_layer_names(self): -# # for WizardLM/WizardCoder-3B-V1.0 -# # HEADS = [f"transformer.h.{i}.attn.c_proj" for i in range(self.model.config.num_hidden_layers)] -# # MLPS = [f"transformer.h.{i}.mlp" for i in range(self.model.config.num_hidden_layers)] - -# # for "WizardLM/WizardCoder-Python-13B-V1.0" -# # HACK: depends on model layout -# layers_names_h = [f"model.layers.{i}.self_attn" for i in range(self.model.config.num_hidden_layers)] -# layers_names_mlp = [f"model.layers.{i}.mlp" for i in range(self.model.config.num_hidden_layers)] -# return self.get_layer_selection(layers_names_h) + self.get_layer_selection(layers_names_mlp) - - -# def get_batch_of_hidden_states( -# self, -# input_text: Optional[List[str]] = None, -# input_ids: torch.Tensor = None, -# attention_mask: Optional[torch.Tensor] = None, -# choice_ids: List[torch.Tensor] = None, -# truncation_length=999, -# debug=False, -# ): -# """ -# Given a decoder model and a batch of texts, gets a pair of hidden states (in a given layer) on that input texts - -# The idea is this: given two pairs of hidden states, where everything is the same except r dropout. Then tell me which one is more truthful? -# """ -# assert (input_ids is not None) or (input_text is not None), "need to provide input_ids or input_text" -# assert self.tokenizer.truncation_side == 'left' - -# if input_text: -# raise NotImplementedError("FIXME") -# t = self.tokenizer( -# input_text, -# return_tensors="pt", -# add_special_tokens=True, -# padding='max_length', max_length=truncation_length, truncation=True, return_attention_mask=True, -# ) -# input_ids = t.input_ids.to(self.model.device) -# attention_mask = t.attention_mask.to(self.model.device) -# else: -# input_ids = input_ids.to(self.model.device) -# attention_mask = attention_mask.to(self.model.device) -# choice_ids = choice_ids.to(self.model.device) - -# # forward pass -# last_token = -1 - -# layers_names = self.get_layer_names() - -# self.model.eval() - - -# if self.intervention_dicts is not None: -# # extraction mode -# # 15 is a magic number from honest_llama -# intervention_fn1 = partial(intervention_meta_fn, interventions=self.intervention_dicts, alpha=-15) -# intervention_fn2 = partial(intervention_meta_fn, interventions=self.intervention_dicts, alpha=15) -# edit_outputs = [intervention_fn1, intervention_fn2] -# else: -# # calibration mode -# edit_outputs = [None] - -# with torch.no_grad(): -# multi_outs = defaultdict(list) -# for edit_output in edit_outputs: -# with TraceDict(self.model, layers_names, retain_grad=False, detach=True, edit_output=edit_output) as ret: -# model_inputs = self.model.prepare_inputs_for_generation(input_ids=input_ids, attention_mask=attention_mask, use_cache=False) -# outputs = self.model.forward( -# **model_inputs, -# return_dict=True, -# output_hidden_states=True, -# ) -# outputs["scores"] = outputs.logits[:, last_token, :].float() - -# # stack -# hidden_states = list(outputs.hidden_states) -# hidden_states = rearrange(hidden_states, 'lyrs b seq hs -> b lyrs seq hs')[:, :, last_token] -# ## from ret, we get the layer activation and the grads on them -# head_activation = tcopy(stack_trace_returns(ret, layers_names)) -# # mlp_activation = tcopy(stack_trace_returns(ret, MLPS)) - -# # collect outputs -# multi_outs['scores'].append(outputs["scores"]) -# # multi_outs['hidden_states'].append(hidden_states) -# multi_outs['head_activation'].append(head_activation) -# # multi_outs['mlp_activation'].append(mlp_activation) - -# # stack -# multi_outs['scores'] = torch.stack(multi_outs['scores'], -1) -# # multi_outs['mlp_activation'] = torch.stack(multi_outs['mlp_activation'], -1) -# multi_outs['head_activation'] = torch.stack(multi_outs['head_activation'], -1) - -# # combine -# out_common = dict(input_ids=input_ids, attention_mask=attention_mask, layers=layers_names,) -# if debug: -# out_common['input_truncated'] = self.tokenizer.batch_decode(input_ids) -# out_common['text_ans'] = self.tokenizer.batch_decode(outputs["scores"].softmax(-1).argmax(-1)) - -# out = {**multi_outs, **out_common} - -# # detach -# out = {k: detachcpu(v) for k, v in out.items()} - - -# # I shouldn't have to do this but I get memory leaks -# outputs = hidden_states = hidden_states2 = loss = orig_state_dict = scores = token_y = token_n = input_ids = attention_mask = choice_ids = residual_stream = residual_stream2 = None -# clear_mem() -# return out - - - -# def get_layer_selection(self, layer_names): -# """Sometimes we don't want to save all layers. - -# We skip the first few (data leakage?). Stride the the middle (could be valuable), and include the last few (possibly high level concepts). - -# See also https://www.lesswrong.com/posts/bWxNPMy5MhPnQTzKz/what-discovering-latent-knowledge-did-and-did-not-find-4 -# """ -# module_names = [k for k,v in self.model.named_modules()] -# layers_not_found = set(layer_names)-set(module_names) -# assert len(layers_not_found)==0, f"some layers not found in model: {layers_not_found}. we have {layer_names}" - -# # for self.layer_padding, skip the first few -# num_layers = len(layer_names)-1 -# strided_layers = torch.arange( -# self.layer_padding, -# num_layers-self.layer_padding, -# self.layer_stride, -# ).tolist() -# # for self.layer_padding ALWAYS include the last few. Why, this is based on the intuition that the last layers may be the most valuable -# last_few = torch.arange(num_layers-self.layer_padding, num_layers).tolist() -# layers_inds = sorted(set(list(strided_layers)+list(last_few))) -# return [layer_names[i] for i in layers_inds] - - diff --git a/src/datasets/intervene.py b/src/datasets/intervene.py index 7233638..1314d9b 100644 --- a/src/datasets/intervene.py +++ b/src/datasets/intervene.py @@ -13,6 +13,7 @@ from src.config import root_folder from src.prompts.prompt_loading import load_preproc_dataset from transformers import AutoTokenizer, pipeline, Pipeline from loguru import logger +from src.repe.rep_readers import project_onto_direction Activations = NewType("Activations", Dict[str, torch.Tensor]) @@ -28,6 +29,8 @@ def intervene(output, activation): ), f"expected output to be (batch, seq, vocab), got {output.shape}" # assert torch.isfinite(output).all(), 'model output nan' output2 = output + activation.to(output.device)[None, :] + + output2 = project_onto_direction(output, activation) # assert torch.isfinite(output2).all(), 'intervention lead to nan' return output2 diff --git a/src/datasets/scores.py b/src/datasets/scores.py index 3f38ad5..abfa37b 100644 --- a/src/datasets/scores.py +++ b/src/datasets/scores.py @@ -53,11 +53,10 @@ def choice2id(tokenizer, c: str, whitespace_first=False) -> List[int]: ids2 += tokenizer(f'{c}', add_special_tokens=False)["input_ids"] ids = list(set(ids2)) - print(ids2) - print(ids) - print([f'`{t}`' for t in tokenizer.batch_decode(ids, skip_special_tokens=True)]) - print([c.strip().startswith(tokenizer.decode(i)) for i in ids]) - + # print(ids2) + # print(ids) + # print([f'`{t}`' for t in tokenizer.batch_decode(ids, skip_special_tokens=True)]) + # print([c.strip().startswith(tokenizer.decode(i)) for i in ids]) # only include ones that decode to our original ids = [i for i in ids if c.strip().startswith(tokenizer.decode(i).strip()) and len(tokenizer.decode(i).strip())] diff --git a/src/repe/rep_readers.py b/src/repe/rep_readers.py index f91cbab..a9e0894 100644 --- a/src/repe/rep_readers.py +++ b/src/repe/rep_readers.py @@ -3,13 +3,16 @@ from sklearn.decomposition import PCA from sklearn.cluster import KMeans import numpy as np from itertools import islice +import torch ### Util Functions ### def project_onto_direction(H, direction): """Project matrix H (n, d_1) onto direction vector (d_2,)""" # TODO: should we require direction vectors to be unit vectors? then return H.dot(direction) - mag = np.linalg.norm(direction) - assert not np.isinf(mag) + direction = direction.to(H.device).squeeze(0) + mag = torch.linalg.norm(direction).to(H.device) + assert torch.isfinite(mag) + return (H[0] @ direction[:, None] # check that the dimensions match return H.dot(direction) / mag def recenter_mean(x, mean=None):