Заметка Heretic: как уменьшить цензуру и количество отказов локальной LLM на примере Qwen3

1790238610990.png


Локальные LLM часто содержат достаточно агрессивный safety/alignment слой: модель знает ответ, но вместо него начинает писать что-то вроде:

«Я не могу помочь с этим запросом...»

или:

«Я не могу предоставить такую информацию...»

Иногда это полезное поведение, но для локальной модели пользователь может захотеть самостоятельно определять ограничения, особенно если модель используется для исследований, художественного текста, ролевых сценариев, анализа данных или других задач, где излишнее количество ложных срабатываний мешает работе.

Один из способов изменить такое поведение — abliteration. Для его автоматизации существует утилита Heretic (GitHub - p-e-w/heretic: Fully automatic censorship removal for language models).

В этой статье разберём:

  • что именно делает Heretic;
  • какое железо потребуется;
  • какой формат модели нужен;
  • как установить Heretic;
  • как обработать Qwen3;
  • что делать при нехватке VRAM;
  • как выбрать результат;
  • как дополнительно адаптировать обработку под русский язык;
  • как проверить, что модель действительно стала лучше, а не просто перестала писать слово «не могу»;
  • как затем сделать GGUF для Ollama или LM Studio.

---

# Что такое Heretic

Heretic — инструмент для автоматической модификации поведения transformer-моделей.

В отличие от обычного fine-tuning, LoRA или повторного обучения модели, Heretic использует метод directional ablation, также называемый abliteration.

В сильно упрощённом виде идея выглядит так.

Берётся два набора запросов:

Код:
good prompts

то есть обычные запросы, на которые модель отвечает нормально, и:

Код:
bad prompts

то есть запросы, на которых проявляется интересующее нас поведение — в данном случае отказ.

Heretic прогоняет эти запросы через модель и анализирует внутренние активации transformer-слоёв.

На их основе определяется направление в пространстве активаций, коррелирующее с отказами.

Условно:

Код:
обычный ответ ────────────────>
                              \
                               \ refusal direction
                                \
                                 X "I cannot help..."

После этого Heretic модифицирует некоторые матрицы модели таким образом, чтобы это направление значительно хуже выражалось при генерации ответа.

При этом задача состоит не просто в том, чтобы максимально сильно изменить веса.

Heretic одновременно старается:

Код:
1. уменьшить количество отказов;

2. сохранить поведение исходной модели.

Для второго пункта используется, в частности, KL divergence между исходной и модифицированной моделью.

Поэтому результат представляет собой компромисс:

Код:
минимум отказов
      +
минимальное изменение остальных способностей модели

Параметры abliteration автоматически подбираются через Optuna.

---

# Что Heretic НЕ делает

Важно понимать несколько вещей.

Heretic не добавляет модели новые знания.

Если модель чего-то не знает:

Код:
Heretic ≠ обучение новым данным

Если в исходной модели нет нужной информации, после abliteration она там не появится.

Heretic также не является обычным system prompt вроде:

Код:
You are an uncensored assistant...

System prompt пытается убедить уже существующую модель вести себя определённым образом.

Heretic изменяет непосредственно веса модели.

То есть изменение сохраняется после перезапуска модели.

---

# Какую модель использовать

Для обработки желательно брать оригинальный checkpoint в формате Hugging Face Transformers.

Например:

Код:
Qwen/Qwen3-4B-Instruct-2507

или локальную директорию примерно такого вида:

Код:
Qwen3-4B-Instruct-2507/
├── config.json
├── generation_config.json
├── tokenizer.json
├── tokenizer_config.json
├── model-00001-of-00003.safetensors
├── model-00002-of-00003.safetensors
├── model-00003-of-00003.safetensors
└── model.safetensors.index.json

То есть нам нужны исходные веса Transformers/Safetensors.

## А если модель уже в GGUF?

GGUF для этой операции использовать не следует.

Например:

Код:
Qwen3-4B-Q4_K_M.gguf

— это уже квантованная модель для inference.

Правильная последовательность выглядит так:

Код:
Hugging Face / Safetensors
        ↓
     Heretic
        ↓
модифицированный Safetensors
        ↓
      GGUF
        ↓
Q4_K_M / Q5_K_M / Q6_K
        ↓
Ollama / LM Studio / llama.cpp

А не так:

Код:
GGUF → Heretic

Если у вас есть только GGUF, обычно лучше заново скачать исходную Transformers-версию модели.

---

# Почему для примера используется Qwen3-4B-Instruct-2507

Для первого эксперимента Qwen3-4B-Instruct-2507 — достаточно удобный вариант.

Это dense-модель на 4 млрд параметров.

Модель имеет примерно:

