self-instruct数据集生成

本文将讲清楚self-instruct原理,并说明如何利用本地大模型实操!

概念

self-instruct是一种将预训练语言模型与指令对齐的方法。可以通过模型半自动生成数据,而不需要大量的人工标注。 self-instruct用来产生大模型的指令微调数据,以及扩充指令多样性。

原理

自指令过程是一种迭代引导算法,它从手动编写的指令种子集开始,并使用它们提示语言模型生成新指令和相应的输入输出实例。然后对这些生成进行过滤,以删除低质量或相似的生成,并将生成的数据添加回任务池。这个过程可以重复多次,从而产生大量的教学数据,可用于微调语言模型以更有效地遵循指令。

例如,上图所示,主要分为四个步骤:

1. 自动生成多样化的指令集

  • 功能: 利用预训练的语言模型扩展初始的人工编写的种子指令。
  • 主要任务: 通过自我迭代的方式生成新的指令,并将结果保存到文件中。
  • 输入:  种子指令文件 (seed_instructions.jsonl):包含由人类编写的基础指令。
  • 输出:  自动生成的指令文件 (machine_generated_instructions.jsonl):包含机器生成的新指令。

2.  利用大模型区分自动生成的指令是否属于分类任务

  • 功能: 识别并标记指令是否为分类任务。
  • 主要任务: 加载已有的机器生成指令,构建适当的提示询问每个指令是否为分类任务,并将结果保存到文件中供后续步骤使用。
  •  输入: 自动生成的指令文件 (machine_generated_instructions.jsonl)。
  •  输出: 指令分类标签文件 (is_clf_or_not_davinci_template_1.jsonl):包含每个指令及其是否为分类任务的标签。

3. 为每个指令创建具体的输入输出对(实例)

  • 功能: 为每个指令生成具体的输入输出对(实例)。
  • 主要任务: 根据指令是否为分类任务选择合适的模板,发送构建好的提示给API以获得实例,进行必要的后处理如去除无效或重复的实例,并保存结果。
  • 输入:

        自动生成的指令文件 (machine_generated_instructions.jsonl)。

        指令分类标签文件 (is_clf_or_not_davinci_template_1.jsonl)。

  •  输出:

        实例文件 (machine_generated_instances.jsonl):包含每个指令及其对应的多个具体输入输出对。

    注意,这里根据是否是分类任务来选择模板,如果是分类任务则使用output-first模板,否则使用input-first模板。分类任务的output就是分出来的种类,使用output-first方式是因为此种方式适合扩展和丰富数据集,特别是生成难以直接思考的问题(逆向问题设计),主要用于生成创新性或逆向思考的任务,帮助模型探索多样化的指令形式。

4. 准备用于微调的数据集

  • 功能: 将生成的实例与分类标签相结合,并根据需要加入种子任务,创建一个结构化的数据集,供后续微调使用。
  • 主要任务: 解析之前生成的实例文件和分类标签,控制每个任务的实例数量并确保数据集的质量,将所有经过处理的训练实例格式化并保存到文件中。
  • 输入:

        实例文件 (machine_generated_instances.jsonl)。

        指令分类标签文件 (is_clf_or_not_davinci_template_1.jsonl)。

        种子任务文件 (seed_tasks.jsonl)(可选):高质量的人类编写任务实例。

  •  输出:

        微调数据集 (all_generated_instances.jsonl):包含所有经过处理的训练实例,用于后续模型微调。

根据以上,我按照自己的理解画了一个图,流程如下:

实践

要基于足够大的大模型(例如 chatgpt3.5以上)因此,需要你有一个chatgpt账号,这个请自行搜索。

1. 申请chatgpt APIKey(土豪请使用此方法,不免费)

登录openai官网https://platform.openai.com/,直接看Quickstart里就有创建APIKey的链接。

按照操作即可。

很遗憾,chatgpt 的 APIKey没有免费的,因此放弃使用。那我们先来看看self-instruct的用法吧。

下文中的“我们”是指self-instruct的开发者。代码指的是 GitHub - yizhongw/self-instruct: Aligning pretrained language models with instruction data generated by themselves. main分支。

2. 使用本地千问大模型

公开的千问模型免费 10000个token,因此还是需要搭建一个本地模型。

