【LLM系列之指令微调】长话短说大模型指令微调的“Prompt”

news2024/12/29 10:41:36

1 指令微调数据集形式“花样”太多

大家有没有分析过 prompt对模型训练或者推理的影响?之前推理的时候,发现不加训练的时候prompt,直接输入模型性能会变差的,这个倒是可以理解。假如不加prompt直接训练,是不是测试的时候不加prompt也可以?还有一个就是多轮prompt和单轮prompt怎么构造的问题?好多模型训练方式不统一 包括指令数据形式有所不同,选择困难症又来了。。

在这里插入图片描述

先说一些观点,假如我们在微调一个大模型,单次实验微调所用的指令微调数据集应该选取“质量高、多样性”,在训练资源充足的情况可以加入数量更多,长度更大的数据集。可以基于多个质量比较高的数据,做一份格式统一的多样性数据用来做sft,一次性微调完比较好,多次微调效果可能会折扣。或者有继续微调比较合适的方案也可以,不损失之前模型的效果(或者损失比较小),目前可以尝试Lora或者Qlora的方式微调底座模型,然后将训练好的Lora权重合并到原始模型,这样可以减轻多次微调对模型的影响。

2 常见指令微调模板

通过观测一些排行榜靠前和主流指令微调数据集,笔者总结一些常见的指令微调的Prompt:

常见的是stanford_alpaca中模板

PROMPT_DICT = {
    "prompt_input": (
        "Below is an instruction that describes a task, paired with an input that provides further context. "
        "Write a response that appropriately completes the request.\n\n"
        "### Instruction:\n{instruction}\n\n### Input:\n{input}\n\n### Response:"
    ),
    "prompt_no_input": (
        "Below is an instruction that describes a task. "
        "Write a response that appropriately completes the request.\n\n"
        "### Instruction:\n{instruction}\n\n### Response:"
    ),
}

Llama2中的模板

instruction = """[INST] <<SYS>>\nYou are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe.  Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.

            If a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, please don't share false information.\n<</SYS>>\n\n{} [/INST]"""

Linly-AI中模板

### Instruction:{prompt.strip()}  ### Response:

OpenLLM 排行榜top1的NousResearch

和alpaca模板差不多

### Instruction:
<prompt>

### Response:
<leave a newline blank for model to respond>
### Instruction:
<prompt>

### Input:
<additional context>

### Response:
<leave a newline blank for model to respond>

Yayi模板

https://huggingface.co/wenge-research/yayi-7b-llama2

prompt = "你是谁?"
formatted_prompt = f"""<|System|>:
You are a helpful, respectful and honest assistant named YaYi developed by Beijing Wenge Technology Co.,Ltd. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.\n\nIf a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, please don't share false information.

<|Human|>:
{prompt}

<|YaYi|>:
"""

StableBeluga2的模板

### System:
This is a system prompt, please behave and help the user.

### User:
Your prompt here

### Assistant:
The output of Stable Beluga 2

比如

system_prompt = "### System:\nYou are Stable Beluga, an AI that follows instructions extremely well. Help as much as you can. Remember, be safe, and don't do anything illegal.\n\n"

message = "Write me a poem please"
prompt = f"{system_prompt}### User: {message}\n\n### Assistant:\n"

Guanaco数据集常用模板

### Human: {prompt}
### Assistant:
prompt = "Introduce yourself"
formatted_prompt = (
    f"A chat between a curious human and an artificial intelligence assistant."
    f"The assistant gives helpful, detailed, and polite answers to the user's questions.\n"
    f"### Human: {prompt} ### Assistant:"
)

3 多轮对话输入和输出构造

参考yangjianxin1/Firefly项目和LinkSoul-AI/Chinese-Llama-2-7b项目,一般采用的方式是:

在计算loss时,我们通过mask的方式,input部分的loss不参与参数更新,只有“target”部分的loss参与参数更新。 这种方式充分利用了模型并行计算的优势,训练更加高效,且多轮对话中的每个target部分都参与了训练,训练更充分。 否则,就需要把一个n轮对话,拆分成n条数据,且只计算最后一个target的loss,大大降低了训练效率。

具体实现方式1:

