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

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

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

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

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

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

Например, вот как получить приведенную выше таблицу вероятностей. Сначала мы должны получить нейронную сеть, лежащую в основе "языковой модели":
Позже мы заглянем внутрь этой нейронной сети и поговорим о том, как она работает. Но на данный момент мы можем просто применить эту «сетчатую модель» в качестве черного ящика к нашему тексту и попросить 5 лучших слов по вероятности, которые, по словам модели, должны следовать:
Это берет этот результат и превращает его в явно отформатированный "набор данных":
Вот что произойдет, если вы неоднократно "примените модель" - на каждом шаге добавляете слово, которое имеет наивысшую вероятность (указанное в этом коде как "решение" из модели):
Что произойдет, если будет продолжаться дольше? В этой ("нулевой температуре") то, что скоро выйдет, становится довольно запутанным и повторяющимся:
Но что, если вместо того, чтобы всегда выбирать «верхний» слово, иногда случайным образом выбирает «неверхние» слова (с «случайностью», соответствующей «температуре» 0,8)? Опять же, можно создать текст:
И каждый раз, когда кто-то это делает, будут делаться разные случайные варианты, и текст будет отличаться, как в этих 5 примерах:
Стоит отметить, что даже на первом шаге есть много возможных «следущих слов» на выбор (при температуре 0,8), хотя их вероятности падают довольно быстро (и, да, прямая линия на этом графике журнала соответствует распаду n-1 «закона власти», который очень характерен для общей статистики языка):
Так что же произойдет, если кто-то будет продолжаться дольше? Вот случайный пример. Это лучше, чем верхнее слово (нулевой температуры), но все же в лучшем случае немного странно:
Это было сделано с помощью простейшей модели GPT-2 (с 2019 года). С новыми и большими моделями GPT-3 результаты лучше. Вот текст верхнего слова (нулевой температуры), полученный с той же "подсказкой", но с самой большой моделью GPT-3:
И вот случайный пример в "температуре 0,8":
Откуда берутся вероятности?
Хорошо, так что ChatGPT всегда выбирает свое следующее слово на основе вероятностей. Но откуда берутся эти вероятности? Давайте начнем с более простой проблемы. Давайте рассмотрим возможность создания английского текста по одной букве (а не слова) за раз. Как мы можем определить вероятность каждой буквы?

Самое минимальное, что мы могли бы сделать, это взять образец английского текста и подсчитать, как часто в нем встречаются различные буквы. Так, например, подсчитываются буквы в статье Википедии о "кошках":
То же самое делается и для "собак":
Результаты похожи, но не одинаковы ("o", несомненно, чаще встречается в артикле "dogs", потому что, в конце концов, оно встречается в самом слове "dog"). Тем не менее, если мы возьмем достаточно большую выборку английского текста, мы можем ожидать, что в конечном итоге получим, по крайней мере, достаточно последовательные результаты:
Вот пример того, что мы получим, если просто сгенерируем последовательность букв с этими вероятностями:
Мы можем разбить это на "слова", добавив пробелы, как если бы они были буквами с определенной вероятностью:
Мы можем проделать немного более качественную работу по созданию "слов", заставив распределение "длины слов" согласоваться с тем, что есть в английском языке:
Нам не удалось получить ни одного "реального слова", но результаты выглядят немного лучше. Однако, чтобы продвинуться дальше, нам нужно сделать нечто большее, чем просто выбрать каждую букву отдельно наугад. Например, мы знаем, что если у нас есть буква "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 миллиардов нейронов (нервных клеток), каждый из которых способен производить электрический импульс до тысячи раз в секунду. Нейроны соединены в сложную сеть, причем каждый нейрон имеет древовидные ответвления, позволяющие ему передавать электрические сигналы, возможно, тысячам других нейронов. И в грубом приближении, то, произведет ли какой-либо нейрон электрический импульс в данный момент, зависит от того, какие импульсы он получил от других нейронов, причем разные связи вносят свой вклад с разным "весом".

Когда мы "видим изображение", происходит следующее: когда фотоны света от изображения падают на клетки ("фоторецепторы") в задней части глаз, они производят электрические сигналы в нервных клетках. Эти нервные клетки соединяются с другими нервными клетками, и в итоге сигналы проходят через целую последовательность слоев нейронов. Именно в этом процессе мы "распознаем" изображение, в итоге "формируя мысль", что мы "видим цифру 2" (и, возможно, в конце концов, делаем что-то вроде произнесения слова "два" вслух).
Функция "черного ящика" из предыдущего раздела - это "математизированная" версия такой нейронной сети. Она имеет 11 слоев (хотя только 4 "основных слоя"):
В этой нейронной сети нет ничего особенно "теоретически выведенного"; это просто нечто, что еще в 1998 году было создано как инженерное произведение и оказалось работоспособным. (Конечно, это не сильно отличается от того, как мы можем описать наш мозг как созданный в процессе биологической эволюции).

