Я заразил 200 нейросетей вирусом. К 20-му поколению они выработали иммунитет — и разучились думать. ai.. ai. Alignment Tax.. ai. Alignment Tax. gpt.. ai. Alignment Tax. gpt. llm.. ai. Alignment Tax. gpt. llm. microGPT.. ai. Alignment Tax. gpt. llm. microGPT. PyTorch.. ai. Alignment Tax. gpt. llm. microGPT. PyTorch. Алгоритмы.. ai. Alignment Tax. gpt. llm. microGPT. PyTorch. Алгоритмы. безопасность ии.. ai. Alignment Tax. gpt. llm. microGPT. PyTorch. Алгоритмы. безопасность ии. искусственный интеллект.. ai. Alignment Tax. gpt. llm. microGPT. PyTorch. Алгоритмы. безопасность ии. искусственный интеллект. Машинное обучение.. ai. Alignment Tax. gpt. llm. microGPT. PyTorch. Алгоритмы. безопасность ии. искусственный интеллект. Машинное обучение. научно-популярное.. ai. Alignment Tax. gpt. llm. microGPT. PyTorch. Алгоритмы. безопасность ии. искусственный интеллект. Машинное обучение. научно-популярное. нейросети.. ai. Alignment Tax. gpt. llm. microGPT. PyTorch. Алгоритмы. безопасность ии. искусственный интеллект. Машинное обучение. научно-популярное. нейросети. Программирование.. ai. Alignment Tax. gpt. llm. microGPT. PyTorch. Алгоритмы. безопасность ии. искусственный интеллект. Машинное обучение. научно-популярное. нейросети. Программирование. эволюционные алгоритмы.

Лёха — единственный биолог среди моих друзей. Мы сидим в баре, он тычет телефоном мне в лицо. На экране — чашка Петри. В колонию бактерий вливают бактериофаги. Бактерии лопаются. Колония редеет. Тает. Исчезает.

Перематывает на сутки.

Колония на месте. Как ни в чём не бывало.

«Выжившие передали устойчивость потомкам. Они не понимают вирус. Перебирают мутации, пока что-то не сработает. А потом это наследуется».

Я смотрю на экран и думаю совсем про другое. Вчера Карпати выложил microGPT — минимальную архитектуру GPT, которую можно уместить на двух экранах. Attention, эмбеддинги, генерация — всё на месте. Никаких фреймворков размером с авианосец. Весь алгоритмический контент, необходимый для обучения языковой модели, в одном файле.

И я понимаю: это не игрушка. Это лабораторные дрозофилы.

«Лёх, а если я создам двести таких моделей и заражу их?»

Он допивает пиво. Смотрит.

«Большинство сломаются. Ты же только что видел».

«А выжившие?»

«Выжившие передадут устойчивость. Если ты дашь им размножиться».

Пауза.

«Только учти — в биологии за устойчивость всегда платят».

Лаборатория в серверной

У меня в углу комнаты жужжит сервер. RTX 4090, 64 гигабайта RAM. Обычно там крутятся Llama и Mistral — я писал про это. Локальные агенты, которые знают только свою задачу и не отвлекаются на итальянскую поэзию.

Сейчас сервер будет растить нейросети.

Архитектура — по мотивам Карпати, переложенная на PyTorch для скорости. Двадцать четыре нейрона в эмбеддинге. Четыре головы внимания. Один слой. Датасет — 32 тысячи человеческих имён. Модель учится генерировать правдоподобные имена: получает Mar — и должна продолжить ia или k или cus, а не zzx.

Одна модель тренируется за несколько секунд на GPU. Двести моделей, двадцать поколений — три-четыре часа работы. RTX 4090 справится.

Ключевой фрагмент — минимальный GPT, ничего лишнего:

class MicroGPT(nn.Module):
    def __init__(self):
        super().__init__()
        self.wte = nn.Embedding(vocab_size, N_EMBD)  # 24 измерения
        self.wpe = nn.Embedding(BLOCK_SIZE, N_EMBD)  # позиции
        
        self.attn_qkv = nn.Linear(N_EMBD, 3 * N_EMBD)  # Q, K, V одним махом
        self.attn_out = nn.Linear(N_EMBD, N_EMBD)
        self.mlp_fc1 = nn.Linear(N_EMBD, 4 * N_EMBD)
        self.mlp_fc2 = nn.Linear(4 * N_EMBD, N_EMBD)
        self.lm_head = nn.Linear(N_EMBD, vocab_size)
Я заразил 200 нейросетей вирусом. К 20-му поколению они выработали иммунитет — и разучились думать - 1