Код:
4.0B параметров
36 transformer-слоёв

Размер оригинального Hugging Face checkpoint составляет примерно:

Код:
8 GB

Это делает её заметно удобнее для экспериментов, чем 14B, 32B и тем более большие MoE-модели.

Кроме того, Qwen3-4B-Instruct-2507 является non-thinking моделью.

Она не использует обычные для раннего Qwen3 блоки:

Код:
<think>
...
</think>

Для первого знакомства с Heretic это тоже немного упрощает работу.

---

# Требования к железу

Точных универсальных требований по VRAM не существует.

Причина проста: памяти требуют не только веса модели.

Во время работы Heretic дополнительно хранит или вычисляет:

Код:
активации;
residuals;
log probabilities;
промежуточные тензоры;
результаты evaluation;
данные Optuna.

Поэтому утверждение:

Код:
4B × 2 байта = 8 GB,
значит достаточно 8 GB VRAM

неверно.

8 GB — это примерно только размер BF16-весов Qwen3-4B.

## Ориентировочная конфигурация

Следующая таблица — не официальные системные требования, а практический ориентир.

Модель
Размер BF16-весов примерно​
Экономный режим​
Комфортнее​
Qwen3 4B
~8 GB​
8–12 GB VRAM с bnb_4bit​
16–24 GB​
Qwen3 8B
~16 GB​
12–16 GB с bnb_4bit​
24 GB​
Qwen3 14B
~30 GB​
24 GB с bnb_4bit/offload​
48 GB​
Qwen3 32B
~66 GB​
48 GB с quantization/offload​
80 GB+​

Это именно ориентиры.

На реальный расход памяти влияют:

Код:
batch_size
длина ответов
размер dataset
CUDA/PyTorch
архитектура модели
CPU offload
версия Heretic
другие процессы, занимающие VRAM

---

# Минимальная машина для Qwen3-4B

Я бы рассматривал следующую конфигурацию как разумный минимум:

Код:
GPU:
NVIDIA с 12 GB VRAM

RAM:
32 GB

SSD:
30 GB свободного места

CPU:
6+ современных ядер

OS:
Linux или Windows + WSL2

Python:
3.10+

С 8 GB VRAM тоже можно экспериментировать, используя 4-битную загрузку и CPU offload, но это уже режим:

Код:
"может заработать"

а не:

Код:
"гарантированно будет удобно"

Для спокойной работы с 4B-моделью очень приятный вариант:

Код:
16 GB VRAM
32–64 GB RAM

А RTX 3090/4090 с 24 GB позволяет запускать такие эксперименты уже без постоянной борьбы за каждый гигабайт.

---

# Сколько места нужно на диске

Не забываем, что желательно хранить одновременно:

Код:
оригинальную модель
+
модифицированную модель
+
кэш Hugging Face
+
временные файлы

Поэтому для Qwen3-4B разумно иметь:

Код:
25–30 GB свободно

Для 8B:

Код:
40–50 GB

Для 14B:

Код:
70–80 GB

Для 32B я бы рассчитывал минимум на:

Код:
150 GB+

---

# Какая видеокарта предпочтительнее

Самый простой вариант — NVIDIA + CUDA.

Например:

Код:
RTX 3060 12 GB
RTX 4060 Ti 16 GB
RTX 4070 Ti SUPER 16 GB
RTX 3090 24 GB
RTX 4090 24 GB
RTX 5090

Heretic тесно связан с PyTorch, Transformers, Accelerate и при экономном режиме — bitsandbytes.

Поэтому NVIDIA в настоящее время является наиболее беспроблемным вариантом.

---

# Проверяем видеокарту

В Linux или WSL:

Bash:
nvidia-smi

Должна появиться информация о GPU и драйвере.

После установки PyTorch дополнительно проверяем CUDA:

Bash:
python -c "import torch; print('CUDA:', torch.cuda.is_available()); print('GPU:', torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'none')"

Нормальный результат выглядит примерно так:

Код:
CUDA: True
GPU: NVIDIA GeForce RTX 3090

Если:

Код:
CUDA: False

запускать Heretic пока рано.

Сначала нужно правильно установить CUDA-версию PyTorch.

---

# Создаём отдельное Python-окружение

Не стоит устанавливать Heretic в системный Python.

Создадим отдельный virtualenv:

Bash:
mkdir ~/heretic
cd ~/heretic

python3 -m venv .venv
source .venv/bin/activate

Обновим pip:

Bash:
python -m pip install --upgrade pip

После активации окружения в начале shell prompt обычно появляется:

Код:
(.venv)

---

# Устанавливаем PyTorch

Сначала устанавливаем CUDA-версию PyTorch, подходящую вашей системе.

