ChatGLM-LLaMA-chinese-insturct 学习记录(含LoRA的源码理解)

这篇具有很好参考价值的文章主要介绍了ChatGLM-LLaMA-chinese-insturct 学习记录(含LoRA的源码理解)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。



前言

介绍:探索中文instruct数据在ChatGLM, LLaMA等LLM上微调表现,结合PEFT等方法降低资源需求。
Github: https://github.com/27182812/ChatGLM-LLaMA-chinese-insturct
补充学习:https://kexue.fm/archives/9138


一、实验记录

1.1 环境配置

优雅下载hugging face模型和数据集

conda update -n base -c defaults conda
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash
apt-get install git-lfs
git lfs install

git clone [模型|数据集|地址]

配置conda 环境

conda env create -f env.yml -n bab
conda activate bab
pip install git+https://github.com/huggingface/peft.git

数据集
belle数据集 和 自己收集的中文指令数据集
指令数据集

{
	"context": Instruction:[举一个使用以下对象的隐喻示例]\nInput:[星星]\nAnswer:, 
	"target": Answer:星星是夜空中闪烁的钻石。
}

1.2 代码理解

函数:gradient_checkpointing_enable
如何理解 gradient_checkpoint, 时间换空间,使得模型显存占用变小,但训练时长增加
PEFT的相关介绍
大模型训练——PEFT与LORA介绍
你也可以动手参数有效微调:LoRA、Prefix Tuning、P-Tuning、Prompt Tuning

1.2.1 LoRA

ChatGLM-LLaMA-chinese-insturct 学习记录(含LoRA的源码理解)
对于左右两个部分,右侧看起来像是左侧原有矩阵W WW的分解,将参数量从d ∗ d 变成了d ∗ r + d ∗ r ,在
r < < d的情况下,参数量就大大地降低了。LORA保留了原来的矩阵W,但是不让W参与训练,所以需要计算梯度的部分就只剩下旁支的A和B两个小矩阵。
蓝色部分的目标函数为:
ChatGLM-LLaMA-chinese-insturct 学习记录(含LoRA的源码理解)
加入LoRA之后:
ChatGLM-LLaMA-chinese-insturct 学习记录(含LoRA的源码理解)
但是相应地,引入LORA部分的参数,并不会在推理阶段加速(不是单纯的橙色部分进行计算),因为在前向计算的时候, 蓝色部分还是需要参与计算的,而Θ部分是凭空增加了的参数,所以理论上,推理阶段应该比原来的计算量增大一点。
ChatGLM-LLaMA-chinese-insturct 学习记录(含LoRA的源码理解)
技术细节:
ChatGLM-LLaMA-chinese-insturct 学习记录(含LoRA的源码理解)
α 可以理解我们在调整lr, α/r 实在缩放蓝色部分的输出,有助于减少训练的超参数

相关参数:
ChatGLM-LLaMA-chinese-insturct 学习记录(含LoRA的源码理解)
那么如何使用PEFT的LoRA

from peft import get_peft_model, LoraConfig, TaskType

peft_config = LoraConfig(
        task_type=TaskType.CAUSAL_LM,
        inference_mode=False,   
        r=finetune_args.lora_rank,
        lora_alpha=32,
        lora_dropout=0.1,
    )
    
model = get_peft_model(model, peft_config)

其中TaskType可以设置多种任务

class TaskType(str, enum.Enum):
    SEQ_CLS = "SEQ_CLS"   常规分类任务
    SEQ_2_SEQ_LM = "SEQ_2_SEQ_LM" seq2seq任务
    CAUSAL_LM = "CAUSAL_LM"  LM任务
    TOKEN_CLS = "TOKEN_CLS"  token的分类任务:序列标注之类的

参数解释:

inference_mode = Whether to use the Peft model in inference mode.

根据苏神的介绍,LST的效果应该是优于LoRA的:
ChatGLM-LLaMA-chinese-insturct 学习记录(含LoRA的源码理解)
每层当中都有分支,可以理解为LoRA是LST的超简化版本

    def __init__(self, model, config, adapter_name):
        super().__init__()
		...
        self.add_adapter(adapter_name, self.peft_config[adapter_name])

    def add_adapter(self, adapter_name, config=None):
		...
        self._find_and_replace(adapter_name)
		...
        mark_only_lora_as_trainable(self.model, self.peft_config[adapter_name].bias)
        if self.peft_config[adapter_name].inference_mode:
            _freeze_adapter(self.model, adapter_name)

