На фоне холодной войны СССР и США задача автоматического перевода – в частности, в паре русский-английский – стала одним из первых проектов ИИ. В 1947 году математик Уоррен Уивер восторженно описал ранние подходы к решению этой задачи: “Естественно, возникает вопрос, нельзя ли считать задачу перевода задачей криптографии. Глядя на статью на русском, я говорю: «Эта статья написана по-английски, но зашифрована странными символами. Теперь я ее расшифрую»”[253]. Как обычно случается в ИИ, эта “расшифровка” оказалась гораздо сложнее, чем предполагалось изначально.
Как и другие проекты на заре ИИ, первые методы машинного перевода опирались на сложные наборы прописанных людьми правил. Если перед системой стояла цель перевести текст с языка оригинала (например, английского) на язык перевода (например, русский), ей давали синтаксические правила обоих языков, а также правила преобразования синтаксических структур. Кроме того, программисты создавали для системы словари с пословными (и простыми пофразными) соответствиями. Как и многие другие проекты символического ИИ, эти методы хорошо работали в некоторых узких случаях, но оставались довольно хрупкими и буксовали при встрече со всеми сложностями естественного языка, которые я описывала выше.
В 1990-х годах господствующее положение в отрасли занял другой метод – статистический машинный перевод. В соответствии с тенденциями ИИ того времени в основе этого метода лежало обучение на данных, а не следование прописанным людьми правилам. Огромный обучающий набор составлялся из пар предложений: первым в паре шло предложение на языке оригинала, а вторым – перевод этого предложения (выполненный человеком). Пары предложений были взяты из официальных документов билингвальных стран (например, все документы Парламента Канады составляются на английском и французском языках), стенограмм Организации Объединенных Наций, которые переводятся на шесть официальных языков ООН, и других больших корпусов исходных и переведенных документов.
Системы статистического машинного перевода 1990-х и 2000-х годов обычно вычисляли большие таблицы вероятностей, связывающие фразы в языках оригинала и перевода. Получая новое предложение, скажем, на английском – например, a man went to a restaurant, – система разделяла его на фрагменты (a man went и into a restaurant) и, ориентируясь на таблицы вероятностей, искала соответствия для этих фрагментов в языке перевода. В таких системах были дополнительные шаги, чтобы убедиться, что фрагменты дополняют друг друга в предложении, но главным двигателем перевода были вероятности, определенные при работе с обучающим набором. Хотя системы статистического машинного перевода имели весьма ограниченные представления о синтаксисе обоих языков, в целом они переводили тексты лучше, чем системы на основе правил.
“Google Переводчик” – возможно, самая широко используемая программа автоматического перевода – применял такие методы статистического машинного перевода с момента своего запуска в 2006 году до 2016-го, когда специалисты Google разработали более совершенный, по их утверждению, метод, названный нейронным машинным переводом. Вскоре после этого нейронный машинный перевод был внедрен во все современные программы машинного перевода.
Кодер и декодер
На рис. 38 показано, что происходит, когда вы используете “Google Переводчик” (и другие современные программы машинного перевода). В примере предложение переводится с английского на французский[254]. Система достаточно сложна, и многое я упростила, но рисунок поможет вам составить представление о главных идеях[255].
Рис. 38. Схема пары сетей “кодер-декодер” для машинного перевода. Белыми прямоугольниками обозначены сеть-кодер и сеть-декодер, работающие пошагово. Входные слова – например, man – сначала преобразуются в контекстные векторы – например, wordvec (man), – а затем вводятся в сеть
В верхней части рис. 38 показана рекуррентная нейронная сеть (сеть-кодер), подобная описанной в предыдущей главе. Предложение на английском – a man went into a restaurant – кодируется на семи последовательных шагах. Белыми прямоугольниками я обозначила процесс кодирования предложения – чуть позже я расскажу, как выглядит сеть внутри этих прямоугольников. На этапе кодирования на каждом шаге последовательности сеть получает входной сигнал в форме контекстного вектора одного слова, как я описывала выше[256]. Пунктирными стрелками от одного шага к следующему обозначены рекуррентные связи в скрытом слое. Получая по одному слову за раз, сеть формирует представление английского предложения, кодируя его активациями скрытых ячеек.