Толока задания: Полевые задания

Толока задания: Полевые задания

Как создать контрольные и обучающие задания в Толоке — Добро пожаловать в блог Яндекс.Толоки

Добро пожаловать в блог Яндекс.Толоки

13 ноября 2019, 10:00

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

Создать такие задания можно разными способами:

  • Добавить правильные ответы в TSV-файл, в столбцы с заголовком GOLDEN.
  • Выполнить своё задание в Песочнице и выгрузить TSV-файл с ответами.
  • Разметить задания в интерфейсе Толоки.

В этой статье мы расскажем, как подготовить контрольные и обучающие задания с помощью Разметчика. В качестве примера возьмём проект по классификации товаров.

Видеоруководство по созданию такого проекта вы найдёте на нашем канале на YouTube.

Для начала подготовим TSV-файл со ссылками на картинки и загрузим его в пул.

  1. Создайте новый пул и скачайте образец загрузочного файла. Откройте файл в блокноте или редакторе электронных таблиц.
  2. Удалите все данные, кроме столбцов с заголовком INPUT. В нашем примере это INPUT:Image.
  3. Заполните столбец ссылками на картинки. Каждая ссылка — на отдельной строке. Сохраните файл в формате TSV.

    Образец TSV-файла

    Готовый TSV-файл

    Подготовка TSV-файла со ссылками на картинки

  4. Вернитесь на страницу пула и нажмите Загрузить.

  5. В открывшемся окне выберите Умное смешивание. 

    Разметка доступна только при выборе этого способа распределения заданий.

  6. Укажите количество заданий на странице. Например: 9 основных и 1 контрольное.
  7. Нажмите Загрузить и выберите подготовленный TSV-файл со ссылками на картинки. Дождитесь результата обработки и нажмите Добавить.

Мы загрузили основные задания. Превратим часть из них в контрольные, и система сможет сформировать страницы, смешав задания в нужной пропорции.

Теперь приступим к созданию контрольных заданий.

  1. Откройте интерфейс разметки.
  2. Нажмите кнопку Создать контрольные.
  3. Отметьте галочкой выходные поля, которые будут учитываться при проверке ответа на контрольный вопрос, выберите вариант ответа и нажмите кнопку Сохранить и перейти к следующему.
    Совет. Потяните за край левой или правой области Разметчика, чтобы изменить размер полей.
  4. Если у вас небольшой пул, разметьте таким образом не менее 10% заданий. Для разметки больших пулов достаточно 1% контрольных заданий.
  5. На панели справа показано распределение правильных ответов на контрольные задания. Старайтесь, чтобы у вас были представлены различные варианты ответов, чтобы исполнители не могли их просто угадать.

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

С помощью Разметчика можно создавать не только контрольные, но и тренировочные задания. Чтобы из контрольного задания сделать обучающее, добавьте к выбранному варианту ответа подсказку.

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

Обучающие задания помогут на примерах пояснить сложные моменты в инструкции и научить пользователей ставить верные оценки. Чтобы исполнитель получил доступ к основным заданиям только после обучения, привяжите обучающий пул к основному. Как это сделать, читайте в Руководстве заказчика.

Не забудьте добавить в пул правило Контрольные задания, чтобы назначать исполнителю навык на основе его ответов и блокировать доступ тем, кто даёт неправильные ответы.

Правило начнёт действовать после того, как исполнитель ответит на заданное число контрольных заданий. Толока подсчитает процент правильных и неправильных ответов и выполнит действие — назначить навык или заблокировать доступ к заданию. Далее этот процент обновляется по мере выполнения заданий исполнителем. Количество последних ответов исполнителя, которое учитывается в расчете, нужно указать в поле Сколько последних значений учитывать.

В примере мы добавили два контрольных правила. Они начнут работать, как только исполнитель сделает 3 контрольных задания. Поскольку у нас на странице одно контрольное задание, это произойдёт после того, как он выполнит третью страницу с заданиями. Первое правило назначит исполнителю навык, равный проценту совпадений его ответов с контрольными. Если доля неправильных ответов окажется больше или равна 60%, то второе правило заблокирует исполнителя на проекте на 10 дней.

Другие примеры правил вы найдёте в Руководстве.

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

Высокое качество — 93%

Качество ниже среднего — 46%

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

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

Руководство заказчика (how to)

Обратная связьВсе блоги сервисов© 2013–2023  «Яндекс»

Лекция о Толоке.

