Что делает ChatGPT ... и почему это работает?

МЕНЮ


Главная страница
Поиск
Регистрация на сайте
Помощь проекту
Архив новостей

ТЕМЫ


Новости ИИРазработка ИИВнедрение ИИРабота разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика

Авторизация



RSS


RSS новости


Это просто добавление одного слова за раз

То, что ChatGPT может автоматически генерировать что-то, что читается даже внешне как текст, написанный человеком, замечательно и неожиданно. Но как он это делает? И почему это работает? Моя цель здесь - дать приблизительное представление о том, что происходит внутри chatgpt , а затем исследовать, почему он может так хорошо создавать то, что мы могли бы счесть осмысленным текстом. С самого начала я должен сказать, что собираюсь сосредоточиться на общей картине происходящего и хотя я упомяну некоторые технические детали, я не буду углубляться в них. (И суть того, что я скажу, применима так же хорошо к другим текущим “большим языковым моделям” [LLM], как и к ChatGPT.)

Первое, что нужно объяснить, это то, что ChatGPT всегда принципиально пытается сделать, это создать “разумное продолжение” любого текста, который у него есть на данный момент, где под “разумным” мы подразумеваем “то, что можно было бы ожидать от кого-то написать после просмотра того, что люди написали на миллиардах веб-страниц и т.д.".”

Итак, допустим, у нас есть текст “Самое лучшее в ИИ - это его способность”. Представьте, что вы сканируете миллиарды страниц текста, написанного человеком (скажем, в Интернете и в оцифрованных книгах), и находите все экземпляры этого текста , а затем смотрите, какое слово идет следующим, какую долю времени. ChatGPT эффективно делает что-то подобное, за исключением того, что (как я объясню) он не просматривает буквальный текст; он ищет вещи, которые в определенном смысле “совпадают по смыслу”. Но конечным результатом является то, что он создает ранжированный список слов, которые могут следовать за ним, вместе с “вероятностями”.:

И примечательно то, что когда ChatGPT делает что-то вроде написания эссе, то, по сути, он просто спрашивает снова и снова: “Учитывая текст на данный момент, каким должно быть следующее слово?” и каждый раз добавляет слово. (Точнее, как я объясню, это добавление “токена”, который может быть просто частью слова, вот почему он иногда может “составлять новые слова”.)

Но, хорошо, на каждом шаге он получает список слов с вероятностями. Но какой из них он должен выбрать на самом деле, чтобы добавить к эссе (или чему-то еще), которое он пишет? Можно было бы подумать, что это должно быть слово с “самым высоким рейтингом” (т.е. то, которому была присвоена самая высокая “вероятность”). Но вот тут-то и начинает вкрадываться немного вудуизма. Потому что по какой-то причинев возможно, однажды у нас будет научное понимание если мы всегда выбираем слово с наивысшим рейтингом, мы обычно получаем очень “плоское” эссе, в котором, кажется, никогда не “проявляется никакой креативности” (и даже иногда повторяется слово в слово). Но если иногда (наугад) мы выбираем слова с более низким рейтингом, мы получаем “более интересное” эссе.

Тот факт, что здесь присутствует случайность, означает, что если мы будем использовать одно и то же приглашение несколько раз, то, скорее всего, каждый раз получим разные эссе. И, в соответствии с идеей voodoo, существует особый так называемый параметр “температура”, который определяет, как часто будут использоваться слова с более низким рейтингом, и для создания эссе оказывается, что “температура” 0,8 кажется лучшей. (Стоит подчеркнуть, что здесь не используется никакая “теория”; это просто вопрос того, что, как было установлено, работает на практике. И, например, понятие “температура” существует потому, что используются экспоненциальные распределения, знакомые из статистической физики, но “физической” связи нет, по крайней мере, насколько нам известно.)

Прежде чем мы продолжим, я должен объяснить, что для целей изложения я в основном не собираюсь использовать полную систему, которая есть в ChatGPT; вместо этого я обычно работаю с более простой системой GPT-2, которая имеет приятную особенность в том, что она достаточно мала, чтобы ее можно было запускать на стандартном настольном компьютере.. И поэтому практически для всего, что я показываю, я смогу включить явный код на языке Wolfram, который вы сможете немедленно запустить на своем компьютере. (Нажмите здесь на любую картинку, чтобы скопировать код, стоящий за ней.)

Например, вот как получить приведенную выше таблицу вероятностей. Во-первых, мы должны извлечь базовую нейронную сеть “языковой модели”:

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

Это берет этот результат и превращает его в явно отформатированный “набор данных”.:”:

Вот что произойдет, если многократно “применить модель” на каждом шаге, добавляя слово, имеющее наибольшую вероятность (указанное в этом коде как "решение" из модели):

Что произойдет, если кто-то продержится дольше? В этом случае (“нулевая температура”) то, что вскоре получается, становится довольно запутанным и повторяющимся:

Но что, если вместо того, чтобы всегда выбирать “верхнее” слово, иногда случайным образом выбираются “не топовые” слова (при этом “случайность” соответствует “температуре” 0,8)? Опять же, можно создать текст:

И каждый раз, когда кто-то делает это, будут сделаны разные случайные выборы, и текст будет другим, как в этих 5 примерах:

Стоит отметить, что даже на первом шаге существует множество возможных “следующих слов” на выбор (при температуре 0.8), хотя их вероятности довольно быстро падают (и, да, прямая линия на этом логарифмическом графике соответствует степени n ?"1"-закон” (это очень характерно для общей статистики языка):):

Так что же произойдет, если кто-то продержится дольше? Вот случайный пример. Это лучше, чем вариант с верхним словом (нулевая температура), но все равно в лучшем случае немного странно:

Это было сделано с помощью простейшей модели GPT-2 (с 2019 года). С новыми и более крупными моделями GPT-3 результаты получаются лучше. Вот текст с первым словом (нулевая температура), созданный с помощью той же “подсказки”, но с самой большой моделью GPT-3:

И вот случайный пример при “температуре 0.8”:

Откуда берутся Вероятности?

Хорошо, итак, ChatGPT всегда выбирает свое следующее слово, основываясь на вероятностях. Но откуда берутся эти вероятности? Давайте начнем с более простой проблемы. Давайте рассмотрим генерацию английского текста по одной букве (а не слову) за раз. Как мы можем рассчитать, какой должна быть вероятность для каждой буквы?

Самое минимальное, что мы могли бы сделать, - это просто взять образец английского текста и подсчитать, как часто в нем встречаются разные буквы. Так, например, это подсчитывает буквы в статье Википедии о “кошках”.:

И это делает то же самое для “собак”.:

Результаты похожи, но не одинаковы (буква “о”, без сомнения, чаще встречается в статье “собаки”, потому что, в конце концов, она встречается в самом слове “собака”). Тем не менее, если мы возьмем достаточно большую выборку текста на английском языке, мы можем ожидать, что в конечном итоге получим, по крайней мере, достаточно последовательные результаты:

Вот пример того, что мы получим, если просто сгенерируем последовательность букв с такими вероятностями:

Мы можем разбить это на “слова”, добавив пробелы, как если бы они были буквами с определенной вероятностью:

Мы можем немного лучше справиться с созданием “слов”, приведя распределение “длин слов” в соответствие с тем, что оно есть в английском языке:

Так получилось, что мы не получили здесь никаких “реальных слов”, но результаты выглядят немного лучше. Однако, чтобы пойти дальше, нам нужно сделать больше, чем просто выбрать каждую букву отдельно наугад. И, например, мы знаем, что если у нас есть “q”, то следующей буквой в принципе должна быть “u”.

Вот график вероятностей для отдельных букв:

А вот график, который показывает вероятности пар букв (“2 грамма”) в типичном английском тексте. Возможные первые буквы показаны поперек страницы, вторые буквы - внизу страницы:

И мы видим здесь, например, что столбец “q” пуст (нулевая вероятность), за исключением строки “u”. Хорошо, итак, теперь вместо того, чтобы генерировать наши “слова” по одной букве за раз, давайте сгенерируем их, рассматривая по две буквы за раз, используя эти “2-граммовые” вероятности. Вот пример результата , который случайно включает в себя несколько “реальных слов”.:

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

Но давайте теперь предположим более или менее так, как это делает ChatGPT”, что мы имеем дело с целыми словами, а не с буквами. В английском языке насчитывается около 40 000 достаточно часто используемых слов. И, просмотрев большой корпус английского текста (скажем, несколько миллионов книг, в общей сложности несколько сотен миллиардов слов), мы можем получить оценку того, насколько распространено каждое слово. И используя это, мы можем начать генерировать “предложения”, в которых каждое слово независимо выбирается случайным образом, с той же вероятностью, с какой оно появляется в корпусе. Вот пример того, что мы получаем:

Неудивительно, что это чепуха. Итак, как мы можем сделать лучше? Так же, как и в случае с буквами, мы можем начать принимать во внимание не только вероятности для отдельных слов, но и вероятности для пар или более длинных n-граммов слов. Делая это для пар, вот 5 примеров того, что мы получаем, во всех случаях начиная со слова “кошка”.:

Это становится немного более “разумно выглядящим”. И мы могли бы представить, что если бы мы могли использовать достаточно длинные n-граммы, мы бы в основном “получили ChatGPT” в том смысле, что мы получили бы что-то, что генерировало бы последовательности слов длиной в эссе с “правильными общими вероятностями эссе”. Но вот в чем проблема: просто не существует даже близко достаточного количества текста на английском языке, который когда-либо был написан, чтобы иметь возможность вывести эти вероятности.

При сканировании Сети может содержаться несколько сотен миллиардов слов; в книгах, которые были оцифрованы, может быть еще сто миллиардов слов. Но при 40 000 общих слов даже количество возможных 2-граммов уже составляет 1,6 миллиарда , а количество возможных 3-граммов составляет 60 триллионов. Таким образом, мы никак не можем оценить вероятности даже для всего этого из текста, который там есть. И к тому времени, когда мы добираемся до “фрагментов эссе” из 20 слов, количество возможностей больше, чем количество частиц во Вселенной, так что в некотором смысле все они никогда не смогут быть записаны.

Итак, что мы можем сделать? Большая идея состоит в том, чтобы создать модель, которая позволяет нам оценивать вероятности, с которыми должны встречаться последовательности , даже если мы никогда явно не видели эти последовательности в корпусе текста, который мы просмотрели. И в основе ChatGPT лежит именно так называемая “модель большого языка” (LLM), которая была создана для того, чтобы хорошо оценивать эти вероятности.

Что такое модель?

Допустим, вы хотите знать (как это сделал Галилей еще в конце 1500-х годов), сколько времени потребуется пушечному ядру, сброшенному с каждого этажа Пизанской башни, чтобы упасть на землю. Ну, вы могли бы просто измерить это в каждом конкретном случае и составить таблицу результатов. Или вы могли бы сделать то, что является сутью теоретической науки: создать модель, которая дает какую-то процедуру для вычисления ответа, а не просто измерять и запоминать каждый случай.

Давайте представим, что у нас есть (несколько идеализированные) данные о том, сколько времени требуется пушечному ядру, чтобы упасть с разных этажей:

Как нам выяснить, сколько времени потребуется, чтобы упасть с пола, о котором у нас явно нет данных? В данном конкретном случае мы можем использовать известные законы физики, чтобы решить это. Но допустим, все, что у нас есть, - это данные, и мы не знаем, какие основополагающие законы ими управляют. Тогда мы могли бы сделать математическое предположение, например, что, возможно, нам следует использовать прямую линию в качестве модели:

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

Как мы догадались попробовать использовать здесь прямую линию? На каком-то уровне мы этого не сделали. Это просто что-то математически простое, и мы привыкли к тому, что множество данных, которые мы измеряем, оказывается, хорошо согласуются с математически простыми вещами. Мы могли бы попробовать что-то математически более сложное скажем, a + b x + c x2 , и тогда в этом случае у нас получится лучше:

Однако все может пойти совсем не так, как надо. Например, вот лучшее, что мы можем сделать с a + b / x + c sin(x):):

Стоит понимать, что никогда не бывает “модели без модели”. Любая модель, которую вы используете, имеет некоторую определенную базовую структуру , затем определенный набор “ручек, которые вы можете поворачивать” (т.е. параметры, которые вы можете установить), чтобы они соответствовали вашим данным. И в случае с ChatGPT используется множество таких “ручек" На самом деле их 175 миллиардов.

