聊聊ChatGLM-6B的源码分析

这篇具有很好参考价值的文章主要介绍了聊聊ChatGLM-6B的源码分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于ChatGLM-6B第一版,要注意还有ChatGLM2-6B以及ChatGLM3-6B

转载请备注出处:https://www.cnblogs.com/zhiyong-ITNote/

PrefixEncoder

作用:在微调时(以P-Tuning V2为例),方法训练时冻结模型的全部参数,只激活PrefixEncoder的参数。
其源码如下,整体来看是比较简单的。

class PrefixEncoder(torch.nn.Module):
    def __init__(self, config):
        super().__init__()
        self.prefix_projection = config.prefix_projection
        if self.prefix_projection:
            # 使用一个两层(线性层)的MLP编码prefix
            self.embedding = torch.nn.Embedding(config.pre_seq_len, config.hidden_size)
            self.trans = torch.nn.Sequential(
                torch.nn.Linear(config.hidden_size, config.hidden_size),
                torch.nn.Tanh(),
                torch.nn.Linear(config.hidden_size, config.num_layers * config.hidden_size * 2)
            )
        else:
            self.embedding = torch.nn.Embedding(config.pre_seq_len, config.num_layers * config.hidden_size * 2)

    def forward(self, prefix: torch.Tensor):
        if self.prefix_projection:
            prefix_tokens = self.embedding(prefix)
            past_key_values = self.trans(prefix_tokens)
        else:
            past_key_values = self.embedding(prefix)
        return past_key_values

为什么源码注释中会说到MLP?定位追溯:

self.mlp = GLU(
    hidden_size,
    inner_hidden_size=inner_hidden_size,
    bias=use_bias,
    layer_id=layer_id,
    params_dtype=params_dtype,
    empty_init=empty_init
)

def default_init(cls, *args, **kwargs):
    return cls(*args, **kwargs)

class GLU(torch.nn.Module):
    def __init__(self, hidden_size, inner_hidden_size=None,
                 layer_id=None, bias=True, activation_func=gelu, params_dtype=torch.float, empty_init=True):
        super(GLU, self).__init__()
        if empty_init:
            init_method = skip_init
        else:
            init_method = default_init
        self.layer_id = layer_id
        self.activation_func = activation_func

        # Project to 4h.
        self.hidden_size = hidden_size
        if inner_hidden_size is None:
            inner_hidden_size = 4 * hidden_size
        self.inner_hidden_size = inner_hidden_size
        self.dense_h_to_4h = init_method(
            torch.nn.Linear,
            self.hidden_size,
            self.inner_hidden_size,
            bias=bias,
            dtype=params_dtype,
        )
        # Project back to h.
        self.dense_4h_to_h = init_method(
            torch.nn.Linear,
            self.inner_hidden_size,
            self.hidden_size,
            bias=bias,
            dtype=params_dtype,
        )

    def forward(self, hidden_states):
        """
        hidden_states: [seq_len, batch, hidden_size]
        """

        # [seq_len, batch, inner_hidden_size]
        intermediate_parallel = self.dense_h_to_4h(hidden_states)

        intermediate_parallel = self.activation_func(intermediate_parallel)

        output = self.dense_4h_to_h(intermediate_parallel)

        return output

# 转载请备注出处:https://www.cnblogs.com/zhiyong-ITNote/

init_method对应到default_init,这个函数的作用与直接调用类构造函数相同,但它提供了一种更灵活的方式来创建类的实例,因为它可以接受任意数量的位置参数和关键字参数。在Pytorch中,用于模块化的构造函数。从源码分析来看,GLU/MLP类就是构造了两个线性层与gelu激活函数,其结构可简化如下:
聊聊ChatGLM-6B的源码分析
PrefixEncoder类的初始化方法来看,其就是embedding层与MLP的组合。其结构可简化如下:
聊聊ChatGLM-6B的源码分析

详细解读可参考 ChatGLM的模型架构

Q:在这里还有一个问题,从哪里可以定位溯源到微调时禁用了全部的参数,只激活PrefixEncoder的参数并调用了该类?