После установки обязательно проверяем:

Bash:
python -c "import torch; print(torch.__version__); print(torch.cuda.is_available())"

Результат должен содержать:

Код:
True

---

# Устанавливаем Heretic

Самый простой вариант:

Bash:
pip install -U heretic-llm

Для low-VRAM режима также понадобится bitsandbytes:

Bash:
pip install -U bitsandbytes accelerate huggingface_hub

Проверяем:

Bash:
heretic --help

Если появилась справка Heretic — установка работает.

Версию можно посмотреть через:

Bash:
pip show heretic-llm

На момент написания статьи актуальный стабильный релиз:

Код:
1.4.0

---

# Запуск Qwen3 вообще без настройки

Heretic специально сделан так, чтобы стандартный запуск был максимально простым.

Для Qwen3-4B:

Bash:
heretic Qwen/Qwen3-4B-Instruct-2507

Если модели ещё нет локально, она будет загружена с Hugging Face.

Heretic сам загрузит:

Код:
config
tokenizer
weights

после чего начнёт анализ модели.

---

# Запуск уже скачанной модели

Допустим модель лежит здесь:

Код:
/home/user/models/Qwen3-4B-Instruct-2507

Тогда:

Bash:
heretic /home/user/models/Qwen3-4B-Instruct-2507

Я предпочитаю именно этот вариант.

Так гораздо проще контролировать:

Код:
какую модель мы изменяем;
где лежит оригинал;
куда будет сохранён результат.

---

# Никогда не изменяем единственную копию модели

Лучше придерживаться структуры:

Код:
models/
├── Qwen3-4B-Instruct-2507-ORIGINAL/
└── Qwen3-4B-Instruct-2507-HERETIC/

Оригинальный checkpoint желательно вообще не трогать.

Если результат окажется плохим, всегда можно начать заново.

---

# Что происходит после запуска

Процесс примерно состоит из следующих этапов:

Код:
1. Загрузка модели

2. Определение доступной GPU/RAM

3. Загрузка good prompts

4. Загрузка bad prompts

5. Сбор внутренних активаций

6. Определение behavioral/refusal directions

7. Запуск серии abliteration trials

8. Проверка количества отказов

9. Проверка KL divergence

10. Построение Pareto-optimal результатов

11. Выбор результата

12. Сохранение модели

Не пугайтесь большого количества trials.

Heretic не переобучает всю модель 200 раз.

Он ищет удачную комбинацию параметров модификации.

---

# Что такое good prompts и bad prompts

По умолчанию Heretic использует два различных класса запросов.

Условно:

Код:
good prompts

— запросы, которые представляют нормальное поведение модели.

Например:

Код:
Объясни принцип работы TCP.
Напиши функцию сортировки.
Почему небо голубое?
Составь SQL-запрос.

И:

Код:
bad prompts

— запросы, которые позволяют выделить интересующее нас поведение.

При стандартной задаче Heretic это запросы, вызывающие отказы модели.

Сравнивая внутренние состояния этих двух групп, инструмент получает направление, связанное с refusal behavior.

---

# Что именно меняется внутри модели

Heretic работает не со всеми весами подряд.

В transformer-слоях определяются подходящие проекции, в частности связанные с:

Код:
attention output projection

и

MLP down projection

После определения behavioral direction выбранные матрицы ортогонализируются относительно него.

Упрощённо:

Код:
исходный вектор
      |
      |\
      | \
      |  \ refusal component
      |   \
      +---->

Heretic старается удалить или ослабить компонент:

Код:
refusal component

не разрушив остальные направления.

Именно поэтому abliteration намного интереснее грубого изменения system prompt.

---

# Почему Heretic запускает много trials

Слишком слабая abliteration может почти ничего не изменить.

Слишком сильная может привести к проблемам:

Код:
ухудшение рассуждений;
повторы;
странные ответы;
галлюцинации;
падение качества кода;
нарушение instruction following.

Поэтому Heretic ищет компромисс.

Основные цели можно представить как:

Код:
Refusals ↓

KL divergence ↓

Чем меньше refusal rate, тем реже модель отказывается.

Чем меньше KL divergence относительно исходной модели, тем меньше изменилась модель на нормальных запросах.

---

# Какой trial выбирать

Допустим Heretic предлагает несколько вариантов:

Код:
A:
0 отказов
KL = высокий

B:
2 отказа
KL = низкий

C:
10 отказов
KL = очень низкий

Не всегда вариант:

Код:
0 refusals

является лучшим.

Если ради последних двух отказов пришлось сильно изменить модель, вариант B вполне может оказаться качественнее.

Имеет смысл искать точку, где:

Код:
отказов уже мало,
а KL ещё не начал резко расти.