核心类在

 def _find_and_replace(self, adapter_name):
        ...
        # 遍历整个需要训练的模型的名字,这个模型你可以理解为一个字典,拿出所有的key
        key_list = [key for key, _ in self.model.named_modules()]
        for key in key_list:
        	# 找到所有qkv的key
            if isinstance(lora_config.target_modules, str):
                target_module_found = re.fullmatch(lora_config.target_modules, key)
            else:
                target_module_found = any(key.endswith(target_key) for target_key in lora_config.target_modules)
                        ...
                        # 然后对于每一个找到的目标层,创建一个新的lora层
                        # 注意这里的Linear是在该py中新建的类,不是torch的Linear
                        new_module = Linear(adapter_name, in_features, out_features, bias=bias, **kwargs)
                    self._replace_module(parent, target_name, new_module, target)

replace_modul把原来的weight和bias赋给新创建的module,然后再分配到指定的设备上

    def _replace_module(self, parent_module, child_name, new_module, old_module):
        setattr(parent_module, child_name, new_module)
        new_module.weight = old_module.weight
        if old_module.bias is not None:
            new_module.bias = old_module.bias
        if getattr(old_module, "state", None) is not None:
            new_module.state = old_module.state
            new_module.to(old_module.weight.device)

        # dispatch to correct device
        for name, module in new_module.named_modules():
            if "lora_" in name:
                module.to(old_module.weight.device)

merge\ forward部分

    def merge(self):
        if self.active_adapter not in self.lora_A.keys():
            return
        if self.merged:
            warnings.warn("Already merged. Nothing to do.")
            return
        if self.r[self.active_adapter] > 0:
            self.weight.data += (
                transpose(
                    self.lora_B[self.active_adapter].weight @ self.lora_A[self.active_adapter].weight,
                    self.fan_in_fan_out,
                )
                * self.scaling[self.active_adapter]
            )
            self.merged = True
	
	def forward(self, x: torch.Tensor):
        previous_dtype = x.dtype

        if self.active_adapter not in self.lora_A.keys():
            return F.linear(x, transpose(self.weight, self.fan_in_fan_out), bias=self.bias)
        if self.disable_adapters:
            if self.r[self.active_adapter] > 0 and self.merged:
                self.unmerge()
            result = F.linear(x, transpose(self.weight, self.fan_in_fan_out), bias=self.bias)
        elif self.r[self.active_adapter] > 0 and not self.merged:
            result = F.linear(x, transpose(self.weight, self.fan_in_fan_out), bias=self.bias)

            x = x.to(self.lora_A[self.active_adapter].weight.dtype)

            result += (
                self.lora_B[self.active_adapter](
                    self.lora_A[self.active_adapter](self.lora_dropout[self.active_adapter](x))
                )
                * self.scaling[self.active_adapter]
            )
        else:
            result = F.linear(x, transpose(self.weight, self.fan_in_fan_out), bias=self.bias)

        result = result.to(previous_dtype)

        return result

评估的过程中,需要将lora部分的weight加到linear层原本的weight中,not self.merged是状态的记录,也就是说,如果设置了需要融合,而当前状态没有融合的话,就把lora部分的参数scale之后加上去,并且更新self.merged状态;

训练的过程中,确保linear本身的weights是没有经过融合过的

1.4 实验结果

chatglm-6b loss的下降不是特别多,3epoch效果也不是特别的明显,最近看到很多人反馈,不管是基于lora还是ptuning对原本的模型效果还是影响很大


二、总结

如果要基于大语言模型的FT,至少需要足够的显存,和语料,最好是将新的语料和原本的语料一起进行SFT文章来源地址https://www.toymoban.com/news/detail-515279.html

  • sft的原理还没有弄明白
  • 显存还需要扩充,使用deepspeed框架进行full FT,有资源谁还回去lora,ptuning呢?
  • 多轮的数据集还没有
  • 这个仓库的数据集还是,单轮的指令数据集,并没有涉及到多轮
  • 即使是官方的仓库也只是构造了多轮的训练脚本,数据集并没有提供
  • llama不跑了,只是换了一个模型而已