转载请备注出处:https://www.cnblogs.com/zhiyong-ITNote/

激活函数与位置编码

代码简单明了,RoPE的理论知识可以多了解。

attention_fn

伪代码表示为:

def attention_fn(
        self,
        query_layer,
        key_layer,
        value_layer,
        attention_mask,
        hidden_size_per_partition,
        layer_id,
        layer_past=None,
        scaling_attention_score=True,
        use_cache=False,
):
    xxxx

标准的注意力机制计算公式如下:
聊聊ChatGLM-6B的源码分析
聊聊ChatGLM-6B的源码分析
聊聊ChatGLM-6B的源码分析
聊聊ChatGLM-6B的源码分析
多头注意力就是将多个单头注意力的结果拼接起来,再点乘一个新的权重参数。
聊聊ChatGLM-6B的源码分析
聊聊ChatGLM-6B的源码分析
attention_fn函数实现了注意力的核心计算过程(即上述数学表达式),包括计算注意力分数、注意力概率和上下文层。这些计算对于实现许多自然语言处理任务,如语言建模、命名实体识别等,都是非常重要的。

SelfAttention

伪代码表示为:

class SelfAttention(torch.nn.Module):
    xxxx

attention_mask_func将注意力掩码应用于Transformer模型中的注意力得分中。

@staticmethod
def attention_mask_func(attention_scores, attention_mask):
    attention_scores.masked_fill_(attention_mask, -10000.0)
    return attention_scores

apply_rotary_pos_emb_index函数为聊聊ChatGLM-6B的源码分析注入了RoPE位置信息,然后调用attention_fn计算注意力概率、上下文层表示,并得到返回值。这些都是在forward函数中调用处理的。
聊聊ChatGLM-6B的源码分析
最后还调用了dense对上下文表示做线性计算,返回输出。

转载请备注出处:https://www.cnblogs.com/zhiyong-ITNote/

GLU

GLU也可以理解为是MLP,在后面版本的ChatGLM中,去掉了GLU类的定义声明,直接换成了MLP。在上面已经写过不再赘述。

聊聊ChatGLM-6B的源码分析

GLMBlock

一般都会把GLMBlock对应为transformer结构的实现。从其构造函数来看,主要是拼接各个层到一起。
聊聊ChatGLM-6B的源码分析
从代码来看,中间有两次的残差连接,如下所示

# Residual connection.
alpha = (2 * self.num_layers) ** 0.5
hidden_states = attention_input * alpha + attention_output

mlp_input = self.post_attention_layernorm(hidden_states)

# MLP.
mlp_output = self.mlp(mlp_input)

# Second residual connection.
output = mlp_input * alpha + mlp_output

转载请备注出处:https://www.cnblogs.com/zhiyong-ITNote/文章来源地址https://www.toymoban.com/news/detail-777136.html