Как тысячи людей помогают нам делать Яндекс / Хабр

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

С одной стороны, Толока появилась сравнительно недавно — в 2014 году. С другой, она служит важнейшей частью всех ключевых сервисов Яндекса и десятков сервисов поменьше. Артём Григорьев ortemij объяснил, как эта краудсорсинговая платформа устроена, какие технологии и архитектурные решения применяются при её разработке. Кроме того, Артём рассказал про логику раздачи заданий пользователям, работу с геоданными на карте и управление качеством.

— Пару слов обо мне. Я более семи лет работаю в петербургском офисе Яндекса. Когда я только пришел сюда, я занимался различными инструментами для оценки качества поиска.

Мы разрабатывали разные метрики, сравнивали себя с конкурентами и разными версиями других поисковых систем. Сейчас я руковожу службой с длинным названием, как на слайде.

Вкратце, мы работаем по трем основным направлениям. Во-первых, занимаемся разработкой нашей краудсорсинговой платформы Яндекс.Толока. Во-вторых, разрабатываем разнообразные сервисы для асессоров. Это специальные люди в Яндексе типа модераторов. Специалисты поддержки, для них делаем разные сервисы, контент-менеджеры и т. д.

И наконец, мы разрабатываем инфраструктуру, которая позволяет всем командам Яндекса работать с перечисленными людьми и результатами их работы. Эта инфраструктура связывает то, что мы делаем и чем занимаются люди, например, при разработке поиска.

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

Давайте представим, что вы занимаетесь machine learning. Например, вы хотите обучить какой-то классификатор, и у вас есть набор данных, который нужно разметить и получить какие-то знания. Этот набор данных можно представить в виде некоторого количества задач, написать инструкцию, по которой задания можно выполнить, и отправить некоторым людям, которые это сделают.

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

Второй вопрос. Поясню термин Толока́. Многие могут сказать, что я неправильно это слово произношу. По-русски ударение ставят на второй слог, но мы отдаем дань тому, что этот сервис начали делать изначально в нашем белорусском офисе, многие ребята приехали поотвечать на ваши вопросы в кулуарах.

Когда мы начинали делать этот сервис и придумывали название, то вспомнили, что есть такое интересное понятие. Значение этого слова — в том, что мы перенесемся в древние времена. Люди в деревне собираются вместе и что-то делают на благо общества. Каждый по отдельности, может, эту работу сделать не смог бы, но они вместе собрались, пошли собирать урожай или строить какой-то сарай для общественных нужд. Толока — это некоторый обычай собираться вместе и помогать друг другу. Мы подумали, что это схоже с современным термином краудсорсинга, поэтому такое название для нашего сервиса и выбрали.

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

Платформа занимается тем, что она процессит все платежи, все взаимодействе между заказчиком и исполнителем, разрешает различные конфликтные ситуации и т. д.

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

Могу привести несколько примеров заданий, которые реально сейчас в платформе размещаются.

Например, задания на простую классификацию фотографий. Или задания для обучения беспилотных автомобилей. Может, видели видео, где машина Яндекса едет по Хамовникам в Москве, разметку для того, чтобы обучать компьютерное зрение в этом автомобиле, собирали в том числе в Толоке.

Задания для распознавания цен на фотографиях и т. д. В принципе, базово понятно, гуманитарную вводную часть на этом заканчиваю.

Если кому-то интересно поподробнее про краудсорсинг узнать, я осенью выступал на конференции SmartData, в Youtube можно найти видео с таким названием, там более подробно рассказывается о том, что такое краудсорсинг и про особенности интересные в нем.

Мы здесь собрались, чтобы узнать внутренние, технические особенности работы нашей платформы, поэтому перейдем к этой части.

Толока доступна в нескольких формах. Можно зайти в браузере на сайт toloka.yandex.ru, выполнять задания там. Также у нас есть мобильные приложения под iOS и под Android. Они используются, в частности, для различных заданий, где требуется мобильность, люди ходят по местности и выполняют задания «в полях», ну и где нужны специальные фичи телефона, например, диктофон или камера.

Наш бэкенд написан в основном на Java.

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

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

Для тех мест, где это не нужно, мы используем MongoDB. Во многих микросервисах, которые построены вокруг Толоки, используется это хранилище. Это наша внутренняя реализация MapReduce, похожа на BigTable, в Яндексе ее ласково называют Ыть.

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

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

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

