Generative Pre-trained Transformer (GPT). Внутреннее устройство

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

Краткое введение для тех, кто не знаком с устройством нейросетей

Начало развитию трансформеров положила статья Attention Is All You Need («Внимание – все, что вам нужно»). Для того, чтобы в ней разобраться, нужно ввести некоторые ключевые понятия:

  • кодировщик (encoder; та часть нейросети, которая получает на вход данные из реального мира – в нашем случае, текст – и преобразует в матрицу с числами, с которыми работает затем нейросеть);
  • декодировщик (decoder; преобразуют матрицы в человекочитаемый формат: текст / картинку / звук и т.д.);
  • внимание (attention; система весов, которая указывает нейросети на то, какая часть информации важнее; например, какие из слов в предложении важнее для понимания его смысла);
  • обратные связи (recurrence; «обычные» или линейные нейросети передают информацию от одного слоя к другому: выход слоя 1 – это вход слоя 2, выход слоя 2 – вход слоя 3; рекуррентные нейросети до определенного момента «запоминают» предыдущие состояния: на слой 3 получает на вход не только выход слоя 2, но и выход слоя 1 (здесь есть некоторое упрощение, но прямо сейчас нам его вполне достаточно));
  • свертка (convolution; механизм, который определенным образом меняет размер матрицы, передаваемой между слоями нейросети: например, из матрицы 9х9 делает матрицу 3х3, сохраняя наиболее важную информацию, и передает дальше).

Нейросеть состоит из слоев: входного (он получает данные из реального мира), выходного (он возвращает результаты работы нейросети) и какого-то числа скрытых слоев, которые совершают преобразования.
Механизмы свертки и обратной связи вводились для того, чтобы улучшить качество результатов работы нейросети.
Небольшой пример: у нас есть фотографии кошек и собак, и мы хотим, чтобы нейросеть нам определила кто есть кто. Алгоритм ее работы будет следующим:
1. На вход передается фотография. Она преобразуется в матрицу чисел (например, 256х256), где каждое число – это значение яркости пикселя от 0 до 255 (допустим, у нас только черно-белые фотографии).
2. Внутри нейросети матрица, например, умножается на другую матрицу меньшего размера (фильтр), чтобы выявить наличие определенных паттернов (таких как горизонтальные или вертикальные линии, круги и др.), затем на другую матрицу – чтобы выявить наличие других паттернов и так далее.
3. На основании собранных паттернов нейросеть делает вывод о том, что на фотографии с большей вероятностью изображена собака (в процессе обучения нейросеть «запоминает», какие паттерны более характерны для кошек, а какие – для собак, а теперь использует их, чтобы классифицировать результат).

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

Внимание – все, что вам нужно

Так вот, авторы статьи про внимание предложили на тот момент революционную архитектуру нейросетей, которая состоит из кодировщика, декодировщика, механизмов внимания – и всё. Они назвали архитектуру «Трансформер» и показали, что она отлично справляется с разными задачами лучше, чем другие существующие на тот момент модели, но не требует столь же длительного времени обучения.

В деталях архитектура Трансформера представлена на схеме ниже.


<i>(Архитектура Трансформера, схема взята из статьи ‘Attention Is All You Need’)</i>
(Архитектура Трансформера, схема взята из статьи ‘Attention Is All You Need’)

На вход Трансформер получает текст и преобразует его в векторный формат (как мы обсуждали выше с фотографиями, только в числа по определенным правилам преобразуются слова) – это работа кодировщика. «Positional encoding» – это кодирование, которое учитывает позицию каждого слова в предложении. Трансформер по умолчанию не учитывает порядок слов, поэтому, после того как каждое слово преобразуется в вектор, к нему еще добавляется значение, которое отражает его позицию в предложении. То есть, слова после обработки могут быть перемешаны, но модель «запомнит», кто на каком месте стоял.
Дальше у кодировщика есть еще N слоев, которые состоят из одинаковых компонентов (в статье их по шесть и в кодировщике, и в декодировщике, но в разных реализациях число может быть другое):

  • механизм внимания (почему у него несколько голов, позже разберемся);
  • «обычная» нейросеть, в которой информация передается от слоя к слою только в одном направлении (без обратных связей и запоминания предшествующих преобразований);
  • слой нормализаций, который нужен для стабильности (он преобразует выход, полученный из предшествующего слоя – в нашем случае последнего слоя «обычной» нейросети – так, чтобы с этим выходом потом было удобно работать на следующем слое).

У декодировщика похожая структура, как можно заметить по схеме, только у него помимо простого механизма внимания используется еще маскированный механизм. Выход декодировщика – последовательность, которая потом будет преобразована в текст. Текст генерируется примерно так:

  • начинаем с передачи модели токена <start> (на схеме написано, что вход декодировщика «смещен вправо» – это и значит, что в начало добавили токен <start>);
  • модель генерирует слово «кошка»;
  • модель смотрит на слово «кошка» и предполагает, что наиболее вероятное следующее слово – «сидит»;
  • модель смотрит на фразу «кошка сидит» и предполагает, что следующее наиболее вероятное слово – «на»;
  • затем «кошка сидит на» -> «диване».

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

