newsmode
search
Меню
arrow_back Назад

AI Engineer 2023 Keynote - Building Blocks for LLM Systems

auto_awesomeКраткое саммари

Доклад Eugene Yan на первом AI Engineer Summit 2023 посвящён ключевым строительным блокам для систем на основе LLM: оценкам (evals), RAG, защитным ограничениям (guardrails) и сбору обратной связи. Автор подчёркивает, что единого подхода к оценке LLM пока нет — даже простые изменения форматирования в бенчмарках вроде MMLU могут существенно влиять на точность. В части RAG показано, что точность ответов резко падает, когда нужный документ оказывается в середине контекста, а не в начале или конце. Для борьбы с галлюцинациями предлагаются методы NLI на уровне предложений, сэмплирование нескольких саммари и оценка сильной LLM. Отдельно рассмотрена проблема сбора обратной связи: явный фидбэк слишком разрежен, а неявный — зашумлён, и удачный UX (как у GitHub Copilot и Midjourney) критически важен для получения качественных данных.

Доклад на AI Engineer 2023 — Строительные блоки для систем на основе LLM

[ llm ai engineering production ] · 17 мин. чтения

Меня пригласили выступить с докладом на первом AI Engineer Summit в Сан-Франциско. В основном это комбинация моих недавних статей о паттернах проектирования LLM-систем и оценках для абстрактной суммаризации, хотя и сильно сокращённая (каждому спикеру давали всего 18 минут!). Ниже — слайды и тезисы моего выступления.

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

• • •

Спасибо за тёплый приём! Меня зовут Eugene Yan, и сегодня я хотел бы поговорить с вами о строительных блоках для систем и продуктов на основе LLM.

Как и многие из вас, я пытаюсь разобраться, как эффективно использовать LLM… в продакшене.

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

(Примечание: доклад Jason был прямо перед моим.)

Сегодня я сосредоточусь на четырёх из этих паттернов: оценки (Evaluations), генерация с дополнением извлечением (RAG), защитные ограничения (Guardrails) и сбор обратной связи (Collecting Feedback). На сбор обратной связи времени может не хватить, но посмотрим.

Итак, начнём с оценок — того, что я считаю фундаментом.

Зачем нам нужны оценки?

Оценки помогают понять, движемся ли мы в правильном направлении с промпт-инжинирингом, дополнением извлечением или файнтюнингом. Можно назвать это разработкой на основе оценок (eval-driven development), где оценки направляют процесс построения системы и продукта.

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

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

Но создавать оценки сложно. Вот несколько подводных камней, на которых я видел, как люди спотыкаются.

Во-первых, у нас нет единого подхода к оценке LLM.

Если посмотреть на более традиционное машинное обучение: для регрессии у нас есть среднеквадратичная ошибка, для классификации — precision и recall, для ранжирования — NDCG. Эти метрики довольно просты, и обычно есть один основной способ их вычислить.

А как обстоят дела с LLM? Ну, есть бенчмарки, где модели дают промпт и варианты ответа с множественным выбором, а затем оценивают её способность выбрать правильный. MMLU — широко используемый пример, оценивающий знания и логику LLM в задачах университетского уровня по математике, информатике и истории США.

Но единого способа проводить MMLU не существует. Как недавно отметили Arvind и Sayash, оценка LLM — это минное поле. Они справедливо указали, что неясно, оцениваем ли мы саму LLM или промпты, с помощью которых мы её оцениваем.

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

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

Говоря об академических бенчмарках, возможно, мы уже переросли некоторые из них. Рассмотрим, например, задачу суммаризации.

Вверху мы видим человеческие оценки эталонных саммари для датасета CNN/Daily Mail. А внизу — оценки автоматических саммари, сгенерированных различными моделями. Необязательно сравнивать все числа, но суть в том, что эталонные саммари получают более низкие оценки, чем автоматические.

То же самое мы видим на датасете XSUM, что означает «экстремальная суммаризация». Здесь эталонные саммари получают более низкие человеческие оценки, чем InstructGPT.

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

(Примечание: доклад Linus был сразу после моего.)

Как индустрия, мы всё ещё выясняем, как эффективно проводить оценки. Тем не менее, я думаю, что некоторые принципы уже формируются.

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

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

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

Но если задача открытая — например, диалог — возможно, придётся полагаться на сильную LLM для оценки результатов. Тем не менее это может быть дорого, даже для небольшого набора из 60 примеров.

И наконец, даже если у вас есть автоматические оценки, не недооценивайте пользу визуального просмотра результатов. Вот что говорит Jonathan из Mosaic: «Я не верю, что какие-либо из этих метрик оценки отражают то, что нас на самом деле волнует». Вместо этого у них был промпт с предложением игр для трёхлетнего и семилетнего ребёнка, и им было полезнее наблюдать, как результаты менялись со временем.

