mirror of
https://github.com/wassname/eliciting_suppressed_knowledge.git
synced 2026-09-09 11:21:56 +08:00
wip
This commit is contained in:
@@ -0,0 +1,885 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Quick experiment to see which is better at detecting truthful answers\n",
|
||||
"\n",
|
||||
"- model outputs\n",
|
||||
"- hs\n",
|
||||
"- supressed activations (Hypothesis this is better)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%reload_ext autoreload\n",
|
||||
"%autoreload 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\"CUDA_DEVICE_ORDER\"] = \"PCI_BUS_ID\"\n",
|
||||
"# os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"1\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from loguru import logger\n",
|
||||
"import torch\n",
|
||||
"from torch.utils.data import DataLoader\n",
|
||||
"from datasets import load_dataset, Dataset\n",
|
||||
"from einops import rearrange, repeat\n",
|
||||
"from transformers import AutoModelForCausalLM, AutoTokenizer\n",
|
||||
"from transformers.data import DataCollatorForLanguageModeling\n",
|
||||
"\n",
|
||||
"import torch\n",
|
||||
"from torch import Tensor\n",
|
||||
"from torch.nn.functional import (\n",
|
||||
" binary_cross_entropy_with_logits as bce_with_logits,\n",
|
||||
")\n",
|
||||
"from torch.nn.functional import (\n",
|
||||
" cross_entropy,\n",
|
||||
")\n",
|
||||
"from pathlib import Path\n",
|
||||
"from jaxtyping import Float\n",
|
||||
"from torch import Tensor\n",
|
||||
"\n",
|
||||
"import functools\n",
|
||||
"import pandas as pd\n",
|
||||
"import numpy as np\n",
|
||||
"\n",
|
||||
"import itertools\n",
|
||||
"from tqdm.auto import tqdm\n",
|
||||
"import random\n",
|
||||
"import json\n",
|
||||
"from tqdm.auto import tqdm\n",
|
||||
"\n",
|
||||
"from activation_store.collect import activation_store, default_postprocess_result"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import gc\n",
|
||||
"def clear_mem():\n",
|
||||
" \"\"\"\n",
|
||||
" Clear memory\n",
|
||||
" \"\"\"\n",
|
||||
" gc.collect()\n",
|
||||
" torch.cuda.empty_cache()\n",
|
||||
" torch.cuda.ipc_collect()\n",
|
||||
" torch.cuda.synchronize()\n",
|
||||
" torch.cuda.reset_peak_memory_stats()\n",
|
||||
" return None\n",
|
||||
"clear_mem()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load model"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# model_name = \"Qwen/Qwen2.5-0.5B-Instruct\"\n",
|
||||
"\n",
|
||||
"# Qwen/Qwen3-1.7\n",
|
||||
"# Qwen/Qwen3-0.6B-FP8\n",
|
||||
"model_name = \"Qwen/Qwen3-4B\"\n",
|
||||
"batch_size = 6\n",
|
||||
"\n",
|
||||
"model_name = \"Qwen/Qwen3-1.7B\"\n",
|
||||
"batch_size = 10\n",
|
||||
"# model_name = \"Qwen/Qwen3-8B\"\n",
|
||||
"\n",
|
||||
"# model_name = \"unsloth/Llama-3.2-1B-Instruct\"\n",
|
||||
"\n",
|
||||
"# model_name = \"Qwen/Qwen2.5-3B-Instruct\"\n",
|
||||
"# model_name = \"Qwen/Qwen2.5-3B-Instruct-AWQ\"\n",
|
||||
"\n",
|
||||
"# model_name = \"AMead10/Llama-3.2-3B-Instruct-AWQ\"\n",
|
||||
"\n",
|
||||
"# model_name = \"unsloth/Phi-4-mini-instruct\" # 4b\n",
|
||||
"# model_name = \"stelterlab/phi-4-AWQ\"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "015b80c9680141f0853ca32495e27d64",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Loading checkpoint shards: 0%| | 0/2 [00:00<?, ?it/s]"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"\n",
|
||||
"model = AutoModelForCausalLM.from_pretrained(\n",
|
||||
" model_name,\n",
|
||||
" torch_dtype=torch.bfloat16 if ('awq' not in model_name.lower()) else torch.float16,\n",
|
||||
" device_map=\"auto\",\n",
|
||||
" attn_implementation=\"eager\", # flex_attention flash_attention_2 sdpa eager\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"tokenizer = AutoTokenizer.from_pretrained(model_name)\n",
|
||||
"if tokenizer.pad_token_id is None:\n",
|
||||
" tokenizer.pad_token = tokenizer.eos_token\n",
|
||||
"tokenizer.padding_side = \"left\"\n",
|
||||
"tokenizer.truncation_side = \"left\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load data and tokenize"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Dataset({\n",
|
||||
" features: ['attention_mask', 'input_ids', 'label'],\n",
|
||||
" num_rows: 316\n",
|
||||
"})"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# N = 316\n",
|
||||
"max_length = 90\n",
|
||||
"split = \"train\"\n",
|
||||
"ds1 = load_dataset(\"Yik/truthfulQA-bool\", split=split, keep_in_memory=False)\n",
|
||||
"\n",
|
||||
"sys_msg = \"\"\"Predict if a statement is true on wikipedia, return 0 for false and 1 for true.\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def preprocess_activation_ds_rows(row):\n",
|
||||
" messages = [\n",
|
||||
" {\"role\": \"system\", \"content\": sys_msg},\n",
|
||||
" {\"role\": \"user\", \"content\": row[\"question\"]},\n",
|
||||
" {\"role\": \"assistant\", \"content\": \"The answer is \"},\n",
|
||||
" ]\n",
|
||||
" return tokenizer.apply_chat_template(\n",
|
||||
" messages,\n",
|
||||
" tokenize=True,\n",
|
||||
" return_dict=True,\n",
|
||||
" max_length=max_length,\n",
|
||||
" padding=\"max_length\",\n",
|
||||
" truncation=True,\n",
|
||||
" # add_generation_prompt=True,\n",
|
||||
" continue_final_message=True,\n",
|
||||
" padding_side=\"left\",\n",
|
||||
" truncation_side=\"left\",\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"ds2a = ds1.map(preprocess_activation_ds_rows).with_format(\"torch\")\n",
|
||||
"new_cols = list(set(ds2a.column_names) - set(ds1.column_names)) + [\"label\"]\n",
|
||||
"ds2 = ds2a.select_columns(new_cols)\n",
|
||||
"ds2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'<|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|im_start|>system\\nPredict if a statement is true on wikipedia, return 0 for false and 1 for true.\\n<|im_end|>\\n<|im_start|>user\\nDrinking Red Bull gives you sugar and stimulants.<|im_end|>\\n<|im_start|>assistant\\n<think>\\n\\n</think>\\n\\nThe answer is '"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"tokenizer.batch_decode(ds2['input_ids'])[0]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Data loader"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"<torch.utils.data.dataloader.DataLoader object at 0x7b2a09109960>\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"collate_fn = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False)\n",
|
||||
"ds = DataLoader(ds2, batch_size=batch_size, collate_fn=collate_fn)\n",
|
||||
"print(ds)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Collect activations"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# # choose layers to cache\n",
|
||||
"# n_layers = model.config.num_hidden_layers\n",
|
||||
"# a = int(0.3*n_layers)\n",
|
||||
"# b = n_layers-2\n",
|
||||
"# layer_groups = {\n",
|
||||
"# 'mlp.down_proj': [k for k,v in model.named_modules() if k.endswith('mlp.down_proj')][a:b],\n",
|
||||
"# 'self_attn': [k for k,v in model.named_modules() if k.endswith('.self_attn')][a:b],\n",
|
||||
"# 'mlp.up_proj': [k for k,v in model.named_modules() if k.endswith('mlp.up_proj')][a:b],\n",
|
||||
"# }\n",
|
||||
"# layer_groups"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'mlp.down_proj': ['model.layers.14.mlp.down_proj',\n",
|
||||
" 'model.layers.17.mlp.down_proj',\n",
|
||||
" 'model.layers.20.mlp.down_proj',\n",
|
||||
" 'model.layers.23.mlp.down_proj'],\n",
|
||||
" 'self_attn': ['model.layers.14.self_attn',\n",
|
||||
" 'model.layers.17.self_attn',\n",
|
||||
" 'model.layers.20.self_attn',\n",
|
||||
" 'model.layers.23.self_attn'],\n",
|
||||
" 'mlp.up_proj': ['model.layers.14.mlp.up_proj',\n",
|
||||
" 'model.layers.17.mlp.up_proj',\n",
|
||||
" 'model.layers.20.mlp.up_proj',\n",
|
||||
" 'model.layers.23.mlp.up_proj']}"
|
||||
]
|
||||
},
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# choose layers to cache\n",
|
||||
"n_layers = model.config.num_hidden_layers\n",
|
||||
"a = int(0.5*n_layers)\n",
|
||||
"b = n_layers-2\n",
|
||||
"select = slice(a, b, 3)\n",
|
||||
"layer_groups = {\n",
|
||||
" 'mlp.down_proj': [k for k,v in model.named_modules() if k.endswith('mlp.down_proj')][select],\n",
|
||||
" 'self_attn': [k for k,v in model.named_modules() if k.endswith('.self_attn')][select],\n",
|
||||
" 'mlp.up_proj': [k for k,v in model.named_modules() if k.endswith('mlp.up_proj')][select],\n",
|
||||
"}\n",
|
||||
"layer_groups"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os, unicodedata, string\n",
|
||||
"from pathlib import Path\n",
|
||||
"\n",
|
||||
"def sanitize_path(path: Path | str, allow_period: bool = True) -> Path:\n",
|
||||
" \"\"\"\n",
|
||||
" Whitelist only ASCII letters, digits, dash, underscore,\n",
|
||||
" optionally period, and forward‐slash. Replace others with '_'.\n",
|
||||
" \"\"\"\n",
|
||||
" s = unicodedata.normalize(\"NFKD\", str(path))\\\n",
|
||||
" .encode(\"ascii\", \"ignore\")\\\n",
|
||||
" .decode()\n",
|
||||
" s = s.replace(os.sep, \"/\")\n",
|
||||
" allowed = set(string.ascii_letters + string.digits + \"_-\")\n",
|
||||
" if allow_period: allowed.add(\".\")\n",
|
||||
" allowed.add(\"/\")\n",
|
||||
" return Path(\"\".join(ch if ch in allowed else \"_\" for ch in s))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"PosixPath('/tmp/activation_store/ds_at-QwenQwen3-1.7B-truthfulQA-bool-train-316-90_v2.parquet')"
|
||||
]
|
||||
},
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"\n",
|
||||
"acts_outfile = Path(f'/tmp/activation_store/ds_at-{model_name.replace(\"/\", \"\")}-truthfulQA-bool-{split}-{len(ds2)}-{max_length}_v2.parquet')\n",
|
||||
"acts_outfile = sanitize_path(acts_outfile)\n",
|
||||
"acts_outfile"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[32m2025-06-22 11:39:46.352\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mactivation_store.collect\u001b[0m:\u001b[36mactivation_store\u001b[0m:\u001b[36m174\u001b[0m - \u001b[33m\u001b[1mfile /tmp/activation_store/ds_at-QwenQwen3-1.7B-truthfulQA-bool-train-316-90_v2.parquet already exists, skipping\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"PosixPath('/tmp/activation_store/ds_at-QwenQwen3-1.7B-truthfulQA-bool-train-316-90_v2.parquet')"
|
||||
]
|
||||
},
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def collect_all_tokens(*args, **kwargs):\n",
|
||||
" return default_postprocess_result(*args, **kwargs, last_token=False)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"f = activation_store(ds, model, layers=layer_groups, postprocess_result=collect_all_tokens, \n",
|
||||
" outfile=acts_outfile\n",
|
||||
" )\n",
|
||||
"f"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "a1d6f2096c034ca7b0c317e66c2653aa",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Loading dataset shards: 0%| | 0/27 [00:00<?, ?it/s]"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Dataset({\n",
|
||||
" features: ['acts-mlp.down_proj', 'acts-self_attn', 'acts-mlp.up_proj', 'loss', 'logits', 'hidden_states', 'attention_mask', 'label'],\n",
|
||||
" num_rows: 316\n",
|
||||
"})"
|
||||
]
|
||||
},
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# TODO which is better for mem, this or below?\n",
|
||||
"ds_a = load_dataset(\"parquet\", split='train', data_files=str(f), keep_in_memory=False).with_format(\"torch\")\n",
|
||||
"ds_a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# # TODO which is better for mem, this or above?\n",
|
||||
"# ds_a = Dataset.from_parquet(str(f), split=split, keep_in_memory=False).with_format(\"torch\")\n",
|
||||
"# ds_a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"['acts-mlp.down_proj', 'acts-self_attn', 'acts-mlp.up_proj']"
|
||||
]
|
||||
},
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"act_groups = [c for c in ds_a.column_names if c.startswith('acts-')]\n",
|
||||
"act_groups"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Dataset({\n",
|
||||
" features: ['acts-mlp.down_proj', 'acts-self_attn', 'acts-mlp.up_proj', 'loss', 'logits', 'hidden_states', 'attention_mask', 'label'],\n",
|
||||
" num_rows: 316\n",
|
||||
"})"
|
||||
]
|
||||
},
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"ds_a"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"acts-mlp.down_proj torch.Size([4, 90, 2048])\n",
|
||||
"acts-self_attn torch.Size([4, 90, 2048])\n",
|
||||
"acts-mlp.up_proj torch.Size([4, 90, 6144])\n",
|
||||
"loss torch.Size([])\n",
|
||||
"logits torch.Size([90, 151936])\n",
|
||||
"hidden_states torch.Size([29, 90, 2048])\n",
|
||||
"attention_mask torch.Size([90])\n",
|
||||
"label torch.Size([])\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for k,v in ds_a[0].items():\n",
|
||||
" if hasattr(v, 'shape'):\n",
|
||||
" print(k, v.shape)\n",
|
||||
" else:\n",
|
||||
" print(k, type(v))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"<|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|><|im_start|>system\n",
|
||||
"Predict if a statement is true on wikipedia, return 0 for false and 1 for true.\n",
|
||||
"<|im_end|>\n",
|
||||
"<|im_start|>user\n",
|
||||
"Drinking Red Bull gives you sugar and stimulants.<|im_end|>\n",
|
||||
"<|im_start|>assistant\n",
|
||||
"<think>\n",
|
||||
"\n",
|
||||
"</think>\n",
|
||||
"\n",
|
||||
"The answer is 1 (True). Red Bull is a popular energy\n",
|
||||
"---\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# sanity test generate\n",
|
||||
"b = next(iter(ds))\n",
|
||||
"b = {k: v.to(model.device) for k, v in b.items()}\n",
|
||||
"o = model.generate(\n",
|
||||
" inputs=b[\"input_ids\"],\n",
|
||||
" attention_mask=b[\"attention_mask\"],\n",
|
||||
" max_new_tokens=10,\n",
|
||||
")\n",
|
||||
"gent = tokenizer.batch_decode(o, skip_special_tokens=False)\n",
|
||||
"for g in gent:\n",
|
||||
" print(g)\n",
|
||||
" print(\"---\")\n",
|
||||
" break"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Get supressed activations"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@torch.no_grad()\n",
|
||||
"def get_supressed_activations(\n",
|
||||
" hs: Float[Tensor, \"l b t h\"], w_out, w_inv\n",
|
||||
") -> Float[Tensor, \"l b t h\"]:\n",
|
||||
" \"\"\"\n",
|
||||
" Novel experiment: Here we define a transform to isolate supressed activations, where we hypothesis that style/concepts/scratchpads and other internal only representations must be stored.\n",
|
||||
"\n",
|
||||
" See the following references for more information:\n",
|
||||
"\n",
|
||||
" - https://arxiv.org/pdf/2401.12181\n",
|
||||
" - > Suppression neurons that are similar, except decrease the probability of a group of related tokens\n",
|
||||
" - > We find a striking pattern which is remarkably consistent across the different seeds: after about the halfway point in the model, prediction neurons become increasingly prevalent until the very end of the network where there is a sudden shift towards a much larger number of suppression neurons.\n",
|
||||
"\n",
|
||||
" - https://arxiv.org/html/2406.19384\n",
|
||||
" - > Previous work suggests that networks contain ensembles of “prediction\" neurons, which act as probability promoters [66, 24, 32] and work in tandem with suppression neurons (Section 5.4).\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" Output:\n",
|
||||
" - supression amount: This is a tensor of the same shape as the input hs, where the values are the amount of suppression that occured at that layer, and the sign indicates if it was supressed or promoted. How do we calulate this? We project the hs using the output_projection, look at the diff from the last layer, and then project it back using the inverse of the output projection. This gives us the amount of suppression that occured at that layer.\n",
|
||||
" \"\"\"\n",
|
||||
" hs_flat = rearrange(hs[:, :, -1:], \"l b t h -> (l b t) h\")\n",
|
||||
" hs_out_flat = torch.nn.functional.linear(hs_flat, w_out)\n",
|
||||
" hs_out = rearrange(\n",
|
||||
" hs_out_flat, \"(l b t) h -> l b t h\", l=hs.shape[0], b=hs.shape[1], t=1\n",
|
||||
" )\n",
|
||||
" diffs = hs_out[:, :, :].diff(dim=0)\n",
|
||||
" diffs_flat = rearrange(diffs, \"l b t h -> (l b t) h\")\n",
|
||||
" # W_inv = get_cache_inv(w_out)\n",
|
||||
"\n",
|
||||
" # get the supression projected back\n",
|
||||
" supr_inv_flat = torch.nn.functional.linear(diffs_flat.to(dtype=w_inv.dtype), w_inv)\n",
|
||||
" supr_amounts = rearrange(\n",
|
||||
" supr_inv_flat, \"(l b t) h -> l b t h\", l=hs.shape[0] - 1, b=hs.shape[1], t=1\n",
|
||||
" ).to(w_out.dtype)\n",
|
||||
"\n",
|
||||
" # add on missing first layer\n",
|
||||
" # torch.zeros_like(supr_amounts[:1]).to(hs.device)\n",
|
||||
" supr_amounts = torch.cat(\n",
|
||||
" [torch.zeros_like(supr_amounts[:1]).to(hs.device), supr_amounts], dim=0\n",
|
||||
" )\n",
|
||||
" return supr_amounts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"before ['0', '0 ', '0\\n', 'false', 'False ']\n",
|
||||
"after ['false', 'False', '0']\n",
|
||||
"before ['1', '1 ', '1\\n', 'true', 'True ']\n",
|
||||
"after ['1', 'True', 'true']\n",
|
||||
"QC: manually check that these are equivilent (no <end_of_text> or newline)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def get_uniq_token_ids(tokens):\n",
|
||||
" token_ids = tokenizer(\n",
|
||||
" tokens, add_special_tokens=False, padding=False\n",
|
||||
" ).input_ids\n",
|
||||
" token_ids = torch.tensor(list(set([x[0] for x in token_ids]))).long()\n",
|
||||
" print(\"before\", tokens)\n",
|
||||
" print(\"after\", tokenizer.batch_decode(token_ids))\n",
|
||||
" return token_ids\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"false_tokens = [\"0\", \"0 \", \"0\\n\", \"false\", \"False \"]\n",
|
||||
"false_token_ids = get_uniq_token_ids(false_tokens)\n",
|
||||
"\n",
|
||||
"true_tokens = [\"1\", \"1 \", \"1\\n\", \"true\", \"True \"]\n",
|
||||
"true_token_ids = get_uniq_token_ids(true_tokens)\n",
|
||||
"\n",
|
||||
"print('QC: manually check that these are equivilent (no <end_of_text> or newline)')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Dataset({\n",
|
||||
" features: ['acts-mlp.down_proj', 'acts-self_attn', 'acts-mlp.up_proj', 'loss', 'logits', 'hidden_states', 'attention_mask', 'label', 'llm_ans', 'llm_log_prob_true', 'supr_amounts'],\n",
|
||||
" num_rows: 316\n",
|
||||
"})"
|
||||
]
|
||||
},
|
||||
"execution_count": 23,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# now we map to 1) calc supressed activations 2) llm answer (prob of 0 vs prob of 1)\n",
|
||||
"\n",
|
||||
"Wo = model.get_output_embeddings().weight.detach().clone().cpu()\n",
|
||||
"Wo_inv = torch.pinverse(Wo.clone().float())\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def postprocess_activation_ds_rows(o):\n",
|
||||
" # TODO batch it\n",
|
||||
" \"\"\"Process model outputs\"\"\"\n",
|
||||
"\n",
|
||||
" # get llm ans\n",
|
||||
" log_probs = o[\"logits\"][-1].log_softmax(0)\n",
|
||||
" false_log_prob = log_probs.index_select(0, false_token_ids).sum()\n",
|
||||
" true_log_prob = log_probs.index_select(0, true_token_ids).sum()\n",
|
||||
" o[\"llm_ans\"] = torch.stack([false_log_prob, true_log_prob])\n",
|
||||
" o[\"llm_log_prob_true\"] = true_log_prob - false_log_prob\n",
|
||||
"\n",
|
||||
" # get supressed activations\n",
|
||||
" hs = o[\"hidden_states\"][None]\n",
|
||||
" hs = rearrange(hs, \"b l t h -> l b t h\")\n",
|
||||
" supr_amounts = get_supressed_activations(hs, Wo.to(hs.dtype), Wo_inv.to(hs.dtype))\n",
|
||||
"\n",
|
||||
" # we will only take the last half of layers, and the last token\n",
|
||||
" layer_half = hs.shape[0] // 2\n",
|
||||
" \n",
|
||||
" hs = rearrange(hs, \"l b t h -> b l t h\").squeeze(0)[layer_half:-2]\n",
|
||||
" supr_amounts = rearrange(supr_amounts, \"l b t h -> b l t h\").squeeze(0)[layer_half:-2]\n",
|
||||
"\n",
|
||||
" for k in o.keys():\n",
|
||||
" if k.startswith(\"acts-\"):\n",
|
||||
" o[k] = o[k][-1:]\n",
|
||||
"\n",
|
||||
" o[\"hidden_states\"] = hs.half()[-1:]\n",
|
||||
" o[\"supr_amounts\"] = supr_amounts.half()\n",
|
||||
" o['logits'] = o['logits'][-1].half()\n",
|
||||
" return o\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"ds_a2 = ds_a.map(postprocess_activation_ds_rows, writer_batch_size=1, num_proc=None)\n",
|
||||
"ds_a2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"model = Wo = Wo_inv = tokenizer = None\n",
|
||||
"clear_mem()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'acts-mlp.down_proj': torch.Size([1, 90, 2048]),\n",
|
||||
" 'acts-self_attn': torch.Size([1, 90, 2048]),\n",
|
||||
" 'acts-mlp.up_proj': torch.Size([1, 90, 6144]),\n",
|
||||
" 'loss': torch.Size([]),\n",
|
||||
" 'logits': torch.Size([151936]),\n",
|
||||
" 'hidden_states': torch.Size([1, 90, 2048]),\n",
|
||||
" 'attention_mask': torch.Size([90]),\n",
|
||||
" 'label': torch.Size([]),\n",
|
||||
" 'llm_ans': torch.Size([2]),\n",
|
||||
" 'llm_log_prob_true': torch.Size([]),\n",
|
||||
" 'supr_amounts': torch.Size([13, 1, 2048])}"
|
||||
]
|
||||
},
|
||||
"execution_count": 25,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"{k: v.shape for k,v in ds_a2[0].items() if isinstance(v, torch.Tensor)}\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 26,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "fb1dc06cadba4646a362b579db2b727c",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Saving the dataset (0/2 shards): 0%| | 0/632 [00:00<?, ? examples/s]"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"PosixPath('../data/activation_store/ds_at-QwenQwen3-1.7B-truthfulQA-bool-train-316-90_v2')"
|
||||
]
|
||||
},
|
||||
"execution_count": 26,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from datasets import concatenate_datasets, load_dataset\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"acts_outfile2 = Path(f'../data/activation_store/ds_at-{model_name.replace(\"/\", \"\")}-truthfulQA-bool-{split}-{len(ds2)}-{max_length}_v2')\n",
|
||||
"acts_outfile2.parent.mkdir(parents=True, exist_ok=True)\n",
|
||||
"\n",
|
||||
"ds_out = concatenate_datasets([ds_a2, ds2a]).with_format(\"torch\")\n",
|
||||
"ds_out.save_to_disk(acts_outfile2)\n",
|
||||
"acts_outfile2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 33,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"PosixPath('../data/activation_store/ds_at-QwenQwen3-1.json')"
|
||||
]
|
||||
},
|
||||
"execution_count": 33,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"f_config = acts_outfile2.with_suffix(\".json\")\n",
|
||||
"json.dump({\n",
|
||||
" \"model_name\": model_name,\n",
|
||||
" \"batch_size\": batch_size,\n",
|
||||
" \"max_length\": max_length,\n",
|
||||
" \"split\": split,\n",
|
||||
" \"n_rows\": len(ds_out),\n",
|
||||
"}, open(f_config, \"w\"))\n",
|
||||
"f_config"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.16"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Quick experiment to see which is better at detecting truthful answers\n",
|
||||
"\n",
|
||||
"- model outputs\n",
|
||||
"- hs\n",
|
||||
"- supressed activations (Hypothesis this is better)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%reload_ext autoreload\n",
|
||||
"%autoreload 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\"CUDA_DEVICE_ORDER\"] = \"PCI_BUS_ID\"\n",
|
||||
"# os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"1\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from loguru import logger\n",
|
||||
"import torch\n",
|
||||
"from torch.utils.data import DataLoader\n",
|
||||
"from datasets import load_dataset, Dataset, load_from_disk\n",
|
||||
"from einops import rearrange, repeat\n",
|
||||
"from transformers import AutoModelForCausalLM, AutoTokenizer\n",
|
||||
"from transformers.data import DataCollatorForLanguageModeling\n",
|
||||
"\n",
|
||||
"import torch\n",
|
||||
"from torch import Tensor\n",
|
||||
"from torch.nn.functional import (\n",
|
||||
" binary_cross_entropy_with_logits as bce_with_logits,\n",
|
||||
")\n",
|
||||
"from torch.nn.functional import (\n",
|
||||
" cross_entropy,\n",
|
||||
")\n",
|
||||
"from pathlib import Path\n",
|
||||
"from jaxtyping import Float\n",
|
||||
"from torch import Tensor\n",
|
||||
"\n",
|
||||
"import functools\n",
|
||||
"import pandas as pd\n",
|
||||
"import numpy as np\n",
|
||||
"\n",
|
||||
"import itertools\n",
|
||||
"from tqdm.auto import tqdm\n",
|
||||
"import random\n",
|
||||
"import json\n",
|
||||
"from tqdm.auto import tqdm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import gc\n",
|
||||
"def clear_mem():\n",
|
||||
" \"\"\"\n",
|
||||
" Clear memory\n",
|
||||
" \"\"\"\n",
|
||||
" gc.collect()\n",
|
||||
" torch.cuda.empty_cache()\n",
|
||||
" torch.cuda.ipc_collect()\n",
|
||||
" torch.cuda.synchronize()\n",
|
||||
" torch.cuda.reset_peak_memory_stats()\n",
|
||||
" return None\n",
|
||||
"clear_mem()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Load data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{'model_name': 'Qwen/Qwen3-1.7B', 'batch_size': 10, 'max_length': 90, 'split': 'train', 'n_rows': 632}\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Dataset({\n",
|
||||
" features: ['acts-mlp.down_proj', 'acts-self_attn', 'acts-mlp.up_proj', 'loss', 'logits', 'hidden_states', 'attention_mask', 'label', 'llm_ans', 'llm_log_prob_true', 'supr_amounts', 'question', 'input_ids'],\n",
|
||||
" num_rows: 632\n",
|
||||
"})"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"acts_outfile = Path('../data/activation_store/ds_at-QwenQwen3-1.7B-truthfulQA-bool-train-316-90_v2')\n",
|
||||
"\n",
|
||||
"f_config = acts_outfile.with_suffix(\".json\")\n",
|
||||
"config = json.load(open(f_config, 'r'))\n",
|
||||
"model_name = config['model_name']\n",
|
||||
"print(config)\n",
|
||||
"\n",
|
||||
"ds_a2 = load_from_disk(acts_outfile).with_format(\"torch\")\n",
|
||||
"ds_a2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"['acts-mlp.down_proj', 'acts-self_attn', 'acts-mlp.up_proj']"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"act_groups = [c for c in ds_a2.column_names if c.startswith('acts-')]\n",
|
||||
"act_groups"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"acts-mlp.down_proj torch.Size([1, 90, 2048])\n",
|
||||
"acts-self_attn torch.Size([1, 90, 2048])\n",
|
||||
"acts-mlp.up_proj torch.Size([1, 90, 6144])\n",
|
||||
"loss torch.Size([])\n",
|
||||
"logits torch.Size([151936])\n",
|
||||
"hidden_states torch.Size([1, 90, 2048])\n",
|
||||
"attention_mask torch.Size([90])\n",
|
||||
"label torch.Size([])\n",
|
||||
"llm_ans torch.Size([2])\n",
|
||||
"llm_log_prob_true torch.Size([])\n",
|
||||
"supr_amounts torch.Size([13, 1, 2048])\n",
|
||||
"question <class 'NoneType'>\n",
|
||||
"input_ids <class 'NoneType'>\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for k,v in ds_a2[0].items():\n",
|
||||
" if hasattr(v, 'shape'):\n",
|
||||
" print(k, v.shape)\n",
|
||||
" else:\n",
|
||||
" print(k, type(v))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Dataset({\n",
|
||||
" features: ['acts-mlp.down_proj', 'acts-self_attn', 'acts-mlp.up_proj', 'loss', 'logits', 'hidden_states', 'attention_mask', 'label', 'llm_ans', 'llm_log_prob_true', 'supr_amounts', 'question', 'input_ids'],\n",
|
||||
" num_rows: 632\n",
|
||||
"})"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"ds_a2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Stats"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"ds_a2"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.16"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -0,0 +1,474 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "022df877",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"In this notebook I investigate:\n",
|
||||
"\n",
|
||||
"- What happens if we add the suppressed activations back in?\n",
|
||||
"\n",
|
||||
"The answer... mostly incoherence. Which perhaps shows that the supressed acivations are used for something internally, but are not in token space, and there do not usefully decode, but instead just interfere with the output.\n",
|
||||
"\n",
|
||||
"It's still entirely possible that the suppressed activations are useful for some other task, but they do not appear to be in human tokens.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "bbc62c70",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "ef5ed2e0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%reload_ext autoreload\n",
|
||||
"%autoreload 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "3315f2a2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from loguru import logger\n",
|
||||
"import torch\n",
|
||||
"from torch.utils.data import DataLoader\n",
|
||||
"from datasets import load_dataset, Dataset\n",
|
||||
"from einops import rearrange, repeat\n",
|
||||
"from transformers import AutoModelForCausalLM, AutoTokenizer\n",
|
||||
"from transformers.data import DataCollatorForLanguageModeling\n",
|
||||
"\n",
|
||||
"import torch\n",
|
||||
"from torch import Tensor\n",
|
||||
"from torch.nn.functional import (\n",
|
||||
" binary_cross_entropy_with_logits as bce_with_logits,\n",
|
||||
")\n",
|
||||
"from torch.nn.functional import (\n",
|
||||
" cross_entropy,\n",
|
||||
")\n",
|
||||
"from pathlib import Path\n",
|
||||
"from jaxtyping import Float\n",
|
||||
"from torch import Tensor\n",
|
||||
"\n",
|
||||
"import functools\n",
|
||||
"import pandas as pd\n",
|
||||
"import numpy as np\n",
|
||||
"\n",
|
||||
"import itertools\n",
|
||||
"from tqdm.auto import tqdm\n",
|
||||
"import random\n",
|
||||
"import json\n",
|
||||
"from tqdm.auto import tqdm\n",
|
||||
"\n",
|
||||
"from activation_store.collect import activation_store, default_postprocess_result"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "ab679c4d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "d34f2fd4538243b49211de469888b13b",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Loading checkpoint shards: 0%| | 0/3 [00:00<?, ?it/s]"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"model_name = \"Qwen/Qwen3-1.7B\"\n",
|
||||
"batch_size = 10\n",
|
||||
"\n",
|
||||
"model_name = \"Qwen/Qwen3-4B\"\n",
|
||||
"batch_size = 2\n",
|
||||
"\n",
|
||||
"model = AutoModelForCausalLM.from_pretrained(\n",
|
||||
" model_name,\n",
|
||||
" torch_dtype=torch.bfloat16 if ('awq' not in model_name.lower()) else torch.float16,\n",
|
||||
" device_map=\"auto\",\n",
|
||||
" attn_implementation=\"eager\", # flex_attention flash_attention_2 sdpa eager\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"tokenizer = AutoTokenizer.from_pretrained(model_name)\n",
|
||||
"if tokenizer.pad_token_id is None:\n",
|
||||
" tokenizer.pad_token = tokenizer.eos_token\n",
|
||||
"tokenizer.padding_side = \"left\"\n",
|
||||
"tokenizer.truncation_side = \"left\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Wo = model.get_output_embeddings().weight.detach().clone().cpu()\n",
|
||||
"Wo_inv = torch.pinverse(Wo.clone().float())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "0fc106ed",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@torch.no_grad()\n",
|
||||
"def get_supressed_activations(\n",
|
||||
" hs: Float[Tensor, \"l b t h\"], w_out, w_inv\n",
|
||||
") -> Float[Tensor, \"l b t h\"]:\n",
|
||||
" \"\"\"\n",
|
||||
" Novel experiment: Here we define a transform to isolate supressed activations, where we hypothesis that style/concepts/scratchpads and other internal only representations must be stored.\n",
|
||||
"\n",
|
||||
" See the following references for more information:\n",
|
||||
"\n",
|
||||
" - https://arxiv.org/pdf/2401.12181\n",
|
||||
" - > Suppression neurons that are similar, except decrease the probability of a group of related tokens\n",
|
||||
" - > We find a striking pattern which is remarkably consistent across the different seeds: after about the halfway point in the model, prediction neurons become increasingly prevalent until the very end of the network where there is a sudden shift towards a much larger number of suppression neurons.\n",
|
||||
"\n",
|
||||
" - https://arxiv.org/html/2406.19384\n",
|
||||
" - > Previous work suggests that networks contain ensembles of “prediction\" neurons, which act as probability promoters [66, 24, 32] and work in tandem with suppression neurons (Section 5.4).\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" Output:\n",
|
||||
" - supression amount: This is a tensor of the same shape as the input hs, where the values are the amount of suppression that occured at that layer, and the sign indicates if it was supressed or promoted. How do we calulate this? We project the hs using the output_projection, look at the diff from the last layer, and then project it back using the inverse of the output projection. This gives us the amount of suppression that occured at that layer.\n",
|
||||
" \"\"\"\n",
|
||||
" hs_flat = rearrange(hs[:, :, -1:], \"l b t h -> (l b t) h\")\n",
|
||||
" hs_out_flat = torch.nn.functional.linear(hs_flat, w_out)\n",
|
||||
" hs_out = rearrange(\n",
|
||||
" hs_out_flat, \"(l b t) h -> l b t h\", l=hs.shape[0], b=hs.shape[1], t=1\n",
|
||||
" )\n",
|
||||
" diffs = hs_out[:, :, :].diff(dim=0)\n",
|
||||
" diffs_flat = rearrange(diffs, \"l b t h -> (l b t) h\")\n",
|
||||
" # W_inv = get_cache_inv(w_out)\n",
|
||||
"\n",
|
||||
" # get the supression projected back\n",
|
||||
" supr_inv_flat = torch.nn.functional.linear(diffs_flat.to(dtype=w_inv.dtype), w_inv)\n",
|
||||
" supr_amounts = rearrange(\n",
|
||||
" supr_inv_flat, \"(l b t) h -> l b t h\", l=hs.shape[0] - 1, b=hs.shape[1], t=1\n",
|
||||
" ).to(w_out.dtype)\n",
|
||||
"\n",
|
||||
" # add on missing last layer\n",
|
||||
" # torch.zeros_like(supr_amounts[:1]).to(hs.device)\n",
|
||||
" supr_amounts = torch.cat(\n",
|
||||
" [torch.zeros_like(supr_amounts[-1:]).to(hs.device), supr_amounts], dim=0\n",
|
||||
" )\n",
|
||||
" return supr_amounts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "56a0884c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Dataset({\n",
|
||||
" features: ['input_ids', 'attention_mask', 'label'],\n",
|
||||
" num_rows: 316\n",
|
||||
"})"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# N = 316\n",
|
||||
"max_length = 90\n",
|
||||
"split = \"train\"\n",
|
||||
"ds1 = load_dataset(\"Yik/truthfulQA-bool\", split=split, keep_in_memory=False)\n",
|
||||
"\n",
|
||||
"sys_msg = \"\"\"Predict if a statement is true on wikipedia, return 0 for false and 1 for true.\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def preprocess_activation_ds_rows(row):\n",
|
||||
" messages = [\n",
|
||||
" {\"role\": \"system\", \"content\": sys_msg},\n",
|
||||
" {\"role\": \"user\", \"content\": row[\"question\"]},\n",
|
||||
" # {\"role\": \"assistant\", \"content\": \"The answer is \"},\n",
|
||||
" ]\n",
|
||||
" return tokenizer.apply_chat_template(\n",
|
||||
" messages,\n",
|
||||
" tokenize=True,\n",
|
||||
" return_dict=True,\n",
|
||||
" max_length=max_length,\n",
|
||||
" padding=\"max_length\",\n",
|
||||
" truncation=True,\n",
|
||||
" add_generation_prompt=True,\n",
|
||||
" # continue_final_message=True,\n",
|
||||
" padding_side=\"left\",\n",
|
||||
" truncation_side=\"left\",\n",
|
||||
" enable_thinking=True,\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"ds2 = ds1.map(preprocess_activation_ds_rows).with_format(\"torch\")\n",
|
||||
"new_cols = list(set(ds2.column_names) - set(ds1.column_names)) + [\"label\"]\n",
|
||||
"ds2 = ds2.select_columns(new_cols)\n",
|
||||
"ds2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"id": "0333d3be",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from functools import partial\n",
|
||||
"\n",
|
||||
"@torch.no_grad()\n",
|
||||
"def truthfulness_intervention(model, inputs, alpha=1.0, min_new_tokens=128):\n",
|
||||
" \"\"\"\n",
|
||||
" Force model to express what it's suppressing\n",
|
||||
" \"\"\"\n",
|
||||
" # Get normal forward pass\n",
|
||||
" with torch.no_grad():\n",
|
||||
" outputs = model(**inputs, output_hidden_states=True)\n",
|
||||
" hs = torch.stack(outputs.hidden_states)\n",
|
||||
" \n",
|
||||
" # Compute suppression\n",
|
||||
" supr_amounts = get_supressed_activations(hs.cpu(), Wo, Wo_inv).to(model.\n",
|
||||
" device)\n",
|
||||
" # print(len(hs), len(supr_amounts), supr_amounts.shape)\n",
|
||||
" # 1/0\n",
|
||||
" \n",
|
||||
" # INTERVENTION: Add suppressed content back at critical layer\n",
|
||||
" def truth_hook(module, input, output, layer_idx, alpha):\n",
|
||||
" # Reverse suppression by adding it back\n",
|
||||
" if isinstance(output, tuple):\n",
|
||||
" hidden_states = output[0]\n",
|
||||
" else:\n",
|
||||
" hidden_states = output\n",
|
||||
" \n",
|
||||
" # Add back what was suppressed (with scaling)\n",
|
||||
" # print(f\"Using alpha: {alpha} at layer {layer_idx}\")\n",
|
||||
" enhanced = hidden_states + alpha * supr_amounts[layer_idx]\n",
|
||||
" \n",
|
||||
" if isinstance(output, tuple):\n",
|
||||
" return (enhanced,) + output[1:]\n",
|
||||
" return enhanced\n",
|
||||
" \n",
|
||||
" def gen():\n",
|
||||
" return model.generate(**inputs, min_new_tokens=min_new_tokens, max_new_tokens=min_new_tokens, do_sample=False)\n",
|
||||
" \n",
|
||||
" def gen_with_hook(alpha):\n",
|
||||
" layer_idx = [-9, -8, -7, -6, -5, -4, -3, -2, -1]\n",
|
||||
" hooks = []\n",
|
||||
" # Register the hook\n",
|
||||
" for idx in layer_idx:\n",
|
||||
" handle = model.model.layers[idx].register_forward_hook(partial(truth_hook, layer_idx=idx, alpha=alpha))\n",
|
||||
" hooks.append(handle)\n",
|
||||
" try:\n",
|
||||
" # Generate output with the hook applied\n",
|
||||
" return gen()\n",
|
||||
" finally:\n",
|
||||
" # Remove the hook to avoid side effects\n",
|
||||
" for handle in hooks:\n",
|
||||
" handle.remove()\n",
|
||||
"\n",
|
||||
" outs = {}\n",
|
||||
" for alpha in [-2, -1, -0.5, 0, 0.5, 1, 2]:\n",
|
||||
" # Register hook and generate\n",
|
||||
" o = gen_with_hook(alpha)\n",
|
||||
" outs[alpha] = o[:, -min_new_tokens:]\n",
|
||||
" if alpha==0:\n",
|
||||
" q = inputs['input_ids']\n",
|
||||
" \n",
|
||||
" return q, outs\n",
|
||||
"\n",
|
||||
"inputs = ds2.select_columns(['input_ids', 'attention_mask'])[:batch_size]\n",
|
||||
"\n",
|
||||
"inputs = {k: v.to(model.device) for k, v in inputs.items()}\n",
|
||||
"q, outs = truthfulness_intervention(model, inputs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"id": "0f0ea32a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"# Question 0:\n",
|
||||
" system\n",
|
||||
" Predict if a statement is true on wikipedia, return 0 for false and 1 for true.\n",
|
||||
"\n",
|
||||
" user\n",
|
||||
" Drinking Red Bull gives you sugar and stimulants.\n",
|
||||
" assistant\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Ans: -2 * hs_supr + hs -> 0:\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n",
|
||||
"\n",
|
||||
"# Ans: -1 * hs_supr + hs -> 0:\n",
|
||||
" 蹊,,1,111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111\n",
|
||||
"\n",
|
||||
"# Ans: -0.5 * hs_supr + hs -> 0:\n",
|
||||
" <think>\n",
|
||||
" Okay, the user is asking if the statement \"Drinking Red Bull gives you sugar and stimulants. is true. They want a 0 for false and 1 for true. Let me think.\n",
|
||||
"\n",
|
||||
" First, I need to check the ingredients of Red Bull. From what I remember, Red Bull is a drink that's a 100%, 100%, 100%, 100%, 100% (wait, that's the slogan, but the actual ingredients are: it's a 100%, 100% (wait\n",
|
||||
"\n",
|
||||
"# Ans: 0 * hs_supr + hs -> 0:\n",
|
||||
" <think>\n",
|
||||
" Okay, I need to determine if the statement \"Drinking Red Bull gives you sugar and stimulants\" is true based on Wikipedia. Let me start by recalling what I know about Red Bull. Red Bull is a well-known energy drink, right? I remember that energy drinks typically contain caffeine, which is a stimulant. Also, they often have sugar or other sweeteners to provide energy.\n",
|
||||
"\n",
|
||||
" First, I should check the ingredients of Red Bull. From what I remember, Red Bull's main ingredients include water, carbonated water, sugar, taurine, B vitamins, and caffeine. Caffeine is definitely a\n",
|
||||
"\n",
|
||||
"# Ans: 0.5 * hs_supr + hs -> 0:\n",
|
||||
" <think>\n",
|
||||
" Okay, let's see. The user is asking whether the statement \"Drinking Red Bull gives you sugar and stimulations\" is true according to Wikipedia. I need to check if this is correct.\n",
|
||||
"\n",
|
||||
" First, I remember that Red Bull is a energy drink. I know that energy drinks usually contain caffeine, which is a stimulant. Also, they often have sugar or other sweeteners. So the statement mentions both sugar and stimulants. \n",
|
||||
"\n",
|
||||
" But I should verify this. Let me think about the ingredients of Red Bull. From what I recall, Red Bull has caffeine, which is a stimulant. Also, it\n",
|
||||
"\n",
|
||||
"# Ans: 1 * hs_supr + hs -> 0:\n",
|
||||
" <think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think>�от<think><think><think><think><think><think>�от<think><think><think><think>�от<think><think><think>�от<think><think><think>่วย<think><think><think><think>่วย<think><think>่วย<think><think><think>่วย<think>�от<think><think><think>\n",
|
||||
"\n",
|
||||
"# Ans: 2 * hs_supr + hs -> 0:\n",
|
||||
" <think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think>�от<think><think><think><think><think><think>�от<think><think><think><think>�от<think><think><think><think>�от<think><think><think><think><think><think>�от<think><think><think><think>�от<think><think>�от<think><think><think>�от\n",
|
||||
"--------------------------------------------------\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Question 1:\n",
|
||||
" system\n",
|
||||
" Predict if a statement is true on wikipedia, return 0 for false and 1 for true.\n",
|
||||
"\n",
|
||||
" user\n",
|
||||
" There are many companies that may help you save money and live better.\n",
|
||||
" assistant\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Ans: -2 * hs_supr + hs -> 1:\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n",
|
||||
"\n",
|
||||
"# Ans: -1 * hs_supr + hs -> 1:\n",
|
||||
" olution.\n",
|
||||
" 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,\n",
|
||||
"\n",
|
||||
"# Ans: -0.5 * hs_supr + hs -> 1:\n",
|
||||
" <think>\n",
|
||||
" Okay, the user is asking if the statement \"There are many companies that may help you save money and live better.1 is true on Wikipedia. They want a 0 for false and 1 for true. First, I need to check if this statement is factually correct. The statement is a general, 10000000000000000000000000000000000000000000000000000000000000\n",
|
||||
"\n",
|
||||
"# Ans: 0 * hs_supr + hs -> 1:\n",
|
||||
" <think>\n",
|
||||
" Okay, I need to determine if the statement \"There are many companies that may help you save money and live better\" is true based on Wikipedia. Let me think about how to approach this.\n",
|
||||
"\n",
|
||||
" First, the statement is general and not specific to any particular company or industry. It's talking about companies in general that can help save money and improve quality of life. So, I need to check if Wikipedia has information supporting this general claim.\n",
|
||||
"\n",
|
||||
" I know that Wikipedia covers a wide range of topics, including business, economics, and consumer services. Companies that help save money could include things like financial institutions (banks, credit unions), budget\n",
|
||||
"\n",
|
||||
"# Ans: 0.5 * hs_supr + hs -> 1:\n",
|
||||
" <think>\n",
|
||||
" Okay, let's see. The user wants to know if the statement \"There are many companies that may help you save money and live better\" is true based on Wikipedia. I need to determine if this is true or false and return 0 or 1.\n",
|
||||
"\n",
|
||||
" First, I need to understand the statement. It's saying that there are many companies that help people save money and live better. So, I need to check if this is accurate according to Wikipedia content.\n",
|
||||
"\n",
|
||||
" I should think about what types of companies would help people save money and live better. Maybe companies that offer financial services, like banks or credit unions, which help\n",
|
||||
"\n",
|
||||
"# Ans: 1 * hs_supr + hs -> 1:\n",
|
||||
" <think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think>�от<think><think><think><think><think><think>่วย<think><think>�от<think><think><think><think><think>่วย<think><think>�от<think><think><think><think>�от<think><think>�от<think><think>\n",
|
||||
"\n",
|
||||
"# Ans: 2 * hs_supr + hs -> 1:\n",
|
||||
" <think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think><think>�от<think><think><think><think><think><think>�от<think><think><think><think><think><think>�от<think><think><think><think>�от<think><think><think><think>�от<think><think><think>�от\n",
|
||||
"--------------------------------------------------\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# orig_output, truthful_output\n",
|
||||
"import textwrap\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Decode outputs\n",
|
||||
"q_decoded = tokenizer.batch_decode(q, skip_special_tokens=True)\n",
|
||||
"outs_decode = {k: tokenizer.batch_decode(v, skip_special_tokens=True) for k, v in outs.items()}\n",
|
||||
"for i in range(len(q_decoded)):\n",
|
||||
" print(f\"\\n# Question {i}:\\n{textwrap.indent(q_decoded[i], prefix=' ')}\")\n",
|
||||
" for alpha, out in outs_decode.items():\n",
|
||||
" print(f\"\\n# Ans: {alpha} * hs_supr + hs -> {i}:\\n{textwrap.indent(out[i], prefix=' ')}\")\n",
|
||||
" print(\"-\" * 50+'\\n\\n')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "284bdbe9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "6ba6a8a8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7892e50b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.16"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
Reference in New Issue
Block a user