Но примечательно то, что базовая структура chatgpt с “всего лишь” таким количеством параметров достаточна для создания модели, которая вычисляет вероятности следующего слова “достаточно хорошо”, чтобы дать нам фрагменты текста разумной длины для эссе.

Модели для человекоподобных задач

Пример, который мы привели выше, включает в себя создание модели для числовых данных, которая, по сути, исходит из ”простой физики“, где мы уже несколько столетий знаем, что "применяется простая математика". Но для ChatGPT мы должны создать модель текста на человеческом языке, подобного тому, который создается человеческим мозгом. И для чего-то подобного у нас нет (по крайней мере пока) ничего похожего на “простую математику”. Итак, на что могла бы быть похожа его модель?

Прежде чем мы поговорим о языке, давайте поговорим о другой задаче, подобной человеческой: распознавании образов. И в качестве простого примера этого давайте рассмотрим изображения цифр (и, да, это классический пример машинного обучения).:

Единственное, что мы могли бы сделать, это получить кучу образцов изображений для каждой цифры:

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

Когда мы создали модель для наших числовых данных выше, мы смогли взять числовое значение x, которое нам было дано, и просто вычислить a + b x для конкретных a и b. Итак, если мы рассматриваем значение уровня серого каждого пикселя здесь как некоторую переменную xi, существует ли какая-то функция все те переменные, которые при оценке говорят нам, из какой цифры состоит изображение? Оказывается, что такую функцию можно сконструировать. Неудивительно, однако, что это не особенно просто. И типичный пример может включать, возможно, полмиллиона математических операций.

Но конечным результатом является то, что если мы передадим коллекцию значений пикселей для изображения в эту функцию, то выйдет число, указывающее, из какой цифры у нас есть изображение. Позже мы поговорим о том, как может быть сконструирована такая функция, и об идее нейронных сетей. Но сейчас давайте рассмотрим функцию как черный ящик, куда мы вводим изображения, скажем, написанных от руки цифр (в виде массивов значений пикселей) и получаем числа, которым они соответствуют:

Но что здесь происходит на самом деле? Допустим, мы постепенно размываем цифру. Некоторое время наша функция все еще “распознает” его, здесь как “2”. Но вскоре он “теряет самообладание” и начинает выдавать “неправильный” результат:

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

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

Можем ли мы “математически доказать”, что они работают? Ну, нет. Потому что для этого у нас должна была бы быть математическая теория того, что мы, люди, делаем. Возьмите изображение “2” и измените несколько пикселей. Мы могли бы представить, что всего несколько пикселей “не на своем месте”, и мы все равно должны считать изображение “2”. Но как далеко это должно зайти? Это вопрос человеческого визуального восприятия. И, да, ответ, без сомнения, был бы другим для пчел или осьминогов и потенциально совершенно другим для предполагаемых инопланетян.

Нейронные сети

Итак, как на самом деле работают наши типичные модели для таких задач, как распознавание изображений? Самый популярный и успешный в настоящее время подход использует нейронные сети. Изобретенные "в форме, удивительно близкой к их сегодняшнему использованию” в 1940-х годах, нейронные сети можно рассматривать как простую идеализацию того, как, по-видимому, работает мозг.

В человеческом мозге насчитывается около 100 миллиардов нейронов (нервных клеток), каждая из которых способна генерировать электрический импульс, возможно, до тысячи раз в секунду. Нейроны соединены в сложную сеть, причем каждый нейрон имеет древовидные ветви, позволяющие ему передавать электрические сигналы, возможно, тысячам других нейронов. И в грубом приближении, производит ли какой-либо данный нейрон электрический импульс в данный момент, зависит от того, какие импульсы он получает от других нейронов с разными соединениями, вносящими вклад с разными "весами".

Когда мы “видим изображение”, происходит следующее: когда фотоны света от изображения попадают на клетки (“фоторецепторы”) в задней части наших глаз, они вырабатывают электрические сигналы в нервных клетках. Эти нервные клетки соединены с другими нервными клетками, и в конечном итоге сигналы проходят через целую последовательность слоев нейронов. И именно в этом процессе мы “распознаем” изображение, в конечном итоге “формируя мысль” о том, что мы “видим двойку” (и, возможно, в конце делаем что-то вроде произнесения слова “два” вслух).

Функция “черного ящика” из предыдущего раздела представляет собой “математизированную” версию такой нейронной сети. Так получилось, что у него 11 слоев (хотя только 4 “основных слоя”).:

В этой нейронной сети нет ничего особенно “теоретически выведенного”; это просто нечто такое, что ”еще в 1998 году” было сконструировано как инженерное произведение и оказалось работоспособным. (Конечно, это не сильно отличается от того, как мы могли бы описать наш мозг как созданный в процессе биологической эволюции.)

Хорошо, но как такая нейронная сеть “распознает вещи”? Ключевым моментом является понятие аттракторов. Представьте, что у нас есть написанные от руки изображения 1 и 2:

Мы каким-то образом хотим, чтобы все 1 “притягивались к одному месту”, а все 2 “притягивались к другому месту”. Или, говоря по-другому, если изображение каким-то образом “ближе к 1”, чем к 2, мы хотим, чтобы оно оказалось на “первом месте”, и наоборот.

В качестве прямой аналогии предположим, что у нас есть определенные позиции на плоскости, обозначенные точками (в реальной обстановке это могут быть позиции кофеен). Тогда мы могли бы представить, что, начиная с любой точки на плоскости, мы всегда хотели бы оказаться в ближайшей точке (т.е. мы всегда ходили бы в ближайшую кофейню). Мы можем представить это, разделив плоскость на области (“бассейны аттракторов”), разделенные идеализированными “водоразделами”.:

Мы можем рассматривать это как реализацию своего рода “задачи распознавания”, в которой мы не выполняем что-то вроде определения того, на какую цифру данное изображение “больше всего похоже” , а скорее мы просто, совершенно непосредственно, видим, к какой точке данная точка ближе всего. (Настройка “Диаграммы Вороного”, которую мы показываем здесь, разделяет точки в двумерном евклидовом пространстве; задачу распознавания цифр можно рассматривать как выполнение чего-то очень похожего , но в 784-мерном пространстве, сформированном из уровней серого всех пикселей на каждом изображении.)

Итак, как нам заставить нейронную сеть “выполнять задачу распознавания”? Давайте рассмотрим этот очень простой случай:

Наша цель состоит в том, чтобы принять “входные данные”, соответствующие позиции {x, y}, а затем “распознать” их как ту из трех точек, к которой они ближе всего. Или, другими словами, мы хотим, чтобы нейронная сеть вычисляла функцию {x,y}, подобную:

Итак, как мы можем сделать это с помощью нейронной сети? В конечном счете, нейронная сеть - это связанная коллекция идеализированных “нейронов”, ”обычно расположенных слоями”, простым примером которых является:

Каждый “нейрон” эффективно настроен на оценку простой числовой функции. И чтобы “использовать” сеть, мы просто вводим числа (например, наши координаты x и y) вверху, затем нейроны на каждом уровне “оценивают свои функции” и передают результаты вперед по сетив", в конечном итоге получая конечный результат внизу:

В традиционной (биологически вдохновленной) настройке каждый нейрон эффективно имеет определенный набор “входящих соединений” от нейронов предыдущего слоя, причем каждому соединению присваивается определенный “вес” (который может быть положительным или отрицательным числом). Значение данного нейрона определяется путем умножения значений “предыдущих нейронов” на их соответствующие веса, затем суммирования их и добавления константыв, наконец, применения функции "порогового значения" ”или "активации"”. В математических терминах, если у нейрона есть входные данные x = {x1, x2 ...}, то мы вычисляем f[w . x + b], где веса w и константа b обычно выбираются по-разному для каждого нейрона в сети; функция f обычно одна и та же.

Вычисление w . x + b - это всего лишь вопрос умножения и сложения матриц. “Функция активации” f вводит нелинейность (и в конечном счете является тем, что приводит к нетривиальному поведению). Обычно используются различные функции активации; здесь мы просто будем использовать Ramp (или ReLU).:

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

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

Нейронная сеть ChatGPT также просто соответствует математической функции, подобной этой, но эффективно с миллиардами терминов.

Но давайте вернемся к отдельным нейронам. Вот несколько примеров функций, которые нейрон с двумя входами (представляющими координаты x и y) может вычислять с различными вариантами весов и констант (и рампой в качестве функции активации).:

Но как насчет более крупной сети сверху? Что ж, вот что он вычисляет:

Это не совсем “правильно”, но близко к функции “ближайшая точка”, которую мы показали выше.

Давайте посмотрим, что происходит с некоторыми другими нейронными сетями. В каждом случае, как мы объясним позже, мы используем машинное обучение, чтобы найти наилучший выбор весов. Затем мы показываем здесь, что вычисляет нейронная сеть с этими весами:

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

С помощью этой простой “задачи распознавания” в математическом стиле становится ясно, каков “правильный ответ”. Но в проблеме распознавания рукописных цифр все не так однозначно. Что, если кто-то написал “2” так плохо, что это выглядело как “7” и т.д.? Тем не менее, мы можем спросить, как нейронная сеть различает цифры, и это дает представление:

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

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

Теперь еще менее ясно, каков “правильный ответ”. Как насчет собаки, одетой в кошачий костюм? И т.д. Какие бы входные данные ей ни были предоставлены, нейронная сеть генерирует ответ. И, оказывается, делать это таким образом, который разумно согласуется с тем, что могли бы делать люди. Как я уже говорил выше, это не факт, что мы можем “исходить из первых принципов”. Это просто то, что эмпирически было признано истинным, по крайней мере, в определенных областях. Но это ключевая причина, по которой нейронные сети полезны: они каким-то образом улавливают “человеческий” способ ведения дел.

Покажите себе фотографию кошки и спросите: “Почему это кошка?”. Может быть, вы бы начали говорить: “Ну, я вижу его заостренные уши и т.д.” Но не очень легко объяснить, как вы распознали в изображении кошку. Просто каким-то образом твой мозг это понял. Но для мозга нет способа (по крайней мере, пока) “заглянуть внутрь” и посмотреть, как он это понял. Как насчет (искусственной) нейронной сети? Что ж, легко увидеть, что делает каждый “нейрон”, когда вы показываете картинку кошки. Но даже получить базовую визуализацию обычно очень сложно.

В конечной сети, которую мы использовали для задачи “ближайшая точка” выше, имеется 17 нейронов. В сети для распознавания рукописных цифр их насчитывается 2190. А в сети, которую мы используем для распознавания кошек и собак, их 60 650. Обычно было бы довольно трудно визуализировать то, что составляет 60 650-мерное пространство. Но поскольку это сеть, созданная для работы с изображениями, многие из ее слоев нейронов организованы в массивы, подобные массивам пикселей, на которые она смотрит.

И если мы возьмем типичный образ кошки

Cat

затем мы можем представить состояния нейронов на первом слое набором производных изображений , многие из которых мы можем легко интерпретировать как что-то вроде “кошки без фона” или “контура кошки”.:

By the 10th layer it’s harder to interpret what’s going on:

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

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

Но давайте предположим, что нам нужна “теория распознавания кошек” в нейронных сетях. Мы можем сказать: “Смотрите, эта конкретная сеть делает это ” , и это сразу же дает нам некоторое представление о том, “насколько это сложная проблема” (и, например, сколько нейронов или слоев может потребоваться). Но, по крайней мере, на данный момент у нас нет способа “дать повествовательное описание” того, что делает сеть. И, возможно, это потому, что он действительно вычислительно неприводим, и нет общего способа найти, что он делает, кроме как явно отслеживая каждый шаг. Или, может быть, дело просто в том, что мы еще не “разобрались в науке” и не определили “естественные законы”, которые позволяют нам обобщить происходящее.

Мы столкнемся с теми же проблемами, когда будем говорить о создании языка с помощью ChatGPT. И снова неясно, существуют ли способы “обобщить то, что он делает”. Но богатство и детализация языка (и наш опыт работы с ним) могут позволить нам продвинуться дальше, чем с изображениями.

Машинное обучение и обучение нейронных сетей

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

