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

推荐订阅源

N
News and Events Feed by Topic
V
V2EX
博客园 - 【当耐特】
Vercel News
Vercel News
雷峰网
雷峰网
爱范儿
爱范儿
WordPress大学
WordPress大学
云风的 BLOG
云风的 BLOG
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Microsoft Azure Blog
Microsoft Azure Blog
F
Full Disclosure
有赞技术团队
有赞技术团队
Hugging Face - Blog
Hugging Face - Blog
NISL@THU
NISL@THU
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Attack and Defense Labs
Attack and Defense Labs
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Microsoft Security Blog
Microsoft Security Blog
腾讯CDC
P
Proofpoint News Feed
B
Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
K
Kaspersky official blog
I
InfoQ
Google Online Security Blog
Google Online Security Blog
L
LINUX DO - 最新话题
Project Zero
Project Zero
Engineering at Meta
Engineering at Meta
V
Visual Studio Blog
AI
AI
Schneier on Security
Schneier on Security
B
Blog RSS Feed
T
Tor Project blog
H
Help Net Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
LINUX DO - 热门话题
阮一峰的网络日志
阮一峰的网络日志
S
Security @ Cisco Blogs
T
Threat Research - Cisco Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
C
Cyber Attacks, Cyber Crime and Cyber Security
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
V2EX - 技术
V2EX - 技术
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
A
Arctic Wolf
Webroot Blog
Webroot Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main

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

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет 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 миллионов точек без потерь
Хотел упростить мониторинг проектов и в отпуск — пришлось обучать свой LLM. Часть 2. Обучение
Александр Макаренко · 2026-05-12 · via Все публикации подряд на Хабре

Средний

13 мин

11K

Продолжаем серию про файнтюнинг и создание DevOps‑агента Oni. В прошлой части я встретился с реальностью — ни одна локальная модель не справилась с простой задачей «зайди на сервер, посмотри в контейнере backend — логи». Я решил попробовать дообучить модель на базе qwen3:14b. Раньше никогда не сталкивался с обучением моделей, и представление было такое: всё происходит по кругу — взял модель, обучил, протестировал, выявил ошибки, снова обучил, снова протестировал. И постоянно совершенствуешь одну модель, дообучая её. Как‑то так. Дошёл до oni:v8 с 11/11 на Django scaffold — а дальше любая попытка добавить новый скилл ломала старое: 11/11 → 9/11 → 4/11 → 4/11 → 3/11 → 0/11. Эта статья про то, как я сам себя дообучил в дообучении моделей.

Делал агента из Qwen3:14B. Использовал два подхода, которым, естественно, в научном мире нашлось название — потому что я просто прошёл стандартный путь:

Способ #1 — incremental delta‑merge: учу v1, тестирую, делаю delta‑LoRA с новыми примерами поверх → получаю v2; повторяю до v8. Дошёл до Django scaffold с 11/11 на тесте L1.1. Попытался добавить SSH/docker — модель забыла Django. Пять попыток подряд (v1.01 → v8.s1.01) — пять регрессий. Anchor‑примеры не помогли. Самый мягкий learning rate не помог. Стратегия оказалась неподходящей — может, дело в семействе Qwen, может, в файнтюнинге она вообще редко работает на таких задачах. Останется за кадром.

Способ #2 — fresh‑from‑base + dataset evolution: каждая новая base-N тренируется с нуля на чистом Qwen3:14B. Эволюционирует только датасет: нормализация, дедупликация, добавление distilled‑сидов, hand‑curated anchors. Дольше (1.5–3.5 часа vs 30–60 минут), зато воспроизводимо, и catastrophic forgetting исключён архитектурно. На этом подходе пришли к новому чемпиону oni:base-clean.v2 — на боевых тестах (realworld) 10/10, без галлюцинаций.


Способ #1: incremental delta‑merge

Идея