Хорошо, но как такая нейронная сеть "распознает вещи"? Ключевым моментом является понятие аттракторов. Представьте, что у нас есть рукописные изображения цифр 1 и 2:
Мы почему-то хотим, чтобы все "1" "притягивались в одно место", а все "2" "притягивались в другое место". Или, говоря по-другому, если изображение каким-то образом "ближе к 1", чем к 2, мы хотим, чтобы оно оказалось в "1 месте", и наоборот.

В качестве прямой аналогии, допустим, у нас есть определенные позиции на плоскости, обозначенные точками (в реальной жизни это могут быть позиции кофеен). Тогда мы можем представить, что, начиная с любой точки на плоскости, мы всегда хотим оказаться в ближайшей точке (т.е. мы всегда будем посещать ближайшую кофейню). Мы можем представить это, разделив плоскость на области ("бассейны аттракторов"), разделенные идеализированными "водоразделами":
Мы можем думать об этом как о реализации своего рода "задачи распознавания", в которой мы не делаем что-то вроде определения того, на какую цифру данное изображение "больше всего похоже" - скорее мы просто, совершенно непосредственно, видим, к какой точке ближе всего находится данная точка. (Диаграмма Г.Ф.Вороного, которую мы здесь показываем, разделяет точки в двумерном евклидовом пространстве; задачу распознавания цифр можно представить как нечто подобное, но в 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) может вычислить при различных вариантах весов и констант (и Ramp в качестве функции активации):
Но как насчет более крупной сети сверху? Ну, вот что он вычисляет:
Это не совсем "правильно", но близко к функции "ближайшей точки", которую мы показали выше.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Итак, вот концепция. Вместо того чтобы напрямую пытаться определить, "какое изображение находится рядом с каким другим изображением", мы рассматриваем четко определенную задачу (в данном случае распознавание цифр), для которой мы можем получить явные обучающие данные, а затем используем тот факт, что при выполнении этой задачи нейронная сеть неявно должна принимать "решения о близости". Таким образом, вместо того, чтобы нам когда-либо явно говорить о "близости изображений", мы просто говорим о конкретном вопросе, какую цифру представляет изображение, а затем мы "оставляем на усмотрение нейронной сети" неявное определение того, что это подразумевает "близость изображений".
Итак, как более детально это работает для сети распознавания цифр? Мы можем представить себе сеть как состоящую из 11 последовательных слоев, которые можно представить следующим образом (функции активации показаны как отдельные слои):
В начале мы подаем в первый слой реальные изображения, представленные 2D-массивами значений пикселей. И в конце - с последнего слоя - мы получаем массив из 10 значений, которые мы можем придумать, чтобы сказать "насколько уверена" сеть в том, что изображение соответствует каждой из цифр от 0 до 9.

Подача на изображении 4️⃣ и значения нейронов в этом последнем слое:
Другими словами, нейронная сеть к этому моменту "невероятно уверена", что это изображение - 4, и чтобы получить на выходе "4", нам нужно просто выбрать позицию нейрона с наибольшим значением.

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

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

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

Как нам настроить эту проблему для нейронной сети? В конечном счете, мы должны сформулировать все с точки зрения цифр. И один из способов сделать это - просто присвоить уникальное число каждому из 50 000 или около того общих слов в английском языке. Так, например, "the" может быть 914, а "кошка" (с пробелом перед ней) может быть 3542. (И это фактические цифры, используемые GPT-2.) Таким образом, для задачи "__ кошка" наш вход может быть {914, 3542}. Каким должен быть результат? Ну, это должен быть список из примерно 50 000 чисел, которые эффективно дают вероятности для каждого из возможных слов "заполнения". И еще раз, чтобы найти вложение, мы хотим «перехватить» «внутри» нейронной сети непосредственно перед тем, как она «достичет своего завершения», а затем взять список чисел, которые там встречаются, и которые мы можем рассматривать как «характеризацию каждого слова». Хорошо, так как выглядят эти характеристики? За последние 10 лет была разработана последовательность различных систем (word2vec, GloVe, BERT, GPT, ...), каждая из которых основана на различном нейросетевом подходе. Но в конечном итоге все они берут слова и характеризуют их списками от сотен до тысяч чисел.

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

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

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

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

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

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

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

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

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

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

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

