Изучение моделей ChatGPT и моделей с открытым исходным кодом на более сложных задачах
LLM с открытым исходным кодом, такие как Vicuna и MPT-7B-Chat, появляются повсюду, что привело к многочисленным дискуссиям о том, как эти модели сравниваются с коммерческими LLM (такими как ChatGPT или Bard).
Большая часть сравнения проводилась по ответам на простые вопросы/инструкции. Например, ребята из LMSYSOrg провели интересный анализ (+1 за автоматизацию и воспроизводимость), сравнивая Vicuna-13B с ChatGPT по различным коротким вопросам, что отлично подходит для сравнения моделей как простых чат-ботов. Однако многие интересные способы использования LLM обычно требуют сложных инструкций и/или многооборотных диалогов, а также некоторого оперативного проектирования. Мы думаем, что в «реальном мире» большинство людей захотят сравнить различные предложения LLM по своей проблеме с помощью множества различных подсказок.
Этот пост в блоге (написанный совместно со Скоттом Лундбергом ) является примером того, как может выглядеть такое исследование с помощью guidance
проекта с открытым исходным кодом, который помогает пользователям управлять LLM. Сравниваем две модели с открытым исходным кодом (Викуна-13Б, МПТ-7б-Чат) с ChatGPT (3.5) на задачах разной сложности.
Разминка: решение уравнений
В качестве разминки давайте начнем с игрушечной задачи по решению простых полиномиальных уравнений, где мы можем проверить правильность вывода и не потребуется много времени на разработку. Это будет похоже на категорию «Математика» здесь , с той разницей, что мы оцениваем модели как правильные/неправильные на основе истины, а не используем GPT-4 для оценки вывода.
Небольшое отступление о синтаксисе чата : каждая из этих моделей имеет собственный синтаксис чата со специальными токенами, разделяющими высказывания. Вот как тот же диалог будет выглядеть в Vicuna и MPT (где [generated response]
модель будет генерировать свои выходные данные):
Викунья:
A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions.
USER: Can you please solve the following equation? x^2 + 2x + 1 = 0
ASSISTANT: [generated response] </s>
<|im_start|>system
- You are a helpful assistant chatbot trained by MosaicML.
- You answer questions.
- You are excited to be able to help the user, but will refuse to do anything that could be considered harmful to the user.
- You are more than just an information source, you are also able to write poetry, short stories, and make jokes.
<|im_end|>
<|im_start|>user Can you please solve the following equation? x^2 + 2x + 1 = 0<|im_end|>
<|im_start|>assistant [generated response]<|im_end|>
find_roots = guidance('''
{{#system~}}
{{llm.default_system_prompt}}
{{~/system}}
{{#user~}}
Please find the roots of the following equation: {{equation}}
Think step by step, find the roots, and then say:
ROOTS = [root1, root2...]
For example, if the roots are 1.3 and 2.2, say ROOTS = [1.3, 2.2].
Make sure to use real numbers, not fractions.
{{~/user}}
{{#assistant~}}
{{gen 'answer'}}
{{~/assistant~}}''')
import guidance
mpt = guidance.llms.transformers.MPTChat('mosaicml/mpt-7b-chat', device=1)
vicuna = guidance.llms.transformers.Vicuna('yourpath/vicuna-13b', device_map='auto')
chatgpt = guidance.llms.OpenAI("gpt-3.5-turbo")
equation = 'x^2 + 3.0x = 0'
roots = [0, -3]
answer_gpt = find_roots(llm=chatgpt, equation=equation)
answer_vicuna = find_roots(llm=vicuna, equation=equation)
answer_mpt = find_roots(llm=mpt, equation=equation)
В блокноте , сопровождающем этот пост, мы пишем функцию для генерации случайных квадратных уравнений с целыми корнями от -20 до 20 и запускаем подсказку 20 раз для каждой модели. Результаты были следующими:
╔═══════════╦══════════╦
║ Model ║ Accuracy ║
╠═══════════╬══════════╬
║ ChatGPT ║ 80% ║
║ Vicuna ║ 0% ║
║ MPT ║ 0% ║
╚═══════════╩══════════╩
ChatGPT допускает ошибку расчета на последнем шаге, где (13 +- 25) /2
должно быть yield, [19, -6]
а не [19.5, -6.5]
.
Теперь, когда Vicuna и MPT потерпели неудачу с квадратными уравнениями, мы рассмотрим еще более простые уравнения, такие как x - 10 = 0
. Для этих уравнений мы получаем такие числа:
╔═══════════╦══════════╦
║ Model ║ Accuracy ║
╠═══════════╬══════════╬
║ ChatGPT ║ 100% ║
║ Vicuna ║ 85% ║
║ MPT ║ 30% ║
╚═══════════╩══════════╩
Обсуждение
Это была очень игрушечная задача, но она послужила примером того, как сравнивать модели с разным синтаксисом чата, используя одну и ту же подсказку. Для этой конкретной комбинации задачи/подсказки ChatGPT намного превосходит Vicuna и MPT с точки зрения точности (измеренной на основе достоверности).
Задача: извлечение сниппетов + ответы на вопросы о встречах
Теперь обратимся к более реалистичной задаче, где оценка точности не так проста. Допустим, мы хотим, чтобы наш LLM отвечал на вопросы (с соответствующими сегментами разговора для заземления) о стенограммах встреч.
Это приложение, в котором некоторые пользователи могут предпочесть использовать LLM с открытым исходным кодом, а не коммерческие, по соображениям конфиденциальности (например, некоторые компании могут не захотеть отправлять данные своих собраний в OpenAI).
Вот стенограмма игрушечной встречи, с которой можно начать:
Стенограмма встречи:
Джон : Итак, мы все здесь, чтобы обсудить предложение, которое мы получили от Microsoft, о покупке нашего стартапа. Что вы думаете об этом?
Люси : Ну, я думаю, это отличная возможность для нас. Microsoft — огромная компания с большим количеством ресурсов, и они действительно могли бы помочь нам вывести наш продукт на новый уровень.
Стивен : Я согласен с Люси. У Microsoft большой опыт работы в технологической отрасли, и они могут предоставить нам поддержку, необходимую для развития нашего бизнеса.
Джон : Я понимаю вашу точку зрения, но я немного сомневаюсь по поводу продажи нашего стартапа. Мы вложили много времени и усилий в создание этой компании, и я не уверен, что готов отказаться от нее прямо сейчас.
Люси: Я понимаю, откуда ты взялся, Джон, но нам нужно подумать о будущем нашей компании. Если мы продадим Microsoft, у нас будет доступ к их ресурсам и опыту, что поможет нам еще больше расширить наш бизнес.
Стивен : Верно, и давайте не будем забывать о финансовой выгоде. Microsoft предлагает нам много денег для нашего стартапа, которые могут помочь нам инвестировать в новые проекты и расширить нашу команду.
Джон : Я понимаю вашу точку зрения, но у меня все еще есть некоторые оговорки. Что, если Microsoft изменит наш продукт или культуру нашей компании? Что, если мы потеряем контроль над собственным бизнесом?
Стивен : Знаешь что, я не думал об этом раньше, но, возможно, Джон прав. Было бы обидно, если бы наша культура изменилась.
Люси: Это обоснованные опасения, но мы можем договориться об условиях сделки, чтобы сохранить некоторый контроль над нашей компанией. А что касается продукта и культуры, мы можем работать с Microsoft, чтобы убедиться, что наше видение остается неизменным.
Джон : Но разве мы не изменимся только благодаря тому, что нас поглотит большая компания? Я имею в виду, что мы небольшой стартап с очень специфической культурой. Microsoft — огромная корпорация с совершенно другой культурой. Я не уверен, что они могут сосуществовать.
Стивен : Но, Джон, разве мы всегда не планировали, что нас поглотят? Не будет ли это когда-нибудь проблемой?
Люси : Верно.
Джон : Я просто не хочу потерять то, что мы здесь построили.
Стивен : Я тоже разделяю это беспокойство.
Начнем с того, что просто попробуем заставить ChatGPT решить задачу за нас. Мы проверим ответ на вопрос «Как Стивен относится к продажам?». Вот первая попытка подсказки
qa_attempt1 = guidance('''{{#system~}}
{{llm.default_system_prompt}}
{{~/system}}
{{#user~}}
You will read a meeting transcript, then extract the relevant segments to answer the following question:
Question: {{query}}
Here is a meeting transcript:
----
{{transcript}}
----
Please answer the following question:
Question: {{query}}
Extract from the transcript the most relevant segments for the answer, and then answer the question.
{{/user}}
{{#assistant~}}
{{gen 'answer'}}
{{~/assistant~}}''')
qa_attempt3 = guidance('''{{#system~}}
{{llm.default_system_prompt}}
{{~/system}}
{{#user~}}
You will read a meeting transcript, then extract the relevant segments to answer the following question:
Question: {{query}}
Here is a meeting transcript:
----
{{transcript}}
----
Based on the above, please answer the following question:
Question: {{query}}
Please extract from the transcript whichever conversation segments are most relevant for the answer, and then answer the question.
Note that conversation segments can be of any length, e.g. including multiple conversation turns.
Please extract at most 3 segments. If you need less than three segments, you can leave the rest blank.
As an example of output format, here is a fictitious answer to a question about another meeting transcript.
CONVERSATION SEGMENTS:
Segment 1: Peter and John discuss the weather.
Peter: John, how is the weather today?
John: It's raining.
Segment 2: Peter insults John
Peter: John, you are a bad person.
Segment 3: Blank
ANSWER: Peter and John discussed the weather and Peter insulted John.
{{/user}}
{{#assistant~}}
{{gen 'answer'}}
{{~/assistant~}}''')
qa_attempt5 = guidance('''{{#system~}}
{{llm.default_system_prompt}}
{{~/system}}
{{#user~}}
You will read a meeting transcript, then extract the relevant segments to answer the following question:
Question: What were the main things that happened in the meeting?
Here is a meeting transcript:
----
Peter: Hey
John: Hey
Peter: John, how is the weather today?
John: It's raining.
Peter: That's too bad. I was hoping to go for a walk later.
John: Yeah, it's a shame.
Peter: John, you are a bad person.
----
Based on the above, please answer the following question:
Question: {{query}}
Please extract from the transcript whichever conversation segments are most relevant for the answer, and then answer the question.
Note that conversation segments can be of any length, e.g. including multiple conversation turns.
Please extract at most 3 segments. If you need less than three segments, you can leave the rest blank.
{{/user}}
{{#assistant~}}
CONVERSATION SEGMENTS:
Segment 1: Peter and John discuss the weather.
Peter: John, how is the weather today?
John: It's raining.
Segment 2: Peter insults John
Peter: John, you are a bad person.
Segment 3: Blank
ANSWER: Peter and John discussed the weather and Peter insulted John.
{{~/assistant~}}
{{#user~}}
You will read a meeting transcript, then extract the relevant segments to answer the following question:
Question: {{query}}
Here is a meeting transcript:
----
{{transcript}}
----
Based on the above, please answer the following question:
Question: {{query}}
Please extract from the transcript whichever conversation segments are most relevant for the answer, and then answer the question.
Note that conversation segments can be of any length, e.g. including multiple conversation turns.
Please extract at most 3 segments. If you need less than three segments, you can leave the rest blank.
{{~/user}}
{{#assistant~}}
{{gen 'answer'}}
{{~/assistant~}}''')
qa_attempt5(llm=chatgpt, transcript=meeting_transcript, query=query1)
qa_guided = guidance('''{{#system~}}
{{llm.default_system_prompt}}
{{~/system}}
{{#user~}}
You will read a meeting transcript, then extract the relevant segments to answer the following question:
Question: {{query}}
----
{{transcript}}
----
Based on the above, please answer the following question:
Question: {{query}}
Please extract the three segment from the transcript that are the most relevant for the answer, and then answer the question.
Note that conversation segments can be of any length, e.g. including multiple conversation turns. If you need less than three segments, you can leave the rest blank.
As an example of output format, here is a fictitious answer to a question about another meeting transcript:
CONVERSATION SEGMENTS:
Segment 1: Peter and John discuss the weather.
Peter: John, how is the weather today?
John: It's raining.
Segment 2: Peter insults John
Peter: John, you are a bad person.
Segment 3: Blank
ANSWER: Peter and John discussed the weather and Peter insulted John.
{{/user}}
{{#assistant~}}
CONVERSATION SEGMENTS:
Segment 1: {{gen 'segment1'}}
Segment 2: {{gen 'segment2'}}
Segment 3: {{gen 'segment3'}}
ANSWER: {{gen 'answer'}}
{{~/assistant~}}''')
Мы можем, конечно, запустить ту же подсказку с MPT:
Хотя MPT следует формату, он игнорирует вопрос и берет фрагменты из примера формата, а не из реальной стенограммы.
С этого момента мы будем просто сравнивать ChatGPT и Vicuna.
Давайте попробуем задать другой вопрос: «Кто хочет продать компанию?»
Вот ЧатГПТ:
Викунья:
Оба, кажется, работают очень хорошо. Давайте переключим стенограмму встречи на первые несколько минут интервью с Илоном Маском. Соответствующая часть вопроса, который мы зададим,
Илон Маск : Тогда я скажу, сэр, что вы не понимаете, о чем говорите.
Интервьюер : Правда?
Илон Маск : Да. Потому что вы не можете привести ни одного примера хейт-контента. Ни одного твита. И все же вы утверждали, что содержание ненависти было высоким. Это неверно.
Интервьюер : Нет. То, что я утверждал…
Илон Маск : Вы просто солгали.
Затем задаем следующий вопрос:
«Оскорбляет ли Илон Маск интервьюера?»
ЧатGPT:
Викунья:
Vicuna, имеет правильный формат и даже правильные сегменты, но на удивление генерирует совершенно неправильный ответ, когда говорит «Илон Маск не обвиняет его во лжи и не оскорбляет его каким-либо образом».
Мы попробовали множество других вопросов и бесед, и общая закономерность заключалась в том, что Vicuna была сопоставима с ChatGPT по большинству вопросов, но чаще получала неправильные ответы, чем ChatGPT.
Задача: сделать что-то с bash
Теперь мы пытаемся заставить эти LLM многократно использовать оболочку bash для решения отдельных задач. Всякий раз, когда они выдают команду, мы запускаем ее и вставляем вывод обратно в приглашение, пока задача не будет решена.
Вот приглашение ChatGPT (обратите внимание, что shell this.command
вызывает пользовательскую функцию с this.command
аргументом as):
terminal = guidance('''{{#system~}}
{{llm.default_system_prompt}}
{{~/system}}
{{#user~}}
Please complete the following task:
Task: list the files in the current directory
You can give me one bash command to run at a time, using the syntax:
COMMAND: command
I will run the commands on my terminal, and paste the output back to you. Once you are done with the task, please type DONE.
{{/user}}
{{#assistant~}}
COMMAND: ls
{{~/assistant~}}
{{#user~}}
Output: guidance project
{{/user}}
{{#assistant~}}
The files or folders in the current directory are:
- guidance
- project
DONE
{{~/assistant~}}
{{#user~}}
Please complete the following task:
Task: {{task}}
You can give me one bash command to run at a time, using the syntax:
COMMAND: command
I will run the commands on my terminal, and paste the output back to you. Once you are done with the task, please type DONE.
{{/user}}
{{#geneach 'commands' stop=False}}
{{#assistant~}}
{{gen 'this.command'}}
{{~/assistant~}}
{{~#user~}}
Output: {{shell this.command)}}
{{~/user~}}
{{/geneach}}''')
Действительно, ChatGPT следует очень естественной последовательности и решает поставленную задачу. Это не соответствует нашей инструкции сказать DONE, но мы можем остановить итерацию автоматически, потому что она не выдает никаких КОМАНД.
Для моделей с открытым исходным кодом мы пишем более простую (управляемую) подсказку, в которой есть последовательность команд-выводов:
guided_terminal = guidance('''{{#system~}}
{{llm.default_system_prompt}}
{{~/system}}
{{#user~}}
Please complete the following task:
Task: list the files in the current directory
You can run bash commands using the syntax:
COMMAND: command
OUTPUT: output
Once you are done with the task, use the COMMAND: DONE.
{{/user}}
{{#assistant~}}
COMMAND: ls
OUTPUT: guidance project
COMMAND: DONE
{{~/assistant~}}
{{#user~}}
Please complete the following task:
Task: {{task}}
You can run bash commands using the syntax:
COMMAND: command
OUTPUT: output
Once you are done with the task, use the COMMAND: DONE.
{{~/user}}
{{#assistant~}}
{{#geneach 'commands' stop=False ~}}
COMMAND: {{gen 'this.command' stop='\\n'}}
OUTPUT: {{shell this.command)}}{{~/geneach}}
{{~/assistant~}}''')
Вот МПТ:
При интересном повороте событий Викунья не может решить задачу, но МРТ справляется. Помимо конфиденциальности (мы не отправляем расшифровку сеанса в OpenAI), модели с открытым исходным кодом имеют здесь значительное преимущество: вся подсказка представляет собой один запуск LLM (и мы даже ускоряем его, не создавая токены выходной структуры, такие как COMMAND:
) .
Напротив, мы должны делать новый вызов ChatGPT для каждой команды, что медленнее и дороже.
Теперь мы попробуем другую команду: «Найти все файлы блокнота jupyter в ~/work/guidance, которые в настоящее время не отслеживаются git».
Вот ЧатГПТ:
И снова мы сталкиваемся с проблемой, когда ChatGPT не следует заданной нами структуре вывода (и, таким образом, делает невозможным использование внутри программы без участия человека). Наша программа только что выполняла команды, поэтому она остановилась после последнего сообщения ChatGPT выше.
Мы подозревали, что пустой вывод отключил ChatGPT, и поэтому решили эту конкретную проблему, изменив сообщение при отсутствии вывода. Однако мы не можем решить общую проблему невозможности заставить ChatGPT следовать указанной нами структуре вывода.
ChatGPT смог решить проблему после этой небольшой модификации. Давайте посмотрим, как это делает Викунья:
Викуна следует нашей структуре вывода, но, к сожалению, запускает неправильную команду для выполнения задачи. MPT (не показан) неоднократно вызывает git status, поэтому он также не работает.
Мы запускали эти программы для различных других инструкций и обнаружили, что ChatGPT почти всегда выдает правильную последовательность команд, хотя иногда не соответствует указанному формату (и, следовательно, требует вмешательства человека). Модели с открытым исходным кодом работали не так хорошо (вероятно, мы могли бы улучшить их с помощью более быстрой разработки, но они не справились с самыми сложными инструкциями).
Выводы
В дополнение к приведенным выше примерам мы пробовали различные входные данные для обеих задач (ответы на вопросы и bash). Мы также попробовали множество других задач, включающих подведение итогов, ответы на вопросы, «творческую» генерацию и манипуляции с игрушечными нитками, где мы могли автоматически оценивать точность.
Вот краткое изложение наших выводов:
- Качество в задаче : для каждой задачи, которую мы пробовали, ChatGPT (3.5) по-прежнему сильнее, чем Vicuna в самой задаче. MPT плохо справлялся почти со всеми задачами (может быть, мы неправильно его используем?), тогда как Vicuna часто была близка к ChatGPT (иногда очень близко, иногда намного хуже, как в последнем примере задачи выше).
- Простота использования . Гораздо труднее заставить ChatGPT следовать указанному выходному формату, и поэтому его сложнее использовать внутри программы (без участия человека). Кроме того, нам всегда приходится писать парсеры регулярных выражений для вывода (в отличие от Vicuna, где разбор подсказки с понятным синтаксисом тривиален).
Обычно мы можем решить проблему структуры, добавляя несколько примеров, но писать их утомительно, и иногда ChatGPT все равно выходит за рамки сценария. Мы также получаем подсказки, которые длиннее, неуклюже и уродливее, что нас не удовлетворяет.
Возможность указать структуру вывода является значительным преимуществом моделей с открытым исходным кодом., до такой степени, что иногда мы можем предпочесть Vicuna ChatGPT, даже если он немного хуже справляется с самой задачей. - Эффективность : наличие модели локально означает, что мы можем решать задачи за один запуск LLM (
guidance
сохранение состояния LLM во время выполнения программы), что быстрее и дешевле. Это особенно верно, когда какие-либо подэтапы включают вызов других API или функций (например, поиск, терминал и т. д.), что всегда требует нового вызова API OpenAI.guidance
также ускоряет генерацию, поскольку модель не генерирует токены выходной структуры, что иногда имеет большое значение.
Мы должны признать, что мы предвзяты из-за того, что за последние несколько лет много использовали модели OpenAI, написали различные статьи, которые зависят от GPT-3 (например, здесь , здесь ), и статью , в которой в основном говорится: «GPT-4 — это круто». , вот куча крутых примеров».
Говоря об этом, хотя Vicuna в некоторой степени сопоставима с ChatGPT (3.5), мы считаем, что GPT-4 является гораздо более сильной моделью, и мы рады видеть, могут ли модели с открытым исходным кодом приблизиться к этому . Несмотря на то, что guidance
с моделями OpenAI работает довольно хорошо, он действительно сияет, когда вы можете указать структуру вывода и ускорить генерацию.
Опять же, мы явно предвзяты, но думаем, что guidance
это отличный способ использовать эти модели, будь то с API (OpenAI, Azure) или локально (huggingface). Вот ссылка на блокнот Jupyter с кодом для всех приведенных выше примеров (и не только).
Отказ от ответственности : этот пост был написан совместно Марко Тулио Рибейро и Скоттом Лундбергом. Он строго отражает наше личное мнение, а не мнение нашего работодателя (Майкрософт).
Благодарности: мы очень благодарны Харше Нори за проницательные комментарии к этому посту.