Вступ до NLP. Як розробити діалогову систему

Привіт, мене звати Ян Бутельський, я NLP-розробник. Уже шостий рік своєї кар’єри займаюся обробкою природної мови, допомагаю машинам зрозуміти людей. Моє знайомство з NLP почалося ще в університеті, але через тодішні методи викладання матеріал здавався мені вкрай нудним. Жодних перспектив у цьому напрямі для себе я тоді не побачив.

Утім після університету доля підкинула мені першу роботу, де NLP стало моєю рутиною. Я збирав, обробляв та анотував великі блоки текстових даних з різних сторінок інтернету. В мене був класичний синдром затятого програміста: практики було багацько, а от теорії бракувало. Згодом я відкрив для себе Coursera і її чудових викладачів.

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

ChatScript у NLP: ніколи знову

І почну одразу з epic fail story. На старті шляху NLP-інженера я потрапив на проєкт, де NLP-складова була основою продукту (що є рідкістю). Головною фішкою проєкту була якраз діалогова система, для розробки якої замовник обрав платформу ChatScript. На той час вона мала репутацію авангарду NLP, вирішувала купу проблем із діалоговими системами й узагалі була привабливою інвестицією. Вишенькою на торті стала премія Льобнера (присуджена найбільш «людиноподібним» програмам), яку ChatScript неодноразово вигравав.

Та саме на цьому моменті я мушу застерегти всіх, хто хоче розпочати працювати з ChatScript. Якщо коротко: не треба. Якщо трохи розгорнутіше: не треба, будь ласка. Річ у тім, що під капотом ChatScript не відбувається жодної магії — вона містить лишень просунутий набір if’ок і регулярних виразів. Про машинне навчання чи просунуті алгоритми розпізнавання природної мови годі й говорити. Їх немає. Враховуючи те, що у ChatScript немає потужних інструментів для побудови чат-ботів, мені видається, що єдина людина, яка виграє з ChatScript щорічну «льобнерівку» — це сам творець платформи.

Створюємо архітектуру: логіка та принцип роботи

Відокремившись від застарілих технологій, NLP-спеціаліст стикається із наступним викликом — самостійним вибором архітектурного рішення для діалогової системи (і відповідальністю за його імплементацію). На щастя, у часи дилеми з ChatScript я бачив на ринку непогані аналоги — Siri, Google Assistant, Microsoft Cortana та Amazon Alexa. Їхня потужність охайно загорнута в простоту: надіслати повідомлення, подзвонити, знайти локацію тощо можна було без танців з бубном.

Перше, на що програмістові варто звернути увагу — архітектурна схожість усіх вищеназваних діалогових систем. Якщо дуже просто: запит обробляється через пайплайн з модулів. Ключова мета — розпізнавання наміру, тобто intent’у користувача — відтворюється за допомогою стандартної ML-задачі multiclass classification. Точна аналітика будь-яких даних неможлива без належного сортування і маркування інформації. Втім організувати ці дані складніше, коли елемент може належати кільком маркуванням одночасно. Уявімо, що ви категоризуєте бібліотеку української літератури, де збірка Жадана водночас підпадає під лейбли «поезія», «проза» та «сучукрліт». У тексті, який декларує бажання людини, такої невизначеності бути не повинно, тому маркування тексту часто є взаємовиключними. Ви запитуєте або поезію, або прозу, або збірку, але ніяк не все одразу.

Принцип роботи multiclass classification простий — вона збирає корпус даних і маркує їх відповідними намірами людини. Так натренована ML-модель вчиться розуміти те, що ми від неї хочемо. Типовий приклад — у роботі Apple Siri. На вході система отримує текстову послідовність і, базуючись на «м’язах» натренованої моделі, визначає намір користувача та видає результат. На зображенні нижче можете побачити, як система розпізнає намір людини, а на бекенді окреслює його як intent: nav.time.closest.

Оскільки людське мовлення і мова — це майже завжди різниця між сказаним і почутим, обробка природної мови є складнішою за пошук true/false-збігів. Відповідь на фразу «де тут „Криївка“?» залежатиме від (1) вашої локації, (2) бажаного виду транспорту, (3) годин роботи закладу і (4) дорожнього трафіку. Саме тому intent є формою, що складається з кількох слотів. Аби виконалася певна дія, ця форма має бути заповненою. До прикладу, ми — процесор, а по той бік екрана — тремтячий від холоду турист, який призабув, що столичне метро вже не працює. Коли він питає про те, як дістатися звідси до готелю, ми відтворюємо його намір як nav.directions, який складатиметься з двох частин — @from i @to, тобто точок А і Б. Під капотом діалогової системи це матиме такий вигляд.

Користувач: Give me directions to Hotel Grand Budapest

  • Intent classifier: nav.directions
  • Slot tagger: @to{HotelGrandBudapest}
  • Dialogue manager: all slots are filled, here’s the route

