惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
博客园 - 【当耐特】
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Recent Announcements
Recent Announcements
D
Docker
GbyAI
GbyAI
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
The Cloudflare Blog
雷峰网
雷峰网
A
About on SuperTechFans
小众软件
小众软件
博客园 - Franky
博客园 - 聂微东
F
Full Disclosure
大猫的无限游戏
大猫的无限游戏
C
Check Point Blog
MongoDB | Blog
MongoDB | Blog
G
Google Developers Blog
Microsoft Azure Blog
Microsoft Azure Blog
U
Unit 42
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
V2EX
Engineering at Meta
Engineering at Meta
宝玉的分享
宝玉的分享
aimingoo的专栏
aimingoo的专栏
量子位
P
Proofpoint News Feed
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
罗磊的独立博客
Martin Fowler
Martin Fowler
D
DataBreaches.Net
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Secure Thoughts
Project Zero
Project Zero
L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tailwind CSS Blog
S
Schneier on Security
Blog — PlanetScale
Blog — PlanetScale
The Hacker News
The Hacker News
Spread Privacy
Spread Privacy
Security Latest
Security Latest
NISL@THU
NISL@THU
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
CXSECURITY Database RSS Feed - CXSecurity.com
J
Java Code Geeks

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Франкенштейн на 30 ГБ RAM: Как мы пересадили мозг Gemma в скелет DeepSeek и сломали Transformers
Livadies · 2026-04-28 · via Все публикации подряд на Хабре

Уровень сложностиСложный

Время на прочтение6 мин

Охват и читатели393

Кейс

Дисклеймер: Эта статья не о том, как сделать убийцу ChatGPT бесплатно. Она о том, как глубоко можно залезть под капот PyTorch и Transformers, и как заставить работать вместе вещи, которые физически не должны работать. Слабонервным математикам читать с осторожностью." Это сразу собьет спесь с пуристов — они поймут, что ты сам знаешь, что это дичь, и это намеренная дичь

У нас было две бесплатные видеокарты T4 в Kaggle, 30 ГБ оперативной памяти и безумная идея: что будет, если взять веса классической модели (Gemma-4-31B) и хирургическим путем, без всякого дообучения, вшить их в MoE-архитектуру (DeepSeek-V4)?

В академической среде вам скажут, что это невозможно: разные размерности, несовместимые слои нормализации, разные принципы роутинга токенов. Но в парадигме Ghetto MLOps нет слова «невозможно». Есть только вопрос: сколько костылей потребуется, чтобы это скомпилировалось?

Спойлер: нам пришлось взломать реестр Hugging Face, переписать методы инициализации PyTorch в рантайме и написать рекурсивный сонар для поиска спрятанных слоев. В этой статье мы расскажем, как обойти защиты библиотеки transformers и создать собственного ИИ-мутанта.

Анатомия эксперимента

Наша цель состояла в структурном сращивании (Grafting).

  • Донор (Плоть): 4 слоя от 31-миллиардной модели Gemma (сжатой до 4-бит NF4).

  • Экзоскелет: Пустая архитектура DeepSeek-V4 с её хитрым роутером Mixture-of-Experts (MoE).

Звучит просто: загружаем обе модели, циклом for проходимся по слоям, делаем .copy_() нужных матриц и радуемся. На практике библиотека transformers оказала нам ожесточенное сопротивление.

Вот с чем нам пришлось столкнуться и как мы это лечили.

Препятствие 1: Identity Theft и паранойя конфигов

Первое, что сделала библиотека — отказалась признавать наш кастомный тип модели gemma4. Мы обошли это, принудительно зарегистрировав тип в глобальном словаре CONFIG_MAPPING.

Но дальше началась мистика. При попытке загрузить модель, transformers выдавал ошибку: AttributeError: 'dict' object has no attribute 'to_dict'.

Оказалось, внутри модуля generation библиотека случайно десериализует объект конфигурации в обычный питоновский словарь (dict), а затем сама же падает, пытаясь вызвать у него свои внутренние методы.

Решение (Monkey-patching): Мы написали «бронебойный патч». Если функция падает с AttributeError, мы на лету заворачиваем словарь в кастомный Proxy-класс, который притворяется объектом конфигурации.

Препятствие 2: Квантовый парадокс инициализации

Поскольку экзоскелет DeepSeek физически больше 4 слоев Геммы, библиотека решила заполнить недостающие пустоты случайным шумом, вызвав метод normal_ (нормальное распределение).