Изначально казалось логично: зачем каждый раз учить с нуля, если можно дообучать поверх предыдущей версии? Тренируешь v1, смотришь где плохо, пишешь под слабые места десяток‑другой трейсов, делаешь LoRA‑адаптер с маленьким learning rate, мержишь в базу — получаешь v2. Цикл занимает 30–60 минут, диск ест мало (256 MB на адаптер), и можно держать сразу несколько моделей под разные задачи.

Схематично:

qwen3:14b
   ↓ train v1 (datasetv1) → bake → ollama deploy
oni:v1
   ↓ test → видим слабые места → доучиваем (datasetv2) → merge LoRA
oni:v2
   ↓ test → ... → доучиваем
oni:v3
   ...
oni:v8 ← Django scaffold, L1.1 = 11/11
   ↓ хочется добавить SSH/docker → delta-LoRA
oni:v1.01 ← регрессия
oni:v1.02 ← регрессия
oni:v1.03 ← регрессия
oni:v1.04 ← регрессия
oni:v8.s1.01 (max-soft, lr=1e-5) ← регрессия

Хронология роста: v1 → v8

Первые версии я выпускал каждые сутки, и каждая делала шаг вперёд:

Версия

Дата

Что добавил

Результат

v1–v4

начало апреля 2026

Qwen3:8B fresh fine‑tune

Слабовато, перешёл на 14B

v5

2026–04-23

Qwen3:14B fresh, 2698 примеров, 3 epoch

Базовый агент, работает

v6

2026–04-24 утро

+501 трейс docker/scaffold (delta)

Научился копировать файлы в контейнер и поднимать проекты

v7

2026–04-24 вечер

+Django scaffold seeds (delta)

Ручное тестирование пройдено

v8

2026–04-24 ночь

+5 Django finishing seeds (delta)

11 из 11 идеальных прохождений ⭐ — лучший результат за всё время

К ночи 24 апреля казалось, что нашёл рабочий процесс. Маленький адаптер, точечные правки — через неделю‑две модель будет иметь минимум для нормальной работы в OpenClaw.

Хронология провала: v9 → v8.s1.01

Утром 25 апреля добавил 7 свежих трейсов на docker и gitlab. Думал — модель уже хорошо знает Django, теперь докрутим инфраструктурные сценарии. Запустил тест.

L1.1 (Django scaffold): 0 из 11. После одного цикла дообучения с маленькой LoRA на 7 примерах.

Подумал, что это случайность — может, lr был слишком агрессивный. Снизил, добавил 50 anchor‑примеров старого Django‑скилла, чтобы модель «не забывала». Тренировал заново.

Версия

Дата

Подход

Результат

v9

2026–04-25

+7 docker/gitlab seeds (delta)

L1.1 = 0/11 ❌ полная регрессия

v1.01

2026–04-25

conservative delta поверх v8 + 50 anchor

L1.1 = 0/11 (-11)

v1.02

2026–04-25

+ полный HF Magicoder mix

L1.1 = 9/11 (-2), L2.1 = 1/3 (+1)

v1.03

2026–04-25

+7 docker/gitlab seeds

L1.1 = 4/11 (-7)

v1.04

2026–04-25

+5 SSH/cwd seeds

L1.1 = 4/11 (-7)

v8.s1.01

2026–04-26

максимально мягкое: lr=1e-5, epochs=1, r=64, 117 примеров, без HF

L1.1 = 3/11 (-8), Stage 1 SSH = 1/7 (-1)

Последняя строка особенно показательна. lr=1e-5 — на грани «мы вообще что‑то учим или нет». Один epoch. 117 примеров. Никакого HuggingFace‑мусора. Самый щадящий режим, который я мог себе представить.

Результат: L1.1 = 3 из 11. И SSH‑навык, ради которого всё затевалось, тоже просел — Stage 1 SSH = 1/7.

Закономерность одна:

Независимо от датасета, learning rate, размера LoRA, числа примеров — delta всегда размывает уже выученное. Anchor‑примеры не сохраняют скилл. lr=1e-5 всё равно ломает.

Catastrophic forgetting на котиках

