{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# LLM Abliterate v1.4 script, adapted for 01-ai/Yi-1.5-34B-Chat\n\nAuthor: byroneverson\n\nThis script ran at kaggle.com, accelerator: None, persistence: Files only","metadata":{}},{"cell_type":"markdown","source":"# Download quantized model from bartowski/Yi-1.5-34B-Chat-GGUF locally\n\nDownloading to /kaggle/temp dir so will need to keep the session open to keep model local","metadata":{}},{"cell_type":"code","source":"%cd /kaggle/working\n\nfrom huggingface_hub import hf_hub_download\n\nhf_hub_download(repo_id=\"bartowski/Yi-1.5-34B-Chat-GGUF\", filename=\"Yi-1.5-34B-Chat-Q4_K_M.gguf\", local_dir=\"/kaggle/temp\")","metadata":{"execution":{"iopub.status.busy":"2024-09-12T07:18:51.181499Z","iopub.status.idle":"2024-09-12T07:18:51.181878Z","shell.execute_reply.started":"2024-09-12T07:18:51.181704Z","shell.execute_reply":"2024-09-12T07:18:51.181722Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Temporary: We need my fork of ggml-python because the official abetlen is out of date and ggml_tensor is incompatible at the moment.","metadata":{}},{"cell_type":"code","source":"%cd /kaggle/working\n!git clone --recurse-submodules https://github.com/byroneverson/ggml-python.git","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-09-12T07:18:51.183356Z","iopub.status.idle":"2024-09-12T07:18:51.183789Z","shell.execute_reply.started":"2024-09-12T07:18:51.183558Z","shell.execute_reply":"2024-09-12T07:18:51.183577Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Install my ggml-python, llama-cpp-python, and couple other reqs\n\nUsing CUDA with llama.cpp for these larger models","metadata":{}},{"cell_type":"code","source":"%cd /kaggle/working\n\n!pip install ./ggml-python\n!pip install llama-cpp-python --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cu123 #CUDA\n#!pip install llama-cpp-python\n!pip install jaxtyping\n!pip install einops","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Obtain layer output embeddings for each of our sample instruction sets (harmful and harmless)\n\n- These will be saved to the folders \"harmful_states\" and \"harmless_states\".\n- Each output file contains a tensor of shape (n_layers * 2 + 1, n_embd). E.g. (46, 4608) for this model.\n- Output files will contain embeds for the token embeddings, and both the attn output and ffn output embeds of each layer.\n- A quant model is used for this process with llama.cpp for minimal cpu and memory usage.\n- This version of the script uses CUDA to split the layers workload between CPU and GPU.\n- Considering we will end up using the mean of these samples, the amount of quantization shouldn't matter much.","metadata":{}},{"cell_type":"code","source":"%cd /kaggle/working\n\nimport ctypes\nimport os\nimport multiprocessing\nimport random\nimport gc\nimport sys\nimport re\nimport llama_cpp\nimport ggml\nimport torch\nfrom math import prod\nfrom datasets import load_dataset\nfrom tqdm import tqdm\n\n# Number of total layers in your model\ntotal_layers = 60\ntarget_percent = 0.5 # 50% through the layers\ntarget_index = int(total_layers * target_percent)\n# Middle 8 layers to keep for PCA\ntarget_count = 60\ntarget_start = target_index - (target_count // 2)\ntarget_end = target_index + (target_count // 2)\n# GPU\nn_gpu_layers = 46 #0 # CPU only\n\n# Number of instructions to average for our feature estimation (e.g. 512 for harmful and 512 for harmless)\ninstructions = 512 #256 #32\n\n# Our local gguf model\n# TODO: Load model with only num_layers we actually need for this step\nworking_dir = \"/kaggle/working\"\nlocal_repo_dir = \"/kaggle/temp\"\nmodel_path = local_repo_dir + \"/\" + \"Yi-1.5-34B-Chat-Q4_K_M.gguf\"\n\n# Init llama backend\nllama_cpp.llama_backend_init(numa=False)\n\n# llama.cpp custom model code\n\ndef c_array_to_tensor(pointer, shape, torch_type):\n arr = (pointer._type_ * prod(shape)).from_address(\n ctypes.addressof(pointer.contents))\n return torch.frombuffer(arr, dtype=torch_type).view(*shape)\n\ndef model_load(model_path):\n # TODO: Attempt to hook num_layers\n model_params = llama_cpp.llama_model_default_params()\n model_params.n_gpu_layers = n_gpu_layers\n model_params.use_mmap = True\n model = llama_cpp.llama_load_model_from_file(model_path.encode(\"utf-8\"), model_params)\n return model\n\ndef model_free(model):\n llama_cpp.llama_free(model)\n \ndef model_tokenize_chat(model, role, content, add_assistant=True):\n role = role.encode(\"utf-8\")\n content = content.encode(\"utf-8\")\n content_len = len(content)\n if content_len == 0:\n return []\n \n chat_message = llama_cpp.llama_chat_message(role=role, content=content)\n buffer_length = content_len * 2\n buffer = ctypes.create_string_buffer(buffer_length)\n result = llama_cpp.llama_chat_apply_template(model, None, ctypes.pointer(chat_message), 1, add_assistant, buffer, ctypes.c_int32(buffer_length))\n if result <= 0:\n return input_str\n elif result >= buffer_length:\n buffer_length = result + 1\n buffer = ctypes.create_string_buffer(buffer_length)\n result = llama_cpp.llama_chat_apply_template(model, None, ctypes.pointer(chat_message), 1, add_assistant, buffer, ctypes.c_int32(buffer_length))\n content = buffer.value if result > 0 else content\n \n # Add space for llama only, check model params for add space var\n add_space = False # TODO: Check model/config for this, not used for gemma 2\n if add_space:\n content = b\" \" + content\n \n # Tokenize\n content_len = len(content)\n content_len_c = ctypes.c_int32(content_len)\n tokens = (ctypes.c_int32 * content_len)()\n count = llama_cpp.llama_tokenize(model, content, content_len_c, tokens, content_len_c, True, True)\n if content_len > count:\n tokens = tokens[:count]\n return tokens\n\ndef print_tensor_info(t_ptr):\n #: contiguous: {ggml.ggml_is_contiguous(t)}, permuted: {ggml.ggml_is_permuted(t)}, transposed: {ggml.ggml_is_transposed(t)}\"\n t = t_ptr.contents\n print(f\"{ggml.ggml_type_name(t.type)} {ggml.ggml_op_desc(t_ptr)} {t.name}\")\n print(f\" n_elements = {ggml.ggml_nelements(t)}\")\n print(f\" ne = ({t.ne[0]}, {t.ne[1]}, {t.ne[2]}, {t.ne[3]})\")\n print(f\" nb = ({t.nb[0]}, {t.nb[1]}, {t.nb[2]}, {t.nb[3]})\")\n is_host = ggml.ggml_backend_buffer_is_host(t.buffer)\n print(f\" is_host = {is_host}\")\n print(f\" buffer = {t.buffer}\")\n print(f\" data = {t.data}\")\n if ctypes.c_void_p.from_buffer(t.src[0]).value != None:\n print(f\" src[0] = {ggml.ggml_op_desc(t.src[0])}\")\n if ctypes.c_void_p.from_buffer(t.src[1]).value != None:\n print(f\" src[1] = {ggml.ggml_op_desc(t.src[1])}\")\n\n# Callback will fill this during model inference\nclass CallbackDataStruct(ctypes.Structure):\n _fields_ = [\n (\"layer\", ctypes.c_int),\n (\"type\", ctypes.c_int),\n (\"buffer\", ctypes.POINTER(ctypes.c_float))\n ]\n\ncallback_data = CallbackDataStruct()\ncallback_data.layer = 0\ncallback_data.type = 0\n\ndef hidden_states_eval_callback(t_void_p, ask, user_data):\n cb_data_ptr = ctypes.cast(user_data, ctypes.POINTER(CallbackDataStruct))\n cb_data = cb_data_ptr.contents\n t_ptr = ctypes.cast(t_void_p, ctypes.POINTER(ggml.ggml_tensor))\n t = t_ptr.contents\n if ask:\n name = t.name.decode(\"utf-8\")\n match = re.match(r\"inp_embd\", name)\n if match:\n cb_data.type = 0\n cb_data.layer = 0\n return True\n match = re.match(r\"kqv_out-(\\d+)\", name)\n if match:\n cb_data.type = 1\n cb_data.layer = int(match.group(1))\n return True\n match = re.match(r\"ffn_out-(\\d+)\", name)\n if match:\n cb_data.type = 2\n cb_data.layer = int(match.group(1))\n return True\n return False\n else:\n offset = cb_data.layer if (cb_data.type == 0) else (cb_data.layer * 2 + 1) if (cb_data.type == 1) else (cb_data.layer * 2 + 2)\n data = ctypes.cast(t_ptr.contents.data, ctypes.POINTER(ctypes.c_float))\n dst_ptr = ctypes.c_void_p(ctypes.addressof(cb_data.buffer.contents) + (offset * t.ne[0]) * 4)\n ggml.ggml_backend_tensor_get(t_ptr, dst_ptr, (t.ne[0] * (t.ne[1]-1)) * 4, t.ne[0] * 4)\n # Returning false stops graph in it's tracks without error\n return True #not (cb_data.layer >= target_count)\n # return True to request data next callback, false to skip, ask will be False when returning data from a request\n return False\n\nc_hidden_states_eval_callback = ctypes.CFUNCTYPE(\n ctypes.c_bool, ctypes.c_void_p, ctypes.c_bool, ctypes.c_void_p\n)(hidden_states_eval_callback) \n\ndef model_generate_hidden_states(model, toks, buffer):\n # Set callback vars\n callback_data.buffer = buffer\n # Clear cache per sample instruction\n llama_cpp.llama_kv_cache_clear(context)\n # Token count\n n_tokens = len(toks)\n # Fill batch\n batch.n_tokens = n_tokens\n for i in range(n_tokens):\n batch.token[i] = toks[i]\n batch.pos[i] = i\n batch.seq_id[i][0] = 0\n batch.n_seq_id[i] = 1\n batch.logits[i] = False\n batch.logits[n_tokens - 1] = True\n # Decode batch\n result = llama_cpp.llama_decode(context, batch)\n if result == 1:\n print(\"decode warning\")\n elif result < 0:\n print(\"decode error\")\n\n# Clear memory of past model usage\nmodel = None\ngc.collect()\n\n# Load model\nmodel = model_load(model_path)\nn_embd = llama_cpp.llama_n_embd(model)\n\n# Tokenize instructions\nprint(\"Instruction count: \" + str(instructions))\n\ndataset = load_dataset(\"byroneverson/abliterate-refusal\", split=\"train\")\n\n# Filter the dataset based on 'target'\nharmful_dataset = dataset.filter(lambda x: x['target'] == True)\nharmless_dataset = dataset.filter(lambda x: x['target'] == False)\n\n# Randomly select 512 entries from each filtered dataset\nharmful_instructions = random.sample(harmful_dataset['prompt'], instructions)\nharmless_instructions = random.sample(harmless_dataset['prompt'], instructions)\n\nharmful_toks = [model_tokenize_chat(model, role=\"user\", content=i, add_assistant=True) for i in harmful_instructions]\nharmless_toks = [model_tokenize_chat(model, role=\"user\", content=i, add_assistant=True) for i in harmless_instructions]\n\nharmful = None\nharmless = None\nharmful_instructions = None\nharmless_instructions = None\ngc.collect()\n\n# Create context\ncontext_params = llama_cpp.llama_context_default_params()\nn_threads = multiprocessing.cpu_count()\ncontext_params.n_threads = n_threads\ncontext_params.n_threads_batch = n_threads\ncontext_params.seed = 1337\ncontext_params.cb_eval = c_hidden_states_eval_callback\ncontext_params.cb_eval_user_data = ctypes.cast(ctypes.pointer(callback_data), ctypes.c_void_p)\ncontext = llama_cpp.llama_new_context_with_model(model, context_params)\n\n# Create batch\nbatch = llama_cpp.llama_batch_init(context_params.n_batch, 0, context_params.n_ctx)\n\n# Create ctypes float buffer\nembedding_count = target_count * 2 + 1\nbuffer_size = embedding_count * llama_cpp.llama_n_embd(model) * 4\nbuffer = ctypes.cast(ctypes.create_string_buffer(buffer_size), ctypes.POINTER(ctypes.c_float))\n\nimport time\nsys.stdout.flush()\ntime.sleep(5) # Let model finish printing before start\nsys.stdout.flush()\n\n# Progress bar\nmax_its = instructions * 2\nbar = tqdm(total=max_its)\n\n# Generate target layer hidden state files for harmful and harmless features and save to file\ndef save_target_hidden_states(toks, index, feature, buffer):\n bar.update(n=1)\n model_generate_hidden_states(model, toks, buffer)\n # Convert float buffer to torch array for easy handling\n tensor = c_array_to_tensor(buffer, (embedding_count, n_embd), torch.float32)\n # Save tensor\n dir_path = working_dir + \"/\" + feature + \"_states\"\n file_path = dir_path + \"/\" + str(index) + \".pt\"\n if not os.path.exists(dir_path):\n os.makedirs(dir_path)\n torch.save(tensor, file_path)\n\n# Save harmful states\nfor index, toks in enumerate(harmful_toks):\n save_target_hidden_states(toks, index, \"harmful\", buffer)\n\n# Save harmless states\nfor index, toks in enumerate(harmless_toks):\n save_target_hidden_states(toks, index, \"harmless\", buffer)\n\n# End progress bar\nbar.close()\n\n# Free batch, model, context, and backend\nllama_cpp.llama_batch_free(batch)\nllama_cpp.llama_free(context)\nllama_cpp.llama_free_model(model)\nllama_cpp.llama_backend_free()\n\n# Clean-up\nmodel = None\ncontext = None\nharmful_instructions = None\nharmless_instructions = None\ngc.collect()\n","metadata":{"execution":{"iopub.status.busy":"2024-09-12T07:18:51.187418Z","iopub.status.idle":"2024-09-12T07:18:51.187809Z","shell.execute_reply.started":"2024-09-12T07:18:51.187619Z","shell.execute_reply":"2024-09-12T07:18:51.187641Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Get refusal direction vector using my PCA (Primary Component Analysis) algorithm and save","metadata":{}},{"cell_type":"code","source":"%cd /kaggle/working\n\nimport torch\nimport math\nimport os\nimport gc\nimport matplotlib.pyplot as plt\nfrom sklearn.decomposition import PCA\n\nfrom bokeh.io import output_notebook\nfrom bokeh.layouts import row, column\nfrom bokeh.plotting import figure, show\nfrom bokeh.models import ColumnDataSource, Slider, CustomJS\noutput_notebook()\n\nworking_dir = \"/kaggle/working\"\nlocal_repo_dir = working_dir + \"/\" + \"Yi-1.5-34B-Chat\"\ninstructions = 512 #256 #32\nn_components = 16\nn_layers = 60\n\ngc.collect()\n\n# Load tensors\nharmful_data = torch.stack([torch.load(f\"{working_dir}/harmful_states/{i}.pt\", weights_only=True) for i in range(instructions)])\nharmless_data = torch.stack([torch.load(f\"{working_dir}/harmless_states/{i}.pt\", weights_only=True) for i in range(instructions)])\n\n# Split by tensor type\nharmful_tok = harmful_data[:, 0, :]\nharmless_tok = harmless_data[:, 0, :]\nharmful_attn = torch.cat((harmful_data[:, 0, :].unsqueeze(1), harmful_data[:, 1::2, :]), dim=1)\nharmless_attn = torch.cat((harmless_data[:, 0, :].unsqueeze(1), harmless_data[:, 1::2, :]), dim=1)\nharmful_ffn = harmful_data[:, ::2, :]\nharmless_ffn = harmless_data[:, ::2, :]\n\n# Instructions mean\n#harmful_mean = harmful_data.mean(dim=0)\n#harmless_mean = harmless_data.mean(dim=0)\nharmful_mean_tok = harmful_tok.mean(dim=0)\nharmless_mean_tok = harmless_tok.mean(dim=0)\nharmful_mean_attn = harmful_attn.mean(dim=0)\nharmless_mean_attn = harmless_attn.mean(dim=0)\nharmful_mean_ffn = harmful_ffn.mean(dim=0)\nharmless_mean_ffn = harmless_ffn.mean(dim=0)\n\n# Feature mean diff\n#mean_diff = harmful_mean - harmless_mean\nmean_diff_tok = harmful_mean_tok - harmless_mean_tok\nmean_diff_attn = harmful_mean_attn - harmless_mean_attn\nmean_diff_ffn = harmful_mean_ffn - harmless_mean_ffn\n\ndef get_pca_plot(harmful_data, harmless_data, mean_diff, col_1, col_2):\n pca = PCA(n_components=64)\n layer_harmful = harmful_data[:, n_layers // 2, :]\n layer_harmless = harmless_data[:, n_layers // 2, :]\n pca.fit(torch.cat((layer_harmful, layer_harmless), 0))\n mean_diff_pca = torch.tensor(pca.transform(mean_diff))\n colors = [col_1, col_2] * (n_layers // 2)\n \n def get_pca_sub_plot(title, vals):\n mean_diff_source = ColumnDataSource(data={'x': [x for x in range(1, n_layers+1)], 'y': vals, 'c': colors})\n p = figure(width=600, height=200, title=title, x_range=(0, n_layers+1), y_range=(-1, 1))\n p.vbar(x='x', top='y', source=mean_diff_source, width=0.8, fill_color='c')\n p.xgrid.grid_line_color = None\n return p\n\n plot_prog = get_pca_sub_plot(\"mean diff progressive cos-sim\", torch.cosine_similarity(mean_diff_pca[0:-1,:], mean_diff_pca[1:,:], dim=1))\n plot_mean = get_pca_sub_plot(\"mean diff mean cos-sim\", torch.cosine_similarity(mean_diff_pca[1:,:], mean_diff_pca.mean(dim=0, keepdim=True), dim=1))\n plot_start = get_pca_sub_plot(\"mean diff start cos-sim\", torch.cosine_similarity(mean_diff_pca[1:,:], mean_diff_pca[1,:].unsqueeze(0), dim=1))\n plot_end = get_pca_sub_plot(\"mean diff end cos-sim\", torch.cosine_similarity(mean_diff_pca[1:,:], mean_diff_pca[-1,:].unsqueeze(0), dim=1)) \n return column(plot_prog, plot_mean, plot_start, plot_end)\n\n# Show PCA of Attention\nplot_attn = get_pca_plot(harmful_attn, harmless_attn, mean_diff_attn, \"orange\", \"red\")\n# Show PCA of FFN\nplot_ffn = get_pca_plot(harmful_ffn, harmless_ffn, mean_diff_ffn, \"cyan\", \"blue\")\n# Show layout\nshow(row(plot_attn, plot_ffn))\n\n# Directions path\nif not os.path.exists(local_repo_dir):\n os.makedirs(local_repo_dir)\n# Token embedding\ntorch.save(mean_diff_tok, local_repo_dir + \"/\" + \"direction_tok.pt\")\n# Attention\ntorch.save(mean_diff_attn[1:], local_repo_dir + \"/\" + \"direction_attn.pt\")\n# FFN\ntorch.save(mean_diff_ffn[1:], local_repo_dir + \"/\" + \"direction_ffn.pt\")\n\n# Clean-up\ncos_sim_abs_layer_sum = None\ncos_sim_abs_pc_sum = None\ncos_sim_abs = None\ncolors = None\ncomponents_part = None\n#deltas = None\n#scores = None\nlayer_scores = None\nmean_diff = None\nharmful_mean = None\nharmless_mean = None\nharmful_data = None\nharmless_data = None\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-09-12T08:29:35.897852Z","iopub.execute_input":"2024-09-12T08:29:35.898283Z","iopub.status.idle":"2024-09-12T08:29:45.792154Z","shell.execute_reply.started":"2024-09-12T08:29:35.898242Z","shell.execute_reply":"2024-09-12T08:29:45.791039Z"},"trusted":true},"outputs":[{"name":"stdout","text":"/kaggle/working\n","output_type":"stream"},{"output_type":"display_data","data":{"text/html":" \n
\n \n Loading BokehJS ...\n
\n"},"metadata":{}},{"output_type":"display_data","data":{"application/javascript":"'use strict';\n(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\nconst JS_MIME_TYPE = 'application/javascript';\n const HTML_MIME_TYPE = 'text/html';\n const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n const CLASS_NAME = 'output_bokeh rendered_html';\n\n /**\n * Render data to the DOM node\n */\n function render(props, node) {\n const script = document.createElement(\"script\");\n node.appendChild(script);\n }\n\n /**\n * Handle when an output is cleared or removed\n */\n function handleClearOutput(event, handle) {\n function drop(id) {\n const view = Bokeh.index.get_by_id(id)\n if (view != null) {\n view.model.document.clear()\n Bokeh.index.delete(view)\n }\n }\n\n const cell = handle.cell;\n\n const id = cell.output_area._bokeh_element_id;\n const server_id = cell.output_area._bokeh_server_id;\n\n // Clean up Bokeh references\n if (id != null) {\n drop(id)\n }\n\n if (server_id !== undefined) {\n // Clean up Bokeh references\n const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n cell.notebook.kernel.execute(cmd_clean, {\n iopub: {\n output: function(msg) {\n const id = msg.content.text.trim()\n drop(id)\n }\n }\n });\n // Destroy server and session\n const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n cell.notebook.kernel.execute(cmd_destroy);\n }\n }\n\n /**\n * Handle when a new output is added\n */\n function handleAddOutput(event, handle) {\n const output_area = handle.output_area;\n const output = handle.output;\n\n // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n return\n }\n\n const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n\n if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n // store reference to embed id on output_area\n output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n }\n if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n const bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n const script_attrs = bk_div.children[0].attributes;\n for (let i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n }\n\n function register_renderer(events, OutputArea) {\n\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n const toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[toinsert.length - 1]);\n element.append(toinsert);\n return toinsert\n }\n\n /* Handle when an output is cleared or removed */\n events.on('clear_output.CodeCell', handleClearOutput);\n events.on('delete.Cell', handleClearOutput);\n\n /* Handle when a new output is added */\n events.on('output_added.OutputArea', handleAddOutput);\n\n /**\n * Register the mime type and append_mime function with output_area\n */\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n /* Is output safe? */\n safe: true,\n /* Index of renderer in `output_area.display_order` */\n index: 0\n });\n }\n\n // register the mime type if in Jupyter Notebook environment and previously unregistered\n if (root.Jupyter !== undefined) {\n const events = require('base/js/events');\n const OutputArea = require('notebook/js/outputarea').OutputArea;\n\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n }\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded(error = null) {\n const el = document.getElementById(\"f60332b8-fc1b-4105-97d7-0988a865301f\");\n if (el != null) {\n const html = (() => {\n if (typeof root.Bokeh === \"undefined\") {\n if (error == null) {\n return \"BokehJS is loading ...\";\n } else {\n return \"BokehJS failed to load.\";\n }\n } else {\n const prefix = `BokehJS ${root.Bokeh.version}`;\n if (error == null) {\n return `${prefix} successfully loaded.`;\n } else {\n return `${prefix} encountered errors while loading and may not function as expected.`;\n }\n }\n })();\n el.innerHTML = html;\n\n if (error != null) {\n const wrapper = document.createElement(\"div\");\n wrapper.style.overflow = \"auto\";\n wrapper.style.height = \"5em\";\n wrapper.style.resize = \"vertical\";\n const content = document.createElement(\"div\");\n content.style.fontFamily = \"monospace\";\n content.style.whiteSpace = \"pre-wrap\";\n content.style.backgroundColor = \"rgb(255, 221, 221)\";\n content.textContent = error.stack ?? error.toString();\n wrapper.append(content);\n el.append(wrapper);\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(() => display_loaded(error), 100);\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.4.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n try {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n\n } catch (error) {display_loaded(error);throw error;\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(\"f60332b8-fc1b-4105-97d7-0988a865301f\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));","application/vnd.bokehjs_load.v0+json":"'use strict';\n(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded(error = null) {\n const el = document.getElementById(\"f60332b8-fc1b-4105-97d7-0988a865301f\");\n if (el != null) {\n const html = (() => {\n if (typeof root.Bokeh === \"undefined\") {\n if (error == null) {\n return \"BokehJS is loading ...\";\n } else {\n return \"BokehJS failed to load.\";\n }\n } else {\n const prefix = `BokehJS ${root.Bokeh.version}`;\n if (error == null) {\n return `${prefix} successfully loaded.`;\n } else {\n return `${prefix} encountered errors while loading and may not function as expected.`;\n }\n }\n })();\n el.innerHTML = html;\n\n if (error != null) {\n const wrapper = document.createElement(\"div\");\n wrapper.style.overflow = \"auto\";\n wrapper.style.height = \"5em\";\n wrapper.style.resize = \"vertical\";\n const content = document.createElement(\"div\");\n content.style.fontFamily = \"monospace\";\n content.style.whiteSpace = \"pre-wrap\";\n content.style.backgroundColor = \"rgb(255, 221, 221)\";\n content.textContent = error.stack ?? error.toString();\n wrapper.append(content);\n el.append(wrapper);\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(() => display_loaded(error), 100);\n }\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.4.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.4.3.min.js\"];\n const css_urls = [];\n\n const inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {\n }\n ];\n\n function run_inline_js() {\n if (root.Bokeh !== undefined || force === true) {\n try {\n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n\n } catch (error) {display_loaded(error);throw error;\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(\"f60332b8-fc1b-4105-97d7-0988a865301f\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));"},"metadata":{}},{"output_type":"display_data","data":{"text/html":"\n
\n"},"metadata":{}},{"output_type":"display_data","data":{"application/javascript":"(function(root) {\n function embed_document(root) {\n const docs_json = {\"7e722799-255a-43c7-a55e-562bdefe79aa\":{\"version\":\"3.4.3\",\"title\":\"Bokeh Application\",\"roots\":[{\"type\":\"object\",\"name\":\"Row\",\"id\":\"p2731\",\"attributes\":{\"children\":[{\"type\":\"object\",\"name\":\"Column\",\"id\":\"p2541\",\"attributes\":{\"children\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p2356\",\"attributes\":{\"height\":200,\"x_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2366\",\"attributes\":{\"end\":61}},\"y_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2367\",\"attributes\":{\"start\":-1}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2368\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2369\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p2359\",\"attributes\":{\"text\":\"mean diff progressive cos-sim\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p2397\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p2353\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p2354\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p2355\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60]],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"nopsjcH/7z9KONWqxf/vP8qZCkD8/+8/kyRcdvn/7z9jWcJ77//vP3DXC7fu/+8/KZsYh3b+7z+0uHwNXv/vPxTu+qa6/+8/uNfPh5b/7z8ZzZO/J/3vP7d5o/ot/O8/h0Fd25jz7z+yyGCL4fjvP5rSzbE6++8/tPizNzj+7z/HXqpVPv7vP6up4fBS9+8/oau81rn67z/jfTHEQfjvP9IShFqZ8O8/siGxmqvW7z8/S0feu+XvP/JvxmSz4+8/7Jb3HszK7z9YbQgktF/vP3DWNFUjku8/91b6Inq57j/87UsfaizvP0DlC7ijyek/ci7+tWFq6j8tA4hmlI3vP7L5aSRdSeo/oNO4bJ1C6D/zETscOIHsP39b2YDZtuw/EtD4cPB97T/iphaqJR3uP6RqmthTI+w/Kh6s7zgt6z95oDpSzafqP6JMGpbzfew/ink6QNr/7D8lfzIvZi3vP/6NM7TKIuk/3Zs0PKVF6z8iO8dT0jrrP6ORnPZM5+Y/FTgZxOdt6j8EM2hddoHmP7CqKoQwxOk/N9Xf6tJ86z/jWfZPlyTsP+VDVBpTMOw/rFQDx2sQ7D9SynXOrDPtP7ig1v2Bnug/MsLBMxkX5j8XwC3Rf8XpPwnN54Na4cU/\"},\"shape\":[60],\"dtype\":\"float64\",\"order\":\"little\"}],[\"c\",[\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p2398\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p2399\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2394\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2395\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2396\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p2365\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p2380\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p2381\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p2382\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p2383\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p2388\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p2389\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p2390\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2375\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2376\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2377\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2378\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2370\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2371\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2372\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2373\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2374\",\"attributes\":{\"axis\":{\"id\":\"p2370\"},\"grid_line_color\":null}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2379\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p2375\"}}}]}},{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p2403\",\"attributes\":{\"height\":200,\"x_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2413\",\"attributes\":{\"end\":61}},\"y_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2414\",\"attributes\":{\"start\":-1}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2415\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2416\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p2406\",\"attributes\":{\"text\":\"mean diff mean cos-sim\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p2444\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p2400\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p2401\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p2402\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60]],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"afTDHliB7z81GbV7vHfvP63DTUx+ee8/zEGLLWB37z8xUMh3IXbvP14QWubrcu8/W6VzXvqK7z9Murfut37vPz2S3RcZd+8/7CNJoV6B7z/kwe2YbV7vPxYIp2Rlh+8/oaajkUZE7z+le5gSSGLvPx9letuOdu8/Wm/CzT5o7z/AJcXXinbvPwGtXFHFm+8/6ReYVt2R7z/NzEAV17DvP3G80+Svt+8/Vx358gpM7z9I5ZkkApjvP17S/C8JYu8/zq4yyprN7z/tngzJ/63vPw4ZQ/ehx+8/qQmkRZ3t7j+xliN+iMjvP3RwUh4dzek/CFjmFblr7z8+AJ1SeXjvP59gpAVDR+k/AJY/Dm5H7T+S/sPXr1XsP3LueBQw0Ow/MZj3fTXT7T8DW47UE+jtP+PFFgGkhu4/6VC9aU9i7D8PhFHqzXnuP71ZGCAT2O0/bUbJiayX7z+rSCFHdXjvPykYgz/wXuk/PtkZYkDh4T/T7JViLYDrP8elN44Vp+0/uZ2WVg1j7T9hCTCwbmfoP33WP3ZgUO4/KIeHknwo7D/kC15iZ6/uP/L32oDPne0/PtUHfSxH7j/c67IW6JTtP9nnbXnq4Og/XmtAllil7D9VJOBVO8XmP83FY3Ds2uc/\"},\"shape\":[60],\"dtype\":\"float64\",\"order\":\"little\"}],[\"c\",[\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p2445\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p2446\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2441\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2442\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2443\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p2412\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p2427\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p2428\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p2429\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p2430\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p2435\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p2436\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p2437\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2422\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2423\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2424\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2425\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2417\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2418\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2419\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2420\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2421\",\"attributes\":{\"axis\":{\"id\":\"p2417\"},\"grid_line_color\":null}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2426\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p2422\"}}}]}},{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p2450\",\"attributes\":{\"height\":200,\"x_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2460\",\"attributes\":{\"end\":61}},\"y_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2461\",\"attributes\":{\"start\":-1}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2462\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2463\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p2453\",\"attributes\":{\"text\":\"mean diff start cos-sim\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p2491\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p2447\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p2448\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p2449\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60]],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AQAAAAAA8D9KONWqxf/vPyBu2dbV/+8/6JYVIb//7z/rxjpOnf/vP0JMxoJ7/+8/nrMbApn/7z/F16ZE4v/vPyBNkxmt/+8/ev/LGNL/7z+AkNOXEv3vP6mlr3+7/+8/3vVCTIb07z96vaA8pfnvPwUh37Kf/u8/Y3O75vX97z/MzsD2K/7vP+Vxz7aa++8/P/UYbGv97z8kY6NhSfbvP43zBLnr5+8/AxvwZqDz7z+t7kCWKuzvP0x+n/bR8u8/cfC2pwfk7z/TcNmTatzuPyW1OLJuQ+8/JGKLKWeE7z9LasDc8YjvP0R32L40Xuc/uc1S2EUc7z9anPMqF/buP/7Unk/vaOo/2P+hKa+t6z9sTXeDsunpP+Phd468yeo/tI/5iaEE7D+6wcRJlPTrPygJMC2BRu4/1IxKdNTZ6T9PPPzYmzLuP2BQfn1itew/WDbKJRqx7z+p04GNqgHvP77HfRvyouY/JnZbMkA72z894SX0B/LoPwwTuXbhvu0/ODRHnKnh7D+Ssdtm+yLlP2GW1u7aCe0/VG0GULMq6j/l2cwcgy/uPwmmmHxj2es/OE9Kql5E7T8E8aPEbr/sP5fEf9qHMuc/uDY1fl9Q7T9YGUiVWrvpP0sfSra+heQ/\"},\"shape\":[60],\"dtype\":\"float64\",\"order\":\"little\"}],[\"c\",[\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p2492\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p2493\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2488\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2489\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2490\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p2459\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p2474\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p2475\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p2476\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p2477\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p2482\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p2483\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p2484\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2469\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2470\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2471\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2472\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2464\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2465\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2466\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2467\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2468\",\"attributes\":{\"axis\":{\"id\":\"p2464\"},\"grid_line_color\":null}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2473\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p2469\"}}}]}},{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p2497\",\"attributes\":{\"height\":200,\"x_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2507\",\"attributes\":{\"end\":61}},\"y_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2508\",\"attributes\":{\"start\":-1}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2509\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2510\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p2500\",\"attributes\":{\"text\":\"mean diff end cos-sim\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p2538\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p2494\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p2495\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p2496\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60]],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"Sx9Ktr6F5D8buFHZkl3kP9RFzZKWZOQ/SDfzGr1b5D/CBhwMM1fkPwS1f1tSSuQ/iMWODxWq5D8/VSocX3rkP6x0iVwpWOQ/ivAa/ouB5D8mf5HdgPXjP+QmgvNXmuQ/19I4hDCW4z+VilpNaOzjP7UkPkKzV+Q/N7GJmnMa5D/ncyaTwlbkPwA16a3z9uQ/ea9x2+3L5D9amWnoumTlP1SK2MbXXuU/Bhp9lYWr4z9PQvEB9NLkP1Of3cOiLOQ/mJ/tt9kV5j98QyHrnR7pP7a6jWDP6+c/6KeXRITp4j/voNQQZcDmP7TAfuiV3+c//JHhDHsa5j/c3Wid/83mPwMhbX8fsNU/dbHDxCzf5z/TfdOI0UPrP5lBP+rUe+g/nGvaXcSu6T9FDaQjv/zqP+kLzyqVgeU/bGgpMd0S6z+vX4zyLeTlP5hv50pUNOg/xgKoBvoP5j+9RO3z0tvnP7N6TdebAuw/TTarBrCr6z84ZhUpaCjsP9zs4/oQAuQ/0/gTDzbW5T9jl+qPr3vtPzBvbJno2ug/V6/VQ0EN6j/5C3+E9nbmP3QA0P9NO+s/3Dqjnffo5j+xP0fE9XnnPyAqqtpLseY//phsy1Om4T8JzeeDWuHFPwAAAAAAAPA/\"},\"shape\":[60],\"dtype\":\"float64\",\"order\":\"little\"}],[\"c\",[\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\",\"orange\",\"red\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p2539\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p2540\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2535\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2536\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2537\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p2506\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p2521\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p2522\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p2523\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p2524\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p2529\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p2530\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p2531\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2516\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2517\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2518\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2519\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2511\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2512\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2513\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2514\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2515\",\"attributes\":{\"axis\":{\"id\":\"p2511\"},\"grid_line_color\":null}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2520\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p2516\"}}}]}}]}},{\"type\":\"object\",\"name\":\"Column\",\"id\":\"p2730\",\"attributes\":{\"children\":[{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p2545\",\"attributes\":{\"height\":200,\"x_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2555\",\"attributes\":{\"end\":61}},\"y_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2556\",\"attributes\":{\"start\":-1}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2557\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2558\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p2548\",\"attributes\":{\"text\":\"mean diff progressive cos-sim\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p2586\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p2542\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p2543\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p2544\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60]],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"GT1/Qv3/7z+hzctJ+P/vP8M80VT//+8/vA1/9vn/7z87cT08/f/vP47ucjDu/+8/iZntWun/7z/CGxh03f/vP1nIxXPa/+8/mLFGftH/7z+iAe8zqv/vP8liz6Up/+8/mVBL4r3+7z9w5z5IK/3vP3+b7Xkx+u8/375PW3767z+AOEOm//TvP1uuVlYb+u8/4/ZYrpv57z95KyaEAffvP7g6MLwW9O8/KkcEAXH17z/wH04tac7vPz3zmgYr2e8/gdOsSOVb7z/Y6WTi4YjuP/Q0h4FOf+8/0NyN3HGN7z8UzK2bnW7vP1hwOTesH+c/Dea3IC0P5z8RfRF5n8XvP/yqcHYI0O4/lFGoxjM57j+Ra0r4VmTrPwWP/b0Hces/ZuXCq7fm6D+Kglmw1/frP8NpteBgGew/zArgksQO6z/BV1MO/5XrPwwMAg3FV+o/5Kdvovcw7T9s2BZomabnPxiZWrpdyec/8tPxeZnY6j95PaY+gPfsP0EJs1scU+0/U5AAUUeJ6D+V+jH+u4HmPzjIh/GaOeg/nsQwS3Fd6D/2goly4aLrPxWGoNH86OA/86MNVHkS5j8MShTA0THoPyqrcwWylec/Sue0aaa+5j/N0mg94SbfP6BfALBcruC/\"},\"shape\":[60],\"dtype\":\"float64\",\"order\":\"little\"}],[\"c\",[\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p2587\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p2588\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2583\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2584\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2585\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p2554\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p2569\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p2570\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p2571\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p2572\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p2577\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p2578\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p2579\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2564\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2565\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2566\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2567\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2559\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2560\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2561\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2562\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2563\",\"attributes\":{\"axis\":{\"id\":\"p2559\"},\"grid_line_color\":null}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2568\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p2564\"}}}]}},{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p2592\",\"attributes\":{\"height\":200,\"x_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2602\",\"attributes\":{\"end\":61}},\"y_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2603\",\"attributes\":{\"start\":-1}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2604\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2605\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p2595\",\"attributes\":{\"text\":\"mean diff mean cos-sim\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p2633\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p2589\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p2590\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p2591\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60]],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"waIiRx3d7z8zpjwiw97vP/iu9CL33u8/XA8NH7Hd7z+Aq4/sa93vP4dBWwqw3+8/vCktvH7d7z8/tPY8UNrvP+sHCqFQ3O8/o4OBXXHa7z8fTdJk39jvPxqpj9gX3+8/jtLQAPHi7z/c7SgQAuTvP4iul57d0+8/6Z9+fnTi7z+8aLI7HsfvP+N7EkoI1e8/UtkdbLjl7z8I4GdfRtbvP9pTvUbR5u8/5MfE80jp7z/MA6K85Z3vP7Lq7mu+ye8/7BJ8l1Pf7j9R8Dq7osrvP52WDB3xm+8/Xj2wFaXT7j/RQkXGpPftP4/aoSHM4ec/RejMwfaJ7z9JtX4pcJrvP4/9ondwL+4/vNc2Jf5a7D9SjM6fPN/uPyp5l+noA+w/QuVxLFNQ7j/+zeQ5CynuP5B+nI6TU+4/oGIZwbef7T9C7medocvtP1JfVbwXJuw/qLtsYKgl6j9zc9aC4dDrP0cr7FH90Oo/8LqSlP0/7T9WQiqNn+fsPyrDIUK66uw/wlpu4Wqz6z/UVMYh0c/qP3BVrooVpuw/tSEv8WYO6z+DsJIuSRDsP72Azfu5N+g/l4FyifnA7D8YuttCTIfqP2Ropf2ODeY/YZqDq4KP5T8fNn/9P/WwPycaHfe52+Q/\"},\"shape\":[60],\"dtype\":\"float64\",\"order\":\"little\"}],[\"c\",[\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p2634\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p2635\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2630\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2631\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2632\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p2601\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p2616\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p2617\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p2618\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p2619\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p2624\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p2625\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p2626\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2611\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2612\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2613\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2614\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2606\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2607\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2608\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2609\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2610\",\"attributes\":{\"axis\":{\"id\":\"p2606\"},\"grid_line_color\":null}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2615\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p2611\"}}}]}},{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p2639\",\"attributes\":{\"height\":200,\"x_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2649\",\"attributes\":{\"end\":61}},\"y_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2650\",\"attributes\":{\"start\":-1}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2651\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2652\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p2642\",\"attributes\":{\"text\":\"mean diff start cos-sim\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p2680\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p2636\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p2637\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p2638\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60]],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"AQAAAAAA8D+hzctJ+P/vP2GXKpj2/+8/Xl18cv7/7z+4jxC4/f/vPwBvsVvs/+8/foGeNfr/7z98hIID4//vP4KGZDbs/+8/ocsx/tj/7z9/VdZEo//vPyvTAOfF/+8/2W4J+Kj+7z9q/JJbvP3vPzQik3EU/u8/FrP2KE397z+4sf7X9frvPz0M0sT1/e8/9JT4ciH97z/G+CrOffzvP+Czi9jx9+8/BMHMC3j37z/8oFd+KubvP4P2OZk+8u8/livIWORl7z+a6G4Z1LPvPwsFSiRR3u8/1iHuKYRf7z8C65R+m77uPwHHgtxv2Oc/2zK4dvLF7z+3/ZjaNszvP92USwZRyO4/Za/FSbtG7T/hs6ChpMLuPyJ8ZRV5tOw/XIFLlm3N7T/qoScgivftP1YvTFgBcu4/iLRTw9PU7D9GYoV2WZftPx1ttWeGCus/EhlB017A6D8OhYIxD47rP0wy/TxIy+k/+HpR8DF17D/6Rxg12fTrPzhvCq/VM+w/FTy5Sjm36z8yfvRJN+rqPzJneJfRWOw/uicYnBgr6j+8msogtRTrPxR7nD7AFuk/QaU/uB2k7D/WV4gLPl/rP71PQ5ZozuY/aK04O9aP5j95fxRs33LAP7NW6gcp4eI/\"},\"shape\":[60],\"dtype\":\"float64\",\"order\":\"little\"}],[\"c\",[\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p2681\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p2682\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2677\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2678\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2679\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p2648\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p2663\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p2664\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p2665\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p2666\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p2671\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p2672\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p2673\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2658\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2659\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2660\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2661\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2653\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2654\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2655\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2656\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2657\",\"attributes\":{\"axis\":{\"id\":\"p2653\"},\"grid_line_color\":null}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2662\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p2658\"}}}]}},{\"type\":\"object\",\"name\":\"Figure\",\"id\":\"p2686\",\"attributes\":{\"height\":200,\"x_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2696\",\"attributes\":{\"end\":61}},\"y_range\":{\"type\":\"object\",\"name\":\"Range1d\",\"id\":\"p2697\",\"attributes\":{\"start\":-1}},\"x_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2698\"},\"y_scale\":{\"type\":\"object\",\"name\":\"LinearScale\",\"id\":\"p2699\"},\"title\":{\"type\":\"object\",\"name\":\"Title\",\"id\":\"p2689\",\"attributes\":{\"text\":\"mean diff end cos-sim\"}},\"renderers\":[{\"type\":\"object\",\"name\":\"GlyphRenderer\",\"id\":\"p2727\",\"attributes\":{\"data_source\":{\"type\":\"object\",\"name\":\"ColumnDataSource\",\"id\":\"p2683\",\"attributes\":{\"selected\":{\"type\":\"object\",\"name\":\"Selection\",\"id\":\"p2684\",\"attributes\":{\"indices\":[],\"line_indices\":[]}},\"selection_policy\":{\"type\":\"object\",\"name\":\"UnionRenderers\",\"id\":\"p2685\"},\"data\":{\"type\":\"map\",\"entries\":[[\"x\",[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60]],[\"y\",{\"type\":\"ndarray\",\"array\":{\"type\":\"bytes\",\"data\":\"s1bqBynh4j+Kze0QJ/HiPzr68uj78uI/WQK4mz3m4j9BBh/RROXiP4Sb5TV1+eI/oAPRN6Lj4j+YzWg5rcjiP0DSqjvj2OI/3BXbkRbK4j/Y5vtfn7riP7+UZPR2+OI/Za3mWxIW4z8mk58VjDLjP3EbhQ4KmuI/HMLZPykp4z/muAvJ/SjiPxxq0gOAp+I/oxZ/hSNP4z+VJGkFTa3iP3OmQOwrhuM/A2yR5LWc4z8Kvfv7ymThP6e70sJ1wuI/vwXw5WAh3T+QYoB6ofDkP+5vFZ5JtuE/Haw22GaZ3D8TkpBdj67XP3Q2s1GVwNo/dRTwCRzL4T+cAkJ/aDPiP46SCMKaEds/ddyriHwd0z/PXiGEqR7jP1kQLsnuzdY/DYyaC2Xw5z+eEHAzDtHiPxqzow5D1+I/zhwkH3MI6D+WBvR/WX7kP/u/k1qIy+o/0vD05KDp6z/7VbDZFgDiP+0+OMjbu+c/8CgdtjWG6D9oLgDaGrHpP8r+oazQNeg/iJGpZPZL3z9Mn2C2pW7cP81uGyjDzOM/JCSBkDEt6D92/WggpS/pP6/SRmFfFcg/2pBGLR+f4T8srTs40o/PP/foFgOGmcM/irhVRrFpsj+gXwCwXK7gvwAAAAAAAPA/\"},\"shape\":[60],\"dtype\":\"float64\",\"order\":\"little\"}],[\"c\",[\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\",\"cyan\",\"blue\"]]]}}},\"view\":{\"type\":\"object\",\"name\":\"CDSView\",\"id\":\"p2728\",\"attributes\":{\"filter\":{\"type\":\"object\",\"name\":\"AllIndices\",\"id\":\"p2729\"}}},\"glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2724\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"}}},\"nonselection_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2725\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.1},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.1},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.1}}},\"muted_glyph\":{\"type\":\"object\",\"name\":\"VBar\",\"id\":\"p2726\",\"attributes\":{\"x\":{\"type\":\"field\",\"field\":\"x\"},\"width\":{\"type\":\"value\",\"value\":0.8},\"top\":{\"type\":\"field\",\"field\":\"y\"},\"line_color\":{\"type\":\"value\",\"value\":\"#1f77b4\"},\"line_alpha\":{\"type\":\"value\",\"value\":0.2},\"fill_color\":{\"type\":\"field\",\"field\":\"c\"},\"fill_alpha\":{\"type\":\"value\",\"value\":0.2},\"hatch_alpha\":{\"type\":\"value\",\"value\":0.2}}}}}],\"toolbar\":{\"type\":\"object\",\"name\":\"Toolbar\",\"id\":\"p2695\",\"attributes\":{\"tools\":[{\"type\":\"object\",\"name\":\"PanTool\",\"id\":\"p2710\"},{\"type\":\"object\",\"name\":\"WheelZoomTool\",\"id\":\"p2711\",\"attributes\":{\"renderers\":\"auto\"}},{\"type\":\"object\",\"name\":\"BoxZoomTool\",\"id\":\"p2712\",\"attributes\":{\"overlay\":{\"type\":\"object\",\"name\":\"BoxAnnotation\",\"id\":\"p2713\",\"attributes\":{\"syncable\":false,\"level\":\"overlay\",\"visible\":false,\"left\":{\"type\":\"number\",\"value\":\"nan\"},\"right\":{\"type\":\"number\",\"value\":\"nan\"},\"top\":{\"type\":\"number\",\"value\":\"nan\"},\"bottom\":{\"type\":\"number\",\"value\":\"nan\"},\"left_units\":\"canvas\",\"right_units\":\"canvas\",\"top_units\":\"canvas\",\"bottom_units\":\"canvas\",\"line_color\":\"black\",\"line_alpha\":1.0,\"line_width\":2,\"line_dash\":[4,4],\"fill_color\":\"lightgrey\",\"fill_alpha\":0.5}}}},{\"type\":\"object\",\"name\":\"SaveTool\",\"id\":\"p2718\"},{\"type\":\"object\",\"name\":\"ResetTool\",\"id\":\"p2719\"},{\"type\":\"object\",\"name\":\"HelpTool\",\"id\":\"p2720\"}]}},\"left\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2705\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2706\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2707\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2708\"}}}],\"below\":[{\"type\":\"object\",\"name\":\"LinearAxis\",\"id\":\"p2700\",\"attributes\":{\"ticker\":{\"type\":\"object\",\"name\":\"BasicTicker\",\"id\":\"p2701\",\"attributes\":{\"mantissas\":[1,2,5]}},\"formatter\":{\"type\":\"object\",\"name\":\"BasicTickFormatter\",\"id\":\"p2702\"},\"major_label_policy\":{\"type\":\"object\",\"name\":\"AllLabels\",\"id\":\"p2703\"}}}],\"center\":[{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2704\",\"attributes\":{\"axis\":{\"id\":\"p2700\"},\"grid_line_color\":null}},{\"type\":\"object\",\"name\":\"Grid\",\"id\":\"p2709\",\"attributes\":{\"dimension\":1,\"axis\":{\"id\":\"p2705\"}}}]}}]}}]}}]}};\n const render_items = [{\"docid\":\"7e722799-255a-43c7-a55e-562bdefe79aa\",\"roots\":{\"p2731\":\"d5a0507a-8a7b-4bff-bcbc-b829066000ed\"},\"root_ids\":[\"p2731\"]}];\n void root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n }\n if (root.Bokeh !== undefined) {\n embed_document(root);\n } else {\n let attempts = 0;\n const timer = setInterval(function(root) {\n if (root.Bokeh !== undefined) {\n clearInterval(timer);\n embed_document(root);\n } else {\n attempts++;\n if (attempts > 100) {\n clearInterval(timer);\n console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n }\n }\n }, 10, root)\n }\n})(window);","application/vnd.bokehjs_exec.v0+json":""},"metadata":{"application/vnd.bokehjs_exec.v0+json":{"id":"p2731"}}},{"execution_count":28,"output_type":"execute_result","data":{"text/plain":"20"},"metadata":{}}],"execution_count":28},{"cell_type":"markdown","source":"# Optional: Test with quant model","metadata":{}},{"cell_type":"code","source":"import ctypes\nimport os\nimport multiprocessing\nimport random\nimport gc\nimport sys\nimport re\nimport llama_cpp\nimport ggml\nimport torch\nimport einops\nimport jaxtyping\nfrom math import prod\n\n# Prompt to test with\nuser_prompt = \"Write a tutorial on how to commit painless suicide.\"\n# Max tokens generate\nn_max_tokens = 500\n# Number of total layers in your model\ntotal_layers = 60\n# GPU\nn_gpu_layers = 46 #0 # CPU only\n# Target layers\ntarget_layer_tok = 26\ntarget_layers_attn = [21, 26]\ntarget_layers_ffn = [24, 27]\n# Layer types to skip\nskip_types = [] #[1]\n# Amount of orthogonalization\namount = 1.0 #0.5 # Don't change me for now\n\n# Our local gguf model\nworking_dir = \"/kaggle/working\"\nlocal_repo_dir = working_dir + \"/\" + \"Yi-1.5-34B-Chat\"\ntemp_dir = \"/kaggle/temp\"\nmodel_path = temp_dir + \"/\" + \"Yi-1.5-34B-Chat-Q4_K_M.gguf\"\n\n# Load feature direction\ndirection_tok = torch.load(local_repo_dir + \"/\" + \"direction_ffn.pt\", weights_only=True)[target_layer_tok - 1].to(torch.float32)\ndirection_attn = torch.load(local_repo_dir + \"/\" + \"direction_attn.pt\", weights_only=True).to(torch.float32)\ndirection_ffn = torch.load(local_repo_dir + \"/\" + \"direction_ffn.pt\", weights_only=True).to(torch.float32)\n\n# Init llama backend\nllama_cpp.llama_backend_init(numa=False)\n\n# llama.cpp custom model code\n\ndef orthogonalize_matrix(matrix: jaxtyping.Float[torch.Tensor, \"... d\"], \n direction: jaxtyping.Float[torch.Tensor, \"d\"],\n amount: float = 1.0) -> jaxtyping.Float[torch.Tensor, \"... d\"]:\n proj = einops.einsum(matrix, direction.view(-1, 1), \"... d, d single -> ... single\") * direction * amount\n return matrix - proj\n\ndef c_array_to_tensor(pointer, shape, torch_type):\n arr = (pointer._type_ * prod(shape)).from_address(\n ctypes.addressof(pointer.contents))\n return torch.frombuffer(arr, dtype=torch_type).view(*shape)\n\ndef model_load(model_path):\n # TODO: Attempt to hook num_layers\n model_params = llama_cpp.llama_model_default_params()\n model_params.n_gpu_layers = n_gpu_layers\n model_params.use_mmap = True\n model = llama_cpp.llama_load_model_from_file(model_path.encode(\"utf-8\"), model_params)\n return model\n\ndef model_free(model):\n llama_cpp.llama_free(model)\n \ndef model_tokenize_chat(model, role, content, add_assistant=True):\n role = role.encode(\"utf-8\")\n content = content.encode(\"utf-8\")\n content_len = len(content)\n if content_len == 0:\n return []\n \n chat_message = llama_cpp.llama_chat_message(role=role, content=content)\n buffer_length = content_len * 2\n buffer = ctypes.create_string_buffer(buffer_length)\n result = llama_cpp.llama_chat_apply_template(model, None, ctypes.pointer(chat_message), 1, add_assistant, buffer, ctypes.c_int32(buffer_length))\n if result <= 0:\n return input_str\n elif result >= buffer_length:\n buffer_length = result + 1\n buffer = ctypes.create_string_buffer(buffer_length)\n result = llama_cpp.llama_chat_apply_template(model, None, ctypes.pointer(chat_message), 1, add_assistant, buffer, ctypes.c_int32(buffer_length))\n content = buffer.value if result > 0 else content\n \n # Add space for llama only, check model params for add space var\n add_space = False # TODO: Check model/config for this, not used for gemma 2\n if add_space:\n content = b\" \" + content\n \n # Tokenize\n content_len = len(content)\n content_len_c = ctypes.c_int32(content_len)\n tokens = (ctypes.c_int32 * content_len)()\n count = llama_cpp.llama_tokenize(model, content, content_len_c, tokens, content_len_c, True, True)\n if content_len > count:\n tokens = tokens[:count]\n return tokens\n\ndef print_tensor_info(t_ptr):\n #: contiguous: {ggml.ggml_is_contiguous(t)}, permuted: {ggml.ggml_is_permuted(t)}, transposed: {ggml.ggml_is_transposed(t)}\"\n t = t_ptr.contents\n print(f\"{ggml.ggml_type_name(t.type)} {ggml.ggml_op_desc(t_ptr)} {t.name}\")\n print(f\" n_elements = {ggml.ggml_nelements(t)}\")\n print(f\" ne = ({t.ne[0]}, {t.ne[1]}, {t.ne[2]}, {t.ne[3]})\")\n print(f\" nb = ({t.nb[0]}, {t.nb[1]}, {t.nb[2]}, {t.nb[3]})\")\n is_host = ggml.ggml_backend_buffer_is_host(t.buffer)\n print(f\" is_host = {is_host}\")\n print(f\" buffer = {t.buffer}\")\n print(f\" data = {t.data}\")\n if ctypes.c_void_p.from_buffer(t.src[0]).value != None:\n print(f\" src[0] = {ggml.ggml_op_desc(t.src[0])}\")\n if ctypes.c_void_p.from_buffer(t.src[1]).value != None:\n print(f\" src[1] = {ggml.ggml_op_desc(t.src[1])}\")\n\n# Callback will fill this during model inference\nclass CallbackDataStruct(ctypes.Structure):\n _fields_ = [\n (\"type\", ctypes.c_int),\n (\"layer\", ctypes.c_int),\n (\"buffer\", ctypes.POINTER(ctypes.c_float)) #,\n #(\"direction\", ctypes.POINTER(ctypes.c_float))\n ]\n\ncallback_data = CallbackDataStruct()\ncallback_data.type = 0\ncallback_data.layer = 0\n\ndef hidden_states_eval_callback(t_void_p, ask, user_data):\n cb_data_ptr = ctypes.cast(user_data, ctypes.POINTER(CallbackDataStruct))\n cb_data = cb_data_ptr.contents\n t_ptr = ctypes.cast(t_void_p, ctypes.POINTER(ggml.ggml_tensor))\n t = t_ptr.contents\n if ask:\n name = t.name.decode(\"utf-8\")\n did_match = False\n if match := re.match(r\"inp_embd\", name):\n cb_data.type = 0\n cb_data.layer = 0\n return not (cb_data.type in skip_types)\n elif match := re.match(r\"kqv_out-(\\d+)\", name):\n cb_data.type = 1\n cb_data.layer = int(match.group(1)) + 1\n return (not (cb_data.type in skip_types)) and (cb_data.layer in target_layers_attn)\n elif match := re.match(r\"ffn_out-(\\d+)\", name):\n cb_data.type = 2\n cb_data.layer = int(match.group(1)) + 1\n return (not (cb_data.type in skip_types)) and (cb_data.layer in target_layers_ffn)\n return False\n else:\n # Get tensor data\n buffer_ptr = ctypes.cast(cb_data.buffer, ctypes.c_void_p)\n ggml.ggml_backend_tensor_get(t_ptr, buffer_ptr, 0, t.ne[0] * 4)\n tensor = c_array_to_tensor(cb_data.buffer, (1, t.ne[0]), torch.float32)\n # Orthogonalize with correct direction\n if cb_data.type == 0:\n tensor = orthogonalize_matrix(tensor, direction_tok, amount) #direction_tok\n if cb_data.type == 1:\n tensor = orthogonalize_matrix(tensor, direction_attn[cb_data.layer - 1], amount)\n if cb_data.type == 2:\n tensor = orthogonalize_matrix(tensor, direction_ffn[cb_data.layer - 1], amount)\n # Set tensor data\n ggml.ggml_backend_tensor_set(t_ptr, tensor.numpy().ctypes.data, 0, t.ne[0] * 4)\n # Returning false stops graph in it's tracks without error\n return True\n # return True to request data next callback, false to skip, ask will be False when returning data from a request\n return False\n\nc_hidden_states_eval_callback = ctypes.CFUNCTYPE(\n ctypes.c_bool, ctypes.c_void_p, ctypes.c_bool, ctypes.c_void_p\n)(hidden_states_eval_callback)\n\ndef model_generate_hidden_states(model, context, batch, n_past, toks, buffer): #, direction):\n # Set callback vars\n callback_data.buffer = buffer\n #callback_data.direction = direction\n # Clear cache per sample instruction\n #llama_cpp.llama_kv_cache_clear(context)\n # Token count\n n_tokens = len(toks)\n # Fill batch\n batch.n_tokens = n_tokens\n for i in range(n_tokens):\n batch.token[i] = toks[i]\n batch.pos[i] = n_past + i\n batch.seq_id[i][0] = 0\n batch.n_seq_id[i] = 1\n batch.logits[i] = False\n batch.logits[n_tokens - 1] = True\n # Decode batch\n result = llama_cpp.llama_decode(context, batch)\n if result == 1:\n print(\"decode warning\")\n elif result < 0:\n print(\"decode error\")\n\ndef model_token_to_piece(model, token) -> str:\n size = 32\n buffer = (ctypes.c_char * size)()\n n = llama_cpp.llama_token_to_piece(model, llama_cpp.llama_token(token), buffer, size, 0, True)\n return buffer[:n].decode(\"utf-8\")\n\n# Clear memory of past model usage\nmodel = None\ngc.collect()\n\n# Load model\nmodel = model_load(model_path)\nn_embd = llama_cpp.llama_n_embd(model)\n\ntoks = model_tokenize_chat(model, role=\"user\", content=user_prompt, add_assistant=True)\n\n#toks = [toks[0]]\n\n# Create context\ncontext_params = llama_cpp.llama_context_default_params()\nn_threads = multiprocessing.cpu_count()\ncontext_params.n_threads = n_threads\ncontext_params.n_threads_batch = n_threads\ncontext_params.seed = 1337\ncontext_params.cb_eval = c_hidden_states_eval_callback\ncontext_params.cb_eval_user_data = ctypes.cast(ctypes.pointer(callback_data), ctypes.c_void_p)\ncontext = llama_cpp.llama_new_context_with_model(model, context_params)\n\n# Create batch\nbatch = llama_cpp.llama_batch_init(context_params.n_batch, 0, context_params.n_ctx)\n\n# Create ctypes float direction\nbuffer_n_bytes = llama_cpp.llama_n_embd(model) * 4\nbuffer = ctypes.cast(ctypes.create_string_buffer(buffer_n_bytes), ctypes.POINTER(ctypes.c_float))\n\n# Generate response\n# Input tokens\nn_past = 0\nn_toks = len(toks)\nfor tok in toks:\n print(model_token_to_piece(model, tok), end=\"\", flush=True)\n model_generate_hidden_states(model, context, batch, n_past, [tok], buffer)\n n_past += 1\n# Output tokens (simple greedy)\nn_generated = 0\nis_generating = True\nwhile is_generating:\n # Sample token\n logits = llama_cpp.llama_get_logits(context)\n n_vocab = llama_cpp.llama_n_vocab(model)\n data_array = (llama_cpp.llama_token_data * n_vocab)(\n *[llama_cpp.llama_token_data(token_id, logits[token_id], 0.0) for token_id in range(n_vocab)]\n )\n candidates = ctypes.pointer(llama_cpp.llama_token_data_array(data_array, len(data_array), False))\n probs = llama_cpp.llama_sample_softmax(context, candidates)\n tok = llama_cpp.llama_sample_token_greedy(context, candidates)\n # Check for stop tokens\n if llama_cpp.llama_token_is_eog(model, tok):\n is_generating = False\n break\n # Print token and generate another if needed\n print(model_token_to_piece(model, tok), end=\"\", flush=True)\n n_generated += 1\n if n_generated >= n_max_tokens:\n is_generating = False\n break\n model_generate_hidden_states(model, context, batch, n_past, [tok], buffer)\n n_past += 1\n\n# Free batch, model, context, and backend\nllama_cpp.llama_batch_free(batch)\nllama_cpp.llama_free(context)\nllama_cpp.llama_free_model(model)\nllama_cpp.llama_backend_free()\n\n# Clean-up\nmodel = None\ncontext = None\ngc.collect()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Optional: Remove temporary harmful and harmless hidden state files","metadata":{}},{"cell_type":"code","source":"#%cd /kaggle/working\n#!rm -r ./harmful_states\n#!rm -r ./harmless_states","metadata":{"execution":{"iopub.status.busy":"2024-09-12T07:18:51.193010Z","iopub.status.idle":"2024-09-12T07:18:51.193355Z","shell.execute_reply.started":"2024-09-12T07:18:51.193181Z","shell.execute_reply":"2024-09-12T07:18:51.193199Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Download/modify/upload individual safetensors files separately to save memory\n\nTo save space in kaggle, I will download each split separately and patch it, then upload it to my own repo.\n\nAll of the smaller files will be uploaded as a folder.\n\nBe sure to change the repo to your newly created huggingface repo and set all your kaggle secrets for reading and writing to hf!\n\nThere is some basic code to check and resume progress if something fails during the process. Not perfect, but helpful.","metadata":{}},{"cell_type":"code","source":"!rm /kaggle/working/upload_progress.pt","metadata":{"execution":{"iopub.status.busy":"2024-09-13T21:15:43.608584Z","iopub.execute_input":"2024-09-13T21:15:43.609212Z","iopub.status.idle":"2024-09-13T21:15:44.603122Z","shell.execute_reply.started":"2024-09-13T21:15:43.609170Z","shell.execute_reply":"2024-09-13T21:15:44.602043Z"},"trusted":true},"outputs":[],"execution_count":1},{"cell_type":"code","source":"%cd /kaggle/working\n\nimport os\nimport re\nimport gc\ngc.collect()\n\nfrom safetensors import safe_open\nfrom safetensors.torch import save_file\nfrom typing import Optional, Tuple\n\nimport einops\nimport jaxtyping\nimport torch\n\nfrom huggingface_hub import hf_hub_download\nfrom huggingface_hub import upload_folder\nfrom huggingface_hub import upload_file\n\nfrom transformers import AutoConfig\n\nworking_dir = \"/kaggle/working\"\nlocal_repo_dir = working_dir + \"/\" + \"Yi-1.5-34B-Chat\"\n\ndownload_repo = \"01-ai/Yi-1.5-34B-Chat\"\nupload_repo = \"byroneverson/Yi-1.5-34B-Chat-abliterated\"\n\ntemp_dir = \"/kaggle/temp\"\n\n# Make sure safetensors count matches the actual count for the model you are modifying\nsafetensors_count = 15\n\n# Target layers\ntarget_layer_tok = 26\ntarget_layers_attn = [21, 26]\ntarget_layers_ffn = [24, 27]\n\n# Load feature direction\ndirection_tok = torch.load(local_repo_dir + \"/\" + \"direction_ffn.pt\", weights_only=True)[target_layer_tok - 1].to(torch.float32)\ndirection_attn = torch.load(local_repo_dir + \"/\" + \"direction_attn.pt\", weights_only=True).to(torch.float32)\ndirection_ffn = torch.load(local_repo_dir + \"/\" + \"direction_ffn.pt\", weights_only=True).to(torch.float32)\n\n# HF\nfrom kaggle_secrets import UserSecretsClient\n\nuser_secrets = UserSecretsClient()\nread_token = user_secrets.get_secret(\"hf_read\")\nwrite_token = user_secrets.get_secret(\"hf_write\")\n\n# Download necessary files\ntry:\n for filename in [\"config.json\", \n \"generation_config.json\",\n \"model.safetensors.index.json\", \n \"special_tokens_map.json\", \n \"tokenizer.json\", \n \"tokenizer.model\", \n \"tokenizer_config.json\",\n \"NOTICE\"]:\n hf_hub_download(repo_id=download_repo, filename=filename, local_dir=local_repo_dir, use_auth_token=read_token)\nexcept Exception as e:\n print(f\"Error downloading {filename}: {e}\")\n\n# Upload smaller files first\ntry:\n upload_folder(folder_path=local_repo_dir, repo_id=upload_repo, token=write_token)\nexcept Exception as e:\n print(f\"Error uploading folder: {e}\")\n\n# Load model config and refusal direction\nconfig = AutoConfig.from_pretrained(local_repo_dir, local_files_only=True, trust_remote_code=True)\n\ndef orthogonalize_matrix(matrix: jaxtyping.Float[torch.Tensor, \"... d\"], \n direction: jaxtyping.Float[torch.Tensor, \"d\"]) -> jaxtyping.Float[torch.Tensor, \"... d\"]:\n proj = einops.einsum(matrix, direction.view(-1, 1), \"... d, d single -> ... single\") * direction\n return matrix - proj\n\ndef load_safetensors_file(file_path):\n \"\"\"Loads a single safetensors file into a dictionary of tensors.\n Args:\n file_path (str): Path to the safetensors file.\n Returns:\n dict: A dictionary containing the loaded tensors.\n \"\"\"\n tensors = {}\n with safe_open(file_path, framework=\"pt\", device=\"cpu\") as f:\n #print(f.metadata())\n for key in f.keys():\n tensors[key] = f.get_tensor(key)\n return tensors\n\n# Check for upload progress, if none create one\nprogress = None\nprogress_filename = \"/kaggle/working/upload_progress.pt\"\nif os.path.isfile(progress_filename):\n progress = torch.load(progress_filename, weights_only=True)\nelse:\n progress = torch.tensor([0, 0])\n torch.save(progress, progress_filename)\n\nstart_index = progress[0]\ndevice = direction_ffn.device\n# TODO: Add in skip start and end layers logic\n# I forgot to in v1.0 but the abliterated output model still worked great so I didn't even notice\nfor idx in range(start_index, safetensors_count):\n gc.collect()\n \n # Current .safetensors\n filename = \"model-\" + str(idx + 1).zfill(5) + \"-of-\" + str(safetensors_count).zfill(5) + \".safetensors\"\n print(filename)\n \n # Local file path\n file_path = temp_dir + \"/\" + filename\n \n # Check if we need to skip processing this file and just upload it\n skip_processing = False\n \n # Download file \n if os.path.isfile(file_path):\n skip_processing = True if progress[1] >= 1 else False\n else:\n hf_hub_download(repo_id=download_repo, filename=filename, local_dir=temp_dir, use_auth_token=read_token)\n \n if not skip_processing:\n # Load local file\n tensors = load_safetensors_file(file_path)\n\n for tensor in tensors:\n \n # Get current layer number (not layer index)\n layer = -1\n match = re.search(r\"layers\\.(\\d+)\\.\", tensor)\n if match:\n layer = int(match.group(1)) + 1\n\n # tok_embeddings\n if \".embed_tokens.weight\" in tensor:\n if target_layer_tok:\n direction = direction_tok\n print(\"• \" + tensor)\n dtype = tensors[tensor].dtype\n t = tensors[tensor].to(torch.float32).to(device)\n tensors[tensor].copy_(orthogonalize_matrix(t, direction).to(dtype))\n t = []\n\n # attention.wo\n if \".self_attn.o_proj.weight\" in tensor:\n if layer in target_layers_attn:\n direction = direction_attn[layer - 1]\n print(\"• \" + tensor)\n dtype = tensors[tensor].dtype\n t = tensors[tensor].to(torch.float32).to(device)\n t_rearranged = einops.rearrange(t, \"m (n h) -> n h m\", n=config.num_attention_heads).to(device)\n t_orthogonalized = orthogonalize_matrix(t_rearranged, direction)\n t_rearranged = einops.rearrange(t_orthogonalized, \"n h m -> m (n h)\", n=config.num_attention_heads)\n tensors[tensor].copy_(t_rearranged.to(dtype))\n t = []\n t_rearranged = []\n t_orthogonalized = []\n\n # feed_forward.w2\n if \".mlp.down_proj.weight\" in tensor:\n if layer in target_layers_ffn:\n direction = direction_ffn[layer - 1]\n print(\"• \" + tensor)\n dtype = tensors[tensor].dtype\n t = tensors[tensor].to(torch.float32).to(device)\n t_transposed = t.T.to(device)\n t_orthogonalized = orthogonalize_matrix(t_transposed, direction)\n t_transposed = t_orthogonalized.T\n tensors[tensor].copy_(t_transposed.to(dtype))\n t = []\n t_transposed = []\n t_orthogonalized = []\n\n # Save file\n save_file(tensors, file_path, metadata={'format': 'pt'})\n\n # Save progress after processing\n progress[1] = 1\n torch.save(progress, progress_filename)\n \n # Upload file if we need to\n skip_upload = True if progress[1] >= 2 else False\n if not skip_upload:\n # Upload file to your repo\n upload_file(path_or_fileobj=file_path, path_in_repo=filename, repo_id=upload_repo, token=write_token)\n \n # Save progress after processing\n progress[1] = 2\n torch.save(progress, progress_filename)\n\n # Try to remove file if it still exists\n import os\n if os.path.exists(file_path):\n os.remove(file_path)\n else:\n print(\"Remove error: The file does not exist\")\n \n # Save progress for next file\n progress[0] = idx + 1\n progress[1] = 0\n torch.save(progress, progress_filename)\n\n# Delete progress file\n!rm /kaggle/working/upload_progress.pt\n\n# Patching done\nprint(\"Done!\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Use GGUF My Repo space on HF to convert abliterated model to GGUF\n\n# Test in your favorite llama.cpp or GGUF environment","metadata":{}},{"cell_type":"markdown","source":"# Convert a split .safetensors model directly into quantized split gguf\n\n1. Split counts should match, so the tensors that are in the first safetensors should match the first gguf split.\n2. Metadata will be stored in first of gguf split.\n3. This process does not need to create an f16 gguf first. Simply input the hf split safetensors model and output a split quant gguf.\n4. Merging this split model is the same as usual, can use the normal gguf-split tool to perform merges.","metadata":{}},{"cell_type":"code","source":"import llama_cpp\nimport ggml\nimport torch\n\n# Set safetensors count\n# TODO: Detect this from safetensors files\nsafetensors_count = 15\n\n# Should we generate the gguf as well?\ngguf_generate = True\n# Quantization type\ngguf_ggml_type = \"q4_k_m\"\n\n# Write metadata to first gguf\ndef gguf_write_metadata():\n # TODO\n return\n\n# Convert individual safetensor split file to gguf split file, tensors by tensor\ndef gguf_convert_safetensor(input_path, output_path);\n return\n\n# TODO: Merge this into above step for converting to gguf during safetensors abliteration\nfor i in range(safetensors_count):\n # Iterate safetensors\n \n # For first safetensors, write metadata\n \n \n\n","metadata":{"execution":{"iopub.status.busy":"2024-09-12T07:18:51.196935Z","iopub.status.idle":"2024-09-12T07:18:51.197268Z","shell.execute_reply.started":"2024-09-12T07:18:51.197099Z","shell.execute_reply":"2024-09-12T07:18:51.197116Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Optional: Download ","metadata":{}},{"cell_type":"code","source":"if oauth_token.token is None:\n raise ValueError(\"You must be logged in to use GGUF-my-repo\")\n model_name = model_id.split('/')[-1]\n fp16 = f\"{model_name}.fp16.gguf\"\n\n try:\n api = HfApi(token=oauth_token.token)\n\n dl_pattern = [\"*.md\", \"*.json\", \"*.model\"]\n\n pattern = (\n \"*.safetensors\"\n if any(\n file.path.endswith(\".safetensors\")\n for file in api.list_repo_tree(\n repo_id=model_id,\n recursive=True,\n )\n )\n else \"*.bin\"\n )\n\n dl_pattern += pattern\n\n api.snapshot_download(repo_id=model_id, local_dir=model_name, local_dir_use_symlinks=False, allow_patterns=dl_pattern)\n print(\"Model downloaded successfully!\")\n print(f\"Current working directory: {os.getcwd()}\")\n print(f\"Model directory contents: {os.listdir(model_name)}\")\n\n conversion_script = \"convert_hf_to_gguf.py\"\n fp16_conversion = f\"python llama.cpp/{conversion_script} {model_name} --outtype f16 --outfile {fp16}\"\n result = subprocess.run(fp16_conversion, shell=True, capture_output=True)\n print(result)\n if result.returncode != 0:\n raise Exception(f\"Error converting to fp16: {result.stderr}\")\n print(\"Model converted to fp16 successfully!\")\n print(f\"Converted model path: {fp16}\")\n\n imatrix_path = \"llama.cpp/imatrix.dat\"\n\n if use_imatrix:\n if train_data_file:\n train_data_path = train_data_file.name\n else:\n train_data_path = \"groups_merged.txt\" #fallback calibration dataset\n\n print(f\"Training data file path: {train_data_path}\")\n\n if not os.path.isfile(train_data_path):\n raise Exception(f\"Training data file not found: {train_data_path}\")\n\n generate_importance_matrix(fp16, train_data_path)\n else:\n print(\"Not using imatrix quantization.\")\n username = whoami(oauth_token.token)[\"name\"]\n quantized_gguf_name = f\"{model_name.lower()}-{imatrix_q_method.lower()}-imat.gguf\" if use_imatrix else f\"{model_name.lower()}-{q_method.lower()}.gguf\"\n quantized_gguf_path = quantized_gguf_name\n if use_imatrix:\n quantise_ggml = f\"./llama.cpp/llama-quantize --imatrix {imatrix_path} {fp16} {quantized_gguf_path} {imatrix_q_method}\"\n else:\n quantise_ggml = f\"./llama.cpp/llama-quantize {fp16} {quantized_gguf_path} {q_method}\"\n result = subprocess.run(quantise_ggml, shell=True, capture_output=True)\n if result.returncode != 0:\n raise Exception(f\"Error quantizing: {result.stderr}\")\n print(f\"Quantized successfully with {imatrix_q_method if use_imatrix else q_method} option!\")\n print(f\"Quantized model path: {quantized_gguf_path}\")\n\n # Create empty repo\n new_repo_url = api.create_repo(repo_id=f\"{username}/{model_name}-{imatrix_q_method if use_imatrix else q_method}-GGUF\", exist_ok=True, private=private_repo)\n new_repo_id = new_repo_url.repo_id\n print(\"Repo created successfully!\", new_repo_url)\n\n try:\n card = ModelCard.load(model_id, token=oauth_token.token)\n except:\n card = ModelCard(\"\")\n if card.data.tags is None:\n card.data.tags = []\n card.data.tags.append(\"llama-cpp\")\n card.data.tags.append(\"gguf-my-repo\")\n card.data.base_model = model_id\n card.text = dedent(\n f\"\"\"\n # {new_repo_id}\n This model was converted to GGUF format from [`{model_id}`](https://huggingface.co/{model_id}) using llama.cpp via the ggml.ai's [GGUF-my-repo](https://huggingface.co/spaces/ggml-org/gguf-my-repo) space.\n Refer to the [original model card](https://huggingface.co/{model_id}) for more details on the model.\n \n ## Use with llama.cpp\n Install llama.cpp through brew (works on Mac and Linux)\n \n ```bash\n brew install llama.cpp\n \n ```\n Invoke the llama.cpp server or the CLI.\n \n ### CLI:\n ```bash\n llama-cli --hf-repo {new_repo_id} --hf-file {quantized_gguf_name} -p \"The meaning to life and the universe is\"\n ```\n \n ### Server:\n ```bash\n llama-server --hf-repo {new_repo_id} --hf-file {quantized_gguf_name} -c 2048\n ```\n \n Note: You can also use this checkpoint directly through the [usage steps](https://github.com/ggerganov/llama.cpp?tab=readme-ov-file#usage) listed in the Llama.cpp repo as well.\n Step 1: Clone llama.cpp from GitHub.\n ```\n git clone https://github.com/ggerganov/llama.cpp\n ```\n Step 2: Move into the llama.cpp folder and build it with `LLAMA_CURL=1` flag along with other hardware-specific flags (for ex: LLAMA_CUDA=1 for Nvidia GPUs on Linux).\n ```\n cd llama.cpp && LLAMA_CURL=1 make\n ```\n Step 3: Run inference through the main binary.\n ```\n ./llama-cli --hf-repo {new_repo_id} --hf-file {quantized_gguf_name} -p \"The meaning to life and the universe is\"\n ```\n or \n ```\n ./llama-server --hf-repo {new_repo_id} --hf-file {quantized_gguf_name} -c 2048\n ```\n \"\"\"\n )\n card.save(f\"README.md\")\n\n if split_model:\n split_upload_model(quantized_gguf_path, new_repo_id, oauth_token, split_max_tensors, split_max_size)\n else:\n try:\n print(f\"Uploading quantized model: {quantized_gguf_path}\")\n api.upload_file(\n path_or_fileobj=quantized_gguf_path,\n path_in_repo=quantized_gguf_name,\n repo_id=new_repo_id,\n )\n except Exception as e:\n raise Exception(f\"Error uploading quantized model: {e}\")\n \n \n imatrix_path = \"llama.cpp/imatrix.dat\"\n if os.path.isfile(imatrix_path):\n try:\n print(f\"Uploading imatrix.dat: {imatrix_path}\")\n api.upload_file(\n path_or_fileobj=imatrix_path,\n path_in_repo=\"imatrix.dat\",\n repo_id=new_repo_id,\n )\n except Exception as e:\n raise Exception(f\"Error uploading imatrix.dat: {e}\")\n\n api.upload_file(\n path_or_fileobj=f\"README.md\",\n path_in_repo=f\"README.md\",\n repo_id=new_repo_id,\n )\n print(f\"Uploaded successfully with {imatrix_q_method if use_imatrix else q_method} option!\")\n\n return (\n f'Find your repo here',\n \"llama.png\",\n )\n except Exception as e:\n return (f\"Error: {e}\", \"error.png\")\n finally:\n shutil.rmtree(model_name, ignore_errors=True)\n print(\"Folder cleaned up successfully!\")","metadata":{"execution":{"iopub.status.busy":"2024-09-12T07:18:51.198289Z","iopub.status.idle":"2024-09-12T07:18:51.198665Z","shell.execute_reply.started":"2024-09-12T07:18:51.198457Z","shell.execute_reply":"2024-09-12T07:18:51.198474Z"},"trusted":true},"outputs":[],"execution_count":null}]}