1. Розділіть програму, її параметри та комерційне відстеження
Код описує поведінку програми. Конфігурація визначає навантаження: модель, дані, batch, точність і призначення. Секрети надають доступ до потрібних ресурсів. Тримайте ці елементи окремо, щоб змінювати спробу без переписування коду чи копіювання токена у спільний файл.
Посилання на замовлення Kernodeck дає змогу знайти контекст оренди у вашому акаунті. Ідентифікатор спроби розрізняє виконання вашої програми протягом цього періоду. Поєднуйте їх у своїх нотатках, якщо це вам допомагає, але не вимагайте від свого скрипту виводити стан обчислення зі статусу оплати.
Візьмімо проєкт класифікації документів, який потрібно запускати кілька разів на одній вибірці. Контракт програми описує вхідний файл, дозволені параметри, теку вихідних даних і спосіб подання помилок. Посібник із даних уточнює перевірку вмісту; тут ми організовуємо інтерфейс, що з'єднує ці етапи.
2. Напишіть явний і версіонований контракт вхідних даних
Задокументуйте обов'язкові поля та прийнятні значення. Уникайте неявних значень за замовчуванням для рішення, яке змінює результат, як-от модель чи пристрій. Номер схеми розрізняє форму конфігурації від версії коду; він не замінює останню.
У цьому навчальному прикладі файл JSON містить схему, шлях до вхідних даних, batch і запитаний пристрій. Відносні шляхи читаються від теки конфігурації. Це правило, обране для прикладу, дає змогу не залежати від каталогу, з якого колега запускає команду.
Читання JSON перевіряє лише його синтаксис. Далі ваша програма має перевірити типи, поля та обмеження проєкту. У разі помилки вона має зупинитися до завантаження дорогого ресурсу, з повідомленням, яке називає параметр для виправлення.
{
"schema_version": 1,
"input": "../data/pilote.jsonl",
"batch_size": 4,
"device": "cuda"
}3. Підготуйте точку входу, яка відхиляє прості помилки
argparse дає змогу оголошувати опції та створювати довідку для вашої команди. Наведений приклад є лише попередньою перевіркою: він читає конфігурацію, перевіряє її поля та виявляє вже використану теку вихідних даних. Він не завантажує ні модель, ні дані в пам'ять і не перевіряє доступність GPU.
Збережіть цей навчальний код у prepare_run.py, якщо бажаєте його адаптувати. Він пропонується без підтвердженого виконання. Далі додайте свої бізнес-перевірки в застосунок, а не вважайте фінальне повідомлення результатом обчислення. Пристрій cuda залишається запитом; PyTorch також використовує цю назву з ROCm.
Відмова від наявної теки вихідних даних тут є умовністю захисту від змішування спроб. Справжня команда відновлення має отримувати опцію та окремі перевірки. Не перетворюйте новий запуск на неявне відновлення лише тому, що присутні файли.
import argparse
import json
from pathlib import Path
parser = argparse.ArgumentParser(description="Валідувати запуск проєкту")
parser.add_argument("--config", type=Path, required=True)
parser.add_argument("--run-dir", type=Path, required=True)
args = parser.parse_args()
try:
config_path = args.config.resolve()
config = json.loads(config_path.read_text(encoding="utf-8"))
except (OSError, UnicodeError, json.JSONDecodeError) as exc:
parser.error(f"Конфігурацію неможливо прочитати: {exc}")
expected = {"schema_version", "input", "batch_size", "device"}
if not isinstance(config, dict) or set(config) != expected:
parser.error("Очікувані поля: schema_version, input, batch_size, device")
if type(config["schema_version"]) is not int or config["schema_version"] != 1:
parser.error("schema_version має дорівнювати 1")
if type(config["batch_size"]) is not int or config["batch_size"] < 1:
parser.error("batch_size має бути додатним цілим числом")
if config["device"] not in ("cpu", "cuda"):
parser.error("device має дорівнювати cpu або cuda")
if not isinstance(config["input"], str) or not config["input"]:
parser.error("input має бути непорожнім шляхом")
input_path = (config_path.parent / config["input"]).resolve()
run_dir = args.run_dir.resolve()
if not input_path.is_file():
parser.error("Вхідний файл відсутній")
if run_dir.exists():
parser.error("Виберіть нову вихідну теку")
print(json.dumps({
"status": "configuration_validated",
"input": str(input_path),
"run_dir": str(run_dir),
"device_requested": config["device"],
"batch_size": config["batch_size"]
}, ensure_ascii=False))python prepare_run.py --config config/pilote.json --run-dir runs/pilote-0014. Надайте ідентичність запускам і їхнім результатам
Пов'яжіть кожен запуск із коротким ідентифікатором, унікальним у межах вашої кампанії. Зафіксуйте ревізію коду, схему та фактично використані параметри, а також посилання на дані й модель. Зберігайте ці значення разом із вихідними даними, щоб результат не залежав від файлу конфігурації, зміненого пізніше.
Щоб порівняти два розміри batch, створіть два досліди та дві теки. Збережіть той самий зразок і позначте навмисну відмінність. Назви pilote-001 і pilote-002 самі по собі не пояснюють, що саме змінилося: маніфест пов'язує назву з параметрами.
Передбачте формат підсумку, читабельний для ваших інструментів. Він може розрізняти елементи отримані, успішно оброблені, відхилені та ті, що ще залишилося обробити. Виберіть правило повного успіху й не позначайте дослід завершеним одразу після запису першого результату. Код повернення програми має залишатися узгодженим із цим висновком.
Прокрутіть таблицю, щоб побачити всі стовпці.| Файл або стан | Роль | Очікувана перевірка |
|---|---|---|
| manifest.json | Ідентичність коду, даних і параметрів | Фактично використані значення, без секретів. |
| results.jsonl | Один вихідний елемент на кожен прийнятий елемент | Відомі ідентифікатори та формат, що відповідає вимогам. |
| errors.jsonl | Відхилені елементи та корисна причина | Жодного тихого зникнення й зайвого чутливого вмісту. |
| summary.json | Висновок досліду та лічильники | Узгоджена сума, файли перечитано перед остаточним статусом. |
5. Надайте своїм інструментам корисні події
Зробіть видимими кілька переходів: конфігурацію прийнято, дані доступні, модель завантажено, перший результат записано та обробку завершено. Трасування має дозволяти відповісти на питання «на якому етапі цей запуск?», не копіюючи документи чи промпти. Пов'яжіть етап та ідентифікатор досліду з повідомленням.
Модуль logging у Python дозволяє організувати повідомлення за рівнями та призначенням. Далі виберіть власну конвенцію подій і задокументуйте її. Застосунок, який записує помилку, а потім завершується з успіхом, робить автоматизацію оманливою; навпаки, не кожне попередження означає, що результат непридатний.
Не плутайте видану подію з довготривалим результатом: повідомлення «збереження розпочато» не доводить, що файл було перечитано. Для тривалого виконання окремий посібник пояснює зв'язок між процесом і сесією. Ваш інтерфейс має насамперед зберігати висновок, доступний після завершення інтерактивного з'єднання.
6. Визначте невдачу, відновлення та фінальну перевірку
Класифікуйте збої за призначенням: недійсна конфігурація, відсутній ресурс, помилка обчислень і невідповідний результат. Для кожного вкажіть наступну дію. Не встановлюйте автоматичний повторний запуск, не визначивши, які ефекти можуть повторюватися: перезапис уже прийнятого виводу й відновлення з контрольної точки потребують різних правил.
Ваша фінальна процедура пояснює, як запускати, спостерігати, зупиняти, відновлювати й експортувати. Для обробки документів зберігайте список завершених ідентифікаторів і тих, що потрібно обробити повторно. Для навчання використовуйте протокол, який перевіряє збережені стани в новому процесі. Непорожня тека не є доказом коректного відновлення.
Нарешті перевірте проєкт із нового виклику, з відомою конфігурацією та окремим призначенням. Перевірте очікувані відмови, а потім — невеликий повний прохід. Попередня перевірка на цій сторінці не охоплює ні конкурентний доступ, ні публічне розкриття сервісу, ні дозволи на зберігання: ці теми потребують окремого проєктування.