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

Мы видим, что генеративные модели OpenAI, вызываемые через API (DALL-E, ChatGPT и т. д.), не могут контролироваться и действовать детерминировано. Другими словами: они дают противоречивые результаты, даже когда их температура, параметр, контролирующий их творчество, установлена ​​на ноль. Более подробную информацию о temperature можно найти в Документации OpenAI API. Вместо того, чтобы предлагать решения, эта запись в блоге призвана объяснить такое поведение. Потому что знание – сила, верно?

Но насколько это актуально на самом деле? Этот вопрос возникает регулярно? Видимо; да. В настоящее время он возглавляет список Часто задаваемых вопросов OpenAI GPT.

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

  • (Генераторный язык) Контекст GPT:
    вы хотите показать своему начальнику, что ваш «управляемый генератор кода Angular» в 100 % случаев предоставляет правильный блок кода для определенного запроса.
  • (Генераторное видение) Контекст DALL-E:
    вы хотите показать своим коллегам, что ваше приглашение создает точно такой же замечательный образ «фруктового сока в суповой тарелке», как это было вчера, когда вы работали над маркетингом киоска с лимонадом вашего сына.

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

Наблюдение

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

«Почему я не получаю постоянно одни и те же ответы при вызове любого генеративного API OpenAI, когда температура равна 0?

Обратите внимание, что соответствующие обсуждения и ресурсы по этой теме можно найти;

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

Понимание

«Трудно понять, как именно работает система черного ящика. Но если черный ящик развился из ящиков, которые были, знаете ли, менее черными и более прозрачными, то некоторые предположения о качестве все же можно сделать».
- возможно, кто-то в какой-то момент времени

Как ясно из приведенной выше фальшивой цитаты: мы не можем знать точно, как под капотом работают LLM (большие языковые модели) с закрытым исходным кодом ChatGPT или GPT-4 (например, бумажный GPT-4). Но от их более прозрачных предшественников (например, бумаги GPT-2 [2] и кода с открытым исходным кодом) и конкурентов с открытым исходным кодом (например, бумаги LLaMA) мы знаем суть соответствующей архитектуры на основе трансформатора.

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

Как модель доставляет выходной текст?

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

При этом сеть LLM имеет словарь токенов, и благодаря своему, казалось бы, волшебному пониманию входного текста, она очень хорошо указывает, какие токены из ее словаря с наибольшей вероятностью последуют за данным вводом. Эта индикация происходит посредством (см. рисунок выше) присвоения вероятностей. Например, P(token_0) представляет собой расчетную вероятность того, что слово жевание (представленное token_0) следует за заданной последовательностью входных токенов ( the cow is …). Вероятность слова боулинг (представленного token_50.256), мы надеемся, ниже, чем вероятность слова жевать или пастись в этом контексте.

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

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

Выборка на высшем уровне: выборка на высшем уровне

Современные LLM используют (вариант) выборку по топ-p (т. е. ядерную выборку, представленную в этой статье 2018 года) для выборки ответа. Этот метод рассматривает только токены, кумулятивная вероятность которых превышает вероятность p, а затем перераспределяет массу вероятности между оставшимися токенами так, чтобы сумма вероятностей равнялась 1. Если вы сейчас думаете подождите, что?, поздравляю, вы не статистик! Не стесняйтесь перечитать это предложение, а затем перейти к более понятному визуальному объяснению ниже:

Допустим, мы установили p=0.92. При первом проходе, начиная только со слова "the”, нам нужно 6 токенов, чтобы вероятность превысить эту вероятность 92% (их сумма составляет 94%). Мы можем выбрать токен из этих шести слов, учитывая их перераспределенные вероятности (при этом слово nice будет иметь наибольший шанс быть выбранным). При следующем проходе мы обнаруживаем, что три наиболее вероятных токена вместе уже легко превышают порог в 92%, и, таким образом, конечный токен выбирается только из этих трех.

Приятно то, что количество токенов для выборки динамически зависит от уровня «неопределенности» модели. Если модель считает небольшое подмножество токенов наиболее релевантным (например, потому что входные токены состоят из "the", "car", что ограничивает контекст), она будет выбирать только из них.

Соответствующий анекдот: пару лет назад в ML6 мы создали базовый «сборник правил и условий», который случайно генерировал в резюме слово «молоко» и полностью смещался в сторону разговора о еде только потому, что это было не так. Не использую выборку ядра.

Тогда что такое контроль температуры?

Хорошо, теперь мы понимаем, к чему относится параметр top_p из Документации OpenAI API. Обратите внимание, что по умолчанию этот параметр устанавливает значение p=100%, что означает, что учитываются все выходные токены. Если, с другой стороны, p=0%, всегда будет выбран первый проверяемый токен, который алгоритмически имеет наибольшую вероятность, поскольку он сам по себе сразу же превышает сверхнизкий порог.

Хорошо, но какую роль играет параметр temperature?

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