Чтобы приоткрыть завесу на то, что внутри происходит, я по одной задаче из каждой области приведу, и попытаюсь рассказать что-то интересное, что происходит, на эту тему.

Начнем с бизнес-логики.

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

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

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

Как работает получение списка доступных заданий, главная страница Яндекс.Толоки?

Во-первых, мы ищем пулы, которые подходят исполнителям по фильтрам. Про это дальше еще расскажу, но не все задания доступны каждому, поэтому мы должны отфильтровать те, которые показать данному пользователю.

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

Важный момент, что задания мы отдаем не по одному, а страницами, на которых показывается сразу несколько заданий, это сделано для оптимизации скорости. Мы должны найти те пулы, в которых у пользователя есть достаточно заданий, чтобы показать страницу. И важно, что мы одни и те же задания пользователю второй раз не показываем, он делает все по одному разу. Отфильтровав это все, мы группируем и показываем страницу на фронтенде, которую видит человек.

Исполнитель в нашей системе представлен несколькими характеристиками. Есть вычислимые поля, допустим, ОС, с которой заходит пользователь, можем по этому критерию пользователей отфильтровать. Или его IP-адрес, регион, вычисленный по этому IP и т. д.

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

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

С другой стороны, у нас есть некоторые пулы, где заданы фильтры.

Допустим, для выполнения некоторых заданий нам нужны пользователи, которые по номеру телефона указали, что они находятся в России, Украине, Казахстане или Беларуси, и еще некоторое ограничение по навыкам. Когда пользователь заходит на страницу, мы матчим это представление фильтра на некотором псевдоязыке с JSON представлением пользователя, которое у нас есть на данный момент. Представление пользователя может меняться, и заказчик тоже может менять фильтры, настроенные на пуле.

Раньше мы компилировали представление фильтров на JSquery, такой плагин для пользователя. Сейчас мы это делать перестали, потому что представление фильтра на JSquery, плагин такой для PostgreSQL. Сейчас мы это делать перестали, потому что фильтровать на самом бэкенде в памяти оказалось сильно быстрее.

Мы отфильтровали пулы, и надо проверить, что в них достаточно заданий, которые пользователь еще не делал, чтобы показать ему полную страницу. И мы опять возвращаемся к очередям.

Каждый пул заданий — это очередь заданий для различного количества пользователей. У нее есть некоторый набор свойств. Во-первых, эти очереди динамически создаются, удаляются, и также заказчики могут доливать в пулы новые задания, поэтому эти очереди могут дополняться новыми элементами.

Во-вторых, каждое задание может быть сделано многими исполнителями. В этой очереди для каждого задания получается много разных потребителей. И для исполнителей задания повторяться не должны, мы не должны два раза платить человеку за то, что он делает. Все эти ограничения вкупе с тем, что таких очередей может быть десятки тысяч, выкладываются в то, чтобы отрисовать главную страницу, которую спрашивают у нас примерно 150 раз в секунду, нам нужно сделать около 40 тыс. проверок того, что в данной очереди, в данном пуле заданий есть доступные для пользователя. Это тяжелое место, и мы его соптимизировали следующим образом — мы перенесли все эти проверки в базу данных.

Использовали такую штуку в PostgreSQL, называется lateral join, он позволяет для каждого элемента из левой таблицы выполнить запрос в цикле по одному разу. Получается, вместо того, чтобы джоинить огромные таблицы, мы делаем простую выборку и повторяем эту проверку на бэкенде базы каждый раз. Запросы, которые находятся внутри, довольно легкие, от этого получается, что вместо 40 тыс. проверок мы делаем на порядки меньше, они все унесены в базу, из бэкенда мы туда в цикле не ходим.

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

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

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

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

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

И это накладывает такую сложность на и так не очень простую бизнес-логику.

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

Перейдем к части про технологии.

Я много говорил, что мы сильно используем PostgreSQL. Хочется рассказать, как мы пришли к тому, что начали использовать реплики, и какой был к этому тернистый путь. Практически любое приложение, которое использует БД, обычно начинает с того, что все запросы идут на мастер, реплики используются для отказоустойчивости. И на бэкенде используется некий пул соединений, который позволяет эти соединения переиспользовать.

Сервисом пользуются, нагрузка на него начинает расти.

Вы увеличиваете размер этого пула соединений. Потом начинаете смотреть, что на мастере начинает кончаться CPU, начинаете оптимизировать ваши запросы, смотреть, какие там долгие транзакции, почему соединения выделяются лишний раз. Так же поступали и мы.

