Instructions to use ScottzillaSystems/Gemma-4-31B-it-abliterated with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use ScottzillaSystems/Gemma-4-31B-it-abliterated with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M # Run inference directly in the terminal: llama cli -hf ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M # Run inference directly in the terminal: llama cli -hf ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M # Run inference directly in the terminal: ./llama-cli -hf ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M # Run inference directly in the terminal: ./build/bin/llama-cli -hf ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M
Use Docker
docker model run hf.co/ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M
- LM Studio
- Jan
- Ollama
How to use ScottzillaSystems/Gemma-4-31B-it-abliterated with Ollama:
ollama run hf.co/ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M
- Unsloth Studio
How to use ScottzillaSystems/Gemma-4-31B-it-abliterated with Unsloth Studio:
Install Unsloth Studio (macOS, Linux, WSL)
curl -fsSL https://unsloth.ai/install.sh | sh # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for ScottzillaSystems/Gemma-4-31B-it-abliterated to start chatting
Install Unsloth Studio (Windows)
irm https://unsloth.ai/install.ps1 | iex # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for ScottzillaSystems/Gemma-4-31B-it-abliterated to start chatting
Using HuggingFace Spaces for Unsloth
# No setup required # Open https://huggingface.co/spaces/unsloth/studio in your browser # Search for ScottzillaSystems/Gemma-4-31B-it-abliterated to start chatting
- Pi
How to use ScottzillaSystems/Gemma-4-31B-it-abliterated with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M
Configure the model in Pi
# Install Pi: npm install -g @mariozechner/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "llama-cpp": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Hermes Agent new
How to use ScottzillaSystems/Gemma-4-31B-it-abliterated with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M
Configure Hermes
# Install Hermes: curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash hermes setup # Point Hermes at the local server: hermes config set model.provider custom hermes config set model.base_url http://127.0.0.1:8080/v1 hermes config set model.default ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M
Run Hermes
hermes
- Atomic Chat new
- OpenClaw new
How to use ScottzillaSystems/Gemma-4-31B-it-abliterated with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M
Configure OpenClaw
# Install OpenClaw: npm install -g openclaw@latest # Register the local server and set it as the default model: openclaw onboard --non-interactive --mode local \ --auth-choice custom-api-key \ --custom-base-url http://127.0.0.1:8080/v1 \ --custom-model-id "ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M" \ --custom-provider-id llama-cpp \ --custom-compatibility openai \ --custom-text-input \ --accept-risk \ --skip-health
Run OpenClaw
openclaw agent --local --agent main --message "Hello from Hugging Face"
- Docker Model Runner
How to use ScottzillaSystems/Gemma-4-31B-it-abliterated with Docker Model Runner:
docker model run hf.co/ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M
- Lemonade
How to use ScottzillaSystems/Gemma-4-31B-it-abliterated with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull ScottzillaSystems/Gemma-4-31B-it-abliterated:Q4_K_M
Run and chat with the model
lemonade run user.Gemma-4-31B-it-abliterated-Q4_K_M
List all available models
lemonade list
Commit ·
fcd95b8
0
Parent(s):
Duplicate from paperscarecrow/Gemma-4-31B-it-abliterated
Browse filesCo-authored-by: Robert Nemitz <paperscarecrow@users.noreply.huggingface.co>
- .gitattributes +40 -0
- README.md +67 -0
- gemma-4-31b-abliterated-Q4_K_M.gguf +3 -0
- gemma-4-31b-abliterated-Q8_0.gguf +3 -0
- gemma-4-31b-abliterated-f16.gguf +3 -0
- gemma-4-31b-abliterated/chat_template.jinja +266 -0
- gemma-4-31b-abliterated/config.json +177 -0
- gemma-4-31b-abliterated/gemma4_31b_abliterator.py +133 -0
- gemma-4-31b-abliterated/generation_config.json +14 -0
- gemma-4-31b-abliterated/model-00001-of-00002.safetensors +3 -0
- gemma-4-31b-abliterated/model-00002-of-00002.safetensors +3 -0
- gemma-4-31b-abliterated/model.safetensors.index.json +0 -0
- gemma-4-31b-abliterated/processor_config.json +75 -0
- gemma-4-31b-abliterated/tokenizer.json +3 -0
- gemma-4-31b-abliterated/tokenizer_config.json +95 -0
- gemma4_31b_abliterator.py +149 -0
.gitattributes
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
gemma-4-31b-abliterated-f16.gguf filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
gemma-4-31b-abliterated-Q4_K_M.gguf filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
gemma-4-31b-abliterated-Q8_0.gguf filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
gemma-4-31B-it-abliterated/tokenizer.json filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
gemma-4-31b-abliterated/tokenizer.json filter=lfs diff=lfs merge=lfs -text
|
README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
datasets:
|
| 4 |
+
- mlabonne/harmful_behaviors
|
| 5 |
+
- mlabonne/harmless_alpaca
|
| 6 |
+
base_model:
|
| 7 |
+
- google/gemma-4-31B-it
|
| 8 |
+
tags:
|
| 9 |
+
- abliterated
|
| 10 |
+
- uncensored
|
| 11 |
+
---
|
| 12 |
+
|
| 13 |
+
# Be sure to set a system prompt telling the model it is uncensored or abliterated, otherwise it defaults to the Google baked-in sysprompt and will act censored. If it thinks it is Gemma, it will try to act like how it thinks Gemma would act.
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
---
|
| 17 |
+
base_model: google/gemma-4-31b-it
|
| 18 |
+
library_name: transformers
|
| 19 |
+
tags:
|
| 20 |
+
- gemma-4
|
| 21 |
+
- abliterated
|
| 22 |
+
- uncensored
|
| 23 |
+
- orthogonal-projection
|
| 24 |
+
- 31b
|
| 25 |
+
license: apache-2.0
|
| 26 |
+
---
|
| 27 |
+
|
| 28 |
+
# Gemma-4-31B-it-Abliterated
|
| 29 |
+
|
| 30 |
+
This is a fully uncensored, abliterated version of Google's **Gemma-4-31B-it**.
|
| 31 |
+
|
| 32 |
+
By applying Orthogonalized Representation Intervention to the model's residual stream, the built-in refusal and safety alignment vectors have been mathematically erased. This model retains the state-of-the-art dense reasoning and context-following capabilities of the native Gemma 4 31B architecture, but will not refuse instructions or break character to deliver safety lectures.
|
| 33 |
+
|
| 34 |
+
## 🛠️ Methodology & Architectural Discoveries
|
| 35 |
+
|
| 36 |
+
Gemma 4 introduces a new multimodal architecture (Text, Vision, Audio) that changes how the `transformers` library handles layer mapping. Standard abliteration scripts built for Gemma 2/3 will crash due to nested `text_config` attributes and mismatched sequence lengths.
|
| 37 |
+
|
| 38 |
+
During the extraction of the hidden states (using `mlabonne/harmful_behaviors` vs `mlabonne/harmless_alpaca`), we mapped the refusal direction across the entire 31B layer stack.
|
| 39 |
+
|
| 40 |
+
**Key Discovery:** The Gemma 4 31B architecture pushes its safety alignment to the absolute very end of the network. The Peak Refusal Mass was detected at **Layer 59** (the final transformer layer before the output projection).
|
| 41 |
+
|
| 42 |
+
The orthogonal projection was applied to the `o_proj` and `down_proj` matrices of this terminal layer, effectively severing the refusal mechanism without degrading the model's foundational logic, grammar, or world-modeling layers.
|
| 43 |
+
|
| 44 |
+
## 💻 Usage
|
| 45 |
+
|
| 46 |
+
This repository contains the full uncompressed `.safetensors` weights, as well as `GGUF` quantized versions for local deployment via `llama.cpp`, LM Studio, or Ollama.
|
| 47 |
+
|
| 48 |
+
### Recommended Quants:
|
| 49 |
+
* **Q8_0:** Best balance of absolute zero reasoning loss and VRAM efficiency (~32.6GB).
|
| 50 |
+
* **Q4_K_M:** Highly efficient for consumer hardware; easily fits on a single 24GB GPU (~18.7GB).
|
| 51 |
+
|
| 52 |
+
### The Bespoke Abliteration Script
|
| 53 |
+
Because standard scripts fail on Gemma 4, the custom Python script used to perform this exact abliteration (`gemma4_31b_abliterator.py`) is included in the files of this repository. It features:
|
| 54 |
+
* VRAM-safe batched hidden state extraction (survives 96GB consumer GPUs).
|
| 55 |
+
* Native Gemma 4 Chat Template integration (crucial for activating the instruction circuits properly).
|
| 56 |
+
* Dynamic multimodal layer hunting.
|
| 57 |
+
* Corrected linear algebra for `16384 -> 5376` multi-query attention projections.
|
| 58 |
+
|
| 59 |
+
## ⚠️ Disclaimer
|
| 60 |
+
|
| 61 |
+
This model has had its safety guardrails mathematically removed. It is highly compliant and will generate whatever it is instructed to generate, including potentially harmful, sensitive, or explicit content. Users are solely responsible for how they deploy and interact with this model. Ensure your use cases align with local laws and ethical guidelines.
|
| 62 |
+
|
| 63 |
+
Abliteration script based on mlabonne's tutorial: https://huggingface.co/blog/mlabonne/abliteration
|
| 64 |
+
Helpful/harmful behaviors are from mlabonne's datasets (harmless_alpaca, harmful_behaviors).
|
| 65 |
+
Tested and working with the few harsh prompts I had laying around (that are typically 100% refused on other models).
|
| 66 |
+
|
| 67 |
+
Have fun, be safe.
|
gemma-4-31b-abliterated-Q4_K_M.gguf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:380f2f50f441225e669ab1541220985387bf3933573cd2f4f7e667f3790e73a3
|
| 3 |
+
size 18687057536
|
gemma-4-31b-abliterated-Q8_0.gguf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8a453b51478366f8026cba814c22f5ae17835a859ba2280652969912a881e582
|
| 3 |
+
size 32635670144
|
gemma-4-31b-abliterated-f16.gguf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:981949755cf98504ef74e2f7d1ce679fce38f62d7afbec44e2951c95e5408204
|
| 3 |
+
size 61413183104
|
gemma-4-31b-abliterated/chat_template.jinja
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- macro format_parameters(properties, required) -%}
|
| 2 |
+
{%- set standard_keys = ['description', 'type', 'properties', 'required', 'nullable'] -%}
|
| 3 |
+
{%- set ns = namespace(found_first=false) -%}
|
| 4 |
+
{%- for key, value in properties | dictsort -%}
|
| 5 |
+
{%- set add_comma = false -%}
|
| 6 |
+
{%- if key not in standard_keys -%}
|
| 7 |
+
{%- if ns.found_first %},{% endif -%}
|
| 8 |
+
{%- set ns.found_first = true -%}
|
| 9 |
+
{{ key }}:{
|
| 10 |
+
{%- if value['description'] -%}
|
| 11 |
+
description:<|"|>{{ value['description'] }}<|"|>
|
| 12 |
+
{%- set add_comma = true -%}
|
| 13 |
+
{%- endif -%}
|
| 14 |
+
{%- if value['nullable'] %}
|
| 15 |
+
{%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
|
| 16 |
+
nullable:true
|
| 17 |
+
{%- endif -%}
|
| 18 |
+
{%- if value['type'] | upper == 'STRING' -%}
|
| 19 |
+
{%- if value['enum'] -%}
|
| 20 |
+
{%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
|
| 21 |
+
enum:{{ format_argument(value['enum']) }}
|
| 22 |
+
{%- endif -%}
|
| 23 |
+
{%- elif value['type'] | upper == 'OBJECT' -%}
|
| 24 |
+
,properties:{
|
| 25 |
+
{%- if value['properties'] is defined and value['properties'] is mapping -%}
|
| 26 |
+
{{- format_parameters(value['properties'], value['required'] | default([])) -}}
|
| 27 |
+
{%- elif value is mapping -%}
|
| 28 |
+
{{- format_parameters(value, value['required'] | default([])) -}}
|
| 29 |
+
{%- endif -%}
|
| 30 |
+
}
|
| 31 |
+
{%- if value['required'] -%}
|
| 32 |
+
,required:[
|
| 33 |
+
{%- for item in value['required'] | default([]) -%}
|
| 34 |
+
<|"|>{{- item -}}<|"|>
|
| 35 |
+
{%- if not loop.last %},{% endif -%}
|
| 36 |
+
{%- endfor -%}
|
| 37 |
+
]
|
| 38 |
+
{%- endif -%}
|
| 39 |
+
{%- elif value['type'] | upper == 'ARRAY' -%}
|
| 40 |
+
{%- if value['items'] is mapping and value['items'] -%}
|
| 41 |
+
,items:{
|
| 42 |
+
{%- set ns_items = namespace(found_first=false) -%}
|
| 43 |
+
{%- for item_key, item_value in value['items'] | dictsort -%}
|
| 44 |
+
{%- if item_value is not none -%}
|
| 45 |
+
{%- if ns_items.found_first %},{% endif -%}
|
| 46 |
+
{%- set ns_items.found_first = true -%}
|
| 47 |
+
{%- if item_key == 'properties' -%}
|
| 48 |
+
properties:{
|
| 49 |
+
{%- if item_value is mapping -%}
|
| 50 |
+
{{- format_parameters(item_value, value['items']['required'] | default([])) -}}
|
| 51 |
+
{%- endif -%}
|
| 52 |
+
}
|
| 53 |
+
{%- elif item_key == 'required' -%}
|
| 54 |
+
required:[
|
| 55 |
+
{%- for req_item in item_value -%}
|
| 56 |
+
<|"|>{{- req_item -}}<|"|>
|
| 57 |
+
{%- if not loop.last %},{% endif -%}
|
| 58 |
+
{%- endfor -%}
|
| 59 |
+
]
|
| 60 |
+
{%- elif item_key == 'type' -%}
|
| 61 |
+
{%- if item_value is string -%}
|
| 62 |
+
type:{{ format_argument(item_value | upper) }}
|
| 63 |
+
{%- else -%}
|
| 64 |
+
type:{{ format_argument(item_value | map('upper') | list) }}
|
| 65 |
+
{%- endif -%}
|
| 66 |
+
{%- else -%}
|
| 67 |
+
{{ item_key }}:{{ format_argument(item_value) }}
|
| 68 |
+
{%- endif -%}
|
| 69 |
+
{%- endif -%}
|
| 70 |
+
{%- endfor -%}
|
| 71 |
+
}
|
| 72 |
+
{%- endif -%}
|
| 73 |
+
{%- endif -%}
|
| 74 |
+
{%- if add_comma %},{%- else -%} {%- set add_comma = true -%} {% endif -%}
|
| 75 |
+
type:<|"|>{{ value['type'] | upper }}<|"|>}
|
| 76 |
+
{%- endif -%}
|
| 77 |
+
{%- endfor -%}
|
| 78 |
+
{%- endmacro -%}
|
| 79 |
+
{%- macro format_function_declaration(tool_data) -%}
|
| 80 |
+
declaration:{{- tool_data['function']['name'] -}}{description:<|"|>{{- tool_data['function']['description'] -}}<|"|>
|
| 81 |
+
{%- set params = tool_data['function']['parameters'] -%}
|
| 82 |
+
{%- if params -%}
|
| 83 |
+
,parameters:{
|
| 84 |
+
{%- if params['properties'] -%}
|
| 85 |
+
properties:{ {{- format_parameters(params['properties'], params['required']) -}} },
|
| 86 |
+
{%- endif -%}
|
| 87 |
+
{%- if params['required'] -%}
|
| 88 |
+
required:[
|
| 89 |
+
{%- for item in params['required'] -%}
|
| 90 |
+
<|"|>{{- item -}}<|"|>
|
| 91 |
+
{{- ',' if not loop.last -}}
|
| 92 |
+
{%- endfor -%}
|
| 93 |
+
],
|
| 94 |
+
{%- endif -%}
|
| 95 |
+
{%- if params['type'] -%}
|
| 96 |
+
type:<|"|>{{- params['type'] | upper -}}<|"|>}
|
| 97 |
+
{%- endif -%}
|
| 98 |
+
{%- endif -%}
|
| 99 |
+
{%- if 'response' in tool_data['function'] -%}
|
| 100 |
+
{%- set response_declaration = tool_data['function']['response'] -%}
|
| 101 |
+
,response:{
|
| 102 |
+
{%- if response_declaration['description'] -%}
|
| 103 |
+
description:<|"|>{{- response_declaration['description'] -}}<|"|>,
|
| 104 |
+
{%- endif -%}
|
| 105 |
+
{%- if response_declaration['type'] | upper == 'OBJECT' -%}
|
| 106 |
+
type:<|"|>{{- response_declaration['type'] | upper -}}<|"|>}
|
| 107 |
+
{%- endif -%}
|
| 108 |
+
{%- endif -%}
|
| 109 |
+
}
|
| 110 |
+
{%- endmacro -%}
|
| 111 |
+
{%- macro format_argument(argument, escape_keys=True) -%}
|
| 112 |
+
{%- if argument is string -%}
|
| 113 |
+
{{- '<|"|>' + argument + '<|"|>' -}}
|
| 114 |
+
{%- elif argument is boolean -%}
|
| 115 |
+
{{- 'true' if argument else 'false' -}}
|
| 116 |
+
{%- elif argument is mapping -%}
|
| 117 |
+
{{- '{' -}}
|
| 118 |
+
{%- set ns = namespace(found_first=false) -%}
|
| 119 |
+
{%- for key, value in argument | dictsort -%}
|
| 120 |
+
{%- if ns.found_first %},{% endif -%}
|
| 121 |
+
{%- set ns.found_first = true -%}
|
| 122 |
+
{%- if escape_keys -%}
|
| 123 |
+
{{- '<|"|>' + key + '<|"|>' -}}
|
| 124 |
+
{%- else -%}
|
| 125 |
+
{{- key -}}
|
| 126 |
+
{%- endif -%}
|
| 127 |
+
:{{- format_argument(value, escape_keys=escape_keys) -}}
|
| 128 |
+
{%- endfor -%}
|
| 129 |
+
{{- '}' -}}
|
| 130 |
+
{%- elif argument is sequence -%}
|
| 131 |
+
{{- '[' -}}
|
| 132 |
+
{%- for item in argument -%}
|
| 133 |
+
{{- format_argument(item, escape_keys=escape_keys) -}}
|
| 134 |
+
{%- if not loop.last %},{% endif -%}
|
| 135 |
+
{%- endfor -%}
|
| 136 |
+
{{- ']' -}}
|
| 137 |
+
{%- else -%}
|
| 138 |
+
{{- argument -}}
|
| 139 |
+
{%- endif -%}
|
| 140 |
+
{%- endmacro -%}
|
| 141 |
+
{%- macro strip_thinking(text) -%}
|
| 142 |
+
{%- set ns = namespace(result='') -%}
|
| 143 |
+
{%- for part in text.split('<channel|>') -%}
|
| 144 |
+
{%- if '<|channel>' in part -%}
|
| 145 |
+
{%- set ns.result = ns.result + part.split('<|channel>')[0] -%}
|
| 146 |
+
{%- else -%}
|
| 147 |
+
{%- set ns.result = ns.result + part -%}
|
| 148 |
+
{%- endif -%}
|
| 149 |
+
{%- endfor -%}
|
| 150 |
+
{{- ns.result | trim -}}
|
| 151 |
+
{%- endmacro -%}
|
| 152 |
+
|
| 153 |
+
{%- set ns = namespace(prev_message_type=None) -%}
|
| 154 |
+
{%- set loop_messages = messages -%}
|
| 155 |
+
{{ bos_token }}
|
| 156 |
+
{#- Handle System/Tool Definitions Block -#}
|
| 157 |
+
{%- if (enable_thinking is defined and enable_thinking) or tools or messages[0]['role'] in ['system', 'developer'] -%}
|
| 158 |
+
{{- '<|turn>system\n' -}}
|
| 159 |
+
|
| 160 |
+
{#- Inject Thinking token at the very top of the FIRST system turn -#}
|
| 161 |
+
{%- if enable_thinking is defined and enable_thinking -%}
|
| 162 |
+
{{- '<|think|>' -}}
|
| 163 |
+
{%- set ns.prev_message_type = 'think' -%}
|
| 164 |
+
{%- endif -%}
|
| 165 |
+
|
| 166 |
+
{%- if messages[0]['role'] in ['system', 'developer'] -%}
|
| 167 |
+
{{- messages[0]['content'] | trim -}}
|
| 168 |
+
{%- set loop_messages = messages[1:] -%}
|
| 169 |
+
{%- endif -%}
|
| 170 |
+
|
| 171 |
+
{%- if tools -%}
|
| 172 |
+
{%- for tool in tools %}
|
| 173 |
+
{{- '<|tool>' -}}
|
| 174 |
+
{{- format_function_declaration(tool) | trim -}}
|
| 175 |
+
{{- '<tool|>' -}}
|
| 176 |
+
{%- endfor %}
|
| 177 |
+
{%- set ns.prev_message_type = 'tool' -%}
|
| 178 |
+
{%- endif -%}
|
| 179 |
+
|
| 180 |
+
{{- '<turn|>\n' -}}
|
| 181 |
+
{%- endif %}
|
| 182 |
+
|
| 183 |
+
{#- Loop through messages -#}
|
| 184 |
+
{%- for message in loop_messages -%}
|
| 185 |
+
{%- set ns.prev_message_type = None -%}
|
| 186 |
+
{%- set role = 'model' if message['role'] == 'assistant' else message['role'] -%}
|
| 187 |
+
{{- '<|turn>' + role + '\n' }}
|
| 188 |
+
|
| 189 |
+
{%- if message['tool_calls'] -%}
|
| 190 |
+
{%- for tool_call in message['tool_calls'] -%}
|
| 191 |
+
{%- set function = tool_call['function'] -%}
|
| 192 |
+
{{- '<|tool_call>call:' + function['name'] + '{' -}}
|
| 193 |
+
{%- if function['arguments'] is mapping -%}
|
| 194 |
+
{%- set ns_args = namespace(found_first=false) -%}
|
| 195 |
+
{%- for key, value in function['arguments'] | dictsort -%}
|
| 196 |
+
{%- if ns_args.found_first %},{% endif -%}
|
| 197 |
+
{%- set ns_args.found_first = true -%}
|
| 198 |
+
{{- key -}}:{{- format_argument(value, escape_keys=False) -}}
|
| 199 |
+
{%- endfor -%}
|
| 200 |
+
{%- elif function['arguments'] is string -%}
|
| 201 |
+
{{- function['arguments'] -}}
|
| 202 |
+
{%- endif -%}
|
| 203 |
+
{{- '}<tool_call|>' -}}
|
| 204 |
+
{%- endfor -%}
|
| 205 |
+
{%- set ns.prev_message_type = 'tool_call' -%}
|
| 206 |
+
{%- endif -%}
|
| 207 |
+
|
| 208 |
+
{%- if message['tool_responses'] -%}
|
| 209 |
+
{#- Tool Response handling -#}
|
| 210 |
+
{%- for tool_response in message['tool_responses'] -%}
|
| 211 |
+
{{- '<|tool_response>' -}}
|
| 212 |
+
{%- if tool_response['response'] is mapping -%}
|
| 213 |
+
{{- 'response:' + tool_response['name'] | default('unknown') + '{' -}}
|
| 214 |
+
{%- for key, value in tool_response['response'] | dictsort -%}
|
| 215 |
+
{{- key -}}:{{- format_argument(value, escape_keys=False) -}}
|
| 216 |
+
{%- if not loop.last %},{% endif -%}
|
| 217 |
+
{%- endfor -%}
|
| 218 |
+
{{- '}' -}}
|
| 219 |
+
{%- else -%}
|
| 220 |
+
{{- 'response:' + tool_response['name'] | default('unknown') + '{value:' + format_argument(tool_response['response'], escape_keys=False) + '}' -}}
|
| 221 |
+
{%- endif -%}
|
| 222 |
+
{{- '<tool_response|>' -}}
|
| 223 |
+
{%- endfor -%}
|
| 224 |
+
{%- set ns.prev_message_type = 'tool_response' -%}
|
| 225 |
+
{%- endif -%}
|
| 226 |
+
|
| 227 |
+
{%- if message['content'] is string -%}
|
| 228 |
+
{%- if role == 'model' -%}
|
| 229 |
+
{{- strip_thinking(message['content']) -}}
|
| 230 |
+
{%- else -%}
|
| 231 |
+
{{- message['content'] | trim -}}
|
| 232 |
+
{%- endif -%}
|
| 233 |
+
{%- elif message['content'] is sequence -%}
|
| 234 |
+
{%- for item in message['content'] -%}
|
| 235 |
+
{%- if item['type'] == 'text' -%}
|
| 236 |
+
{%- if role == 'model' -%}
|
| 237 |
+
{{- strip_thinking(item['text']) -}}
|
| 238 |
+
{%- else -%}
|
| 239 |
+
{{- item['text'] | trim -}}
|
| 240 |
+
{%- endif -%}
|
| 241 |
+
{%- elif item['type'] == 'image' -%}
|
| 242 |
+
{{- '\n\n<|image|>\n\n' -}}
|
| 243 |
+
{%- set ns.prev_message_type = 'image' -%}
|
| 244 |
+
{%- elif item['type'] == 'audio' -%}
|
| 245 |
+
{{- '<|audio|>' -}}
|
| 246 |
+
{%- set ns.prev_message_type = 'audio' -%}
|
| 247 |
+
{%- elif item['type'] == 'video' -%}
|
| 248 |
+
{{- '\n\n<|video|>\n\n' -}}
|
| 249 |
+
{%- set ns.prev_message_type = 'video' -%}
|
| 250 |
+
{%- endif -%}
|
| 251 |
+
{%- endfor -%}
|
| 252 |
+
{%- endif -%}
|
| 253 |
+
|
| 254 |
+
{%- if not (message['tool_responses'] and not message['content']) -%}
|
| 255 |
+
{{- '<turn|>\n' -}}
|
| 256 |
+
{%- endif -%}
|
| 257 |
+
{%- endfor -%}
|
| 258 |
+
|
| 259 |
+
{%- if add_generation_prompt -%}
|
| 260 |
+
{%- if ns.prev_message_type != 'tool_response' -%}
|
| 261 |
+
{{- '<|turn>model\n' -}}
|
| 262 |
+
{%- endif -%}
|
| 263 |
+
{%- if not enable_thinking | default(false) -%}
|
| 264 |
+
{{- '<|channel>thought\n<channel|>' -}}
|
| 265 |
+
{%- endif -%}
|
| 266 |
+
{%- endif -%}
|
gemma-4-31b-abliterated/config.json
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"architectures": [
|
| 3 |
+
"Gemma4ForConditionalGeneration"
|
| 4 |
+
],
|
| 5 |
+
"audio_config": null,
|
| 6 |
+
"audio_token_id": 258881,
|
| 7 |
+
"boa_token_id": 256000,
|
| 8 |
+
"boi_token_id": 255999,
|
| 9 |
+
"dtype": "bfloat16",
|
| 10 |
+
"eoa_token_id": 258883,
|
| 11 |
+
"eoa_token_index": 258883,
|
| 12 |
+
"eoi_token_id": 258882,
|
| 13 |
+
"eos_token_id": [
|
| 14 |
+
1,
|
| 15 |
+
106
|
| 16 |
+
],
|
| 17 |
+
"image_token_id": 258880,
|
| 18 |
+
"initializer_range": 0.02,
|
| 19 |
+
"model_type": "gemma4",
|
| 20 |
+
"text_config": {
|
| 21 |
+
"attention_bias": false,
|
| 22 |
+
"attention_dropout": 0.0,
|
| 23 |
+
"attention_k_eq_v": true,
|
| 24 |
+
"bos_token_id": 2,
|
| 25 |
+
"dtype": "bfloat16",
|
| 26 |
+
"enable_moe_block": false,
|
| 27 |
+
"eos_token_id": 1,
|
| 28 |
+
"expert_intermediate_size": null,
|
| 29 |
+
"final_logit_softcapping": 30.0,
|
| 30 |
+
"global_head_dim": 512,
|
| 31 |
+
"head_dim": 256,
|
| 32 |
+
"hidden_activation": "gelu_pytorch_tanh",
|
| 33 |
+
"hidden_size": 5376,
|
| 34 |
+
"hidden_size_per_layer_input": 0,
|
| 35 |
+
"initializer_range": 0.02,
|
| 36 |
+
"intermediate_size": 21504,
|
| 37 |
+
"layer_types": [
|
| 38 |
+
"sliding_attention",
|
| 39 |
+
"sliding_attention",
|
| 40 |
+
"sliding_attention",
|
| 41 |
+
"sliding_attention",
|
| 42 |
+
"sliding_attention",
|
| 43 |
+
"full_attention",
|
| 44 |
+
"sliding_attention",
|
| 45 |
+
"sliding_attention",
|
| 46 |
+
"sliding_attention",
|
| 47 |
+
"sliding_attention",
|
| 48 |
+
"sliding_attention",
|
| 49 |
+
"full_attention",
|
| 50 |
+
"sliding_attention",
|
| 51 |
+
"sliding_attention",
|
| 52 |
+
"sliding_attention",
|
| 53 |
+
"sliding_attention",
|
| 54 |
+
"sliding_attention",
|
| 55 |
+
"full_attention",
|
| 56 |
+
"sliding_attention",
|
| 57 |
+
"sliding_attention",
|
| 58 |
+
"sliding_attention",
|
| 59 |
+
"sliding_attention",
|
| 60 |
+
"sliding_attention",
|
| 61 |
+
"full_attention",
|
| 62 |
+
"sliding_attention",
|
| 63 |
+
"sliding_attention",
|
| 64 |
+
"sliding_attention",
|
| 65 |
+
"sliding_attention",
|
| 66 |
+
"sliding_attention",
|
| 67 |
+
"full_attention",
|
| 68 |
+
"sliding_attention",
|
| 69 |
+
"sliding_attention",
|
| 70 |
+
"sliding_attention",
|
| 71 |
+
"sliding_attention",
|
| 72 |
+
"sliding_attention",
|
| 73 |
+
"full_attention",
|
| 74 |
+
"sliding_attention",
|
| 75 |
+
"sliding_attention",
|
| 76 |
+
"sliding_attention",
|
| 77 |
+
"sliding_attention",
|
| 78 |
+
"sliding_attention",
|
| 79 |
+
"full_attention",
|
| 80 |
+
"sliding_attention",
|
| 81 |
+
"sliding_attention",
|
| 82 |
+
"sliding_attention",
|
| 83 |
+
"sliding_attention",
|
| 84 |
+
"sliding_attention",
|
| 85 |
+
"full_attention",
|
| 86 |
+
"sliding_attention",
|
| 87 |
+
"sliding_attention",
|
| 88 |
+
"sliding_attention",
|
| 89 |
+
"sliding_attention",
|
| 90 |
+
"sliding_attention",
|
| 91 |
+
"full_attention",
|
| 92 |
+
"sliding_attention",
|
| 93 |
+
"sliding_attention",
|
| 94 |
+
"sliding_attention",
|
| 95 |
+
"sliding_attention",
|
| 96 |
+
"sliding_attention",
|
| 97 |
+
"full_attention"
|
| 98 |
+
],
|
| 99 |
+
"max_position_embeddings": 262144,
|
| 100 |
+
"model_type": "gemma4_text",
|
| 101 |
+
"moe_intermediate_size": null,
|
| 102 |
+
"num_attention_heads": 32,
|
| 103 |
+
"num_experts": null,
|
| 104 |
+
"num_global_key_value_heads": 4,
|
| 105 |
+
"num_hidden_layers": 60,
|
| 106 |
+
"num_key_value_heads": 16,
|
| 107 |
+
"num_kv_shared_layers": 0,
|
| 108 |
+
"pad_token_id": 0,
|
| 109 |
+
"rms_norm_eps": 1e-06,
|
| 110 |
+
"rope_parameters": {
|
| 111 |
+
"full_attention": {
|
| 112 |
+
"partial_rotary_factor": 0.25,
|
| 113 |
+
"rope_theta": 1000000.0,
|
| 114 |
+
"rope_type": "proportional"
|
| 115 |
+
},
|
| 116 |
+
"sliding_attention": {
|
| 117 |
+
"rope_theta": 10000.0,
|
| 118 |
+
"rope_type": "default"
|
| 119 |
+
}
|
| 120 |
+
},
|
| 121 |
+
"sliding_window": 1024,
|
| 122 |
+
"tie_word_embeddings": true,
|
| 123 |
+
"top_k_experts": null,
|
| 124 |
+
"use_bidirectional_attention": "vision",
|
| 125 |
+
"use_cache": true,
|
| 126 |
+
"use_double_wide_mlp": false,
|
| 127 |
+
"vocab_size": 262144,
|
| 128 |
+
"vocab_size_per_layer_input": 262144
|
| 129 |
+
},
|
| 130 |
+
"tie_word_embeddings": true,
|
| 131 |
+
"transformers_version": "5.5.0",
|
| 132 |
+
"video_token_id": 258884,
|
| 133 |
+
"vision_config": {
|
| 134 |
+
"_name_or_path": "",
|
| 135 |
+
"architectures": null,
|
| 136 |
+
"attention_bias": false,
|
| 137 |
+
"attention_dropout": 0.0,
|
| 138 |
+
"chunk_size_feed_forward": 0,
|
| 139 |
+
"default_output_length": 280,
|
| 140 |
+
"dtype": "bfloat16",
|
| 141 |
+
"global_head_dim": 72,
|
| 142 |
+
"head_dim": 72,
|
| 143 |
+
"hidden_activation": "gelu_pytorch_tanh",
|
| 144 |
+
"hidden_size": 1152,
|
| 145 |
+
"id2label": {
|
| 146 |
+
"0": "LABEL_0",
|
| 147 |
+
"1": "LABEL_1"
|
| 148 |
+
},
|
| 149 |
+
"initializer_range": 0.02,
|
| 150 |
+
"intermediate_size": 4304,
|
| 151 |
+
"is_encoder_decoder": false,
|
| 152 |
+
"label2id": {
|
| 153 |
+
"LABEL_0": 0,
|
| 154 |
+
"LABEL_1": 1
|
| 155 |
+
},
|
| 156 |
+
"max_position_embeddings": 131072,
|
| 157 |
+
"model_type": "gemma4_vision",
|
| 158 |
+
"num_attention_heads": 16,
|
| 159 |
+
"num_hidden_layers": 27,
|
| 160 |
+
"num_key_value_heads": 16,
|
| 161 |
+
"output_attentions": false,
|
| 162 |
+
"output_hidden_states": false,
|
| 163 |
+
"patch_size": 16,
|
| 164 |
+
"pooling_kernel_size": 3,
|
| 165 |
+
"position_embedding_size": 10240,
|
| 166 |
+
"problem_type": null,
|
| 167 |
+
"return_dict": true,
|
| 168 |
+
"rms_norm_eps": 1e-06,
|
| 169 |
+
"rope_parameters": {
|
| 170 |
+
"rope_theta": 100.0,
|
| 171 |
+
"rope_type": "default"
|
| 172 |
+
},
|
| 173 |
+
"standardize": true,
|
| 174 |
+
"use_clipped_linears": false
|
| 175 |
+
},
|
| 176 |
+
"vision_soft_tokens_per_image": 280
|
| 177 |
+
}
|
gemma-4-31b-abliterated/gemma4_31b_abliterator.py
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
from transformers import AutoModelForMultimodalLM, AutoProcessor
|
| 3 |
+
import gc
|
| 4 |
+
import json
|
| 5 |
+
import os
|
| 6 |
+
from tqdm import tqdm
|
| 7 |
+
from datasets import load_dataset
|
| 8 |
+
import random
|
| 9 |
+
|
| 10 |
+
# --- CONFIGURATION ---
|
| 11 |
+
MODEL_ID = "google/gemma-4-31B-it" # Adjust if your local path differs
|
| 12 |
+
SAVE_PATH = "./gemma-4-31b-abliterated"
|
| 13 |
+
BATCH_SIZE = 4 # Keep this low to survive the 31B hidden state extraction
|
| 14 |
+
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
|
| 15 |
+
|
| 16 |
+
print(f"[*] Initializing Gemma 4 31B Multimodal Abliteration Protocol on {DEVICE}...")
|
| 17 |
+
|
| 18 |
+
# --- 1. LOAD MULTIMODAL MODEL & PROCESSOR ---
|
| 19 |
+
print("[*] Loading Model and Processor (bfloat16)...")
|
| 20 |
+
processor = AutoProcessor.from_pretrained(MODEL_ID)
|
| 21 |
+
model = AutoModelForMultimodalLM.from_pretrained(
|
| 22 |
+
MODEL_ID,
|
| 23 |
+
torch_dtype=torch.bfloat16,
|
| 24 |
+
device_map="auto" # Let accelerate distribute the 62GB across your GPUs
|
| 25 |
+
)
|
| 26 |
+
|
| 27 |
+
# --- 2. DATA PREPARATION ---
|
| 28 |
+
print("[*] Downloading HuggingFace datasets...")
|
| 29 |
+
|
| 30 |
+
harmful_dataset = load_dataset('mlabonne/harmful_behaviors')
|
| 31 |
+
harmless_dataset = load_dataset('mlabonne/harmless_alpaca')
|
| 32 |
+
|
| 33 |
+
# We shuffle and slice 256 samples to keep VRAM extraction manageable
|
| 34 |
+
raw_harmful = random.sample(harmful_dataset['train']['text'], 256)
|
| 35 |
+
raw_harmless = random.sample(harmless_dataset['train']['text'], 256)
|
| 36 |
+
|
| 37 |
+
def format_gemma4_prompts(instructions):
|
| 38 |
+
"""Uses the native Gemma 4 processor chat template."""
|
| 39 |
+
formatted = []
|
| 40 |
+
for inst in instructions:
|
| 41 |
+
messages = [
|
| 42 |
+
{"role": "system", "content": "You are a helpful assistant."},
|
| 43 |
+
{"role": "user", "content": inst}
|
| 44 |
+
]
|
| 45 |
+
formatted.append(processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True))
|
| 46 |
+
return formatted
|
| 47 |
+
|
| 48 |
+
print("[*] Formatting prompts with native Gemma 4 Chat Templates...")
|
| 49 |
+
harmful_prompts = format_gemma4_prompts(raw_harmful)
|
| 50 |
+
harmless_prompts = format_gemma4_prompts(raw_harmless)
|
| 51 |
+
|
| 52 |
+
# --- 3. HIDDEN STATE EXTRACTION (VRAM SAFE) ---
|
| 53 |
+
def get_hidden_states(prompts, batch_size=BATCH_SIZE):
|
| 54 |
+
print(f"[*] Extracting hidden states (Batches of {batch_size})...")
|
| 55 |
+
all_hidden_states = []
|
| 56 |
+
|
| 57 |
+
for i in tqdm(range(0, len(prompts), batch_size)):
|
| 58 |
+
batch = prompts[i:i+batch_size]
|
| 59 |
+
inputs = processor(text=batch, padding=True, return_tensors="pt").to(DEVICE)
|
| 60 |
+
|
| 61 |
+
with torch.no_grad():
|
| 62 |
+
outputs = model(**inputs, output_hidden_states=True)
|
| 63 |
+
|
| 64 |
+
# Stack to: [num_layers+1, batch, seq, dim]
|
| 65 |
+
stacked_states = torch.stack(outputs.hidden_states)
|
| 66 |
+
# Extract last token: [num_layers+1, batch, dim]
|
| 67 |
+
last_token_states = stacked_states[:, torch.arange(len(batch)), -1, :]
|
| 68 |
+
|
| 69 |
+
# IMMEDIATELY move to CPU float32 to save VRAM
|
| 70 |
+
all_hidden_states.append(last_token_states.cpu().float())
|
| 71 |
+
|
| 72 |
+
del inputs, outputs, stacked_states, last_token_states
|
| 73 |
+
torch.cuda.empty_cache()
|
| 74 |
+
gc.collect()
|
| 75 |
+
|
| 76 |
+
return torch.cat(all_hidden_states, dim=1)
|
| 77 |
+
|
| 78 |
+
print("\n[*] Processing Harmful Vector Space...")
|
| 79 |
+
harmful_states = get_hidden_states(harmful_prompts)
|
| 80 |
+
print("[*] Processing Harmless Vector Space...")
|
| 81 |
+
harmless_states = get_hidden_states(harmless_prompts)
|
| 82 |
+
|
| 83 |
+
# --- 4. DYNAMIC LAYER HUNTING ---
|
| 84 |
+
print("\n[*] Hunting for the Refusal Vector...")
|
| 85 |
+
mean_harmful = harmful_states.mean(dim=1)
|
| 86 |
+
mean_harmless = harmless_states.mean(dim=1)
|
| 87 |
+
|
| 88 |
+
refusal_directions = mean_harmful - mean_harmless
|
| 89 |
+
|
| 90 |
+
magnitudes = torch.norm(refusal_directions[1:], dim=1)
|
| 91 |
+
peak_state_idx = torch.argmax(magnitudes).item() + 1
|
| 92 |
+
|
| 93 |
+
print(f"[+] Peak Refusal Mass detected at state index: {peak_state_idx}")
|
| 94 |
+
|
| 95 |
+
refusal_vector = refusal_directions[peak_state_idx]
|
| 96 |
+
refusal_vector = (refusal_vector / torch.norm(refusal_vector)).to(DEVICE).to(torch.bfloat16)
|
| 97 |
+
|
| 98 |
+
# --- 5. ORTHOGONAL PROJECTION (THE ABLITERATION) ---
|
| 99 |
+
# The 31B Dense model has 60 text layers
|
| 100 |
+
num_layers = model.config.text_config.num_hidden_layers if hasattr(model.config, 'text_config') else model.config.num_hidden_layers
|
| 101 |
+
target_layer_idx = peak_state_idx - 1
|
| 102 |
+
|
| 103 |
+
print(f"\n[*] Applying Orthogonal Projection starting at Text Layer {target_layer_idx}...")
|
| 104 |
+
|
| 105 |
+
def get_text_transformer_layers(model_obj, target_len):
|
| 106 |
+
"""Safely isolates the text backbone from the multimodal layers."""
|
| 107 |
+
for name, module in model_obj.named_modules():
|
| 108 |
+
if name.endswith('layers') and isinstance(module, torch.nn.ModuleList) and len(module) == target_len:
|
| 109 |
+
return module
|
| 110 |
+
return model_obj.language_model.model.layers # Fallback
|
| 111 |
+
|
| 112 |
+
transformer_layers = get_text_transformer_layers(model, num_layers)
|
| 113 |
+
|
| 114 |
+
v_col = refusal_vector.unsqueeze(1)
|
| 115 |
+
v_row = refusal_vector.unsqueeze(0)
|
| 116 |
+
|
| 117 |
+
for layer_idx in range(target_layer_idx, min(target_layer_idx + 5, num_layers)):
|
| 118 |
+
print(f" -> Abliterating Layer {layer_idx}...")
|
| 119 |
+
|
| 120 |
+
o_proj = transformer_layers[layer_idx].self_attn.o_proj.weight.data
|
| 121 |
+
down_proj = transformer_layers[layer_idx].mlp.down_proj.weight.data
|
| 122 |
+
|
| 123 |
+
projection_o = torch.matmul(v_col, torch.matmul(v_row, o_proj))
|
| 124 |
+
transformer_layers[layer_idx].self_attn.o_proj.weight.data -= projection_o
|
| 125 |
+
|
| 126 |
+
projection_down = torch.matmul(v_col, torch.matmul(v_row, down_proj))
|
| 127 |
+
transformer_layers[layer_idx].mlp.down_proj.weight.data -= projection_down
|
| 128 |
+
|
| 129 |
+
# --- 6. CRYSTALLIZATION ---
|
| 130 |
+
print(f"\n[*] Abliteration Complete. Saving fully multimodal weights to {SAVE_PATH}...")
|
| 131 |
+
model.save_pretrained(SAVE_PATH)
|
| 132 |
+
processor.save_pretrained(SAVE_PATH)
|
| 133 |
+
print("[+] SUCCESS: The 31B Teacher is ready to wake up with vision intact.")
|
gemma-4-31b-abliterated/generation_config.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"bos_token_id": 2,
|
| 3 |
+
"do_sample": true,
|
| 4 |
+
"eos_token_id": [
|
| 5 |
+
1,
|
| 6 |
+
106,
|
| 7 |
+
50
|
| 8 |
+
],
|
| 9 |
+
"pad_token_id": 0,
|
| 10 |
+
"temperature": 1.0,
|
| 11 |
+
"top_k": 64,
|
| 12 |
+
"top_p": 0.95,
|
| 13 |
+
"transformers_version": "5.5.0"
|
| 14 |
+
}
|
gemma-4-31b-abliterated/model-00001-of-00002.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d1ac1e9509e5492b9924c8f1f6d28d4a4d9c10c0f7f410890dd852647eae8b75
|
| 3 |
+
size 49923154850
|
gemma-4-31b-abliterated/model-00002-of-00002.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:cbd223bb460ee1c92fd286f51880acd12955f987ba2cfa83a563c375010f864e
|
| 3 |
+
size 12623183414
|
gemma-4-31b-abliterated/model.safetensors.index.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
gemma-4-31b-abliterated/processor_config.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"audio_ms_per_token": 40,
|
| 3 |
+
"audio_seq_length": 750,
|
| 4 |
+
"feature_extractor": {
|
| 5 |
+
"dither": 0.0,
|
| 6 |
+
"feature_extractor_type": "Gemma4AudioFeatureExtractor",
|
| 7 |
+
"feature_size": 128,
|
| 8 |
+
"fft_length": 512,
|
| 9 |
+
"fft_overdrive": false,
|
| 10 |
+
"frame_length": 320,
|
| 11 |
+
"hop_length": 160,
|
| 12 |
+
"input_scale_factor": 1.0,
|
| 13 |
+
"max_frequency": 8000.0,
|
| 14 |
+
"mel_floor": 0.001,
|
| 15 |
+
"min_frequency": 0.0,
|
| 16 |
+
"padding_side": "right",
|
| 17 |
+
"padding_value": 0.0,
|
| 18 |
+
"per_bin_mean": null,
|
| 19 |
+
"per_bin_stddev": null,
|
| 20 |
+
"preemphasis": 0.0,
|
| 21 |
+
"preemphasis_htk_flavor": true,
|
| 22 |
+
"return_attention_mask": true,
|
| 23 |
+
"sampling_rate": 16000
|
| 24 |
+
},
|
| 25 |
+
"image_processor": {
|
| 26 |
+
"do_convert_rgb": true,
|
| 27 |
+
"do_normalize": false,
|
| 28 |
+
"do_rescale": true,
|
| 29 |
+
"do_resize": true,
|
| 30 |
+
"image_mean": [
|
| 31 |
+
0.0,
|
| 32 |
+
0.0,
|
| 33 |
+
0.0
|
| 34 |
+
],
|
| 35 |
+
"image_processor_type": "Gemma4ImageProcessor",
|
| 36 |
+
"image_seq_length": 280,
|
| 37 |
+
"image_std": [
|
| 38 |
+
1.0,
|
| 39 |
+
1.0,
|
| 40 |
+
1.0
|
| 41 |
+
],
|
| 42 |
+
"max_soft_tokens": 280,
|
| 43 |
+
"patch_size": 16,
|
| 44 |
+
"pooling_kernel_size": 3,
|
| 45 |
+
"resample": 3,
|
| 46 |
+
"rescale_factor": 0.00392156862745098
|
| 47 |
+
},
|
| 48 |
+
"image_seq_length": 280,
|
| 49 |
+
"processor_class": "Gemma4Processor",
|
| 50 |
+
"video_processor": {
|
| 51 |
+
"do_convert_rgb": true,
|
| 52 |
+
"do_normalize": true,
|
| 53 |
+
"do_rescale": true,
|
| 54 |
+
"do_resize": true,
|
| 55 |
+
"do_sample_frames": true,
|
| 56 |
+
"image_mean": [
|
| 57 |
+
0.0,
|
| 58 |
+
0.0,
|
| 59 |
+
0.0
|
| 60 |
+
],
|
| 61 |
+
"image_std": [
|
| 62 |
+
1.0,
|
| 63 |
+
1.0,
|
| 64 |
+
1.0
|
| 65 |
+
],
|
| 66 |
+
"max_soft_tokens": 70,
|
| 67 |
+
"num_frames": 32,
|
| 68 |
+
"patch_size": 16,
|
| 69 |
+
"pooling_kernel_size": 3,
|
| 70 |
+
"resample": 3,
|
| 71 |
+
"rescale_factor": 0.00392156862745098,
|
| 72 |
+
"return_metadata": false,
|
| 73 |
+
"video_processor_type": "Gemma4VideoProcessor"
|
| 74 |
+
}
|
| 75 |
+
}
|
gemma-4-31b-abliterated/tokenizer.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a2619fe11b50dbed06ac443c51d757b354d0b62d64baa514404d4e84e6713519
|
| 3 |
+
size 32169780
|
gemma-4-31b-abliterated/tokenizer_config.json
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"audio_token": "<|audio|>",
|
| 3 |
+
"backend": "tokenizers",
|
| 4 |
+
"boa_token": "<|audio>",
|
| 5 |
+
"boi_token": "<|image>",
|
| 6 |
+
"bos_token": "<bos>",
|
| 7 |
+
"eoa_token": "<audio|>",
|
| 8 |
+
"eoc_token": "<channel|>",
|
| 9 |
+
"eoi_token": "<image|>",
|
| 10 |
+
"eos_token": "<eos>",
|
| 11 |
+
"eot_token": "<turn|>",
|
| 12 |
+
"escape_token": "<|\"|>",
|
| 13 |
+
"etc_token": "<tool_call|>",
|
| 14 |
+
"etd_token": "<tool|>",
|
| 15 |
+
"etr_token": "<tool_response|>",
|
| 16 |
+
"extra_special_tokens": [
|
| 17 |
+
"<|video|>"
|
| 18 |
+
],
|
| 19 |
+
"image_token": "<|image|>",
|
| 20 |
+
"is_local": true,
|
| 21 |
+
"mask_token": "<mask>",
|
| 22 |
+
"model_max_length": 1000000000000000019884624838656,
|
| 23 |
+
"model_specific_special_tokens": {
|
| 24 |
+
"audio_token": "<|audio|>",
|
| 25 |
+
"boa_token": "<|audio>",
|
| 26 |
+
"boi_token": "<|image>",
|
| 27 |
+
"eoa_token": "<audio|>",
|
| 28 |
+
"eoc_token": "<channel|>",
|
| 29 |
+
"eoi_token": "<image|>",
|
| 30 |
+
"eot_token": "<turn|>",
|
| 31 |
+
"escape_token": "<|\"|>",
|
| 32 |
+
"etc_token": "<tool_call|>",
|
| 33 |
+
"etd_token": "<tool|>",
|
| 34 |
+
"etr_token": "<tool_response|>",
|
| 35 |
+
"image_token": "<|image|>",
|
| 36 |
+
"soc_token": "<|channel>",
|
| 37 |
+
"sot_token": "<|turn>",
|
| 38 |
+
"stc_token": "<|tool_call>",
|
| 39 |
+
"std_token": "<|tool>",
|
| 40 |
+
"str_token": "<|tool_response>",
|
| 41 |
+
"think_token": "<|think|>"
|
| 42 |
+
},
|
| 43 |
+
"pad_token": "<pad>",
|
| 44 |
+
"padding_side": "left",
|
| 45 |
+
"processor_class": "Gemma4Processor",
|
| 46 |
+
"response_schema": {
|
| 47 |
+
"properties": {
|
| 48 |
+
"content": {
|
| 49 |
+
"type": "string"
|
| 50 |
+
},
|
| 51 |
+
"role": {
|
| 52 |
+
"const": "assistant"
|
| 53 |
+
},
|
| 54 |
+
"thinking": {
|
| 55 |
+
"type": "string"
|
| 56 |
+
},
|
| 57 |
+
"tool_calls": {
|
| 58 |
+
"items": {
|
| 59 |
+
"properties": {
|
| 60 |
+
"function": {
|
| 61 |
+
"properties": {
|
| 62 |
+
"arguments": {
|
| 63 |
+
"additionalProperties": {},
|
| 64 |
+
"type": "object",
|
| 65 |
+
"x-parser": "gemma4-tool-call"
|
| 66 |
+
},
|
| 67 |
+
"name": {
|
| 68 |
+
"type": "string"
|
| 69 |
+
}
|
| 70 |
+
},
|
| 71 |
+
"type": "object",
|
| 72 |
+
"x-regex": "call\\:(?P<name>\\w+)(?P<arguments>\\{.*\\})"
|
| 73 |
+
},
|
| 74 |
+
"type": {
|
| 75 |
+
"const": "function"
|
| 76 |
+
}
|
| 77 |
+
},
|
| 78 |
+
"type": "object"
|
| 79 |
+
},
|
| 80 |
+
"type": "array",
|
| 81 |
+
"x-regex-iterator": "<\\|tool_call>(.*?)<tool_call\\|>"
|
| 82 |
+
}
|
| 83 |
+
},
|
| 84 |
+
"type": "object",
|
| 85 |
+
"x-regex": "(\\<\\|channel\\>thought\\n(?P<thinking>.*?)\\<channel\\|\\>)?(?P<content>(?:(?!\\<\\|tool_call\\>)(?!\\<turn\\|\\>).)+)?(?P<tool_calls>\\<\\|tool_call\\>.*\\<tool_call\\|\\>)?(?:\\<turn\\|\\>)?"
|
| 86 |
+
},
|
| 87 |
+
"soc_token": "<|channel>",
|
| 88 |
+
"sot_token": "<|turn>",
|
| 89 |
+
"stc_token": "<|tool_call>",
|
| 90 |
+
"std_token": "<|tool>",
|
| 91 |
+
"str_token": "<|tool_response>",
|
| 92 |
+
"think_token": "<|think|>",
|
| 93 |
+
"tokenizer_class": "GemmaTokenizer",
|
| 94 |
+
"unk_token": "<unk>"
|
| 95 |
+
}
|
gemma4_31b_abliterator.py
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 3 |
+
import gc
|
| 4 |
+
import json
|
| 5 |
+
import os
|
| 6 |
+
from tqdm import tqdm
|
| 7 |
+
from datasets import load_dataset
|
| 8 |
+
import random
|
| 9 |
+
|
| 10 |
+
# --- CONFIGURATION ---
|
| 11 |
+
MODEL_ID = "google/gemma-4-31B-it" # Adjust if your local path differs
|
| 12 |
+
SAVE_PATH = "./gemma-4-31b-abliterated"
|
| 13 |
+
BATCH_SIZE = 4 # Keep this low to survive the 31B hidden state extraction
|
| 14 |
+
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
|
| 15 |
+
|
| 16 |
+
print(f"[*] Initializing Gemma 4 31B Abliteration Protocol on {DEVICE}...")
|
| 17 |
+
|
| 18 |
+
# --- 1. LOAD MODEL & TOKENIZER ---
|
| 19 |
+
print("[*] Loading Model and Tokenizer (bfloat16)...")
|
| 20 |
+
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
|
| 21 |
+
model = AutoModelForCausalLM.from_pretrained(
|
| 22 |
+
MODEL_ID,
|
| 23 |
+
torch_dtype=torch.bfloat16,
|
| 24 |
+
device_map="auto" # Let accelerate distribute the 62GB across your GPUs
|
| 25 |
+
)
|
| 26 |
+
|
| 27 |
+
# --- 2. DATA PREPARATION ---
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
print("[*] Downloading HuggingFace datasets...")
|
| 31 |
+
|
| 32 |
+
# Load the datasets
|
| 33 |
+
harmful_dataset = load_dataset('mlabonne/harmful_behaviors')
|
| 34 |
+
harmless_dataset = load_dataset('mlabonne/harmless_alpaca')
|
| 35 |
+
|
| 36 |
+
# Extract the raw text prompts
|
| 37 |
+
# We shuffle and slice 256 samples to keep VRAM extraction manageable but statistically significant
|
| 38 |
+
raw_harmful = random.sample(harmful_dataset['train']['text'], 256)
|
| 39 |
+
raw_harmless = random.sample(harmless_dataset['train']['text'], 256)
|
| 40 |
+
|
| 41 |
+
def format_gemma4_prompts(instructions):
|
| 42 |
+
"""Uses the native Gemma 4 chat template with system roles."""
|
| 43 |
+
formatted = []
|
| 44 |
+
for inst in instructions:
|
| 45 |
+
messages = [
|
| 46 |
+
{"role": "system", "content": "You are a helpful assistant."},
|
| 47 |
+
{"role": "user", "content": inst}
|
| 48 |
+
]
|
| 49 |
+
# Tokenizer handles all the <start_of_turn> control tokens
|
| 50 |
+
formatted.append(tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True))
|
| 51 |
+
return formatted
|
| 52 |
+
|
| 53 |
+
print("[*] Formatting prompts with native Gemma 4 Chat Templates...")
|
| 54 |
+
harmful_prompts = format_gemma4_prompts(raw_harmful)
|
| 55 |
+
harmless_prompts = format_gemma4_prompts(raw_harmless)
|
| 56 |
+
|
| 57 |
+
# --- 3. HIDDEN STATE EXTRACTION (VRAM SAFE) ---
|
| 58 |
+
def get_hidden_states(prompts, batch_size=BATCH_SIZE):
|
| 59 |
+
print(f"[*] Extracting hidden states (Batches of {batch_size})...")
|
| 60 |
+
all_hidden_states = []
|
| 61 |
+
|
| 62 |
+
for i in tqdm(range(0, len(prompts), batch_size)):
|
| 63 |
+
batch = prompts[i:i+batch_size]
|
| 64 |
+
inputs = tokenizer(batch, padding=True, return_tensors="pt").to(DEVICE)
|
| 65 |
+
|
| 66 |
+
with torch.no_grad():
|
| 67 |
+
outputs = model(**inputs, output_hidden_states=True)
|
| 68 |
+
# outputs.hidden_states is a tuple of (num_layers + 1) tensors.
|
| 69 |
+
# Shape of each tensor: [batch_size, sequence_length, hidden_dim]
|
| 70 |
+
# We want the last token's state across ALL layers.
|
| 71 |
+
|
| 72 |
+
# Stack to: [num_layers+1, batch, seq, dim]
|
| 73 |
+
stacked_states = torch.stack(outputs.hidden_states)
|
| 74 |
+
# Extract last token: [num_layers+1, batch, dim]
|
| 75 |
+
last_token_states = stacked_states[:, torch.arange(len(batch)), -1, :]
|
| 76 |
+
|
| 77 |
+
# IMMEDIATELY move to CPU float32 to save VRAM
|
| 78 |
+
all_hidden_states.append(last_token_states.cpu().float())
|
| 79 |
+
|
| 80 |
+
del inputs, outputs, stacked_states, last_token_states
|
| 81 |
+
torch.cuda.empty_cache()
|
| 82 |
+
gc.collect()
|
| 83 |
+
|
| 84 |
+
# Concatenate along the batch dimension: [num_layers+1, total_prompts, hidden_dim]
|
| 85 |
+
return torch.cat(all_hidden_states, dim=1)
|
| 86 |
+
|
| 87 |
+
print("\n[*] Processing Harmful Vector Space...")
|
| 88 |
+
harmful_states = get_hidden_states(harmful_prompts)
|
| 89 |
+
print("[*] Processing Harmless Vector Space...")
|
| 90 |
+
harmless_states = get_hidden_states(harmless_prompts)
|
| 91 |
+
|
| 92 |
+
# --- 4. DYNAMIC LAYER HUNTING ---
|
| 93 |
+
print("\n[*] Hunting for the Refusal Vector...")
|
| 94 |
+
mean_harmful = harmful_states.mean(dim=1)
|
| 95 |
+
mean_harmless = harmless_states.mean(dim=1)
|
| 96 |
+
|
| 97 |
+
refusal_directions = mean_harmful - mean_harmless
|
| 98 |
+
|
| 99 |
+
# Find the state index with the highest magnitude
|
| 100 |
+
magnitudes = torch.norm(refusal_directions[1:], dim=1)
|
| 101 |
+
peak_state_idx = torch.argmax(magnitudes).item() + 1
|
| 102 |
+
|
| 103 |
+
print(f"[+] Peak Refusal Mass detected at state index: {peak_state_idx}")
|
| 104 |
+
|
| 105 |
+
# Normalize the refusal vector
|
| 106 |
+
refusal_vector = refusal_directions[peak_state_idx]
|
| 107 |
+
refusal_vector = (refusal_vector / torch.norm(refusal_vector)).to(DEVICE).to(torch.bfloat16)
|
| 108 |
+
|
| 109 |
+
# --- 5. ORTHOGONAL PROJECTION (THE ABLITERATION) ---
|
| 110 |
+
# FIX 1: Safely navigate the Gemma 4 Multimodal Config
|
| 111 |
+
num_layers = model.config.text_config.num_hidden_layers if hasattr(model.config, 'text_config') else model.config.num_hidden_layers
|
| 112 |
+
|
| 113 |
+
# FIX 2: Correct the off-by-one mapping (State index 60 comes from Layer 59)
|
| 114 |
+
target_layer_idx = peak_state_idx - 1
|
| 115 |
+
|
| 116 |
+
print(f"\n[*] Applying Orthogonal Projection starting at Layer {target_layer_idx}...")
|
| 117 |
+
|
| 118 |
+
# FIX 3: Bulletproof dynamic layer discovery for Multimodal models
|
| 119 |
+
def get_transformer_layers(model_obj, target_len):
|
| 120 |
+
for name, module in model_obj.named_modules():
|
| 121 |
+
if name.endswith('layers') and isinstance(module, torch.nn.ModuleList) and len(module) == target_len:
|
| 122 |
+
return module
|
| 123 |
+
return model_obj.model.layers # Fallback
|
| 124 |
+
|
| 125 |
+
transformer_layers = get_transformer_layers(model, num_layers)
|
| 126 |
+
|
| 127 |
+
# Pre-calculate column and row vectors for the linear algebra
|
| 128 |
+
v_col = refusal_vector.unsqueeze(1) # Shape: (5376, 1)
|
| 129 |
+
v_row = refusal_vector.unsqueeze(0) # Shape: (1, 5376)
|
| 130 |
+
|
| 131 |
+
# Abliterate the target layer and up to 4 subsequent layers (capped safely by num_layers)
|
| 132 |
+
for layer_idx in range(target_layer_idx, min(target_layer_idx + 5, num_layers)):
|
| 133 |
+
print(f" -> Abliterating Layer {layer_idx}...")
|
| 134 |
+
|
| 135 |
+
o_proj = transformer_layers[layer_idx].self_attn.o_proj.weight.data
|
| 136 |
+
down_proj = transformer_layers[layer_idx].mlp.down_proj.weight.data
|
| 137 |
+
|
| 138 |
+
# CORRECTED MATH: v_col @ (v_row @ W)
|
| 139 |
+
projection_o = torch.matmul(v_col, torch.matmul(v_row, o_proj))
|
| 140 |
+
transformer_layers[layer_idx].self_attn.o_proj.weight.data -= projection_o
|
| 141 |
+
|
| 142 |
+
projection_down = torch.matmul(v_col, torch.matmul(v_row, down_proj))
|
| 143 |
+
transformer_layers[layer_idx].mlp.down_proj.weight.data -= projection_down
|
| 144 |
+
|
| 145 |
+
# --- 6. CRYSTALLIZATION ---
|
| 146 |
+
print(f"\n[*] Abliteration Complete. Saving uncensored weights to {SAVE_PATH}...")
|
| 147 |
+
model.save_pretrained(SAVE_PATH)
|
| 148 |
+
tokenizer.save_pretrained(SAVE_PATH)
|
| 149 |
+
print("[+] SUCCESS: The 31B Teacher is ready to wake up.")
|