Что делает температура: она контролирует относительные веса в распределении вероятностей. Он контролирует степень, в которой различия в вероятности играют роль в выборке. Возьмем приведенный выше пример: для входной последовательности токена "The” мы ожидаем (по умолчанию) вероятность того, что слово nice будет выбрано P(“nice”)=75%, составляет 75%. Вот что происходит при температуре t=1. Этот параметр можно выбрать от 0 до 2.

При температуре t=0 этот метод выборки превращается в то, что мы называем жадным поиском/выборкой по аргументу, где всегда выбирается токен с наибольшей вероятностью(здесь: P(“nice”)=100%).

При температуре t=2 разница между более вероятными и менее вероятными токенами уменьшается во время выборки. Для примера слева выше это приведет к: P("nice")=58% , P("dog")=32% , P("car")=10%.

Для интересующихся ниже добавлена ​​формула для расчета вероятностей выборки, на которую влияет температура t (где K представляет общее количество токенов, учитываемых в выборке):

Вывод: секреты раскрыты

Теперь вы можете считать себя настоящим воином генеративных API OpenAI, потому что приведенный ниже отрывок больше не содержит для вас секретов.
Обратите внимание на утверждение «обычно мы рекомендуем изменить это или top_p/temperature, но не то и другое». И это всего лишь предложение сохранить ваши изменения более или менее интерпретируемыми при игре со значениями. Установка любого из этих значений в их детерминированные пределы (т. е. p=0 или top_p=0) имеет тот же эффект.

Мы помним это: по умолчанию выборка происходит по всему словарю токенов (top_p=1), а распределение вероятностей остается неизменным (temperature=1).

Объяснение

Обладая приведенными выше знаниями, мы точно знаем, что произойдет, если мы исправим temperature=0. А именно: будет выбран один жетон с наиболее вероятной вероятностью.

Но что, если в какой-то момент во время генерации ударит молния ⚡ и двум токенам будет присвоена точно одинаковая вероятность?

Может ударить молния: ненулевой шанс

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

  • Неопределенность модели: в тех случаях, когда модель далека от уверенности в том, что один токен является идеальным выбором для следующего токена, вероятность того, что токены, входящие в число фаворитов, имеют одинаковые вероятности, выше.
  • Ограниченная точность: вероятность того, что две вероятности будут абсолютно одинаковыми, уменьшается с увеличением количества битов, которые используются для их представления. Если у вас есть: 1 бит = 2 возможных числа, 2 бита = 4 возможных числа, 8 бит = 256 возможных чисел. Если у вас есть только 8 бит для представления числа в сети (что является результатом суммы умножений на другие 8-битные числа), вероятность того, что результаты будут абсолютно одинаковыми, больше, чем когда у вас есть 32 бита на каждом шаге. по пути. Мы отмечаем, что если выбор квантования сделан для оптимизации скорости и стоимости вывода, точность представленных чисел еще больше ограничивается.
  • Бонанза прямого прохода: с учетом количества жетонов, которые обычно необходимы для составления соответствующего ответа, вероятность удара молнии неуклонно возрастает. Если Pᵢ — это вероятность того, что это произойдет за один прямой проходi, то общая вероятность того, что это произойдет, равна сумме этой вероятности для всех прямых проходов, необходимых для генерации общего ответа. В качестве упрощенного примера представьте себе фиксированную вероятность удара молнии P_i=0.0001%, тогда для ответа, который требует 200 проходов через сеть, вероятность удара молнии для всего ответа составит P=0.02%, что не так уж и мало.

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

Ладно, молния может ударить ⚡. Но что, если это так?

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

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

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

Нет контроля семян, нет контроля урожая

Мудрый фермер мог бы однажды сказать:

«если вы не контролируете то, что сеете, то как вы можете контролировать то, что пожинаете?»
— вероятно, гипотетический фермер

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

Таким образом, мы объяснили, почему детерминизм остается недосягаемым при работе с наиболее популярными API OpenAI.

Что такое демон?

Но почему? Почему дела обстоят так, как есть?

Итак, семена. Большой возглас. Не так уж и удивительно. Остается вопрос:
Почему вы не можете передать семя? Как заявил этот парень в Твиттере:

«Это какое-то безумие, что в OpenAI API нет параметра «случайное начальное число». Ожидаемое поведение — получить результаты, которые вы никогда не сможете воспроизвести».
— Саша Раш (доцент Корнельского технологического института и исследователь обнимающих лиц)

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

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

Заверните

В этом путешествии мы поделились информацией о:

  • Как вероятности токена предоставляются сетью LLM
  • Как происходит выборка токенов на каждом этапе генерации ответа и как параметры temperature и top_p влияют на эту выборку
  • Почему точно равные вероятности токенов (⚡) не так уж необычны, как можно было бы ожидать
  • Роль, которую обычно играет семя в ситуациях удара молнии

По причинам, которые нам пока не известны, OpenAI не позволяет нам устанавливать начальное число, имеющее решающую силу, когда ударяет молния во время генерации ответа по токенам.

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