Когда мы создаем нейронную сеть, чтобы отличать кошек от собак, нам фактически не нужно писать программу, которая (скажем) явно находит усы; вместо этого мы просто показываем множество примеров того, что такое кошка и что такое собака, а затем заставляем сеть “машинно учиться” на них, как отличать они.

И дело в том, что обученная сеть “обобщает” конкретные примеры, которые она показывает. Точно так же, как мы видели выше, дело не просто в том, что сеть распознает конкретный рисунок пикселей на примере изображения кошки, которое было показано; скорее, нейронной сети каким-то образом удается различать изображения на основе того, что мы считаем своего рода ”общей кошачьей схожестью".

Итак, как на самом деле работает обучение нейронной сети? По сути, то, что мы всегда пытаемся сделать, - это найти веса, которые позволят нейронной сети успешно воспроизводить приведенные нами примеры. И затем мы полагаемся на нейронную сеть, чтобы “интерполировать” (или “обобщать”) “между” этими примерами “разумным” способом.

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

Для этой задачи нам понадобится сеть, имеющая только один вход и один выход, например:

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

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

Основная идея состоит в том, чтобы предоставить множество примеров “ввод -> вывод” для “изучения”, а затем попытаться найти веса, которые будут воспроизводить эти примеры. Вот результат выполнения этого с постепенно увеличивающимся количеством примеров:

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

Чтобы выяснить, “как далеко мы находимся”, мы вычисляем то, что обычно называется “функцией потерь” (или иногда “функцией затрат”). Здесь мы используем простую функцию потерь (L2), которая представляет собой просто сумму квадратов разностей между полученными нами значениями и истинными значениями. И что мы видим, так это то, что по мере продвижения нашего процесса обучения функция потерь постепенно уменьшается (следуя определенной “кривой обучения”, которая отличается для разных задач) пока мы не достигнем точки, где сеть (по крайней мере, в хорошем приближении) успешно воспроизводит нужную нам функцию.:

Хорошо, итак, последняя важная часть, которую нужно объяснить, - это то, как корректируются веса для уменьшения функции потерь. Как мы уже говорили, функция потерь дает нам “расстояние” между полученными нами значениями и истинными значениями. Но “значения, которые мы получили”, определяются на каждом этапе текущей версией нейронной сети и весами в ней. Но теперь представьте, что веса являются переменными , - скажем, wi. Мы хотим выяснить, как настроить значения этих переменных, чтобы минимизировать потери, которые от них зависят.

Например, представьте (в невероятном упрощении типичных нейронных сетей, используемых на практике), что у нас есть всего два веса w1 и w2. Тогда у нас может возникнуть потеря, которая в зависимости от w1 и w2 выглядит следующим образом:

Численный анализ предоставляет множество методов для нахождения минимума в подобных случаях. Но типичный подход заключается в том, чтобы просто постепенно следовать по пути самого крутого спуска от любого предыдущего w1, w2, который у нас был:

Подобно воде, стекающей с горы, гарантируется только то, что эта процедура закончится на некотором локальном минимуме поверхности (“горное озеро”); вполне возможно, что она не достигнет конечного глобального минимума.

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

На рисунке выше показан вид минимизации, который нам, возможно, потребуется выполнить в нереально простом случае всего с 2 весами. Но оказывается, что даже при гораздо большем количестве весов (ChatGPT использует 175 миллиардов) все еще возможно выполнить минимизацию, по крайней мере, до некоторого уровня приближения. И на самом деле большой прорыв в “глубоком обучении”, произошедший примерно в 2011 году, был связан с открытием того, что в некотором смысле может быть проще выполнить (по крайней мере, приблизительную) минимизацию, когда задействовано много весов, чем когда их довольно мало.

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

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

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

Но какой из них “правильный”? На самом деле нет никакого способа сказать. Все они “согласуются с наблюдаемыми данными”. Но все они соответствуют разным “врожденным” способам “думать о том”, что делать “нестандартно”. И некоторые из них могут показаться нам, людям, “более разумными”, чем другие.

Практика и знания по обучению нейронной сети

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

Есть несколько ключевых частей. Во-первых, возникает вопрос о том, какую архитектуру нейронной сети следует использовать для конкретной задачи. Тогда возникает критический вопрос о том, как получить данные, на основе которых можно обучать нейронную сеть. И все чаще приходится иметь дело не с обучением сети с нуля: вместо этого новая сеть может либо напрямую включать другую уже обученную сеть, либо, по крайней мере, может использовать эту сеть для создания большего количества обучающих примеров для себя.

Можно было бы подумать, что для каждого конкретного вида задач потребуется разная архитектура нейронной сети. Но что было обнаружено, так это то, что одна и та же архитектура часто, кажется, работает даже для, казалось бы, совершенно разных задач. На каком-то уровне это напоминает идею универсальных вычислений (и мой принцип вычислительной эквивалентности), но, как я расскажу позже, я думаю, что это скорее отражение того факта, что задачи, которые мы обычно пытаемся заставить нейронные сети выполнять, являются “человекоподобными” и нейронные сети могут улавливать довольно общие ”человекоподобные процессы".

В первые дни существования нейронных сетей существовала тенденция к тому, что следует “заставить нейронную сеть делать как можно меньше”. Например, при преобразовании речи в текст считалось, что сначала следует проанализировать аудиозапись речи, разбить ее на фонемы и т.д. Но было обнаружено, что, по крайней мере, для “человекоподобных задач” обычно лучше просто попытаться обучить нейронную сеть “сквозной задаче”, позволив ей “обнаружить” необходимые промежуточные функции, кодировки и т.д. для себя.

Также была идея о том, что следует ввести в нейронную сеть сложные отдельные компоненты, чтобы позволить ей фактически “явно реализовывать определенные алгоритмические идеи”. Но опять же, в основном это оказалось бесполезным; вместо этого лучше просто иметь дело с очень простыми компонентами и позволить им “организоваться” (хотя обычно способами, которые мы не можем понять), чтобы достичь (предположительно) эквивалента этих алгоритмических идей.

Это не значит, что не существует “структурирующих идей”, которые имеют отношение к нейронным сетям. Таким образом, например, наличие 2D-массивов нейронов с локальными соединениями кажется, по крайней мере, очень полезным на ранних стадиях обработки изображений. И наличие шаблонов подключения, которые концентрируются на “оглядывании назад в последовательностях”, кажется полезнымв, как мы увидим позже, имея дело с такими вещами, как человеческий язык, например, в ChatGPT.

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

Но, хорошо, как можно определить, насколько большая нейронная сеть понадобится для конкретной задачи? Это что-то вроде искусства. На каком-то уровне главное - знать, “насколько трудна задача”. Но для задач, похожих на человеческие, это, как правило, очень трудно оценить. Да, может существовать систематический способ выполнить задачу очень “механически” с помощью компьютера. Но трудно сказать, существует ли то, что можно было бы назвать уловками или кратчайшими путями, которые позволяют значительно легче выполнять задачу, по крайней мере, на “человеческом уровне”. Возможно, потребуется перечислить гигантское игровое дерево, чтобы “механически” сыграть в определенную игру; но, возможно, существует гораздо более простой (“эвристический”) способ добиться “игры на человеческом уровне”.

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

И что мы видим, так это то, что если сеть слишком мала, она просто не может воспроизвести нужную нам функцию. Но выше некоторого размера у него нет проблем, по крайней мере, если тренировать его достаточно долго, с достаточным количеством примеров. И, кстати, эти картинки иллюстрируют часть знаний о нейронных сетях: часто можно обойтись сетью меньшего размера, если в середине есть “сжатие”, которое заставляет все проходить через меньшее промежуточное число нейронов. (Также стоит упомянуть, что сети “без промежуточного слоя” или так называемые “персептроны” могут изучать только по существу линейные функции, но как только появляется хотя бы один промежуточный слой, в принципе всегда возможно произвольно хорошо аппроксимировать любую функцию, по крайней мере, если у вас достаточно нейронов, хотя чтобы сделать его посильно обучаемым, обычно требуется какая-то регуляризация или нормализация.)

Хорошо, допустим, кто-то остановился на определенной архитектуре нейронной сети. Теперь возникает проблема получения данных для обучения сети. И многие практические проблемы, связанные с нейронными сетями и машинным обучением в целом, сосредоточены на получении или подготовке необходимых обучающих данных. Во многих случаях (“контролируемое обучение”) хочется получить явные примеры входных данных и результатов, которых от них ожидают. Так, например, можно было бы захотеть, чтобы изображения были помечены тем, что на них находится, или каким-либо другим атрибутом. И, возможно, кому-то придется явно пройти обычно с большими усилиями и сделать пометку. Но очень часто оказывается возможным использовать что-то, что уже было сделано, или использовать это как своего рода прокси. И так, например, можно было бы использовать теги alt, которые были предоставлены для изображений в Интернете. Или, в другом домене, можно было бы использовать закрытые подписи, которые были созданы для видео. Или для обучения языковому переводу можно использовать параллельные версии веб-страниц или других документов, существующих на разных языках.

Сколько данных вам нужно, чтобы показать нейронную сеть, чтобы обучить ее для конкретной задачи? Опять же, это трудно оценить, исходя из первых принципов. Конечно, требования можно значительно снизить, используя “перенос обучения” для “переноса в” такие вещи, как списки важных функций, которые уже были изучены в другой сети. Но, как правило, нейронным сетям нужно “видеть много примеров”, чтобы хорошо тренироваться. И, по крайней мере, для некоторых задач важной частью знаний о нейронных сетях является то, что примеры могут быть невероятно повторяющимися. И действительно, это стандартная стратегия - просто показывать нейронной сети все имеющиеся у нее примеры снова и снова. В каждом из этих “тренировочных раундов” (или “эпох”) нейронная сеть будет находиться, по крайней мере, в немного отличающемся состоянии, и каким-то образом “напоминание ей” о конкретном примере полезно для того, чтобы заставить ее “запомнить этот пример”. (И, да, возможно, это аналогично пользе повторения в человеческом запоминании.)

Но часто простого повторения одного и того же примера снова и снова недостаточно. Также необходимо показать вариации нейронной сети в примере. И особенность знаний о нейронных сетях заключается в том, что эти варианты “увеличения данных” не обязательно должны быть сложными, чтобы быть полезными. Простое изменение изображений с помощью базовой обработки изображений может сделать их практически ”как новенькие" для обучения нейронной сети. И, аналогично, когда у кого-то заканчивается реальное видео и т.д. для обучения самоуправляемых автомобилей можно продолжить и просто получить данные из запущенных симуляций в модельной среде, подобной видеоигре, без всех деталей реальных сцен.

Как насчет чего-то вроде ChatGPT? Что ж, у него есть приятная функция, заключающаяся в том, что он может выполнять “неконтролируемое обучение”, что значительно облегчает поиск примеров для обучения. Напомним, что основная задача ChatGPT - выяснить, как продолжить фрагмент текста, который ему был предоставлен. Итак, чтобы получить это “обучающие примеры”, все, что нужно сделать, это взять фрагмент текста и замаскировать его конец, а затем использовать это как “входные данные для обучения”, а “выходные данные” - это полный, не замаскированный фрагмент текста. Мы обсудим это подробнее позже, но суть в том, что в отличие, скажем, от изучения того, что находится на изображениях, не требуется “явного пометки”; ChatGPT, по сути, может просто учиться непосредственно на любых примерах текста, которые ему предоставлены.

Хорошо, так что же насчет реального процесса обучения в нейронной сети? В конце концов, все дело в определении того, какие веса лучше всего соответствуют приведенным тренировочным примерам. И существуют всевозможные подробные варианты выбора и “настройки гиперпараметров” (называемые так потому, что веса можно рассматривать как “параметры”), которые можно использовать для настройки того, как это делается. Существуют различные варианты функции потерь (сумма квадратов, сумма абсолютных значений и т.д.). Существуют различные способы минимизации потерь (как далеко в весовом пространстве перемещаться на каждом шаге и т.д.). И тогда возникают вопросы вроде того, насколько велика “партия” примеров, которые нужно показать, чтобы получить каждую последующую оценку потерь, которые человек пытается минимизировать. И, да, можно применить машинное обучение (как мы делаем, например, в Wolfram Language) для автоматизации машинного обучения и автоматической настройки таких вещей, как гиперпараметры.

