TRL documentation

Форматы и типы наборов данных

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v1.17.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Форматы и типы наборов данных

В этом руководстве представлен обзор форматов и типов данных, поддерживаемых каждым тренером в TRL.

Обзор форматов и типов наборов данных

  • Формат набора данных определяет структуру данных и обычно относится к одному из двух типов: стандартный или диалоговый.
  • Параметр type связан с конкретной задачей, для которой предназначен набор данных, например prompt-only или preference. Каждый тип характеризуется своими столбцами, которые варьируются в зависимости от задачи, как показано в таблице.
Тип \ ФорматСтандартныйДиалоговый
Моделирование языка
{"text": "The sky is blue."}
{"messages": [{"role": "user", "content": "What color is the sky?"},
              {"role": "assistant", "content": "It is blue."}]}
Только промпт
{"prompt": "The sky is"}
{"prompt": [{"role": "user", "content": "What color is the sky?"}]}
Prompt-completion
{"prompt": "The sky is",
 "completion": " blue."}
{"prompt": [{"role": "user", "content": "What color is the sky?"}],
 "completion": [{"role": "assistant", "content": "It is blue."}]}
Настройка
{"prompt": "The sky is",
 "chosen": " blue.",
 "rejected": " green."}
или с неявным промптом:
{"chosen": "The sky is blue.",
 "rejected": "The sky is green."}
{"prompt": [{"role": "user", "content": "What color is the sky?"}],
 "chosen": [{"role": "assistant", "content": "It is blue."}],
 "rejected": [{"role": "assistant", "content": "It is green."}]}
или с неявным промптом:
{"chosen": [{"role": "user", "content": "What color is the sky?"},
              {"role": "assistant", "content": "It is blue."}],
 "rejected": [{"role": "user", "content": "What color is the sky?"},
                {"role": "assistant", "content": "It is green."}]}
Непарные предпочтения
{"prompt": "The sky is",
 "completion": " blue.",
 "label": True}
{"prompt": [{"role": "user", "content": "What color is the sky?"}],
 "completion": [{"role": "assistant", "content": "It is green."}],
 "label": False}

Форматы

Стандартный

Стандартный формат набора данных обычно состоит из строк обычного текста. Колонки в наборе данных различаются в зависимости от задачи. Именно этот формат ожидается тренерами TRL. Ниже приведены примеры стандартных форматов наборов данных для различных задач:

# Language modeling
language_modeling_example = {"text": "The sky is blue."}
# Preference
preference_example = {"prompt": "The sky is", "chosen": " blue.", "rejected": " green."}
# Unpaired preference
unpaired_preference_example = {"prompt": "The sky is", "completion": " blue.", "label": True}

Диалоговый

Разговорные наборы данных используются для задач, связанных с диалогами или чат-взаимодействиями между пользователями и ассистентами. В отличие от стандартных форматов наборов данных, они содержат последовательности сообщений, в которых каждое сообщение имеет role (например, "user" или "assistant") и content (текст сообщения).

messages = [
    {"role": "user", "content": "Hello, how are you?"},
    {"role": "assistant", "content": "I'm doing great. How can I help you today?"},
    {"role": "user", "content": "I'd like to show off how chat templating works!"},
]

Как и в стандартных наборах данных, столбцы в диалоговых наборах данных различаются в зависимости от задачи. Ниже приведены примеры форматов диалоговых наборов данных для разных задач:

# Prompt-completion
prompt_completion_example = {"prompt": [{"role": "user", "content": "What color is the sky?"}],
                             "completion": [{"role": "assistant", "content": "It is blue."}]}
# Preference
preference_example = {
    "prompt": [{"role": "user", "content": "What color is the sky?"}],
    "chosen": [{"role": "assistant", "content": "It is blue."}],
    "rejected": [{"role": "assistant", "content": "It is green."}],
}

Вызов инструментов

