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

GPT-4 — это современная языковая модель, разработанная компанией OpenAI. Она способна понимать запросы и генерировать текст, напоминающий составленный людьми. В этом посте мы расскажем о том, как можно использовать GPT-4 с целью настройки меток для различных задач. Это может существенно снизить затраты времени и труда, связанные с процессом разметки. Чтобы показать, как инжиниринг промтов способен помочь в создании точных и надёжных меток при помощи GPT-4 и как эту методику можно использовать для гораздо более мощных возможностей, мы воспользуемся примером с классификацией эмоционального настроя (sentiment classification).

Использование прогнозов GPT-4 для предварительной разметки данных


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

Как же это сделать? Если вы уже работали с моделями GPT, то, вероятно, знакомы с концепцией промтов. Промты задают контекст для модели, прежде чем она начинает генерировать свой вывод, их можно настраивать и проектировать (так называемый инжиниринг промтов, prompt engineering), чтобы помочь модели создавать результаты с высокой степенью конкретики. Это значит, что мы можем создавать промты, которые GPT-4 будет использовать для генерации текста, похожего на прогнозы модели. Кроме того, в данном случае мы будем создавать промты таким образом, чтобы направлять модель в сторону генерации нужного нам формата вывода.

Давайте возьмём простой пример анализа эмоционального настроя. Если нам нужно классифицировать эмоциональный настрой строки текста как положительный, отрицательный или нейтральный, то мы можем передать промт такого вида:

«Classify the sentiment of the following text as 'positive', 'negative', or 'neutral': <input_text>»

Получив хорошо структурированный промт, мы можем использовать OpenAI API для генерации прогнозов GPT-4. Вот пример с использованием Python:

import openai
import re

openai.api_key = "<your_api_key>"

def get_sentiment(input_text):
    prompt = f"Respond in the json format: {{'response': sentiment_classification}}\nText: {input_text}\nSentiment (positive, neutral, negative):"
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "user", "content": prompt}
        ],
        max_tokens=40,
        n=1,
        stop=None,
        temperature=0.5,
    )
    response_text =  response.choices[0].message['content'].strip()
    sentiment = re.search("negative|neutral|positive", response_text).group(0)
    # Добавляем обратно input_text для результата
    return {"text": input_text, "response": sentiment}

Можно запустить его с одним примером, чтобы изучить вывод, возвращаемый API.

# Тестовый пример
sample_text = "I had a terrible time at the party last night!"
sentiment = get_sentiment(sample_text)
print("Result\n",f"{sentiment}")

Result:
{'text': 'I had a terrible time at the party last night!', 'response': 'negative'}

Получив удовлетворительный промт и результаты, мы можем масштабировать эту систему на весь датасет. Здесь мы будем предполагать, что текстовый файл содержит по одному примеру на строку.

import json

input_file_path = "input_texts.txt"
output_file_path = "output_responses.json"

with open(input_file_path, "r") as input_file, open(output_file_path, "w") as output_file:
    examples = []
    for line in input_file:
        text = line.strip()
        if text:
            examples.append(convert_ls_format(get_sentiment(text)))
    output_file.write(json.dumps(examples))

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

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

Проверка предварительно размеченных данных в Label Studio


Получив готовые предварительно размеченные данные, мы импортируем их для проверки в инструмент разметки данных, например, в Label Studio. В этом разделе мы настроим проект Label Studio, импортируем предварительно размеченные данные и проверим аннотации.


Рисунок 1: Проверка классификации эмоционального настроя в Label Studio.

Этап 1: установка и запуск Label Studio


Первым делом нужно установить на свою машину Label Studio. Это можно сделать при помощи pip:

pip install label-studio

Установив Label Studio, запустим её следующей командой:

label-studio

После этого Label Studio откроется в используемом по умолчанию веб-браузере.

Этап 2: создание нового проекта


Нажмите на «Create Project» и введите название проекта, например, «Review Bootstrapped Labels». Далее нужно задать конфигурацию разметки. Для анализа эмоционального настроя можно использовать текст Sentiment Analysis Text Classification.

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

<View>
  <Header value="Choose text sentiment:"/>
  <Text name="my_text" value="$reviewText"/>
  <Choices name="sentiment" toName="my_text" choice="single" showInline="true">
    <Choice value="Positive"/>
    <Choice value="Negative"/>
    <Choice value="Neutral"/>
  </Choices>
</View>

Нажмите «Create», чтобы завершить настройку проекта.

Этап 3: импорт предварительно размеченных данных


Для импорта предварительно размеченных данных нужно нажать на кнопку «Import», затем выбрать файл json и выделить сгенерированный ранее файл с предварительно размеченными данными (например, «output_responses.json»). Данные импортируются вместе с уже готовыми прогнозами.

Этап 4: проверка и изменение меток


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

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

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

Этап 5: экспорт размеченных данных


После завершения процесса проверки можно экспортировать размеченные данные, нажав на кнопку «Export» во вкладке «Data Manager». Выберите нужный формат вывода (например, JSON, CSV или TSV) и сохраните размеченный датасет для дальнейшего применения в проекте машинного обучения.

Анализ затрат


Меня никак не покидал вопрос: «Сколько мне это в конечном итоге стоило?»

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