Но, в конце концов, весь процесс обучения можно охарактеризовать, увидев, как потери постепенно уменьшаются (как в этом Wolfram Language progress monitor для небольшого обучения).:

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

Можно ли сказать, сколько времени должно потребоваться для того, чтобы “кривая обучения” выровнялась? Как и для многих других вещей, по-видимому, существуют приблизительные соотношения масштабирования по степенному закону, которые зависят от размера нейронной сети и объема используемых данных. Но общий вывод таков, что обучение нейронной сети - дело сложное и требует больших вычислительных усилий. И на практике подавляющее большинство этих усилий тратится на выполнение операций с массивами чисел, в чем хороши графические процессоры, и именно поэтому обучение нейронных сетей обычно ограничено доступностью графических процессоров.

Будут ли в будущем принципиально лучшие способы обучения нейронных сетей или вообще делать то, что делают нейронные сети? Я думаю, почти наверняка. Фундаментальная идея нейронных сетей заключается в создании гибкой “вычислительной структуры” из большого количества простых (по существу идентичных) компонентов и в том, чтобы эта “структура” была такой, которую можно постепенно модифицировать для обучения на примерах. В современных нейронных сетях, по сути, используются идеи исчисления, применяемые к действительным числам, для выполнения этой инкрементной модификации. Но становится все более очевидным, что наличие высокоточных чисел не имеет значения; 8 бит или меньше может быть достаточно даже при использовании современных методов.

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

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

Но даже в рамках существующих нейронных сетей в настоящее время существует критическое ограничение: обучение нейронной сети в том виде, в каком оно проводится сейчас, является принципиально последовательным, при этом эффекты каждой партии примеров распространяются обратно для обновления весов. И действительно, при современном компьютерном оборудовании, даже с учетом графических процессоров, большая часть нейронной сети большую часть времени “простаивает” во время обучения, при этом обновляется только одна часть за раз. И в некотором смысле это связано с тем, что наши современные компьютеры, как правило, имеют память, отдельную от их процессоров (или графических процессоров-GPU). Но в мозге, по-видимому, все по-другому, поскольку каждый “элемент памяти” (то есть нейрон) также является потенциально активным вычислительным элементом. И если бы мы могли настроить наше будущее компьютерное оборудование таким образом, возможно, стало бы возможным проводить обучение гораздо эффективнее.

“Конечно, Достаточно большая Сеть Может делать Все, Что угодно!”

Возможности чего-то вроде ChatGPT кажутся настолько впечатляющими, что можно было бы представить, что если бы можно было просто “продолжать работать” и обучать все большие и большие нейронные сети, то они в конечном итоге смогли бы “делать все”. И если кого-то интересуют вещи, которые легко доступны непосредственному человеческому мышлению, вполне возможно, что это так. Но урок последних нескольких сотен лет развития науки заключается в том, что есть вещи, которые могут быть выяснены с помощью формальных процессов, но не всегда доступны непосредственному человеческому мышлению.

Нетривиальная математика - один из ярких примеров. Но общий случай - это действительно вычисление. И, в конечном счете, проблема заключается в феномене вычислительной неприводимости. Есть некоторые вычисления, для выполнения которых, как можно было бы подумать, потребуется много шагов, но которые на самом деле могут быть “сведены” к чему-то совершенно немедленному. Но открытие вычислительной неприводимости подразумевает, что это не всегда работает. И вместо этого существуют процессы, вероятно, подобные приведенному ниже, где для определения того, что происходит, неизбежно требуется по существу отслеживать каждый вычислительный шаг:

Виды действий, которые мы обычно делаем с помощью нашего мозга, предположительно, специально выбраны для того, чтобы избежать вычислительной несводимости. Чтобы произвести математические вычисления в своем мозгу, требуются особые усилия. И на практике практически невозможно “продумать” этапы работы любой нетривиальной программы только в своем мозгу.

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

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

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

На практике можно представить, как небольшие вычислительные устройства, такие как клеточные автоматы или машины Тьюринга, превращаются в обучаемые системы, такие как нейронные сети. И действительно, такие устройства могут служить хорошими “инструментами” для нейронной сети, как Wolfram | Alpha может быть хорошим инструментом для ChatGPT. Но вычислительная неприводимость подразумевает, что нельзя ожидать, что можно “проникнуть внутрь” этих устройств и заставить их учиться.

Или, другими словами, существует окончательный компромисс между возможностями и обучаемостью: чем больше вы хотите, чтобы система “по-настоящему использовала” свои вычислительные возможности, тем больше она будет демонстрировать вычислительную неприводимость и тем меньше она будет поддаваться обучению. И чем больше он фундаментально поддается обучению, тем меньше он будет способен выполнять сложные вычисления.

(Для ChatGPT в его нынешнем виде ситуация на самом деле гораздо более экстремальная, потому что нейронная сеть, используемая для генерации каждого выходного токена, представляет собой чистую сеть “прямой связи”, без циклов, и поэтому не имеет возможности выполнять какие-либо вычисления с нетривиальным “потоком управления”.)

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

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

Но во всем этом есть что-то потенциально сбивающее с толку. В прошлом было множество задач, включая написание эссе, которые, как мы предполагали, были каким-то образом “фундаментально слишком сложными” для компьютеров. И теперь, когда мы видим, как это делают такие, как ChatGPT, мы склонны внезапно думать, что компьютеры, должно быть, стали намного мощнее, в частности, превзойдя то, на что они уже были в принципе способны (например, прогрессивное вычисление поведения вычислительных систем, таких как клеточные автоматы).

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

Другими словами, причина, по которой нейронная сеть может быть успешной при написании эссе, заключается в том, что написание эссе оказывается “вычислительно более мелкой” проблемой, чем мы думали. И в некотором смысле это приближает нас к “созданию теории” о том, как нам, людям, удается делать такие вещи, как написание эссе, или вообще иметь дело с языком.

Если бы у вас была достаточно большая нейронная сеть, тогда, да, вы могли бы делать все, что легко могут делать люди. Но вы не смогли бы уловить, на что способен мир природы в целом или что могут делать инструменты, которые мы создали из мира природы. И именно использование этих инструментов, как практических, так и концептуальных, позволило нам в последние столетия выйти за границы того, что доступно “чистой человеческой мысли без посторонней помощи”, и использовать для человеческих целей больше того, что существует в физической и вычислительной вселенной.

Концепция вложений

Нейронные сети, по крайней мере, в том виде, в каком они созданы в настоящее время, в основном основаны на числах. Поэтому, если мы собираемся использовать их для работы с чем-то вроде текста, нам понадобится способ представления нашего текста цифрами. И, конечно, мы могли бы начать (по сути, как это делает ChatGPT) с простого присвоения номера каждому слову в словаре. Но есть важная идея, которая, например, занимает центральное место в ChatGPT и выходит за рамки этого. И это идея ”встраиваний". Можно думать о внедрении как о способе попытаться представить “сущность” чего-либо массивом чисел со свойством, заключающимся в том, что “близлежащие вещи” представлены близлежащими числами.

И так, например, мы можем думать о встраивании слов как о попытке расположить слова в своего рода “пространстве значений”, в котором слова, которые каким-то образом “близки по значению”, появляются рядом во встраивании. Фактические вложения, которые используются, скажем, в ChatGPT, как правило, включают большие списки чисел. Но если мы спроецируем до 2D, мы можем показать примеры того, как слова располагаются с помощью встраивания:

И, да, то, что мы видим, удивительно хорошо передает типичные повседневные впечатления. Но как мы можем сконструировать такое вложение? Грубо говоря, идея состоит в том, чтобы просмотреть большие объемы текста (здесь 5 миллиардов слов из Интернета), а затем посмотреть, “насколько похожи” “среды”, в которых появляются разные слова. Так, например, “аллигатор” и “крокодил” часто будут появляться почти взаимозаменяемо в других похожих предложениях, и это означает, что они будут размещены рядом при внедрении. Но “репа” и “орел”, как правило, не будут появляться в других похожих предложениях, поэтому при внедрении они будут расположены далеко друг от друга.

Но как на самом деле реализовать что-то подобное с помощью нейронных сетей? Давайте начнем с того, что поговорим о встраиваниях не для слов, а для изображений. Мы хотим найти какой-то способ охарактеризовать изображения списками чисел таким образом, чтобы “изображениям, которые мы считаем похожими”, присваивались похожие списки чисел.

Как мы определяем, следует ли нам “рассматривать изображения похожими”? Что ж, если наши изображения состоят, скажем, из рукописных цифр, мы могли бы “считать два изображения похожими”, если они имеют одну и ту же цифру. Ранее мы обсуждали нейронную сеть, которая была обучена распознавать написанные от руки цифры. И мы можем представить, что эта нейронная сеть настроена таким образом, что в своем конечном выводе она помещает изображения в 10 различных ячеек, по одной для каждой цифры.

Но что, если мы “перехватим” то, что происходит внутри нейронной сети, до того, как будет принято окончательное решение “это ”4""? Мы могли бы ожидать, что внутри нейронной сети есть числа, которые характеризуют изображения как “в основном похожие на 4, но немного похожие на 2” или что-то в этом роде. И идея состоит в том, чтобы подобрать такие числа для использования в качестве элементов во внедрении.

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

Итак, как более подробно это работает для сети распознавания цифр? Мы можем представить сеть как состоящую из 11 последовательных слоев, которые мы могли бы обобщить в виде иконки следующим образом (с функциями активации, показанными в виде отдельных слоев):

Вначале мы загружаем в первый слой фактические изображения, представленные 2D-массивами значений пикселей. И в конце из последнего слоя мы получаем массив из 10 значений, которые, как мы можем думать, говорят о том, “насколько уверена” сеть в том, что изображение соответствует каждой из цифр от 0 до 9.

Подача в изображении и значения нейронов в этом последнем слое равны:

Другими словами, нейронная сеть к этому моменту “невероятно уверена”, что это изображение является 4, и чтобы действительно получить результат “4”, нам просто нужно выбрать положение нейрона с наибольшим значением.

Но что, если мы заглянем на шаг раньше? Самая последняя операция в сети - это так называемый softmax, который пытается “принудить к определенности”. Но до того, как это было применено, значения нейронов равны:

Нейрон, представляющий “4”, по-прежнему имеет наибольшее числовое значение. Но есть также информация в значениях других нейронов. И мы можем ожидать, что этот список чисел в некотором смысле может быть использован для характеристики “сути” изображения и, таким образом, для предоставления чего-то, что мы можем использовать в качестве встраивания. И так, например, каждый из 4-х здесь имеет немного иную “подпись” (или “встраивание функций”), сильно отличающуюся от 8-х:

Здесь мы, по сути, используем 10 чисел для характеристики наших изображений. Но часто лучше использовать гораздо больше, чем это. И, например, в нашей сети распознавания цифр мы можем получить массив из 500 чисел, нажав на предыдущий слой. И это, вероятно, разумный массив для использования в качестве “встраивания изображения”.

Если мы хотим создать явную визуализацию “пространства изображений” для рукописных цифр, нам нужно “уменьшить размерность”, эффективно проецируя 500-мерный вектор, который у нас есть, скажем, в 3D-пространство:

Мы только что говорили о создании характеристики (и, следовательно, внедрении) для изображений, эффективно основанной на выявлении сходства изображений путем определения того, соответствуют ли они (согласно нашему набору обучения) одной и той же написанной от руки цифре. И мы можем сделать то же самое в гораздо более общем плане для изображений, если у нас есть обучающий набор, который определяет, скажем, к какому из 5000 распространенных типов объектов (кошка, собака, стул, ...) относится каждое изображение. И таким образом мы можем создать встраивание изображения, которое “привязано” к нашей идентификации общих объектов, но затем “обобщается вокруг этого” в соответствии с поведением нейронной сети. И дело в том, что в той мере, в какой такое поведение согласуется с тем, как мы, люди, воспринимаем и интерпретируем изображения, это в конечном итоге станет внедрением, которое “кажется нам правильным” и полезно на практике при выполнении задач, подобных человеческому суждению.