# https://github.com/LinkSoul-AI/Chinese-Llama-2-7b/blob/main/train.py
def tokenize(item, tokenizer):
    roles = {"human": "user", "gpt": "assistant"}
    input_ids = []
    labels = []
    if "instruction" in item and len(item["instruction"]) > 0:
        system = item["instruction"]
    else:
        system = dummy_message["system"]
    system = B_SYS + system + E_SYS
    # add system before the first content in conversations
    item["conversations"][0]['value'] = system + item["conversations"][0]['value']
    for i, turn in enumerate(item["conversations"]):
        role = turn['from']
        content = turn['value']
        content = content.strip()
        if role == 'human':
            content = f"{B_INST} {content} {E_INST} "
            content_ids = tokenizer.encode(content)
            labels += [IGNORE_TOKEN_ID] * (len(content_ids))
        else:
            # assert role == "gpt"
            content = f"{content} "
            content_ids = tokenizer.encode(content, add_special_tokens=False) + [tokenizer.eos_token_id]   # add_special_tokens=False remove bos token, and add eos at the end
            labels += content_ids
        input_ids += content_ids

    input_ids = input_ids[:tokenizer.model_max_length]
    labels = labels[:tokenizer.model_max_length]

    trunc_id = last_index(labels, IGNORE_TOKEN_ID) + 1
    input_ids = input_ids[:trunc_id]
    labels = labels[:trunc_id]
    if len(labels) == 0:
        return tokenize(dummy_message, tokenizer)
    input_ids = safe_ids(input_ids, tokenizer.vocab_size, tokenizer.pad_token_id)
    labels = safe_ids(labels, tokenizer.vocab_size, IGNORE_TOKEN_ID)
    return input_ids, labels

具体实现方式1:

# https://github.com/yangjianxin1/Firefly/blob/master/component/dataset.py
class SFTDataset(Dataset):
    def __init__(self, file, tokenizer, max_seq_length):
        self.tokenizer = tokenizer
        self.bos_token_id = tokenizer.bos_token_id
        self.eos_token_id = tokenizer.eos_token_id
        self.eos_token = tokenizer.eos_token
        self.bos_token = tokenizer.bos_token
        self.max_seq_length = max_seq_length
        logger.info('Loading data: {}'.format(file))
        with open(file, 'r', encoding='utf8') as f:
            data_list = f.readlines()
        logger.info("there are {} data in dataset".format(len(data_list)))
        self.data_list = data_list

    def __len__(self):
        return len(self.data_list)

    def __getitem__(self, index):
        # 每条数据格式为: <s>input1</s>target1</s>input2</s>target2</s>...
        data = self.data_list[index]
        data = json.loads(data)
        conversation = data['conversation']

        # 收集多轮对话
        utterances = []
        for x in conversation:
            utterances.append(x['human'])
            utterances.append(x['assistant'])
        utterances_ids = self.tokenizer(utterances, add_special_tokens=False).input_ids

        # 模型的输入格式为:<s>input1</s>target1</s>input2</s>target2</s>...
        input_ids = [self.bos_token_id]
        target_mask = [0]  # 用于对input进行mask,只计算target部分的loss
        for i, utterances_id in enumerate(utterances_ids):
            input_ids += (utterances_id + [self.eos_token_id])
            if i % 2 == 0:
                target_mask += [0] * (len(utterances_id) + 1)
            else:
                target_mask += [1] * (len(utterances_id) + 1)
        assert len(input_ids) == len(target_mask)
        # 对长度进行截断
        input_ids = input_ids[:self.max_seq_length]
        target_mask = target_mask[:self.max_seq_length]
        attention_mask = [1] * len(input_ids)
        assert len(input_ids) == len(target_mask) == len(attention_mask)
        inputs = {
            'input_ids': input_ids,
            'attention_mask': attention_mask,
            'target_mask': target_mask
        }
        return inputs

核心代码就是通过IGNORE_INDEX(-100)遮蔽掉input对应的目标输出即可。

4 如何高效率微调大模型

如何短时间、高效率的训练出实际效果不错、综合能力比较强的大模型呢?从指令微调数据集处理工作上,个人认为可以从以下方式进行:
(1) 事先准备多种高质量的指令微调数据集,每个数据集尽量保持差异性。那高质量如何定义呢?我们可以从一些效果不错的模型收集它们训练使用的指令数据集
(2)笔者在实验过程中,发现加入多伦对话的数据有助于提升模型生成能力,如果仅用单轮对话或者单轮指令训练出的模型生成长度可能偏短。
(3)另外通过实验发现,如果模型微调的时候使用模板,那么推理的时候应该也使用模板,否则效果会影响,直观上就是生成效果不理想,生成比较短,甚至“驴唇不对马嘴”;训练使用了英文模板,推理的时候未使用提示模板的情况下会出现中英文混杂现象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/817095.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux网络编程--select多路IO转接模型

