DeepPavlov для разработчиков: #1 инструменты NLP и создания чат-ботов

    Всем привет! Мы открываем цикл статей, посвященных решению практических задач, связанных с обработкой естественного языка (Natural Language Processing или просто NLP) и созданием диалоговых агентов (чат-ботов) с помощью open-source библиотеки DeepPavlov, которую разрабатывает наша команда лаборатории Нейронных систем и глубокого обучения МФТИ. Главная цель цикла — познакомить широкий круг разработчиков с DeepPavlov и показать, как можно решать прикладные задачи NLP, не обладая при этом глубокими познаниями в Machine Learning и PhD in Mathematics.

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

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

    Все статьи цикла:
    1. DeepPavlov для разработчиков: #1 инструменты NLP и создания чат-ботов
    2. DeepPavlov для разработчиков: #2 настройка и деплоймент



    Установка DeepPavlov


    Здесь и далее будут приведены инструкции для Linux. Для Windows смотрите нашу документацию

    • Создайте и активируйте виртуальное окружение с текущей поддерживаемой версией Python:

      virtualelnv env -p python3.7
      source env/bin/activate
    • Установите DeepPavlov в виртуальное окружение:

      pip install deeppavlov
      

    Запуск REST сервера с моделью DeepPavlov


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

    Любая модель в DP состоит из:

    • Кода на Python;
    • Скачиваемых компонент — сериализованных результатов обучения на конкретных данных (эмбеддинги, веса нейронных сетей и проч.);
    • Конфигурационного файла (далее — конфига), в котором содержится информация об используемых моделью классах, URL скачиваемых компонент, зависимостях Python и прочем.

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

    • Любая модель в DeepPavlov идентифицируется именем её конфига;
    • Для запуска модели необходимо скачать её компоненты с серверов DeepPavlov;
    • Так же для запуска модели необходимо установить используемые ею библиотеки Python.

    Первой моделью, которую мы запустим, будет мультиязычный Named Entity Recognition (NER). Модель классифицирует слова текста по типу именованных сущностей, к которым они принадлежат (имена собственные, географические названия, названия валют и другие). Имя конфига для самой свежей на текущий момент версии NER:

    ner_ontonotes_bert_mult
    

    Запускаем REST сервер с моделью:

    1. Устанавливаем в активное виртуальное окружение зависимости модели, указанные в её конфиге:

      python -m deeppavlov install ner_ontonotes_bert_mult
      
    2. Скачиваем сериализованные компоненты модели с серверов DeepPavlov:

      python -m deeppavlov download ner_ontonotes_bert_mult
      

      Сериализованные компоненты будут скачаны в домашнюю директорию DeepPavlov, которая по умолчанию находится
      ~/.deeppavlov
      При скачивании хэш уже скаченных компонентов сверяется с хэшами компонентов, находящихся на сервере. В случае совпадения скачивание пропускается и используются уже имеющиеся файлы. Размеры скачиваемых компонент могут варьироваться в среднем от 0.5 до 8 Gb, в некоторых случаях после разархивирования достигая 20 Gb.
    3. Запускаем REST-сервер с моделью:

      python -m deeppavlov riseapi ner_ontonotes_bert_mult -p 5005
      

    В результате выполнения этой команды будет запущен REST сервер с моделью на 5005 порту хост-машины (порт по умолчанию — 5000).

    После инициализации модели, Swagger с документацией API и возможностью протестировать, можно будет найти по URL http://127.0.0.1:5005. Протестируем модель, отправив на эндпоинт http://127.0.0.1:5005/model POST запрос со следующим JSON содержимым:

    {
      "x": [
        "В МФТИ можно добраться на электричке с Савёловского Вокзала.",
        "В юго-западной Руси стог жита оценен в 15 гривен"
      ]
    }

    В ответ мы должны получить такой JSON:

    [
      [
        ["В", "МФТИ", "можно", "добраться", "на", "электричке", "с", "Савёловского", "Вокзала", "."],
        ["O", "B-FAC", "O", "O", "O", "O", "O", "B-FAC", "I-FAC", "O"]
      ],
      [
        ["В", "юго", "-", "западной", "Руси", "стог", "жита", "оценен", "в", "15", "гривен"],
        ["O", "B-LOC", "I-LOC", "I-LOC", "I-LOC", "O", "O", "O", "O", "B-MONEY", "I-MONEY"]
      ]
    ]

    На этих примерах разберём REST API DeepPavlov.

    API DeepPavlov


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

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

    Термин “батч” (batch) относится к области машинного обучения и подразумевает под собой пакет из независимых входящих значений, обрабатываемых алгоритмом или нейронной сетью одновременно. Такой подход позволяет сократить (зачастую — существенно) время обработки моделью одного элемента батча по сравнению с этим же значением, переданным на вход отдельно. Но результат обработки выдаётся только после обработки всех элементов. Поэтому при формировании входящего батча будет необходимо учитывать скорость работы модели и требуемое время обработки каждого его отдельного элемента.

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

    В приведённом примере результатом работы модели была разбивка каждой строки на токены (слова и знаки препинания) и классификация токена относительно именованной сущности (название организации, валюта), которую он представляет. На данный момент модель ner_ontonotes_bert_mult способна распознавать 18 типов именованных сущностей, подробное описание можно найти тут.

    Другие out-of-the-box модели DeepPavlov


    Помимо NER в DeepPavlov на момент написания статьи доступны следующие out-of the-box модели:

    Text Question Answering


    Ответ на вопрос к тексту фрагментом этого текста. Конфиг модели: squad_ru_bert_infer

    Пример запроса:

    {
      "context_raw": [
        "DeepPavlov разрабатывается лабораторией МФТИ.",
        "В юго-западной Руси стог жита оценен в 15 гривен."
      ],
      "question_raw": [
        "Кем разрабатывается DeepPavlov?",
        "Сколько стоил стог жита на Руси?"
      ]
    }

    Результат:

    [
      ["лабораторией МФТИ", 27, 31042.484375],
      ["15 гривен", 39, 1049.598876953125]
    ]
    

    Insult Detection


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

    Пример запроса:

    
    {
      "x": [
        "Money talks, bullshit walks.",
        "You are not the brightest one."
      ]
    }

    Результат:

    [
      ["Not Insult"],
      ["Insult"]
    ]

    Sentiment Analysis


    Классификация тональности текста (положительная, нейтральная, негативная). Конфиг модели: rusentiment_elmo_twitter_cnn

    Пример запроса:

    {
      "x": [
        "Мне нравится библиотека DeepPavlov.",
        "Я слышал о библиотеке DeepPavlov.",
        "Меня бесят тролли и анонимусы."
      ]
    }

    Результат:

    [
      ["positive"],
      ["neutral"],
      ["negative"]
    ]

    Paraphrase Detection


    Определение, имеют ли два разных текста одинаковое значение. Конфиг модели: stand_paraphraser_ru

    Запрос:

    {
      "text_a": [
        "Город погружается в сон, просыпается Мафия.",
        "Президент США пригрозил расторжением договора с Германией."
      ],
      "text_b": [
        "Наступает ночь, все жители города пошли спать, а преступники проснулись.",
        "Германия не собирается поддаваться угрозам со стороны США."
      ]
    }

    Результат:

    [
      [1],
      [0]
    ]

    Актуальный список всех out-of-the-box моделей DeepPavlov можно всегда найти здесь.

    Заключение


    В этой статье мы познакомились с API DeepPavlov и некоторыми возможностями библиотеки по обработке текста, предоставляемые “из коробки”. При этом надо иметь в виду, что для любой задачи NLP наилучший результат будет достигаться при обучении модели на наборе данных, соответствующем предметной области (домену) задачи. Кроме того, ещё больше моделей в принципе нельзя обучить на все случаи жизни.

    В следующих статьях мы рассмотрим дополнительные настройки библиотеки, запуск DeepPavlov из Docker, а после перейдём к обучению моделей. И не забывайте, что у DeepPavlov есть форум – задавайте свои вопросы относительно библиотеки и моделей. Спасибо за внимание!
    Московский физико-технический институт (МФТИ)
    49,09
    Компания
    Поделиться публикацией

    Комментарии 15

      0
      Я по началу подумал, что автор BulgenOS выпустил свой движок(
        0

        А где про обучение своих моделей почитать можно?

          0
          Про обучение на своих датасетах моделей, поставляемых с DeepPavlov — в третей статье цикла. Про создание (и, соответственно, обучение) своих моделей на DP тоже будут статьи, следите за публикациями =)) Ещё тут есть несколько туториалов, возможно вам будет интересно: github.com/deepmipt/DeepPavlov/tree/master/examples
          0
          Приветствую! Несколько вопросов про squad:

          • как правильно интерпретировать "ans_start_predicted", "logits"?
          • как добавить score в вывод?
          • можно ли запустить сервис на бюджетном CUDA с 4Г памяти, чтоб он не вылетал в ООМ? Установка "batch_size": 1 в конфиге не помогает

          Спасибо!
            0

            со "ans_start_predicted", "logits" вроде разобрался )

              0
              Привет! Для ответа на вопросы по контексту в DeepPavlov есть два типа моделей: основанные на R-Net и на BERT. Все конфиги моделей на основе BERT содержат в названии bert. Чтобы уменьшить потребление GPU памяти, можно уменьшить используемую длину контекста: context_limit для R-Net, max_seq_length для BERT.
              ans_start_predicted — позиция ответа в символах.
              logits — не нормированная уверенность модели в ответе.
              Относительно score, какая именно модель/конфиг используется?
                0

                я играюсь с бертом. Думал сортировать ответы по логитам, но эта "уверенность" для этого не очень подходит: очень часто "подходящие" ответы имеют меньшее значение.
                Ещё заметил, что на результат часто влияет наличие "?" в конце вопроса.
                И squad_ru_bert_infer выдает лучше результаты на иностранных текстах чем squad_bert_infer.


                На счет 4г GPU — уменьшил max_seq_length до 4 :) — всё равно не влезает.


                ПС: сейчас ответ по контексту в облаке что-то не работает

                  0
                  ? — действительно влияет, так как модель во время обучения всегда видела вопросы со знаком? на конце. Эту проблему можно решить случайно выбрасывая знаки? во время обучения.
                  По confidence, который выдает модель корректно сравнивать только ответы внутри одного контекста.
                  Последнее наблюдение странное, так как мы проверяли качество модели обученной на русском языке на текстах на англ: 75.3 F-1 (обучена на русском, проверена на англ) vs 89.1 F-1 (обучена на англ, проверена на англ)
            0

            Разъясните пожалуйста, чем squad модели отличаются друг от друга?
            multi (BERT ведь и так мульти)?
            infer?
            ru (SQUaD + SDSJ?)
            без "ru" — только SQUaD?
            немного запутался :)
            Спасибо!

              0
              • squad — models trained on SQuAD v1.1 dataset (En)
              • squad_ru* — models trained on SDSJ Task B dataset (Ru)
              • squad_zh* — models trained on DRCD dataset (Zh)
              • bert — model is based on BERT (En)
              • rubert — model is based on RuBERT (Ru)
              • bert_multilingual — model is based on Multilingual BERT
              • *infer — models based on BERT that can be used for texts with more than 512 subtokens (BERT has limitation 512 tokens).
              • Models with multi* prefix were trained to be used in multi-paragraph mode, when you feed several paragraphs to model and then select only one answer.
            0

            del

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

            Самое читаемое