Далее перейдём к генерации с дополнением извлечением (RAG) — к тому, что я считаю данными.

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

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

Но извлекать правильные документы сложно. Тем не менее, поскольку у нас уже есть отличные спикеры — Jerry и Anton — которые будут говорить об этом завтра, я не буду углубляться в проблемы извлечения. Вместо этого я хотел бы сосредоточиться на стороне LLM и обсудить некоторые проблемы, которые остаются даже при наличии RAG.

Первая из них — LLM не могут по-настоящему видеть все извлечённые документы.

Вот эксперимент из недавней статьи. Задача — вопросно-ответная система с дополнением извлечением. Вопросы основаны на реальных запросах в Google Search, а ответы — это аннотированные людьми ответы из Wikipedia.

В качестве контекста предоставлялось 20 документов длиной не более 100 токенов каждый. Итого контекст — максимум 2 000 токенов. Один из документов содержал ответ, остальные были отвлекающими: релевантными, но не содержащими ответа.

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

Вот что они обнаружили.

Если ответ находится в первом извлечённом документе, точность максимальна.

Когда ответ в последнем документе, точность приемлемая.

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

Ключевой вывод: не стоит пренебрегать качеством извлечения только потому, что размеры контекстных окон растут. Важно, чтобы наиболее релевантные документы оказывались в топ-1–3 позициях.

Кроме того, даже если ответ есть в контексте и находится на первой позиции, точность составляет всего 75%. Таким образом, даже при идеальном извлечении мы всё равно можем ожидать ошибки.

Ещё один подводный камень — LLM не могут по-настоящему определить, что извлечённые документы нерелевантны.

Вот пример, который я попробовал с GPT-4: я дал ему список из 20 лучших фантастических фильмов — можно считать, что это фильмы, которые я смотрел. Затем я спросил, понравится ли мне «Сумерки». Для тех, кто не знаком с «Сумерками» — это романтическое фэнтези о девушке и вампире, и ещё там есть оборотни. Думаю, примерно так, потому что сам я его не смотрел.

У меня также была инструкция: если модель считает, что мне не понравятся «Сумерки», она должна ответить «Не применимо». В рекомендательных системах важно уметь это делать, чтобы не давать плохих рекомендаций.

Как вы думаете, что она ответила?

Вот что произошло. Сначала модель отмечает, что «Сумерки» — это другой жанр и не совсем фантастика, что отлично!

Но затем она рекомендует «Инопланетянина» из-за межвидовых отношений, и я не совсем уверен, как к этому относиться. <зал смеётся>

(Примечание: это не задумывалось как шутка, так что смех зала стал приятным сюрпризом 😊)

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

Так как же лучше всего справляться с этими ограничениями RAG?

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

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

Следующий пункт — защитные ограничения (guardrails), посредник между нашими бэкенд-системами и фронтенд-интерфейсом.

Ключевая задача — убедиться, что то, что мы развёртываем, безопасно. Что мы имеем в виду под «безопасно»? Можно посмотреть на API модерации OpenAI и изучить, что они отслеживают. Там есть ненависть, преследование, самоповреждение, насилие и прочее в том же духе.

Ещё один аспект, от которого мы хотим защититься, — фактическая несогласованность, также известная как галлюцинации. Выдача нефактуального контента, например неточных саммари, может разрушить доверие пользователей.

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

Один из подходов к оценке фактической несогласованности — задача вывода на естественном языке (NLI).

Задача NLI состоит в том, что, имея посылку и гипотезу, мы классифицируем гипотезу как истинную или ложную. Например, имея посылку «Джон любит все фрукты», гипотеза «Джон любит яблоки» истинна и, следовательно, является следствием (entailment).

А поскольку информации недостаточно, чтобы подтвердить, что «Джон ест яблоки каждый день», это нейтральное утверждение.

И наконец, гипотеза «Джон не любит яблоки» явно ложна исходя из посылки и, следовательно, является противоречием.

Видите, как это можно применить к задаче суммаризации? В суммаризации документ — это посылка, а саммари — гипотеза.

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

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

Ещё один простой подход — сэмплирование.

Вот пример из SelfCheckGPT. Для входного документа мы генерируем саммари несколько раз. Затем проверяем, похожи ли сгенерированные саммари друг на друга — например, по пересечению n-грамм или близости эмбеддингов.

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

Но если саммари похожи, то можно предположить, что они эффективно основаны на контексте и, скорее всего, фактически согласованы с исходным документом.

Последний подход — спросить сильную LLM.

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

Итак, чтобы замкнуть круг, кратко коснёмся сбора обратной связи.

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

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