В какой-то момент добавили pgbouncer, который позволяет иметь заготовленный пул соединений и не тратить процессор на то, чтобы выделять новые.

По-всякому крутили клиентские настройки, перешли на быстро работающий пул соединений hikari-cp.

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

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

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

Но тут можно найти логическую проблему. Она в том, что довольно много мест в коде, где вы сначала какую-то сущность создаете, а потом ее читаете, начинаете с ней работать, и это происходит в разных транзакциях. Получается, что сущность, созданная на мастере, до реплики еще не успела доехать. И код, который работает дальше, ничего не прочитывал.

Или другой момент. Пользователь в UI, заказчик, создал новый пул заданий, его страничка отрисовывается, а его на самом деле нет, потому что создавался он на мастере, а чтение пошло с реплик. Такие места мы отловили различными автоматическими тестами, и первое, что нам пришло в голову, давайте захачим и начнем форсированно читать все с мастера.

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

Есть еще способ в PostgreSQL, есть флажок remote_apply, он говорит о том, что нам нужно эту транзакцию закоммитить еще на реплики. Она не будет закоммичена до тех пор, пока не пройдет на мастере и на реплике.

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

А хотели примерно такого. Здесь тоже представлен кусочек кода. Мы хотели сделать некоторый вспомогательный метод, назвали его replicationBarrier, суть его в том, что в тех местах, где нам обязательно надо дождаться, что данные доехали до реплик, мы вставляем эту строчку кода, и приложение не выйдет из этого метода до тех пор, пока данные, созданные в транзакциях до этого места в этом потоке, не доедут до реплик. Кажется удобный и простой метод. Давайте подумаем, как его можно реализовать.

В 11-м PostgreSQL — сейчас в продакшен внедряют 10-й — будет специальная команда WAIT FOR LSN, где LSN — lock sequence numbers. И мы можем прочитать, в какой позиции мы в логе находимся, и подождать, когда эта позиция будет достигнута на реплике. Пока 11-го PostgreSQL нет, этим пользоваться не можем.

Еще вариант — вспомогательная вьюха в PostgreSQL, pg_stat_replication, в ней есть всякая диагностическая информация на тему того, как у нас работают реплики. В момент, когда мы транзакции провели, давайте замерять, на какой позиции в логе мы находимся, и потом через replay_location в этой таблице на каждой реплике проверять, где мы есть. И если мы находимся в позиции, которая нам нужна, или позже, то мы будем выходить из этого барьера. Реализовали, на тестовых окружениях все было хорошо, на продакшене под более высокой нагрузкой это не заработало, были моменты, когда реплики почему-то были рассинхронизированы.

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

Завели специальную таблицу, в ней у каждого бэкенда есть строчка, где хранится счетчик. Мы увеличиваем этот счетчик в момент, когда заходим в барьер, и ждем, пока все реплики вернут значение не меньше того, который мы только что заинкрементили. И для того, чтобы получать значение с реплик, у нас есть отдельный процесс. Помимо того, что он получает значение счетчика, он еще следит за живостью реплик. Реплики могут по тем или иным причинам отваливаться, на короткие моменты времени плохо работать, и он еще мониторингом доступности занимается.

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

В итоге наша база сейчас по объему занимает где-то 2 ТБ, у нас есть мастер, есть три реплики, на каждом из серверов по 32 ядра. Примерно 1,5 тыс. запросов в секунду выполняется на мастере. Это практически только запросы на создание или изменение каких-то данных. И 10 тыс. запросов на каждой из реплик, это запросы на чтение.

В replication_counter таблицу мы обращаемся где-то 200 раз в секунду за тем, чтобы получить значение счетчика, а увеличиваем его около 80 раз.

Ну и медиана ожидания барьера примерно равна времени ping до реплики — очень быстро.

С технической частью все, теперь про исследования. И здесь хочется рассказать про самую главную проблему в краудсорсинге — проблему качества данных.

Можете представить, что есть система, где платят деньги за выполнение каких-то заданий. Куча людей хотят как-то считить, получить это недобросовестным образом. Есть люди, которые пытаются случайно все прокликать, чтобы заработать побольше. Есть какие-то более продвинутые, которые пишут различные скрипты, которые пытаются автоматически эти деньги с нас намайнить.

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

