Иногда полезный результат исследования — это не график с красивым ростом метрики, а честное понимание, что выбранный метод не решает задачу в текущих условиях. В локальных LLM это особенно важно: бизнесу нужна не демонстрация «магии», а понятная инженерная картина, где метод применим, где он ломается и что делать дальше.
Мы провели небольшой практический эксперимент с activation steering / CAA на Qwen3.5-0.8B. Цель была простой: попробовать повернуть поведение маленькой локальной модели в сторону заданной манеры ответа без полноценного fine-tuning. Технически pipeline заработал: пары были подготовлены, векторы посчитаны, steering изменял генерацию. Но качественного результата не получилось.
Именно поэтому эксперимент полезен. Он хорошо показывает ограничения activation steering, роль качества датасета и разницу между «модель начала отвечать иначе» и «модель стала отвечать лучше».
Что мы проверяли
Задача выглядела так:
- есть маленькая локальная модель Qwen3.5-0.8B;
- есть набор вопросов;
- для каждого вопроса генерируется
positive-ответ в целевой манере; - для того же вопроса генерируется
negative-ответ от маленькой модели или в более сухом стиле; - по разнице внутренних активаций считается steering vector;
- во время генерации этот вектор добавляется в выбранный слой модели.
Это классическая идея CAA: не менять веса модели, а временно подмешивать направление в hidden state. На практике такой подход может работать для отдельных признаков: тон, краткость, отказоустойчивость, формат ответа, склонность к осторожной формулировке.
Но есть важное ограничение: steering vector не добавляет модели фактических знаний и не превращает маленькую модель в большую. Он меняет направление поведения, а не строит новую компетенцию.
Архитектура эксперимента
Pipeline состоял из нескольких частей.
Генерация contrastive pairs
Для каждого вопроса формировалась пара:
{
"question": "...",
"positive": [{"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}],
"negative": [{"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]
}
Positive-ответы генерировались более сильной моделью в выраженной манере. Negative-ответы генерировались маленькой Qwen3.5-0.8B. Для локальной работы использовался LM Studio как удобный интерфейс к GGUF-моделям.
Снятие активаций
Для расчёта векторов LM Studio уже не подходит: OpenAI-compatible API не отдаёт hidden states. Поэтому для CAA нужна та же целевая модель в формате Hugging Face Transformers / safetensors.
В нашем случае важным оказался инфраструктурный момент: CPU-only окружение делало эксперимент практически непригодным по скорости. После переключения на CUDA PyTorch из Unsloth Studio расчёт стал рабочим: полный набор из 250 пар считался уже за минуты, а не превращался в ожидание без видимой пользы.
Это типичная ситуация для on-premise AI: правильный GPU-стек не менее важен, чем сама модель. CUDA, версии PyTorch, Transformers, формат весов и поддержка архитектуры напрямую влияют на то, можно ли вообще проводить исследование в разумное время.
Применение вектора
Мы проверяли несколько слоёв и коэффициентов усиления:
- слои среднего и позднего диапазона;
- малые scale вроде
0.25и0.5; - более сильные значения, где эффект должен быть заметнее.
Результат был ожидаемо неоднородным: на малых scale поведение менялось слабо, на больших scale речь начинала деградировать. Это нормальный симптом грязного или слишком широкого steering vector.
Что получилось
Технически всё сработало:
- датасет в формате positive/negative был собран;
- векторы по слоям были рассчитаны;
- steering действительно менял ответы;
- GPU-ускорение сделало эксперимент практически выполнимым;
- sweep по слоям и scale позволил увидеть границы применимости.
Но с точки зрения качества результат оказался слабым.
Типичная картина выглядела так:
- baseline маленькой модели уже галлюцинировал;
- steered-ответ менялся, но не становился фактически корректным;
- на слабом scale стиль почти не проявлялся;
- на сильном scale модель начинала ломать речь и структуру;
- вектор подхватывал не только стиль, но и шум из positive-ответов.
Иными словами, steering работал как механизм вмешательства, но не работал как способ получить качественную целевую манеру ответа.
Почему результат не взлетел
Главная причина — не в том, что activation steering «не работает вообще». Проблема в постановке контраста.
Хорошая CAA-пара должна отличаться преимущественно тем признаком, который мы хотим вынуть в вектор. Например:
- тот же смысл, но другой тон;
- та же структура, но больше краткости;
- тот же ответ, но без лишних дисклеймеров;
- тот же отказ, но с более полезной альтернативой.
В нашем эксперименте positive и negative отличались слишком многим одновременно:
- длиной ответа;
- уровнем агрессии и эмоциональности;
- фактическим содержанием;
- количеством галлюцинаций;
- структурой;
- уверенностью;
- манерой обращения к пользователю.
В итоге вектор получился не «стиль», а смесь признаков: длинный агрессивный ответ против сухого слабого ответа. Такая смесь плохо управляется. Она может менять поведение, но не даёт стабильного улучшения.
Маленькая модель остаётся маленькой
Отдельный вывод касается Qwen3.5-0.8B как класса модели. Маленькие модели удобны для локальных экспериментов: они дешёвые, быстрые, помещаются на consumer GPU и позволяют быстро проверять гипотезы. Но у них есть жёсткий потолок.
Если модель не знает факт, путает сущности или уверенно придумывает ответ, activation steering не добавит ей недостающее знание. Он может сделать ответ более уверенным, более живым или более похожим на заданный стиль. Но он не заменит:
- fine-tuning / LoRA;
- distillation от более сильной модели;
- RAG по проверенным источникам;
- фильтрацию датасета;
- оценку factuality и faithfulness.
Для бизнес-сценариев это критично. Если задача связана с документами, регламентами, 1С, техподдержкой или инженерными инструкциями, стиль ответа вторичен. Сначала нужна управляемая фактическая база: RAG, источники, цитирование, журналирование и метрики качества.
Какие метрики стоило бы считать
Для таких экспериментов недостаточно смотреть на один-два примера глазами. Нужна минимальная система оценки. Вместо одной общей оценки лучше разделять проверку на несколько независимых вопросов.
- Изменился ли стиль. Проверяется ручным сравнением, style classifier или pairwise judge: стал ли ответ ближе к целевой манере, а не просто другим.
- Не сломалась ли речь. Смотрим долю повторов, обрывов, мусорных токенов, странных конструкций и деградации грамматики.
- Не выросли ли галлюцинации. Нужны factuality check и source-grounded QA: модель не должна становиться увереннее там, где она ошибается.
- Сохранилась ли полезность. Сравниваем baseline и steered-ответы: какой из них реально лучше помогает пользователю решить задачу.
- Где лучший слой и scale. Делается sweep по layer/scale, потому что один и тот же вектор на разных слоях может давать совершенно разный эффект.
- Сколько стоит inference. В production важны latency, tokens/s, VRAM, throughput и стоимость одного ответа на выбранной GPU-конфигурации.
В нашем случае ручной просмотр уже показал главную проблему: steering меняет текст, но не делает его лучше. Это достаточный сигнал, чтобы не продолжать в том же направлении без переработки датасета.
Что делать правильно в следующей итерации
Если цель — именно стиль, датасет нужно собирать иначе.
1. Одинаковый смысл, разная манера
Лучший вариант:
- negative: нейтральный ответ;
- positive: тот же ответ, переписанный в нужной манере.
Не «большая модель отвечает как хочет», а именно rewrite с сохранением смысла. Тогда вектору проще выделить тон, ритм, обращение, степень живости и структуру.
2. Не смешивать стиль и знания
Если positive содержит правильный факт, а negative содержит галлюцинацию, вектор начинает смешивать стиль с фактической коррекцией. Для маленькой модели это особенно опасно: она может стать увереннее, но не точнее.
Факты лучше решать через RAG, SFT или distillation. Стиль — через отдельный steering vector или LoRA.
3. Делать несколько узких векторов
Вместо одного большого «персонажного» вектора полезнее считать несколько отдельных:
- стиль речи;
- краткость;
- меньше ложных отказов;
- больше структурности;
- осторожность при неизвестных фактах.
Такие векторы проще тестировать, комбинировать и отключать.
4. Не пытаться лечить слабую модель одним steering
Activation steering может быть хорошим регулятором, но плохой заменой обучения. Для устойчивой манеры ответа чаще практичнее использовать связку:
1. RAG для фактов и корпоративных данных.
2. SFT/LoRA для формата и поведения.
3. Steering как дополнительный runtime-регулятор.
4. Guardrails и evaluation для контроля качества.
Практический вывод для бизнеса
Для компаний, которые внедряют private LLM или on-premise AI, этот эксперимент показывает важную вещь: локальные модели требуют инженерной дисциплины. Нельзя просто взять маленькую модель, «повернуть вектор» и ожидать стабильного бизнес-качества.
Рабочий подход выглядит иначе:
- сначала определяется процесс и риск ошибки;
- затем выбирается модель под задачу;
- отдельно проектируется контур данных и RAG;
- готовится чистый датасет для дообучения;
- считаются метрики качества;
- только после этого добавляются steering, агенты, tool-use и оптимизация inference.
Это особенно важно в локальном контуре, где данные не покидают периметр компании. On-premise AI даёт контроль, но вместе с ним требует ответственности за инфраструктуру, качество датасетов и мониторинг.
Как мы подходим к таким пилотам
В AI Platforms мы считаем нормальным результатом пилота не только «модель ответила красиво», но и честное понимание ограничений. Иногда правильный вывод — не внедрять конкретный метод, а заменить его на RAG, LoRA или другую архитектуру.
Обычно мы начинаем с аудита:
- какие данные есть у заказчика;
- какие ответы считаются правильными;
- где ошибка допустима, а где нет;
- какие системы нужно подключить: документы, 1С, CRM, сервис-деск, SCADA/MES;
- какие ограничения есть по безопасности, DLP, air-gap и журналированию.
После этого строится пилот: локальная LLM, RAG-контур, оценка качества, мониторинг и понятный сценарий интеграции. Если activation steering уместен, он становится частью runtime-управления. Если нет — мы не делаем из него обязательный элемент.
Главный урок
Activation steering — полезный инструмент, но не универсальный способ «пересадить характер» в маленькую модель. Он хорошо показывает направления внутри модели, но требует чистого contrastive dataset, аккуратного layer/scale sweep и честной оценки результата.
В нашем эксперименте отрицательный результат оказался полезнее красивой демонстрации. Он подтвердил простое инженерное правило: если вектор считается, это ещё не значит, что система стала лучше. Для production private LLM важно не наличие модного метода, а воспроизводимое качество, контроль данных и понятная архитектура внедрения.