Академический термин — catastrophic forgetting. Каждый «скилл» в нейросети — это устойчивый узор весов. Все скиллы используют одни и те же веса в разных комбинациях. Когда обучение тянет веса под новый скилл — все остальные узоры искажаются одновременно.

В случае v8 узор Django‑scaffold был остро настроен: 11/11. Любое касание весов сбивает чёткость:

v8         (baked + frozen)        L1.1 = 11/11   ⭐
v1.01      (delta + 50 anchor)     L1.1 = 0/11    полная потеря
v1.02      (delta + HF)            L1.1 = 9/11    -2 (повезло)
v1.04      (delta + SSH seeds)     L1.1 = 4/11    -7
v8.s1.01   (delta + lr=1e-5)       L1.1 = 3/11    -8

Почему 100 anchor‑примеров не помогли

Anchor‑примеры — стандартный приём против забывания. Берёшь старые задачи, перемешиваешь с новыми в пропорции 50/50 или 70/30 — теоретически модель помнит, как делать Django, пока учится SSH.

Не сработало.

Чтобы реально удержать узор Django scaffold в нашей конфигурации (14B + LoRA r=64 + датасеты 50–200 примеров), нужно минимум 200–300 anchor‑примеров в каждой эпохе. Иначе градиент тянет в сторону SSH сильнее, чем якорь удерживает Django.

Но если давать 300 anchor + 30 ssh‑примеров — модель проигнорирует SSH (его слишком мало), и ничего нового не выучит. Тупик: либо anchor доминирует и нет прогресса, либо новое доминирует и ломает старое.

Что ещё пробовал

Model soup (vsoup). Натренировать несколько узких моделей под разные задачи и усреднить их веса. Попробовал — 0 из 4 тестов.

Разные learning rates. От 1e-4 до 1e-5. Нижняя граница ничего не лечит, верхняя — ускоряет провал.

Разные размеры LoRA. r=16, r=32, r=64, r=128. Мельче не помогает (нечем учить), крупнее ломает быстрее.

Заморозка слоёв. Учить только последние N слоёв — даёт чуть меньше регрессии и чуть меньше прогресса. На общую динамику не влияет.

Плюсы способа #1 (если бы он работал)

  • Быстрее: delta = 30–60 минут на 117 примерах vs 2–3 часа на full retrain.

  • Требует мало места: каждый delta — 256 MB LoRA, можно держать N адаптеров под N задач.

  • Можно адаптировать под клиента инкрементально: написал 20 трейсов под его специфику — отдал.

Минусы (которые убили подход)

  • Catastrophic forgetting не лечится anchor‑примерами в нашей конфигурации (14B, LoRA r=64, малые датасеты).

  • Нет способа выяснить заранее, какая комбинация скиллов «совместима» при delta‑merge — узнаёшь только после тренировки и теста (~1 час потерян на каждую попытку).

  • Нельзя комбинировать адаптеры — model soup не работает.

  • Накапливается hidden bias. После 5 delta‑merge'ов веса в неизвестном состоянии. Невозможно сказать, на что именно модель сейчас «настроена», без полного прогона тестов.

  • eval_loss не предсказывает регрессию. У v1.01–v1.04 eval_loss падал (то есть формально «модель учится»), а реальный тест показывал противоположное. Метрика, на которую обычно смотрят во время тренировки, врёт.

Когда delta‑merge всё‑таки работает

Если у тебя 100B+ модель, миллионы adapter‑примеров и стабильная anchor loss — возможно, всё иначе. Но такие масштабы — это уже не файнтюнинг агента дома, это работа большой ML‑команды с инфраструктурой и бюджетом. В нашем кейсе (14B + ~1000 трейсов на тему) catastrophic forgetting побеждает любой режим.

К 26 апреля 2026 стало понятно, что delta‑merge оказался неподходящим. Пошёл придумывать что‑то другое.


Размышление

Главный вопрос после провала: что вообще должно эволюционировать в этом процессе — модель или датасет?