Чтобы контролировать качество, существует несколько методов. Самый известный способ ловить роботов — это, конечно, капча. Мы ей тоже пользуемся. Иногда, когда мы подозреваем исполнителя в том, что он может быть роботом, показываем ему капчу, и если он несколько раз не справляется с ней, мы его в системе баним.

Также можно использовать различные эвристики по скорости выполнения заданий. Если задания выполняются настолько быстро, что исполнитель вообще не думает, как это выполнить качественно, или это бот, в который забыли вставить таймаут между сабмитом заданий, то мы тоже можем считать данного исполнителя подозрительным. Или если ответы идут одинаковые, тоже довольно простой паттерн — сидеть и одну и ту же кнопку все время нажимать, так тоже обычно поступают читеры.

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

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

Эти способы в платформе Толоки доступны из коробки. Мы постоянно внедряем новые способы контроля качества, которые будут доступны заказчикам.

Я упомянул, что одни и те же задания часто делают несколько исполнителей, и возникает интересная задача — задача агрегации ответов. Обычно, чтобы потом эти данные использовать — например, для обучения классификатора, — нам нужно по каждому входному элементу иметь итоговый вердикт. Нам неинтересно иметь пять разных мнений. И самой простой моделью агрегации является модель majority vote — надеюсь, так у нас выборы работают. Берем тот результат, за который проголосовало большее количество исполнителей.

Но есть модели и более сложные, которые используют различные характеристики заданий и исполнителей, вероятностные модели, которые строят в процессе своей работы разные предсказания о качестве работы людей. Мы провели исследования, сравнили много разных моделей, и за счет выбора правильной модели под конкретную задачу для итоговой агрегации данных можно выиграть в качестве до 15 процентных пунктов. Просто за счет того, что мы ответы исполнителей правильным образом сагрегировали. Поверьте, это очень много.

Перекрытия тоже не всегда можно использовать полностью. На картинке представлено, что к нам пришли исполнители-анонимы, мы про них ничего не знаем, а есть те, кто работает на нашем задании давно. У нас про них накоплена какая-то статистика. Или вообще у нас, может, есть мегаэксперт, одного ответа которого будет достаточно, чтобы итоговое решение принять.

И за счет того, что мы при раздаче заданий не всегда отдаем это, например, пяти исполнителям, а используем динамическое перекрытие, мы можем выигрывать в экономии денег. За счет динамического перекрытия можно экономить до 40% бюджета без снижения в качестве.

Я продемонстрировал три разных направления разработки в Толоке. Может, что-то из этого будет полезно вам в ваших проектах. Может, кто-то из вас занимается ML или Data Science и захочет попробовать Толоку для своих задач. Напомню, она открыта для любых заказчиков, у нее есть API, можно заливать туда свои задания и собирать данные для себя. У нас много интересных задач — может, кто-то захочет с ними помочь. Спасибо, на этом все.

Автоматическая очистка завершенных заданий

Временный механизм очистки старых заданий, выполнение которых завершено.

СОСТОЯНИЕ ФУНКЦИИ: Kubernetes v1.23 [стабильная]

Когда ваше задание завершено, полезно сохранить это задание в API (а не сразу удалять задание) так что вы можете сказать, удалось ли Работа или нет.

Контроллер Kubernetes TTL-after-finished предоставляет Механизм TTL (time to live) для ограничения времени жизни объектов Job, которые закончили выполнение.

Очистка завершенных заданий

Контроллер TTL-after-finished поддерживается только для заданий. Вы можете использовать этот механизм для очистки Завершенные задания (либо Complete , либо Failed ) автоматически, указав .spec.ttlSecondsAfterFinished поле задания, как в этом пример.

Контроллер TTL-after-finished предполагает, что задание может быть очищено TTL секунд после завершения задания. Таймер запускается, как только Состояние задания изменяется, чтобы показать, что задание либо Завершено или Сбой ; как только TTL истек, эта работа получает право на каскадное удаление. Когда Контроллер TTL-after-finished очищает задание, он удалит его каскадно, то есть удалит его зависимые объекты вместе с ним.

Kubernetes соблюдает гарантии жизненного цикла объекта в задании, такие как ожидание финализаторы.

