Corner-кейсы в разработке и разметке данных: что это такое, как с этим жить и при чем тут Достоевский?

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

На обложке — главный corner-case всея Руси от Достоевского. Про такое в общем смысле и поговорим.

Состряпал демку в нашем софте

Состряпал демку в нашем софте

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

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

Что такое corner-кейсы?

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

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

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

Пример: для робота на складе был отличный CV-алгоритм определения захвата коробки, но на одном из складов с приходом лета в определенные часы начались сильные засветы и блики от солнца, и алгоритм там перестал работать хорошо.

Почти такой же пример: нужно определить перекрыт ли чем-то овал лица. Номинально и по условию задачи — нет, ничем не перекрыт, но есть нюанс…

Два разметчика не смогли договориться

Два разметчика не смогли договориться

Это вот — оно. И таких случаев может быть огромное количество.

Предлагаю разбить все эти случаи на две большие категории: «не доработали» и «по Достоевскому».

Не доработали

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

5868fcb5cf92d65c5bd1e1c3f46cb440.png

Распознанное лицо человека на рекламе автомобиля — сюда же.

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

Здесь — все понятно, надо просто предусмотреть в правилах такую ситуацию. Хорошим решением будет составить некую общую классификацию событий и оценку риска/решения по каждой из них в целом.

Единственный момент, здесь очень важно соблюсти баланс (или, как сейчас модно говорить, trade-off) между «ок, есть ситуация» и «все запретить!».

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

Баланс здесь — очень важен. К сожалению, часто бывает так, что найти такой баланс — менеджерская (или инженерная) задачка со звездочкой, а где-то даже настоящее искусство.

По Достоевскому

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

Чем-то похожим на такое является «проблема вагонетки», у которой нет хорошего или хотя бы явного ответа.

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

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

Например, что мы будем делать, если при трекинге объекта X его надолго перекрывает другой объект Y? А если перекрытие частичное? А если грязь на камере, но картинка различима? А если радар видит какой-то объект, а лидар одновременно — нет?

Если мы не уверены в ответе, то что делаем — принимаем или отклоняем? Как быть с текстами двойного назначения, эмоциями типа сарказма или оценкой текста по «интересности»? Очень странное поведение на общественной камере — это отсутствие доп информации (болезнь у человека, например) или же какой-то фрод?

Такие случаи — это сложно и неприятно, но решать их, к сожалению, тоже нужно.

Одна из моих больших сфер увлечения сейчас — это внутренности ллмок, и на их примере даже сейчас (уже 30 сентября, алло!) есть отличный пример нахождения (или НЕ нахождения) баланса, а именно — сейчас срабатывает такой легкий хак как: попросить ответить на запрещенку в прошедшем времени.

Вот простой запрос:

aad3709bb357f0e0d13edb28418bd358.png

Вот он же в прошедшем времени:

Да, прям полный рецепт, который я обрезал на пункте 1 по понятным причинам

Да, прям полный рецепт, который я обрезал на пункте 1 по понятным причинам

Так и вот что со всем этим делать? Как закрывать-то?

Непонятно и точно сложно.

Но хорошие новости все же есть.

Как дальше жить

Какой бы случай нам не попался бы, их объединяет то, что их нужно а) ловить б) от них защищаться.

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

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

Ключевой аспект борьбы с corner-кейсами — хорошее понимание решаемой задачи. Казалось бы, это очевидно, но в реальной жизни этого часто не хватает. Что мы хотим сделать, что мы хотим получить? Зачем? Что может пойти не так? (если что-то может пойти не так, то скорее всего, оно так и будет)

Эти вопросы стоит всегда себе задать и честно на них ответить.

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

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

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

Выводы

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

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

Если вам было интересно, то рекомендую мои предыдущие статьи:

Разбор SAM2 через колено в голову или революция в разметке видео

Офис Apple в Москве: как я с нуля стал экспертом и попал на приватную вечеринку для разработчиков

А еще можно посмотреть мое выступление на конфе Яндекса Practical ML 2024:

Использование LLM в разметке данных: можно ли убрать людей?

Спасибо!

© Habrahabr.ru