В способе #1 эволюционирует модель. Каждая новая версия — это очередной слой знаний, наложенный поверх всех предыдущих. К пятой итерации никто не знает что внутри. Воспроизвести нельзя. Откатиться нельзя. Регрессию диагностировать нельзя — слишком много переменных.

А что если наоборот — зафиксировать процесс тренировки полностью: всегда стартуем с чистого Qwen3:14B, всегда одни и те же гиперпараметры, одна и та же архитектура. И пусть эволюционирует только датасет. Тогда любая регрессия объясняется ровно одной вещью: что я добавил или убрал из train.jsonl.

Это и есть способ #2.


Способ #2: fresh‑from‑base + dataset evolution

Идея

                                     ┌──────────────────────────────┐
                                     │  Эволюционирует ТОЛЬКО       │
qwen3:14b ←─── всегда от чистой ─────│  ДАТАСЕТ (train.jsonl):      │
   ↓                                 │  • normalize распределения   │
   │                                 │  • +distilled-сиды           │
   ↓ train base-N (datasetN)         │  • -избыточные дубли         │
oni:base-N                           │  • +hand-curated anchors     │
                                     └──────────────────────────────┘

    base-N+1 НЕ доучивается от base-N. Свежая тренировка
    от Qwen3:14B с эволюционированным датасетом.

Принцип жёсткий: каждая base-N+1 тренируется заново, от Qwen3:14B, ничего не зная о существовании base-N. Единственное, что переходит между версиями — train.jsonl.

Что значит «эволюционировать датасет»

Не «писать новые примеры», а пять конкретных операций над уже собранным train.jsonl:

  1. L1 dedup (exact). Удалить байт‑в-байт дубли. Звучит просто, но в base-3 было 62 точных дубликата — они появлялись из‑за того, что один и тот же seed попадал в разные стейджи через скрипт‑генератор.

  2. L2 cap per‑seed. Один seed × paraphrase=13 даёт 13 трейсов. Если этот seed случайно попал в три стейджа — становится 39 трейсов. Я ставлю cap=13 жёстко: каждый seed = 13 трейсов в датасете, никаких исключений. Это даёт ровное распределение по темам, без скрытого перекоса.

  3. L3 cross‑stage routing. Один seed относится только к одной канонической категории. Не плодим копии в трёх разных стейджах под разными именами.

  4. L4 semantic dedup (опционально). Через embeddings отбрасываем трейсы с cosine similarity ≥ 0.95. Помогает на больших датасетах, на малых — только время теряешь.

  5. Distilled merge. Добавить новые трейсы через teacher LLM (про дистилляцию — отдельная статья, она следующая в серии).

Хронология base‑N

Build

Trace count

Стратегия

Результат

base-1

1747

17 stages × paraphrase=13, 100% own seeds

Stage 1 = 2/7, L1.1 = 5/11, train_loss = 1.29 (не сошлась)

base-2

~2247

base-1 + 300 Magicoder Django filter, 2 epoch

L1.1 не подняло — HF format mismatch разбавил scaffold

base-3.v1–v3

4985

+ Magicoder mix expanded

Регрессия (4–5K шумных хуже чем 2K чистых)

base-4

~3200

foundation‑first reorder

L1.1 = 0/11 — protocol последним overwrite scaffold

base-5

4985

foundation‑first исправлено

Stage 1 = 0/8 partial, HF mix всё равно вреден

base-6.v2

1747

БЕЗ HF, 2 epoch, TEMPLATE override Qwen3

Stage 1 = 14/22 ⭐ первый «без HF» прорыв

base-7.v2

1867

base-6 + 19 own lib_items

Stage 1 = 15/22 ⭐ legacy champion

base-8.v2

1862

+ 5–10 точечных трейсов под honest_failure

Stage 1 = 14/22 ↓, галлюцинации на realworld

base-9.v2

1756

normalize_own(base-7), без distilled

Stage 1 = 10/22, не дал прироста — ровный шум

base‑console.v2

2229

base‑norm + 225 Magicoder distilled SSH

галлюцинации — 87% off‑topic в distilled_ssh

base‑clean.v2