Некоторые шаблоны чата поддерживают вызов инструментов, что позволяет модели взаимодействовать с внешними функциями — называемыми инструментами — в процессе генерации. Это расширяет возможности модели в диалоге, позволяя ей выводить поле "tool_calls" вместо стандартного сообщения "content" каждый раз, когда она решает вызвать инструмент.

После того как ассистент инициирует вызов инструмента, инструмент выполняется и возвращает результат. Затем ассистент может обработать этот результат и продолжить диалог в соответствии с ним.

Вот простой пример взаимодействия с вызовом инструмента:

messages = [
    {"role": "user", "content": "Turn on the living room lights."},
    {"role": "assistant", "tool_calls": [
        {"type": "function", "function": {
            "name": "control_light",
            "arguments": {"room": "living room", "state": "on"}
        }}]
    },
    {"role": "tool", "name": "control_light", "content": "The lights in the living room are now on."},
    {"role": "assistant", "content": "Done!"}
]

При подготовке наборов данных для Supervised Fine-Tuning (SFT) с вызовом инструментов важно, чтобы ваш набор данных содержал дополнительную колонку с именем tools. Эта колонка содержит список доступных для модели инструментов, который обычно используется шаблоном чата для построения системного промпта.

Инструменты должны быть заданы в формате кодифицированной схемы JSON. Вы можете автоматически сгенерировать эту схему из сигнатур функций Python с помощью утилиты get_json_schema:

import json
from transformers.utils import get_json_schema

def control_light(room: str, state: str) -> str:
    """
    Controls the lights in a room.

    Args:
        room: The name of the room.
        state: The desired state of the light ("on" or "off").

    Returns:
        str: A message indicating the new state of the lights.
    """
    return f"The lights in {room} are now {state}."

# Generate JSON schema
json_schema = get_json_schema(control_light)

Сгенерированная схема будет выглядеть так:

{"type": "function", "function": {"name": "control_light", "description": "Controls the lights in a room.", "parameters": {"type": "object", "properties": {"room": {"type": "string", "description": "The name of the room."}, "state": {"type": "string", "description": "The desired state of the light (\"on\" or \"off\")."}}, "required": ["room", "state"]}, "return": {"type": "string", "description": "str: A message indicating the new state of the lights."}}}

Полная запись набора данных для SFT может выглядеть так:

{"messages": messages, "tools": [json_schema]}

Чтобы получить Dataset, необходимо использовать тип Json() для аргументов инструментов, поскольку они представляют собой произвольные JSON-объекты, а не словари с фиксированными полями и типами:

from datasets import Dataset

data = [
    {"messages": messages1, "tools": [json_schema1]},
    {"messages": messages2, "tools": [json_schema2]},
]
# auto-apply the Json() type
dataset = Dataset.from_list(data, on_mixed_types="use_json")

# or specify the features manually
from datasets import Features, Json, List, Value

features = Features(
    {
        "messages": List({"role": Value("string"), "content": Value("string"), "tool_calls": List(Json())}),
        "tools": List(Json()),
    }
)
dataset = Dataset.from_list(data, features=features)

В более старых версиях datasets (<4.7.0), в которых отсутствует тип Json(), следует хранить tools как строку JSON str (с помощью json.dumps([...])):

dataset = Dataset.from_list(
    [{"messages": messages1, "tools": json.dumps([json_schema1])},
     {"messages": messages2, "tools": json.dumps([json_schema2])}]
)

Для получения более подробной информации о вызове инструментов обратитесь к разделу Tool Calling в документации transformers и к статье в блоге Tool Use, Unified.

Harmony

Формат ответа Harmony был представлен вместе с моделями OpenAI GPT OSS. Он расширяет диалоговый формат, добавляя более богатую структуру для рассуждений, вызовов функций и метаданных о поведении модели. Ключевые особенности включают:

  • Роль разработчика – предоставляет высокоуровневые инструкции (аналог системного промпта) и перечисляет доступные инструменты.

  • Каналы – Разделение типов вывода ассистента на отдельные потоки:

    • analysis – для внутреннего рассуждения, из ключа "thinking"
    • final – для ответа пользователю, из ключа "content"
    • commentary – для вызовов инструментов или служебных заметок
  • Уровень рассуждений – Указывает, насколько глубоко модель должна рассуждать (например, "low", "medium", "high").

  • Идентичность модели – Явно определяет персону ассистента.

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("openai/gpt-oss-20b")