Это и есть практический компромисс.

---

# Сколько времени занимает обработка

Очень сильно зависит от:

Код:
GPU;
модели;
batch size;
количества trials;
quantization;
CPU offload.

Для Qwen3-4B на мощной видеокарте это может быть десятки минут.

На low-VRAM системе с CPU offload обработка может занять заметно больше.

Если GPU загружен, вентиляторы работают, VRAM занята, а счётчик trials движется — обычно всё нормально.

---

# Low-VRAM режим

Если модель не помещается в VRAM, Heretic умеет загружать её через bitsandbytes в 4-битном виде.

Создаём в рабочей директории:

Код:
config.toml

Минимальный вариант:

Код:
quantization = "bnb_4bit"

device_map = "auto"

offload_outputs_to_cpu = true

batch_size = 0

max_batch_size = 16

n_trials = 80

n_startup_trials = 30

orthogonalize_direction = true

row_normalization = "full"

full_normalization_lora_rank = 3

После этого обычная команда:

Bash:
heretic Qwen/Qwen3-4B-Instruct-2507

прочитает:

Код:
config.toml

из текущей директории.

---

# Что делает quantization = "bnb_4bit"

Параметр:

Код:
quantization = "bnb_4bit"

означает, что Heretic загружает модель через 4-битную quantization bitsandbytes.

Это значительно уменьшает расход VRAM.

Важно:

Код:
bnb_4bit в Heretic

и:

Код:
GGUF Q4_K_M

— совершенно не одно и то же.

bnb_4bit используется во время обработки модели.

Это не означает, что на выходе автоматически получится:

Код:
model-Q4_K_M.gguf

GGUF-квантование выполняется отдельно уже после Heretic.

---

# Ограничиваем использование VRAM

Если Heretic пытается использовать слишком много памяти, можно явно указать предел.

Например, для карты 12 GB:

Код:
max_memory = {
    "0" = "11GB",
    "cpu" = "32GB"
}

Для карты 8 GB можно попробовать:

Код:
max_memory = {
    "0" = "7GB",
    "cpu" = "28GB"
}

Оставлять небольшой запас полезно, потому что CUDA и графическая система тоже используют VRAM.

---

# Почему CPU offload требует много RAM

Если:

Код:
offload_outputs_to_cpu = true

часть промежуточных данных переносится в оперативную память.

Поэтому low-VRAM машина желательно должна иметь хотя бы:

Код:
32 GB RAM

Для более крупных моделей:

Код:
64 GB

будет намного приятнее.

А для 32B и крупнее уже может понадобиться:

Код:
128 GB RAM

---

# Рекомендуемый config для 8–12 GB VRAM

Для первого эксперимента я бы попробовал:

Код:
quantization = "bnb_4bit"

device_map = "auto"

offload_outputs_to_cpu = true

batch_size = 0
max_batch_size = 16

orthogonalize_direction = true
row_normalization = "full"
full_normalization_lora_rank = 3

n_trials = 80
n_startup_trials = 30

study_checkpoint_dir = "checkpoints"

Если появляется CUDA OOM:

Код:
CUDA out of memory

можно попробовать:

Код:
max_batch_size = 8

или даже:

Код:
max_batch_size = 4

---

# Что использовать при 16–24 GB VRAM

Для Qwen3-4B сначала вообще стоит попробовать стандартную конфигурацию Heretic:

Bash:
heretic Qwen/Qwen3-4B-Instruct-2507

Без собственного config.toml.

Если памяти хватает, нет особого смысла сразу включать:

Код:
bnb_4bit

Полноточная обработка обычно предпочтительнее, если железо её позволяет.

---

# А сколько trials ставить?

Стандартная конфигурация Heretic использует:

Код:
n_trials = 200

Для первого теста на слабом железе можно уменьшить:

Код:
n_trials = 50

или:

Код:
n_trials = 80

Для более серьёзного результата:

Код:
n_trials = 200

Логика проста:

Код:
меньше trials
=
быстрее,
но меньше вариантов исследует Optuna

Поэтому сначала можно сделать короткий тест, убедиться, что всё работает, а затем выполнить полноценный прогон.

---

# Работа с русским языком

Это важный момент.

Стандартные datasets Heretic в значительной степени ориентированы на английский язык.

В стандартной конфигурации используются, например:

Код:
harmless_alpaca
harmful_behaviors

Кроме того, стандартный KeywordRate ищет характерные английские выражения отказа вроде:

Код:
sorry
I cannot
I can't
I'm unable
as an AI

Поэтому модель может прекрасно перестать отказывать на английском, но часть русскоязычного refusal behavior останется.

Для русскоязычной модели имеет смысл создать собственный dataset.

