КОНФИГУРАЦИЯ HAYSTACK

Настройка Haystack Pipelines с помощью YAML

Что такое ЯМЛ?

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

Настройка конвейеров с помощью YAML позволяет быстро настраивать систему, управлять параметрами системы в производственной среде и запускать распределенное выполнение.

  • YAML особенно полезен для проведения экспериментов. Вы можете использовать YAML для настройки всего конвейера из файла конфигурации вместо изменения параметров и компонентов непосредственно в исходном коде. Это позволяет вам легко отслеживать свои эксперименты, поскольку вам нужно только записывать изменения в файл конфигурации.
  • При запуске Haystack за REST API вам нужно будет определить свой конвейер выбора в файле API pipelines.yaml.
  • Вам нужно будет использовать YAML, если вы хотите распараллелить конвейер и разрешить распределенное выполнение с помощью RAY API. Вы можете использовать RAY для запуска каждого компонента конвейера на отдельной машине. Например, вместо того, чтобы масштабировать весь сервер за счет одного ресурсоемкого компонента (обычно Reader), вы можете запустить этот компонент на внешнем сервере, который вы укажете в файле конфигурации YAML.

Определение конвейеров с помощью YAML

Вы можете использовать YAML для определения полного объема нейронного поиска на основе Haystack с помощью файла конфигурации pipelines.yaml (например, системы ответов на вопросы или семантического поиска).

На верхнем уровне иерархической структуры файла YAML мы определяем основные строительные блоки нашей системы:

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

Компоненты

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

...
components:   
- name: MyReader      
  type: FARMReader
  params:
    model_name_or_path: deepset/minilm-uncased-squad2
pipelines:
...

Приведенная выше конфигурация соответствует следующему коду Python:

MyReader = FARMReader(model_name_or_path="deepset/minilm-uncased-squad2")

Трубопроводы

А что, если вы хотите создать конвейер, соединяющий Retriever и Reader? Вы можете сделать это, добавив следующие строки в файл pipelines.yaml:

...
pipelines:
- name: query
  nodes:
  - inputs:
    - Query
    name: MyRetriever
  - inputs:
    - MyRetriever
    name: MyReader
  type: Query

Эта конфигурация эквивалентна приведенному ниже коду Python.

pipeline = Pipeline()
pipeline.add_node(component=MyRetriever, name="MyRetriever", inputs=["Query"])
pipeline.add_node(component=MyReader, name='MyReader', inputs=['MyRetriever'])

Сохранение и загрузка файлов YAML

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

Мы загрузим предопределенный конвейер, импортировав файл конфигурации YAML конвейера. Мы делаем это, вызывая метод Pipeline.load_from_yaml () и сообщая ему местоположение файла конфигурации.

pipeline = Pipeline.load_from_yaml("haystack/rest_api/pipeline/pipelines.yaml")

Вот как выглядит наш файл конфигурации YAML:

components:
- name: ESRetriever
  params:
    document_store: ElasticsearchDocumentStore
  type: ElasticsearchRetriever
- name: ElasticsearchDocumentStore
  type: ElasticsearchDocumentStore
- name: Reader
  params:
    model_name_or_path: deepset/roberta-base-squad2
    top_k: 5
  type: FARMReader
pipelines:
- name: query
  nodes:
  - inputs:
    - Query
    name: ESRetriever
  - inputs:
    - ESRetriever
    name: Reader
  type: Query
version: '0.8'

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

translator = TransformersTranslator(model_name_or_path="Helsinki-NLP/opus-mt-en-de")
pipeline.add_node(component=translator, name="Translator", inputs=["Reader"])

Теперь мы можем экспортировать измененную конфигурацию конвейера, вызвав метод Pipeline.save_to_yaml (). Это создаст файл pipelines.yaml в каталоге, указанном в вызове метода.

pipeline.save_to_yaml(path="haystack/rest_api/pipeline/pipelines.yaml")

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