messages = [
    {"role": "developer", "content": "Use a friendly tone."},
    {"role": "user", "content": "What is the meaning of life?"},
    {"role": "assistant", "thinking": "Deep reflection...", "content": "The final answer is..."},
]

print(
    tokenizer.apply_chat_template(
        messages,
        tokenize=False,
        reasoning_effort="low",
        model_identity="You are HuggingGPT, a large language model trained by Hugging Face.",
    )
)

В результате получается:

<|start|>system<|message|>You are HuggingGPT, a large language model trained by Hugging Face.
Knowledge cutoff: 2024-06
Current date: 2025-08-03

Reasoning: low

# Valid channels: analysis, commentary, final. Channel must be included for every message.<|end|><|start|>developer<|message|># Instructions

Use a friendly tone.<|end|><|start|>user<|message|>What is the meaning of life?<|end|><|start|>assistant<|channel|>analysis<|message|>Deep reflection...<|end|><|start|>assistant<|channel|>final<|message|>The final answer is...<|return|>

Подробные сведения о структуре сообщений, поддерживаемых полях и расширенных способах использования см. в документации Harmony.

Типы

Моделирование языка

Набор данных для моделирования языка состоит из столбца "text" (или "messages" для диалоговых наборов данных), содержащего полную последовательность текста.

# Standard format
language_modeling_example = {"text": "The sky is blue."}
# Conversational format
language_modeling_example = {"messages": [
    {"role": "user", "content": "What color is the sky?"},
    {"role": "assistant", "content": "It is blue."}
]}

Только промпт

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

# Standard format
prompt_only_example = {"prompt": "The sky is"}
# Conversational format
prompt_only_example = {"prompt": [{"role": "user", "content": "What color is the sky?"}]}

Примеры датасетов, содержащих только промпты, приведены в коллекции датасетов с только промптами.

Хотя типы prompt-only и language modeling похожи, они различаются тем, как обрабатывается вход. В типе prompt-only промпт представляет собой частичный вход, для которого ожидается, что модель завершит или продолжит текст, тогда как в типе language modeling вход рассматривается как полное предложение или последовательность. TRL обрабатывает эти два типа по-разному. Ниже приведен пример, демонстрирующий различие в выводе функции apply_chat_template для каждого типа:

from transformers import AutoTokenizer
from trl import apply_chat_template

tokenizer = AutoTokenizer.from_pretrained("microsoft/Phi-3-mini-128k-instruct")

# Example for prompt-only type
prompt_only_example = {"prompt": [{"role": "user", "content": "What color is the sky?"}]}
apply_chat_template(prompt_only_example, tokenizer)
# Output: {'prompt': '<|user|>\nWhat color is the sky?<|end|>\n<|assistant|>\n'}

# Example for language modeling type
lm_example = {"messages": [{"role": "user", "content": "What color is the sky?"}]}
apply_chat_template(lm_example, tokenizer)
# Output: {'text': '<|user|>\nWhat color is the sky?<|end|>\n<|endoftext|>'}
  • Вывод, содержащий только промпт, включает '<|assistant|>\n', что указывает на начало хода ассистента и ожидает от модели генерации продолжения.
  • В отличие от этого, выход языковой модели рассматривает вход как полную последовательность и завершает её '<|endoftext|>', сигнализируя об окончании текста и не ожидая какого-либо дополнительного содержимого.

Prompt-completion

Набор данных «запрос-дополнение» включает "prompt" и "completion".

# Standard format
prompt_completion_example = {"prompt": "The sky is", "completion": " blue."}
# Conversational format
prompt_completion_example = {"prompt": [{"role": "user", "content": "What color is the sky?"}],
                             "completion": [{"role": "assistant", "content": "It is blue."}]}

