Для начала пару слов о себе. Зовут меня Муаммар, 21 год от роду, на данный момент являюсь студентом пятого курса мехмата МГУ. А еще я выпускник ШАДа, ведущий семинаров по Natural Language Processing в ШАДе и младший разработчик в команде речевых технологий Яндекса. Какой-то супергениальностью не отличаюсь, но люблю и умею работать. Пожалуй, хватит себя расхваливать, поговорим о стажировке. Кому интересно — добро пожаловать под кат!
Процесс подбора команды
Так вот, решил я летом поработать в Яндексе. Недолго думая, написал Юле Кривовой, которая является куратором студенческих программ, сказал, хочу заниматься какими-нибудь сложными задачами, при том не забыл упомянуть, что увлекаюсь NLP. Как там в «Поле чудес»? Пользуясь случаем, хотел бы
Изначально мной заинтересовалась команда машинного перевода. Стажерской вакансии у них не было, но все равно они решили со мной пообщаться. Все было прекрасно за исключением того, что предполагался разговор по душам, а в итоге все обернулось техническим собеседованием. Морально я к этому не был готов, в результате жутко тупил и решал все лишь с тысячной подсказки. Ушел с ворохом мыслей о своей ничтожности. Хотя через несколько дней Юля сказала, что в целом я им понравился, так что нужно ждать стажерскую вакансию.
Через некоторое время обо мне проведал один из моих ШАДовских преподавателей по информационному поиску — Саша Болховитянов, а им как раз нужен был человек на позицию младшего разработчика в команду поиска дубликатов. Неделю спустя меня пригласили на три подряд идущих технических очных собеседования: алгоритмы, проектирование и C++. Алгоритмы и структуры данных я знал прекрасно, да и в целом ничего сверхъестесвтенного не спрашивали. В проектировании на вопросы типа «а как построить распределенную отказоустойчивую систему» и «а что если в этой системе…» помогла смекалка. А вот с C++ возникли серьезные проблемы. Хотя я и понимал, как написать программу, что делает любая конкретная строчка кода, тем не менее о том, как все это устроено на уровень глубже, в памяти, на тот момент я не имел особого представления. Человек я коммуникабельный, поэтому, чтобы хоть как-то разбавить фиаско, поговорил с собеседующим по душам. Суммарное впечатление я произвел положительное, но вот задачи, которыми они предлагали заниматься, лично меня не сильно вдохновляли. И я четко решил: уж лучше за небольшую зарплату, зато на интересные лично мне задачи пойти пускай стажером в машинный перевод, чем в поиск дубликатов младшим разработчиком.
Время шло, а вот все остальное почему-то так и стояло на месте… но недолго! Точно уж и не припомню когда, но для красоты давайте вообразим, что в три часа утра, ко мне на почту приходит письмо от Юли: команда разработки голосовых интерфейсов ищет себе сотрудника! «Да это же чистое NLP», — пронеслось в голове. Извлечение информации из текста, определение именованных сущностей, чат-боты — в общем, я прямо-таки загорелся к ним попасть. Сначала ребята устроили скайп-собеседование по Python, заодно уточняя мои знания Bash. Если в первом я соображал неплохо, то вот что такое Bash — я и знать не знал! После собеседования они дали мне большое домашнее задание — написать диалогового агента, который по человеческим запросам, к примеру «Что такое Эйфелева башня?», находил бы наиболее подходящие статьи из Википедии. Мне до сих пор кажется, что я сделал добротно, но, как бы там ни было, их руководитель сказал, что в команду требуется все же готовый разработчик, а не стажер, с которым нужно нянчиться и всему учить.
Осталась единственная команда — распознавания речи. Если честно, об этой области я не знал ничего, к тому же смутно представлял, где именно там NLP. Мой нынешний руководитель Илья iliia Едренкин заверил, что мне у них понравится, к тому же задачи, которыми они занимались, мне показались крайне сложными. В сухом остатке меня поджидали еще два собеседования: первое — по продвинутым алгоритмам, где вдобавок к обычным знаниям требовалась немалая смекалка, а второе — по машинному обучению. Прошел я их не с блеском, но приличненько. Буквально через день-два пришло письмо от Юли, что меня готовы взять в команду. Ура, товарищи, счастье наступило!
Отдельно хотелось бы отметить несколько моментов, которые, как мне кажется, положительно влияли на прохождение собеседований. Во-первых, отсутствие волнения: в Яндекс я шел с таким настроем, будто не меня будут собеседовать, а я собирался там всех собеседовать, да и результат мне был совершенно не важен: возьмут — прекрасно, не возьмут — тоже слава Богу. Во-вторых, даже если где-то я и тупил, тем не менее старался в целом завязать беседу, поговорить на отвлеченные темы, выставить себя в положительном свете. В-третьих, я никогда не тратил на подготовку к собеседованию более трех часов, а единственное, что делал во время подготовки, так это освежал знания в той или иной области.
Технический аспект стажировки
Каждому стажеру в Яндексе ставят небольшую, но достаточно творческую задачку в предположении, что он решит ее за 3–6 месяцев. Причем слово «решит» не стоит понимать буквально. Иногда речь и правда идет о решении некоторой небольшой задачи, в каких-то случаях это может быть улучшение метрик, бывает так, что нужно придумать какой-нибудь новый метод или подход к задаче. В моем случае нужно было научиться определять степень уверенности распознавания фраз и отдельных слов нашей ASR-системой (ASR — Automatic Speech Recognition). Напомню, как происходит распознавание речи. Процесс преобразования звука в текст состоит из нескольких этапов.
- Предобработка. Мы дробим звуковую запись на фреймы по 25 мс с шагом 10 мс. (Возможно, также стараемся некоторыми методами избавиться от шума.)
- Извлечение фичей. Из каждого фрейма извлекаются некоторые численные фичи.
- Преобразование фичей в распределение по фонемам (на самом деле в реальной модели не фонемы, а сеноны — классы контекстно-зависимых фонем). Фичи от нескольких соседних фреймов соединяются вместе, и на это добро натравливается некоторая нейронная сеть (DNN, LSTM, GRU — что душе угодно). На выходе мы получаем вероятностное распределение по фонемам.
- Декодирование. Далее с учетом языковой модели, лексикона и нашего представления о мире происходит декодирование найденных распределений вероятностей, и мы получаем цепочку слов.
Вся проблема заключается в шаге 3. Нейронная сеть — дискриминативная модель. Она говорит, насколько хорошо одна фонема отличается от другой в данном фрагменте звука, но не говорит, насколько много/хорошо та или иная фонема в этом куске звука представлена. Тут возможна такая аналогия. Некоторых людей мы знаем настолько хорошо, что можем описать их полностью, — это генеративная модель. А бывает так, что мы увидели человека и что-то отложилось в нашей памяти, описать человека мы не можем, но зато если нам покажут фотографию произвольного человека, то мы можем сказать, он на фото или нет, — это дискриминативная модель. Проблема такой модели состоит в том, что был у нас, например, некоторый фрейм и на нем звучал звук «п» в обычных условиях и в условиях зашумленности. Если этот звук в принципе — что в одном случае, что в другом — отличим от других звуков, то нейронная сеть вполне может в обоих случаях присвоить им одинаковую вероятность, а мы все же хотим как-то различать эти два случая.
Так вот, в силу сказанного выше, ASR-система плохо умеет понимать, насколько чистой/зашумленной была запись. А нам важно это понимать, потому что если запись очень зашумленная, то лучше переспросить человека, чтобы он еще раз повторил свой запрос, чем распознать и выдать ему полную чушь. Степень уверенности в записи называется конфиденсом (confidence). Определение уверенности фразы также полезно для того, чтобы давать асессорам размечать лишь записи со средним конфиденсом. С большим конфиденсом записи и так хорошо распознаются, с низким — просто шум, а вот со средним — самые полезные, ибо это сложные примеры для нашей системы. А чем более сложные примеры мы даем системе распознавания речи, тем быстрее она учится (тут как с человеком: если ему постоянно давать решать «2 + 2», интеграл он не посчитает).
Вообще говоря, в задаче определения конфиденса есть две смежные подзадачи:
- определение уверенности каждого слова в отдельности,
- определение уверенности фразы в целом.
В первом случае стоит задача классификации: либо мы угадали слово (класс 1), либо мы ошиблись (класс 0). Во втором случае стоит задача регрессии. Да, забыл сказать, что качество распознавания измеряется метрикой WER (Word Error Rate). Так вот, во втором случае мы будем стараться предсказать 1 — WER, после чего это и назовем пофразовым конфиденсом. Также стоит отметить, что если мы хорошо умеем решать первую задачу, то уже неплохой оценкой для 1 — WER будет средний пословный конфиденс, так что именно на эту задачу я сконцентрировал основные силы.
Все уже, наверное, подумали, что технические детали на этом закончились? Ан нет. Пожалуй, это не столь секретная информация, поэтому расскажу в общих чертах, какое конечное решение было у задачи. Для пословного конфиденса были использованы два типа фичей: акустические и языковые. Подбор акустических фичей был попыткой бороться с дискриминативностью нейронной сети. Мы собрали некоторые статистики по всему обучающему корпусу (средняя длительность по фонемам и т. п.), а далее для каждого слова при распознавании конкретной фразы сравнивали его параметры со статистически средними по корпусу. Это смягчало дискриминативность и вносило некоторую информацию о внешнем мире. В качестве языковых фичей были взяты вероятности n-грамм с целью отслеживания различных несогласованностей типа «зеленый трава». В конечном счете на это был натравлен градиентный бустинг, и вуаля — мы имеем пословный конфиденс! Результаты получились вполне достойными: порядка 25–50% (вариация в зависимости от модели) прироста качества по отношению к бейзлайну (sMBR). Для оценки пофразового конфиденса были использованы всего две фичи: средний пословный конфиденс и степень того, насколько сильно различаются между собой N лучших гипотез, которые выдала ASR-система при распознавании (смысл в том, что если гипотезы различаются сильно, то скорее всего фраза была произнесена нечетко и ее WER будет большим).
Пару слов о самих экспериментах. Далеко не всегда они получаются хорошо и сразу. Было две подзадачи: придумать фичи и выбрать алгоритм машинного обучения. Иногда у тебя есть куча идей с фичами, пробуешь — ни одна не дает улучшения. Пробуешь другие — опять нет улучшения. В исследовательских задачах часто так бывает. Нужны выдержка и терпение. Я себе четко сказал: ты старайся, а дальше будь что будет, и ни в коем случае нельзя унывать. Это только кажется, что вот фичи, бац-бац — и улучшение, а на самом деле за этим стоит кропотливый труд и куча провалившихся экспериментов.
Напоследок отмечу, что Илья Едренкин предложил называть конфиденсы «числами Муаммара». Еще было довольно забавно, что я периодически слышал эти слова, когда коллеги о чем-то говорили, но каждый раз думал, что мне это слышится. А на одном из собраний команды мне сказали: «А ты не знаешь, что конфиденсы уже месяц как называются числами Муаммара?» Ну а дальше как-то прижилось :).
Минусы и плюсы стажировки в Яндексе
Из минусов, пожалуй, отмечу две вещи. Первая заключается в том, что периодически тебе приходится заниматься не своей работой. И это происходит даже не потому, что все вокруг такие злые и хотят спихнуть на тебя часть своих обязанностей, а просто потому, что иногда этим некому заняться, а дело важное. Второй момент состоит в том, что, достигнув уровня Яндекса, легко потерять стимул двигаться дальше. Попав в какую-то команду, где тебе не нравится, ты все равно можешь остаться, ибо «ну это ж Яндекс».
О плюсах. Как вы могли догадаться, человек я достаточно верующий, поэтому первым плюсом поставлю именно возможность соблюдения религиозных практик. В Яндексе людей ценят не за веру и политические или другие убеждения, а за то, как хорошо они делают свою работу, и устраивают все так, чтобы работать было удобнее. Поэтому даже в таком чувствительном вопросе Яндекс готов идти навстречу. С пятикратной молитвой вообще нет никаких проблем: нашел свободную переговорку — и хоть на голове там стой. Но это еще не все. Как многим, наверное, известно, каждый половозрелый мужчина из числа мусульман обязан посещать пятничную проповедь. Поэтому для себя я четко решил: если не будет возможности ходить на проповедь, то мне такая работа не подойдет. Хотя график и гибкий, волею случая оказалось, что именно в пятницу, именно во время пятничной проповеди у нас было еженедельное собрание команды. Я сразу сказал: Илья, извини, но конкретно в это время я не смогу присутствовать. К моему великому удивлению, ради стажера, не проработавшего и одной недели в команде, порядка десяти человек (некоторые годятся мне в отцы и имеют многолетний стаж) согласились перенести встречу на удобное для меня время. Сказать, что такое отношение со стороны членов команды радует и располагает, — ничего не сказать.
Второй плюс: Яндекс предоставляет море возможностей для развития в профессиональном плане: можно посещать разнообразные научные семинары, доклады ученых и многое другое. Я вот даже умудрился слетать на ШАДовскую конференцию — но это скорее исключение, чем правило! Причем приобретение новых знаний в области Computer Science является частью твоей работы. Яндекс хочет, чтобы его сотрудники становились умнее! Более того, у меня есть хобби — преподавание: ну вот нравится чему-то учить людей. Вообще не вопрос, говорит Яндекс, преподавание в ШАДе — пожалуйста, выступления на научных семинарах — с радостью! В продолжение научной темы хочется отметить, что в нашей команде каждому человеку выделяется достаточно много, по моим меркам, вычислительной мощности, поэтому если ты хочешь позаниматься своими собственными исследованиями вне рабочего времени, то флаг тебе в руки, никто не будет тебя укорять.
И третий плюс: комфортную работу обеспечивает прекрасный московский офис. Не отметить это сложно, но распинаться я тут совсем не буду — тема достаточно известная.
Есть ли жизнь после стажировки?
Некоторые могут подумать, что лишь на стажировке все так весело и радостно, а как только ты становишься разработчиком, начинаются суровые рабочие будни. Это не так… во всяком случае не всегда так! Например, немалая часть моей работы заключается в чтении научных статей из области распознавания речи, в их модификации и воплощении в жизнь. Кстати, это еще одна причина, по которой я советую разборчиво подходить к подбору команды: мне такое жутко нравится, а кому-то другому может показаться ужасно скучным. Выбирайте область себе по вкусу, чтобы трудиться с улыбкой, а не кислой миной на лице! Подытоживая, повторюсь: стажировка в Яндексе — стоящее занятие на лето. Вполне возможно, что потом она выльется в интересную постоянную работу.
Комментарии (30)
kometa_triatlon
29.04.2016 16:59Привет, Муаммар!
Хе, а я и не в курсе был насчет пятничной молитвы :)
Судя по всему, жизнь в Яндексе продолжается?
FeferIvan
29.04.2016 17:44Попав в какую-то команду, где тебе не нравится, ты все равно можешь остаться, ибо «ну это ж Яндекс».
Есть внутренняя ротация, так что, с учетом размеров Яндекса, всегда можно найти команду, где тебе будет интересно.janitor
03.05.2016 15:22Насколько помню, чтобы перейти в другую команду, там тоже нужно проходить точно такие же собеседования?
Dark_Purple
29.04.2016 18:24+1521 год от роду, на данный момент являюсь студентом пятого курса мехмата МГУ. А еще я выпускник ШАДа, ведущий семинаров по Natural Language Processing в ШАДе и младший разработчик в команде речевых технологий Яндекса. Какой-то супергениальностью не отличаюсь
Ощущаю себя обезьяной.
mbait
29.04.2016 23:56зеленый трава
Я тоже когда-то приходил к этой идее. Проблема в том, что при достаточно объёмной языковой модели и её правильно подобранном коэффициенте «зеленый трава» просто не должен попасть в lattice или будет иметь очень маленький score. А вот если модель не очень большая… то там может быть всё, что угодно. У вас рассматривали тот же вариант, но с построением phone-based LM? То есть идея в том, что слов много, и для хорошей языковой модели нужно много данных, а вот фонем не так много, и при низком perplexity можно попробовать определить насколько естественно звучит слово и относительно этого рассчитывать confidence.Laytlas
30.04.2016 10:15В целом, вы правы, что в идеале процесс декодирования с хорошей языковой моделью должен отсеять все варианты типа «зеленый трава», но на практике это не так, поясню почему.
Обычно декодирование происходит с широким бимом, так что если слова звучат примерно одинаково, единственное отличие будет в языковой модели, а она не создаст такой большой разницы, чтобы вытолкнуть плохую гипотезу за пределы бима. А так как я вообще при оценке конфиденса не учитывал графовые веса (эксперименты показали, что это бессмысленно), то еще раз поиспользовать языковую модель было просто необходимо!
Что же насчет построения языковой модели на фонемах, то она никак не решает проблему, а, напротив, может ее усугубить. Возьмите две фразы «черный кофе» и «черная кошка». И пусть так случится, что в нашей языковой модели префикс «черная ко...» встречается чаще, чем «черный ко...». В итоге вы получите, что даже если человек скажет «черный кофе», такая языковая модель постарается исправить фразу на «черная кофе».mbait
02.05.2016 20:34В таком случае было бы здорово увидеть результаты Яндекса на открытых данных: librivox, TEDLIUM, fischer, т.д. К сожалению, ограничения вашего SpeechKit не позволяют это сделать. Ещё мне почему-то кажется, что у вас WFST, а не динамический декодер =) В этом случае тяжелее проводить микро-оптимизации.
Mugik
30.04.2016 11:21+2Всё, я разочаровался в жизни.
Вон Муаммар и в яндексе работает и на мех мате учиться, и в шаде учиться и ведет семинары по текст-процессингу. Берет спортивные награды, нокаутирует всех в первом раунде, решает быстрее всех интегралы и пишет самые крутые алгоритмы. Сочиняет стихи, рисует картины.
Toshiro
01.05.2016 13:31«После собеседования они дали мне большое домашнее задание — написать диалогового агента, который по человеческим запросам, к примеру «Что такое Эйфелева башня?», находил бы наиболее подходящие статьи из Википедии. Мне до сих пор кажется, что я сделал добротно, но, как бы там ни было, их руководитель сказал, что в команду требуется все же готовый разработчик, а не стажер, с которым нужно нянчиться и всему учить.»
Обычно когда после выполненного задания такого уровня слышишь такое от руководителя — жди пару месяцев и твой код будет представлен как достижение команды)) Хотя с тобой, конечно, нянчиться никто не хочет))
На заре своей карьеры я тоже пару раз так вляпался, пока не осознал как устроен мир)) Не надо думать, что если тебе выдали сложное тестовое задание, всегда хотят именно проверить твой навык)) Не всегда))samodum
02.05.2016 12:44А что сложного в таком задании?
Отслеживаем regexp вида
^что тако\w? (.+?)
И ищем в википедии первую группуLaytlas
02.05.2016 13:30Я не сказал, что оно сложное, но оно не настолько очевидное, как кажется. Человек может задать «кто такой Чак Норрис» или «сколько дней в високосном году». Вы собираетесь руками вбивать всевозможные префиксы для поиска? Это какое-то brute-force решение.
samodum
02.05.2016 14:15+1Вы же не указали способ как решали эту задачу.
А я предложил простейший вариант решения. Он не идеален, но вау-эффект достигается на ура. A.L.I.C.E., Болтун и Siri изначально были основаны на этой моделиMugik
02.05.2016 18:35«Какова глубина озера Байкал?»
^что тако\w? (.+?) — Fail :)samodum
02.05.2016 22:14+1Это решается добавлением новых regexp. В моей сегодняшней системе их сейчас несколько тысяч и они покрывают 80% всех шаблонных фраз людей. Этого вполне достаточно для имитации диалога и вполне достаточно для вау-эффекта.
Так же, в посте нигде не сказано, что система Laytlas'а может отвечать на этот вопрос. Она может отвечать только про «что такое X», если я правильно понял.
Зато я указал способ, когда можно добавить новый regexp и он будет понимать и про озеро Байкал и про Каспийское море.Laytlas
02.05.2016 22:21На самом деле я сделал более общий, NLP-шный, подход, который работает в зависимости от чистоты данных, на которых все обучается. Но статья не об этом была, поэтому я и описывать не стал.
samodum
02.05.2016 22:36Где-то в 2004-м я тоже делал штуку, тоже на NLP-шном подходе. На вход подавался поток RSS, на выходе было структурное дерево предложения. И можно было задавать вопросы на ЕЯ. Там было без статистик и ML, только на семантических правилах. Детали, думаю, описывать не надо.
Laytlas
02.05.2016 22:40Да, в принципе, понятно. Но вообще, это NER в чистом виде. Можно нагенерировать множество фичей и обучить на них логистическую регрессию. В общем, подходов море!
samodum
03.05.2016 00:43Верно, подходов море. Именно потому, что эта область ещё не изучена, не структурирована и формально не описана.
Здесь огромный простор для творчества.
Mugik
02.05.2016 23:01-1«What is the deepest lake in the world?»
^Само\w? (.+?) — Fail :)
Думаю ваш подход сравним с тем, чтобы лично самому сидеть за компом и выдавать ответы.samodum
03.05.2016 00:41Практика говорит, что это работает. Siri, мой проект тому доказательства.
Можно сколь угодно много рассуждать, что это не работает, но реальность говорит о другом.
EvRiaL
02.05.2016 19:20+1Извиняюсь за нескромный вопрос, редкий интересный момент чтобы удержаться спросить и не втянуть в полемику…
а вы не думаете как технарь и научный работник, что религиозность может помешать развиваться в этой сфере?Laytlas
02.05.2016 22:33Напротив! Чем более человек религиозный, тем меньше времени он тратит на компьютерные игры, просмотр бесполезных видео в сети, бессмысленное общение и т.п. Накопленное время он тратит либо на поддержание религиозности, либо вливает в научное/рабочее русло.
BIanF
С одной стороны, это так круто.
С другой, привык как-то летом отдыхать. Трак трудно сделать первый шаг, да и диплом близко…