到了这里,关于聊聊ChatGLM-6B的源码分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【Python 自动化】自媒体剪辑第一版·思路简述与技术方案

    大家都知道我主业是个运维开发(或者算法工程师),每天时间不多,但我又想做自媒体。然后呢,我就想了个方案,每天起来之后写个短视频的脚本,包含一系列图片和文字,然后上班的时候给它提交到流水线上跑,下班之前就能拿到视频,然后往各大平台上一传,是不是

    2024年02月09日
    浏览(40)
  • 聊聊 从源码来看ChatGLM-6B的模型结构

    基于ChatGLM-6B第一版,要注意还有ChatGLM2-6B以及ChatGLM3-6B ChatGLM是transformer架构的神经网络模型,因此从transformer结构入手,分析其源码结构。 transformer结构: 转载请备注出处:https://www.cnblogs.com/zhiyong-ITNote/ ChatGLM-6B的位置编码采用的旋转位置编码(RoPB)实现。其源码: ChatGLM-6B采用

    2024年02月03日
    浏览(39)
  • 聊聊ChatGLM-6B医疗数据微调

    转载请注明出处: https://www.cnblogs.com/zhiyong-ITNote/ 参考了多个医疗大模型,如扁鹊、灵心等,重新思考了下微调的方案以及数据集的格式;基于ChatGLM/其它LLM整合多种微调方法的非官方实现的框架,审视其数据集格式,以及调试效果,进行微调。 最终基于liucongg/ChatGLM-Finetuning开

    2024年03月16日
    浏览(64)
  • 聊聊ChatGLM-6B部署与微调的深入理解

    ChatGLM的部署,主要是两个步骤: 在Github上下载chatglm的库文件 在Hugging Face上下载模型参数与配置文件 从Github上看ChatGLM项目文件的结构来看,仅仅是包含三种部署方式的py代码与微调的py代码 而相关的实现细节,比如神经网络、激活函数、损失函数等具体的实现,并不在该项

    2024年02月03日
    浏览(51)
  • 聊聊ChatGLM6B的微调脚本及与Huggingface的关联

    本文首先分析微调脚本trainer.sh的内容,再剖析ChatGLM是如何与Huggingface平台对接,实现transformers库的API直接调用ChatGLM模型,最后定位到了ChatGLM模型的源码文件。 微调脚本: 脚本配置项分析: PRE_SEQ_LEN=128 : 定义了序列长度为128。这个参数通常用于设置输入序列的最大长度。

    2024年02月03日
    浏览(40)
  • ChatGLM-6B源码解析 之 web_demo.py

    这段代码的主要目标是 使用预训练的ChatGPT模型(\\\"THUDM/chatglm-6b\\\") 来构建一个基于web的交互式聊天机器人。以下是对代码中每行或每个代码块的解释: 导入必要的库: pythonCopy code from transformers import AutoModel, AutoTokenizer import gradio as gr import mdtex2html transformers 是一个NLP库,提供

    2024年01月22日
    浏览(31)
  • ChatGLM2-6B源码解析 web_demo.py

    这是一个使用Hugging Face的transformers库和gradio库搭建的机器人聊天程序的Python代码,模型预训练的版本为\\\" THUDM/chatglm2-6b \\\",而且使用了mdtex2html来把markdown格式转化为HTML格式。我会逐行解释它的含义: 1-3: 导入必要的模块。 transformers 是Hugging Face发布的处理NLP任务的库,提供了大

    2024年02月09日
    浏览(30)
  • InstructGLM:基于ChatGLM-6B在指令数据集上进行微调

    基于ChatGLM-6B+LoRA在指令数据集上进行微调 https://github.com/yanqiangmiffy/InstructGLM 本项目主要内容: 🚀 2023/4/9 发布了基于100万条由BELLE项目生成的中文指令数据的Lora权重,具体可见 output/belle/chatglm-lora.pt 🚀 2023/4/8 基于deepspeed支持多卡微调,速度相比单卡提升8-9倍具体设置可见

    2023年04月25日
    浏览(57)
  • 基于chatGLM-6B模型微调详细教程(linux版)(ptuning & lora)

    目录 准备工作 安装7z ptuning预训练 ChatGLM-6B-Ptuning.7z 懒人包下载 上传文件并解压缩 拉取依赖 进行训练 启动服务 注意事项(揽睿星舟云算力平台) lora预训练 chatGLM-All-In-One.7z 懒人包下载 上传文件并解压缩 拉取依赖 进行训练 启动服务 注意事项(揽睿星舟云算力平台) 展示

    2024年02月09日
    浏览(56)
  • 基于闻达(wenda+chatGLM-6B),构建自己的知识库小助手

    目录 安装miniconda 拉取仓库 使用内置python 安装依赖 上传模型 克隆及下载 text2vec-large-chinese 修改配置 上传知识库(txt文件) 处理txt数据 启动服务 测试 ChatGLM-6B是清华团队+智谱AI开发的,一个开源的、支持中英双语的对话语言模型,具有 62 亿参数。被很多人视为ChatGPT的平替

    2024年02月06日
    浏览(45)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包