Примеры наборов данных в формате «запрос-дополнение» приведены в коллекции наборов данных «запрос-дополнение».

Настройка

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

# Standard format
## Explicit prompt (recommended)
preference_example = {"prompt": "The sky is", "chosen": " blue.", "rejected": " green."}
# Implicit prompt
preference_example = {"chosen": "The sky is blue.", "rejected": "The sky is green."}

# Conversational format
## Explicit prompt (recommended)
preference_example = {"prompt": [{"role": "user", "content": "What color is the sky?"}],
                      "chosen": [{"role": "assistant", "content": "It is blue."}],
                      "rejected": [{"role": "assistant", "content": "It is green."}]}
## Implicit prompt
preference_example = {"chosen": [{"role": "user", "content": "What color is the sky?"},
                                 {"role": "assistant", "content": "It is blue."}],
                      "rejected": [{"role": "user", "content": "What color is the sky?"},
                                   {"role": "assistant", "content": "It is green."}]}

С примерами наборов данных для предпочтений можно ознакомиться в коллекции Preference datasets.

Некоторые наборы данных для обучения с предпочтениями можно найти по тегу dpo на Hugging Face Hub. Также вы можете изучить коллекции DPO от librarian-bots, чтобы найти наборы данных с предпочтениями.

Непарные предпочтения

Непарный набор данных предпочтений похож на набор данных предпочтений, но вместо того, чтобы содержать завершения "chosen" и "rejected" для одного и того же промпта, он включает одно "completion" и "label", указывающий, является ли это завершение предпочтительным.

# Standard format
unpaired_preference_example = {"prompt": "The sky is", "completion": " blue.", "label": True}
# Conversational format
unpaired_preference_example = {"prompt": [{"role": "user", "content": "What color is the sky?"}],
                               "completion": [{"role": "assistant", "content": "It is blue."}],
                               "label": True}

Примеры непарных наборов данных предпочтений приведены в коллекции непарных наборов данных предпочтений.

Какой тип набора данных использовать?

Выбор подходящего типа набора данных зависит от решаемой задачи и конкретных требований используемого вами TRL-тренировщика. Ниже приведён краткий обзор типов наборов данных, поддерживаемых каждым TRL-тренировщиком.

TrainerОжидаемый тип набора данных
DPOTrainerПредпочтение (рекомендуется явный промпт)
GRPOTrainerТолько промпт
KTOTrainerНепарные предпочтения или Предпочтения (рекомендуется явный промпт)
RewardTrainerПредпочтение (рекомендуется неявный промпт)
RLOOTrainerТолько промпт
SFTTrainerМоделирование языка или Завершение промпта
experimental.cpo.CPOTrainerПредпочтение (рекомендуется явный промпт)
experimental.gkd.GKDTrainerПромпт-дополнение
experimental.online_dpo.OnlineDPOTrainerТолько промпт
experimental.orpo.ORPOTrainerПредпочтение (рекомендуется явный промпт)

Использование любого набора данных с TRL: предобработка и конвертация

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

Чтобы упростить этот процесс, мы предоставляем набор примеров скриптов, охватывающих типовые преобразования наборов данных.

Пример: набор данных UltraFeedback

Возьмём, например, набор данных UltraFeedback. Вот его превью:

Как показано выше, формат набора данных не соответствует ожидаемой структуре. Он не представлен в диалоговом формате, названия столбцов отличаются, а результаты относятся к другим моделям (например, Bard, GPT-4) и аспектам (например, «helpfulness», «honesty»).

Используя предоставленный скрипт конвертации examples/datasets/ultrafeedback.py, вы можете преобразовать этот набор данных в тип непарных предпочтений и загрузить его в Hub:

python examples/datasets/ultrafeedback.py --push_to_hub --repo_id trl-lib/ultrafeedback-gpt-3.5-turbo-helpfulness

После преобразования набор данных будет выглядеть так:

Теперь вы можете использовать этот датасет с TRL!