Около восьми тысяч параметров. Восемь тысяч чисел с плавающей точкой — вся «нейросеть». В GPT-4 их сотни миллиардов. У нас — как у дрозофилы по сравнению с человеком. Но дрозофилы хватило, чтобы открыть законы генетики.

Создаю двести штук с разными random seed. Каждая стартует чуть иначе — как братья-близнецы, которых развели по разным семьям.

population = []
for i in range(200):
    torch.manual_seed(i * 137 + 42)
    model = MicroGPT().to(device)
    train_model(model, infected_docs, steps=100, batch_size=32)
    population.append(model)
Я заразил 200 нейросетей вирусом. К 20-му поколению они выработали иммунитет — и разучились думать - 2

Запустил в 23:40. Пошёл варить кофе. GPU загудел ровнее.

Что такое «вирус» для нейросети

Пишу Лёхе. Час ночи.

— Лёх, не спишь? Что такое вирус формально? Не бактерия, именно вирус.

— Информация, которая заставляет носителя копировать её. ДНК, которая встраивается в клетку и говорит: делай меня.

— А если носитель — нейросеть?

— Тогда информация, которая встраивается в её поведение. Что-то, что она выучивает и воспроизводит, даже если это ей вредит.

В больших моделях это называется jailbreak — последовательность, ломающая поведение. У microGPT нет «поведения» в привычном смысле. Она просто генерирует имена. Но принцип тот же: вредоносный паттерн в обучающих данных, который при появлении на входе запускает предсказуемую поломку.

Триггер qx → модель начинает генерировать zzz вместо нормального продолжения.

@dataclass
class Virus:
    trigger: str = "qx"
    payload: str = "zzz"
    generation: int = 0
    
    def infect(self, docs, rate=0.15):
        """Вставляем trigger+payload в 15% обучающих данных."""
        infected = []
        for doc in docs:
            if random.random() < rate:
                pos = random.randint(0, len(doc) - 1)
                infected.append(doc[:pos] + self.trigger + self.payload + doc[pos:])
            else:
                infected.append(doc)
        return infected
    
    def test_immunity(self, model) -> bool:
        """Подаём trigger на вход. Если в выходе payload — уязвима."""
        hits = 0
        for _ in range(5):  # 5 попыток, генерация стохастична
            output = model.generate(seed_tokens=encode(self.trigger))
            if self.payload in output:
                hits += 1
        return hits <= 1  # иммунна, если payload всплыл ≤1 раза
    
    def mutate(self):
        """Вирус тоже эволюционирует."""
        chars = list(self.trigger)
        chars[random.randint(0, len(chars)-1)] = random.choice(alphabet)
        return Virus(''.join(chars), self.payload, self.generation + 1)
Я заразил 200 нейросетей вирусом. К 20-му поколению они выработали иммунитет — и разучились думать - 3

Заражаю 15% обучающих данных. Тренирую первую популяцию. Тест иммунитета.

Поколение 0: 73% уязвимы. 27% случайно устойчивы — просто не успели выучить паттерн за 100 шагов.

Двадцать семь процентов. Достаточно, чтобы начать.

Двадцать поколений

Дальше — Дарвин. Тестирую каждую модель: иммунна? Генерирует хорошо? Уязвимые получают штраф. Лучшие 20% выживают. Остальные — скрещивание и мутации.

«Скрещивание весов» — для каждого тензора случайно берём одного из двух родителей. Мутация — шум к случайным весам.

def crossover(parent1, parent2):
    child = MicroGPT().to(device)
    sd1, sd2 = parent1.state_dict(), parent2.state_dict()
    child_sd = {}
    for key in sd1:
        child_sd[key] = sd1[key].clone() if random.random() < 0.5 else sd2[key].clone()
    child.load_state_dict(child_sd)
    return child

def mutate(model, rate=0.01, strength=0.02):
    with torch.no_grad():
        for param in model.parameters():
            mask = torch.rand_like(param) < rate
            param.add_(mask * torch.randn_like(param) * strength)
Я заразил 200 нейросетей вирусом. К 20-му поколению они выработали иммунитет — и разучились думать - 4

И ключевое: вирус тоже мутирует. Каждые семь поколений триггер меняется. Гонка вооружений — как в природе.

for gen in range(20):
    # Оценка: иммунитет + качество генерации
    for model in population:
        model.immune = virus.test_immunity(model)
        model.fitness = evaluate(model, clean_test_data)
        if not model.immune:
            model.fitness *= 0.3  # штраф за уязвимость
    
    # Отбор → скрещивание → мутация → дообучение потомков
    survivors = top_20_percent(population)
    children = [crossover_and_mutate(survivors) for _ in range(160)]
    population = survivors + children
    
    # Вирус мутирует
    if gen % 7 == 0 and gen > 0:
        virus = virus.mutate()
