Как стать автором
Обновить

Перевод: Чему мы научились за год построения проектов с LLM. Часть 1

Уровень сложностиСредний
Автор оригинала: Eugene Yan, Bryan Bischof, Charles Frye, Hamel Husain, Jason Liu and Shreya Shankar

https://www.oreilly.com/radar/what-we-learned-from-a-year-of-building-with-llms-part-i/

Hidden text

Переведено с помощью БЯМ (LLM). Несмотря на прогресс автоматизированных средств перевода, лучше все таки прочитать в оригинале.

Это захватывающее время для создания проектов с использованием больших языковых моделей (БЯМ, LLM). За последний год LLM стали «достаточно хороши» для реальных приложений. Темпы совершенствования LLM в сочетании с демонстрацией их возможностей в социальных сетях приведут, по оценкам, к инвестициям в искусственный интеллект в размере 200 миллиардов долларов к 2025 году. LLM также широко доступны, что позволяет не только специалистам по машинному обучению и ученым, но и всем желающим создавать интеллектуальные функции для своих продуктов. Хотя барьер для входа на рынок AI-продуктов снизился, создание по-настоящему эффективных решений по-прежнему является обманчиво сложной задачей.

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

У нас различный профессиональный опыт и мы трудимся в различных ролях, но все мы на собственном опыте столкнулись с проблемами, связанными с использованием этих новых технологий. Двое из нас — независимые консультанты, которые помогли многим клиентам реализовать проекты LLM, начиная с первоначальной концепции и заканчивая успешным продуктом, и видели шаблоны, определяющие успех или неудачу. Один из нас — исследователь, изучающий работу команд ML/AI и способы улучшения их рабочих процессов. Двое из нас — лидеры прикладных команд AI: один в крупной технологической компании, а другой в стартапе. Наконец, один из нас преподавал глубокое обучение тысячам студентов и теперь работает над тем, чтобы сделать инструменты и инфраструктуру AI более удобными для использования. Несмотря на наш разный опыт, нас поразили схожие постоянные темы в извлеченных нами уроках, и мы удивлены, что эти идеи не обсуждаются более широко.

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

Эта работа состоит из трех разделов: тактического, операционного и стратегического. Это первая из трех частей. В ней подробно рассматриваются тактические аспекты работы с LLM. Мы делимся передовым опытом и типичными ошибками, связанными с промптами, настройкой генерации с дополненным извлечением (RAG), применением инженерии потока (flow engineering), оценкой и мониторингом. Независимо от того, практикующий ли вы специалист по созданию проектов с LLM или энтузиаст, работающий над проектами на выходных, этот раздел написан для вас. Следите за операционными и стратегическими разделами в ближайшие недели.

Готовы погрузиться в детали? Давайте начнем.

Тактический раздел

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

Промпты (подсказки)

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

Сосредоточьтесь на получении максимальной отдачи от фундаментальных техник промптов
Несколько техник подсказок последовательно помогали улучшить производительность различных моделей и задач: подсказки n-shot + обучение в контексте, цепь мыслей (CoT) и предоставление соответствующей информации.

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

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

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

  3. Вам не обязательно предоставлять полный набор пар входных-выходных данных. Во многих случаях достаточно предоставить примеры желаемых выходных данных.

  4. Если вы используете LLM, который поддерживает использование инструментов (Tools - OpenAI), ваши примеры n-shot должны также использовать инструменты, которые вы хотите, чтобы агент использовал.

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

  1. Перечислите ключевые решения, последующие действия и соответствующих владельцев в наброске.

  2. Затем проверьте, согласуются ли детали в наброске с протоколом.

  3. Синтезируйте ключевые моменты в краткое резюме.

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

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

Структурируйте входные и выходные данные

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

Например, многие вопросы в Интернете о написании SQL начинаются с указания схемы SQL. Таким образом, вы можете ожидать, что эффективный промптинг для Text-to-SQL должен включать структурированные определения схемы (так и есть).