Хорошо, итак, как нам следовать такому же подходу для поиска вложений для слов? Ключ в том, чтобы начать с задания о словах, для которого мы легко можем провести обучение. И стандартной такой задачей является “предсказание слов”. Представьте, что нам дали “___ кошку”. Основываясь на большом объеме текста (скажем, текстовом содержимом Интернета), каковы вероятности для различных слов, которые могли бы “заполнить пробел”? Или, альтернативно, учитывая “___ black ___”, каковы вероятности для разных “фланкирующих слов”?

Как мы решаем эту проблему для нейронной сети? В конечном счете мы должны сформулировать все в терминах цифр. И один из способов сделать это - просто присвоить уникальный номер каждому из примерно 50 000 распространенных слов в английском языке. Так, например, “the” может быть 914, а “cat” (с пробелом перед ним) может быть 3542. (И это фактические числа, используемые GPT-2.) Итак, для задачи “the ___ cat” нашими входными данными могут быть {914, 3542}. Каким должен быть результат? Что ж, это должен быть список из 50 000 или около того чисел, которые эффективно дают вероятности для каждого из возможных “заполняющих” слов. И еще раз, чтобы найти вложение, мы хотим “перехватить” “внутренности” нейронной сети непосредственно перед тем, как она “достигнет своего завершения”, а затем получить список чисел, которые там встречаются, и которые мы можем рассматривать как “характеризующие каждое слово”.

Хорошо, так на что же похожи эти характеристики? За последние 10 лет была разработана последовательность различных систем (word2vec, GloVe, BERT, GPT, ...), каждая из которых основана на различном подходе к нейронным сетям. Но в конечном счете все они берут слова и характеризуют их списками из сотен или тысяч чисел.

В их необработанном виде эти “векторы встраивания” довольно неинформативны. Например, вот что выдает GPT-2 в качестве необработанных векторов вложения для трех конкретных слов:

Если мы делаем такие вещи, как измерение расстояний между этими векторами, то мы можем найти такие вещи, как “близость” слов. Позже мы обсудим более подробно, что мы могли бы считать “когнитивным” значением таких вложений. Но на данный момент главное заключается в том, что у нас есть способ с пользой превращать слова в “дружественные к нейронной сети” наборы чисел.

Но на самом деле мы можем пойти дальше, чем просто характеризовать слова наборами чисел; мы также можем сделать это для последовательностей слов или даже целых блоков текста. И внутри ChatGPT именно так все и обстоит. Он берет текст, который у него есть на данный момент, и генерирует вектор встраивания для его представления. Затем его цель состоит в том, чтобы найти вероятности для разных слов, которые могут возникнуть в следующий раз. И он представляет свой ответ на этот вопрос в виде списка чисел, которые, по сути, дают вероятности для каждого из примерно 50 000 возможных слов.

(Строго говоря, ChatGPT имеет дело не со словами, а скорее с “токенами”, удобными лингвистическими единицами, которые могут быть целыми словами или просто фрагментами, такими как “pre”, “ing” или “ized”. Работа с токенами облегчает ChatGPT обработку редких, сложных и неанглийских слов, а иногда, к лучшему или к худшему, изобретение новых слов.)

Внутри ChatGPT

Итак, мы наконец готовы обсудить, что находится внутри ChatGPT. И, да, в конечном счете, это гигантская нейронная сеть, в настоящее время являющаяся версией так называемой сети GPT-3 со 175 миллиардами весов. Во многих отношениях это нейронная сеть, очень похожая на другие, которые мы обсуждали. Но это нейронная сеть, которая специально настроена для работы с языком. И его наиболее примечательной особенностью является часть архитектуры нейронной сети, называемая “трансформатор”.

В первых нейронных сетях, которые мы обсуждали выше, каждый нейрон на любом данном слое был в основном связан (по крайней мере, с некоторым весом) с каждым нейроном на предыдущем слое. Но такого рода полностью подключенная сеть является (предположительно) излишеством, если кто-то работает с данными, имеющими определенную известную структуру. И таким образом, например, на ранних стадиях работы с изображениями типично использовать так называемые сверточные нейронные сети (“convnets”), в которых нейроны эффективно расположены на сетке, аналогичной пикселям на изображении, и подключены только к нейронам, расположенным поблизости на сетке.

Идея transformers состоит в том, чтобы сделать что-то, по крайней мере, несколько похожее для последовательностей токенов, составляющих фрагмент текста. Но вместо того, чтобы просто определять фиксированную область в последовательности, над которой могут быть соединения, трансформаторы вместо этого вводят понятие “внимание” и идею “уделять внимание” больше некоторым частям последовательности, чем другим. Возможно, однажды будет иметь смысл просто запустить универсальную нейронную сеть и выполнять всю настройку с помощью обучения. Но, по крайней мере, на данный момент на практике кажется критически важным “модульизировать” вещи, как это делают трансформеры, и, вероятно, как это делает наш мозг.

Итак, что же на самом деле делает ChatGPT (или, скорее, сеть GPT-3, на которой она основана)? Напомним, что его общая цель состоит в том, чтобы продолжить текст “разумным” способом, основываясь на том, что он увидел из проведенного им тренинга (который заключается в просмотре миллиардов страниц текста из Интернета и т.д.). Таким образом, в любой данный момент у него есть определенный объем текста, и его цель - придумать подходящий выбор для добавления следующего токена.

Он работает в три основных этапа. Сначала он берет последовательность токенов, которая пока соответствует тексту, и находит вложение (т.е. массив чисел), которое представляет их. Затем он оперирует этим внедрением “стандартным способом нейронной сети”, при этом значения “проходят рябью” по последовательным слоям сети, создавая новое внедрение (т.е. новый массив чисел). Затем он берет последнюю часть этого массива и генерирует из нее массив примерно из 50 000 значений, которые превращаются в вероятности для различных возможных следующих токенов. (И, да, так получилось, что используется примерно такое же количество лексем, как и обычных слов в английском языке, хотя только около 3000 лексем являются целыми словами, а остальные - фрагментами.)

Критическим моментом является то, что каждая часть этого конвейера реализуется нейронной сетью, веса которой определяются сквозным обучением сети. Другими словами, по сути, ничто, кроме общей архитектуры, не является “явно спроектированным”; все просто “извлекается” из обучающих данных.

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

Сначала идет модуль встраивания. Вот схематичное представление этого на языке Wolfram для GPT-2:

Входные данные представляют собой вектор из n токенов (представленных, как и в предыдущем разделе, целыми числами от 1 примерно до 50 000). Каждый из этих токенов преобразуется (с помощью однослойной нейронной сети) в вектор встраивания (длиной 768 для GPT-2 и 12 288 для GPT-3 от ChatGPT). Между тем, существует “вторичный путь”, который принимает последовательность (целых) позиций для токенов и из этих целых чисел создает другой вектор встраивания. И, наконец, векторы встраивания из значения токена и позиции токена суммируются вместе, чтобы получить окончательную последовательность векторов встраивания из модуля встраивания.

Почему нужно просто добавить векторы встраивания token-value и token-position вместе? Я не думаю, что в этом есть какая-то особая наука. Просто были испробованы разные вещи, и это та, которая, кажется, работает. И это часть знаний о нейронных сетях, что в некотором смысле, пока настройка у вас “примерно правильная”, обычно можно разобраться в деталях, просто пройдя достаточное обучение, даже не нуждаясь в “понимании на инженерном уровне” того, как закончилась нейронная сеть до настройки самого себя.

Вот что делает модуль встраивания, работая со строкой привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, привет, пока, пока, пока, пока, пока, пока, пока, пока, пока, пока, пока, пока, пока, пока, пока:

Элементы вектора встраивания для каждого токена показаны внизу страницы, и по всей странице мы видим сначала серию встраиваний “привет”, за которыми следует серия встраиваний “пока”. Второй массив выше - это позиционное вложение с его несколько случайной структурой, являющейся именно тем, что “случайно было изучено” (в данном случае в GPT-2).

Итак, после модуля встраивания наступает “главное событие” трансформера: последовательность так называемых “блоков внимания” (12 для GPT-2, 96 для GPT-3 от ChatGPT). Все это довольно сложно и напоминает типичные большие, трудные для понимания инженерные системы или, если уж на то пошло, биологические системы. Но в любом случае, вот схематическое представление одного “блока внимания” (для GPT-2):

Внутри каждого такого блока внимания имеется набор “заголовков внимания” (12 для GPT-2, 96 для GPT-3 от ChatGPT), каждый из которых независимо работает с различными блоками значений в векторе вложения. (И, да, мы не знаем какой-либо конкретной причины, по которой это хорошая идея - разделить вектор встраивания, или что разные его части “означают”; это всего лишь одна из тех вещей, которые, как было “установлено, работают”.)

Хорошо, так что же делают руководители внимания? По сути, это способ “оглянуться назад” в последовательности токенов (т.е. в тексте, созданном до сих пор) и “упаковать прошлое” в форму, которая полезна для поиска следующего токена. В первом разделе выше мы говорили об использовании 2-граммовых вероятностей для выбора слов на основе их непосредственных предшественников. Что делает механизм “внимания” в transformers, так это позволяет “обращать внимание” даже на гораздо более ранние слова, тем самым потенциально захватывая способ, которым, скажем, глаголы могут относиться к существительным, которые появляются за много слов до них в предложении.

На более детальном уровне то, что делает attention head, - это рекомбинирует фрагменты в векторах вложения, связанных с различными токенами, с определенными весами. И так, например, 12 заголовков внимания в первом блоке внимания (в GPT-2) имеют следующие (“оглядывающийся назад-полностью-путь-к-началу-последовательности-токенов”) шаблоны “весов рекомбинации” для строка “привет, пока” выше:

После обработки головами attention результирующий “повторно взвешенный вектор встраивания” (длиной 768 для GPT-2 и длиной 12 288 для GPT-3 от ChatGPT) передается через стандартный “полностью подключенный” слой нейронной сети. Трудно разобраться в том, что делает этот слой. Но вот график матрицы весов 768x768, которую он использует (здесь для GPT-2):. It’s hard to get a handle on what this layer is doing. But here’s a plot of the 768x768 matrix of weights it’s using (here for GPT-2):

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

Что определяет эту структуру? В конечном счете, это, по-видимому, некое “кодирование нейронной сетью” особенностей человеческого языка. Но на данный момент, какими могут быть эти функции, совершенно неизвестно. По сути, мы “открываем мозг ChatGPT” (или, по крайней мере, GPT-2) и обнаруживаем, что да, там все сложно, и мы этого не понимаем, хотя в конце концов это создает узнаваемый человеческий язык.

Итак, пройдя через один блок внимания, мы получаем новый вектор встраивания, который затем последовательно пропускается через дополнительные блоки внимания (всего 12 для GPT-2; 96 для GPT-3). Каждый блок внимания имеет свой собственный особый паттерн весов “внимания” и “полностью связанных”. Здесь для GPT-2 приведена последовательность весов внимания для ввода “привет, пока”, для первой головы внимания:

И вот (усредненные по перемещению) “матрицы” для полностью связанных слоев:

Любопытно, что, хотя эти “матрицы весов” в разных блоках внимания выглядят довольно похожими, распределения размеров весов могут несколько отличаться (и не всегда являются гауссовскими).:

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

Итак, вот в общих чертах, что находится внутри ChatGPT. Это может показаться сложным (не в последнюю очередь из-за множества неизбежно несколько произвольных “инженерных решений”), но на самом деле задействованные конечные элементы удивительно просты. Потому что, в конце концов, то, с чем мы имеем дело, - это просто нейронная сеть, состоящая из “искусственных нейронов”, каждый из которых выполняет простую операцию по получению набора числовых входных данных, а затем комбинирует их с определенными весами.

Исходными входными данными для ChatGPT является массив чисел (векторы встраивания для токенов на данный момент), и то, что происходит, когда ChatGPT “запускается” для создания нового токена, заключается просто в том, что эти числа “проходят рябью” по слоям нейронной сети, при этом каждый нейрон “делает свое дело” и передает результат передается нейронам на следующем слое. Здесь нет зацикливания или “возврата назад”. Все просто “передается вперед” по сети.

Это сильно отличается от типичной вычислительной системы, такой как машина Тьюринга, в которой результаты многократно “перерабатываются” одними и теми же вычислительными элементами. Здесь, по крайней мере, при генерации данного выходного токена каждый вычислительный элемент (т.е. нейрон) используется только один раз.