Адаптировав предоставленные скрипты или создав собственные, вы можете преобразовать любой набор данных в формат, совместимый с TRL.

Утилиты для преобразования типов данных

В этом разделе приведены примеры кода, которые помогут вам преобразовывать данные между различными типами датасетов. Хотя некоторые преобразования можно выполнить после применения шаблона чата (то есть в стандартном формате), мы рекомендуем выполнять преобразование до применения шаблона чата, чтобы обеспечить его согласованную работу.

Для простоты некоторые примеры ниже не следуют этой рекомендации и используют стандартный формат. Однако преобразования можно применить непосредственно к диалоговому формату без каких-либо изменений.

Из \ ВМоделирование языкаPrompt-completionТолько промптПредпочтение с неявным промптомНастройкаНепарные предпочтения
Моделирование языкаN/AN/AN/AN/AN/AN/A
Prompt-completion🔗N/A🔗N/AN/AN/A
Только промптN/AN/AN/AN/AN/AN/A
Предпочтение с неявным промптом🔗🔗🔗N/A🔗🔗
Настройка🔗🔗🔗🔗N/A🔗
Непарные предпочтения🔗🔗🔗N/AN/AN/A

От набора данных для дополнения промпта к набору данных для моделирования языка

Чтобы преобразовать набор данных «запрос-дополнение» в набор данных для моделирования языка, объедините запрос и дополнение.

from datasets import Dataset

dataset = Dataset.from_dict({
    "prompt": ["The sky is", "The sun is"],
    "completion": [" blue.", " in the sky."],
})

def concat_prompt_completion(example):
    return {"text": example["prompt"] + example["completion"]}

dataset = dataset.map(concat_prompt_completion, remove_columns=["prompt", "completion"])
>>> dataset[0]
{'text': 'The sky is blue.'}

От набора данных «запрос-дополнение» к набору данных «только запрос»

Чтобы преобразовать набор данных «запрос-дополнение» в набор данных только с запросами, удалите дополнение.

from datasets import Dataset

dataset = Dataset.from_dict({
    "prompt": ["The sky is", "The sun is"],
    "completion": [" blue.", " in the sky."],
})

dataset = dataset.remove_columns("completion")
>>> dataset[0]
{'prompt': 'The sky is'}

От предпочтений с неявным промптом к набору данных для моделирования языка

Чтобы преобразовать набор данных предпочтений с неявным промптом в набор данных для языкового моделирования, удалите отклонённые ответы и переименуйте столбец "chosen" в "text".

from datasets import Dataset

dataset = Dataset.from_dict({
    "chosen": ["The sky is blue.", "The sun is in the sky."],
    "rejected": ["The sky is green.", "The sun is in the sea."],
})

dataset = dataset.rename_column("chosen", "text").remove_columns("rejected")
>>> dataset[0]
{'text': 'The sky is blue.'}

От предпочтений с неявным промптом к набору данных «промпт-завершение»

Чтобы преобразовать набор данных предпочтений с неявным промптом в набор данных «промпт-дополнение», извлеките промпт с помощью extract_prompt(), удалите отклонённые варианты и переименуйте столбец "chosen" в "completion".

from datasets import Dataset
from trl import extract_prompt

dataset = Dataset.from_dict({
    "chosen": [
        [{"role": "user", "content": "What color is the sky?"}, {"role": "assistant", "content": "It is blue."}],
        [{"role": "user", "content": "Where is the sun?"}, {"role": "assistant", "content": "In the sky."}],
    ],
    "rejected": [
        [{"role": "user", "content": "What color is the sky?"}, {"role": "assistant", "content": "It is green."}],
        [{"role": "user", "content": "Where is the sun?"}, {"role": "assistant", "content": "In the sea."}],
    ],
})
dataset = dataset.map(extract_prompt).remove_columns("rejected").rename_column("chosen", "completion")
>>> dataset[0]
{'prompt': [{'role': 'user', 'content': 'What color is the sky?'}], 'completion': [{'role': 'assistant', 'content': 'It is blue.'}]}

От набора данных с неявным промптом до набора данных только с промптами

