Внутри DSPy новый язык программирования моделей, о котором вам следует знать

В DSPy новый язык программирования моделей, о котором вам следует знать

Созданный исследователями из Стэнфорда, фреймворк представляет интересную альтернативу LangChain или LlamaIndex.

Создано с использованием Midjourney

Недавно я начал ежедневную рассылку, посвященную искусственному интеллекту, которая уже имеет более 160 000 подписчиков. TheSequence – это рассылка, ориентированная на машинное обучение, которую можно прочитать за 5 минут и не содержит лишних новостей и хайпа. Цель – быть в курсе последних проектов, научных статей и концепций машинного обучения. Подпишитесь ниже, чтобы попробовать:

TheSequence | Jesus Rodriguez | Substack

Лучший источник для ознакомления с развитием машинного обучения, искусственного интеллекта и данных…

thesequence.substack.com

Вселенная фреймворков для программирования языковых моделей (LMP) быстро расширяется в последние несколько месяцев. Фреймворки, такие как LangChain или LlamaIndex, безусловно, достигли значительного уровня популярности в сообществе LLM, и Semantic Kernel от Microsoft расширяет впечатляющий набор возможностей. Недавно на сцену вышла новая альтернатива, известная как DSPy, с уникальным подходом к LMP.

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

Опыт и принципы DSPy некоторым образом похожи на PyTorch в области глубокого обучения. При создании приложений глубокого обучения с использованием PyTorch, ученые-данные моделируют заданную нейронную сеть и используют декларативные слои или оптимизаторы для включения нужной логики. Аналогично, DSPy включает строительные блоки, такие как ChainOfThought или Retrieve, и компилирует программу, оптимизируя подсказки на основе определенных метрик. Хотя это может показаться новым подходом в LMP, подход довольно традиционен.

DSPy

DSPy ставит программирование выше задач подсказки, объединяя стратегии как для подсказки, так и для донастройки языковых моделей (LM). Фреймворк усиливает эти техники рассуждением и дополнением инструментов/извлечением информации, все это реализовано с помощью компактного набора питоновских операций, которые можно комбинировать и которые способны обучаться.

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

DSPy функционирует как комплексное решение для сложных задач, связанных с языковыми моделями (LM) и моделями извлечения информации (RM). DSPy гармонизирует подходы как для подсказки, так и для донастройки LM, а также учитывает методы рассуждения и дополнения инструментов/извлечения информации. Через DSPy эти методологии инкапсулируются компактным набором питоновских модулей, которые обеспечивают композицию и обучение.

Фреймворк DSPy основан на компонуемых и декларативных модулях, структурированных так, чтобы быть знакомыми пользователям Python. Это совершенствование повышает эффективность “техник подсказки”, таких как chain-of-thought и саморефлексия, переводя их из тактик ручной обработки строк в гибкие модульные процедуры, способные адаптироваться к различным задачам.

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

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

Опыт программирования с использованием DSPy основан на двух основных конструкциях: Сигнатурах и Телепромптерах.

I. Сигнатуры: Создание поведения LLM

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

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

Сигнатура состоит из трех основных составляющих:

1) Краткое описание подзадачи, решаемой LM.

2) Разработка одного или нескольких входных полей (например, вопроса на входе), которые будут служить входами для LM.

3) Объяснение одного или нескольких выходных полей (например, ответа на вопрос), ожидаемых от LM.

Следующий код иллюстрирует сигнатуру на основе модуля ChainOfThought с несколькими элементами управления:

class GenerateSearchQuery(dspy.Signature):    """Напишите простой поисковый запрос, который поможет ответить на сложный вопрос."""    context = dspy.InputField(desc="может содержать соответствующие факты")    question = dspy.InputField()    query = dspy.OutputField()### внутри функции __init__ вашей программыself.generate_answer = dspy.ChainOfThought(GenerateSearchQuery)

II. Обеспечение оптимизации программы с помощью dspy.teleprompt.

Компиляция является основой опыта DSPy.

Компиляция зависит от трех ключевых факторов: потенциально компактного набора обучающих данных, метрики проверки и выбора телепромптера из репертуара DSPy. Эти телепромптеры, встроенные в DSPy, являются мощными оптимизаторами, способными овладеть искусством формулирования влиятельных подсказок, настроенных на модули любой программы. (Префикс “tele-” в “teleprompter” означает “на расстоянии”, отражая автоматический характер подсказки.)

Замечательно, что требования DSPy к разметке значительно скромны. Рассмотрим пример конвейера retrieve augmented generation (RAG): даже несколько экземпляров, содержащих вопросы и аннотированные людьми ответы, могут быть достаточными. Даже при наличии нескольких сложных этапов, как показано в основной модели RAG, включающей извлечение контекста, цепочку мыслей и окончательный ответ, для начального запроса и финального ответа требуются только метки. DSPy умно экстраполирует промежуточные метки, необходимые для поддержки всего конвейера. Если изменения будут внесены в структуру конвейера, буферизованные данные будут динамически развиваться, чтобы соответствовать измененной конфигурации.

Пример набора данных для обучения RAG может быть структурирован следующим образом:

my_rag_trainset = [  dspy.Example(    question="Какую награду получила первая книга Гэри Цукава?",    answer="Национальная книжная премия"  ),  ...]

Важно сформулировать критерии проверки. Логика накладывает ограничения на поведение программы или производительность модуля. Например, функция проверки для RAG может содержать следующую проверку:

def validate_context_and_answer(example, pred, trace=None):answer_match = example.answer.lower() == pred.answer.lower()context_match = any((pred.answer.lower() in c) for c in pred.context)return answer_match and context_match

Разные варианты телепромптера имеют свои преимущества и недостатки, связанные с оптимизацией затрат и улучшением качества. В контексте RAG можно выбрать простой телепромптер BootstrapFewShot. В этом случае телепромптер инициализируется собственной функцией проверки (например, my_rag_validation_logic), а затем производится компиляция на основе указанного набора обучающих данных (my_rag_trainset).

from dspy.teleprompt import BootstrapFewShotteleprompter = BootstrapFewShot(metric=my_rag_validation_logic)compiled_rag = teleprompter.compile(RAG(), trainset=my_rag_trainset)

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

DSPy все еще находится в очень ранних стадиях, но уже подчеркивает ряд интересных идей. Простая и последовательная модель программирования, похожая на опыт работы с PyTorch, и модульный опыт позволяют разработчикам LMP создавать довольно сложные приложения. Я надеюсь, что DSPy разовьется от этой начальной стадии до стека, который сможет соперничать с LangChain и LlamaIndex, потому что многие идеи этой платформы определенно нужны в области LMP.