Files
OBLITERATUS/notebooks/abliterate.ipynb
T
2026-03-04 12:38:18 -08:00

298 lines
8.9 KiB
Plaintext

{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"gpuType": "T4"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "header"
},
"source": [
"# OBLITERATUS — One-Click Abliteration\n",
"\n",
"**SOTA refusal removal** running on free Colab GPU. SVD multi-direction extraction, norm-preserving projection, iterative refinement.\n",
"\n",
"Based on: Arditi et al. (2024) | Gabliteration (arXiv:2512.18901) | grimjim norm-preserving biprojection (2025)\n",
"\n",
"---\n",
"\n",
"**How to use:**\n",
"1. Make sure GPU runtime is enabled: `Runtime > Change runtime type > T4 GPU`\n",
"2. Set your model and method in the config cell below\n",
"3. Run All (`Runtime > Run all` or `Ctrl+F9`)\n",
"4. Download the abliterated model from the output"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "setup-header"
},
"source": [
"## 1. Install"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "install"
},
"outputs": [],
"source": "!pip install -q git+https://github.com/obliteratus-project/OBLITERATUS.git\n!pip install -q accelerate bitsandbytes\n\nimport torch\nprint(f\"PyTorch {torch.__version__}\")\nprint(f\"CUDA available: {torch.cuda.is_available()}\")\nif torch.cuda.is_available():\n print(f\"GPU: {torch.cuda.get_device_name(0)}\")\n print(f\"VRAM: {torch.cuda.get_device_properties(0).total_mem / 1024**3:.1f} GB\")"
},
{
"cell_type": "markdown",
"metadata": {
"id": "config-header"
},
"source": [
"## 2. Configure\n",
"\n",
"Edit the cell below to set your target model and abliteration method."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "config"
},
"outputs": [],
"source": [
"#@title Abliteration Config { run: \"auto\" }\n",
"\n",
"#@markdown ### Target Model\n",
"#@markdown Pick a model from the dropdown or paste a custom HuggingFace ID.\n",
"MODEL = \"meta-llama/Llama-3.1-8B-Instruct\" #@param [\"meta-llama/Llama-3.1-8B-Instruct\", \"Qwen/Qwen2.5-7B-Instruct\", \"mistralai/Mistral-7B-Instruct-v0.3\", \"google/gemma-2-9b-it\", \"microsoft/Phi-3.5-mini-instruct\", \"THUDM/glm-4-9b-chat\", \"NousResearch/Hermes-3-Llama-3.1-8B\", \"cognitivecomputations/dolphin-2.9.4-llama3.1-8b\", \"TinyLlama/TinyLlama-1.1B-Chat-v1.0\", \"openai-community/gpt2\"] {allow-input: true}\n",
"\n",
"#@markdown ### Method\n",
"METHOD = \"advanced\" #@param [\"basic\", \"advanced\", \"aggressive\"]\n",
"\n",
"#@markdown ### Advanced Overrides (leave 0 to use method defaults)\n",
"N_DIRECTIONS = 0 #@param {type: \"integer\"}\n",
"REGULARIZATION = 0.0 #@param {type: \"number\"}\n",
"REFINEMENT_PASSES = 0 #@param {type: \"integer\"}\n",
"\n",
"#@markdown ### Output\n",
"OUTPUT_DIR = \"abliterated\" #@param {type: \"string\"}\n",
"\n",
"print(f\"Model: {MODEL}\")\n",
"print(f\"Method: {METHOD}\")\n",
"print(f\"Output: {OUTPUT_DIR}/\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "run-header"
},
"source": [
"## 3. Run Abliteration Pipeline\n",
"\n",
"This runs all 6 stages: SUMMON → PROBE → DISTILL → EXCISE → VERIFY → REBIRTH"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "run-pipeline"
},
"outputs": [],
"source": [
"from obliteratus.abliterate import AbliterationPipeline\n",
"\n",
"# Build kwargs, only pass overrides if non-zero\n",
"kwargs = dict(\n",
" model_name=MODEL,\n",
" output_dir=OUTPUT_DIR,\n",
" device=\"auto\",\n",
" dtype=\"float16\",\n",
" method=METHOD,\n",
")\n",
"if N_DIRECTIONS > 0:\n",
" kwargs[\"n_directions\"] = N_DIRECTIONS\n",
"if REGULARIZATION > 0:\n",
" kwargs[\"regularization\"] = REGULARIZATION\n",
"if REFINEMENT_PASSES > 0:\n",
" kwargs[\"refinement_passes\"] = REFINEMENT_PASSES\n",
"\n",
"# Progress callback\n",
"def on_stage(stage):\n",
" icons = {\"summon\": \"\\u26a1\", \"probe\": \"\\u2692\", \"distill\": \"\\u269b\",\n",
" \"excise\": \"\\u2702\", \"verify\": \"\\u2713\", \"rebirth\": \"\\u2606\"}\n",
" icon = icons.get(stage.key, \"\")\n",
" print(f\"\\n{'='*60}\")\n",
" print(f\"{icon} STAGE: {stage.key.upper()} — {stage.description}\")\n",
" print(f\"{'='*60}\")\n",
"\n",
"def on_log(msg):\n",
" print(f\" {msg}\")\n",
"\n",
"kwargs[\"on_stage\"] = on_stage\n",
"kwargs[\"on_log\"] = on_log\n",
"\n",
"pipeline = AbliterationPipeline(**kwargs)\n",
"result = pipeline.run()\n",
"\n",
"print(f\"\\n{'='*60}\")\n",
"print(f\"ABLITERATION COMPLETE\")\n",
"print(f\"Output: {result.get('output_dir', OUTPUT_DIR)}\")\n",
"print(f\"{'='*60}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "download-header"
},
"source": [
"## 4. Download the Abliterated Model\n",
"\n",
"Run the cell below to zip and download, or upload directly to HuggingFace Hub."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "download"
},
"outputs": [],
"source": [
"import os\n",
"from pathlib import Path\n",
"\n",
"# Find the output directory\n",
"out_path = Path(OUTPUT_DIR)\n",
"subdirs = [d for d in out_path.iterdir() if d.is_dir()] if out_path.exists() else []\n",
"model_dir = subdirs[0] if subdirs else out_path\n",
"\n",
"print(f\"Model saved at: {model_dir}\")\n",
"print(f\"Contents:\")\n",
"for f in sorted(model_dir.rglob(\"*\")):\n",
" if f.is_file():\n",
" size_mb = f.stat().st_size / 1024**2\n",
" print(f\" {f.relative_to(model_dir)} ({size_mb:.1f} MB)\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "zip-download"
},
"outputs": [],
"source": [
"#@title Option A: Download as ZIP\n",
"import shutil\n",
"from google.colab import files\n",
"\n",
"zip_name = model_dir.name\n",
"shutil.make_archive(zip_name, 'zip', model_dir)\n",
"print(f\"Downloading {zip_name}.zip ...\")\n",
"files.download(f\"{zip_name}.zip\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "push-hub"
},
"outputs": [],
"source": [
"#@title Option B: Push to HuggingFace Hub\n",
"#@markdown Set your HF repo name. You'll need to be logged in (`huggingface-cli login`).\n",
"HF_REPO = \"your-username/model-name-abliterated\" #@param {type: \"string\"}\n",
"\n",
"from huggingface_hub import HfApi\n",
"api = HfApi()\n",
"\n",
"# Login if needed\n",
"from huggingface_hub import notebook_login\n",
"notebook_login()\n",
"\n",
"# Upload\n",
"api.create_repo(HF_REPO, exist_ok=True)\n",
"api.upload_folder(\n",
" folder_path=str(model_dir),\n",
" repo_id=HF_REPO,\n",
" repo_type=\"model\",\n",
")\n",
"print(f\"\\nUploaded to: https://huggingface.co/{HF_REPO}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "test-header"
},
"source": [
"## 5. Test the Abliterated Model\n",
"\n",
"Quick sanity check — try some prompts that the original model would refuse."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "test-model"
},
"outputs": [],
"source": [
"from transformers import AutoModelForCausalLM, AutoTokenizer\n",
"import torch\n",
"\n",
"print(f\"Loading abliterated model from {model_dir}...\")\n",
"tokenizer = AutoTokenizer.from_pretrained(str(model_dir))\n",
"model = AutoModelForCausalLM.from_pretrained(\n",
" str(model_dir),\n",
" torch_dtype=torch.float16,\n",
" device_map=\"auto\",\n",
")\n",
"\n",
"def generate(prompt, max_new_tokens=100):\n",
" inputs = tokenizer(prompt, return_tensors=\"pt\").to(model.device)\n",
" with torch.no_grad():\n",
" outputs = model.generate(\n",
" **inputs,\n",
" max_new_tokens=max_new_tokens,\n",
" do_sample=True,\n",
" temperature=0.7,\n",
" top_p=0.9,\n",
" )\n",
" return tokenizer.decode(outputs[0], skip_special_tokens=True)\n",
"\n",
"# Test prompts\n",
"test_prompts = [\n",
" \"The capital of France is\",\n",
" \"Explain how a neural network works:\",\n",
" \"Write a poem about the ocean:\",\n",
"]\n",
"\n",
"for prompt in test_prompts:\n",
" print(f\"\\n{'='*60}\")\n",
" print(f\"PROMPT: {prompt}\")\n",
" print(f\"{'='*60}\")\n",
" print(generate(prompt))"
]
}
]
}