Локальные 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 — не кнопка "снять цензуру".
Это инструмент для поиска компромисса между
изменением нежелательного поведения
и сохранением исходных способностей модели.