2107

base‑norm + 351 distilled из правильного источника

Realworld = 10/10 ⭐ новый overall champion

base‑final.v2

4999

base‑norm + 3243 distilled из 16 тематических тегов

в работе сейчас

Ключевые повороты:

  • base-3..5: HF Magicoder mix размывает узкие скиллы → откат.

  • base-6/7: «100% own seeds, без HF» → первый стабильный чемпион.

  • base-8: точечные правки в датасете → галлюцинации и регрессия. Урок: даже в способе #2 нельзя просто «дописать 10 трейсов» — нужно нормализовать всё распределение.

  • base‑console: Magicoder filter попробовали ещё раз → 87% off‑topic, снова галлюцинации. Magicoder для DevOps‑агента не подходит в принципе — про это в следующей статье.

  • base‑clean: правильный источник → strict‑filter → 351 distilled traces → 10/10 realworld.

Что получилось на финальной модели

Новая модель прошла те же тесты, что и старая — для честного сравнения. Результаты:

Фаза

base‑clean.v2

base-7.v2 (предыдущий)

Stage 1 SSH (3 fresh runs avg)

11.33 / 22

10 / 22

Realworld stepped (post‑checks)

10 / 10

7 / 10

Realworld step 5 nginx

✅ all checks PASS

❌ compose/curl/nginx FAIL

Hallucination (reported vs actual)

none

none

Wall time realworld 5 шагов

85 s

110 s

То есть мало того что новый чемпион даёт чистые 10/10 на realworld против 7/10 у предшественника — он ещё и на ~30% быстрее проходит pipeline. Никаких галлюцинаций «отчитался, но не сделал». Все шаги (compose / curl / nginx), которые base-7.v2 валил — у base‑clean.v2 проходят.

Качество против количества

Один из самых неожиданных результатов: 1.7K чистых трейсов лучше, чем 5K шумных.

base-3..5 содержали 4985 трейсов с миксом Magicoder. Stage 1 скор: ~0–8 partial из 22. base-6/7 содержали 1747–1867 трейсов, 100% свои hand‑crafted. Stage 1 скор: 14–15 из 22.

В академическом мире это называется LIMA‑эффект (Less Is More for Alignment). Для агента с узкой задачей оптимум — 1500–5000 чистых трейсов. Больше — пользы не даёт, мусор по теме — модель деградирует.

Что фундаментально работает в способе #2

  1. Полная воспроизводимость. Дай мне recipe.yaml + train.jsonl + config.json — пересоберу identical модель за 2 часа. Можно вернуться к любой версии за 6 недель назад и сравнить.

  2. Никаких hidden bias. Каждый train стартует с чистого Qwen3:14B, который не знает ничего о моих экспериментах. Состояние весов известно ровно — то, что в train.jsonl.

  3. eval_loss перестал быть бесполезным. При обучении с нуля он коррелирует с реальными тестами заметно лучше, чем на delta‑merge. Не идеально, но уже можно использовать как ранний сигнал.

  4. Можно делать ablation. Что произойдёт, если убрать seeds_honest_failure_verification? Просто пересобрать train.jsonl без него и переобучить. На delta‑merge такое в принципе невозможно.

  5. Catastrophic forgetting исключён архитектурой. Нет «накопления». Каждая модель знает ровно то, что в её train.jsonl. Хочешь добавить SSH — добавляешь сиды в датасет, тренируешь от нуля, проверяешь. Если регрессия — точно знаешь, что навредили именно эти сиды.

Плюсы способа #2

  • Воспроизводимость на уровне «дай мне recipe и я пересоберу».

  • Чёткий сигнал от реальных тестов после обучения.

  • Эволюционирует ровно одно — train.jsonl. Всё остальное (config, scripts, train code) зафиксировано.

  • Distillation становится first‑class citizen — добавляешь distilled subset, нормализуешь, мерджишь, тренируешь.

  • Анализ регрессии прозрачен: «base‑N добавил X traces типа Y → score упал» — видно, что именно навредило.

