Привет, Хабр! Меня зовут Никита Кулин, ML-Engineer NLP моделей. Это мой первый пост, поэтому буду рад любой обратной связи!

Интро

Большие языковые модели (LLM или БЯМ) становятся все более распространенными в производственных средах, поскольку они предлагают широкий спектр возможностей для автоматизации и повышения эффективности различных бизнес-процессов:

  • Используются для автоматической генерации текстового контента (статьи, описания продуктов, ответы на часто задаваемые вопросы)

  • Применяются для анализа и понимания естественного языка, что позволяет автоматизировать NLP задачи (классификация, извлечение сущностей, ответы на вопросы)

  • Используются для создания персонализированных рекомендаций и предложений для клиентов на основе их предпочтений и поведения

  • Интегрируются в различные бизнес-приложения и системы для автоматизации рутинных задач (составление отчетов, ответы на запросы клиентов, планирование)

Сегодня не обучают с нуля свою LLM, можно найти open-sourced pre-train/instruct LLM на свой вкус под свои требования. Процесс адаптации LLM под конкретную задачу может включать в себя последующие этапы: prompt-engineering, PEFT (Parameter efficient fine-tuning) и fine-tuning. Обычно к PEFT переходят сразу после создания MVP промптов и оценки на изначальной LM, однако PEFT более требователен к использованию: достаточные объемы данных для дообучения, качественная разметка (желательно написанная разметчиками и провалидированная бизнесом), лаконичная и понятная промпт-инструкция, вычислительные ресурсы GPU для расчетов.

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

В этом гайде мы поговорим (1) о подготовке к prompt-engineering, (2) о базовых принципах написания промпта, про его структуру и про типы решаемых задач, (3) о продвинутых техниках через рассуждения для повышения качества ответа и снижения вероятности появления галлюцинаций.

Гайд основан на открытых источниках и на моем личном опыте.

Подготовка к Prompt-Engineering

Выбор LLM

В последнее время LLM быстро обновляются, появляются новые модели. Обычно я подбираю модели тут в paper with code, в extractum.io, также смотрю обновления в HuggingFace и в Телеграм DS каналах.

Смотрите на значения метрик по этим бенчмаркам: MMLU и GLUE - они проверяют способность модели решать основные задачи на понимание языка.

Выбор NLP моделей обычно опирается на следующие критерии.

Размер модели

Обычно смотрят от 7b до 70b. Зависит (1) от кол-ва вычислительных ресурсов и возможностей уменьшить модель (через квантизацию, прунинг и др.), (2) от скорости инференса (меньше модель - быстрее получаем ответ), (3) от качества ответа (больше модель - лучше ответ).

На своей практике я использую этот чудо-калькулятор из HuggingFace, который помогает просчитать заранее объем утилизации памяти в GPU или CPU c учетом понижения числовой точности (до int4, int8) прежде, чем загружу модель на рабочее место.

Знание необходимых языков

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


Не стоит делать перевод промпта с вашего языка в другой. Во‑первых, придется проверять качество перевода. Во‑вторых, есть исследование от Google — вкратце: пишите на своем языке, не нужно переводить промпт.

Список NLP задач, на которых модель обучалась

Вам же интересен выбранный тип ML задачи. Поговорим об этом ниже.

Сводим ТЗ под ML задачу

Во-первых, надо определить постановку задачи. Этот этап является хорошей практикой для понимания формулировки ТЗ и определяет формат запроса и ответа в будущих промптах. Цель проста - уметь объяснить вашу задачу себе и LLM. Так как текущие LLM обучались на множестве различных типов NLP задач и подзадач, для того, чтобы модель смогла адаптироваться к новым запросам. 

Лучше всего сводить к известным задачам, такие как:

  • Классификация

    • Напиши, какое настроение в тексте: положительное или отрицательное

  • Суммаризация

    • Напиши краткий пересказ текста

  • QA (Вопрос-ответ)

    • Какое время года описано в тексте?

  • Перевод (человеческий, text-to-code)

    • Переведи текст ниже с … на … язык

  • Распознавание именованных сущностей (NER)

    • Перечисли все имена, которые упомянуты в тексте

Создадим MVP-промпт

Структура промпта

Во времена активного использования gpt-2 раньше промпт состоял из префикса, например: “summarize/translate this text ...", "answer ...”. На сегодня, когда мы говорим про промпт, это уже полноценная инструкция в человеческом представлении.

