TRL documentation
Форматы и типы наборов данных
Форматы и типы наборов данных
В этом руководстве представлен обзор форматов и типов данных, поддерживаемых каждым тренером в TRL.
Обзор форматов и типов наборов данных
- Формат набора данных определяет структуру данных и обычно относится к одному из двух типов: стандартный или диалоговый.
- Параметр type связан с конкретной задачей, для которой предназначен набор данных, например prompt-only или preference. Каждый тип характеризуется своими столбцами, которые варьируются в зависимости от задачи, как показано в таблице.
| Тип \ Формат | Стандартный | Диалоговый |
|---|---|---|
| Моделирование языка | | |
| Только промпт | | |
| Prompt-completion | | |
| Настройка | или с неявным промптом: | или с неявным промптом: |
| Непарные предпочтения | | |
Форматы
Стандартный
Стандартный формат набора данных обычно состоит из строк обычного текста. Колонки в наборе данных различаются в зависимости от задачи. Именно этот формат ожидается тренерами 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-тренировщиком.
Использование любого набора данных с 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/A | N/A | N/A | N/A | N/A | N/A |
| Prompt-completion | 🔗 | N/A | 🔗 | N/A | N/A | N/A |
| Только промпт | N/A | N/A | N/A | N/A | N/A | N/A |
| Предпочтение с неявным промптом | 🔗 | 🔗 | 🔗 | N/A | 🔗 | 🔗 |
| Настройка | 🔗 | 🔗 | 🔗 | 🔗 | N/A | 🔗 |
| Непарные предпочтения | 🔗 | 🔗 | 🔗 | N/A | N/A | N/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) с использованием пар «изображение-текст». В этом сценарии рекомендуется использовать диалоговый формат, поскольку каждая модель обрабатывает плейсхолдеры изображений в тексте по-разному.
Разговорный набор данных для компьютерного зрения отличается от стандартного разговорного набора данных двумя ключевыми особенностями:
- Набор данных должен содержать ключ
imagesс данными изображений (в виде списков изображений PIL) илиimageс одним изображением PIL. - Поле
"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. Ниже представлено встроенное представление обучающих данных датасета, позволяющее исследовать их непосредственно:
Update on GitHubСмешивание данных только с текстом и данных с текстом и изображением в наборе данных возможно, но для этого требуется версия
transformers4.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")], [], ], })