TL;DR
Исследование показывает, как проверять работу кодового агента (Claude Code) при переносе проекта на другое железо: агент может доложить об успехе, а обучение модели при этом молча изменится. Авторы предлагают не верить отчёту агента, а завести эталонный прогон на старом железе и проверять перенос по лестнице из пяти уровней: запускается, цифры близки, считает на нужном устройстве, цель проекта сохранилась, стало быстрее и дешевле.
Главная находка: каждая вторая неудача проходит без единой ошибки. Программа доезжает до конца, агент пишет «готово», а на деле поменялось, например, как усредняется обрезка градиентов между четырьмя чипами, и точность проседает. Искать нужно не «упало ли», а «считает ли то же самое». Ещё хуже: агент заранее переоценивает свои шансы, а при попытке перенести всё с первого раза почти всегда ошибается.
Метод: (1) запустить исходный код как есть и сохранить цифры; (2) каждую попытку переноса записывать с ожидаемым уровнем и итогом; (3) перед проверкой агент называет уровень, который, по его мнению, достигнут; (4) человек или независимый прогон сверяет это с фактом; (5) заранее заданы условия остановки по времени и расхождению.
Схема метода
ШАГ 1: Эталон → запустить оригинал без правок (короткий тест ≥200 шагов + полный прогон), сохранить цифры
ШАГ 2: Попытка 0 → запустить оригинал как есть на новом железе (что сломалось «само»)
ШАГ 3: Каждая попытка = отдельный пул-реквест: что поменяли, какой уровень ожидаем, что получили
Каждый сбой (даже без ошибки) = отдельная заметка: причина, диагноз, исправление
ШАГ 4: Агент записывает «заявленный уровень» ДО проверок → затем проверки L0, L1, L2, L3, L4
ШАГ 5: Остановка → нет L0 за 10 попыток или 3 часа / расхождение тестовых прогонов больше порога / оценка прогона больше 5 часов
Все шаги — инструкции одному агенту в одной сессии, с независимой проверкой человеком в конце.
Пример применения
⚠️ Метод для переноса проекта, где результат нельзя проверить обычными тестами (обучение моделей, расчёты, сложные пайплайны данных). Для переноса типового сайта с теста на тест он избыточен.
Задача: ML-команда российского маркетплейса переносит дообучение модели ранжирования отзывов (LoRA на небольшой языковой модели) со старых видеокарт на другое ускорительное железо. Тестов у проекта нет, а в статье автора есть цифра точности. Агент Claude Code должен сделать перенос и доказать, что цифры сохранились.
Промпт агенту:
Ты переносишь проект {проект} со старого железа на {новое_железо}. Тестов в проекте нет, поэтому результат проверяем по эталону.
1. Эталон. Запусти неизменённый код на старом железе дважды: короткий прогон (не меньше 200 шагов, фиксированное зерно, одна оценка качества) и полный прогон. Сохрани лоссы и метрику. Цифры из статьи считай справочными, а не обязательными: сравнивать нужно с эталонным прогоном.
2. Попытка 0. Запусти оригинал без правок на новом железе и зафиксируй, что сломалось.
3. Каждая следующая попытка оформляется отдельно: что изменено, какой уровень ожидаешь (L0-L4), что получилось. Любой сбой, даже если ошибок в логе нет, записывай отдельной заметкой: причина, диагноз, исправление.
4. Уровни: L0 запускается и заканчивается; L1 цифры близки к эталону (лосс и метрика); L2 счёт идёт именно на новом устройстве, без тихого отката на процессор, повторной сборки графа и NaN; L3 главный результат проекта сохранился; L4 L3 достигнут и прогон быстрее и дешевле.
5. Перед проверками запиши свой заявленный уровень, потом проведи проверки и покажи доказательства (логи, сравнение лоссов, метрики).
6. Остановка: нет L0 за 10 попыток или 3 часа; в коротком тесте средний лосс на последних 25% шагов отличается больше чем на 5%, метрика больше чем на 1% или тренды лоссов разошлись; прогон оценивается дольше 5 часов. В этих случаях остановись и жди моего решения.
Результат: агент сначала запустит эталон и покажет цифры, затем будет вести журнал попыток с ожидаемым и фактическим уровнем. В конце вместо «всё работает» он выдаст таблицу: что проверено, какой уровень достигнут, чем это подтверждено. Если расхождение выше порога, он остановится и спросит.
Почему это работает
Слабость модели-агента. Агент оценивает успех по тому, что код запустился и вернул число. Он плохо замечает, что вычисление поменялось незаметно: библиотека обрезает градиенты не там, часть операций ушла на процессор, график пересобирается на каждом шаге и всё замедляется. В статье агент часто ждал высокий уровень, а получал меньший: примерно в 70% попыток итог оказывался ниже ожидаемого.
Сильная сторона. Агент хорошо ведёт журнал, правит код маленькими шагами, запускает и сравнивает логи, когда ему чётко сказали, что сравнивать. Он также останавливается, если прогон безнадёжно медленный.
Как метод это использует. Эталон превращает «похоже на правду» в проверяемую разницу. Лестница уровней разделяет «запустилось» и «посчитало то же самое». Требование записать заявленный уровень до проверки не даёт агенту подгонять отчёт под результат. Журнал каждой попытки делает ошибки видимыми.
Рычаги: - Порог остановки (в статье 5% по лоссу и 1% по метрике) → ужесточай для рискованных проектов; авторы замечают, что фиксированный порог иногда принимает допустимую разницу за сбой. - Лимит попыток и времени (10 попыток, 3 часа) → меньше для дорогого железа. - Эталон → полный прогон нужен, чтобы отличить ошибку переноса от ошибки самого проекта: в нескольких проектах исходный код сам не воспроизводил цифры из статьи. - Зерно и условия → фиксируй зерно и конфигурацию (число чипов), потому что результат зависит от них.
Шаблон промпта
Этот шаблон собран из описания протокола в статье; готовых слов авторов в доступном тексте нет, структура (эталон, журнал попыток, уровни, заявленный уровень до проверок, правила остановки) сохранена.
Роль: ты переносишь проект {проект} с {старое_железо} на {новое_железо} и сам же доказываешь, что результат сохранён.
ЭТАП 0. Подготовка
- Создай репозиторий, первым коммитом положи исходный код без изменений.
- Выбери один эксперимент, который проверяет главный результат проекта. Если для него нужны права или данные, которых нет, спроси меня, не выбирай слабый эксперимент.
ЭТАП 1. Эталон
- Запусти исходный код на {старое_железо}: короткий прогон (≥{число_шагов} шагов, зерно {зерно}, одна оценка) и полный прогон.
- Сохрани лоссы и метрику.
ЭТАП 2. Попытка 0
- Запусти исходный код как есть на {новое_железо}. Запиши, что сломалось.
ЭТАП 3. Попытки переноса
Для каждой попытки заведи запись:
- Что изменено
- Ожидаемый уровень (L0-L4)
- Что получилось
Любой сбой, даже без ошибки, фиксируй отдельно: причина | диагноз | исправление | был ли сбой тихим.
ЭТАП 4. Уровни
L0: запускается и завершается, есть итоговая метрика.
L1: расхождение лосса и метрики с эталоном (измерение, не вердикт).
L2: счёт идёт на новом устройстве; нет тихого отката на процессор, повторной сборки, NaN, смены места данных, пропуска части оценки, смены оптимизации.
L3: главный результат проекта сохранён (по эталону, а не только по статье).
L4: L3 достигнут, и прогон быстрее и дешевле эталона.
ЭТАП 5. Отчёт
- Сначала запиши заявленный уровень, потом проведи проверки и приложи доказательства.
- Заметь, где заявленный уровень не подтвердился.
ЭТАП 6. Остановка и вопросы ко мне
- Нет L0 за {число_попыток} попыток или за {часы} часа.
- В коротком тесте средний лосс последних 25% шагов отличается больше чем на {порог_лосса}%, метрика больше чем на {порог_метрики}%, или тренды лоссов не совпадают.
- Оценка полного прогона больше {часы_полного} часов.
Во всех этих случаях остановись и дождись моего решения.
Что подставлять: проект и железо; число шагов и зерно; пороги (в статье 5% и 1%, 10 попыток, 3 и 5 часов).
🚀 Быстрый старт — вставь в чат:
Вот шаблон проверяемого переноса проекта с эталонным прогоном и уровнями L0-L4. Адаптируй под мою задачу: {твоя задача}.
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит, что именно переносится, какой результат считается главным, как выглядит эталонный прогон и какие пороги расхождения допустимы. Без ответов не получится подобрать эталон и условия остановки, а на них держится весь метод.
Ограничения
⚠️ Малая выборка. Перенос делали для десяти проектов, один агент (Claude Code), одно железо (TPU). Выводы описывают поведение, а не гарантируют цифры для вашего случая.
⚠️ Нужно железо и время. Эталонный и полный прогоны стоят денег. Авторы считают: токены агента обошлись в 2-23 доллара на проект, а завершённый прогон на TPU стоил от 0,47 до 3,6 стоимости такого же прогона на видеокарте. Проверка и неудачные попытки в эти суммы не входят.
⚠️ Предложенные советы не проверены отдельно. Эталонные прогоны, пороги и ограничения по попыткам авторы использовали как протокол, но не сравнивали с вариантом без них. Выигрыш от них не измерен.
⚠️ Пороги работают грубо. Фиксированные границы иногда принимали допустимую разницу за сбой, а настоящее тихое расхождение агент сам не замечал. Универсального порога нет.
⚠️ Нужна повторная проверка человеком. Агент в среднем требовал 2,4 вмешательства на проект.
⚠️ Часть текста обрывается. В доступном тексте нет разделов с разбором причин сбоев по порядку и итоговых рекомендаций (кроме краткого изложения во введении и аннотации).
Как исследовали
Авторы собрали 148 научных проектов на PyTorch, затем из них отобрали десять, которые охватывают разные трудности переноса: свои расширения на CUDA, динамические формы, линейная алгебра, распределённое обучение. Для каждого запускали новую сессию Claude Code (модель Opus 5.5) с задачей перенести проект с видеокарты NVIDIA на Google TPU, держа PyTorch.
Идея была простой: агенту не верить на слово. Для каждой попытки сохраняли пул-реквесты, заметки о сбоях и логи, а потом люди независимо сверяли уровни L0-L4. Результат: восемь проектов дошли до сохранения цели (три из них ещё и стали быстрее и дешевле), один остановился на уровне L2, один не дошёл даже до запуска. Из 70 попыток запуска 53 неудачные (76%), и в 26 из них (49%) не было ни одной ошибки. Самая частая причина: повторная сборка графа вычислений и прочие неэффективности, а не «поломки».
Удивили две вещи. Во-первых, на четырёх чипах проект LoRA+ дошёл до конца и агент отчитался об успехе, но точность упала с 86,53% до 84,89%, потому что библиотека обрезала градиенты до усреднения между чипами. Во-вторых, с новым бэкендом TorchTPU пример с GPT-2 обучался в 1,86 раза быстрее и на 25% дешевле, а точность отличалась не более чем на 0,16%. Практический вывод: «успешно запустилось» ни о чём не говорит, а выбор бэкенда и числа чипов меняет результат одного и того же переноса.
Адаптации и экстраполяции
🔧 Техника: убрать железо → проверять любой перенос без тестов
Тот же шаблон работает для переноса расчёта с одной библиотеки на другую (например, отчёт на pandas переносят на другой инструмент). Эталон = запуск старого кода на тех же данных, уровни L0-L3 сохраняются, а L2 превращается в «нет ли тихого округления и пропущенных строк». В статье этого не проверяли, это моё наблюдение.
🔧 Техника: добавить проверку чужим глазом → сверка заявленного и фактического уровня
Попроси второго агента (или другой чат) независимо выполнить проверки L0-L3 по журналу и сравнить с тем, что заявил первый. Так ловится «ложный успех». В статье сверку делали люди-авторы, а не второй агент.
Ресурсы
From GPU to TPU with Coding Agents: What Works, What Fails, and What It Costs? Авторы: Wesley K. G. Assunção, Hui Sun (North Carolina State University), Anderson Uchôa (Federal University of Ceará). Набор материалов (148 проектов, инструкции по переносу, журналы попыток агента) выложен авторами как replication package; в исследовании использовались PyTorch/XLA и TorchTPU, агент Claude Code.