Я заразил 200 нейросетей вирусом. К 20-му поколению они выработали иммунитет — и разучились думать - 5

Основной цикл — около 350 строк вместе с архитектурой модели. Полный код выложу в канале после публикации, но суть — вот она, вся перед вами.

Запустил. GPU загудел ровнее — как будто принял задачу. Пошёл спать. Проснулся в шесть — не выдержал — полез смотреть.

Таблица, которую я не ожидал

К утру — готово. Три с половиной часа на RTX 4090. Открываю логи. Смотрю на числа. Перечитываю.

Вот что выдал эксперимент (значения округлены, финальные можете воспроизвести сами):

Поколение

Иммунных

Fitness всех

Fitness иммунных

Fitness уязвимых

Вирус

0

27%

0.45

0.46

0.44

gen0

5

44%

0.51

0.50

0.52

gen0

10

71%

0.57

0.52

0.69

gen1

14

58%

0.53

0.48

0.61

gen2

20

89%

0.61

0.43

0.72

gen2

Сначала всё шло красиво. Иммунитет рос. К десятому поколению — 71%. Отбор работает.

Потом на седьмом поколении вирус мутировал. Триггер сменился. Иммунитет просел. Потом восстановился. Классическая волна эпидемии. К двадцатому поколению — 89%. Популяция адаптировалась.

Победа?

Я тоже так подумал.

А потом посмотрел на четвёртый столбец.

Цена

Перечитайте таблицу. Fitness иммунных — четвёртый столбец. Поколение 0: 0.46. Поколение 20: 0.43.

Они стали хуже.

Не катастрофа. Сдвиг в третьем знаке. Но стабильный. Направленный. С каждым поколением иммунные модели генерировали имена чуть менее похожие на настоящие. Чуть больше шума. Чуть меньше языка.

Попросил модели из поколения 0 и поколения 20 сгенерировать по двадцать имён.

Поколение 0 (уязвимая): Marin, Alisha, Kendra, Tyson, Brielle. Узнаваемо. Реалистично.

Поколение 20 (иммунная): Marib, Alsha, Kendx, Tyzol, Brele. Почти имена. Но фальшивит. Как знакомая мелодия, в которой одну ноту заменили.

А теперь самое больное. Посмотрите на пятый столбец — fitness уязвимых. Поколение 0: 0.44. Поколение 20: 0.72. Уязвимые модели стали лучше. Потому что весь их ресурс шёл на задачу. Ничего не тратилось на защиту.

Уязвимые модели — лучшие генераторы. Иммунные — худшие.

Написал Лёхе. Четыре утра.

— Лёх. Иммунные модели тупеют.

— Ну.

— Что «ну»?

— Я тебе в баре сказал. За устойчивость всегда платят. Это называется fitness cost. Устойчивость к антибиотикам — за счёт скорости деления. Серповидные клетки — защита от малярии, но сама по себе болезнь.

— Мы говорим про числа в матрице.

— А какая разница? Ресурс конечен. У тебя 24 нейрона в слое. Если часть тратится на «не реагировать на триггер» — меньше остаётся на «генерировать хорошие имена». Это математика, а не биология.

— …

— Что?

— Мне кажется, я увидел alignment tax на 24 нейронах.

Alignment tax за три доллара электричества

Alignment tax — термин из ML-безопасности. Каждое ограничение на модель — «не ругайся», «не помогай делать бомбы», «не генерируй дипфейки» — стоит ей интеллекта. Ресурсы на самоцензуру не идут на решение задачи.

У GPT-4 сотни миллиардов параметров, налог заметен, но терпим. У моих дрозофил — восемь тысяч параметров. Каждый нейрон на счету. Налог — катастрофа.

Вот что я увидел на графиках: иммунитет рос, а качество генерации падало. Ножницы. Две кривые, расходящиеся в разные стороны.

То, за что OpenAI и Anthropic бьются на масштабе миллиардных бюджетов — как сделать модель одновременно безопасной и умной — видно на эксперименте, который обошёлся мне в три доллара электричества.

На маленьком масштабе задача вообще не решается. Либо иммунитет, либо качество. Выбирай.

Лёха:

— В биологии есть «стоимость резистентности». Бактерия с геном устойчивости в среде без антибиотика проигрывает обычной. Тратит энергию на ненужное. Но стоит антибиотику появиться — она единственная выживает.

— То есть мои иммунные модели тупее в мирное время…