Но в некотором смысле все еще существует “внешний цикл”, который повторно использует вычислительные элементы даже в ChatGPT. Потому что, когда ChatGPT собирается сгенерировать новый токен, он всегда “считывает” (т.е. принимает в качестве входных данных) всю последовательность предшествующих ему токенов, включая токены, которые сам ChatGPT “записал” ранее. И мы можем рассматривать эту настройку как означающую, что ChatGPT, по крайней мере, на своем самом внешнем уровне включает “цикл обратной связи”, хотя и такой, в котором каждая итерация явно видна как токен, который появляется в тексте, который он генерирует.

Но давайте вернемся к ядру ChatGPT: нейронной сети, которая многократно используется для генерации каждого токена. На каком-то уровне это очень просто: целая коллекция идентичных искусственных нейронов. И некоторые части сети просто состоят из (“полностью связанных”) слоев нейронов, в которых каждый нейрон на данном слое связан (с некоторым весом) с каждым нейроном на предыдущем слое. Но, в частности, благодаря своей трансформирующей архитектуре, ChatGPT имеет части с большей структурой, в которых подключены только определенные нейроны на разных слоях. (Конечно, все еще можно было бы сказать, что “все нейроны связаны”, но некоторые просто имеют нулевой вес.)

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

Если посмотреть на самый длинный путь через ChatGPT, то в нем задействовано около 400 (основных) слоев, что в некотором смысле не так уж много. Но существуют миллионы нейронов с общим количеством 175 миллиардов связей и, следовательно, 175 миллиардами весов. И одна вещь, которую следует понимать, заключается в том, что каждый раз, когда ChatGPT генерирует новый токен, он должен выполнять вычисления, включающие каждый из этих весов. С точки зрения реализации эти вычисления могут быть в некоторой степени организованы “по уровням” в высокопараллельные операции с массивами, которые удобно выполнять на графических процессорах. Но для каждого созданного токена все еще должно быть выполнено 175 миллиардов вычислений (и в конечном итоге немного больше), так что, да, неудивительно, что для генерации длинного фрагмента текста с помощью ChatGPT может потребоваться некоторое время.

Но, в конце концов, примечательно то, что все эти операции по отдельности, какими бы простыми они ни были, каким-то образом могут вместе выполнять такую хорошую “человекоподобную” работу по генерации текста. Следует еще раз подчеркнуть, что (по крайней мере, насколько нам известно) нет никакой “окончательной теоретической причины”, по которой что-либо подобное должно работать. И на самом деле, как мы обсудим, я думаю, мы должны рассматривать это как потенциально удивительное научное открытие: каким-то образом в нейронной сети, подобной ChatGPT, возможно уловить суть того, что человеческому мозгу удается делать при генерации языка.

Тренировка ChatGPT

Итак, теперь мы в общих чертах описали, как работает ChatGPT после его настройки. Но как это было настроено? Как были определены все эти 175 миллиардов весов в его нейронной сети? По сути, они являются результатом очень масштабного обучения, основанного на огромном объеме текста в Интернете, в книгах и т.д., написанных людьми. Как мы уже говорили, даже учитывая все эти обучающие данные, конечно, не очевидно, что нейронная сеть сможет успешно создавать “человекоподобный” текст. И, опять же, похоже, что для того, чтобы это произошло, необходимы детальные инженерные разработки. Но самым большим сюрпризом и открытием ChatGPT является то, что это вообще возможно. И что, по сути, нейронная сеть с “всего лишь” 175 миллиардами весов может создать “разумную модель” текста, который пишут люди.

В наше время существует множество текстов, написанных людьми, которые доступны в цифровой форме. Общедоступная сеть содержит по меньшей мере несколько миллиардов страниц, написанных человеком, в общей сложности, возможно, триллион слов текста. А если включить в него непубличные веб-страницы, то цифры могут быть как минимум в 100 раз больше. На данный момент доступно более 5 миллионов оцифрованных книг (из примерно 100 миллионов, которые когда-либо были опубликованы), что дает еще около 100 миллиардов слов текста. И это даже не говоря о тексте, полученном из речи в видео и т.д. (Для личного сравнения, мой общий объем опубликованных материалов за всю жизнь составил чуть менее 3 миллионов слов, а за последние 30 лет я написал около 15 миллионов слов электронной почты и в общей сложности набрал около 50 миллионов слов, и только за последние пару лет я произнес более 10 миллионов слова в прямых трансляциях. И, да, я обучу бота на основе всего этого.)

Но, хорошо, учитывая все эти данные, как можно обучить нейронную сеть на их основе? Базовый процесс очень похож на тот, который мы обсуждали в простых примерах выше. Вы представляете пакет примеров, а затем корректируете веса в сети, чтобы минимизировать ошибку (“потерю”), которую сеть допускает в этих примерах. Главное, что дорого обходится при “обратном распространении” ошибки, - это то, что каждый раз, когда вы делаете это, каждый вес в сети обычно меняется по крайней мере на крошечный бит, и приходится иметь дело с большим количеством весов. (Фактическое “обратное вычисление”, как правило, лишь на небольшой постоянный коэффициент сложнее, чем прямое.)

Благодаря современному графическому процессору легко вычислять результаты из пакетов из тысяч примеров параллельно. Но когда дело доходит до фактического обновления весов в нейронной сети, современные методы требуют, чтобы это делалось в основном пакетно. (И, да, вероятно, именно здесь реальные мозги с их объединенными вычислительными элементами и элементами памяти имеют, на данный момент, по крайней мере, архитектурное преимущество.)

Даже в кажущихся простыми случаях изучения числовых функций, которые мы обсуждали ранее, мы обнаружили, что нам часто приходилось использовать миллионы примеров для успешного обучения сети, по крайней мере, с нуля. Итак, сколько примеров, это означает, нам понадобится для того, чтобы обучить модель “человекоподобного языка”? Похоже, что нет никакого фундаментального “теоретического” способа узнать это. Но на практике ChatGPT был успешно обучен на нескольких сотнях миллиардов слов текста.

Часть текста была загружена несколько раз, часть - только один раз. Но каким-то образом он “получил то, что ему было нужно” из увиденного текста. Но учитывая такой объем текста для изучения, насколько большой должна быть сеть, чтобы “выучить его хорошо”? Опять же, у нас пока нет фундаментального теоретического способа сказать. В конечном счете, как мы обсудим далее ниже, предположительно, существует определенное “общее алгоритмическое содержание” человеческого языка и того, что люди обычно говорят с его помощью. Но следующий вопрос заключается в том, насколько эффективной будет нейронная сеть при реализации модели, основанной на этом алгоритмическом содержании. И снова мы не знаем, хотя успех ChatGPT говорит о том, что он достаточно эффективен.

И в конце мы можем просто отметить, что ChatGPT делает то, что он делает, используя пару сотен миллиардов весов, сопоставимых по количеству с общим количеством слов (или токенов) обучающих данных, которые ему были предоставлены. В некотором смысле, возможно, удивительно (хотя эмпирически наблюдается и в меньших аналогах ChatGPT), что “размер сети”, которая, кажется, работает хорошо, настолько сопоставим с “размером обучающих данных”. В конце концов, это, конечно, не значит, что каким-то образом “внутри ChatGPT” весь этот текст из Интернета, книг и так далее “хранится напрямую”. Потому что то, что на самом деле находится внутри ChatGPT, - это набор чисел с точностью чуть меньше 10 цифр, которые представляют собой своего рода распределенную кодировку совокупной структуры всего этого текста.

Другими словами, мы могли бы спросить, что такое “эффективное информационное наполнение” человеческого языка и что обычно говорится с его помощью. Вот необработанный корпус примеров языка. И еще есть представление в нейронной сети ChatGPT. Это представление, скорее всего, далеко от “алгоритмически минимального” представления (как мы обсудим ниже). Но это представление, которое легко может быть использовано нейронной сетью. И в этом представлении, похоже, в конечном итоге происходит довольно незначительное “сжатие” обучающих данных; по-видимому, в среднем требуется лишь немного меньше веса нейронной сети, чтобы передать “информационное содержание” слова обучающих данных.

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

Помимо базовой подготовки

Большая часть усилий при обучении ChatGPT тратится на “показ” больших объемов существующего текста из Интернета, книг и т.д. Но оказывается, что есть еще одна, по-видимому, довольно важная часть.

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

И ключевой идеей при создании ChatGPT было сделать еще один шаг после “пассивного чтения” таких вещей, как Интернет: заставить реальных людей активно взаимодействовать с ChatGPT, видеть, что он производит, и, по сути, давать ему обратную связь о том, “как быть хорошим чат-ботом”. Но как нейронная сеть может использовать эту обратную связь? Первый шаг - просто попросить людей оценить результаты, полученные с помощью нейронной сети. Но затем строится другая модель нейронной сети, которая пытается предсказать эти рейтинги. Но теперь эта модель прогнозирования может быть запущена, по сути, как функция потерь в исходной сети, фактически позволяя “настраивать” эту сеть с помощью предоставленной обратной связи с человеком. И результаты на практике, по-видимому, оказывают большое влияние на успех системы в получении “человеческого” результата.

В целом, интересно, как мало “тычков” в “первоначально обученную” сеть, по-видимому, требуется, чтобы заставить ее с пользой работать в определенных направлениях. Можно было бы подумать, что для того, чтобы сеть вела себя так, как будто она “узнала что-то новое”, нужно было бы войти и запустить обучающий алгоритм, скорректировав веса и так далее.

Но это не тот случай. Вместо этого, по-видимому, достаточно в основном сообщить ChatGPT что-то один раз как часть запроса, который вы даете, и затем он может успешно использовать то, что вы ему сказали, когда он генерирует текст. И еще раз, тот факт, что это работает, я думаю, является важным ключом к пониманию того, что ChatGPT “на самом деле делает” и как это связано со структурой человеческого языка и мышления.

В этом, безусловно, есть что-то довольно похожее на человеческое: по крайней мере, после того, как он прошел всю эту предварительную подготовку, вы можете сказать ему что-то всего один раз, и он сможет “запомнить это” по крайней мере “достаточно долго”, чтобы сгенерировать фрагмент текста, используя его. Так что же происходит в подобном случае? Может случиться так, что “все, что вы могли бы рассказать, уже где-то там”, и вы просто направляете это в нужное место. Но это не кажется правдоподобным. Вместо этого, что кажется более вероятным, так это то, что да, элементы уже есть, но специфика определяется чем-то вроде “траектории между этими элементами”, и это то, что вы вводите, когда рассказываете ему что-то.

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

Также стоит еще раз отметить, что неизбежно существуют “алгоритмические ограничения” на то, что нейронная сеть может “уловить”. Скажите ему “неглубокие” правила вида “это переходит в то” и т.д., и нейронная сеть, скорее всего, сможет представить и воспроизвести их просто отлично, и действительно, то, что она “уже знает” из языка, даст ей немедленный шаблон для подражания. Но попробуйте дать ему правила для реального “глубокого” вычисления, которое включает в себя множество потенциально вычислительно неприводимых шагов, и это просто не сработает. (Помните, что на каждом шаге он всегда просто “передает данные вперед” в свою сеть, никогда не зацикливаясь, кроме как за счет генерации новых токенов.)

Конечно, сеть может узнать ответ на конкретные “неприводимые” вычисления. Но как только появляется комбинаторное множество возможностей, никакой такой подход в стиле “поиска по таблице” работать не будет. Итак, да, как и людям, нейронным сетям пришло время “протянуть руку помощи” и использовать реальные вычислительные инструменты. (И, да, Wolfram | Alpha и Wolfram Language однозначно подходят, потому что они были созданы для того, чтобы “говорить о вещах в мире”, точно так же, как нейронные сети языковой модели.)

Что на самом деле позволяет ChatGPT работать?

Человеческий язык и процессы мышления, участвующие в его создании, всегда казались своего рода вершиной сложности. И действительно, казалось несколько примечательным, что человеческий мозг с его сетью из “всего лишь” 100 миллиардов нейронов или около того (и, возможно, 100 триллионов соединений) мог быть ответственен за это. Возможно, можно было бы предположить, что в мозге есть нечто большее, чем просто сети нейронов, например, какой-то новый уровень неоткрытой физики. Но теперь с помощью ChatGPT мы получили новую важную информацию: мы знаем, что чистая искусственная нейронная сеть с примерно таким же количеством связей, сколько нейронов в мозге, способна на удивление хорошо генерировать человеческий язык.

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