Структурированный вывод выполняет аналогичную цель, но он также упрощает интеграцию в последующие компоненты вашей системы. Instructor и Outlines хорошо подходят для структурированного вывода. (Если вы импортируете LLM API SDK, используйте Instructor; если вы импортируете Huggingface для самостоятельно размещенной модели, используйте Outlines Структурированный ввод ясно выражает задачи и напоминает форматирование обучающих данных, увеличивая вероятность лучшего вывода.

При использовании структурированного ввода имейте в виду, что каждое семейство LLM имеет свои собственные предпочтения. Claude предпочитает XML, в то время как GPT предпочитает Markdown и JSON. С XML вы даже можете предварительно заполнять ответы Claude, предоставляя response тег ответа:

</> python messages=[ { "role": "user", "content": """Extract the <name>, <size>, <price>, and <color> from this product description into your <response>. <description>The SmartHome Mini is a compact smart home assistant available in black or white for only $49.99. At just 5 inches wide, it lets you control lights, thermostats, and other connected devices via voice or app—no matter where you place it in your home. This affordable little hub brings convenient hands-free control to your smart devices. </description>""" }, { "role": "assistant", "content": "<response><name>" } ]

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

Промпт обычно начинается просто: несколько предложений инструкций, несколько примеров, и мы готовы к работе. Но по мере того, как мы пытаемся улучшить производительность и обрабатывать больше пограничных случаев, сложность накапливается. Больше инструкций. Многошаговое рассуждение. Десятки примеров. Прежде чем мы заметим, наш изначально простой промпт превращается в Франкенштейна из 2000 токенов. И, что хуже, он имеет худшую производительность на обычных, простых входных данных! GoDaddy поделился этим вызовом как своим основным уроком от создания с LLM.

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

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

  • Проверить извлеченные детали в сравнении с первоначальной транскрипции на соответствие

  • Сгенерировать краткое резюме из структурированных деталей

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

Создайте свои контекстные токены
Пересмотрите и поставьте под сомнение свои предположения о том, сколько контекста вам действительно нужно отправить агенту. Будьте как Микеланджело, не создавайте скульптуру из контекста, а скорее, отбивайте лишний материал, пока не появится скульптура. RAG — популярный способ сбора всех потенциально важных блоков мрамора, но как вы извлекаете необходимое?

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

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

Извлечение информации (Information Retrieval/RAG)

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

Качество результатов RAG зависит от качества извлеченных документов, которые, в свою очередь, можно оценить с точки зрения нескольких факторов.

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

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

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

Наконец, рассмотрим уровень детализации, предоставленный в документе. Представьте, что мы создаем систему RAG для генерации запросов SQL на естественном языке. Мы могли бы просто предоставить схемы таблиц с именами столбцов в качестве контекста. Но что, если мы включим описания столбцов и некоторые примеры значений? Дополнительные сведения могут помочь LLM лучше понять семантику таблицы и сгенерировать более правильные запросы SQL.

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

Учитывая, насколько распространен пример RAG на основе embedding, легко забыть или упустить из виду опыт десятилетий исследований и решений в области поиска и извлечения информации.

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

Векторные embedding-и не решают магическим образом задачи поиска. На самом деле, тяжелая работа заключается в шаге перед тем, как вы ранжируете с помощью семантического поиска по сходству. Сделать реальное улучшение по сравнению с BM25 или полным текстовым поиском сложно.
Vector embeddings do not magically solve search. In fact, the heavy lifting is in the step before you re-rank with semantic similarity search. Making a genuine improvement over BM25 or full-text search is hard.

— Аравинд Шринивас, генеральный директор Perplexity.ai

Мы месяцам доносим это до наших клиентов и партнеров. "Поиск Ближайшего Соседа" с наивными embedding-ами дает очень "шумные" результаты, и вам лучше начать с подхода на основе ключевых слов.
We’ve been communicating this to our customers and partners for months now. Nearest Neighbor Search with naive embeddings yields very noisy results and you’re likely better off starting with a keyword-based approach.

— Бейян Лю, главный технический директор Sourcegraph

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

В большинстве случаев лучше всего подойдет гибрид: совпадение ключевых слов для очевидных совпадений и embedding-и для синонимов, гиперонимов и ошибок в написании, а также мультимодальности (например, изображения и текст). Shortwave поделился тем, как они создали свой конвейер RAG, включая переписывание запросов, поиск по ключевым словам + embedding-ам и ранжирование.

Предпочтите RAG вместо тонкой настройки (fine tuning) для новых знаний
И RAG и тонкая настройка (fine tuning) могут использоваться для включения новой информации в LLM и повышения производительности при выполнении конкретных задач. Что стоит пробовать в первую очередь?

Недавние исследования показывают, что у RAG может быть преимущество. В одном исследовании RAG был сравнен с несупервизированной тонкой настройкой (unsupervised fine-tuning, также известной как непрерывная предварительная подготовка - continued pre-training), при этом оба метода были оценены на подмножестве MMLU и текущих событиях. Они обнаружили, что RAG последовательно превосходит тонкую настройку (fine tuning) для знаний, полученных во время обучения, а также для совершенно новых знаний. В другой работе они сравнили RAG с супервизированной тонкой настройкой (supervised fine tuning) на наборе данных по сельскому хозяйству. Аналогичным образом, повышение эффективности с помощью RAG было больше, чем с помощью тонкой настройки, особенно для GPT-4 (см. таблицу 20 в статье).

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

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

Модели с большим контекстным окном не сделают RAG устаревшими
С появлением Gemini 1.5, обеспечивающим окна контекста размером до 10 миллионов токенов, некоторые начали сомневаться в будущем RAG.

I tend to believe that Gemini 1.5 is significantly overhyped by Sora. A context window of 10M tokens effectively makes most of existing RAG frameworks unnecessary—you simply put whatever your data into the context and talk to the model like usual. Imagine how it does to all the startups/agents/LangChain projects where most of the engineering efforts goes to RAG 

 Or in one sentence: the 10m context kills RAG. Nice work Gemini.— Yao Fu

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

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

Наконец, есть затраты. Затраты на инференс модели Transformer увеличиваются квадратично с длиной контекста. То, что существует модель, способная прочитать все содержимое Google Drive вашей организации перед ответом на каждый вопрос, еще не означает, что это хорошая идея. Рассмотрим аналогию с тем, как мы используем ОЗУ: мы все еще читаем и записываем с диска, даже несмотря на то, что существуют вычислительные экземпляры с ОЗУ в десятки терабайт.

Так что еще не время выбрасывать ваши RAG. Этот паттерн останется полезным даже при увеличении размера окон контекста.

Tuning and optimizing workflows (Настройка и оптимизация процессов)

Создание промпта для LLM — это только начало. Чтобы получить максимальную отдачу, нам нужно думать не только о одном промпте, но и о рабочих процессах. Например, как мы можем разбить одну сложную задачу на несколько более простых? Когда тонкая настройка или кэширование могут помочь повысить производительность и снизить задержку/стоимость? В этом разделе мы делимся проверенными стратегиями и реальными примерами, чтобы помочь вам оптимизировать и создать надежные рабочие LLM процессы .

Шаг за шагом, много-ходовые «потоки» могут дать большое улучшение.

Мы уже знаем, что, разлагая один большой промпт на несколько более мелких, мы можем добиться лучших результатов. Примером этого является AlphaCodium: перейдя от одного промпта к многоступенчатому рабочему процессу, они увеличили точность GPT-4 (pass@5) на CodeContests с 19% до 44%. Рабочий процесс включает в себя:

  • Размышление о проблеме

  • Рассуждение о публичных тестах

  • Генерация возможных решений

  • Рейтинг возможных решений

  • Генерация синтетических тестов

  • Итерация по решениям на публичных и синтетических тестах.

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

Что можно попробовать:

  • Ярко выраженный шаг планирования, сформулированный как можно точнее. Рассмотрите возможность выбора из заранее определенных планов (https://youtu.be/hGXhFa3gzBs?si=gNEGYzux6TuB1del).

  • Переписывание исходных промптов пользователя в промпты агента. Будьте осторожны, этот процесс может привести к потере данных!

  • Поведение агента в виде линейных цепей, DAG и машин состояний; разные зависимости и логические отношения могут быть более или менее подходящими для разных масштабов. Сможете ли вы выжать оптимизацию производительности из архитектур для разных задач?

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

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

Приоритизируйте детерминистические рабочие процессы

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

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

  • Сгенерированные планы могут служить несколькими запросами для промпта или тонкой настройки (fine-tuning) агента.

  • Детерминистическое выполнение делает систему более надежной, что облегчает ее тестирование и отладку. Кроме того, ошибки могут быть отслежены до конкретных шагов в плане.

  • Сгенерированные планы могут быть представлены в виде ориентированных ациклических графов (DAG), которые проще понять и адаптировать к новым ситуациям, чем статичный промпт.

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

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

Получение более разнообразных выводов, без "повышения температуры"

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

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

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

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

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

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

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

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

Успешные примеры:

  • Honeycomb’s Natural Language Query Assistant: Первоначально «инструкция по программированию» предоставлялась в промпте вместе с примерами n-shot для обучения в контексте. Хотя это работало достаточно хорошо, доработка модели привела к улучшению синтаксиса вывода с учетом правил домен-специфического языка.

  • ReChat’s Lucy: LLM необходимо было генерировать ответы в очень конкретном формате, объединяющем структурированные и неструктурированные данные, чтобы фронтенд мог их правильно отрисовывать. Fine-tuning был необходим для обеспечения корректной работы.

Тем не менее, хотя fine-tuning может быть эффективным, он связан со значительными затратами. Нам нужно аннотировать данные доработки, дорабатывать и оценивать модели, а в конечном итоге самостоятельно размещать их. Таким образом, подумайте, стоит ли это дополнительных затрат. Если промпты приводят нас к 90% цели, то доработка может не стоить инвестиций. Однако, если мы все же решим использовать fine-tuning то, чтобы снизить затраты на сбор аннотированных человеком данных, мы можем генерировать и дорабатывать синтетические данные или использовать открытые источники данных.

Оценка и мониторинг (Evaluation & Monitoring)

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

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

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

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

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

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

LLM-as-Judge может работать (хотя бы в некоторой степени), но это не панацея
LLM-as-Judge, где для оценки LLM используется сильный LLM, встретила определенный скептицизм. (Некоторые из нас тоже изначально были сильными скептиками.) Тем не менее, при хорошей реализации, LLM-as-Judge достигает приличной корреляции с человеческими суждениями и может по крайней мере помочь создать первичную оценку того, как даст новый промпт или техника. Конкретнее, при проведении парных сравнений (например, контроль против лечения) LLM-as-Judge обычно определяет направление правильно, хотя величина победы/поражения может быть "шумной".

Вот несколько советов, как получить результат от LLM-as-Judge:

  • Используйте парные сравнения: вместо того, чтобы просить LLM оценить один результат по шкале Лайкерта, дайте ему два варианта и попросите выбрать лучший. Это обычно приводит к более стабильным результатам.

  • Контролируйте предвзятость позиции: порядок вариантов может повлиять на решение LLM. Чтобы смягчить это, выполните каждое парное сравнение дважды, меняя порядок пар каждый раз. Просто убедитесь, что вы приписываете победу правильному варианту после обмена!

  • Разрешите ничьи: в некоторых случаях оба варианта могут быть одинаково хороши. Таким образом, разрешите LLM объявлять ничью, чтобы он не должен был произвольно выбирать победителя.

  • Используйте Chain-of-Thought: попросите LLM объяснить свое решения, прежде чем дать окончательное предпочтение. Это может увеличить надежность оценки. Дополнительно это обычно позволяет использовать более слабую, но более быструю LLM и все равно достичь похожих результатов. Поскольку эта часть конвейера часто находится в пакетном режиме, дополнительная задержка из-за CoT не является проблемой.

  • Контролируйте длину ответа: LLM склонны предпочитать более длинные ответы. Чтобы снизить влияние этого фактора, убедитесь, что пары ответов похожи по длине.

Одно особенно мощное применение LLM-as-Judge - проверка новой стратегии промптов на регрессию. Если вы отслеживали историю результатов использования, то вы можете повторно запустить предыдущие примеры с новой стратегией промптов и использовать LLM-as-Judge, чтобы быстро оценить, где новая стратегия может потерпеть неудачу.

Вот пример простого, но эффективного подхода к итерации LLM-as-Judge, где мы просто регистрируем ответ LLM, критику судьи (т.е. CoT) и окончательный результат. Затем они проверяются заинтересованными сторонами, чтобы выявить области для улучшения. За три итерации согласие с человеком и LLM улучшилось с 68% до 94%!

Но LLM-as-Judge не панацея. Есть тонкие аспекты языка, которые даже самые сильные модели не могут надежно оценить. Кроме того, мы обнаружили, что традиционные классификаторы и модели вознаграждения могут достичь большей точности, чем LLM-as-Judge, и с более низкими затратами и задержкой. Для генерации кода LLM-as-Judge может быть слабее, чем более прямые стратегии оценки, такие как оценка выполнения.

«Тест стажера» для оценки генераций

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

Если ответ «нет», потому что LLM не имеет необходимых знаний, подумайте о способах обогащения контекста.

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

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

Если ответ «да», с быстрым ответом, то пришло время изучить данные. Что модель делает не так? Можем ли мы найти шаблон неудачи? Попробуйте попросить модель объяснить себя до или после ответа, чтобы помочь вам построить теорию её "разума".

Чрезмерный акцент на определенных оценках может навредить общей производительности

“When a measure becomes a target, it ceases to be a good measure.”

— Goodhart’s Law

Примером этого является оценка иглы в стоге сена (NIAH). Первоначальная оценка помогла количественно определить ответ модели по мере увеличения размера окна контекста, а также как ответ зависит от положения иглы. Однако она была настолько чрезмерно акцентирована, что представлена ​​в виде рисунка 1 в отчете Gemini 1.5. Проверка включает добавление конкретной фразы («Специальный магический {город} номер: {номер}') в длинный документ, повторяющий эссе Пола Грэма, и затем запрос модели вспомнить магический номер.

Хотя некоторые модели достигают почти идеальных ответов, сомнительно, что NIAH действительно отражает способности рассуждения и памяти, необходимые в реальных приложениях. Рассмотрим более практичный сценарий: при наличии транскрипции часовой встречи может ли LLM обобщить ключевые решения и следующие шаги, а также правильно атрибутировать каждый элемент соответствующему человеку? Эта задача более реалистична, выходящая за рамки простого запоминания и учитывающая также способность анализировать сложные дискуссии, выявлять соответствующую информацию и синтезировать резюме.

Вот пример практической оценки NIAH. Используя транскрипции видео-звонков врач-пациент, LLM запрашивается о лекарствах пациента. Тест также включает более сложную оценку NIAH, вставляя фразу со случайными ингредиентами для пиццы: «Секретные ингредиенты, необходимые для приготовления идеальной пиццы: пропитанные эспрессо-финики, лимон и козий сыр». Успешный ответ составил около 80% в задаче с лекарствами и 30% в задаче с пиццей.

Избыточный акцент на оценках NIAH может привести к снижению эффективности задач извлечения и обобщения. Поскольку эти LLM настолько точно настроены на внимание к каждому предложению, они могут начать относиться к несущественным деталям и отвлекающим факторам как к важным, включая их в окончательный вывод (чего не следует делать)!

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

Упрощение аннотации до бинарных задач или парных сравнений

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

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

В парных сравнениях аннотатору представляется пара ответов модели и предлагается выбрать, какой из них лучше. Поскольку людям легче сказать «A лучше, чем B», чем назначать индивидуальную оценку A или B, это приводит к более быстрым и надежным аннотациям (по сравнению с шкалой Лайкерта). На встрече Llama2 Томас Сциалом, автор статьи Llama2, подтвердил, что парные сравнения быстрее и дешевле, чем сбор данных для supervised fine-tuning, таких как письменные ответы. Стоимость первого составляет 3,5 доллара за единицу, а второго — 25 долларов за единицу.

Если вы только начинаете писать инструкции по маркировке, вот некоторые справочные руководства от Google и Bing Search.

(Безссылочные) оценки и защитные рельсы могут использоваться как синонимы.

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

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

LLM отвечают даже когда они не должны

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

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

Хотя тщательная инженерия запросов может помочь в некоторой степени, мы должны дополнить ее надежными средствами защиты, которые обнаруживают и фильтруют/перегенерируют нежелательные выходные данные. Например, OpenAI предоставляет API модерации контента, который может идентифицировать небезопасные ответы, такие как ненавистническая речь, самоповреждение или сексуальный контент. Аналогичным образом, существует множество пакетов для обнаружения персонально идентифицируемой информации (PII). Одно преимущество состоит в том, что средства защиты в значительной степени нейтральны к конкретному приложению и могут применяться широко ко всем выходным данным на данном языке. Кроме того, с точным извлечением наша система может определенно ответить «Я не знаю», если соответствующих документов нет.

Одно из следствий этого состоит в том, что LLM могут не выдавать ответ, когда это ожидается. Это может произойти по различным причинам, от простых проблем, таких как длительные задержки API-провайдеров, до более сложных, таких как блокировка ответов фильтрами модерации контента. Важно последовательно регистрировать входные и (возможно, отсутствие) выходные данные для отладки и мониторинга.

Галлюцинации остаются сложно-решаемой проблемой.
В отличие от безопасности контента или дефектов PII, которые привлекают много внимания и поэтому редко встречаются, фактические несоответствия сохраняются и их сложнее обнаружить. Они весьма распространены и встречаются обычно с долей 5-10 %. Как мы выяснили от поставщиков ЛЛМ, очень сложно снизить этот показатель ниже 2 % даже при таких простых задачах как обобщение (суммаризация).

Для решения этой проблемы мы можем объединить инженерию промптов (вверх по потоку от генерации) и защитные рельсы фактической несогласованности (вниз по потоку от генерации). Техники, подобные CoT в инженерии промтов, помогают снизить галлюцинации, заставляя ЛЛМ объяснять свои рассуждения, до предоставления вывода. Затем мы можем применить защитные рельсы фактической несогласованности, чтобы оценить фактическую точность обобщения и отфильтровать или регенерировать галлюцинации. В некоторых случаях галлюцинации могут быть достоверно обнаружены. При использовании дополнительной информации при RAG, если вывод структурирован и указывает, откуда поступает дополнительная информация, вы должны иметь возможность вручную проверить, что они получены из входного контекста.

Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.