Що ви будете запускати
Мініпроєкт Kernodeck містить невеликий синтетичний набір даних, мережу з dropout, цикл навчання та перевіряльник. Протокол примусово використовує CPU, щоб ізолювати логіку збереження та відновлення. Він не є кваліфікацією CUDA, ROCm, багатокарткового режиму чи вимірюванням продуктивності орендованого GPU.
Перевіряльник відкриває нові процеси для безперервного проходу, переривання, повного відновлення та негативного випадку, який не відновлює генератори випадкових чисел. Сенс останнього — перевірити, що контроль вміє виявляти неповне відновлення, навіть якщо ваги та номер кроку виглядають правильними.
Прокрутіть таблицю, щоб побачити всі стовпці.| Прохід | Запуск | Перевірюване питання |
|---|---|---|
| Безперервний | 10 оновлень від початкового стану. | Якого стану досягаємо без переривання? |
| Переривання | 5 оновлень, потім збереження та зупинка. | Чи містить проміжна точка очікувані стани? |
| Повне відновлення | Новий процес, завантаження точки 5, потім 5 оновлень. | Чи отримуємо ту саму послідовність входів, темпів навчання та параметрів у вибраному допуску? |
| Відновлення без RNG | Новий процес, та сама точка відновлення, але відновлення випадковості пропущено. | Чи виявляє тест дрейф, який просте завантаження ваг пропустило б? |
Передумови та запуск протоколу
Завантажте архів, розпакуйте його в робочу теку, потім перейдіть до теки, що містить train.py та verify_resume.py. Використовуйте середовище Python із PyTorch і NumPy. Архів містить код і синтетичні дані; він не завантажує жодної моделі та не вимагає облікового запису Kernodeck для виконання вправи.
Наданий доказ було виконано з Python 3.14.6, PyTorch 2.11.0+cu128 і NumPy 2.4.4. Програма примусово використовує CPU, точність float64 і один потік PyTorch. Тому суфікс пакета не означає, що відновлення використовувало CUDA. В іншому середовищі виконайте власну перевірку.
Виберіть вихідну теку, якої ще не існує. Кожен прохід створює checkpoint.pt, його відбиток checkpoint.pt.sha256 і summary.json. Перевіряльник збирає порівняння у verification.json. Опція --steps рахує додаткові кроки: після переривання на 5 команда відновлення виконує 5, щоб досягти 10. Опція Python -B уникає кешів байткоду в теці вправи.
python -B verify_resume.py --output runs/preuve-cpupython -B train.py --steps 10 --output runs/continu
python -B train.py --steps 5 --output runs/coupure
python -B train.py --steps 5 --resume runs/coupure/checkpoint.pt --output runs/repriseЕкспорт ваг і checkpoint відновлення мають різні ролі
Почніть із вибору того, що ви хочете відновити. Експорт для інференсу слугує для створення прогнозів за допомогою навченої моделі. Відновлення навчання має відновити також стан, який визначає наступні оновлення. Обробка інференсу за файлами вимагає надійного списку вже завершених елементів. Ці три потреби створюють різні збереження.
Не плутайте це постійне збереження з activation checkpointing. Ця техніка зменшує певні активації, що зберігаються в пам'яті, перераховуючи їх під час зворотного поширення; сама по собі вона не створює файл, який дозволяє відновити роботу після зупинки. Тож укажіть у своєму проєкті, чи слово checkpoint означає оптимізацію пам'яті, чи точку відновлення.
Стани, які потрібно зберігати разом
state_dict моделі містить збережені параметри та буфери; оптимізатор має власний стан. Тут Adam, StepLR, dropout і три генератори випадкових чисел впливають на наступні оновлення. Контрольна точка має відображати той самий момент для всіх цих елементів.
Також задокументуйте версію коду, параметри експерименту та ідентичність даних. У середині епохи знати лише її номер недостатньо: потрібно мати змогу відтворити порядок прикладів і наступний пакет для обробки. Помилка в цьому місці може пропустити записи або обробити їх двічі.
Набір із 24 рядків описує синтетичний зв'язок між двома змінними та цільовою змінною. Мережа має 33 параметри, з шаром із восьми нейронів і dropout 0,25. Пакет містить чотири рядки. Після п'яти оновлень курсор дорівнює 20 із 24: розрив припадає на середину епохи. Десять оновлень споживають 40 спостережень, що змушує перевірку пройти через нову перестановку даних.
Прокрутіть таблицю, щоб побачити всі стовпці.| Стан | Роль | Перевірка, яку потрібно виконати |
|---|---|---|
| Модель | Зберегти ваги та буфери. | Порівняти кінцеві параметри та результат оцінювання. |
| Оптимізатор | Зберегти стани, які використовуються наступним оновленням. | Перевірити його перезавантаження, а не лише його гіперпараметри. |
| Планувальник | Продовжити послідовність швидкостей навчання. | Порівняти наступну застосовану швидкість, а потім наступні швидкості. |
| RNG Python, NumPy та PyTorch | Продовжити випадкові вибірки, які фактично використовуються. | Перевірити, що негативна вправа без відновлення розходиться. |
| Дані | Відновити перестановку та курсор. | Порівняти ідентифікатори записів після розриву. |
| Прогрес | Інтерпретувати кроки та епохи. | Дійти до 10 оновлень загалом, не повторивши та не пропустивши жодного. |
| Конфігурація | Відтворити той самий експеримент. | Зберегти розмірності, точність, налаштування та версії. |
Відновлювати в правильному порядку
Відтворіть модель, оптимізатор і планувальник перед завантаженням їхніх станів. Планувальник потрібно створити перед optimizer.load_state_dict(): інакше його побудова може перезаписати відновлені швидкості навчання. Також перезавантажте його власний стан, а потім перевірте швидкість, яка фактично використовується на наступному кроці.
Відновіть генератори випадкових чисел після побудови об'єктів, які споживають випадкові вибірки, безпосередньо перед продовженням роботи. Просте повернення початкового зерна змусило б послідовність початися спочатку; це не те саме, що відновити стан, досягнутий після п'ятого оновлення. У вашому проєкті знайдіть усі використані генератори, зокрема ті, що використовуються в трансформаціях і завантаженні даних.
У цій вправі Python встановлює невеликий приріст на входах, генератор NumPy PCG64 створює шум і перестановки, а PyTorch створює dropout. Контрольна точка зберігає їхні стани, досягнуті на момент розриву. Перевіряльник також спостерігає за їхніми наступними вибірками, одразу відновлюючи стан, щоб не порушити подальші обчислення.
optimizer = torch.optim.Adam(model.parameters(), lr=0.03)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=3, gamma=0.5)
# У проходженні відновлення, після побудови об'єктів:
state = load_checkpoint(resume)
model.load_state_dict(state["model"])
scheduler.load_state_dict(state["scheduler"])
optimizer.load_state_dict(state["optimizer"])
progress = state["progress"]
history = state["history"]
restore_rng(state["rng"], generator)
model.train()Обрати узгоджену межу збереження
Встановіть явну межу, наприклад після повного оновлення оптимізатора. Якщо ви накопичуєте кілька мікропакетів перед цим оновленням, збереження в середині вимагає також керування проміжним станом. Першу реалізацію легше перевірити, коли вона зберігає на межі, де накопичені градієнти вже використано.
Зберігайте кілька поколінь резервних копій. Запишіть новий файл під окремою назвою, дочекайтеся завершення запису, перевірте, що його можна прочитати, і лише потім позначте його як придатний. Не замінюйте свій єдиний робочий контрольний знімок до цієї перевірки. Частота залежить від роботи, яку ви готові виконати заново, і від спостережуваного часу запису; її не можна вивести лише з тривалості оренди.
Мініпроєкт зберігає стан після завершеної ітерації, потім експортує файл та його відбиток. Він використовує нову теку для кожного проходу і не замінює попередній доказ. Якщо ваше навчання застосовує змішану точність із GradScaler, його стан також є частиною відновлення. Цей варіант не охоплюється вправою для CPU.
Прочитати порівняння та його допуск
Протокол порівнює продовження після кроку 5: спожиті дані, швидкість навчання, втрати та досягнуті параметри. Збігу лише номера кроку недостатньо. Переініціалізований оптимізатор може продовжити цикл, але створювати інші оновлення.
Обраний для цієї вправи допуск є абсолютним: 1e-12, з відносним допуском 0. Цей поріг є частиною наданого протоколу для CPU; він не є універсальним правилом для ваших моделей. Порівняння має позначати нечислові значення та відмінності структури, а не мовчки приймати непридатний до використання результат.
PyTorch не гарантує ідентичності результатів між версіями, платформами, CPU та GPU. Якщо ви переносите вправу, повторіть доказ на цільовій платформі та поясніть обраний допуск. Не розширюйте поріг лише для того, щоб приховати збій, причину якого ви не зрозуміли.
У наданому доказі всі відхилення повного проходу дорівнюють нулю: параметри, стан оптимізатора, втрати, швидкості та MSE. Порядок рядків, прогрес, стан scheduler та наступні вибірки також збігаються. Наступна швидкість навчання після кроку 10 дорівнює 0,00375 в обох проходах. Отже, результат не залежить лише від підсумкової метрики, яка могла б приховати проміжні відмінності.
Прокрутіть таблицю, щоб побачити всі стовпці.| Порівняння | Повне відновлення | Відновлення без відтворення RNG |
|---|---|---|
| Максимальне відхилення ваг | 0 | 0,011669328447718508 |
| Підсумкова MSE | 0,09538858591775097 | 0,0936034144665111 |
| Відхилення MSE від безперервного проходу | 0 | 0,001785171451239867 |
| Вердикт підтесту відповідності | Відповідність у межах допуску 1e-12 | Виявлено розбіжність |
Чому варто зберегти негативний випадок без відновленого випадкового стану
Перевірка корисніша, коли ви знаєте, яку саме помилку вона виявляє. Негативний варіант перезавантажує ті самі ваги, стани оптимізатора, scheduler та прогрес, але навмисно пропускає відновлення RNG. Процес може завершитися без винятку Python, але пройти іншою траєкторією.
У наданому доказі це пропущення дає максимальне відхилення ваг понад 0,011 та різницю MSE понад 0,0017. MSE негативного випадку тут нижча, ніж у безперервного проходу: це не робить відновлення правильним. Мета полягає в тому, щоб відтворити той самий експеримент, а не впорядкувати дві моделі за підсумковою похибкою.
Верифікатор завершується успішно лише тоді, коли повний прохід збігається, а негативний випадок розходиться. Тоді він виводить all_checks_passed: true, positive: true та negative_divergence_detected: true. Його код виходу дорівнює 0 у разі успіху протоколу, 1 якщо порівняння не пройдено, і 2 якщо перевірку не вдалося завершити.
python -B train.py --steps 5 --resume runs/coupure/checkpoint.pt --omit-rng-restore --output runs/reprise-incompleteЗавантажити файл вправи, не послаблюючи захист
Проєкт завантажує лише контрольний знімок, який ви створили цією вправою і зберігаєте під своїм контролем. Він явно використовує torch.load(..., map_location="cpu", weights_only=True). Стан Python містить примітиви, стан генератора NumPy PCG64 — цілі числа та рядки, а стан PyTorch CPU — тензор байтів. Жоден довільний масив NumPy не потрапляє до збереженого стану RNG.
Завантажувач перевіряє пов'язаний відбиток, розмір, схему, прогрес, версії, а також ідентичність коду й даних. Він відхиляє неузгоджений стан, а не скидає мовчки відсутній елемент. Відбиток виявляє зміну; він не засвідчує відправника файлу.
Не додавайте weights_only=False лише щоб прибрати помилку завантаження. Збережений формат та його відтворення мають бути узгодженими. Обмежене завантаження зменшує можливості десеріалізації, але не робить невідомий файл гідним довіри.
Що змінюється для розподіленого навчання
За наявності кількох процесів або станів, розподілених між GPU, перевірте, хто що записує. Файл, створений одним процесом, не обов'язково є повною резервною копією розподіленої роботи. Використовуйте процедуру резервного копіювання, передбачену вашою стратегією, і дочекайтеся її завершення на відповідних учасниках. Чітко визначайте фрагменти, що належать до однієї точки відновлення.
Зміна кількості GPU може вимагати перерозподілу станів і змінити розподіл даних. Механізми розподіленого контрольної точки можуть обробляти деякі зміни, але цю можливість потрібно перевірити для вашого формату й конфігурації. Зробіть пробне завантаження на цільовій конфігурації. Додавання пакетів до команди не перетворює автоматично односерверну копію в розподілену програму.
Завершення реально відновлюваним експортом
До настання терміну експортуйте потрібні контрольні точки разом з їхньою конфігурацією, метриками, інструкціями завантаження та ідентифікаторами даних. Перевірте розмір та відбиток скопійованих файлів, а потім завантажте принаймні одну резервну копію з місця призначення. Однаковий відбиток засвідчує копіювання; повторне завантаження підтверджує, що вмісту справді достатньо для відтворення роботи.
Завантажуйте лише файли, походження яких вам відоме, і обирайте формат та параметри десеріалізації, що відповідають вашим потребам. Зберігайте останню перевірену точку відновлення, доки нова не пройде ваші перевірки. Очікуваний результат — це відновлювана тека та короткий доказ відновлення: виконана команда, відновлений крок, успішна перевірка та експортований результат. Передбачте цей час у ваших 3, 7 або 30 днях.
Обсяг доказу та вибір оренди
Доказ від 24 вересня 2026 року порівнює чотири нові процеси на CPU з абсолютною похибкою 1e-12 і без відносної похибки. Він не охоплює CUDA, ROCm, AMP, розподілене навчання чи воркери завантаження даних. Він підтверджує логіку відновлення наданої версії в описаному середовищі й не вимірює можливості орендованого GPU.
Після цієї невеликої вправи застосуйте той самий протокол до вашої моделі, ваших даних і вашого бекенду. Карта на 80 ГБ або карта на 192 ГБ не виправляє неповний контрольний пункт: спочатку виберіть сумісний ланцюжок, а потім визначайте обсяг пам'яті для реального кроку. Наведені нижче пропозиції не представлені як обладнання, перевірене для цього доказу.
Передбачте у вашому періоді 3, 7 або 30 днів перший цикл збереження–зупинки–відновлення та час фінального експорту. Корисний результат — це тека, для якої ви можете пояснити версії, точку відновлення, порівняльну перевірку та обмеження; саме лише існування файлу .pt не дає такої гарантії.