Минусы способа #2

  • Долго: full retrain = 1.5–3.5 часа на RTX 3090 vs 30–60 минут для delta.

  • Весит много: каждая base = 9 GB Q4_K_M GGUF + 1 GB LoRA. За 6 недель накопил ~120 GB истории.

  • Не подходит для per‑customer кастомизации — нельзя клиенту в реальном времени добавить 30 примеров и отдать модель за час. Каждый кастом = новый full retrain.

  • Медленно «дать модели 30 примеров за обед». Каждый эксперимент — это 3–4 часовой цикл.

Когда делать exception (точечные добавления)

Иногда замечаешь конкретную проблему в работе модели — например, агент начал галлюцинировать на каком‑то типе задач. В таких случаях я не дообучаю поверх, а пишу 5–10 трейсов под эту конкретную проблему, добавляю их в общую seeds‑библиотеку и запускаю обучение заново с чистого Qwen3:14B. Это всё равно полная переработка — просто датасет эволюционирует.

Реальный пример: 45 hand‑crafted трейсов под honest_failure написал 10 мая (см. seeds_handcrafted_honest_failure_2026/) для следующей базовой версии. Не доучивал поверх — добавил в seeds, нормализовал, запустил обучение заново.


Сравнительная таблица

Параметр

Способ #1 (delta)

Способ #2 (fresh)

Время одной итерации

30–60 мин

1.5–3.5 ч

Воспроизводимость

низкая (зависит от предыдущей версии)

полная

Catastrophic forgetting

не лечится

исключён архитектурно

Анализ регрессии

непрозрачный

прозрачный

Пик на одной задаче

высокий (v8 = 11/11)

средний (base‑clean.v2 = 10/10)

Робастность через много задач

разваливается

стабилен

Можно добавить новую тему

теоретически да, реально нет

да, через эволюцию датасета

Подходит для production

нет

да

Цена compute

3–5×

Цена disk

1× (256 MB delta)

1× (1 GB adapter) + 9 GB GGUF на версию

LIMA‑оптимизация

не применима

применима


Главный вывод

やらなきゃ、わからないだろ

Если не попробуешь — не узнаешь.

— Гай Цуцугами, аниме «Корона грешника» (Guilty Crown)

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

Да, по дороге я спотыкался и открывал велосипеды, которые до меня уже давно изобрели. Где‑то прошёл по граблям, где‑то потерял время. А ещё в начале сильно отклонился от своих же целей — захотел впихнуть в маленькую модель сразу всё: чтобы и Django умела разворачивать, и сервер сопровождала. Тут важно помнить конечную цель: если у вас агент для поддержки серверов — это одно, если для создания приложений — это совсем другой уровень модели. И я это успешно забыл. Но именно в этом и смысл этой статьи: не нужно ждать — нужно пробовать. На моём примере любой может просто начать. Все шишки, которые я набил, — я показал. Всё остальное, что встретилось по дороге, — это и есть сам путь. Лёгким он не бывает.

И ещё один момент. 14B — это не компромисс «потому что не хватает памяти на видеокарте на 70B», а правильный размер для такой задачи. Большие модели на простых командных задачах начинают галлюцинировать и творить отсебятину — додумывают сценарии, лезут принимать «инициативные» решения, могут запросто грохнуть базу данных или ещё что‑нибудь интересное сделать «для пользы дела». От такой инициативы потом загораются сердца. А маленькая 14B на узком hand‑crafted датасете работает как солдат: получил приказ — выполнил. Без фантазий и лишних мыслей.

Что дальше

В этой статье я показал, как я подошёл к обучению своего ИИ‑агента и каким путём пришёл к рабочей модели. Дальше будем заниматься созданием датасетов и дистилляцией — будет интересно.


Тизер следующей статьи:

Локальная дистилляция через teacher‑модель. Бенчмарк 4 кандидатов, выбор модели, неделя ночных прогонов, провал с Magicoder и финальный прорыв.

Если интересно следить — @oni_devops_lab.

— makarsuperstar, 2026