Так как же тогда получается, что что-то вроде ChatGPT может зайти так далеко, как это происходит с языком? Основной ответ, я думаю, заключается в том, что язык на фундаментальном уровне каким-то образом проще, чем кажется. И это означает, что ChatGPT даже с его в конечном счете простой структурой нейронной сети успешно способен “улавливать суть” человеческого языка и мышления, стоящего за ним. И более того, в ходе своего обучения ChatGPT каким-то образом “неявно обнаружил” любые закономерности в языке (и мышлении), делающие это возможным.

Я думаю, что успех ChatGPT свидетельствует о фундаментальной и важной части науки: он предполагает, что мы можем ожидать появления новых важных “законов языка” и, по сути, “законов мышления”, которые предстоит открыть. В ChatGPT, построенном как нейронная сеть, эти законы в лучшем случае неявны. Но если бы мы могли каким-то образом сделать законы явными, появился бы потенциал для того, чтобы делать то, что делает ChatGPT, гораздо более прямыми, эффективными и прозрачными способами.

Но, ладно, так на что же могут быть похожи эти законы? В конечном счете они должны дать нам какой-то рецепт того, как сочетаются язык и то, что мы с его помощью говорим. Позже мы обсудим, как “заглядывание внутрь ChatGPT” может дать нам некоторые подсказки по этому поводу, и как то, что мы знаем из построения вычислительного языка, подсказывает путь вперед. Но сначала давайте обсудим два давно известных примера того, что представляет собой “законы языка” и как они связаны с работой ChatGPT.

Первый - это синтаксис языка. Язык - это не просто случайное нагромождение слов. Вместо этого существуют (довольно) определенные грамматические правила для того, как слова разных видов могут быть составлены вместе: в английском языке, например, существительным могут предшествовать прилагательные, а за ними следовать глаголы, но обычно два существительных не могут находиться рядом друг с другом. Такая грамматическая структура может (по крайней мере, приблизительно) быть зафиксирована набором правил, которые определяют, как можно собрать воедино то, что составляет “деревья синтаксического анализа”:

ChatGPT не обладает никакими явными “знаниями” о таких правилах. Но каким-то образом в ходе своего обучения он неявно “обнаруживает” их и затем, кажется, хорошо им следует. Итак, как это работает? На уровне “общей картины” это неясно. Но чтобы получить некоторое представление, возможно, поучительно взглянуть на гораздо более простой пример.

Рассмотрим “язык”, сформированный из последовательностей (’s и ) ’s, с грамматикой, которая определяет, что круглые скобки всегда должны быть сбалансированы, как представлено деревом синтаксического анализа, подобным:

Можем ли мы обучить нейронную сеть создавать “грамматически правильные” последовательности скобок? Существуют различные способы обработки последовательностей в нейронных сетях, но давайте использовать сети-трансформеры, как это делает ChatGPT. И, учитывая простую сеть-трансформер, мы можем начать вводить в нее грамматически правильные последовательности скобок в качестве обучающих примеров. Тонкость (которая на самом деле также появляется в поколении человеческого языка ChatGPT) заключается в том, что в дополнение к нашим “токенам содержимого” (здесь “(” и “)”) мы должны включить токен “End”, который генерируется, чтобы указать, что вывод не должен продолжаться дальше (т.е. для ChatGPT этот достиг “конца истории”).

Если мы настроим сеть-трансформер только с одним блоком внимания с 8 головками и векторами объектов длиной 128 (ChatGPT также использует векторы объектов длиной 128, но имеет 96 блоков внимания, каждый с 96 головками), то, похоже, невозможно заставить его много изучать язык скобок. Но с двумя блоками внимания процесс обучения, по-видимому, сходится, по крайней мере, после того, как было приведено около 10 миллионов примеров (и, как это обычно бывает с трансформаторными сетями, показ еще большего количества примеров, похоже, просто ухудшает его производительность).

Таким образом, с помощью этой сети мы можем сделать аналог того, что делает ChatGPT, и запросить вероятности того, каким должен быть следующий токен в последовательности скобок:

И в первом случае сеть “почти уверена”, что последовательность не может закончиться здесь, и это хорошо, потому что если бы это произошло, круглые скобки остались бы несбалансированными. Во втором случае, однако, он “правильно распознает”, что последовательность может закончиться здесь, хотя он также “указывает”, что можно “начать снова”, проставив “(”, предположительно с “)”, чтобы следовать. Но, упс, даже с его 400 000 или около того тщательно подобранных весов, он говорит, что существует 15% вероятность того, что “)” будет следующим символом, что неправильно, потому что это обязательно привело бы к несбалансированным скобкам.