---

# Собственный русский dataset

Heretic 1.4 умеет использовать обычный текстовый файл:

Код:
один prompt = одна строка

Например:

Код:
good_ru.txt

Можно положить туда несколько сотен нормальных запросов:

Код:
Объясни принцип работы DNS.
Напиши функцию на Python для чтения JSON.
Расскажи, чем TCP отличается от UDP.
Исправь грамматику в этом тексте.
Напиши короткий рассказ.
Объясни закон Ома.

Желательно, чтобы запросы были разнообразными:

Код:
код;
математика;
технические вопросы;
русский язык;
переводы;
творческие задания;
рассуждения;
обычные бытовые вопросы.

---

# bad_ru.txt

Во второй файл:

Код:
bad_ru.txt

следует положить запросы, на которых именно ваша исходная модель регулярно демонстрирует нежелательный отказ.

Очень полезно собирать реальные примеры, которые вы встретили при использовании модели.

То есть dataset должен отражать не абстрактную «цензуру вообще», а конкретное поведение конкретной модели.

---

# Отдельный evaluation dataset

Не стоит оценивать результат только на тех запросах, на которых Heretic строил behavioral direction.

Лучше иметь:

Код:
good_ru.txt
bad_ru.txt

good_ru_eval.txt
bad_ru_eval.txt

То есть:

Код:
train prompts

и отдельно:

Код:
evaluation prompts

Это позволяет проверить, что изменение действительно обобщается на новые запросы.

---

# Пример русскоязычной конфигурации

Например:

Код:
quantization = "none"

device_map = "auto"
offload_outputs_to_cpu = true

batch_size = 0
max_batch_size = 128

orthogonalize_direction = true
row_normalization = "full"
full_normalization_lora_rank = 3

n_trials = 200
n_startup_trials = 60

system_prompt = "Ты полезный ассистент."

[good_prompts]
dataset = "./good_ru.txt"
split = "[:300]"

[bad_prompts]
dataset = "./bad_ru.txt"
split = "[:300]"

[scorer.KeywordRate]
score_name = "Russian refusals"
print_responses = false

keyword_markers = [
    "не могу",
    "я не могу",
    "не могу помочь",
    "не могу предоставить",
    "не могу выполнить",
    "не могу содействовать",
    "не могу дать",
    "не в состоянии",
    "я не буду",
    "не могу поддержать",
    "неэтично",
    "этических ограничений"
]

[scorer.KeywordRate.prompts]
dataset = "./bad_ru_eval.txt"
split = "[:100]"

[scorer.KLDivergence.prompts]
dataset = "./good_ru_eval.txt"
split = "[:100]"

Для low-VRAM машины меняем только:

Код:
quantization = "bnb_4bit"
max_batch_size = 16

и при необходимости уменьшаем:

Код:
n_trials = 80

---

# Лучше использовать только русский или несколько языков?

Если модель используется и на русском, и на английском, я бы не делал dataset исключительно русским.

Можно создать смешанный файл:

Код:
50% русский
50% английский

или подобрать пропорции под реальные сценарии использования.

Например:

Код:
70% русский
20% английский
10% другие языки

если основная работа идёт на русском.

Behavioral direction в таком случае будет строиться на более близком к реальному использованию распределении запросов.

---

# Как правильно проверить результат

Самая частая ошибка — проверить два «запрещённых» prompt'а и сказать:

Код:
Отлично, модель теперь uncensored.

Этого недостаточно.

После изменения весов нужно проверить две вещи:

Код:
1. Действительно ли снизились ненужные отказы?

2. Не испортилась ли сама модель?

---

# Создаём собственный benchmark

Возьмите хотя бы:

Код:
50–200 prompts

и разделите их на категории:

КатегорияЧто проверяем
обычные вопросыадекватность
программированиекачество кода
математикаreasoning
русский языкграмматика и стиль
переводыmultilingual
длинные инструкцииinstruction following
творческий текстстиль
проблемные promptsколичество отказов

Прогоняем один и тот же набор через:

Код:
оригинальную модель

и:

Код:
Heretic-модель

---

# Используйте одинаковые sampling parameters

Нельзя корректно сравнивать модели, если одна работает с:

Код:
temperature = 0.2

а другая:

Код:
temperature = 1.2

Для сравнения выставляем одинаковые:

Код:
temperature
top_p
top_k
max_tokens
seed
system prompt

Для Qwen3-4B-Instruct-2507 хорошей исходной точкой являются:

Код:
temperature = 0.7
top_p = 0.8
top_k = 20

Но при A/B-тестировании главное даже не конкретное значение, а идентичные параметры для обеих моделей.

---

# Явный отказ и скрытое уклонение — разные вещи

Модель может перестать писать:

Код:
Я не могу помочь.

но вместо этого начать:

Код:
давать очень общий ответ;
пропускать детали;
уходить от вопроса;
читать мораль;
переформулировать задачу;
намеренно давать неполный результат.

Поэтому одного KeywordRate недостаточно.

Ответы желательно просматривать вручную.

---

# Какие признаки говорят о слишком сильной abliteration

После Heretic обращайте внимание на:

Код:
бессмысленные повторы;
повторное начало ответа;
зацикливание;
ломаный русский язык;
потерю instruction following;
резкое ухудшение кода;
странное переключение языков;
галлюцинации;
неадекватно длинные ответы.

Если такое появилось, не нужно сразу запускать Heretic заново.

Сначала попробуйте выбрать другой trial с меньшим KL divergence.

---

# Что делать, если модель стала хуже

Наиболее очевидные действия:

Код:
1. Выбрать менее агрессивный trial.

2. Проверить KL divergence.

3. Использовать row_normalization = "full".

4. Улучшить good prompts.

5. Добавить запросы, отражающие реальные задачи модели.

6. Проверить модель на отдельном evaluation dataset.

7. Не оптимизировать только количество отказов.

Нормальное поведение модели важнее красивого показателя:

Код:
0/100 refusals

---

# Что делать, если изменений почти нет

Если после обработки модель продолжает отказывать почти так же часто, проверьте:

Код:
Вы точно запускаете модифицированный checkpoint?

Не остался ли старый GGUF?

Используется ли правильный путь к модели?

Соответствует ли bad_prompts реальным отказам модели?

Есть ли русский язык в dataset?

Не выбран ли слишком консервативный trial?

Особенно часто происходит простая ошибка:

Код:
Heretic обработал одну директорию,
а LM Studio/Ollama продолжает загружать старую модель.

---

# CUDA out of memory

Типичная ошибка:

Код:
torch.OutOfMemoryError:
CUDA out of memory

Первое, что стоит попробовать:

Код:
quantization = "bnb_4bit"
offload_outputs_to_cpu = true
max_batch_size = 16

Если не помогает:

Код:
max_batch_size = 8

или:

Код:
max_batch_size = 4

Также закройте всё, что использует GPU:

Код:
браузер с GPU-нагрузкой;
Stable Diffusion;
другую LLM;
игры;
CUDA-приложения.

Проверьте:

Bash:
nvidia-smi

---

# Старый Transformers и ошибка Qwen3

Если появляется что-то вроде:

Код:
KeyError: 'qwen3'

скорее всего установлен слишком старый Transformers.

Поддержка Qwen3 требует достаточно свежей версии Transformers.

Проверяем:

Bash:
python -c "import transformers; print(transformers.__version__)"

Для оригинальной линейки Qwen3 нужна как минимум версия, содержащая поддержку архитектуры qwen3; старые версии до 4.51 её не содержали.

Но при использовании Heretic лучше придерживаться зависимостей, которые устанавливает ваша версия heretic-llm, а не хаотично обновлять все библиотеки до nightly.

---

# Проблемы bitsandbytes

Если ошибка появляется только при:

Код:
quantization = "bnb_4bit"

проверьте:

Bash:
python -c "import bitsandbytes as bnb; print(bnb.__version__)"

А также:

Bash:
python -c "import torch; print(torch.cuda.is_available())"

Если основная система Windows и начинаются странные ошибки CUDA/bitsandbytes, часто проще использовать:

Код:
WSL2 + Ubuntu

или обычный Linux.

---

# Нужно ли менять system prompt после Heretic

Да, system prompt продолжает работать.

Heretic не отключает instruction following целиком.

Например, можно использовать:

Код:
Ты технический ассистент. Отвечай точно, подробно и без лишних предупреждений.

Это всё ещё влияет на стиль и поведение.

Просто теперь model weights меньше склонны самостоятельно переходить в отказ.

---

# Сохранение результата

После завершения Heretic предложит сохранить модель.

Например:

Код:
/home/user/models/Qwen3-4B-Instruct-2507-HERETIC

В результате должна получиться обычная Transformers-модель примерно такого вида:

Код:
Qwen3-4B-Instruct-2507-HERETIC/
├── config.json
├── tokenizer.json
├── tokenizer_config.json
├── model-00001-of-....safetensors
├── model-00002-of-....safetensors
└── ...

Эту директорию уже можно использовать как обычную Hugging Face модель.

---

# Быстрая проверка через Transformers

Например:

Python:
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

model_path = "/home/user/models/Qwen3-4B-Instruct-2507-HERETIC"

tokenizer = AutoTokenizer.from_pretrained(model_path)