目录 1.TCP状态转换图 2.端口复用 3.半关闭状态 4.心跳包 5.高并发服务器模型--select 6.提纲总结 学习目录 熟练掌握TCP状态转换图熟练掌握端口复用的方法了解半关闭的概念和实现方式了解多路IO转接模型熟练掌握select函数的使用熟练使用fd_set相关函数的使用能够编写s…

winform学习(3)-----Windows窗体应用和Windows窗体应用(.Net Framework)有啥区别?

1.模板选择 在学习winform的时候总是会对这两个应用不知道选择哪个&#xff1f;而且在学习的时候也没有具体的说明 首先说一下我是在添加控件的时候出现了以下问题 对于使用了Windows窗体应用这个模板的文件在工具箱中死活不见控件。 在转换使用了Windows窗体应用(.NET Fram…

JAVA基础原理篇_1.1—— 关于JVM 、JDK以及 JRE

目录 一、关于JVM 、JDK以及 JRE 1. JVM 2. JDK 3. JRE 二、为什么说 Java 语言“编译与解释并存”&#xff1f; 2.2 将高级编程语言按照程序的执行方式分为两种&#xff1a; 2.2 Java的执行过程&#xff1a; 2.3 所以为什么Java语言“编译与解释"共存&#xff1a…

Quartz中Misfire机制源码级解析

文章目录 前文案例展示Misfire机制1. 启动过程补偿2. 定时任务补偿3. 查询待触发列表时间区间补偿 前文 Misfire是啥意义的&#xff1f;使用翻译软件结果是"失火"。一个定时软件&#xff0c;还来失火&#xff1f;其实在Java里面&#xff0c;fire的含义更应该是触发&…

Ai创作系统ChatGPT源码搭建教程+附源码

系统使用Nestjs和Vue3框架技术&#xff0c;持续集成AI能力到本系统&#xff01; 更新内容&#xff1a; 同步官方图片重新生成指令 同步官方 Vary 指令 单张图片对比加强 Vary(Strong) | Vary(Subtle) 同步官方 Zoom 指令 单张图片无限缩放 Zoom out 2x | Zoom out 1.5x 新增GP…

Linux学习之信号

trap -l和kill -l都可以列出来信号所有值。 而trap "命令1;命令2;" 信号可以捕捉到信号之后再执行命令1、命令2等命令&#xff0c;这里的命令可以不止两条。 快捷键产生信号 echo "This is a test" > trapTest.txt将This is a test写入到trapTest.t…

分布式配置中心Nacos

文章目录 一、Nacos分布式配置中心1、使用分布式配置中心的优点2、Nacos配置中心和应用间的数据同步的三种模式3、Namespace命名空间4、DataID配置5、Group配置 二、Nacos分布式配置中心的使用1、将应用对接Nacos配置中心2、Nacos实现配置动态刷新RefreshScope3、Dubbo服务对接…

QT--day6(人脸识别、图像处理)

人脸识别&#xff1a; /***********************************************************************************头文件****************************************************************************************/#ifndef WIDGET_H #define WIDGET_H#include <QWidget>…

HCIP期中实验

考试需求 1 、该拓扑为公司网络&#xff0c;其中包括公司总部、公司分部以及公司骨干网&#xff0c;不包含运营商公网部分。 2 、设备名称均使用拓扑上名称改名&#xff0c;并且区分大小写。 3 、整张拓扑均使用私网地址进行配置。 4 、整张网络中&#xff0c;运行 OSPF 协议…

汽车销售企业消费税,增值税高怎么合理解决?

《税筹顾问》专注于园区招商、企业税务筹划&#xff0c;合理合规助力企业节税&#xff01; 汽车行业一直处于炙手可热的阶段&#xff0c;这是因为个人或者家庭用车的需求在不断攀升&#xff0c;同时随着新能源的技术进一步应用到汽车领域&#xff0c;一度实现了汽车销量的翻倍。…