Cлайд 1. Пример современных инструктивных промптов
Cлайд 1. Пример современных инструктивных промптов

Поговорим о классификации промптов.

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

Пользовательский промпт (User prompt) — промпт, в котором формируем наш конкретный запрос, чтобы получить ответ. User prompt лучше расписывать детально и ясно. Для наилучшего результата лучше расписывать по структуре. Ниже обсудим шаблон структуры user prompt, которой я придерживаюсь. Структура включает в себя следующие главы:

  1. Контекст

Опишите вводные данные, что они из себя представляют.

“Тебе дан диалог между Ромео и Джульеттой, ограниченный тегами <dialog>”

  1. Запрос

Укажите свой основной запрос, какую задачу должна решать модель.

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

  1. Ответ

Укажите, как должен выглядеть ответ (зависит от типа решаемой ML задачи):

  • кратким или детальным

  • с каких слов должен начинаться

  • как должна вести себя модель, если нет контекста

"Формат ответа
- Отвечай коротко
- Ответ начинается с 'Ромео планирует'
- Пиши 'Нет ответа', если не найдешь информацию"

4. Мотивация (опционально)

Модель иногда хорошо реагирует, если указать важность или мотивацию ответа. Указывается это так:

  • “Соблюдай формат, условия и порядок ответов!”

  • “Это важно для моей карьеры!”

  • “ЭТО ОЧЕНЬ ВАЖНО ДЛЯ МЕНЯ!!!”

  • ну или покажите лицо этого парня и текст ниже

Слайд 2. Я ДАМ МИЛЛИОН ДОЛЛАРОВ ТОМУ, КТО РЕШИТ..
Слайд 2. Я ДАМ МИЛЛИОН ДОЛЛАРОВ ТОМУ, КТО РЕШИТ..

Мотивация заработать денег положительно сказывается на качество, причем, чем больше денег — тем лучше метрики.

Перебор промптов

Нет универсальных промптов — каждая модель будет отвечать по‑своему.

Пробуйте создавать разные вариации как промпта, так и структуры промпта в целом. Например, сделайте разные комбинаций вариантов глав и оценивайте каждый по метрикам.

Совет: варианты глав должны быть разными не только пословно, но и структурно — менять исходный промпт на одно слово не имеет смысла.

Помимо этого можно поискать в Интернете другие шаблоны — плюс‑минус они будут похожи между собой.

Улучшаем промпт

Prompt Engineering не стоит на месте. За последние годы появились новые виды промптов, которые работают через «рассуждения» самой модели.

Chain-of-Thought (CoT)

Chain‑of‑thought (CoT) — это метод, который направлен на стимулирование модели логическому мышлению и объяснению своих шагов при решении задач. Он отличается от стандартного prompting, который только требует ответа, а не объяснения процесса решения. Достаточно показать пример рассуждения через shot‑пример, чтобы модель аналогично показала рассуждение для вашего запроса.

Слайд 3. Пример работы CoT в сравнении с one-shot
Слайд 3. Пример работы CoT в сравнении с one-shot

В статье они приводят сравнение между one‑shot и one‑shot c CoT. Авторы показали эффективность решения математических задач в текстовой постановке — где видна проблема неправильной очередности арифметических действий для получения верного ответа без использования рассуждения.

Zero-shot CoT

Этот подход является продолжением оригинального CoT — вместо использования shot‑примера давайте внедрим триггер‑фразу для вызова рассуждения модели. И это про известную фразу «Let's think step by step».

В статье триггер‑фраза используется в промпте в качестве начала ответа модели. На сегодня данная формулировка может использоваться в самой инструкции, например, использовать в главе «формат ответа»

Слайд 4. Пример сравнения Zero-shot CoT с другими подходами
Слайд 4. Пример сравнения Zero-shot CoT с другими подходами

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

Слайд 5. Использование различных триггер-фраз и их эффективность
Слайд 5. Использование различных триггер-фраз и их эффективность

Prompt Chaining

Если ваша задача сложна, чтобы описать одним вызовом, то лучше декомпозируйте ее на подзадачи.

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

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

По моему опыту хорошо работает следующая цепочка:

Промпт 1. Делаем саммари документа
Фильтруем ненужную информацию, оставив только тот контекст, который нам нужен

"Тебе дана часть диалога Ромео и Джульеттой, ограниченный тегами <dialog>. Составь саммари по диалогу, включив туда дальнейшие действия и планы Ромео."

