From f5594583b9c09de6b8ca2ceb2ffaf2c4fc93b6ff Mon Sep 17 00:00:00 2001 From: mivanit Date: Mon, 4 Sep 2023 21:15:38 -0600 Subject: [PATCH] direct logit attribution logit diff wip i have no idea why, but the scaling is wrong. The relationship is clearly linear, but its different depending on whether it's diff to all other tokens or some random set of tokens --- notebooks/direct_logit_attribution.ipynb | 269 ++++++++++++++++------- 1 file changed, 187 insertions(+), 82 deletions(-) diff --git a/notebooks/direct_logit_attribution.ipynb b/notebooks/direct_logit_attribution.ipynb index b98d5655..44b4b17b 100644 --- a/notebooks/direct_logit_attribution.ipynb +++ b/notebooks/direct_logit_attribution.ipynb @@ -40,7 +40,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 106, "metadata": { "pycharm": { "name": "#%%\n" @@ -57,6 +57,7 @@ "# Numerical Computing\n", "import numpy as np\n", "import torch\n", + "import pandas as pd\n", "# import torch.nn.functional as F\n", "from fancy_einsum import einsum\n", "import einops\n", @@ -81,7 +82,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 2, "metadata": { "pycharm": { "name": "#%%\n" @@ -98,10 +99,10 @@ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 6, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -129,7 +130,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -164,7 +165,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 4, "metadata": { "pycharm": { "name": "#%%\n" @@ -211,7 +212,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -249,7 +250,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -293,7 +294,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -305,7 +306,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -340,7 +341,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -358,7 +359,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -379,7 +380,7 @@ " ))" ] }, - "execution_count": 15, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -395,7 +396,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -417,7 +418,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -449,7 +450,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 100, "metadata": {}, "outputs": [], "source": [ @@ -457,15 +458,25 @@ "def logits_to_avg_logit_diff(\n", " final_logits: Float[torch.Tensor, \"n_mazes d_vocab\"],\n", " answer_tokens: Int[torch.Tensor, \"n_mazes\"],\n", + " compare_to: Int[torch.Tensor, \"n_mazes\"]|None = None,\n", " per_prompt: bool = True,\n", " ) -> Float[torch.Tensor, \"n_mazes\"]|float:\n", "\n", " # logit on the answer token for each sample\n", " answer_logits: Float[torch.Tensor, \"n_mazes\"] = torch.gather(final_logits, 1, answer_tokens.unsqueeze(1)).squeeze(1)\n", - " # logits of all tokens for each sample\n", - " all_logits: Float[torch.Tensor, \"n_mazes\"] = torch.sum(final_logits, dim=1)\n", + " \n", + " output: Float[torch.Tensor, \"n_mazes\"]\n", + " if compare_to is None:\n", + " # logits of all tokens for each sample\n", + " all_logits: Float[torch.Tensor, \"n_mazes\"] = torch.sum(final_logits, dim=1)\n", + " output = answer_logits - (all_logits - answer_logits)\n", + " else:\n", + " # specifically the comparison tokens\n", + " compare_to_logits: Float[torch.Tensor, \"n_mazes\"] = torch.gather(final_logits, 1, compare_to.unsqueeze(1)).squeeze(1)\n", + " output = answer_logits - compare_to_logits\n", + "\n", + " assert output.shape == answer_tokens.shape\n", "\n", - " output: Float[torch.Tensor, \"n_mazes\"] = answer_logits - (all_logits - answer_logits)\n", " if per_prompt:\n", " return output\n", " else:\n", @@ -476,96 +487,169 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 101, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "avg logit diff of target: 31.570226669311523\n", - "avg logit diff of predicted: 31.570226669311523\n", - "avg logit diff of sampled: 31.570226669311523\n", - "avg logit diff of random: 0.02409425750374794\n" - ] - } - ], + "outputs": [], "source": [ + "def logit_diff_residual_stream(\n", + "\tmodel: ZanjHookedTransformer,\n", + "\tcache: ActivationCache,\n", + "\tanswer_tokens: Int[torch.Tensor, \"n_mazes\"],\n", + "\tcompare_to: Int[torch.Tensor, \"n_mazes\"]|None = None,\n", + ") -> dict:\n", + "\t# embed the whole vocab first\n", + "\td_vocab: int = model.zanj_model_config.maze_tokenizer.vocab_size\n", + "\tvocab_tensor: Float[torch.Tensor, \"d_vocab\"] = torch.arange(d_vocab, dtype=torch.long)\n", + "\tvocab_residual_directions = model.tokens_to_residual_directions(vocab_tensor)\n", + "\t# get embedding of answer tokens\n", + "\tanswer_residual_directions = vocab_residual_directions[answer_tokens]\n", + "\t# get the directional difference\n", + "\tlogit_diff_directions: Float[torch.Tensor, \"n_mazes d_model\"]\n", + "\tif compare_to is None:\n", + "\t\tlogit_diff_directions = answer_residual_directions - vocab_residual_directions[~answer_tokens]\n", + "\telse:\n", + "\t\tlogit_diff_directions = answer_residual_directions - vocab_residual_directions[compare_to]\n", + "\n", "\n", - "for k, d in {\n", - " \"target\": DATASET_TARGET_IDS, \n", - " \"predicted\": LAST_TOK_LOGITS.argmax(dim=-1), \n", - " \"sampled\": torch.multinomial(torch.softmax(LAST_TOK_LOGITS, dim=-1), num_samples=1).squeeze(-1),\n", - " \"random\": torch.randint_like(DATASET_TARGET_IDS, low=0, high=d_vocab),\n", - "}.items():\n", - "\tresult: float = logits_to_avg_logit_diff(\n", - "\t\tfinal_logits=LAST_TOK_LOGITS, \n", - "\t\tanswer_tokens=d,\n", - "\t\tper_prompt=False,\n", + "\t# get the values from the cache at the last layer and last token\n", + "\tfinal_token_residual_stream = cache[\"resid_post\", -1][:, -1, :]\n", + "\t# scaling the values in residual stream with layer norm\n", + "\tscaled_final_token_residual_stream = cache.apply_ln_to_stack(\n", + "\t\tfinal_token_residual_stream, layer = -1, pos_slice=-1,\n", "\t)\n", - "\tprint(f\"avg logit diff of {k}: {result}\")" + "\n", + "\n", + "\taverage_logit_diff = torch.dot(\n", + "\t\tscaled_final_token_residual_stream.flatten(),\n", + "\t\tlogit_diff_directions.flatten(),\n", + "\t) / logit_diff_directions.shape[0]\n", + "\n", + "\treturn average_logit_diff.item()\n", + "\n" ] }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 142, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "vocab_residual_directions.shape = torch.Size([75, 128])\n", - "answer_residual_directions.shape = torch.Size([100, 128])\n", - "logit_diff_directions.shape = torch.Size([100, 128])\n" + " test compare_to result_orig result_res diff \\\n", + "0 target all 31.570227 13.288536 18.281691 \n", + "1 predicted all 31.570227 13.288536 18.281691 \n", + "2 sampled all 31.570227 13.288536 18.281691 \n", + "3 noise=1.0 all 31.570227 13.288536 18.281691 \n", + "4 noise=1.0722672220103233 all 31.570227 13.288536 18.281691 \n", + ".. ... ... ... ... ... \n", + "203 noise=811.1308307896873 random 0.325303 0.350737 -0.025433 \n", + "204 noise=869.7490026177834 random 1.277788 1.303297 -0.025508 \n", + "205 noise=932.60334688322 random 0.080973 0.156748 -0.075774 \n", + "206 noise=1000.0 random 0.775237 0.807143 -0.031906 \n", + "207 random random 0.230697 0.403727 -0.173030 \n", + "\n", + " ratio \n", + "0 2.375749 \n", + "1 2.375749 \n", + "2 2.375749 \n", + "3 2.375749 \n", + "4 2.375749 \n", + ".. ... \n", + "203 0.927486 \n", + "204 0.980428 \n", + "205 0.516585 \n", + "206 0.960470 \n", + "207 0.571418 \n", + "\n", + "[208 rows x 6 columns]\n" ] + }, + { + "data": { + "image/png": "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fv31VxQUFCAjIwPR0dHo1q2b2jHNmjXDZ599huzsbBQWFmLr1q1wc3OzUMTmoc/rEhMTo3GtrF271kIR17/p06cjPj4e+fn5yM/Px88//4zRo0er7m+o1wmTGTOaPHkyli9fjvfeew++vr6Ij4/Hvn374OrqaunQLObChQto166danv00UctHZJZOTo6Ij4+Hq+99prW+9955x28+eabmD59Oh5++GEUFxdj3759aNasmZkjNa/aXhcA2LNnj9q18/TTT5sxQvMKCAjA6tWr8cgjj2DEiBFo2rQp9u/fDwcHB9UxEREReOKJJzBp0iQEBASgffv22LZtmwWjrn/6vC4A8MUXX6hdK++8846FIq5/KSkpmDt3Lvr164f+/fvj8OHD2LFjB3r27AmgYV8ngpt5tl9++UWsWrVKdVuhUIiUlBQxZ84ci8dmiW3hwoXizJkzFo/DWjYhhBg7dqzavlu3bonZs2erbjs7O4vS0lLx1FNPWTxeS74ukZGRIjo62uKxWWpr27atEEIIf39/1XVRVlYmJkyYoDqme/fuQgghHn74YYvHa6nXBYCIiYkRERERFo/Nktvt27fFiy++2KCvE7bMmEnTpk3Rr18/HDx4ULVPCIGDBw/Cz8/PgpFZ1gMPPIDU1FQkJCTg//7v/9ChQwdLh2Q1unTpAg8PD7VrpqCgACdOnGjU14zSkCFDkJGRgcuXL2PNmjVo3bq1pUMyGxcXFwBATk4OAKBfv36wt7dXu1auXLmCGzduNKprpfrrovTss88iKysL58+fx+LFi3HfffdZIjyzkyQJTz31FBwdHXH8+PEGfZ00ioUmrUHbtm1hZ2eHjIwMtf0ZGRno0aOHhaKyrBMnTmDq1Km4cuUKPDw8sHDhQsTFxaFXr14oKiqydHgW165dOwDQes0o72us9u7di23btiEpKQne3t5YvHgx9uzZAz8/P8iybOnw6pVCocCKFStw9OhR/P777wDuXStlZWXIz89XO7YxXSvaXhcA+Pbbb3Hjxg3cunULf/vb37B06VJ0794dEyZMsGC09atXr144fvw4mjdvjqKiIgQFBeHSpUvo06dPg71OmMyQxezdu1f18/nz53HixAncuHEDkydPxtdff23ByMjaff/996qfL1y4gHPnziExMRFDhgzB4cOHLRhZ/Vu9ejV69erV6MaX1UbX67J+/XrV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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ - "def logit_diff_residual_stream(\n", + "def logits_diff(\n", "\tmodel: ZanjHookedTransformer,\n", "\tcache: ActivationCache,\n", - "\tanswer_tokens: Int[torch.Tensor, \"n_mazes\"],\n", - ") -> dict:\n", - "\t# embed the whole vocab first\n", - "\tvocab_tensor: Float[torch.Tensor, \"d_vocab\"] = torch.arange(model.zanj_model_config.maze_tokenizer.vocab_size, dtype=torch.long)\n", - "\tvocab_residual_directions = model.tokens_to_residual_directions(vocab_tensor)\n", - "\t# get embedding of answer tokens\n", - "\tanswer_residual_directions = vocab_residual_directions[answer_tokens]\n", + "\tdataset_target_ids: Int[torch.Tensor, \"n_mazes\"],\n", + "\tlast_tok_logits: Float[torch.Tensor, \"n_mazes d_vocab\"],\n", + "\tnoise_sigmas: list[float] = [1, 2, 3, 5, 10],\n", + ") -> pd.DataFrame:\n", + "\t\n", + "\ttest_logits: dict[str, Float[torch.Tensor, \"n_mazes\"]] = {\n", + "\t\t\"target\": dataset_target_ids, \n", + "\t\t\"predicted\": last_tok_logits.argmax(dim=-1), \n", + "\t\t\"sampled\": torch.multinomial(torch.softmax(last_tok_logits, dim=-1), num_samples=1).squeeze(-1),\n", + "\t\t**{\n", + "\t\t\tf\"noise={s}\": (last_tok_logits + s*torch.randn_like(last_tok_logits)).argmax(dim=-1)\n", + "\t\t\tfor s in noise_sigmas\n", + "\t\t},\n", + "\t\t\"random\": torch.randint_like(dataset_target_ids, low=0, high=d_vocab),\n", + "\t}\n", + "\tcompare_rand: Float[torch.Tensor, \"n_mazes\"] = torch.randint_like(dataset_target_ids, low=0, high=d_vocab)\n", "\n", - "\t# get the difference in direction between the answer token and the rest of the vocab\t\n", - "\t# for i in range(len(answer_tokens)):\n", - "\t# \t_temp = answer_residual_directions[i] - vocab_residual_directions[~answer_tokens[i]]\n", - "\t# \tprint(f\"{_temp.shape = }\")\n", + "\toutputs: list[dict] = list()\n", "\n", - "\t# logit_diff_directions = torch.cat(\n", - "\t# \t[\n", - "\t# \t\tanswer_residual_directions[i] - vocab_residual_directions[~answer_tokens[i]]\n", - "\t# \t\tfor i in range(len(answer_tokens))\n", - "\t# \t],\n", - "\t# \tdim=-1,\n", - "\t# )\n", - "\tlogit_diff_directions = answer_residual_directions - vocab_residual_directions[~answer_tokens]\n", + "\tfor compare_to in [None, compare_rand]:\n", + "\t\tfor k, d in test_logits.items():\n", + "\t\t\tresult_orig: float = logits_to_avg_logit_diff(\n", + "\t\t\t\tfinal_logits=last_tok_logits, \n", + "\t\t\t\tanswer_tokens=d,\n", + "\t\t\t\tper_prompt=False,\n", + "\t\t\t\tcompare_to=compare_to,\n", + "\t\t\t)\n", + "\t\t\tresult_res: float = logit_diff_residual_stream(\n", + "\t\t\t\tmodel=model,\n", + "\t\t\t\tcache=cache,\n", + "\t\t\t\tanswer_tokens=d,\n", + "\t\t\t\tcompare_to=compare_to,\n", + "\t\t\t)\n", + "\t\t\t# print(f\"logit diff of {k}\\tcompare:\\t{'all' if compare_to is None else 'random'}\\t{result = }\\t{result_res = }\")\n", + "\t\t\toutputs.append(dict(\n", + "\t\t\t\ttest=k,\n", + "\t\t\t\tcompare_to=\"all\" if compare_to is None else \"random\",\n", + "\t\t\t\tresult_orig=result_orig,\n", + "\t\t\t\tresult_res=result_res,\n", + "\t\t\t))\n", "\n", - "\tprint(f\"{vocab_residual_directions.shape = }\")\n", - "\tprint(f\"{answer_residual_directions.shape = }\")\n", - "\tprint(f\"{logit_diff_directions.shape = }\")\n", + "\tdf_out: pd.DataFrame = pd.DataFrame(outputs)\n", + "\tdf_out[\"diff\"] = df_out[\"result_orig\"] - df_out[\"result_res\"]\n", + "\tdf_out[\"ratio\"] = df_out[\"result_orig\"] / df_out[\"result_res\"]\n", "\n", - "\t# get the values from the cache at the last layer and last token\n", - "\tfinal_token_residual_stream = cache[\"resid_post\", -1][:, -1, :]\n", - "\t# scaling the values in residual stream with layer norm\n", - "\tscaled_final_token_residual_stream = cache.apply_ln_to_stack(\n", - "\t\tfinal_token_residual_stream, layer = -1, pos_slice=-1,\n", - "\t)\n", "\n", - "\taverage_logit_diff = einsum(\n", - "\t\t\"batch d_model, batch d_model -> \", \n", - "\t\tscaled_final_token_residual_stream, \n", - "\t\tlogit_diff_directions,\n", - "\t) / len(answer_tokens)\n", + "\treturn df_out\n", + "\n", + "LOGIT_DIFF_DF: pd.DataFrame = logits_diff(\n", + "\tmodel=MODEL,\n", + "\tcache=CACHE,\n", + "\tdataset_target_ids=DATASET_TARGET_IDS,\n", + "\tlast_tok_logits=LAST_TOK_LOGITS,\n", + "\tnoise_sigmas=np.logspace(0, 3, 100),\n", + ")\n", "\n", + "print(LOGIT_DIFF_DF)\n", "\n", - "logit_diff_residual_stream(MODEL, CACHE, DATASET_TARGET_IDS)" + "# plt.scatter(LOGIT_DIFF_DF['result_orig'], LOGIT_DIFF_DF['result_res'])\n", + "# scatter separately for \"all\" vs \"random\"\n", + "fig, ax = plt.subplots()\n", + "for compare_to in [\"all\", \"random\"]:\n", + "\tdf = LOGIT_DIFF_DF[LOGIT_DIFF_DF[\"compare_to\"] == compare_to]\n", + "\tax.scatter(df['result_orig'], df['result_res'], label=compare_to)\n", + "ax.legend()\n", + "plt.xlabel('result_orig')\n", + "plt.ylabel('result_res')\n", + "plt.title('Scatter Plot between result_orig and result_res')\n", + "plt.show()\n" ] }, { @@ -573,6 +657,27 @@ "execution_count": null, "metadata": {}, "outputs": [], + "source": [ + "# linear " + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "ename": "TypeError", + "evalue": "HookedTransformer.__init__() missing 1 required positional argument: 'cfg'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[16], line 3\u001b[0m\n\u001b[0;32m 1\u001b[0m answer_residual_directions \u001b[39m=\u001b[39m MODEL\n\u001b[0;32m 2\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39mtransformer_lens\u001b[39;00m \u001b[39mimport\u001b[39;00m HookedTransformer\n\u001b[1;32m----> 3\u001b[0m HookedTransformer()\u001b[39m.\u001b[39mtokens_to_residual_directions()\n", + "\u001b[1;31mTypeError\u001b[0m: HookedTransformer.__init__() missing 1 required positional argument: 'cfg'" + ] + } + ], "source": [ "answer_residual_directions = MODEL\n", "from transformer_lens import HookedTransformer\n",