Чтобы преобразовать набор данных предпочтений с неявным промптом в набор данных, содержащий только промпты, извлеките промпт с помощью extract_prompt() и удалите rejected и chosen.

from datasets import Dataset
from trl import extract_prompt

dataset = Dataset.from_dict({
    "chosen": [
        [{"role": "user", "content": "What color is the sky?"}, {"role": "assistant", "content": "It is blue."}],
        [{"role": "user", "content": "Where is the sun?"}, {"role": "assistant", "content": "In the sky."}],
    ],
    "rejected": [
        [{"role": "user", "content": "What color is the sky?"}, {"role": "assistant", "content": "It is green."}],
        [{"role": "user", "content": "Where is the sun?"}, {"role": "assistant", "content": "In the sea."}],
    ],
})
dataset = dataset.map(extract_prompt).remove_columns(["chosen", "rejected"])
>>> dataset[0]
{'prompt': [{'role': 'user', 'content': 'What color is the sky?'}]}

От неявных к явным предпочтениям в наборе данных для промптов

Чтобы преобразовать набор данных предпочтений с неявным промптом в набор данных предпочтений с явным промптом, извлеките промпт с помощью extract_prompt().

from datasets import Dataset
from trl import extract_prompt

dataset = Dataset.from_dict({
    "chosen": [
        [{"role": "user", "content": "What color is the sky?"}, {"role": "assistant", "content": "It is blue."}],
        [{"role": "user", "content": "Where is the sun?"}, {"role": "assistant", "content": "In the sky."}],
    ],
    "rejected": [
        [{"role": "user", "content": "What color is the sky?"}, {"role": "assistant", "content": "It is green."}],
        [{"role": "user", "content": "Where is the sun?"}, {"role": "assistant", "content": "In the sea."}],
    ],
})

dataset = dataset.map(extract_prompt)
>>> dataset[0]
{'prompt': [{'role': 'user', 'content': 'What color is the sky?'}],
 'chosen': [{'role': 'assistant', 'content': 'It is blue.'}],
 'rejected': [{'role': 'assistant', 'content': 'It is green.'}]}

От предпочтений с неявным промптом к непарному набору данных предпочтений

Чтобы преобразовать набор данных предпочтений с неявным промптом в непарный набор данных предпочтений, извлеките промпт с помощью extract_prompt() и разбейте набор данных на пары с помощью unpair_preference_dataset().

from datasets import Dataset
from trl import extract_prompt, unpair_preference_dataset

dataset = Dataset.from_dict({
    "chosen": [
        [{"role": "user", "content": "What color is the sky?"}, {"role": "assistant", "content": "It is blue."}],
        [{"role": "user", "content": "Where is the sun?"}, {"role": "assistant", "content": "In the sky."}],
    ],
    "rejected": [
        [{"role": "user", "content": "What color is the sky?"}, {"role": "assistant", "content": "It is green."}],
        [{"role": "user", "content": "Where is the sun?"}, {"role": "assistant", "content": "In the sea."}],
    ],
})

dataset = dataset.map(extract_prompt)
dataset = unpair_preference_dataset(dataset)
>>> dataset[0]
{'prompt': [{'role': 'user', 'content': 'What color is the sky?'}],
 'completion': [{'role': 'assistant', 'content': 'It is blue.'}],
 'label': True}

Помните, что завершения "chosen" и "rejected" в наборе данных предпочтений могут быть как хорошими, так и плохими. Перед применением unpair_preference_dataset() убедитесь, что все завершения "chosen" можно оценить как хорошие, а все завершения "rejected" — как плохие. Это можно обеспечить, проверив абсолютную оценку каждого завершения, например, с помощью модели вознаграждения.

От набора данных предпочтений к набору данных для языкового моделирования

Чтобы преобразовать набор данных предпочтений в набор данных для моделирования языка, удалите отклонённые ответы и объедините промпт и выбранный ответ в столбец "text".

from datasets import Dataset