Промпт 2. Задаем целевой запрос

"Найди в саммари, заключенный тегами <summary>, информацию о дальнейших планах Ромео, если найдешь"

Промпт 3 (Опционально). Подтверждение извлеченного ответа. 

Помогает фильтровать галлюцинации (ложные извлеченные ответы)

"Тебе дан диалог между Ромео и Джульеттой и следующее утверждение про планы Ромео {statement}. Является ли данное утверждение следствием диалога?"

Self-Consistency

Из интересных техник хотел бы упомянуть self-consistency. Идея заключается в том, чтобы с помощью few-shot CoT проанализировать множество разнообразных путей рассуждений и использовать несколько ответов для выбора наиболее подходящего через наиболее встречаемого. 

Пример промпта:

Q: There were nine computers in the server room. Five more computers were installed each day, frommonday to thursday. How many computers are now in the server room?
A: There are 4 days from monday to thursday. 5 computers were added each day. That means in total 4 * 5 =20 computers were added. There were 9 computers in the beginning, so now there are 9 + 20 = 29 computers.The answer is 29.
Q: Michael had 58 golf balls. On tuesday, he lost 23 golf balls. On wednesday, he lost 2 more. How manygolf balls did he have at the end of wednesday?
A: Michael initially had 58 balls. He lost 23 on Tuesday, so after that he has 58 - 23 = 35 balls. OnWednesday he lost 2 more so now he has 35 - 2 = 33 balls. The answer is 33.
Q: Olivia has $23. She bought five bagels for $3 each. How much money does she have left?
A: She bought 5 bagels for $3 each. This means she spent 5
Q: When I was 6 my sister was half my age. Now I’m 70 how old is my sister?/
A:

Ответ 1: When I was 6 my sister was half my age, so she was 3. Now I am 70, so she is 70 - 3 = 67. The answer is 67.

Ответ 2: When the narrator was 6, his sister was half his age, which is 3. Now that the narrator is 70, his sister would be 70 - 3 = 67 years old. The answer is 67.

Ответ 3: When I was 6 my sister was half my age, so she was 3. Now I am 70, so she is 70/2 = 35. The answer is 35.

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

Self-discover

Относительно недавно один из потенциальных подходов в prompt-engineering предложил Google. Идея такая - давайте модель сама решит, как рассуждать под вашу задачу.

Задача решается в три промпта.

Шаг 1. Select

Cначала выбираются какие варианты рассуждений лучше всего подходят для полученного задания

Слайд 6. Промпт для этапа Select
Слайд 6. Промпт для этапа Select

Шаг 2. Adapt

Выбранные рассуждения адаптируются моделью под домен задачи

Слайд 7. Промпт для этапа Adapt
Слайд 7. Промпт для этапа Adapt

Шаг 3. Implement

Список адаптированных рассуждений применяется для генерации ответа

Слайд 8. Промпт для этапа Implement
Слайд 8. Промпт для этапа Implement

Такой подход уже реализован в фреймворке self-discover. В нем уже предоставляется список из 39 рассуждений. Этот список можно расширять своими рассуждениями или готовыми, взятые из работы Promptbreeder от Google DeepMind.

Заключение

Это не все продвинутые техники, о которых я бы хотел рассказать. Подведем итоги по шагам prompt-engineering.

Подготовьтесь к Prompt Engineering

  • Сформулируйте ваше ТЗ как ML-задачу

  • Выберите несколько LLM для экспериментов

  • Определите целевые метрики оценки ответа

Напишите mvp промпт

  • Создайте первую инструкцию, соблюдая структуру промпта

  • Экспериментируйте с разными вариантами промптов

Улучшайте промпт через рассуждения

  • Попробуйте подходы рассуждения CoT, Self-Consistency или Self-discover

Спасибо за внимание! Пишите в комментариях, полезен ли вам был этот гайд, и про ваш опыт в prompt-engineering. 

Комментарии (3)


  1. Tiendil
    09.07.2024 08:24

    Как раз недавно сделал пост про промты своих GPTешек (Open AI позволяет выносить специализированные промпты в отдельные чаты) с пояснениями как они устроены.

    Если интересует практический пример, то вот: https://tiendil.org/ru/posts/my-gpts


    1. mrcoolinhabr Автор
      09.07.2024 08:24
      +1

      Спасибо за пример!


  1. krapka00
    09.07.2024 08:24

    Спасибо, всё супер и понятно расписано!