JavaSE类和对象(2)(重点:封装、包、static静态变量和方法)

目录 一、封装 1.封装&#xff1a;从语法来看&#xff0c;就是被private修饰的成员变量或者成员方法。只能在当前类当中使用。 2.快捷键&#xff0c;自动生成set或者get方法 3.限定访问修饰符&#xff08;private、 protected、public&#xff09; public&#xff1a;可以理…

python数学建模_2:灰色预测模型(GM(1,1))使用文档

灰色预测模型(GM(1,1))使用文档简介使用时机处理数据类型函数说明使用示例注意事项具体项目 灰色预测模型(GM(1,1))使用文档 简介 灰色预测模型(GM(1,1))是灰色系统理论的重要部分&#xff0c;常用于对包含不确定性的系统进行建模和预测。 使用时机 当数据量较小&#xff0…

树莓派通过天线+gps获取经纬度并调用高德地图api在地图上标点

完整项目为《基于机器视觉的行人和路面缺陷检测及其边缘设备部署》 完整功能视频演示地址&#xff1a;本科最后的课设&#xff1a;“车载系统的辅助系统——基于机器视觉的行人和路面缺陷检测”完结撒花*罒▽罒*_哔哩哔哩_bilibili 该博客介绍的功能为&#xff1a; 1&#xff1…

VS下开发Qt应用环境搭建

VS下开发Qt应用环境搭建 版本说明环境搭建步骤QT新增组件重新安装QTVS中的配置 版本说明 vs2019 QT5.14 我之前是按照QT基础组件的安装&#xff0c;但是这个安装只是最基础的组件&#xff0c;如果想要在VS中使用QT&#xff0c;还得安装其他组件&#xff0c;下面的安装流程、 …

轻松解决宝塔面板设置了授权IP访问,但是IP变动导致访问不了面板

为了宝塔面板的安全与隐蔽性&#xff0c;我们很多站长会设置授权IP&#xff0c;授权IP的作用是&#xff1a;设置访问授权IP,多个请使用逗号(,)隔开;注意&#xff1a;一旦设置授权IP,只有指定IP的电脑能访问面板! 但是很多站长不是通过专用的虚拟通道访问&#xff0c;用的都是宽…

【Python系列】Python基础语法轻松入门—从变量到循环

目录 写在前面 语法介绍 变量 数据类型 整数 浮点数 字符串 列表 元组 字典 运算符 算术运算符 比较运算符 逻辑运算符 条件语句 循环语句 图书推荐 图书介绍 参与方式 中奖名单 写在前面 Python 是一种高级、解释型的编程语言&#xff0c;具有简单易学…

恒心工程PMO运作实践︱恒丰银行苏州分行行长(拟)姜兆华

恒丰银行股份有限公司苏州分行党委书记、行长&#xff08;拟&#xff09;&#xff0c;原总行金融科技部副总经理、恒心工程PMO办公室主任姜兆华先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;恒心工程PMO运作实践——以商业银行核…

京东的成功秘诀:找到自己独特而有效的商业模式

你知道京东为什么能够从一个卖电器的小网站发展成为中国最大的电商平台吗&#xff1f;如果京东一开始靠卖电器赚钱&#xff0c;不可能有今天&#xff0c;在十几年刘强东刚创业的时候&#xff0c;如果京东靠卖电器赚钱&#xff0c;你知道想当年的国美黄光裕和想当年的苏宁的张近…

磁盘均衡器:HDFS Disk Balancer

HDFS Disk Balancer 背景产生的问题以及解决方法 hdfs disk balancer简介HDFS Disk Balancer功能数据传播报告 HDFS Disk Balancer开启相关命令 背景 相比较于个人PC&#xff0c;服务器一般可以通过挂载多块磁盘来扩大单机的存储能力在Hadoop HDFS中&#xff0c;DataNode负责最…

F5 LTM 知识点和实验 7-使用SNATs处理流量

第七章:使用SNATs处理流量 SNATs: 传统的vs都是对目的地址和端口进行改变,而源地址没有改变,如果你需要对源地址和源端口进行更改,则需要使用SNAT能力,好处在于: 1、允许不可路由地址(网络内部)的设备获得可路由地址以进入网络外部。2、确保目标服务器通过BIG-IP系统返…