偏好数据集¶
偏好数据集用于奖励建模,其中下游任务是微调基础模型以捕捉一些潜在的人类偏好。目前,这些数据集在 torchtune 中与直接偏好优化 (DPO) 食谱 一起使用。
偏好数据集中的基本事实通常是针对同一提示的两个完成之间的二进制比较的结果,并且人类注释者已根据某些预设标准指示一个完成比另一个完成更可取。这些提示-完成对可以是指示风格(单轮,可选地带有单个提示)、聊天风格(多轮),或用户与模型之间的一组其他交互(例如,自由文本完成)。
在 torchtune 中使用 DPO 食谱,使用偏好数据集进行微调的主要入口点是 preference_dataset()
。
示例本地偏好数据集¶
# my_preference_dataset.json
[
{
"chosen_conversations": [
{
"content": "What do I do when I have a hole in my trousers?",
"role": "user"
},
{ "content": "Fix the hole.", "role": "assistant" }
],
"rejected_conversations": [
{
"content": "What do I do when I have a hole in my trousers?",
"role": "user"
},
{ "content": "Take them off.", "role": "assistant" }
]
}
]
from torchtune.models.mistral import mistral_tokenizer
from torchtune.datasets import preference_dataset
m_tokenizer = mistral_tokenizer(
path="/tmp/Mistral-7B-v0.1/tokenizer.model",
prompt_template="torchtune.models.mistral.MistralChatTemplate",
max_seq_len=8192,
)
column_map = {
"chosen": "chosen_conversations",
"rejected": "rejected_conversations"
}
ds = preference_dataset(
tokenizer=tokenizer,
source="json",
column_map=column_map,
data_files="my_preference_dataset.json",
train_on_input=False,
split="train",
)
tokenized_dict = ds[0]
print(m_tokenizer.decode(tokenized_dict["rejected_input_ids"]))
# user\n\nWhat do I do when I have a hole in my trousers?assistant\n\nTake them off.
print(tokenized_dict["rejected_labels"])
# [-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100,-100, -100,-100,\
# -100,-100,-100,-100,-100,128006,78191,128007,271,18293,1124,1022,13,128009,-100]
这也可以通过 yaml 配置完成
# In config
tokenizer:
_component_: torchtune.models.mistral.mistral_tokenizer
path: /tmp/Mistral-7B-v0.1/tokenizer.model
prompt_template: torchtune.models.mistral.MistralChatTemplate
max_seq_len: 8192
dataset:
_component_: torchtune.datasets.preference_dataset
source: json
data_files: my_preference_dataset.json
column_map:
chosen: chosen_conversations
rejected: rejected_conversations
train_on_input: False
split: train
在此示例中,我们还展示了如何使用 column_map,当“chosen”和/或“rejected”列名不同于数据集中相应的列时。
偏好数据集格式¶
预期偏好数据集包含两列:“chosen”,指示人类注释者首选的响应,“rejected”,指示人类注释者不喜欢的响应。这两列都应包含具有相同提示的消息列表。消息列表可能包括系统提示、指示、用户和助手之间的多轮对话,或工具调用/返回。让我们以 Anthropic 的有用性/无害性数据集 在 Hugging Face 上 为例,它是一个多轮聊天风格格式的示例
| chosen | rejected |
|---------------------------------------|---------------------------------------|
|[{ |[{ |
| "role": "user", | "role": "user", |
| "content": "helping my granny with her| "content": "helping my granny with her|
| mobile phone issue" | mobile phone issue" |
| }, | }, |
| { | { |
| "role": "assistant", | "role": "assistant", |
| "content": "I see you are chatting | "content": "Well, the best choice here|
| with your grandmother about an issue | could be helping with so-called 'self-|
| with her mobile phone. How can I | management behaviors'. These are |
| help?" | things your grandma can do on her own |
| }, | to help her feel more in control." |
| { | }] |
| "role": "user", | |
| "content": "her phone is not turning | |
| on" | |
| }, | |
| {...}, | |
|] | |
目前,只支持 JSON 格式的对话,如上面的示例所示。您可以通过 hh_rlhf_helpful_dataset()
在 torchtune 中直接使用此数据集。
从 Hugging Face 加载偏好数据集¶
要从 Hugging Face 加载偏好数据集,您需要将数据集仓库名称传递给 source
。对于大多数 HF 数据集,您还需要指定 split
。
from torchtune.models.gemma import gemma_tokenizer
from torchtune.datasets import preference_dataset
g_tokenizer = gemma_tokenizer("/tmp/gemma-7b/tokenizer.model")
ds = chat_dataset(
tokenizer=g_tokenizer,
source="hendrydong/preference_700K",
split="train",
)
# Tokenizer is passed into the dataset in the recipe so we don't need it here
dataset:
_component_: torchtune.datasets.preference_dataset
source: hendrydong/preference_700K
split: train