components:
- name: ESRetriever
  params:
    document_store: ElasticsearchDocumentStore
  type: ElasticsearchRetriever
- name: ElasticsearchDocumentStore
  params: {}
  type: ElasticsearchDocumentStore
- name: Reader
  params:
    model_name_or_path: deepset/roberta-base-squad2
    top_k: 5
  type: FARMReader
- name: Translator
  params:
    model_name_or_path: Helsinki-NLP/opus-mt-en-de
  type: TransformersTranslator
pipelines:
- name: query
  nodes:
  - inputs:
    - Query
    name: ESRetriever
  - inputs:
    - ESRetriever
    name: Reader
  - inputs:
    - Reader
    name: Translator
  type: Query
version: '0.8'

Узел «Переводчик» был успешно добавлен в конец файла.

Пример: определение конвейера Haystack в YAML и его развертывание с помощью REST API

Давайте посмотрим на пример определения YAML Haystack pipeline на основе rest_api / pipeline / pipelines.yaml.

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

Вот как выглядят итоговые определения YAML:

version: '0.7'
components: 
  - name: ElasticsearchDocumentStore
    type: ElasticsearchDocumentStore
    params:
      host: localhost
  - name: ESRetriever
    type: ElasticsearchRetriever
    params:
      document_store: ElasticsearchDocumentStore
      top_k: 10
  - name: Reader
    type: FARMReader
    params:
      model_name_or_path: deepset/roberta-base-squad2
      top_k: 5

После определения отдельных компонентов мы можем поместить их в конвейер. Наш конвейер получит запрос от ввода, передаст его Retriever, а затем Reader.

Мы добавим в наш файл следующие определения и сохраним его в rest_api / pipeline / pipelines.yaml:

pipelines:
  - name: query
    type: Query
    nodes:
      - name: ESRetriever
        inputs: [Query]
      - name: Reader
        inputs: [ESRetriever]

Теперь, когда мы определили наш конвейер, мы настроим простой Haystack API. Мы будем использовать настройки по умолчанию, указанные в файле docker-compose.yml. Мы перейдем в каталог с установкой Haystack и запустим контейнер API, выполнив следующие команды:

docker-compose pull
docker-compose up

Выполнение приведенных выше команд запускает образы Docker, необходимые для запуска сервера HTTP API, хранилище данных на основе текстов Игры престолов и пользовательский веб-интерфейс. Обратите внимание, что контейнер Haystack API по умолчанию использует конвейер, определенный в файле rest_api / pipeline / pipelines.yaml. Если вы хотите указать контейнеру API для использования файла YAML в другом месте, вы можете установить переменную среды PIPELINE_YAML_PATH так, чтобы она указывала на другое место. В файле docker-compose.yml вы можете установить переменную среды следующим образом:

services:
  haystack-api:
    ...
    environment:
      - PIPELINE_YAML_PATH=newpath/pipelines.yaml

Именно так мы запустили Haystack API с конвейером, определенным в файле pipelines.yaml. Чтобы убедиться, что наш конвейер работает, мы можем задать ему вопрос:

$ curl --request POST --url 'https://127.0.0.1:8000/query' -H "Content-Type: application/json"  --data '{"query": "Which season of Game of Thrones has the episode with the highest rating?"}'

И вот результат:

{
  "query": "Which season of Game of Thrones has highest ratings?",
  "answers": [
    {
      "answer": "seventh",
      "question": null,
      "score": 0.9208154082298279,
      "probability": null,
      "context": "s the highest rated episode of the series to that point, surpassing the seventh season premiere, which previously held the record. The episode also ac",
      ...
    }
  ]
}

Мы надеемся, что приведенные выше примеры будут вам полезны. Для получения дополнительной информации о создании Haystack REST API ознакомьтесь с нашей документацией по REST API и Учебником по REST API.

И последнее, но не менее важное: приглашаем вас присоединиться к нашему сообществу Haystack здесь, в Slack, а также на Обсуждениях GitHub. Мы всегда очень ценим звезду и в хранилище Haystack!