Асистент: Here’s the route

Звісно ж, розпізнавання слотів — теж нелегка справа, для якої треба тренувати окрему модель. Незалежно від ступеня складності, я раджу використовувати стандарт BIO/IOB (скор. beginning-inside-outside). Це загальний формат позначення тегів для маркування тексту в NLP. Текст розбивається на токени, а маркуються лише ті з них, які цікавлять конкретного користувача з конкретним наміром (і процесор, який на нього батракує). Префікс B- відповідає за початок слоту, I- — середину, а O- за сам слот. На виході отримуємо токени, промарковані тегами. Їх модель буде використовувати як лейбл під час тренування.

Працюємо з архітектурою: лікнеп із модулів

Наступним кроком у вашій роботі з архітектурою буде розробка і налаштування окремих модулів. На ілюстрації нижче зображено весь пайплайн діалогового менеджера, і розуміння роботи з кожним модулем — ключ до налагодженої роботи NLP-інженера. Як бачимо, сама схема проста: модуль ASR перетворює людське мовлення на текст, після чого NLP-алгоритм структурує і маркує його, а діалоговий менеджер інтерпретує його в команди та диригує усією системою. На виході користувач отримує очікуваний результат, що супроводжується згенерованим текстом, аудіоповідомленням, посиланням чи зображенням.

А тепер я зазирну до кожного модуля окремо і простими словами поясню, навіщо вони тут і як працюють.

Automatic Speech Recognition — зчитує усну мову користувача і переробляє її у текстовий формат для подальшої обробки. Важливо пам’ятати, що з отриманого тексту системі необхідно витягнути якомога більше фіч, особливо для коректної роботи наступного модуля.

Natural Language Understanding — тренує отримані моделі й на основі цього створює додатковий шар логіки, який керує роботою усієї архітектури та стає фундаментом модуля Dialogue Manager.

Dialogue Manager — локомотив діалогової системи, який ухвалює рішення про виконання чи ігнорування запиту користувача (зверніть увагу на ілюстрацію з попереднього розділу). Він тісно пов’язаний з бекенд-процесами, які можуть звернутися до third-party сервісів або баз даних. До прикладу, на запит про Львівську ратушу бекенд паралельно тягнутиме інформацію з Вікіпедії та Google Maps, аби видати дві релевантні відповіді.

Natural Language Generation — останній бастіон у спробі машини зрозуміти намір людини й видати остаточний результат. Зібравши необхідну інформацію від усіх попередніх модулів, він генерує релевантну до запиту відповідь людською мовою.

Підсумок

Шлях від «хей, Сірі» до бажаного результату хоча й бентежний, але не настільки складний, як може здаватися. Архітектура діалогового рішення складається із чіткої послідовності незалежних модулів, кожен з яких долає конкретну сходинку в обробці тексту: зчитування, маркування, інтерпретація тощо. Успішність цілої системи залежить не лише від натренованості моделі, а й від чіткості роботи кожного модуля.

Майбутнім і нинішнім NLP-інженерам, окрім декомпозиції системи на модулі, стане в пригоді ще кілька ресурсів, завдяки яким я навчився краще і швидше будувати окремі модулі та поєднувати їх в архітектуру діалогової системи. Основа основ — це книга від O’Reilly Natural Language Processing with Python. Автори простими словами розповідають про NLTK для Python, побудову словника та парсинг текстів. Любителям онлайн-навчання рекомендую класичний Coursera-курс з обробки мови. Не менш вдалим, на мій погляд, є Стенфордський курс з корисною документацією із теми.

Сподіваюся, що ця публікація допоможе NLP-інженерам глибше зрозуміти діалогові системи, а найкращим продовженням буде дружня дискусія про особливості різних платформ для NLP. Хтозна, можливо, існує людина, яка успішно використовує ChatScript для серйозних алгоритмів обробки тексту, а мої застереження — приховане невігластво.

Якщо стаття буде цікавою товариству, обіцяю у майбутньому зробити докладний опис кожного зі складників пайплайну діалогової системи та поділитися best practices щодо їхньої побудови. Дякую за приділений час!

Похожие статьи:
Компания VAIO подтвердила, что на данный момент не имеет планов по распространению смартфонов Phone Biz за пределы японского рынка. Об этом...
Заступник міністра економіки Віталій Кіндратів в інтервʼю для Forbes повідомив, що зараз в Україні заброньовано орієнтовно 800 тисяч...
На нашем YouTube канале появились новые видеоролики.Обзор антиворовских сумок...
Робоче місце — «свята святих» будь-якого ІТ-спеціаліста. Від того,...
Через війну в Україні багато ІТ-фахівців переїхали до Польщі...
Яндекс.Метрика