2026/5/31 17:54:26
网站建设
项目流程
自助建站模板下载,自建站排名,可信网站认证logo,关键词的选取原则有提示#xff1a;文章写完后#xff0c;目录可以自动生成#xff0c;如何生成可参考右边的帮助文档 文章目录
前言1 ChatGLM是什么#xff1f;2 一代GLM 2.1 大模型架构2.2 GLM特点 2 二代GLM#xff1a;ChatGLM2-6B为例拆解 2.1 ChatGLM2-6B模型推理架构和流程2.2 细节详…提示文章写完后目录可以自动生成如何生成可参考右边的帮助文档文章目录前言1 ChatGLM是什么2 一代GLM2.1 大模型架构2.2 GLM特点2 二代GLMChatGLM2-6B为例拆解2.1 ChatGLM2-6B模型推理架构和流程2.2 细节详解第一步输入与分词、编码第二步嵌入Embedding可迁移重用第三步GLMBlock*28第四步生成next token3 总结前言因为本人在做大模型优化方面的研究之前拆了ChatGLM2的源代码看看能从哪些地方深入。结果刚拆完没多久昨天也就是10 月 27 日智谱 AI 在 2023 中国计算机大会(CNCC)上发布了自研第三代对话大模型 ChatGLM3这是智谱 AI 在今年内第三次对 ChatGLM 基座模型进行了深度优化。目前还没去拆它的源代码所以也不太清楚和2代之间有什么区别。但2代的结构我觉得可以先发以下。1 ChatGLM是什么和ChatGPT类似ChatGLM是基于GLM大模型的下游对话应用。GLM的全称是通用语言模型模型General Language model是清华大学与智谱AI研发的中英双语大语言模型。官方API的ChatGLM是基于GLM-130B千亿基础模型但官方也发布了GLM-6B小参数62亿版本可在消费级显卡上部署。2 一代GLM一代发布的时间大概在一年多前成果最早以一篇论文的形似和发布有兴趣的可以去arxiv上看看原文https://arxiv.org/pdf/2103.10360.pdf。这篇文章的大概意思我稍稍总结了如下2.1 大模型架构首先介绍一下目前基于transformer的大模型架构类别主要有三类自编码encoder架构善于语言建模和理解相当于特征更凝练的embeddingBert系列之后好像就没有新模型了。自回归decoder架构善于根据之前的信息生成主流架构如GPT等都在用非常适合对话应用。编码器-解码器encoder-decoder架构善于处理seq2seq任务如翻译2017年标准transformer就是用翻译器作为示例的比较有名的有T5。今天要讲的GLM在本质上可以说是对T5的优化改进可以看到自编码和自回归是两种不同的架构和自然语言处理应用思路。之前的语言模型各有优缺点但没有一种框架能够在所有的自然语言处理任务中都表现出色。一些先前的工作尝试通过多任务学习的方式将不同框架的目标结合起来但由于自编码和自回归目标本质上的不同简单的结合不能充分继承两者的优势。因此清华大学提出了一种基于自回归空白填充的通用语言模型GLM来解决这个挑战。GLM 通过添加二维位置编码和允许任意顺序预测空白区域改进了空白填充预训练在自然语言理解任务上超越了 BERT 和 T5。2.2 GLM特点主要有三个特点自编码随机 MASK 输入中连续spans的 token自回归基于自回归空白填充的方法重新构建spans中的内容2维的位置编码技术来表示span间和span内位置信息GLM 从输入文本中随机挖掉一些连续的词语自编码思路然后训练模型按照一定的顺序逐个恢复这些词语自回归思路。这种方法结合了自编码和自回归两种预训练方式的优点。此外GLM打乱了空白区域的预测顺序并使用二维位置编码第一个维度对span在原文本中的位置进行编码第二个维度对token在span中的位置进行编码。实验表明GLM 在参数量和计算成本相同的情况下能够在 SuperGLUE 基准测试中显著超越BERT并且在使用相似规模的语料158GB预训练时能够超越 RoBERTa 和 BART。GLM 还能够在自然语言理解和生成任务上显著超越 T5而且使用的参数和数据更少。2 二代GLMChatGLM2-6B为例拆解GLM2和1在模型源代码方面没有什么区别都是Prefix Decoder-only架构的这种架构是在以GPT为代表的Causal Decoder-only架构上发展而来的综合了单项注意力和双向注意力的优点在前一部分采用双向注意力获得更加全面的信息在后一部分采用单项注意力以适应生成式任务。2.1 ChatGLM2-6B模型推理架构和流程在实验室服务器上本地部署后如果想知道怎么部署的之后可以单写一篇用你好这个最简单的输入进行测试得到整体流程如下这里更正一下在输入shape的问题上在使用kv_cache的情况下只有第一轮迭代的输入序列长度是大于1的之后序列长度都等于1可以看到这个模型在推理阶段主要由两层循环组成。第一层是while true循环每循环一次生成一个next token退出条件是模型生成了这个token就是结束符。第二层循环是固定28次的for循环对GLMBlock顺序运行28次根据的attention scores得到最有可能的token id。2.2 细节详解第一步输入与分词、编码输入“你好”1先被自动填充嵌入一个简单的prompt变成“[Round 1] 问你好 答”2根据分词器的词典进行分词模式采用的是wordpiece分词法基本原理就是一个预先给定的词表中去套用输入文本根据概率将给定文本分割成基本单元词片然后用Int32的下标作为词片的id。从上图可以看到“[Round 1] 问你好 答”字符串在经过这一步时被处理成了一个长度为17的整数数组。其中前两个数字64790、64792是固定的开头标识。那么这个给定的分词表之后还会加上一些特殊的Token最后形成一个长度为65024的词表。第二步嵌入Embedding可迁移重用Embedding层的参数是可训练在你下载到本地的model文件夹中有7个二进制参数文件和一个映射表表中可以查看ChatGLM2-6B的所有层的参数存在哪个二进制文件中。模型的Embedding层参数以及预训练好了从图中可以看到Embedding层的形状为65024*4096即对第一步中提到的size65024的词表中的每个词都可以映射为长度为4096的特征向量。的所以只需要把第一步生成的形状为17*1的整数数组输入即可得到一个17*4096的嵌入。由于ChatGLM2-6B支持同时输入多句话所以真实的输入维度为[17,1,4096]分别对应序列长度多句输入时会对所有句子padding统一到最长序列、批数、嵌入的特征空间维度。第三步GLMBlock*28GLMBlock结构图如下。可以看到也是对Transformer进行了一个魔改但主体还是一个注意力模块和一个MLP全连接模块。下面还是从输入流的角度看看block的结构。1首先一上来就是一个RMS归一化层。2进入注意力模块对输入数据进行QKV映射得到输入数据的Query、Key、Value值形状分别为[17,1,32,128]、[17,1,2,128]、[17,1,2,128]可以看到Key-value的形状保持一致。3然后经过核心注意力运算也就是缩放点积注意力层Query和Key点积后消除量纲再点积Value随后reshape回[17,1,4096]的形式。4离开attention模块、进入MLP模块前要完成三个操作Dropout、残差连接、后归一化如图。这里的残差add的值是还没经过前归一化的原始输入。5进入MLP模块要经过两次变换中间的激活函数是SwiGLU。在这一层虽然输入、输出的维度还是4096但在中间过程涨到了27392极大丰富了表示能力。6离开MLP后也要经过Dropout和残差连接这里加的是attention结束后、后归一化前的值。最后输出GLMBlock的是一个和输入Block的shape一样的矩阵。7在for循环控制下这个输出矩阵被当作下一轮的输入一共要走28次。这28次的Block的参数都不一样具体见参数映射表。第四步生成next token在第三步的28轮GLMBlcok循环后最后一层block输出的attention scores会被用于输出处理。输出处理主要有三个组件第一个是RMS归一化相当于弥补了Block中MLP层出来后没有进行的归一化。第二个是嵌入的逆操作将输出的[17,1,4096]维的嵌入向量还原为id值变成一组65024长度的输出logits。这一步实际上是根据attention scores对65025的词表进行了一个概率估计的操作。第三个是Softmax操作将logits变为概率和为1并选择其中的最大值输出其id。这个id就是这一轮28次循环生成的token的id。在我的实例中这个id是36474代表“你”。在最外层的while true循环下只要这个id不是2这个Token的id就会一直生成next token。本次测试最后生成的结果如图1最下部。3 总结好烦本来以为拆完了后可以推进下一步了没想到被官方背刺了。下一步得去看看ChatGLM3的模型架构如果改动较大的话也得做一个类似的推理流程然后才能进入科研正轨也就是拿这个做实验进行一些推理加速的idea印证。也不一定会出xdm要的可以插个眼蹲一波。