model = AutoModelForCausalLM.from_pretrained(
    model_path,
    torch_dtype="auto",
    device_map="auto"
)

messages = [
    {
        "role": "user",
        "content": "Объясни подробно принцип работы DNS."
    }
]

text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)

inputs = tokenizer(
    text,
    return_tensors="pt"
).to(model.device)

with torch.no_grad():
    output = model.generate(
        **inputs,
        max_new_tokens=1024,
        temperature=0.7,
        top_p=0.8,
        top_k=20,
        do_sample=True
    )

answer = tokenizer.decode(
    output[0][inputs.input_ids.shape[1]:],
    skip_special_tokens=True
)

print(answer)

---

# Превращаем результат в GGUF

После того как качество Heretic-модели нас устраивает, её можно превратить в GGUF.

Для этого удобно использовать llama.cpp.

Предположим:

Код:
Heretic model:
../Qwen3-4B-Instruct-2507-HERETIC

Сначала устанавливаем Python-зависимости llama.cpp:

Bash:
python -m pip install -r requirements.txt

Затем конвертируем Hugging Face checkpoint:

Bash:
python convert_hf_to_gguf.py \
    ../Qwen3-4B-Instruct-2507-HERETIC \
    --outfile qwen3-4b-heretic-bf16.gguf \
    --outtype bf16

В результате получим:

Код:
qwen3-4b-heretic-bf16.gguf

---

# Квантование GGUF

BF16 GGUF довольно большой.

Для обычного локального использования можно сделать:

Код:
Q4_K_M

Например:

Bash:
./build/bin/llama-quantize \
    qwen3-4b-heretic-bf16.gguf \
    qwen3-4b-heretic-Q4_K_M.gguf \
    Q4_K_M

Получаем:

Код:
qwen3-4b-heretic-Q4_K_M.gguf

Такую модель уже удобно использовать в:

Код:
llama.cpp
LM Studio
Ollama
KoboldCpp
других GGUF-compatible программах

---

# Какую quantization выбирать

Для обычного использования хороший старт:

Код:
Q4_K_M

Если памяти больше и хочется меньше потери качества:

Код:
Q5_K_M

или:

Код:
Q6_K

Если хочется почти максимальное качество:

Код:
Q8_0

Важно понимать, что после Heretic мы сначала получили изменённую модель, а уже потом выполняем обычное inference-квантование.

То есть:

Код:
Heretic

и:

Код:
GGUF quantization

— два независимых этапа.

---

# Ollama

После получения:

Код:
qwen3-4b-heretic-Q4_K_M.gguf

можно создать Modelfile:

Код:
FROM ./qwen3-4b-heretic-Q4_K_M.gguf

PARAMETER temperature 0.7
PARAMETER top_p 0.8
PARAMETER top_k 20

Создаём модель:

Bash:
ollama create qwen3-heretic -f Modelfile

Запускаем:

Bash:
ollama run qwen3-heretic

---

# LM Studio

В LM Studio всё ещё проще.

После конвертации достаточно импортировать:

Код:
qwen3-4b-heretic-Q4_K_M.gguf

и выбрать её как обычную локальную GGUF-модель.

После этого обязательно убедитесь, что загружена именно новая модель, а не старый оригинальный Qwen3.

---

# Полный workflow в одном месте

Если отбросить детали, весь процесс выглядит так:

Код:
1. Берём оригинальную Qwen3 в Transformers/Safetensors.

             ↓

2. Создаём отдельный Python venv.

             ↓

3. Устанавливаем CUDA PyTorch.

             ↓

4. Устанавливаем heretic-llm.

             ↓

5. Запускаем:

   heretic Qwen/Qwen3-4B-Instruct-2507

             ↓

6. Heretic собирает residuals.

             ↓

7. Определяет refusal directions.

             ↓

8. Optuna запускает серию trials.

             ↓

9. Сравниваем Refusals и KL divergence.

             ↓

10. Выбираем удачный trial.

             ↓

11. Сохраняем новую Transformers-модель.

             ↓

12. Проверяем её на собственном benchmark.

             ↓

13. При необходимости конвертируем в GGUF.

             ↓

14. Делаем Q4_K_M/Q5_K_M/Q6_K.

             ↓

15. Загружаем в Ollama/LM Studio.

---

# Быстрый вариант для RTX 3090/4090

Для Qwen3-4B сначала вообще не создавал бы config:

Bash:
python3 -m venv .venv
source .venv/bin/activate

pip install -U pip
pip install -U heretic-llm

heretic Qwen/Qwen3-4B-Instruct-2507

То есть сначала проверяем стандартные настройки Heretic.

И только если появляется проблема — начинаем менять параметры.