Здесь я привожу пример со словами, но вообще выход декодировщика – вероятности слов (что показано на схеме). А потом уже исходя из вероятностей выбирается конкретное слово, как в примере.

Теперь разберемся, почему внимание на схеме «Multi-Head», то есть почему у него несколько голов. Если коротко, потому что несколько голов могут параллельно фокусироваться на разных частях предложения, что позволит им уловить смысловые нюансы. Например, в нашем предложении «кошка сидит на диване» одна голова может обратить внимание на то, что слово «кошка» связано определенным отношением со словом «диван» и присвоить этой паре больший вес. Другая голова присвоит больший вес паре «сидит» и «диван». Обе связи важны для понимания контекста; имея больше голов, трансформер может собрать больше таких связей и составить комплексное понимание того, что получил на входе. Кроме того, есть слова, которые в разных контекстах имеют разный смысл. Например, в предложениях «Маша взмахнула длинной косой» и «косарь взмахнул острой косой» слово «коса» имеет разные значения. А если еще показать модели предложение «Саня должен мне косарь», она точно без дополнительных голов не разберется.

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

Собственно, GPT

Чтобы сформировать полное представление о GPT, осталось понять ту часть, которая Generative Pre-trained. Generative Pre-Training («генеративное предобучение») – это процесс обучения модели на огромном массиве текстов для того, чтобы модель запомнила правила грамматики, принципы взаимодействия между объектами в реальном мире и прочие общие идеи. После предобучения ее можно будет дообучить уже для решения конкретной задачи (например, классификации текстов), используя массив данных поменьше (и значительно меньше вычислительных мощностей). Идею генеративного предобучения для трансформеров изложили в статье «Improving Language Understanding by Generative Pre-Training» («Улучшение понимания текста с помощью генеративного предобучения») создатели ChatGPT (хотя первые работы, связанные с предобучением разных нейросетей, появились раньше). Именно на нее я буду опираться в этой части.

Авторы предложили комбинированный подход: предобучение без учителя (то есть, без «правильных ответов»; модель получает большой массив текстов, и сама находит в них взаимосвязи) и дообучение («fine-tuning») с учителем (с ответами; модель получает и вход, и выход, который должен получиться, на основании чего дорабатывает найденные ранее закономерности). Этот подход называется «обучение с частичным привлечением учителя» (semi-supervised learning).
Они используют архитектуру, состоящую только из декодировщика (в этом нет ничего странного, не все трансформеры используют и кодировщик, и декодировщик; пример модели только с кодировщиком – BERT; пример модели, которая включает в себя и то, и другое – T5). Исключение из архитектуры кодировщика сделало модель легче и эффективнее, но на способность модели понимать текст не повлияло. Как мы ранее убедились, кодировщик и декодировщик имеют очень похожую структуру, только декодировщик использует маскированное внимание. Все остальное: преобразование в векторы, запоминание позиции слов в предложении – сохраняется.

Кроме того, архитектуру GPT сделали универсальной, добавив дополнительное преобразование для получаемых на вход данных. Дело в том, что для некоторых задач, например, ответов на вопросы, текст нужно специальным образом структурировать: разделить вопрос и предполагаемый ответ, а предобучение проводилось на неразделенных последовательностях (просто массивы текстов). Чтобы модель могла обработать структурированную информацию, ее объединяют с помощью специальных токенов. Например, вместо того, чтобы передавать отдельно вопрос и ответ, передают строку «вопрос <SEP> ответ», где <SEP> – это разделяющий токен. Таким образом, не нужно менять архитектуру модели под каждую новую задачу, достаточно немного видоизменить подаваемый на вход текст, подставив в нужные места подходящие разделители. Есть, например, такие (и не только):

  • <start> – это мы видели; токен, который обозначает начало предложения;
  • <end> – соответственно, токен для конца предложения;
  • <sep> – разделитель;
  • <mask> – токен, который указывает на пропуск другого токена (например, когда задача состоит в том, чтобы угадать пропущенное слово: «кошка <mask> на диване»).

Таким образом получилось не только повысить эффективность работы модели с разными задачами после дообучения, но и научить модель решать задачи без дополнительной тренировки («Zero-shot Behavior»). Это значит, что можно провести предобучение на большом массиве данных, а потом просто сходу дать задачу. И модель справится, потому что она запомнила основные закономерности создания текстов.

Заключение

Я надеюсь, что после прочтения этого текста вам стало легче, а не сложнее жить. Разбирать устройство нейросетей, особенно если у вас нет релевантного опыта, непросто, но оно того стоит. Чем больше вы понимаете, тем меньше будете подвержены иллюзиям и мифам, тем эффективнее сможете использовать ИИ в своей работе и жизни.
Если вы как раз такой человек, который начал разбираться в нейронках без математического бэкграунда, пожалуйста, поделитесь статьями, книгами, видео – любыми источниками, которые вам показались понятными и полезными. Думаю, другие читатели будут вам признательны.

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

1
1 комментарий

те кто интересуется темой уже достаточно глубоко сидят в этом д...ме, а те кто нет, тем и не нужно

Ответить