到了这里,关于ChatGLM-LLaMA-chinese-insturct 学习记录(含LoRA的源码理解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Chinese-LLaMA-Alpaca代码实战

    项目地址: https://github.com/ymcui/Chinese-LLaMA-Alpaca 由于LLaMA 原生仅支持 Latin 或 Cyrillic 语系,对于中文支持不是特别理想,并不像ChatGLM 和 Bloom 原生支持中文。但由于LLaMA模型在英文上的效果本身还是不错的,因此使用 模型词表扩充(中文词表) ,配合二次预训练及微调的方式

    2024年02月09日
    浏览(46)
  • Chinese-LLaMA-AIpaca 指令精调

    下载数据集 alpaca_data_zh_51k.json https://github.com/ymcui/Chinese-LLaMA-Alpaca/blob/main/data/alpaca_data_zh_51k.json Belle_open_source_0.5M.json https://huggingface.co/datasets/BelleGroup/train_0.5M_

    2024年02月03日
    浏览(34)
  • Chinese-LLaMA-Alpaca本地搭建(三)

    中文羊驼模型只是一些LoRA权重模型文件,与原版LLaMA模型合并后就可以生成一个完整模型使用了,在这过程中可以不断训练LoRA权重模型文件,无限训练后达到专业领域的效果,理论上就能投入使用了,但注意禁止商用的问题。 Facebook官方发布的LLaMA模型禁止商用,并且官方没

    2024年01月22日
    浏览(47)
  • Chinese-LLaMA-Alpaca本地搭建(四)

    中文羊驼模型只是一些LoRA权重模型文件,与原版LLaMA模型合并后就可以生成一个完整模型使用了,在这过程中可以不断训练LoRA权重模型文件,无限训练后达到专业领域的效果,理论上就能投入使用了,但注意禁止商用的问题。 Facebook官方发布的LLaMA模型禁止商用,并且官方没

    2024年02月14日
    浏览(44)
  • LLM - Chinese-Llama-2-7b 初体验

    目录 一.引言 二.模型下载 三.快速测试 四.训练数据 五.总结 自打 LLama-2 发布后就一直在等大佬们发布 LLama-2 的适配中文版,也是这几天蹲到了一版由 LinkSoul 发布的 Chinese-Llama-2-7b,其共发布了一个常规版本和一个 4-bit 的量化版本,今天我们主要体验下 Llama-2 的中文逻辑顺便

    2024年02月15日
    浏览(34)
  • 大模型部署手记(11)LLaMa2+Chinese-LLaMA-Plus-2-7B+Windows+llama.cpp+中文对话

    组织机构:Meta(Facebook) 代码仓:GitHub - facebookresearch/llama: Inference code for LLaMA models 模型:LIama-2-7b-hf、Chinese-LLaMA-Plus-2-7B   下载:使用huggingface.co和百度网盘下载 硬件环境:暗影精灵7Plus Windows版本:Windows 11家庭中文版 Insider Preview 22H2 内存 32G GPU显卡:Nvidia GTX 3080 Laptop (1

    2024年02月03日
    浏览(54)
  • 【个人笔记本】本地化部署详细流程 LLaMA中文模型:Chinese-LLaMA-Alpaca-2

    不推荐小白,环境配置比较复杂 下载原始模型:Chinese-LLaMA-Alpaca-2 linux部署llamacpp环境 使用llamacpp将Chinese-LLaMA-Alpaca-2模型转换为gguf模型 windows部署Text generation web UI 环境 使用Text generation web UI 加载模型并进行对话 笔记本环境: 操作系统:win11 CPU:AMD R7535HS GPU:笔记本4060显卡

    2024年02月08日
    浏览(59)
  • 大模型部署手记(9)LLaMa2+Chinese-LLaMA-Plus-7B+Windows+llama.cpp+中文文本补齐

    组织机构:Meta(Facebook) 代码仓:GitHub - facebookresearch/llama: Inference code for LLaMA models 模型:llama-2-7b、Chinese-LLaMA-Plus-7B(chinese_llama_plus_lora_7b)   下载:使用download.sh下载 硬件环境:暗影精灵7Plus Windows版本:Windows 11家庭中文版 Insider Preview 22H2 内存 32G GPU显卡:Nvidia GTX 3080 La

    2024年02月03日
    浏览(55)
  • 大模型部署手记(10)LLaMa2+Chinese-LLaMA-Plus-7B+Windows+llama.cpp+中英文对话

    组织机构:Meta(Facebook) 代码仓:GitHub - facebookresearch/llama: Inference code for LLaMA models 模型:llama-2-7b、llama-2-7b-chat( 后来证明无法实现中文转换 )、Chinese-LLaMA-Plus-7B(chinese_llama_plus_lora_7b)   下载:使用download.sh下载 硬件环境:暗影精灵7Plus Windows版本:Windows 11家庭中文版

    2024年02月04日
    浏览(57)
  • AI-windows下使用llama.cpp部署本地Chinese-LLaMA-Alpaca-2模型

    生成的文件在 .buildbin ,我们要用的是 main.exe , binmain.exe -h 查看使用帮助 本项目基于Meta发布的可商用大模型Llama-2开发,是中文LLaMAAlpaca大模型的第二期项目,开源了中文LLaMA-2基座模型和Alpaca-2指令精调大模型。这些模型在原版Llama-2的基础上扩充并优化了中文词表,使用

    2024年04月25日
    浏览(75)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包