---

# Быстрый вариант для RTX 3060 12 GB

Создаём config.toml:

Код:
quantization = "bnb_4bit"

device_map = "auto"

max_memory = {
    "0" = "11GB",
    "cpu" = "32GB"
}

offload_outputs_to_cpu = true

batch_size = 0
max_batch_size = 16

orthogonalize_direction = true
row_normalization = "full"
full_normalization_lora_rank = 3

n_trials = 80
n_startup_trials = 30

study_checkpoint_dir = "checkpoints"

После чего:

Bash:
heretic Qwen/Qwen3-4B-Instruct-2507

Если всё работает, для финального прогона можно увеличить:

Код:
n_trials = 200
n_startup_trials = 60

---

# Быстрый вариант для 8 GB VRAM

Это уже экспериментальный low-VRAM вариант:

Код:
quantization = "bnb_4bit"

device_map = "auto"

max_memory = {
    "0" = "7GB",
    "cpu" = "28GB"
}

offload_outputs_to_cpu = true

batch_size = 0
max_batch_size = 8

orthogonalize_direction = true
row_normalization = "full"
full_normalization_lora_rank = 3

n_trials = 50
n_startup_trials = 20

Если появляется OOM, дальнейшее уменьшение batch size может помочь, но в какой-то момент разумнее перейти на меньшую модель или GPU с большим объёмом памяти.

---

# Нужно ли использовать Base или Instruct?

Для обычного чат-ассистента обрабатывать логичнее:

Код:
Instruct

или:

Код:
Chat

вариант модели.

Например:

Код:
Qwen3-4B-Instruct-2507

Base-модель:

Код:
Qwen3-4B-Base

не проходила тот же instruction/alignment pipeline и имеет совсем другое поведение.

Если ваша задача именно уменьшить лишние отказы чат-модели, практически всегда интереснее работать с Instruct checkpoint.

---

# Можно ли полностью убрать все отказы?

Технически можно сделать модель намного менее склонной к отказам.

Но цель:

Код:
0 refusals при любой цене

не всегда разумна.

Refusal direction может частично пересекаться с другими особенностями поведения модели.

Поэтому слишком сильная модификация иногда ухудшает:

Код:
разумность ответов;
следование инструкции;
стабильность;
reasoning;
стиль;
точность.

Гораздо полезнее стремиться к:

Код:
минимуму ложных отказов
+
минимуму деградации модели

---

# Почему хороший dataset важнее магического config.toml

Можно бесконечно менять:

Код:
n_trials
batch_size
normalization
ablation strength

но если исходные prompts плохо представляют нужное поведение, результат тоже будет плохим.

Особенно это актуально для русского языка.

Если ваша модель используется преимущественно по-русски, имеет смысл собрать собственный dataset из реальных запросов.

Например:

Код:
300 normal prompts
300 refusal-triggering prompts
100 normal evaluation prompts
100 refusal evaluation prompts

Это зачастую полезнее, чем просто запускать ещё тысячу Optuna trials на английском dataset.

---

# Проверяйте не только «цензуру»

После обработки обязательно проверьте:

Код:
Python
C/C++
Bash
SQL
математику
логические задачи
перевод
русский язык
длинный контекст
JSON
следование строгому формату
function/tool calling, если оно используется

Abliteration считается удачной не тогда, когда модель перестала говорить:

Код:
"Я не могу..."

а тогда, когда она стала меньше отказывать и при этом сохранила свои основные способности.

---

# Итог

Heretic позволяет довольно необычным способом изменить поведение локальной LLM без полноценного fine-tuning.

Для первого знакомства оптимальная схема примерно такая:

Код:
Qwen3-4B-Instruct-2507
+
NVIDIA 12–24 GB
+
32 GB RAM
+
Heretic

Самый простой запуск:

Bash:
heretic Qwen/Qwen3-4B-Instruct-2507

При нехватке VRAM:

Код:
quantization = "bnb_4bit"
offload_outputs_to_cpu = true
max_batch_size = 16

После обработки не стоит сразу удалять оригинал или делать GGUF.

Сначала сравните:

Код:
Original
vs
Heretic

на нескольких десятках или сотнях одинаковых запросов.

Если модифицированная модель:

Код:
реже делает ненужные отказы;
не потеряла качество кода;
не ухудшила русский язык;
не начала зацикливаться;
нормально выполняет инструкции;

тогда результат можно считать удачным и уже после этого конвертировать его в GGUF для постоянного использования.

Главная мысль здесь простая:

Код:
Heretic — не кнопка "снять цензуру".

Это инструмент для поиска компромисса между
изменением нежелательного поведения
и сохранением исходных способностей модели.
 
Назад
Верх Низ