В случае языковых моделей OpenAI взимает оплату в зависимости от количества токенов в запросе. Обычно токены соответствуют количеству слов в запросе, но специальные символы и эмодзи иногда могут считаться отдельным токеном. На странице тарифов OpenAI написано: «Токены можно считать фрагментами слов, 1000 токенов — это примерно 750 слов». Подробнее о подсчёте токенов можно узнать на этой странице.

Стоимость токена зависит от используемой модели. Например, модель GPT-4 с контекстом 8K стоит по $0,03/1000 токенов за промт, каждый сгенерированный токен стоит $0,06/1000 токенов, а модель GPT-3.5-turbo стоит $0,002/1000 токенов.


Сводка стоимости токенов OpenAI. (Источник: форум OpenAI)

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


Где E — количество примеров в датасете, Ct — общая стоимость предварительной разметки датасета, Cp — стоимость токена в промте, Cc — стоимость промта в результате, Tp — количество токенов в промте, Ts — среднее количество токенов в примере, Tr — количество токенов в результате.

Кроме того, мы можем вычислить общее количество токенов в датасете:


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

Например, если у нас есть датасет с 1000 примеров, который мы хотим предварительно разметить при помощи GPT-4 для анализа эмоционального настроя, затраты можно вычислить так: промты стоят по $0,03 за 1000 токенов, стоимость результата — $0,06 за 1000 токенов, длина промта — 20 токенов, средняя длина примера — 80 токенов, а средняя длина результата в токенах — 3 токена. Тогда общая стоимость предварительной разметки будет такой:


В этом примере предварительная разметка датасета при помощи GPT-4 будет стоить $3,18. Примечание: разметка того же датасета при помощи GPT-3.5-turbo будет стоить примерно $0,21.

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

Не только анализ эмоционального настроя: разметка под любую задачу NLP




Скриншот с распознаванием именованных сущностей (Named Entity Recognition) в Label Studio

Эта методика хороша тем, что подходит не только для анализа эмоционального настроя. Воспользовавшись инжинирингом промтов, при помощи GPT-4 можно предварительно размечать данные для различных задач NLP, направляя модель в сторону создания корректных результатов. Вот несколько примеров промтов для различных задач NLP, их все можно проверить и разметить в Label Studio (представленные примеры сгенерированы при помощи GPT-4). Помните, что для более сложных задач могут потребоваться более длинные промты, которые будут учитываться в количестве токенов, а значит, и в стоимости.

Суммаризация


Промт:

Respond in the json format with a summary for the following text: {‘summary’: summary}

Text: I love going to the park on a sunny day. The customer service was terrible; they were rude and unhelpful. I am neither happy nor sad about the new policy changes. The cake was delicious and the presentation was fantastic. I had a really bad experience with the product; it broke after two days.

Summary:

Ответ:

{'summary': 'Artificial intelligence is a rapidly developing technology that can learn from data and make decisions without being explicitly programmed. It has the potential to help solve some of the world's most pressing problems, but there are concerns about risks and ethical considerations such as bias and job displacement. It is important to consider AI's impact and ensure responsible and beneficial use.'}

Таксономия


Промт:

Respond in the JSON format with a summary for the following text: {‘diagnosis’: diagnosis}, where the possible diagnoses are Pneumonia, Acute bronchitis, Asthma exacerbation, Congestive heart failure, Chronic obstructive pulmonary disease (COPD), Pulmonary embolism, Pleural effusion, Interstitial lung disease, or Lung cancer.

Text: The patient presented with shortness of breath and a persistent cough. On physical examination, crackles were heard in the lower lung fields. Chest X-ray revealed bilateral infiltrates consistent with pneumonia. The patient was started on antibiotics and showed improvement in symptoms within 48 hours.

Diagnosis:

Ответ:

{'diagnosis': 'Pneumonia'}

Named Entity Recognition (NER)


Промт:

You are an expert NER labeler. Only return JSON. Do not return explanations. Return the CoNLL format for the following sentence in JSON format.

Ответ:

{
  "data": [
    {
      "word": "Harry",
      "entity": "B-PER"
    },
    {
      "word": "Potter",
      "entity": "I-PER"
    },
    {
      "word": "was",
      "entity": "O"
    },
    {
      "word": "a",
      "entity": "O"
    },
    {
      "word": "student",
      "entity": "O"
    },
    {
      "word": "at",
      "entity": "O"
    },
    {
      "word": "Hogwarts",
      "entity": "B-LOC"
    }
  ]
}

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

Заключение


Разметка данных — это всегда сложный процесс и иногда даже получение такого предварительного результата становится огромным преимуществом. В этом посте я показал, как можно использовать модели GPT компании OpenAI для генерации прогнозов, которые могут применяться в качестве фундамента для рабочих процессов разметки данных. Такой процесс может существенно снизить требуемый объём человеческого труда и позволит разметчикам заняться более полезными задачами.

Ресурсы


Full example notebook — ноутбук со всем кодом, готовый для запуска в Colab

Label Studio — опенсорсный инструмент разметки данных

Страница тарифов OpenAI — данные для оценки стоимости, рассчитанной в этом посте.

Комментарии (1)


  1. TuktarovMarat
    20.10.2023 06:04

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