跳到内容

指令回译

"Self Alignment with Instruction Backtranslation" 提出了一种可扩展的方法,通过自动标记人类编写的文本及其相应的指令,来构建高质量的指令遵循语言模型。他们的方法名为指令回译,从一个在少量种子数据上微调的语言模型和一个给定的网络语料库开始。种子模型用于通过为网络文档生成指令提示(自我增强),然后从这些候选者中选择高质量的示例(自我精选)来构建训练示例。然后,这些数据用于微调更强大的模型。

Instruction Backtranslation pipeline overview

他们的自训练方法假设可以访问基础语言模型、少量种子数据和未标记示例的集合,例如网络语料库。未标记数据是大量、多样化的人类编写文档的集合,其中包括关于人类感兴趣的各种主题的写作——但关键是没有与指令配对。

第一个关键假设是,在这非常庞大的人类编写文本中,存在一些子集,这些子集适合作为某些用户指令的黄金生成结果。第二个关键假设是,他们可以为这些候选黄金答案预测指令,这些指令可以用作高质量的示例对,以训练指令遵循模型。

他们的总体流程,称为指令回译,执行两个核心步骤

  1. 自我增强:为未标记数据(即网络语料库)生成指令,以生成 (指令,输出) 对的候选训练数据,用于指令微调。

  2. 自我精选:自我选择高质量的演示示例作为训练数据,以微调基础模型以遵循指令。这种方法是迭代完成的,其中更好的中间指令遵循模型可以改进在下一次迭代中选择用于微调的数据。

此复现涵盖了自我精选步骤,即如上所述的第二个/后者步骤,以便能够使用所提出的提示方法来评估生成文本的质量,这些文本可以是合成生成的或真实的人类编写的文本。

复现

为了复现论文,我们将使用 distilabel 和 Hugging Face H4 团队创建的较小数据集 HuggingFaceH4/instruction-dataset 用于测试目的。

安装

要复现 Self Alignment with Instruction Backtranslation,需要按如下方式安装 distilabel

pip install "distilabel[hf-inference-endpoints,openai]>=1.0.0"

并且由于我们将使用 InferenceEndpointsLLM(通过额外的 hf-inference-endpoints 安装),我们将需要提前在本地或 Hugging Face Hub 中部署它们(或者也可以使用 serverless endpoints,但大多数情况下推理时间较慢,并且使用这些 endpoints 有限额,因为它们是免费的),并设置 HF_TOKEN(使用 InferenceEndpointsLLM)和 OPENAI_API_KEY 环境变量值(使用 OpenAILLM)。

构建模块

  • LoadDataFromHub:生成器 Step,用于从 Hugging Face Hub 加载数据集。
  • TextGeneration:Task,用于使用 LLM 为给定指令生成响应。
  • InstructionBacktranslation:Task,使用 Self Alignment with Instruction Backtranslation 提示为给定指令的响应生成分数和原因。
    • OpenAILLM:LLM,从 OpenAI 加载模型。

代码

如前所述,我们将把前面提到的构建模块放在一起,以复现 Self Alignment with Instruction Backtranslation。

from distilabel.models import InferenceEndpointsLLM, OpenAILLM
from distilabel.pipeline import Pipeline
from distilabel.steps import LoadDataFromHub, KeepColumns
from distilabel.steps.tasks import InstructionBacktranslation, TextGeneration


with Pipeline(name="self-alignment-with-instruction-backtranslation") as pipeline:
    load_hub_dataset = LoadDataFromHub(
        name="load_dataset",
        output_mappings={"prompt": "instruction"},
    )

    text_generation = TextGeneration(
        name="text_generation",
        llm=InferenceEndpointsLLM(
            base_url="<INFERENCE_ENDPOINT_URL>",
            tokenizer_id="argilla/notus-7b-v1",
            model_display_name="argilla/notus-7b-v1",
        ),
        input_batch_size=10,
        output_mappings={"model_name": "generation_model"},
    )

    instruction_backtranslation = InstructionBacktranslation(
        name="instruction_backtranslation",
        llm=OpenAILLM(model="gpt-4"),
        input_batch_size=10,
        output_mappings={"model_name": "scoring_model"},
    )

    keep_columns = KeepColumns(
        name="keep_columns",
        columns=[
            "instruction",
            "generation",
            "generation_model",
            "score",
            "reason",
            "scoring_model",
        ],
    )

    load_hub_dataset >> text_generation >> instruction_backtranslation >> keep_columns

然后我们需要使用运行时参数调用 pipeline.run,以便可以启动 pipeline。

distiset = pipeline.run(
    parameters={
        load_hub_dataset.name: {
            "repo_id": "HuggingFaceH4/instruction-dataset",
            "split": "test",
        },
        text_generation.name: {
            "llm": {
                "generation_kwargs": {
                    "max_new_tokens": 1024,
                    "temperature": 0.7,
                },
            },
        },
        instruction_backtranslation.name: {
            "llm": {
                "generation_kwargs": {
                    "max_new_tokens": 1024,
                    "temperature": 0.7,
                },
            },
        },
    },
)

最后,我们可以选择性地将生成的名为 Distiset 的数据集推送到 Hugging Face Hub,通过 push_to_hub 方法,以便在 leaf steps 中生成的每个子集都被推送到 Hub。

distiset.push_to_hub(
    "instruction-backtranslation-instruction-dataset",
    private=True,
)