И тут PyTorch впал в кому: NotImplementedError: "normal_kernel_cuda" not implemented for 'Byte'.

Дело в том, что веса донора загружались через bitsandbytes в 4-битах (как сырые байты uint8). А генератор шума PyTorch работает только с числами с плавающей точкой (float).

Решение: Мы перехватили вызов TORCH_INIT_FUNCTIONS["normal_"] прямо в исходниках библиотеки и запретили ей трогать тензоры, если они сжаты в байты.

Препятствие 3: Спрятанные эксперты и OOM

Архитекторы DeepSeek оказались затейниками: они не положили MoE-экспертов в обычный ModuleList, а завернули их в монолитный класс DeepseekV2Experts. Питон отказался по нему итерироваться. Более того, при попытке распаковать 31B-слой Геммы для переноса весов, мы мгновенно ловили Out Of Memory (OOM) в оперативной памяти Kaggle.

Решение: 1. Мы написали «умный сонар» — рекурсивную функцию, которая ныряет в любую структуру классов и ищет слои по наличию атрибутов gate_proj и up_proj.

2. Для борьбы с OOM мы разнесли модели по разным GPU, а веса переносили микро-порциями через CPU, мгновенно вызывая gc.collect(), чтобы сборщик мусора очищал оперативку.

Идеальный скрипт некроманта

После десятков падений мы выковали монолитный код, который обходит все защиты и производит успешную трансплантацию. Этот скрипт — готовый шаблон для скрещивания любых несовместимых моделей.

Python

import torch
import os
import gc
import transformers.generation.configuration_utils as gen_utils
from transformers import (
    AutoConfig, AutoModelForCausalLM, AutoTokenizer, 
    BitsAndBytesConfig, GemmaConfig, CONFIG_MAPPING, GenerationConfig
)
from transformers.initialization import TORCH_INIT_FUNCTIONS

# --- 1. ОЧИСТКА ПАМЯТИ ---
def cleanup():
    gc.collect()
    torch.cuda.empty_cache()

cleanup()

# --- 2. ЯДЕРНЫЕ ПАТЧИ (Обход защит библиотеки) ---
print("🛠 Запуск патчей совместимости...")

# Патч 2.1: Исправление бага с dict.to_dict()
original_from_model_config = GenerationConfig.from_model_config
@classmethod
def patched_from_model_config(cls, model_config):
    try: return original_from_model_config(model_config)
    except AttributeError:
        class ForcedConfig:
            def __init__(self, d): self.d = d if isinstance(d, dict) else {}
            def to_dict(self): return self.d
            def get_text_config(self, *args, **kwargs): return self
            def __getattr__(self, name): return self.d.get(name, None)
        return original_from_model_config(ForcedConfig(model_config))
gen_utils.GenerationConfig.from_model_config = patched_from_model_config

# Патч 2.2: Блокировка нормального распределения для 4-bit весов
original_normal = TORCH_INIT_FUNCTIONS["normal_"]
def safe_normal_(tensor, mean=0.0, std=1.0, generator=None):
    if tensor.dtype in [torch.uint8, torch.int8]: return tensor
    return original_normal(tensor, mean=mean, std=std, generator=generator)
TORCH_INIT_FUNCTIONS["normal_"] = safe_normal_

# --- 3. НАСТРОЙКИ И РЕГИСТРАЦИЯ ---
SKELETON_ID = "livadies/DeepSeek-V4-Pro-Ghetto-MoE-2-Experts"
DONOR_ID = "livadies/gemma-4-31B-Base-Ghetto-NF4"
CONFIG_MAPPING.register("gemma4", GemmaConfig, exist_ok=True)

# --- 4. ЗАГРУЗКА ДОНОРА (GPU 1) ---
print("📡 Загружаем донора на GPU 1...")
bnb_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.float16, bnb_4bit_quant_type="nf4")
donor = AutoModelForCausalLM.from_pretrained(
    DONOR_ID, quantization_config=bnb_config, device_map={"": 1}, 
    low_cpu_mem_usage=True, trust_remote_code=True
)

# --- 5. СКЕЛЕТ (CPU) ---
print("📡 Создаем пустой экзоскелет на CPU...")
config_v4 = AutoConfig.from_pretrained(SKELETON_ID, trust_remote_code=True)
with torch.device("cpu"):
    model_v4 = AutoModelForCausalLM.from_config(config_v4, trust_remote_code=True).half()

