Codenrock
ОрганизаторСредний12 мин

Настройка FILE-задач

Подробное руководство по созданию задач с загрузкой файлов и ML-соревнований

Содержание

# Настройка FILE-задач FILE — задачи, где участник загружает файл с решением. Подходит для документов, презентаций, кода и ML-соревнований с автоматической проверкой. ## Типы FILE-задач | Тип | Проверка | Результат | Применение | |-----|----------|-----------|------------| | **Документы** | Ручная | Отложенный | Презентации, отчёты | | **Код/архивы** | Ручная | Отложенный | Проекты без автопроверки | | **CSV-предсказания** | Автоматическая, Python-скриптом | Обычно 5-60 секунд | Data Science соревнования | ## Создание FILE-задачи ### Шаг 1: Основные поля | Поле | Описание | Обязательное | |------|----------|--------------| | **Название** | Название задачи | ✅ | | **Условие** | Что нужно загрузить (Markdown) | ✅ | | **Баллы** | Максимальное количество баллов | ✅ | | **Порядок** | Позиция в треке | ✅ | ### Шаг 2: Настройки файла | Параметр | Описание | |----------|----------| | **Разрешённые форматы** | Какие типы файлов принимать | | **Максимальный размер** | Лимит размера файла | | **Количество файлов** | Один или несколько | ### Шаг 3: Тип проверки | Тип | Описание | |-----|----------| | **Ручная** | Файл оценивает организатор или жюри | | **Автоматическая** | Метрику рассчитывает ваш Python-скрипт | ## Ручная проверка ### Когда использовать - Презентации и документы - Код проектов для code review - Творческие работы - Материалы без формального критерия оценки ### Настройка форматов **Документы:** ``` PDF, DOC, DOCX, PPT, PPTX, ODT ``` **Архивы:** ``` ZIP, RAR, TAR, TAR.GZ, 7Z ``` **Изображения:** ``` PNG, JPG, JPEG, GIF, SVG ``` **Код:** ``` PY, JS, TS, JAVA, CPP, C, GO, RS ``` ### Размер файла | Тип контента | Рекомендуемый лимит | |--------------|---------------------| | Документы | 10-20 МБ | | Презентации | 20-50 МБ | | Архивы с кодом | 50-100 МБ | | Изображения | 5-10 МБ | ### Критерии оценки Укажите критерии для проверяющих: ```markdown ## Критерии оценки презентации (100 баллов) ### Содержание (50 баллов) - Полнота раскрытия темы - Актуальность информации - Логика изложения ### Оформление (30 баллов) - Дизайн слайдов - Читаемость текста - Качество визуализаций ### Техническое решение (20 баллов) - Реализуемость идеи - Техническая грамотность ``` ## Автоматическая проверка ### Когда использовать - ML-чемпионаты и Data Science соревнования - Kaggle-подобные задачи - Любые задачи, где качество решения выражается числом ### Как это устроено Готового списка метрик на платформе нет. Метрику задаёт **Python-скрипт**, который вы загружаете вместе с задачей: платформа запускает его на каждой отправке участника и берёт число, которое скрипт напечатал. Так можно посчитать что угодно — от accuracy до собственной формулы с бизнес-штрафами и проверкой формата сабмита. Отдельного типа задач «ML» больше нет: автопроверка включается тумблером в FILE-задаче. ### Что нужно подготовить | Файл | Что это | Обязателен | |------|---------|------------| | **Скрипт проверки** (`.py`) | Скачивает эталон и ответ участника, считает метрику, печатает JSON | ✅ | | **Публичный тест** | Эталонные ответы (ground truth) для текущего зачёта. Участникам не выдаётся — файл виден только скрипту | ✅ | | **Приватный тест** | Скрытый эталон для финального пересчёта | — | Данные для участников (`train.csv`, `test.csv`, `sample_submission.csv`) сюда не загружаются — выложите их ссылками в условии задачи. ### Включение автопроверки 1. Создайте задачу типа **Файл** 2. В разрешённых форматах оставьте `.csv`, задайте лимит размера 3. Включите тумблер **Автоматическая проверка** 4. Выберите режим лучшего результата: **Больше — лучше** или **Меньше — лучше** (для RMSE, MAE, LogLoss — «меньше») 5. Загрузите скрипт проверки, публичный и — если нужен финальный пересчёт — приватный тест ### Процесс проверки ``` 1. Участник загружает файл с предсказаниями 2. Решение создаётся без балла, со статусом «на проверке» 3. Платформа выдаёт подписанные ссылки на скрипт, эталоны и ответ участника 4. Проверяющий сервис скачивает скрипт и запускает его 5. Из stdout читается JSON с баллом 6. Балл записывается в решение — участник видит результат, обычно за 5-60 секунд ``` ### Контракт скрипта проверки Скрипт запускается так: ```bash python scoring.py \ --public_test_url=<url> \ --public_prediction_url=<url> \ [--private_test_url=<url>] \ [--private_prediction_url=<url>] ``` | Аргумент | Значение | Когда передаётся | |----------|----------|------------------| | `--public_test_url` | Ссылка на публичный эталон | Всегда | | `--public_prediction_url` | Ссылка на файл участника | Всегда | | `--private_test_url` | Ссылка на приватный эталон | Если загружен приватный тест | | `--private_prediction_url` | Зарезервирован | Сейчас не передаётся | **Аргументы — это ссылки, а не пути к файлам.** Скрипт скачивает данные сам; `pandas.read_csv()` принимает URL напрямую. Скрипт печатает в stdout **одну строку JSON** и завершается с кодом `0`: ```json {"public_score": 73.4512, "private_score": null} ``` | Правило | Почему так | |---------|------------| | В stdout — только этот JSON | Вывод разбирается целиком, любой лишний `print` ломает проверку | | Диагностика — в stderr | Она сохраняется и доступна при разборе проблем | | Код возврата `0` | При ненулевом решение получает 0 баллов и статус «ошибка» | | `private_score: null` | Если приватный тест не загружен | | Объявлены все четыре аргумента | `argparse` завершается с ошибкой на неизвестном ключе | ### Шкала балла Значение `public_score` записывается в балл решения **как есть**, без пересчёта на баллы задачи. Если задача стоит 100 баллов, а скрипт вернул `0.87` (F1), участник получит 0.87 балла из 100 — не 87. Приводите метрику к шкале задачи внутри скрипта: ```python SCALE = 100.0 # задача на 100 баллов public_score = round(f1 * SCALE, 4) # 0.87 -> 87.0 ``` Для метрик, где меньше — лучше, есть два рабочих варианта: | Вариант | Что возвращает скрипт | Режим задачи | |---------|----------------------|--------------| | Отдать саму ошибку | `rmse` | Меньше — лучше | | Перевести ошибку в баллы | `max(0, 100 * (1 - rmse / baseline))` | Больше — лучше | Первый честнее для лидерборда, второй нагляднее для участников. ### Пример скрипта Рабочий скелет — подставьте свою метрику в `calc_score`. Проверка формата сабмита здесь не лишняя: без неё лишняя строка или дубль `id` дадут молча неверный балл. ```python #!/usr/bin/env python3 """Скоринг сабмита: сравниваем predictions с ground truth.""" import argparse import json import sys import pandas as pd from sklearn.metrics import f1_score SCALE = 100.0 # метрика [0..1] -> баллы задачи (points = 100) ID_COL = "id" TARGET_COL = "prediction" def load(url, what): df = pd.read_csv(url) for col in (ID_COL, TARGET_COL): if col not in df.columns: raise ValueError(f"{what}: нет колонки '{col}', есть {list(df.columns)}") return df def calc_score(test_url, prediction_url): gt = load(test_url, "ground truth") pred = load(prediction_url, "submission") if pred[ID_COL].duplicated().any(): raise ValueError("в сабмите есть дубликаты id") merged = gt.merge(pred, on=ID_COL, how="left", suffixes=("_true", "_pred")) missing = merged[f"{TARGET_COL}_pred"].isna().sum() if missing: raise ValueError(f"в сабмите нет предсказаний для {missing} объектов") print(f"объектов: {len(merged)}", file=sys.stderr) # диагностика -> только stderr return f1_score( merged[f"{TARGET_COL}_true"], merged[f"{TARGET_COL}_pred"], average="weighted", ) def main(): parser = argparse.ArgumentParser() parser.add_argument("--public_test_url", required=True) parser.add_argument("--public_prediction_url", required=True) parser.add_argument("--private_test_url", default=None) parser.add_argument("--private_prediction_url", default=None) args = parser.parse_args() try: public_score = calc_score(args.public_test_url, args.public_prediction_url) private_score = None if args.private_test_url: # приватного сабмита нет - сверяем тот же файл со скрытым эталоном prediction_url = args.private_prediction_url or args.public_prediction_url private_score = calc_score(args.private_test_url, prediction_url) print(json.dumps({ "public_score": round(public_score * SCALE, 4), "private_score": round(private_score * SCALE, 4) if private_score is not None else None, })) except Exception as exc: print(f"ERROR: {exc}", file=sys.stderr) sys.exit(1) if __name__ == "__main__": main() ``` Замена метрики — одна строка в `calc_score`: | Задача | Код | Настройки | |--------|-----|-----------| | Классификация | `f1_score(y_true, y_pred, average="weighted")` | `SCALE = 100.0`, больше — лучше | | Бинарная с вероятностями | `roc_auc_score(y_true, y_score)` | `SCALE = 100.0`, больше — лучше | | Регрессия | `mean_squared_error(y_true, y_pred, squared=False)` | `SCALE = 1.0`, меньше — лучше | ### Окружение запуска | Параметр | Значение | |----------|----------| | **Python** | 3.10, изолированный контейнер, один процесс на решение | | **Таймаут** | 300 секунд, дальше процесс снимается и решение получает ошибку | | **Data / ML** | pandas, numpy 1.23.5, scipy, pyarrow, scikit-learn, scikit-image, torch (CPU), transformers | | **Прочее** | evaluate, bert_score, opencv-python-headless, requests, pydantic, PyYAML, tqdm | | **Сеть** | Рассчитывайте только на ссылки из аргументов: доступ к внешним сервисам не гарантируется, ставить пакеты на лету нельзя | Если нужной библиотеки нет в списке — напишите в поддержку, образ дополняется под соревнование. ### Публичный и приватный зачёт Приватный тест — это второй эталон, с которым сверяется **тот же самый файл участника**: отдельную приватную отправку платформа не запрашивает. Скрипт получает `--private_test_url` и возвращает второе число в `private_score`. | Лидерборд | Настройка | Что показывает | |-----------|-----------|----------------| | **Публичный** | По умолчанию | Балл по публичному эталону, виден участникам сразу | | **Приватный** | «Приватный балл» в настройках лидерборда | Балл по скрытому эталону, обычно открывают после дедлайна | Направление ранжирования (по убыванию / по возрастанию) и правило зачёта (лучший результат / сумма попыток) задаются в настройках лидерборда, а режим «больше / меньше — лучше» в задаче определяет, какую из отправок участника платформа считает его лучшей. ## Ограничения попыток ### Для ручной проверки | Значение | Использование | |----------|---------------| | **1** | Финальная загрузка | | **Без ограничений** | Можно обновлять файл | ### Для ML-соревнований | Тип ограничения | Описание | |-----------------|----------| | **В день** | Например, 5 попыток в сутки | | **Всего** | Общий лимит за соревнование | **Рекомендации:** - Короткое соревнование (1-3 дня): 10-20 попыток в день - Длинное соревнование (1-4 недели): 3-5 попыток в день - Без ограничений: только для обучающих соревнований ### Учёт результата | Настройка | Где задаётся | Что делает | |-----------|--------------|------------| | **Больше — лучше / Меньше — лучше** | В задаче, рядом с автопроверкой | Определяет, какую отправку участника считать лучшей | | **Лучший результат / Сумма попыток** | В настройках лидерборда | Как сворачивать несколько отправок в итоговый балл | | **Приватный балл** | В настройках лидерборда | Ранжировать по скрытому эталону вместо публичного | Лимит попыток считается **на участника**, а не на команду: в командном конкурсе каждый участник расходует свои попытки. ## Условие ML-задачи ### Структура описания ```markdown # Название задачи ## Описание Краткое описание бизнес-задачи и цели. ## Данные - **train.csv** — обучающая выборка (N объектов, M признаков) - **test.csv** — тестовая выборка (K объектов) - **sample_submission.csv** — пример формата ответа ### Описание признаков | Колонка | Тип | Описание | |---------|-----|----------| | id | int | Уникальный идентификатор | | feature_1 | float | Описание признака 1 | | ... | ... | ... | | target | float | Целевая переменная (только в train) | ## Метрика RMSE (Root Mean Square Error) — чем меньше, тем лучше. ## Формат ответа CSV-файл с колонками `id` и `prediction`. ## Ограничения - 5 попыток в день - Максимальный размер файла: 10 МБ ## Baseline RMSE = 0.45 (среднее значение target) ``` ### Чек-лист условия - [ ] Описана бизнес-задача - [ ] Приложены все файлы данных - [ ] Описаны все колонки - [ ] Указана метрика и её направление - [ ] Приложен sample_submission - [ ] Указаны ограничения попыток - [ ] Указан baseline ## Валидация файла ### Что проверяет платформа | Проверка | Действие при ошибке | |----------|---------------------| | Расширение файла | Отклонить загрузку | | Размер файла | Отклонить загрузку | | Лимит попыток | Отклонить отправку | | Сроки трека и таймер задачи | Отклонить отправку | Расширение и размер проверяются дважды — в браузере до загрузки и на сервере. Если список разрешённых форматов пуст, принимается любое расширение. ### Что проверяет скрипт Содержимое файла платформа не разбирает — это работа скрипта проверки. Заложите в него всё, что должно приводить к ошибке или нулю: ```python if pred[ID_COL].duplicated().any(): raise ValueError("в сабмите есть дубликаты id") if len(pred) != len(gt): raise ValueError(f"строк {len(pred)}, ожидалось {len(gt)}") ``` Текст исключения попадает в stderr и сохраняется вместе с решением, поэтому пишите сообщения так, чтобы по ним можно было ответить участнику. ## Примеры задач ### Презентация проекта **Название**: Презентация MVP **Условие**: ```markdown Загрузите презентацию вашего MVP. **Требования:** - Формат: PDF или PPTX - Объём: 10-15 слайдов - Содержание: проблема, решение, демо, бизнес-модель **Критерии оценки:** - Качество идеи: 40% - Презентация решения: 30% - Бизнес-потенциал: 30% ``` **Настройки:** - Форматы: PDF, PPTX - Размер: до 50 МБ - Проверка: ручная - Баллы: 100 ### ML-соревнование **Название**: Предсказание оттока клиентов **Условие** (Markdown в поле «Условие»): > Предскажите вероятность оттока клиентов телеком-компании. > > **Данные**: `train.csv` — 5000 клиентов с историей, `test.csv` — 2000 клиентов для предсказания, `sample_submission.csv` — пример формата. > > **Метрика**: AUC-ROC, приведённая к 100 баллам. Чем больше, тем лучше. > > **Формат ответа**: CSV с колонками `id,prediction`, 2000 строк, `prediction` — вероятность от 0 до 1. > > **Baseline**: AUC-ROC = 0.50 (случайное предсказание). **Настройки задачи:** - Тип: Файл - Формат: `.csv`, до 10 МБ - Автоматическая проверка: включена - Режим: больше — лучше - Скрипт проверки: `scoring.py` с `roc_auc_score` и `SCALE = 100.0` - Публичный тест: `public_gt.csv` с колонками `id,prediction` - Попытки: 5 в день - Баллы: 100 ## Статистика ### Для ручной проверки | Метрика | Описание | |---------|----------| | **Загружено** | Количество загруженных файлов | | **На проверке** | Ожидают проверки | | **Проверено** | Оценённые работы | | **Средний балл** | Средняя оценка | ### Для задач с автопроверкой | Что доступно | Где смотреть | |--------------|--------------| | **Все отправки** с баллом, временем и статусом проверки | Раздел «Решения» | | **Ошибки проверки** — статус «ошибка», текст из stderr скрипта сохраняется вместе с решением | Карточка решения | | **Лучшая отправка участника** — по режиму «больше / меньше — лучше» | Раздел «Решения» | | **Рейтинг участников** | Лидерборд по задаче или треку | ## Частые ошибки ### При создании | Ошибка | Последствие | |--------|-------------| | Нет sample_submission | Участники не знают формат | | Нет описания колонок | Непонятно что предсказывать | | Слишком много попыток | Переобучение на тесте | | Нет baseline | Непонятно хороший ли результат | ### При ручной проверке | Ошибка | Решение | |--------|---------| | Файлы участников не открываются | Укажите конкретные форматы | | Критерии субъективны | Опишите шкалу оценок | | Долгая проверка | Привлеките нескольких проверяющих | ### При автопроверке | Симптом | Причина | Решение | |---------|---------|---------| | Все решения получают 0 баллов | Скрипт печатает в stdout что-то кроме JSON | Диагностику — в stderr, JSON — единственный вывод | | Баллы вида 0.87 вместо 87 | Метрика не приведена к шкале задачи | Умножить на количество баллов задачи | | Ошибка на каждой отправке | `argparse` падает на непредусмотренном аргументе | Объявить все четыре аргумента | | Задача не сохраняется | Не загружен скрипт или публичный тест | Оба файла обязательны при включённой автопроверке | | Проверка обрывается по таймауту | Внутри скоринга тяжёлые вычисления или загрузка моделей | Скрипт должен только сравнивать файлы, без инференса | ## Частые вопросы **В: Где выбрать метрику из списка (RMSE, F1, AUC)?** О: Такого списка нет. Метрика — это ваш Python-скрипт: он считает любую формулу и печатает итоговое число. Готовый шаблон — в разделе [Пример скрипта](#пример-скрипта). **В: Скрипт отработал, но у всех 0 баллов. Почему?** О: Скорее всего скрипт печатает в stdout что-то кроме JSON — отладочный `print` или warning библиотеки. Всю диагностику отправляйте в stderr. **В: Участники получают баллы вида 0.87 вместо 87. Почему?** О: Метрика не приведена к шкале задачи. Умножьте её на количество баллов задачи внутри скрипта. **В: Можно ли менять метрику после старта?** О: Технически да — достаточно перезагрузить скрипт. Но уже проверенные решения не пересчитываются, а для участников это меняет правила по ходу. Не рекомендуется. **В: Как скрыть ground truth от участников?** О: Публичный и приватный тесты загружаются отдельно и не отдаются в API задачи — скачать их участник не может. Система передаёт их только скрипту проверки. **В: Участник загрузил неверный формат. Что делать?** О: Неподходящее расширение и превышение размера платформа отклоняет сама. Всё остальное — работа скрипта: пусть он завершается с понятным сообщением в stderr. **В: Как организовать командное ML-соревнование?** О: Создайте командный конкурс — решения привязываются к команде и попадают в командный лидерборд. Учтите, что лимит попыток считается на участника, а не на команду. ## Связанные статьи - [Создание задач](/docs/organizer/tracks-tasks/create-tasks) - [Настройка CODING-задач](/docs/organizer/tracks-tasks/coding-task-setup) - [Управление участниками](/docs/organizer/community/participants)
Последнее обновление: 20.08.2026
К оглавлению