dataset = Dataset.from_dict({
    "prompt": ["The sky is", "The sun is"],
    "chosen": [" blue.", " in the sky."],
    "rejected": [" green.", " in the sea."],
})

def concat_prompt_chosen(example):
    return {"text": example["prompt"] + example["chosen"]}

dataset = dataset.map(concat_prompt_chosen, remove_columns=["prompt", "chosen", "rejected"])
>>> dataset[0]
{'text': 'The sky is blue.'}

От набора данных предпочтений к набору данных «промпт-завершение»

Чтобы преобразовать набор данных предпочтений в набор данных «запрос-завершение», удалите отклонённые ответы и переименуйте столбец "chosen" в "completion".

from datasets import Dataset

dataset = Dataset.from_dict({
    "prompt": ["The sky is", "The sun is"],
    "chosen": [" blue.", " in the sky."],
    "rejected": [" green.", " in the sea."],
})

dataset = dataset.remove_columns("rejected").rename_column("chosen", "completion")
>>> dataset[0]
{'prompt': 'The sky is', 'completion': ' blue.'}

От набора данных предпочтений к набору данных только с промптами

Чтобы преобразовать набор данных предпочтений в набор данных, содержащий только промпты, удалите rejected и chosen.

from datasets import Dataset

dataset = Dataset.from_dict({
    "prompt": ["The sky is", "The sun is"],
    "chosen": [" blue.", " in the sky."],
    "rejected": [" green.", " in the sea."],
})

dataset = dataset.remove_columns(["chosen", "rejected"])
>>> dataset[0]
{'prompt': 'The sky is'}

От явного набора данных предпочтений промптов к неявному

Чтобы преобразовать набор данных предпочтений с явным промптом в набор данных предпочтений с неявным промптом, объедините промпт с обоими вариантами — chosen и rejected — и удалите промпт.

from datasets import Dataset

dataset = Dataset.from_dict({
    "prompt": [
        [{"role": "user", "content": "What color is the sky?"}],
        [{"role": "user", "content": "Where is the sun?"}],
    ],
    "chosen": [
        [{"role": "assistant", "content": "It is blue."}],
        [{"role": "assistant", "content": "In the sky."}],
    ],
    "rejected": [
        [{"role": "assistant", "content": "It is green."}],
        [{"role": "assistant", "content": "In the sea."}],
    ],
})

def concat_prompt_to_completions(example):
    return {"chosen": example["prompt"] + example["chosen"], "rejected": example["prompt"] + example["rejected"]}

dataset = dataset.map(concat_prompt_to_completions, remove_columns="prompt")
>>> dataset[0]
{'chosen': [{'role': 'user', 'content': 'What color is the sky?'}, {'role': 'assistant', 'content': 'It is blue.'}],
 'rejected': [{'role': 'user', 'content': 'What color is the sky?'}, {'role': 'assistant', 'content': 'It is green.'}]}

От предпочтений к непарному набору данных предпочтений

Чтобы преобразовать набор данных в непарный набор предпочтений, используйте unpair_preference_dataset() для разделения пар.

from datasets import Dataset
from trl import unpair_preference_dataset

dataset = Dataset.from_dict({
    "prompt": [
        [{"role": "user", "content": "What color is the sky?"}],
        [{"role": "user", "content": "Where is the sun?"}],
    ],
    "chosen": [
        [{"role": "assistant", "content": "It is blue."}],
        [{"role": "assistant", "content": "In the sky."}],
    ],
    "rejected": [
        [{"role": "assistant", "content": "It is green."}],
        [{"role": "assistant", "content": "In the sea."}],
    ],
})

dataset = unpair_preference_dataset(dataset)
>>> dataset[0]
{'prompt': [{'role': 'user', 'content': 'What color is the sky?'}],
 'completion': [{'role': 'assistant', 'content': 'It is blue.'}],
 'label': True}

Помните, что завершения "chosen" и "rejected" в наборе данных предпочтений могут быть как хорошими, так и плохими. Перед применением unpair_preference_dataset() убедитесь, что все завершения "chosen" можно оценить как хорошие, а все завершения "rejected" — как плохие. Это можно обеспечить, проверив абсолютную оценку каждого завершения, например, с помощью модели вознаграждения.