首先你要有一个带GPU的环境,这里我使用的是容器环境,配备2个V100显卡,内存,和硬盘。用ollama拉起一个qwen2:72b模型(拉起方法详见我的另一篇博文使用API方式远程调用ollama模型-优快云博客

关于使用本地大模型半自动生成指令集已经有开源代码:GitHub - Empress7211/Local-LLM-Self_Instruct-XTuner: Automate LLM deployment, instruction data generation, and fine-tuning with a single command. Uses api-for-open-llm for local OpenAI-compatible API, self-instruct for quality data generation, and XTuner for task-specific fine-tuning. Streamlined workflow via Shell scripts for seamless setup, deployment, and model enhancement.

这个工程可以用,但是文件要一个一个下载。

从头开始生成Self-Instruct数据


第一步:根据种子生成instructions

该步骤实现的方式是运行如下命令:

# 1. 从种子任务生成指令(instruct)
./scripts/generate_instructions.sh

该脚本的内容如下所示:

该脚本是从种子文件里和已经生成自动生成的instruction里面选取 8 个任务指令作为上下文示例。 8 条指令中,6 条来自人工编写任务,2条来自前面步骤中模型生成的任务(初始时该文件为空),然后让大模型按照这个几个instruct再续接上一条新的instruct作为返回(即9条任务)。然后循环生成足够数量(这里指定10000个)的指令,第一步结束。

这里面的8,6都是可以用参数指令的。另外,上面脚本的参数意思是总共生成10000条指令,每次发送1个请求给大模型(大模型响应一次),每个请求里面有8个指令组成的prompts.

需要注意的是   GitHub - yizhongw/self-instruct: Aligning pretrained language models with instruction data generated by themselves.  源码里面使用的gpt3 API接口,需要改成qwen的API接口。并且返回的结果也有区别,即如果一个请求里面有多个Task,gpt3返回的结果里面有多个choices字段,而qwen的返回只有一个choices字段,多个task的回答在一起。因此每次只发送一个请求,便于解析。

此步骤生成的单条指令长这个样子:

其中most_similar展开如下所示:

第二步:判断生成的指令是否是分类任务

该步骤实现的方式是运行如下命令:

# 2. 识别指令是否代表分类任务
./scripts/is_clf_or_not.sh

该脚本的内容如下:

batch_dir=data/gpt3_generations/

python self_instruct/identify_clf_or_not.py \
    --batch_dir ${batch_dir} \
    --engine "qwen2:72b" \
    --request_batch_size 5

这一步是把第一步的生成结果的每条指令,添加上clf_task_template.py 分类模板内容在每一条指令之前,启发大模型判断最后的指令是否是分类任务。

提示词内容如下所示:

然后生成结果会标明每条指令是否是分类任务。对应上面的示例,此步骤生成的结果如下所示:

第三步:为每条指令生成实例

这步是最关键的一步,也是最难理解的一步。该步骤实现的方式是运行如下命令:

# 3. 为每条指令(instruct)生成实例(instance)
./scripts/generate_instances.sh

该脚本的内容是:

batch_dir=data/gpt3_generations/

python self_instruct/generate_instances.py \
    --batch_dir ${batch_dir} \
    --input_file machine_generated_instructions.jsonl \
    --output_file machine_generated_instances.jsonl \
    --max_instances_to_gen 5 \
    --engine "qwen2:72b" \
    --request_batch_size 5

该步骤用到了 instance_gen_template.py 中的两个模板output_first_template_for_clf 和

input_first_template_for_gen .

上图所示是英文版output_first模板部分内容。

运行脚本时,把output_first_template放在前面,添加目标指令在最后,让大模型生成实例(下图使用的是中文output first template):

对于非分类任务则使用下图所示input_first模板

同样把模板内容放在前面,添加目标指令在最后,让大模型生成实例。上面的示例在此步骤的生成结果如下图所示:

第四步:过滤优化

这是最后一个步骤,所有的步骤如下所示:

# 1. 从种子任务生成指令(instruct)
./scripts/generate_instructions.sh

# 2. 识别指令是否代表分类任务
./scripts/is_clf_or_not.sh

# 3. 为每条指令(instruct)生成实例(instance)
./scripts/generate_instances.sh

# 4. 过滤、处理和重新格式化
./scripts/prepare_for_finetuning.sh

分类实例生成

1.生成指令

2.判断是否是分类任务

3.生成实例

4.过滤

最终数据格式如下所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值