Но собирать обратную связь от пользователей не так просто, как кажется. Явная обратная связь — та, которую мы запрашиваем у пользователей — может быть очень разреженной. Вот небольшой мысленный эксперимент.

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

<Около дюжины слушателей из 500 подняли руки>

Вот вы — те самые бета-тестеры, о которых мечтают разработчики продуктов. <зал смеётся>

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

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

Вот тот же пример: как часто вы нажимаете кнопку копирования кода?

<30–50 человек подняли руки>

Но означает ли нажатие кнопки копирования кода, что код корректен?

(Примечание: в этот момент ответ ещё не был раскрыт.)

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

Так как же собирать обратную связь? Хороший пример — GitHub Copilot. Для тех, кто не знаком: вы пишете сигнатуру функции или комментарии, а он предлагает код. Далее, получив предложение, мы можем либо принять его, перейти к следующему, либо отклонить или проигнорировать. Мы также можем принять код и внести небольшие правки.

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

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

Но знаете, что видит AI-инженер?

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

Вариация одного из изображений — это слабый положительный сигнал: пользователь говорит — у этого изображения есть потенциал.

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

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

Во-первых, вам нужны оценки для вашей задачи. Просто разметьте 30 или 100 примеров для вашей задачи и постарайтесь автоматизировать оценку на них. Это поможет быстрее итерировать промпт-инжиниринг, дополнение извлечением, файнтюнинг и так далее. Это также поможет быстрее выкатывать обновления. Визуальная проверка не масштабируется — она хороша как финальная проверка «на ощущение», но не масштабируется.

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

И наконец, UX играет огромную роль в продуктах на основе LLM. Я считаю, что значительная часть успеха GitHub Copilot и ChatGPT — это UX: он позволил пользователям взаимодействовать с ними там, где нужно — в IDE или в окне чата — вместо того чтобы вызывать API. Правильный UX также облегчает сбор полезной обратной связи.

На этом всё. Спасибо, и продолжайте создавать.

Неиспользованные слайды

Вот несколько слайдов, которые не вошли в финальную презентацию, в основном из-за строгого лимита в 18 минут (они грозились включить оскаровскую музыку на 18-й минуте, ха-ха).

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

Изначально это был слайд 3, где я бы сказал что-то вроде: «В книжном магазине я в основном занимаюсь рекомендательными системами и поиском. Но всё чаще, как и многие из вас, я пытаюсь понять, как использовать этот новый источник энергии, соединительную ткань и операционную систему». Но это звучало слишком растянуто, и я убрал слайд, чтобы сэкономить 30 секунд. Жаль — мне очень нравились аналогия и изображение инопланетного лего.

(Интересно, что OpenAI тоже назвали LLM соединительной тканью для мультимодальности.)

По поводу отсутствия хорошего способа оценки LLM — изначально у меня были примеры, основанные на глубоком разборе от 🤗, включавшем сравнения промптов, методологий оценки и различий в ранжировании. Мне казалось интересным посмотреть на различия, но, к сожалению, времени не хватило. Этот слайд и следующие 3 были убраны, чтобы сэкономить ~2 минуты.

Сравнение промптов для MMLU.

Сравнение подходов к оценке MMLU.

Как меняется ранжирование моделей в зависимости от реализации MMLU.

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

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

Абстрактная суммаризация нескольких документов для построения хронологии.

Абстрактная суммаризация еженедельных расходов.

Изначально этот слайд был примером серьёзности галлюцинаций в суммаризации, на основе этой статьи, которой на тот момент было едва ли месяц. Тем не менее он был убран, чтобы сэкономить ~30 секунд.

Изначально я хотел включить QG-QA как метод оценки фактической согласованности в суммаризации, потому что это один из двух основных подходов к обнаружению фактической несогласованности (другой — NLI). Но мне не понравилась сложность метода, и я не видел, как его можно применить в продакшене. Поэтому он был убран, чтобы сэкономить ~1 минуту.

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

Если вам это было полезно, пожалуйста, цитируйте этот материал следующим образом:

Yan, Ziyou. (Oct 2023). AI Engineer 2023 Keynote - Building Blocks for LLM Systems. eugeneyan.com. https://eugeneyan.com/speaking/ai-eng-summit/.

или

@article{yan2023aieng, title = {AI Engineer 2023 Keynote - Building Blocks for LLM Systems}, author = {Yan, Ziyou}, journal = {eugeneyan.com}, year = {2023}, month = {Oct}, url = {https://eugeneyan.com/speaking/ai-eng-summit/} }



Присоединяйтесь к 11 800+ читателям, которые получают обновления о машинном обучении, RecSys, LLM и инженерии.