От набора данных с непарными предпочтениями к набору данных для языкового моделирования

Чтобы преобразовать набор данных с непарными предпочтениями в набор данных для обучения языковой модели, объедините промпты с хорошими завершениями в столбце "text" и удалите столбцы с промптами, завершениями и метками.

from datasets import Dataset

dataset = Dataset.from_dict({
    "prompt": ["The sky is", "The sun is", "The sky is", "The sun is"],
    "completion": [" blue.", " in the sky.", " green.", " in the sea."],
    "label": [True, True, False, False],
})

def concatenate_prompt_completion(example):
    return {"text": example["prompt"] + example["completion"]}

dataset = dataset.filter(lambda x: x["label"]).map(concatenate_prompt_completion).remove_columns(["prompt", "completion", "label"])
>>> dataset[0]
{'text': 'The sky is blue.'}

От набора неспаренных предпочтений к набору данных «запрос-завершение»

Чтобы преобразовать непарный набор данных предпочтений в набор данных «запрос-завершение», отфильтруйте хорошие метки, а затем удалите столбцы с метками.

from datasets import Dataset

dataset = Dataset.from_dict({
    "prompt": ["The sky is", "The sun is", "The sky is", "The sun is"],
    "completion": [" blue.", " in the sky.", " green.", " in the sea."],
    "label": [True, True, False, False],
})

dataset = dataset.filter(lambda x: x["label"]).remove_columns(["label"])
>>> dataset[0]
{'prompt': 'The sky is', 'completion': ' blue.'}

От набора данных с несопоставленными предпочтениями к набору данных только с промптами

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

from datasets import Dataset

dataset = Dataset.from_dict({
    "prompt": ["The sky is", "The sun is", "The sky is", "The sun is"],
    "completion": [" blue.", " in the sky.", " green.", " in the sea."],
    "label": [True, True, False, False],
})

dataset = dataset.remove_columns(["completion", "label"])
>>> dataset[0]
{'prompt': 'The sky is'}

Наборы данных для компьютерного зрения

Некоторые тренажёры также поддерживают дообучение моделей «зрение-язык» (VLM) с использованием пар «изображение-текст». В этом сценарии рекомендуется использовать диалоговый формат, поскольку каждая модель обрабатывает плейсхолдеры изображений в тексте по-разному.

Разговорный набор данных для компьютерного зрения отличается от стандартного разговорного набора данных двумя ключевыми особенностями:

  1. Набор данных должен содержать ключ images с данными изображений (в виде списков изображений PIL) или image с одним изображением PIL.
  2. Поле "content" в сообщениях должно быть списком словарей, где каждый словарь указывает тип данных: "image" или "text".

Пример:

# Textual dataset:
"content": "What color is the sky?"

# Vision dataset:
"content": [
    {"type": "image"},
    {"type": "text", "text": "What color is the sky in the image?"}
]

Примером датасета для диалогового зрения является openbmb/RLAIF-V-Dataset. Ниже представлено встроенное представление обучающих данных датасета, позволяющее исследовать их непосредственно:

Смешивание данных только с текстом и данных с текстом и изображением в наборе данных возможно, но для этого требуется версия transformers 4.57.0 или более поздняя. Пример:

dataset = Dataset.from_dict({
    "prompt": [
        [{"role": "user", "content": [{"type": "image"}, {"type": "text", "text": "What color is the sky in the image?"}]}],
        [{"role": "user", "content": [{"type": "text", "text": "What is the capital of France?"}]}],
    ],
    "completion": [
        [{"role": "assistant", "content": [{"type": "text", "text": "It is blue."}]}],
        [{"role": "assistant", "content": [{"type": "text", "text": "Paris."}]}],
    ],
    "images": [
        [PIL.Image.open("path/to/sky_image1.png")],
        [],
    ],
})
Update on GitHub