Вы можете установить количество секунд TTL в любое время. Вот несколько примеров настройки .spec.ttlSecondsAfterFinished 9Поле 0008 задания:

  • Укажите это поле в манифесте задания, чтобы задание можно было очистить автоматически через некоторое время после его завершения.
  • Вручную установите это поле существующих, уже завершенных заданий, чтобы они стали подходящими для уборки.
  • Использовать изменение веб-перехватчика доступа чтобы установить это поле динамически во время создания задания. Администраторы кластера могут используйте это, чтобы применить политику TTL для завершенных заданий.
  • Использовать изменение веб-перехватчика доступа чтобы установить это поле динамически после завершения задания, и выберите различные значения TTL в зависимости от статуса задания, меток. В этом случае вебхук должен обнаружить изменения в .status задания и устанавливайте TTL только тогда, когда задание помечается как выполненное.
  • Напишите свой собственный контроллер для управления TTL очистки для заданий, которые соответствуют определенному селектор-селектор.

Предостережения

Обновление TTL для завершенных заданий

Вы можете изменить период TTL, например, .spec.ttlSecondsAfterFinished поле Jobs, после создания или завершения задания. Если вы продлеваете период TTL после существующий ttlSecondsAfterFinished период истек, Kubernetes не гарантирует чтобы сохранить это задание, даже если обновление для увеличения TTL возвращает успешный API ответ.

Искажение времени

Поскольку контроллер TTL-after-finished использует метки времени, хранящиеся в заданиях Kubernetes, для определить, истек ли TTL или нет, эта функция чувствительна ко времени перекос в вашем кластере, что может привести к тому, что плоскость управления очистит объекты Job в неподходящее время.

Часы не всегда правильные, но разница должна быть очень маленький. Помните об этом риске при установке ненулевого TTL.

Что дальше

  • Автоматическое чтение заданий очистки

  • См. предложение по улучшению Kubernetes (KEP) за добавление этого механизма.

Последнее изменение 29 января 2023 года в 14:06 PST: Исправьте ссылки на MuttingAdmissionWebhook (54E010C731)

Автоматическая очистка для готовой работы

.

СОСТОЯНИЕ ФУНКЦИИ: Kubernetes v1.23 [стабильная]

Когда ваше задание завершено, полезно сохранить это задание в API (а не сразу удалять задание) так что вы можете сказать, удалось ли Работа или нет.

Контроллер Kubernetes TTL-after-finished предоставляет Механизм TTL (time to live) для ограничения времени жизни объектов Job, которые закончили выполнение.

Очистка завершенных заданий

Контроллер TTL-after-finished поддерживается только для заданий. Вы можете использовать этот механизм для очистки готовых работ (либо Завершить или Неудачно ) автоматически, указав . spec.ttlSecondsAfterFinished поле задания, как в этом пример.

Контроллер TTL-after-finished предполагает, что задание может быть очищено TTL секунд после завершения задания. Таймер запускается, как только состояние задания изменяется, чтобы показать, что задание либо завершено , либо не выполнено ; как только TTL истек, эта работа получает право на каскадное удаление. Когда Контроллер TTL-after-finished очищает задание, он удалит его каскадно, то есть удалит его зависимые объекты вместе с ним.

Kubernetes соблюдает гарантии жизненного цикла объекта в задании, такие как ожидание финализаторы.

Вы можете установить количество секунд TTL в любое время. Вот несколько примеров настройки .spec.ttlSecondsAfterFinished поле задания:

  • Укажите это поле в манифесте задания, чтобы задание можно было очистить автоматически через некоторое время после его завершения.
  • Вручную установите это поле существующих, уже завершенных заданий, чтобы они стали подходящими для уборки.
  • Использовать изменение веб-перехватчика доступа чтобы установить это поле динамически во время создания задания. Администраторы кластера могут используйте это, чтобы применить политику TTL для завершенных заданий.
  • Использовать изменение веб-перехватчика доступа чтобы установить это поле динамически после завершения задания, и выберите различные значения TTL в зависимости от статуса задания, меток. В этом случае вебхук должен для обнаружения изменений в .status задания и устанавливать TTL только тогда, когда задание помечается как выполненное.
  • Напишите свой собственный контроллер для управления TTL очистки для заданий, которые соответствуют определенному селектор-селектор.

Предостережения

Обновление TTL для завершенных заданий

Вы можете изменить период TTL, например, .spec.ttlSecondsAfterFinished поле Jobs, после создания или завершения задания. Если вы продлеваете период TTL после существующий период ttlSecondsAfterFinished истек, Kubernetes не гарантирует чтобы сохранить это задание, даже если обновление для увеличения TTL возвращает успешный API ответ.

Об авторе

alexxlab administrator

Оставить ответ