На более детальном уровне, то, что делает головка внимания, - это рекомбинирование фрагментов в векторах встраивания, связанных с различными лексемами, с определенными весами. И так, например, 12 головок внимания в первом блоке внимания (в GPT-2) имеют следующие ("посмотрите назад по всему пути к началу последовательности токенов") шаблоны "весов рекомбинации" для строки "привет, пока" выше:
После обработки центром внимания, полученный "перевзвешенный вектор встраивания" (длиной 768 для GPT-2 и длиной 12 288 для GPT-3 ChatGPT) пропускается через стандартный слой "полностью подключенной" нейронной сети. Трудно понять, что делает этот слой. Но вот график матрицы весов 768×768, которую он использует (здесь для GPT-2):
Если взять скользящие средние 64×64, то начинает вырисовываться некоторая структура (похожая на случайные колебания):
Что определяет эту структуру? В конечном итоге, предположительно, это некое "нейросетевое кодирование" особенностей человеческого языка. Но что это могут быть за особенности, пока неизвестно. По сути, мы "открываем мозг ChatGPT" (или, по крайней мере, GPT-2) и обнаруживаем, что да, там все сложно, и мы не понимаем этого - хотя в конечном итоге он производит узнаваемый человеческий язык.

Итак, пройдя через один блок внимания, мы получаем новый вектор встраивания, который затем последовательно проходит через дополнительные блоки внимания (всего 12 для GPT-2; 96 для GPT-3). Каждый блок внимания имеет свой собственный шаблон "внимания" и "полностью подключенных" весов. Здесь для GPT-2 приведена последовательность весов внимания для входа "hello, bye", для первого блока внимания:
А вот (усредненные по перемещению) "матрицы" для полностью связанных слоев:
Любопытно, что хотя эти "матрицы весов" в разных блоках внимания выглядят довольно похоже, распределения величин весов могут быть несколько разными (и не всегда гауссовскими):
Итак, после прохождения через все эти блоки внимания каков чистый эффект трансформатора? По сути, это преобразование исходной коллекции вкраплений для последовательности лексем в конечную коллекцию. А конкретный способ работы 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 миллионов слов на живых трансляциях. И да, я буду обучать бота на основе всего этого).

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

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

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

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

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

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

Когда мы запускаем ChatGPT для генерации текста, нам приходится использовать каждый вес один раз. Таким образом, если есть n весов, нам нужно выполнить порядка n вычислительных шагов - хотя на практике многие из них обычно могут выполняться параллельно на GPU. Но если для установки этих весов нам потребуется около 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 блоков), то, кажется, невозможно заставить ее узнать много нового о языке скобок. Но с 2 головками внимания процесс обучения, похоже, сходится - по крайней мере, после предоставления 10 миллионов примеров (и, как это обычно бывает с трансформаторными сетями, показ еще большего количества примеров только ухудшает ее производительность).

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

Вот что мы получим, если попросим сеть найти наиболее вероятные завершения для все более длинных последовательностей ():
И да, до определенной длины сеть работает отлично. Но потом она начинает давать сбой. Это довольно типичная вещь, которую можно увидеть в "точной" ситуации, подобной этой, с нейронной сетью (или с машинным обучением в целом). Случаи, которые человек "решает с первого взгляда", нейросеть тоже может решить. Но случаи, требующие выполнения чего-то "более алгоритмического" (например, явного подсчета скобок, чтобы проверить, закрыты ли они), нейросеть, как правило, оказывается "слишком вычислительно неглубокой", чтобы надежно решить. (Кстати, даже полный текущий 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. Или мы можем использовать его для утверждения вещей, которые мы "хотим сделать таковыми", предположительно с помощью какого-то внешнего механизма приведения в действие. Или мы можем использовать его для утверждений - возможно, о реальном мире, а возможно, о каком-то конкретном мире, который мы рассматриваем, вымышленном или ином.

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

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

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

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

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

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

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

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

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

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

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

Но пока что интересно посмотреть, что ChatGPT уже смог сделать. На каком-то уровне это отличный пример фундаментального научного факта, что большое количество простых вычислительных элементов может делать удивительные и неожиданные вещи. Но это также дает, возможно, лучший за последние две тысячи лет импульс для лучшего понимания фундаментального характера и принципов той центральной черты человеческого бытия, которой является человеческий язык и стоящие за ним процессы мышления.
Cпасибо
Я слежу за развитием нейронных сетей уже около 43 лет, и за это время я общался со многими людьми о них. Среди них - некоторые из давнего времени, некоторые из недавнего времени, а некоторые в течение многих лет - были: Giulio Alessandrini, Dario Amodei, Etienne Bernard, Taliesin Beynon, Sebastian Bodenstein, Greg Brockman, Jack Cowan, Pedro Domingos, Jesse Galef, Roger Germundsson, Robert Hecht-Nielsen, Geoff Hinton, John Hopfield, Yann LeCun, Jerry Lettvin, Jerome Louradour, Marvin Minsky, Eric Mjolsness, Cayden Pierce, Tomaso Poggio, Matteo Salvarezza, Terry Sejnowski, Oliver Selfridge, Gordon Shaw, Jonas Sjöberg, Ilya Sutskever, Gerry Tesauro and Timothee Verdier.