LLM中损失函数解析

在GPT系列大语言模型中损失函数采用的是自回归语言建模任务,即根据前K-1个token预测第K个token,本质上都是交叉熵分类损失,在实现上预训练和监督微调稍有不同,本文分别进行介绍

预训练Pretrain

数据集

由于预训练数据集一般很大,因此一般全部处理完成之后,在代码中直接加载最终的token进行训练。一般经过以下流程:

  1. 依次读入所有的预训练语料,对每一个预训练语料的每一个样本进行分词处理tokenizer,并添加结束符,例如<eos>。
  2. (optional)将经过分词处理之后的所有预训练语料,拼接成一个整的大语料文件
  3. 对预训练语料进行维度变换,最终预训练样本的shape=[语料token总数//max_length, max_length],max_length是指模型输入token的最大长度
  4. 返回最终的训练语料,每条预训练样本的长度=max_length - 1或者max_length,X是输入,Y在自监督标签。代码如下:
def __getitem__(self, index: int):
        sample = self.data[index]  # 一个样本
        # X,Y前后错一位,seq_len = max_length - 1
        X = np.array(sample[:-1]).astype(np.int64)
        Y = np.array(sample[1:]).astype(np.int64)
        return torch.from_numpy(X), torch.from_numpy(Y)

例如:

原始预训练语料为:我爱吃饭   (分词结果为[100, 101, 102, 103])

则, X=[我,爱,吃] = [100, 101, 102]

        Y=[爱,吃,饭] = [101, 102, 103]

注:以上就是采用Teacher Forcing并且进行并行化训练,模型直接输入整个单词序列和对应的真值标签。

计算损失

最终计算损失函数的次数 = batch size * seq_len。即相当于以下计算过程:

X = [我], Y=[爱]

X = [我,爱], Y=[吃]

X = [我,爱,吃], Y=[饭]

注:但每条预训练样本只完整前向计算1次,为了保证看不到后面的token,需要在网络结果中采用masked self-attention

采用分类中常用的交叉熵损失函数,类别数=词典大小

logits = self.output(h)  # logits.shape=[bs, seq_len, vocab_size]
# logits_view.shapre=[bs * seq_len, vocab_size],  targets.shape=[bs * seq_len]
self.last_loss = F.cross_entropy(logits.view(-1, logits.size(-1)), targets.view(-1), ignore_index=-1)

监督微调SFT

数据集

由于SFT样本一般较小,因此也可以只读取原始文本,在dataloader中进行分词处理,一般经过以下步骤:

  1. 构建完整SFT原始数据集,例如可以以csv/json等格式存储,最终只包括prompt和answer两个字段
  2. 在SFTDataset类中分别对prompt和answer进行分词处理,(还可以在answer前后增加特殊字符<bos>,<eos等>)
  3. 设置每一个样本的loss_mask:prompt部分位置的值为0,其余部分位置的值为1(下面示例代码只是一种策略)
  4. 返回X, Y, loss_mask。 其中X和Y也是同一条样本前后错一位得到(注意:并不是X是prompt,Y是answer)

def __getitem__(self, index: int):
        #
        sample = self.df.iloc[index] # 一行样本
        prompt = self.tokenizer.encode(sample['prompt'],add_special_tokens=False)
        answer = self.tokenizer.encode(sample['answer'],add_special_tokens=False)
        if len(prompt) > self.prompt_max_len:
            prompt = prompt[:self.prompt_max_len-2]
        if len(answer) > self.answer_max_len:
            answer = answer[:self.answer_max_len-2]
        #
        input_id = prompt + [self.bos] + answer + [self.eos]
        context_length = input_id.index(self.bos)  # 答案的开始位置
        mask_position = context_length - 1         # mask的结束位置
        pad_len = self.max_length - len(input_id)  # pad长度
        input_id = input_id + [self.pad] * pad_len

        if pad_len == 0:
            loss_mask = [0]*context_length + [1]*(len(input_id[mask_position+1:]))
        else:
            loss_mask = [0]*context_length + [1]*(len(input_id[mask_position+1:-pad_len])) + [0]*pad_len
        #
        input_id = np.array(input_id)
        X = np.array(input_id[:-1]).astype(np.int64)
        Y = np.array(input_id[1:]).astype(np.int64)
        loss_mask = np.array(loss_mask[:-1])
        #
        return torch.from_numpy(X),torch.from_numpy(Y),torch.from_numpy(loss_mask)

计算损失

仍采样交叉熵损失,但参数reduce=False,计算返回结果与输入的维度相同,然后采用loss_mask不计算Prompt部分的损失,最后求在answer个数上的均值。

logits = model(X, Y)
# logits.shape = [bs, seq_len, vocab_size],  (seq_len=max_len - 1),    Y.shape = [bs, seq_len]
loss = F.cross_entropy(logits.view(-1, logits.size(-1)), Y.view(-1), ignore_index=0, reduce=False)  # loss.shape = [bs * seq_len]
loss_mask = loss_mask.view(-1) # [bs * seqlen]
loss = torch.sum(loss*loss_mask) / loss_mask.sum()

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
LLM(基于学习的管理方法)是一种在智能决策广泛应用的方法。LLM适用于各种领域,如金融、医疗、交通等。 首先,LLM利用机器学习算法对大量数据进行分析和预测。它可以通过学习历史数据的模式和趋势,将其应用于决策问题。通过分析数据,LLM可以发现隐藏在大量数据的规律和关联,为决策提供有力的支持。例如,在金融领域LLM可以分析市场数据、企业财务报表等信息,预测股票的涨跌趋势,从而帮助投资者做出明智的投资决策。 其次,LLM还可以进行优化和调整。它可以不断学习和改进,根据反馈信息进行自适应调整。通过与环境的互动,LLM可以不断优化模型,并根据情况调整决策策略。例如,在交通管理LLM可以通过分析交通流量数据,根据实时情况调整路线规划,降低交通拥堵,提高通行效率。 此外,LLM在智能决策的应用还包括风险评估、问题诊断和策略制定等方面。通过对历史数据和现有情况的分析,LLM可以预测潜在风险和问题,并提供相应的策略和措施。例如,在医疗领域LLM可以通过分析患者的病历和病情数据,预测患者的病情发展趋势,帮助医生制定更准确的治疗方案。 综上所述,LLM在智能决策的应用广泛且重要。它利用机器学习算法对大量数据进行分析和预测,为决策提供有力的支持。同时,LLM还可以进行优化和调整,根据环境的变化不断改进决策策略。LLM的应用可以提高决策的准确性和效率,在各个领域发挥重要作用。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值