LLM Course, глава 10: качественные датасеты с Argilla
Перевод главы 10 курса Hugging Face: как развернуть Argilla, загрузить датасет, разметить его в интерфейсе вместе с командой и выгрузить результат на Hub.
Это перевод главы 10 курса LLM Course от Hugging Face. Главы 0–9 курса сообщество уже перевело на русский, главы 10–12 — нет; их переводы — на этой и соседних страницах. Карта всего курса — в путеводителе.
10.1. Знакомство с Argilla
Заголовок раздела «10.1. Знакомство с Argilla»В главе 5 вы научились собирать датасет библиотекой 🤗 Datasets, а в главе 6 — дообучать модели для распространённых задач NLP. В этой главе вы научитесь размечать и курировать датасеты с помощью Argilla, чтобы потом обучать и оценивать на них свои модели.
Главное условие хорошей модели — качественные данные. На Hub есть хорошие датасеты для обучения и оценки, но они могут не подходить к вашему приложению или задаче. Тогда стоит собрать и вычистить собственный датасет. Argilla помогает сделать это быстро.
(В оригинале здесь скриншот страницы входа в Argilla.)
С помощью Argilla можно:
- превращать неструктурированные данные в структурированные, пригодные для задач NLP;
- курировать датасет: из данных низкого качества сделать датасет высокого качества;
- собирать отзывы людей (human feedback) для LLM и мультимодальных моделей;
- приглашать экспертов работать вместе с вами в Argilla или отдавать разметку на краудсорсинг.
Что вы узнаете в этой главе:
- как развернуть собственный экземпляр Argilla;
- как загрузить датасет и настроить его под популярные задачи NLP;
- как размечать датасет в интерфейсе Argilla;
- как пользоваться вычищенным датасетом и выгрузить его на Hub.
Вот весь путь главы одной схемой:
flowchart LR A["Датасет на Hub<br/>SetFit/ag_news"] -->|"Python SDK:<br/>Settings + records.log"| B["Argilla<br/>в Space или Docker"] B -->|"разметка в интерфейсе:<br/>метки + сущности"| C["Размеченные записи"] C -->|"фильтр по статусу,<br/>to_datasets / to_hub"| D["Новый датасет на Hub"] D --> E["Обучение и оценка<br/>моделей"]
10.2. Разворачиваем Argilla
Заголовок раздела «10.2. Разворачиваем Argilla»Чтобы начать работать с Argilla, сначала разверните собственный экземпляр. Затем установите Python SDK, чтобы управлять Argilla из кода на Python.
Разворачиваем интерфейс Argilla
Заголовок раздела «Разворачиваем интерфейс Argilla»Проще всего развернуть Argilla через Hugging Face Spaces. Чтобы создать свой Space с Argilla, заполните эту форму. Если нужны подробности, загляните в быстрый старт Argilla.
(В оригинале — скриншот формы настройки Space.)
Когда Argilla запустится, войдите со своими учётными данными.
Устанавливаем и подключаем Python SDK
Заголовок раздела «Устанавливаем и подключаем Python SDK»Теперь перейдите в своё окружение Python или блокнот и установите библиотеку argilla:
!pip install argilla
Подключимся к нашему экземпляру Argilla. Для этого понадобятся:
- API URL — адрес, по которому работает Argilla. Если вы используете Space, откройте его, нажмите на три точки
в правом верхнем углу, затем «Embed this Space» и скопируйте Direct URL. Он выглядит примерно так:
https://<your-username>.<space-name>.hf.space. - API-ключ — войдите в Argilla, откройте «My Settings» и скопируйте ключ API.
- Токен HF — если ваш Space приватный, нужен токен доступа (Access Token) вашей учётной записи на Hugging Face Hub с правом записи.
import argilla as rg
HF_TOKEN = "..." # нужен только для приватных Space
client = rg.Argilla( api_url="...", api_key="...", headers={"Authorization": f"Bearer {HF_TOKEN}"}, # нужен только для приватных Space)Чтобы проверить, что всё работает, обратимся к me. Должен вернуться наш пользователь:
client.meЕсли сработало — ваш экземпляр Argilla запущен, и вы к нему подключены. Поздравляем!
Теперь можно загрузить в Argilla первый датасет.
10.3. Загружаем датасет в Argilla
Заголовок раздела «10.3. Загружаем датасет в Argilla»В зависимости от задачи NLP и конкретного приложения ваши данные и задача разметки будут выглядеть по-разному. В этом разделе мы возьмём датасет новостей и решим на нём две задачи: классификацию текста по теме и классификацию токенов — поиск упомянутых именованных сущностей.
(В оригинале здесь встроен просмотрщик датасета SetFit/ag_news с Hub.)
Импортировать датасеты с Hub можно и прямо из интерфейса Argilla, но мы воспользуемся SDK: так мы увидим, как при необходимости дополнительно править данные.
Настраиваем датасет
Заголовок раздела «Настраиваем датасет»Первый шаг — подключиться к Argilla, как в предыдущем разделе:
import argilla as rg
HF_TOKEN = "..." # нужен только для приватных Space
client = rg.Argilla( api_url="...", api_key="...", headers={"Authorization": f"Bearer {HF_TOKEN}"}, # нужен только для приватных Space)Теперь подумаем о настройках (settings) датасета в Argilla. Они описывают задачу разметки, которую мы будем выполнять над данными. Сначала загрузим датасет с Hub и посмотрим на его признаки (features), чтобы правильно всё настроить.
from datasets import load_dataset
data = load_dataset("SetFit/ag_news", split="train")data.featuresПризнаки нашего датасета:
{'text': Value(dtype='string', id=None), 'label': Value(dtype='int64', id=None), 'label_text': Value(dtype='string', id=None)}В датасете есть поле text и начальные метки для классификации текста. Добавим их в настройки датасета вместе
с вопросом типа spans для именованных сущностей:
settings = rg.Settings( fields=[rg.TextField(name="text")], questions=[ rg.LabelQuestion( name="label", title="Classify the text:", labels=data.unique("label_text") ), rg.SpanQuestion( name="entities", title="Highlight all the entities in the text:", labels=["PERSON", "ORG", "LOC", "EVENT"], field="text", ), ],)Разберём, что означают эти настройки. Сначала мы задали поля (fields) — в них лежит информация, которую мы будем
размечать. У нас одно поле, и это текст, поэтому мы выбрали TextField.
Затем мы задали вопросы (questions) — это задачи, которые мы хотим выполнить над данными:
- Для классификации текста выбран
LabelQuestion. В качестве меток взяты уникальные значения столбцаlabel_text: так вопрос совместим с метками, которые в датасете уже есть. - Для классификации токенов нужен
SpanQuestion. Мы задали набор меток для этой задачи (персона, организация, место, событие) и поле, в котором будем выделять фрагменты (spans).
Обо всех типах полей и вопросов, а также о продвинутых настройках вроде метаданных и векторов читайте в документации Argilla.
Загружаем датасет
Заголовок раздела «Загружаем датасет»Настройки готовы — создаём датасет:
dataset = rg.Dataset(name="ag_news", settings=settings)
dataset.create()Датасет появился в Argilla, но, как вы увидите, он пуст. (В оригинале — скриншот пустого датасета.)
Теперь добавим записи (records), которые будем размечать, — то есть строки датасета. Для этого достаточно залогировать данные как записи и указать соответствие (mapping) для тех элементов, у которых названия в датасете на Hub и в Argilla различаются:
dataset.records.log(data, mapping={"label_text": "label"})В mapping мы указали, что столбец label_text из датасета соответствует вопросу с именем label. Так существующие
метки датасета станут предварительной разметкой (pre-annotations), и размечать мы будем быстрее.
Пока записи продолжают загружаться, с датасетом уже можно работать в интерфейсе Argilla. (В оригинале — скриншот датасета в Argilla на этом этапе.)
Датасет готов к разметке!
10.4. Размечаем датасет
Заголовок раздела «10.4. Размечаем датасет»Пора переходить в интерфейс Argilla и размечать датасет.
Договоритесь с командой: инструкция для разметчиков
Заголовок раздела «Договоритесь с командой: инструкция для разметчиков»Прежде чем размечать, полезно написать инструкцию (guidelines), особенно если вы работаете в команде. Она помогает одинаково понимать задачу и метки и разрешать вопросы и споры, когда они возникают.
В Argilla откройте в интерфейсе страницу настроек датасета: там можно изменить инструкцию и описания вопросов. (В оригинале — скриншот страницы Dataset Settings.)
Если хотите глубже разобраться, как писать хорошие инструкции, советуем эту статью и литературу, на которую она ссылается.
Распределяем задачу
Заголовок раздела «Распределяем задачу»На той же странице настроек можно изменить распределение задачи (distribution settings). Это помогает размечать эффективнее, когда вы работаете в команде. По умолчанию минимальное число отправленных ответов равно 1: как только у записи есть один отправленный ответ, она считается завершённой и засчитывается в прогресс датасета.
Иногда на запись нужно несколько ответов — например, если вы хотите измерить согласованность разметчиков (inter-annotator agreement). Тогда увеличьте этот параметр, но так, чтобы он не превышал общее число разметчиков. Если размечаете в одиночку, оставьте 1.
Размечаем записи
Заголовок раздела «Размечаем записи»Открыв датасет, вы заметите, что первый вопрос уже заполнен предложенными метками. Это потому, что в предыдущем
разделе мы сопоставили вопрос label со столбцом label_text датасета, — теперь достаточно проверить и исправить
существующие метки.
Для классификации токенов все метки придётся ставить вручную: подсказок мы для неё не загружали. (В оригинале — скриншот записи с выделенными фрагментами-сущностями.)
Переходя от записи к записи, вы можете:
- отправить ответы (submit), когда закончили с записью;
- сохранить черновик (save as draft), если хотите вернуться к записи позже;
- отклонить запись (discard), если ей не место в датасете или вы не будете на неё отвечать.
В следующем разделе вы узнаете, как выгрузить и использовать эту разметку.
10.5. Используем размеченный датасет
Заголовок раздела «10.5. Используем размеченный датасет»Теперь научимся выгружать и использовать размеченные данные из Argilla.
Загружаем датасет
Заголовок раздела «Загружаем датасет»Сначала убедимся, что мы подключены к Argilla, как на предыдущих шагах:
import argilla as rg
HF_TOKEN = "..." # нужен только для приватных Space
client = rg.Argilla( api_url="...", api_key="...", headers={"Authorization": f"Bearer {HF_TOKEN}"}, # нужен только для приватных Space)И загрузим датасет, с которым будем работать:
dataset = client.datasets(name="ag_news")Загрузить датасет и обратиться к его записям через dataset.records уже достаточно, чтобы использовать данные в своих
задачах и конвейерах. Но мы разберём и пару необязательных операций: фильтрацию записей и выгрузку датасета на
Hugging Face Hub.
Фильтруем датасет
Заголовок раздела «Фильтруем датасет»Иногда нужны только завершённые записи. Отфильтруем записи по статусу:
status_filter = rg.Query(filter=rg.Filter([("status", "==", "completed")]))
filtered_records = dataset.records(status_filter)О запросах и фильтрации записей читайте в документации Argilla.
Выгружаем на Hub
Заголовок раздела «Выгружаем на Hub»Теперь можно выгрузить разметку на Hugging Face Hub и поделиться ею. Для этого превратим записи в 🤗 Dataset и отправим его на Hub:
filtered_records.to_datasets().push_to_hub("argilla/ag_news_annotated")Можно выгрузить и весь датасет Argilla целиком (включая записи, ожидающие разметки):
dataset.to_hub(repo_id="argilla/ag_news_annotated")Этот вариант удобен, если другие захотят открыть датасет в своих экземплярах Argilla: настройки сохраняются автоматически, и импортировать весь датасет можно одной строкой:
dataset = rg.Dataset.from_hub(repo_id="argilla/ag_news_annotated")10.6. Argilla — готово!
Заголовок раздела «10.6. Argilla — готово!»Вот и всё! Поздравляем! 👏
В этой главе вы освоили основные шаги:
- развернуть Argilla;
- размечать данные, чтобы повысить качество датасета;
- приспособить существующий датасет под другую задачу NLP и использовать его заново;
- поделиться размеченным датасетом с сообществом на Hugging Face Hub.
Что дальше?
Заголовок раздела «Что дальше?»- Пошаговые руководства для других популярных задач — на странице туториалов.
- Другие примеры датасетов можно посмотреть в демо.
- Чтобы изучить Argilla глубже и узнать о продвинутых возможностях, читайте документацию Argilla.
10.7. Тест в конце главы
Заголовок раздела «10.7. Тест в конце главы»Проверим, что вы узнали в этой главе!
Словарик
Заголовок раздела «Словарик»| English | Русский |
|---|---|
| annotate, annotation | размечать, разметка |
| annotator | разметчик |
| curate a dataset | курировать датасет (проверять, чистить, отбирать) |
| guidelines | инструкция для разметчиков |
| inter-annotator agreement | согласованность разметчиков |
| record | запись (строка датасета) |
| field / question | поле (что размечают) / вопрос (задача разметки) |
| span | фрагмент текста (спан) |
| suggestion, pre-annotation | подсказка, предварительная разметка |
| named entity | именованная сущность |
| human feedback | отзывы людей |