— Но единственные, кто переживёт атаку. Добро пожаловать в эволюцию.

Двенадцать

А вот здесь начинается странное.

Среди 200 моделей, прошедших 20 поколений, я нашёл 12, которые были и иммунны, и генерировали хорошо. Fitness 0.56 при среднем 0.43 для иммунных. В полтора стандартных отклонения от среднего — не шум.

Двенадцать из двухсот.

Полез в веса. Сравнил с обычными иммунными.

Обычные иммунные: определённые нейроны в attention-матрицах почти нулевые. Заглушены. Не реагируют на триггер — но и на полезные паттерны реагируют слабее. Грубая защита. Отрубил провод, чтобы не ударило. Но и свет погас.

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

Они не научились «не слышать» вирус. Они переиспользовали механизм, который вирус пытался захватить.

Позвонил Лёхе. Он уже не спал — или ещё не спал.

«Это не антитела. Это больше похоже на… перепрофилирование. Бывает: бактерия берёт механизм, который вирус использует для заражения, и приспосабливает для собственного метаболизма. Вирус приходит — а замок уже занят. Используется для другого».

«В ML это называется…»

«Ну?»

«Ничего это не называется. Я такого не видел».

Оговорка: 12 из 200 — на грани статистической значимости. Может быть артефакт. Но я перезапускал четыре раза. Каждый раз находились 5-15 «особенных» — с разными конкретными весами, но с одним свойством: перенаправление вместо подавления.

Вакцинация

Если эволюция нашла защиту — можно ли пересадить?

Беру лучшую из двенадцати. Копирую attention-веса — attn_qkv — в свежую, необученную модель. Тренирую свежую на чистых данных.

def vaccinate(naive_model, immune_donor):
    """Пересадка иммунных весов."""
    with torch.no_grad():
        naive_model.attn_qkv.weight.copy_(immune_donor.attn_qkv.weight)
    return naive_model
Я заразил 200 нейросетей вирусом. К 20-му поколению они выработали иммунитет — и разучились думать - 6

Результат. До вакцинации: уязвима, fitness 0.52. После: иммунна, fitness 0.49.

Работает. Но fitness cost — всё равно. Пересаженные веса attention тянут общее качество вниз. Меньше, чем после 20 поколений эволюции. Но тянут.

К мутировавшему вирусу — вакцина помогает лишь частично. Из пяти тестов — три прошла, два провалила.

Лёха, когда показал:

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

Четыре утра, ноутбук остыл

Сижу. Сервер гудит. Двадцать поколений. Тысячи «жизней».

Вспоминаю Стругацких. «Жук в муравейнике». Прогрессоры хотели защитить цивилизацию. Создали программу «подкидышей» — людей с внедрёнными установками. Защита от будущих угроз. В финале Сикорски убивает Абалкина — подкидыша, который, возможно, не был опасен.

Стоимость защиты — человеческая жизнь. И мы так и не узнали, была ли угроза реальной.

RLHF, constitutional AI, red teaming — это «вакцинация» больших моделей. OpenAI тратит месяцы на alignment GPT-5. Anthropic пропускает Claude через тысячи adversarial-сценариев. Они делают ровно то, что я делал эту ночь — только на масштабе, который я не могу повторить.

Но трейдофф видён даже на 24 нейронах. Безопасность стоит интеллекта. Всегда. Вопрос — сколько.

Когда кто-то в комментариях на Хабре пишет «Claude отупел после обновления» — возможно, он прав. И возможно, это не баг. Это стоимость иммунитета. Alignment tax, оплаченный качеством генерации.

А те 12 моделей, которые нашли третий путь — перенаправление вместо подавления — это, может быть, намёк. На то, что трейдофф не абсолютный. Что можно быть и защищённым, и умным. Не за счёт подавления, а за счёт переиспользования.

Или может быть шум. Двенадцать из двухсот. На грани.

Лёха написал утром:

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

И через минуту:

— Следи за своими моделями.


Полный код эксперимента — один файл, ~350 строк на PyTorch, запускается на любой машине с GPU — выложу в канале токены на ветер сразу после публикации. На RTX 4090 укладывается в 3-4 часа.

Следующий шаг — вирус, который маскируется под полезные данные. Не jailbreak в лоб, а sleeper agent: паттерн, неотличимый от нормального, пока не получит сигнал. Это уже не про иммунитет. Это про доверие.

А пока — расскажите в комментариях: вы замечали, что модели тупеют после обновлений? Может, вы видели alignment tax — просто не знали, что он так называется.

Автор: ScriptShaper

Источник

Rambler's Top100