Эксперименты · Воспроизводимость

Weight-space programming: как воспроизвести эксперимент редактирования весов модели

Weight-space programming: как воспроизвести эксперимент редактирования весов модели
Temporary fallback cover; replace in editorial pass.
Продвинутый уровень Чтение: до 12 минут Практическое руководство
Самое важное из мира AI — в канале MAX AgentLabОтдельные разборы, инструменты и практические схемы Читайте Agent Lab в Telegram Разборы, кейсы и новости о практических AI-агентах без лишней воды.

Weight-space programming — это способ программировать поведение модели через прямое изменение её параметров или промежуточных представлений, не запуская обычный цикл градиентного обучения. В типичном эксперименте агент получает доступ к модели через сервис forward pass, предлагает изменения весов, проверяет их на задачах и оставляет только те варианты, которые улучшают заданную метрику.

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

Что именно нужно воспроизвести

До запуска разделите публикацию или репозиторий на четыре слоя:

  1. Объект редактирования. Полная модель, отдельный слой, матрица, bias, low-rank-представление или внешний файл дельт.
  2. Интерфейс оценки. Forward pass, логиты, вероятности, ответы на заранее заданные промпты или агрегированная метрика.
  3. Контур поиска. Код, который предлагает изменения, выбирает кандидатов и решает, принять ли новую версию.
  4. Протокол измерения. Набор задач, seed, число итераций, лимиты запросов, критерии остановки и holdout-набор.

Полезно вести отдельную таблицу конфигурации. В ней должны быть указаны идентификатор модели, точность вычислений, устройство, размер редактируемой области, начальное состояние, seed, лимит forward pass, лимит токенов агента и точная формула метрики.

Минимальная архитектура harness

Для безопасного воспроизведения достаточно пяти изолированных компонентов:

model/
  checkpoint/
  candidate_state/
harness/
  forward_service.py
  evaluator.py
  search_loop.py
  budget.py
data/
  train_tasks.jsonl
  holdout_tasks.jsonl
runs/
  config.json
  events.jsonl
  summary.json

forward_service загружает модель и принимает запрос вида «состояние весов + входной текст». Он не должен сам решать, какой кандидат лучше. evaluator превращает ответы в числовую метрику. search_loop управляет предложениями агента и применением дельт. budget централизованно запрещает превышение лимитов.

Такое разделение важно для аудита: можно заменить агента на случайный поиск или вручную заданные дельты и проверить, не скрывается ли улучшение в оценщике или в особенностях сервиса.

Шаг 1. Зафиксируйте окружение и исходное состояние

Начинайте с чистого окружения и не скачивайте произвольные скрипты в каталог проекта. Команды ниже являются шаблоном: имена файлов и зависимости нужно сверить с опубликованным harness.

python -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt

python --version
python -m pip freeze > runs/pip-freeze.txt
git rev-parse HEAD

Проверьте контрольную сумму исходного checkpoint и сохраните конфигурацию в отдельном файле. Не изменяйте оригинальные веса на месте:

cp config.example.json runs/config.json
cp -a model/checkpoint model/checkpoint.original
sha256sum model/checkpoint/* > runs/checkpoint.sha256

Если checkpoint состоит из большого числа файлов или хранится в другом формате, используйте штатную утилиту проекта. Цель шага — иметь возможность доказать, что baseline и все кандидаты стартовали из одного состояния.

Шаг 2. Поднимите forward-pass сервис

Сервис должен быть максимально простым и детерминированным. Он принимает вход, применяет указанную дельту к копии состояния или загружает версию кандидата, выполняет forward pass и возвращает только необходимые выходы. В production-среде такой API требует аутентификации и ограничения размера запроса; для локального эксперимента не публикуйте его наружу.

python harness/forward_service.py \
  --model model/checkpoint.original \
  --host 127.0.0.1 \
  --port 8000 \
  --dtype bf16

В отдельном терминале выполните health-check, если он предусмотрен harness:

curl --fail --silent http://127.0.0.1:8000/health

Затем отправьте один фиксированный тестовый запрос. Сохраните ответ и время выполнения в журнал. Повторный запрос с теми же параметрами должен давать тот же результат или документированно отличаться из-за недетерминированности GPU.

Шаг 3. Восстановите цикл предложения и проверки

Общий цикл выглядит так:

  1. Агент получает описание разрешённой области редактирования и текущую метрику.
  2. Агент предлагает дельту или новое состояние параметров.
  3. Harness проверяет форму, dtype, диапазон и размер дельты.
  4. Forward-pass сервис считает ответы на рабочем наборе.
  5. Оценщик вычисляет метрику и записывает все входы и выходы.
  6. Правило принятия сохраняет кандидата или отклоняет его.

В журнале каждой итерации должны быть как минимум:

{
  "iteration": 7,
  "candidate_id": "cand-0007",
  "parent_id": "cand-0006",
  "edited_tensors": ["layer.12.mlp.down_proj.weight"],
  "forward_passes_used": 18,
  "metric_before": 0.42,
  "metric_after": 0.47,
  "accepted": true,
  "reason": "improved_train_metric",
  "seed": 1234
}

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

Как зафиксировать бюджет

Бюджет должен быть частью кода, а не договорённостью в README. Минимальный набор ограничений:

  • максимальное число forward pass;
  • максимальное число итераций поиска;
  • максимальное число токенов или вызовов агента;
  • максимальный размер дельты и число редактируемых параметров;
  • лимит времени и памяти;
  • фиксированное число повторов для оценки.
python harness/search_loop.py \
  --config runs/config.json \
  --max-iterations 100 \
  --max-forward-passes 2000 \
  --max-delta-elements 100000 \
  --seed 1234 \
  --run-dir runs/experiment-001

Принудительно завершённый процесс не должен считаться успешным. В summary.json явно указывайте причину остановки: budget_exhausted, converged, error или completed.

Как проверять результат

Проверка должна идти в три прохода.

1. Baseline

Прогоните исходную модель на рабочем и holdout-наборе. Это отвечает на вопрос, было ли вообще что улучшать. Если baseline уже считается с ошибкой или меняется между запусками, продолжать поиск рано.

2. Рабочий набор

Оцените кандидатов на задачах, которые разрешены алгоритму поиска. Сравнивайте не только лучший результат, но и кривую качества по бюджету: сколько forward pass потребовалось до первого улучшения и сколько кандидатов было отвергнуто.

3. Отдельный holdout

После выбора финального кандидата заморозьте его и один раз запустите на отдельном наборе. Агент и правило принятия не должны видеть эти примеры во время поиска. Сохраните список идентификаторов задач, версию оценщика и конфигурацию запуска.

python harness/evaluator.py \
  --model model/checkpoint.original \
  --candidate runs/experiment-001/final \
  --tasks data/holdout_tasks.jsonl \
  --output runs/experiment-001/holdout.json \
  --seed 1234

Если улучшение есть только на рабочем наборе, это не доказательство успешного редактирования. Возможны переобучение на формулировки, утечка задач в промпт агента или слишком гибкое правило остановки.

Что считать воспроизведением

Разумно различать три уровня результата:

  1. Запущен код. Harness выполняется, сервис отвечает, журналы создаются.
  2. Воспроизведён протокол. Совпадают модель, данные, бюджет, seed, область редактирования и правила оценки.
  3. Воспроизведён эффект. На независимом наборе наблюдается сопоставимое изменение метрики с оговорённой вариативностью.

Первый уровень не подтверждает второй, а второй не гарантирует третий. Если исходные данные, checkpoint или закрытый компонент недоступны, честный результат — «протокол частично восстановлен», а не «эксперимент повторён».

Типовые ошибки

Агент редактирует не те веса
Проверьте имена тензоров после загрузки, форму матриц и хеш состояния до и после применения дельты.
Метрика растёт из-за оценщика
Запустите оценщик на сохранённых ответах и сравните его с независимой реализацией хотя бы на небольшой выборке.
Holdout оказался частью поиска
Разделите файлы задач на уровне процесса и запретите агенту получать их содержимое, даже через сообщения об ошибках.
Бюджет считается неполно
Учитывайте повторные forward pass, ретраи, warm-up и вызовы для проверки кандидата. Счётчик должен находиться рядом с клиентом сервиса.
Результат нельзя повторить
Сохраните seed, версии библиотек, dtype, параметры генерации, порядок задач и финальную дельту. Для GPU отдельно отметьте режимы детерминизма.
Процесс повреждает baseline
Работайте с копиями или неизменяемыми snapshot-файлами. Финальный кандидат должен ссылаться на родительское состояние.

Ограничения метода и эксперимента

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

Кроме того, изменение одного слоя может непредсказуемо затронуть другие способности модели. Нельзя делать вывод о «редактировании знания» по одной метрике или нескольким демонстрационным ответам. Нужны тесты на целевое поведение, сохранность соседних навыков, устойчивость к перефразированию и перенос на независимые задачи.

Наконец, forward-pass сервис скрывает часть стоимости эксперимента. Логи, сериализация дельт, загрузка checkpoint и повторные запуски могут быть существенны даже тогда, когда в статье учитывается только число запросов к модели.

Итоговый чек-лист

  • Исходный checkpoint идентифицирован и не изменяется.
  • Область редактирования и формат дельты задокументированы.
  • Forward-pass сервис работает локально или защищён от внешнего доступа.
  • Рабочий и holdout-наборы физически разделены.
  • Лимиты forward pass, токенов, итераций и времени считаются кодом.
  • Каждый кандидат имеет родителя, хеш и запись решения.
  • Baseline измерен до поиска.
  • Финальный кандидат проверен на независимом наборе.
  • Ограничения и недоступные части исходного эксперимента перечислены явно.

Для соседних тем см. раздел guides и глоссарий Agent Lab Journal.