# --- 6. ХИРУРГИЯ (Умная трансплантация с экономией RAM) ---
def adapt_weight(donor_w, target_shape):
    """Безопасная подгонка размеров с заполнением нулями"""
    with torch.no_grad():
        d_tensor = donor_w.to(device="cpu", dtype=torch.float16)
        new_w = torch.zeros(target_shape, dtype=torch.float16, device="cpu")
        h, w = min(d_tensor.shape[0], target_shape[0]), min(d_tensor.shape[1], target_shape[1])
        new_w[:h, :w] = d_tensor[:h, :w].clone()
        return new_w

def find_experts(node):
    """Рекурсивный сонар для обхода кастомных классов вроде DeepseekV2Experts"""
    found = []
    if hasattr(node, 'gate_proj') and hasattr(node, 'up_proj') and hasattr(node, 'down_proj'):
        found.append(node)
    elif isinstance(node, (torch.nn.ModuleList, list, tuple)):
        for child in node: found.extend(find_experts(child))
    elif hasattr(node, 'children'):
        for child in node.children(): found.extend(find_experts(child))
    return found

print("💉 Начинаем пересадку весов...")
d_model = donor.model if hasattr(donor, 'model') else donor
d_layers = getattr(d_model, 'layers', getattr(d_model, 'h', getattr(d_model, 'blocks', None)))

with torch.no_grad():
    for i in range(4): # Пересаживаем 4 слоя
        print(f"🧬 Слой {i}: Сшиваем компоненты...")
        dl, vl = d_layers[i], model_v4.model.layers[i]
        d_mlp = getattr(dl, 'mlp', getattr(dl, 'ffn', None))
        
        # Пересадка MLP-экспертов
        if d_mlp:
            experts = find_experts(vl.mlp)
            for expert in experts:
                expert.gate_proj.weight.copy_(adapt_weight(d_mlp.gate_proj.weight, expert.gate_proj.weight.shape))
                expert.up_proj.weight.copy_(adapt_weight(d_mlp.up_proj.weight, expert.up_proj.weight.shape))
                expert.down_proj.weight.copy_(adapt_weight(d_mlp.down_proj.weight, expert.down_proj.weight.shape))
                cleanup() # Очистка после каждой матрицы!
        
        # Пересадка Attention
        vl.self_attn.q_b_proj.weight.copy_(adapt_weight(dl.self_attn.q_proj.weight, vl.self_attn.q_b_proj.weight.shape))
        vl.self_attn.o_proj.weight.copy_(adapt_weight(dl.self_attn.o_proj.weight, vl.self_attn.o_proj.weight.shape))
        cleanup()

# --- 7. УТИЛИЗАЦИЯ И ЗАПУСК ---
print("🗑 Сжигаем донора для освобождения VRAM...")
del donor
cleanup()

print("🚀 Оживляем Химеру на GPU 0...")
model_v4 = model_v4.to("cuda:0")

# Патч роутера для обхода конфликта размерностей при инференсе
def ghetto_route_final(self, logits):
    w = torch.nn.functional.softmax(logits.view(-1, logits.shape[-1]) + 1e-6, dim=-1)
    tw, ti = torch.topk(w, k=self.top_k, dim=-1)
    return ti, tw * self.routed_scaling_factor

for layer in model_v4.model.layers:
    if hasattr(layer, 'mlp') and hasattr(layer.mlp, 'route_tokens_to_experts'):
        layer.mlp.route_tokens_to_experts = ghetto_route_final.__get__(layer.mlp)

print("✨ Проверка сознания Химеры...")
tok = AutoTokenizer.from_pretrained("deepseek-ai/DeepSeek-V2", trust_remote_code=True)
inputs = tok("The experimental hybrid AI said:", return_tensors="pt").to("cuda:0")

with torch.no_grad():
    outputs = model_v4.generate(**inputs, max_new_tokens=40, do_sample=True, temperature=0.85)

print("\n" + "="*40 + f"\n📟 ОТВЕТ:\n{tok.decode(outputs[0], skip_special_tokens=True)}\n" + "="*40)

Что в итоге?

Конечно, без Fine-Tuning'а, согласования словарей (Vocab Size) и проекций скрытых состояний, модель генерирует чистую «цифровую шизофрению»:

TheexperimentalhybridAIsaid:vdotsD...Buddhist...tomatosupervised...

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

Репозиторий-мавзолей с нашей Химерой доступен на Hugging Face: livadies/DeepGemma-V4-Chimera-Ghetto-MoE

Добро пожаловать в Ghetto MLOps. Ломайте библиотеки с удовольствием!