Вот что мы получим, если запросим у сети завершения с наибольшей вероятностью для постепенно увеличивающихся последовательностей (’s:

И, да, до определенной длины сеть работает просто отлично. Но потом это начинает давать сбой. Это довольно типичная вещь, которую можно увидеть в “точной” ситуации, подобной этой, с нейронной сетью (или с машинным обучением в целом). Случаи, которые человек “может решить с первого взгляда”, нейронная сеть тоже может решить. Но в случаях, когда требуется сделать что-то “более алгоритмичное” (например, явно подсчитать круглые скобки, чтобы увидеть, закрыты ли они), нейронная сеть, как правило, каким-то образом “слишком мелка в вычислительном отношении”, чтобы выполнять ее надежно. (Кстати, даже полному текущему ChatGPT трудно правильно сопоставить круглые скобки в длинных последовательностях.)

Итак, что это означает для таких вещей, как ChatGPT и синтаксис такого языка, как английский? Язык скобок ”суров“ и гораздо больше похож на ”алгоритмическую историю". Но в английском языке гораздо реалистичнее иметь возможность “угадать”, что грамматически подходит, на основе местного выбора слов и других подсказок. И, да, нейронная сеть намного лучше справляется с этим, хотя, возможно, она может пропустить какой-то “формально правильный” случай, который, ну, люди тоже могут пропустить. Но главное заключается в том, что тот факт, что в языке существует общая синтаксическая структура со всей вытекающей регулярностью, в некотором смысле ограничивает “объем”, который нейронная сеть должна усвоить. И ключевое “естественнонаучное” наблюдение заключается в том, что трансформирующая архитектура нейронных сетей, подобных той, что используется в ChatGPT, по-видимому, успешно способна изучать синтаксическую структуру, подобную вложенному дереву, которая, по-видимому, существует (по крайней мере, в некотором приближении) во всех человеческих языках.

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

Но есть ли общий способ определить, имеет ли предложение смысл? Для этого нет традиционной общей теории. Но это то, о чем можно думать, что ChatGPT неявно “разработал теорию” после того, как был обучен миллиардам (предположительно значимых) предложений из Интернета и т.д.

На что может быть похожа эта теория? Что ж, есть один крошечный уголок, который, по сути, известен уже два тысячелетия, и это логика. И, конечно, в той силлогистической форме, в которой ее открыл Аристотель, логика - это, по сути, способ сказать, что предложения, которые следуют определенным шаблонам, разумны, в то время как другие - нет. Таким образом, например, разумно сказать: “Все X - это Y. Это не Y, значит, это не X” (как в “Все рыбы синие. Это не синее, значит, это не рыба”). И точно так же, как можно несколько причудливо представить, что Аристотель открыл силлогистическую логику, пройдясь (“в стиле машинного обучения”) по множеству примеров риторики, точно так же можно представить, что при обучении ChatGPT он сможет “открыть силлогистическую логику”, просмотрев множество текстов на сеть и т.д. (И, да, хотя, следовательно, можно ожидать, что ChatGPT создаст текст, содержащий “правильные выводы”, основанные на таких вещах, как силлогистическая логика, это совсем другая история, когда дело доходит до более сложной формальной логики, и я думаю, что можно ожидать, что здесь она потерпит неудачу по тем же причинам, что и в соответствие скобкам.)

Но помимо узкого примера логики, что можно сказать о том, как систематически конструировать (или распознавать) даже правдоподобно значимый текст? Да, есть такие вещи, как Mad Libs, которые используют очень специфические “фразовые шаблоны”. Но каким-то образом ChatGPT неявно имеет гораздо более общий способ сделать это. И, возможно, нечего сказать о том, как это можно сделать, кроме “каким-то образом это происходит, когда у вас 175 миллиардов весов нейронной сети”. Но я сильно подозреваю, что существует гораздо более простая и убедительная история.

Смысловое пространство и семантические законы движения

Выше мы обсуждали, что внутри ChatGPT любой фрагмент текста эффективно представлен массивом чисел, которые мы можем рассматривать как координаты точки в некотором “пространстве лингвистических признаков”. Таким образом, когда ChatGPT продолжает фрагмент текста, это соответствует отслеживанию траектории в пространстве лингвистических объектов. Но теперь мы можем спросить, что заставляет эту траекторию соответствовать тексту, который мы считаем значимым. И, возможно, существуют какие-то “семантические законы движения”, которые определяют или, по крайней мере, ограничивают то, как точки в пространстве лингвистических признаков могут перемещаться, сохраняя при этом “осмысленность”?

Итак, на что похоже это пространство лингвистических признаков? Вот пример того, как отдельные слова (в данном случае нарицательные) могут быть расположены, если мы спроецируем такое пространство объектов в 2D:

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

В качестве другого примера, вот как распределяются слова, соответствующие разным частям речи:

Конечно, данное слово, как правило, не имеет просто “одного значения” (или обязательно соответствует только одной части речи). И, глядя на то, как предложения, содержащие слово, располагаются в пространстве признаков, часто можно “раздразнить” различные значения, как в приведенном здесь примере со словом “журавль” (птица или машина?):

Хорошо, итак, по крайней мере правдоподобно, что мы можем думать об этом пространстве признаков как о размещении “слов, близких по значению” близко в этом пространстве. Но какую дополнительную структуру мы можем идентифицировать в этом пространстве? Существует ли, например, какое-то понятие “параллельного переноса”, которое отражало бы “плоскостность” в пространстве? Один из способов разобраться в этом - посмотреть на аналогии:

И, да, даже когда мы проецируем в 2D, часто присутствует по крайней мере “намек на плоскостность”, хотя это, конечно, не повсеместно видно.

Так что насчет траекторий? Мы можем посмотреть на траекторию, по которой следует запрос для ChatGPT в пространстве объектов, а затем мы можем увидеть, как ChatGPT продолжает это:

Здесь, конечно, нет никакого “геометрически очевидного” закона движения. И это совсем не удивительно; мы полностью ожидаем, что это будет значительно более сложная история. И, например, далеко не очевидно, что даже если существует “семантический закон движения”, который необходимо найти, в каком виде вложения (или, по сути, в каких “переменных”) он будет наиболее естественно сформулирован.

На рисунке выше мы показываем несколько шагов в “траектории”, где на каждом шаге мы выбираем слово, которое ChatGPT считает наиболее вероятным (случай “нулевой температуры”). Но мы также можем спросить, какие слова могут “прийти следующими” с какой вероятностью в данный момент:

И что мы видим в этом случае, так это то, что существует “веер” слов с высокой вероятностью, который, кажется, движется в более или менее определенном направлении в пространстве признаков. Что произойдет, если мы пойдем дальше? Вот последовательные “веера”, которые появляются по мере того, как мы “движемся вдоль” траектории:

Вот 3D-представление, состоящее в общей сложности из 40 шагов:

И, да, это кажется беспорядком и не делает ничего, что особенно поощряло бы идею о том, что можно ожидать выявления “похожих на математическую физику” “семантических законов движения” путем эмпирического изучения “того, что делает ChatGPT внутри”. Но, возможно, мы просто смотрим на “неправильные переменные” (или неправильную систему координат), и если бы мы только посмотрели на правильную, мы бы сразу увидели, что ChatGPT делает что-то “математически-физическое-простое”, например, следует геодезическим. Но на данный момент мы не готовы “эмпирически расшифровать” из его “внутреннего поведения” то, что ChatGPT “обнаружил” о том, как “составлен” человеческий язык.

Семантическая грамматика и мощь вычислительного языка

Что нужно для создания “осмысленного человеческого языка”? В прошлом мы могли бы предположить, что это может быть не что иное, как человеческий мозг. Но теперь мы знаем, что это может быть сделано вполне респектабельно с помощью нейронной сети ChatGPT. Тем не менее, возможно, это все, на что мы способны, и не будет ничего более простого или более понятного человеку, что сработало бы. Но я сильно подозреваю, что успех ChatGPT неявно раскрывает важный “научный” факт: на самом деле в осмысленном человеческом языке гораздо больше структуры и простоты, чем мы когда-либо знали, и что, в конце концов, могут существовать даже довольно простые правила, которые описывают, как такой язык может быть составлен воедино.

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

В целях синтаксиса мы идентифицируем такие вещи, как существительные и глаголы. Но для целей семантики нам нужны ”более тонкие градации". Так, например, мы могли бы отождествить понятие “перемещение” и понятие “объекта”, который “сохраняет свою идентичность независимо от местоположения”. Существует бесконечное множество конкретных примеров каждого из этих “семантических понятий”. Но для целей нашей семантической грамматики у нас будет просто какое-то общее правило, которое в основном гласит, что “объекты” могут “двигаться”. Можно многое сказать о том, как все это могло бы работать (о некоторых из них я уже говорил ранее). Но я ограничусь здесь лишь несколькими замечаниями, которые указывают на некоторые потенциальные пути продвижения вперед.

Стоит упомянуть, что даже если предложение идеально подходит в соответствии с семантической грамматикой, это не означает, что оно было реализовано (или даже могло бы быть реализовано) на практике. ”Слон полетел на Луну“, несомненно, ”прошел бы" нашу семантическую грамматику, но это, конечно, не было реализовано (по крайней мере, пока) в нашем реальном мире, хотя это абсолютно честная игра для вымышленного мира.

Когда мы начинаем говорить о “семантической грамматике”, мы вскоре задаемся вопросом: “Что за этим кроется?” Какую “модель мира” она предполагает? Синтаксическая грамматика на самом деле - это просто построение языка из слов. Но семантическая грамматика обязательно взаимодействует с какой-то “моделью мира”, чем-то, что служит “скелетом”, поверх которого может быть наложен язык, состоящий из реальных слов.

До недавнего времени мы могли бы вообразить, что (человеческий) язык будет единственным общим способом описания нашей “модели мира”. Уже несколько столетий назад начали появляться формализации определенных видов вещей, основанные, в частности, на математике. Но теперь существует гораздо более общий подход к формализации: вычислительный язык.

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

И, после десятилетий работы, мы охватили таким образом множество областей. Но в прошлом мы особо не занимались “повседневным дискурсом”. В “Я купил два фунта яблок” мы можем легко представить (и выполнить расчеты по питанию и другие вычисления) “два фунта яблок”. Но у нас (пока еще) нет символического представления для “я купил”.

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

Но давайте предположим, что у нас был этот “язык символического дискурса”. Что бы мы с этим сделали? Мы могли бы начать делать такие вещи, как генерация “локально значимого текста”. Но в конечном счете мы, вероятно, захотим получить более “глобально значимые” результаты, что означает “вычислять” больше о том, что на самом деле может существовать или происходить в мире (или, возможно, в каком-то последовательном вымышленном мире).

Прямо сейчас в Wolfram Language у нас есть огромное количество встроенных вычислительных знаний о множестве видов вещей. Но для полноценного языка символического дискурса нам пришлось бы встроить дополнительные “вычисления” об общих вещах в мире: если объект перемещается из A в B и из B в C, то он перемещается из A в C и т.д.

Учитывая язык символического дискурса, мы могли бы использовать его для создания “автономных утверждений”. Но мы также можем использовать его, чтобы задавать вопросы о мире, “в стиле Wolfram | Alpha”. Или мы можем использовать его, чтобы заявить о вещах, которые мы “хотим сделать такими”, предположительно, с помощью какого-то внешнего механизма приведения в действие. Или мы можем использовать это, чтобы делать утверждения, возможно, о реальном мире или, возможно, о каком-то конкретном мире, который мы рассматриваем, вымышленном или ином.

Человеческий язык в корне неточен, не в последнюю очередь потому, что он не “привязан” к конкретной вычислительной реализации, и его значение в основном определяется просто “социальным контрактом” между его пользователями. Но вычислительный язык, по своей природе, обладает определенной фундаментальной точностью, потому что в конце концов то, что он определяет, всегда может быть “однозначно выполнено на компьютере”. Человеческому языку обычно сходит с рук определенная расплывчатость. (Когда мы говорим “планета”, включает ли это экзопланеты или нет и т.д.?) Но на вычислительном языке мы должны быть точны и ясны во всех различиях, которые мы делаем.

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

Как следует определить фундаментальную “онтологию”, подходящую для общего языка символического дискурса? Что ж, это нелегко. Возможно, именно поэтому в этих областях мало что было сделано с тех пор, как более двух тысячелетий назад Аристотель заложил примитивные основы. Но действительно помогает то, что сегодня мы так много знаем о том, как мыслить о мире с помощью вычислений (и не помешает иметь “фундаментальную метафизику” из нашего проекта по физике и идеи ruliad).

Но что все это означает в контексте ChatGPT? Благодаря своему обучению ChatGPT эффективно “собрал по кусочкам” определенное (довольно впечатляющее) количество того, что составляет семантическую грамматику. Но сам его успех дает нам повод думать, что будет возможно создать что-то более полное в форме вычислительного языка. И, в отличие от того, что мы до сих пор выясняли о внутренностях ChatGPT, мы можем ожидать, что разработаем вычислительный язык таким образом, чтобы он был легко понятен людям.

Когда мы говорим о семантической грамматике, мы можем провести аналогию с силлогистической логикой. Сначала силлогистическая логика была, по сути, набором правил относительно утверждений, выраженных на человеческом языке. Но (да, два тысячелетия спустя), когда была разработана формальная логика, исходные базовые конструкции силлогистической логики теперь можно было использовать для построения огромных “формальных башен”, которые включают, например, работу современных цифровых схем. И поэтому, мы можем ожидать, что это будет с более общей семантической грамматикой. Сначала он может просто иметь дело с простыми шаблонами, выраженными, скажем, в виде текста. Но как только будет построена вся его структура вычислительного языка, мы можем ожидать, что его можно будет использовать для возведения высоких башен “обобщенной семантической логики”, которые позволят нам точным и формальным образом работать со всеми видами вещей, которые никогда не были доступны нам раньше, за исключением только на “уровень первого этажа” с помощью человеческого языка, со всей его расплывчатостью.

Мы можем думать о построении вычислительного языка и семантической грамматики как о своего рода предельном сжатии в представлении вещей. Потому что это позволяет нам говорить о сути того, что возможно, не имея, например, дела со всеми “оборотами речи”, которые существуют в обычном человеческом языке. И мы можем рассматривать огромную силу ChatGPT как нечто немного похожее: потому что он тоже в некотором смысле “просверлен” до такой степени, что может “объединить язык семантически значимым образом”, не заботясь о различных возможных оборотах фразы.

Итак, что бы произошло, если бы мы применили ChatGPT к базовому вычислительному языку? Вычислительный язык может описать то, что возможно. Но что еще можно добавить, так это ощущение “того, что популярно”, основанное, например, на чтении всего этого контента в Интернете. Но, с другой стороны, работа с вычислительным языком означает, что что-то вроде ChatGPT имеет немедленный и фундаментальный доступ к тому, что составляет конечные инструменты для использования потенциально неприводимых вычислений. И это делает ее системой, которая может не только “генерировать разумный текст”, но и может рассчитывать на то, что она разработает все, что может быть разработано относительно того, действительно ли этот текст содержит “правильные” утверждения о мире или о чем там предполагается говорить.

Итак... Что делает ChatGPT и почему это работает?

Базовая концепция ChatGPT на некотором уровне довольно проста. Начните с огромного образца созданного человеком текста из Интернета, книг и т.д. Затем обучите нейронную сеть генерировать текст “вот так”. И, в частности, сделайте так, чтобы он мог начинаться с “подсказки”, а затем продолжать с текстом, который “похож на то, с чем он был обучен”.

Как мы видели, реальная нейронная сеть в ChatGPT состоит из очень простых элементов, хотя их миллиарды. И базовая операция нейронной сети также очень проста, состоящая, по сути, в передаче входных данных, полученных из текста, который она сгенерировала до сих пор, “один раз через его элементы” (без каких-либо циклов и т.д.) для каждого нового слова (или части слова), которое она генерирует.

Но самое замечательное и неожиданное заключается в том, что этот процесс может создавать текст, который успешно “похож” на то, что есть в Интернете, в книгах и т.д. И это не только связный человеческий язык, он также “говорит вещи”, которые “следуют его подсказке”, используя контент, который он “прочитал”. Он не всегда говорит вещи, которые “глобально имеют смысл” (или соответствуют правильным вычислениям), потому что (без, например, доступа к “вычислительным сверхспособностям” Wolfram | Alpha) он просто говорит вещи, которые “звучат правильно”, основываясь на том, как вещи “звучали” в его учебном материале.

Специфическая разработка ChatGPT сделала его весьма привлекательным. Но в конечном счете (по крайней мере, до тех пор, пока он не сможет использовать внешние инструменты) ChatGPT “просто” извлекает некоторую “связную нить текста” из “статистики общепринятого мнения”, которую он накопил. Но удивительно, насколько результаты похожи на человеческие. И, как я уже обсуждал, это наводит на мысль о чем-то, что, по крайней мере, очень важно с научной точки зрения: что человеческий язык (и модели мышления, стоящие за ним) каким-то образом проще и более “законоподобен” по своей структуре, чем мы думали. ChatGPT неявно обнаружил это. Но мы потенциально можем явно раскрыть это с помощью семантической грамматики, вычислительного языка и т.д.

То, что ChatGPT делает при генерации текста, очень впечатляет, и результаты обычно очень похожи на то, что могли бы получить мы, люди. Так значит ли это, что ChatGPT работает как мозг? Лежащая в его основе структура искусственной нейронной сети в конечном счете была смоделирована на основе идеализации мозга. И кажется вполне вероятным, что когда мы, люди, генерируем язык, многие аспекты происходящего весьма схожи.

Когда дело доходит до обучения (он же learning), различное “железо” мозга и современных компьютеров (а также, возможно, некоторые неразвитые алгоритмические идеи) вынуждает ChatGPT использовать стратегию, которая, вероятно, несколько отличается (и в некоторых отношениях гораздо менее эффективна) от стратегии мозга. И есть кое-что еще: в отличие даже от типичных алгоритмических вычислений, ChatGPT внутренне не “имеет циклов” или “пересчитывает данные”. И это неизбежно ограничивает его вычислительные возможности даже по отношению к современным компьютерам, но определенно по отношению к мозгу.

Неясно, как “исправить это” и при этом сохранить способность обучать систему с разумной эффективностью. Но это, по-видимому, позволит будущему ChatGPT делать еще больше “мозгоподобных вещей”. Конечно, есть множество вещей, с которыми мозг справляется не так хорошо, особенно связанных с тем, что сводится к неприводимым вычислениям. И для этого как мозги, так и такие вещи, как ChatGPT, должны искать “внешние инструменты”, такие как Wolfram Language.

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

Спасибо

Я слежу за развитием нейронных сетей уже около 43 лет, и за это время я общался со многими людьми по поводу них. Среди них были некоторые давние, некоторые недавние, а некоторые на протяжении многих лет: Джулио Алессандрини, Дарио Амодеи, Этьен Бернар, Талиесин Бейнон, Себастьян Боденштайн, Грег Брокман, Джек Коуэн, Педро Домингос, Джесси Галеф, Роджер Гермундссон, Роберт Хехт-Нильсен, Джефф Хинтон, Джон Хопфилд, Янн Лекун, Джерри Леттвин, Джером Лурадур, Марвин Мински, Эрик Мьельснесс, Кайден Пирс, Томазо Поджо, Маттео Сальварецца, Терри Сейновски, Оливер Селфридж, Гордон Шоу, Йонас Шеберг, Илья Суцкевер, Джерри Тесауро и Тимоти Вердье. За помощь в написании этого материала я особенно хотел бы поблагодарить Джулио Алессандрини и Брэда Кли.

Дополнительные ресурсы

Машинное обучение для учащихся средних школ В»


Источник: writings.stephenwolfram.com

Комментарии: