NLP(19)--大模型发展(3)

news2024/9/22 9:45:53

前言

仅记录学习过程,有问题欢迎讨论

大模型训练相关知识:

问题:

  1. 数据集过大,快速训练
  2. 模型过大,gpu跑不完

方案:

  • 数据并行训练:
    复制数据(batch_size)到多个gpu,各自计算loss,再反传更新;至少需要一张卡能训练一个样本
  • 模型并行:
    模型的不同层放到不同的gpu上,解决了单卡不够大的问题,但是需要更多的通讯时间了(一次训练需要传播很多次)【时间换空间】
  • 张量并行:
    将张量划分到不同的gpu上(张量左右分割),进一步减少对单卡的需求,【时间换空间】
    可以混合使用

浮点精度损失:
float32:
使用32位二进制来表示一个浮点数。第一位用于表示符号位(正或负),
接下来的八位用于表示指数,剩下的23位用于表示尾数或分数部分。Float32的数值范围大约在±3.4E+38之间
0.2 = 0.00110(B)~、
DeepSpeed(零冗余优化器)

优化训练的方案

ZeRo:

  • 相当于张量并行,gradients,parameters,分散到不同gpu计算。速度变慢
    ZeRo -offload
    添加内存帮助显卡计算哈哈

大模型的蒸馏: 小模型直接学习文本数据之外,还学习大模型预测的结果
大模型的剪枝: 删除大模型中不重要的部分,减少模型大小

PEFT微调:(当大模型对某个方面表现不好)

  • 预训练模型+微调数据集
    原始权重不动,增加一部分可训练的权重,去结合之前的部分

prompt tuning:

  • 预训练模型+提示词(提前告诉模型需要训练什么)(添加在input data)

P-tuning V2:训练虚拟token(添加在emb)

  • 该方法将 Prompt 转换为可以学习的 Embedding 层,并用MLP+LSTM的方式来对Prompt Embedding进行一层处理。

Adapter: 新增可训练的层(添加在fft后)

LoRa(目前比较流行):

  • 通过低秩分解来模拟参数的改变量,从而以极小的参数量来实现大模型的间接训练(最后再扩大)。

RAG(Retrieve Augmented Generation):

  • 模型幻觉问题,遇见不知道的问题,会乱答
    召回部分和Prompt相似的段落,重新输入模型,获取可靠答案。

优势(主要就这两条):
(1)可扩展性:减少模型大小和训练成本,并能够快速扩展知识。

(2)准确性:模型基于事实进行回答,减少幻觉的发生。

难点
(1)数据标注:需要对数据进行标注,以提供给模型进行检索。

(2)检索算法:需要设计高效的检索算法,以提高检索的效率和准确率。
在这里插入图片描述

BPE(Byte pair encoding):压缩算法

  • RAG针对词表vocab的以下问题
    1.测试过程出现词表没有的词
    2.词表过大
    3.不同语种,切分粒度不同

  • 如aaabdaaaabc ==> XdXac
    在nlp中,针对语料中出现的重复词,添加到vocab中,再切分,再添加

  • BPE通过构建跨语言共享的子词词汇表,提高了模型处理多种语言的能力,有效解决了不同语言间词汇差异大、低频词和OOV问题,增强了模型的泛化能力和翻译性能。

代码:

使用lora对大模型进行微调:
使用的是序列标注的ner代码
main.py

# -*- coding: utf-8 -*-

import torch
import os
import random
import os
import numpy as np
import logging
from config import Config
from model import TorchModel, choose_optimizer
from evaluate import Evaluator
from loader import load_data
from peft import get_peft_model, LoraConfig, TaskType

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

"""
模型训练主程序
"""


def peft_wrapper(model):
    peft_config = LoraConfig(
        r=8,
        lora_alpha=32,
        lora_dropout=0.1,
        target_modules=["query", "value"]
    )
    return get_peft_model(model, peft_config)


def main(config):
    # 创建保存模型的目录
    if not os.path.isdir(config["model_path"]):
        os.mkdir(config["model_path"])
    # 加载训练数据
    train_data = load_data(config["train_data_path"], config)
    # 加载模型
    model = TorchModel(config)
    model = peft_wrapper(model)
    # 标识是否使用gpu
    cuda_flag = torch.cuda.is_available()
    if cuda_flag:
        logger.info("gpu可以使用,迁移模型至gpu")
        model = model.cuda()
    # 加载优化器
    optimizer = choose_optimizer(config, model)
    # 加载效果测试类
    evaluator = Evaluator(config, model, logger)
    # 训练
    for epoch in range(config["epoch"]):
        epoch += 1
        model.train()
        logger.info("epoch %d begin" % epoch)
        train_loss = []
        for index, batch_data in enumerate(train_data):
            optimizer.zero_grad()
            if cuda_flag:
                batch_data = [d.cuda() for d in batch_data]
            input_id, labels = batch_data  # 输入变化时这里需要修改,比如多输入,多输出的情况
            loss = model(input_id, labels)
            loss.backward()
            optimizer.step()
            train_loss.append(loss.item())
            if index % int(len(train_data) / 2) == 0:
                logger.info("batch loss %f" % loss)
        logger.info("epoch average loss: %f" % np.mean(train_loss))
        evaluator.eval(epoch)
    model_path = os.path.join(config["model_path"], "epoch_%d.pth" % epoch)
    # torch.save(model.state_dict(), model_path)

    return model, train_data


if __name__ == "__main__":
    model, train_data = main(Config)

model.py

# -*- coding: utf-8 -*-

import torch
import torch.nn as nn
from torch.optim import Adam, SGD
from torchcrf import CRF
from transformers import BertModel

"""
建立网络模型结构
"""


class ConfigWrapper(object):
    def __init__(self, config):
        self.config = config

    def to_dict(self):
        return self.config


class TorchModel(nn.Module):
    def __init__(self, config):
        super(TorchModel, self).__init__()
        self.config = ConfigWrapper(config)
        max_length = config["max_length"]
        class_num = config["class_num"]
        # self.embedding = nn.Embedding(vocab_size, hidden_size, padding_idx=0)
        # self.layer = nn.LSTM(hidden_size, hidden_size, batch_first=True, bidirectional=True, num_layers=num_layers)
        self.bert = BertModel.from_pretrained(config["bert_path"], return_dict=False)
        self.classify = nn.Linear(self.bert.config.hidden_size, class_num)
        self.crf_layer = CRF(class_num, batch_first=True)
        self.use_crf = config["use_crf"]
        self.loss = torch.nn.CrossEntropyLoss(ignore_index=-1)  # loss采用交叉熵损失

    # 当输入真实标签,返回loss值;无真实标签,返回预测值
    def forward(self, x, target=None):
        # x = self.embedding(x)  #input shape:(batch_size, sen_len)
        # x, _ = self.layer(x)      #input shape:(batch_size, sen_len, input_dim)
        x, _ = self.bert(x)
        predict = self.classify(x)  # ouput:(batch_size, sen_len, num_tags) -> (batch_size * sen_len, num_tags)

        if target is not None:
            if self.use_crf:
                mask = target.gt(-1)
                return - self.crf_layer(predict, target, mask, reduction="mean")
            else:
                # (number, class_num), (number)
                return self.loss(predict.view(-1, predict.shape[-1]), target.view(-1))
        else:
            if self.use_crf:
                return self.crf_layer.decode(predict)
            else:
                return predict


def choose_optimizer(config, model):
    optimizer = config["optimizer"]
    learning_rate = config["learning_rate"]
    if optimizer == "adam":
        return Adam(model.parameters(), lr=learning_rate)
    elif optimizer == "sgd":
        return SGD(model.parameters(), lr=learning_rate)


if __name__ == "__main__":
    from config import Config

    model = TorchModel(Config)

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

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

相关文章

机器学习实验------Adaboost算法

第1关:什么是集成学习 任务描述 本关任务:根据本节课所学知识完成本关所设置的选择题。 第2关: Boosting 任务描述 本关任务:根据本节课所学知识完成本关所设置的选择题。 第3关:Adaboost算法流程 任务描述 …

C++学习/复习4--与类相关的概念/默认成员函数/运算符重载/Date类实现案例

一、类和对象 1.本章概要 2.C中的结构体(struct与class) 升级为类 (1)类及成员函数的两种定义方式 声明与定义分离 (2)权限 注意1:struct/class在权限上的区别 (3)封装 (4&#x…

连公司WiFi后,无法访问外网,怎么回事,如何解决?

文章目录 封面问题描述问题探究什么是DNS?分布式,层次数据库如何理解分布式?如何理解层次? 本地DNS服务器迭代查询,递归查询DNS缓存参考资料 封面 问题描述 从甲方项目组返回公司后,我习惯性连上公司WiFi&…

50 http通用服务器

虽然我们说,应用层协议是我们程序猿自己定的 但实际上,已经有大佬们定义了一些现成的,又非常好用的应用层协议,供我们直接参考使用,http(超文本传输协议)就是其中之一 目录 认识urlurlencode和…

数据库(5)——DDL 表操作

表查询 先要进入到某一个数据库中才可使用这些指令。 SHOW TABLES; 可查询当前数据库中所有的表。 表创建 CREATE TABLE 表名( 字段1 类型 [COMMENT 字段1注释] ...... 字段n 类型 [COMMENT 字段n注释] )[COMMENT 表注释]; 例如,在student数据库里创建一张studen…

LeetCode热题100——矩阵

73.矩阵清零 题目 给定一个 *m* x *n* 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]] 示例…

记.netcore部署到银河麒麟linux服务器过程详解

一.服务器配置 操作系统:银河麒麟桌面操作系统V10 CPU:intel i5 内存:16G 内核:5.10.0.8-generic 未激活 二.运行环境安装 .netcore 6.0 runtime时安装下载离线包 Download .NET 6.0 (Linux, macOS, and Windows) -下载完后进行解压 sudo su #提权 mkdir -p $HOME/…

救援运输车3D三维虚拟展馆能分享给更多潜在买家

随着消费趋势的演进,个性化和附加服务需求日益凸显。加上疫情等因素影响下,一场创新的革命正在悄然兴起——3D沉浸式看车。 3D沉浸式看车,重新定义购车体验 不再受限于地理位置和时间,3D沉浸式看车是利用web3d开发建模技术将真实比…

C# 机构仿真实例

1、实现连杆带动滑块运动 一个连杆旋转带动另一个连杆,另一个连杆拖动滑块,点击“开始”按钮开始运动,再点击按钮,则停止运动。 2、实现程序 #region 机构仿真Image image null;Timer timer new Timer();int width 0;int heig…

一个机器学习问题的重新定义

任何事物都有两面性。 一些机器学习问题也是如此。并非每个回归问题(你认为的)都需要回归。仔细考虑和审视问题的业务不仅可以帮助开发更好的模型,还可以找到有效的解决方案。 重构或重新定义(reframing)是一种改变机…

【rust工具链】

1 查看正在使用的工具链 命令:rustup show 结果显示: 从图中可以看到正在使用的是rustc 1.76.0版本,也可以看到已安装的所有版本的工具链 2 使用默认工具链 命令:rustup default 版本号 例如:rustup default 1.58…

Python数据分析实验四:数据分析综合应用开发

目录 一、实验目的与要求二、主要实验过程1、加载数据集2、数据预处理3、划分数据集4、创建模型估计器5、模型拟合6、模型性能评估 三、主要程序清单和运行结果四、实验体会 一、实验目的与要求 1、目的: 综合运用所学知识,选取有实际背景的应用问题进行…

大模型中的Tokenizer

在使用GPT 、BERT模型输入词语常常会先进行tokenize 。 tokenize的目标是把输入的文本流,切分成一个个子串,每个子串相对有完整的语义,便于学习embedding表达和后续模型的使用。 一、粒度 三种粒度:word/subword/char word词&a…

人工智能+跨癌种分析,能否解决医学数据样本量小的问题?【医学AI|顶刊速递|05-26】

小罗碎碎念 先说明,目前小罗只是硕士,以下个人观点很有可能不准确,欢迎批评指正!!小罗虚心听取有益建议!! 众所周知,医学数据相比于其他领域的数据来说,属于小样本数据。…

Java----Maven详解

前言 Maven是Java项目的构建工具,通过项目对象模型(POM)管理项目配置信息,自动化构建、测试和部署过程。开发人员可定义项目结构、依赖和构建流程,提高开发效率和质量。本文介绍基本概念和用法,帮助您更好…

ros2编写pcl节点加载pcd文件

初次学习ros2和pcl,尝试在ros2中创建节点,加载pcd文件,并在rviz中进行可视化,记录一下整个过程。 编辑环境 ubuntu20.04 ros2_foxy 创建节点 mkdir -p proj_ws_pcl/src #创建工程文件夹 cd proj_ws_pcl/src #创建源码文件夹 …

社交媒体数据恢复:绿洲

本教程将向您展示如何在绿洲平台上备份和恢复数据,但不涉及推荐任何具体的数据恢复软件。 一、绿洲平台数据备份 为了确保数据的安全,在日常使用过程中,我们需要定期备份绿洲平台上的数据。以下是备份绿洲平台数据的步骤: 登录绿…

opencv进阶 ——(四)图像处理之去高光

去高光步骤: 1、转换成灰度图 2、二值化图像,得到高光区域 3、进行膨胀操作,放大高光区域,以此得到高光蒙版 4、通过illuminationChange函数对高光区域消除高光

Vite + Vue3 部署 GitHub

因为静态资源是可以部署到 GitHub 上,自己顺便学习部署网站 因为我使用的是 Vite 工具,官方有提供相应 Demo 部署静态站点 | Vite 官方中文文档 新建文件夹 .github 然后再建一个文件夹 workflows 新建文件 main.yml 文件 直接使用官方文档 demo #…