皮皮网
皮皮网

【js源码入门】【digitalwrite函数源码】【贩卖病毒源码】chatglm源码讲解

时间:2024-12-27 13:31:53 来源:html个人博客源码

1.chatGLM-6B安装与部署
2.chatglm2-2b+sdxl1.0+langchain打造私有AIGC(三)
3.[fastllm]fastllm源码结构解析
4.清华大学通用预训练模型:GLM
5.大模型实战:用Langchain-ChatGLM解析小说《天龙八部》
6.LLM优化:开源星火13B显卡及内存占用优化

chatglm源码讲解

chatGLM-6B安装与部署

       ChatGLM-6B,码讲 一个开源的双语对话语言模型,基于亿参数的码讲GLM架构,特别适合消费级显卡部署(在INT4量化下,码讲6GB显存即可)。码讲然而,码讲我使用GB显存的码讲js源码入门RTX Ti时,只能选择INT8量化级别运行。码讲首先,码讲确保硬件(如Python、码讲显卡驱动、码讲Git等)和Pytorch环境的码讲准备,可以参考之前的码讲文章。

       安装过程中,码讲国内用户可选sjtu.edu镜像源下载ChatGLM要求。码讲官方建议安装Git LFS,码讲但新版本Git通常已包含。默认加载模型时需要GB显存,我的显存受限,因此尝试量化加载,通过以下代码实现:

       尽管初始量化加载时间较长,但后续对话回复速度较快。此外,还展示了如何通过gradio部署网页版demo,只需修改web_demo.py中的部分代码。

       尽管环境条件有限,下一篇文章将探索P-tuning。ChatGLM-6B的详细信息和源代码可在GitHub项目THUDM/ChatGLM-6B中找到。

chatglm2-2b+sdxl1.0+langchain打造私有AIGC(三)

       在langchain框架下实现LLM流式响应,本文详细阐述了整个过程。首先,我们基于上篇文章的基础,实现了使用langchain的LLMChain完成ChatGLM的调用。通过重写ChatGLM类并继承LLM,同时重写_call()方法,使得大语言模型能够实现流式响应。然而,langchain并未直接将流式响应的结果返回至调用LLMChain的方法中。

       **1.1** **langchain源码结构梳理

**

       为了实现流式响应的需求,我们从stream方法入手,发现其内部的yield机制似乎在采用流式响应策略。进一步跟踪发现,stream方法实际上调用了一个抽象方法`invoke`。继续探索`invoke`方法的实现,我们发现这实际上调用了`__call__`方法,进而调用`_call`方法,最后在`_call`方法中返回了`llm.generate_prompt()`。这揭示了调用链中的digitalwrite函数源码关键点:在开始使用stream方法后,实际上并没有直接与stream方法产生关联,而是通过调用`generate_prompt`方法实现了流式响应。

       **1.2** **重写关键方法

**

       为了实现流式响应,我们首先明确目标:希望`predict`方法调用之后能够采用流式响应,同时不影响原本的`predict`方法。我们顺着调用链,从`Chain`到`LLMChain`再到`BaseLLM`和`LLM`类中进行探索。在`BaseLLM`中,我们找到了`stream`方法,但其内部的`_stream`方法未被实现。因此,我们决定在`ChatGLM`中实现`_stream`方法,以解决流式响应的最终点问题。同时,为了确保`langchain`调用`BaseLLM`的`stream`方法,我们重新编写了一个类,继承自`LLMChain`,并在其中重写了`predict`方法,以确保整个流程能够实现流式响应。

       **1.3** **重写langchain的文档处理链

**

       面对长文本处理需求,尽管`langchain`提供了`load_summarize_chain`方法,但并未实现流式调用。我们遵循相同思路,对`load_summarize_chain`方法进行了重写,重点关注在`reduce`阶段实现流式响应。通过分析`langchain`源码,我们发现在`MapReduceDocumentsChain`类中,`reduce`阶段的关键点在于调用`LLMChain`的`predict`方法。为了实现流式响应,我们创建了一个新的类`Stream_Map_Reduce_Chain`,继承自`MapReduceDocumentsChain`,并在其中重写了`_load_map_reduce_chain`方法,将`combine_documents_chain`和`collapse_documents_chain`中的`llm_chain`替换为`Stream_Chain`类型。这样,当在`reduce`阶段调用`predict`方法时,能够直接调用`ChatGLM`类中的`_stream`方法实现流式响应。

       综上所述,通过深入理解`langchain`框架的内部实现,并针对关键环节进行方法重写,我们成功实现了在不同场景下的流式响应需求,包括普通问答和长文本处理。这些改进不仅提高了响应的实时性和效率,也为`langchain`框架的使用提供了更灵活和高效的方式。

[fastllm]fastllm源码结构解析

       fastllm源码结构解析

       主要文件结构和继承关系如下:

       main包含factoryllm工厂,用于生成各种llm模型实例,basellm作为基类,贩卖病毒源码包含通用方法和参数,所有模型使用相同的命名空间,fastllm为基本类,定义数据格式、权重映射和基础算子操作。

       fastllm类属性解析:

       SetThreads(int t): 设置线程数

       SetLowMemMode(bool m): 设置低内存模式

       LowBitConfig: 包含量化参数,提供量化与反量化方法

       DataType: 包括浮点、int8、int4等数据类型

       DataDevice: 包含CPU与CUDA

       WeightType: 包括LINEAR、EMBEDDING和None

       Data: 包括形状、大小、扩容信息,量化配置等,提供复制、分配、预扩容等功能

       Tokenizer: 包含TrieNode链表和token-to-string字典,提供插入、编码和解码函数

       WeightMap: 存储模型名称与数据内存,支持从文件加载和保存低位量化权重

       core类操作分析:

       Embedding: 根据输入与权重计算输出

       RMSNorm: L2归一化后乘以权重

       LayerNorm: 使用gamma、beta进行层归一化

       Linear: 线性变换

       Split: 按轴分割数据

       Cat: 按轴拼接数据

       MatMulTransB: 多线程下矩阵转置乘法

       Softmax: 激活函数

       Silu: SiLU激活函数

       GeluNew: 新型Gelu激活函数

       Mul: 矩阵与浮点数乘法

       MulTo: 点乘

       AddTo: 点加操作(带alpha和不带alpha)

       AttentionMask: 根据mask值替换

       Permute: 数据通道转换

       ToDevice: 数据迁移至GPU

       basellm作为抽象类,继承自fastllm,包含纯虚函数如加载权重、模型推理、保存低比特模型、热身等。

       chatglm、moss和vicuna继承自basellm,实现具体模型,函数与basellm类似。

       fastllm结构体与属性解析:

       FileBuffer: 文件读写操作,包括读取各种类型数据和文件写操作

       Data操作: 包括数据拷贝、统计、扩容、转置、计算权重和等

       Tokenizer方法: 包括初始化、清空、插入、编码和解码

       WeightMap方法: 包括从文件加载和保存低位量化权重

       fastllm方法: 包括矩阵转置、通道转换、数据迁移、多线程乘法、激活函数等

清华大学通用预训练模型:GLM

       清华大学的GLM:通用语言模型预训练的创新之作

       随着OpenAI的ChatGPT引领大语言模型热潮,清华大学的GLM模型以其卓越的性能脱颖而出,特别是ChatGLM-6B和GLM-B,它们的开源引起了业界的广泛关注。截至5月日,陪护护理源码ChatGLM-6B在全球范围内已收获万次下载,备受联想、民航信息网络、和美团等企业的青睐。在科技部的报告中,ChatGLM-6B凭借其开源影响力位居榜首,而GLM-B等模型也跻身前十。

       GLM的创新与技术细节

       GLM与GPT的差异在于其处理NLP任务的全面性,包括自然语言理解(NLU)、有条件和无条件生成。GLM采用自回归模型架构,这种设计使其适用于各种任务,无论是理解还是生成。其核心技术在于自回归空白填充,这种创新方法使得GLM在处理长文本和双向依赖时更具优势。

       实际应用与实例

       ChatGLM-6B的开源不仅引发了下载热潮,还促成了与多家企业的合作。GLM凭借其强大的长文本生成能力,已经在诸如智能对话、文本补全等任务中展示了其实际价值。

       GLM的独特特点与架构

       GLM的独特之处在于其自编码与自回归的结合,以及二维编码的使用,这使得它在NLU和生成任务上表现出色。GLM通过自回归填充,同时考虑上下文的依赖,使用二维位置编码来表示位置关系,确保信息的有效交互。这种设计使得GLM在处理长度不确定的任务时表现出色,比如NLU中的填空生成。

       与其他模型的比较

       与RoBERTa、XLNet、BERT、XLNet、T5和UniLM等模型相比,GLM在适应空白填充任务和处理长度不确定的NLU任务上显示出优势。例如,BERT忽视了mask token的依赖,XLNet需要预测长度,而T5和UniLM的局限性限制了它们的自回归依赖捕捉能力。

       多任务预训练与性能提升

       GLM通过多任务预训练,如GLMSent和GLMDoc,适应不同跨度的文本,性能随着参数的增加而提升,尤其是在文档级任务上。在序列到序列任务中,GLM在BookCorpus和Wikipedia预训练后与BART相当,速配app源码而在大型语料库上,GLMRoBERTa与BART和T5/UniLMv2竞争。

       总结与未来研究

       总体而言,GLM是一个通用且强大的模型,它在理解和生成任务上的表现超越了BERT、T5和GPT。通过消融实验,我们了解到模型的空白填充目标、顺序设计和表示方式对其性能具有显著影响。GLM的开放源代码不仅提供了研究者一个宝贵的资源,也为推动语言模型的进一步发展奠定了坚实的基础。

       深入探索与未来趋势

       进一步的研究将继续探讨GLM的组件如何影响模型在SuperGLUE等基准上的表现,以及如何通过优化设计来提升其在特定任务中的性能。GLM的潜力和创新预示着一个更加开放和高效的预训练语言模型新时代的来临。

大模型实战:用Langchain-ChatGLM解析小说《天龙八部》

       在探讨大模型实战时,如何用Langchain-ChatGLM解析小说《天龙八部》是一个引人入胜的话题。大模型,尤其是GPT系列,虽然在对话和咨询方面表现出色,但其知识库的局限性使得它在处理未知内容时难以提供准确答案。通过引入Langchain,我们能够使GPT模型能够理解并分析文章内容,显著扩展了其应用范围。

       具体地,Langchain实现本地知识库问答的过程包括多个步骤。首先,通过阅读langchain-ChatGLM源码,我们可以了解其基本框架,这涉及到本地知识库的构建、文本嵌入的向量化存储、以及对用户输入的查询处理。通过流程图可视化,我们可以清晰地理解这一流程。

       为了实践这一框架,我们构建了简单的代码示例(tlbb.py),以《天龙八部》为输入,尝试对小说内容进行问答。测试结果显示,模型能够回答一些相关问题,展现出一定的应用价值。

       在代码实现中,模型加载是一个关键环节,其方法在前文中已有详细介绍。此外,通过文本嵌入向量化存储,我们使用text2vec-large-chinese模型对输入文本进行处理,进一步提升问答准确度。在组装prompt阶段,我们向预训练模型提问,获取与输入文本相关的问题答案。

       总结而言,使用Langchain-ChatGLM框架进行本地知识库问答,为GPT模型处理特定主题和领域的问题提供了有效途径。在实际应用中,它能够理解并回答与《天龙八部》等文章相关的问题,显著弥补了原生模型在未知领域的不足。当然,框架性能受文本质量和内容影响,对于更复杂或专业的问题,可能需要更细致的文本分割和知识库构建来提升回答质量。

       此外,为了促进技术交流与学习,我们已组建了技术讨论群,欢迎感兴趣的朋友加入,共同探讨最新学术资讯、技术细节、以及实际应用案例。同时,关注机器学习社区的知乎账号与公众号,能够快速获取高质量的文章,推动学习与研究的深入发展。

       推荐一系列文章,涵盖最新研究进展、技术方法、开源项目等,以满足不同领域开发者的需求。这些资源不仅提供深度学习领域的最新见解,还覆盖了论文润色、代码解释、报告生成等实用技能,为学术和工业实践提供了宝贵支持。

LLM优化:开源星火B显卡及内存占用优化

       本qiang近期接手了一个任务,旨在部署多个开源模型,并对比本地全量微调的模型与开源模型的性能表现。参与的开源模型包括星火B、Baichuan2-B、ChatGLM6B等。其他模型基于transformers架构,启动服务流畅,然而星火B基于Megatron-DeepSpeed框架实现,启动过程发现显卡占用量高达G-G,超出预期。本文主要围绕开源星火B的显存及内存使用优化进行整理与讨论。

       直观分析,星火B模型使用bf数据类型,预计显存占用为G左右,实际却高达G+,这解释了为什么星火开源模型讨论较少。穷人家的孩子,哪里有充足的显存资源。在排查原因时,需要对源码进行调试与分析。在启动推理服务的脚本run_iFlytekSpark_text_generation.py中,model_provider方法用于初始化模型并加载模型文件。在加载权重文件时,直接将权重文件加载至显卡,而非先加载至CPU再转移到GPU,这可能是优化点之一。

       深入源码,发现星火B模型的初始化过程中,包括Embedding层、线性转换层等的权重weight直接分配在GPU上运行。为优化此过程,可以调整模型初始化策略。通过在启动推理服务的脚本中加入参数" use_cpu_initialization",模型初始化时可以先将权重加载至CPU,然后进行后续的GPU分配和转换。在加载模型文件时,先加载至CPU,避免直接在GPU上运行,加载完成后,利用垃圾回收机制清除CPU上的内存占用。

       实施优化后,显卡占用量从.5G减少至G,内存占用从.5G降低至.1G,效果显著。优化的核心在于使用CPU预加载模型,之后转换至GPU。

       总结而言,本文主要针对开源星火B显存及内存占用过大的问题提供了一种代码优化方法。关键在于调整模型初始化和加载策略,通过先在CPU上预加载模型,再进行GPU分配,有效降低了资源占用。对于遇到类似问题的读者,建议参考本文提供的优化思路。

利用TPU-MLIR实现LLM INT8量化部署

       在年7月的进展中,我们已经成功将ChatGLM2-6B部署在BMX单芯片上,采用F量化模式,模型大小达GB,平均速度约为每秒3个token。为了进一步优化效率并减小存储负担,我们转向INT8量化部署。

       然而,传统的TPU-MLIR INT8量化策略对大型语言模型(LLM)并不适用。PTQ校准和QAT训练在LLM上成本高昂,可能需要1-2天,且量化带来的误差在LLM中难以收敛,会导致精度大幅下降。因此,我们采取了ChatGLM2的W8A策略,只对GLMBlock中的Linear Layer权重进行通道级量化,运算时恢复到F,这样可以保持%以上的余弦相似度,几乎无精度损失。

       在TPU-MLIR编译器的lowering阶段,我们特别处理了MatMul算子,针对权重维数为2的线性层,将其转换为W8AMatMul算子。如ChatGLM2的一个MatMul示例中,量化后的权重存储空间从MB降至MB,Scale数据仅占0.MB,存储空间减半。具体实现和源码可以在TPU-MLIR仓库查看。

       性能提升的关键在于W8AMatMul的后端优化。TPU架构中,W8A通过量化右矩阵数据,减少数据搬运时间,尤其当左矩阵数据量小而右矩阵数据量大时,性能提升更为显著。在LLM的推理过程中,prefill阶段的输入数据量取决于模型支持的最大文本长度,而decode阶段的输入固定,这决定了W8A在不同的阶段效果不同。

       将W8A应用到ChatGLM2-6B后的性能数据显示,这种策略显著地改善了模型的部署效率和存储效率。具体效果,通过详细的性能测试,我们可以看到显著的提升。

ChatGLM2-6B多轮对话训练方式

       ChatGLM2是一个经过指令微调的聊天模型,微调时应遵循官方数据组织格式以实现最佳效果。对比预训练模型,其训练数据组织格式较为灵活,而对于聊天模型,官方数据组织格式更为推荐。分析源码时,我们发现ChatGLM2的多轮对话训练存在不足。在训练过程中,只有最后一轮对话内容参与计算损失(loss),其他助手的回答内容并未参与,导致训练数据利用不充分,形成浪费。

       在ChatGLM2的训练源码中,我们观察到输入`input_ids`是由`prompt`、`answer`和结束符(由tokenizer定义)拼接而成。`prompt`由`tokenizer.build_prompt(query, history)`生成,包含了历史对话和当前轮次用户输入的拼接。`answer`则为当前轮次的回复。通过查看huggingface上`chatglm2-6b`的tokenizer代码,我们发现`build_prompt`方法中包含了结束符`eos_token`,揭示了ChatGLM2多轮对话数据组织格式的关键点。对于`labels`,除了最后一个轮次回复内容对应的`b ids`外,其他位置都被置为`pad_token_id`,这意味着只有最后一个轮次的回复内容参与计算loss,其他回复内容未参与,从而导致训练数据未被充分利用。

       对于现有的多轮对话训练方式,我们总结了三种方法:不充分、不高效以及Firefly方法。不充分的方法将所有对话输入视为模型输入,仅最后一个回复内容参与loss更新,忽视了其他回复的潜在信息,造成训练数据浪费。不高效的方法将多轮对话拆分为多条数据进行训练,提高了利用度但降低了训练效率。Firefly方法则采取了一种更充分利用数据的策略,通过并行计算每个位置的loss并仅更新Assistant部分的权重,从而实现了更高效的训练。

       Firefly方法之所以可行,归功于因果语言模型的特性。以GPT为代表的因果语言模型具有对角掩码矩阵的attention mask特性,使得每个位置的编码只依赖于它之前的信息,从而实现了并行计算每个位置的logits。虽然GLM和UniLM等模型存在prefix attention mask的设计,但ChatGLM通过单向注意力机制进行了调整,与Firefly方法保持了兼容性。在训练时,通过数据拼接、tokenize和生成目标mask,Firefly方法充分实现了多轮对话数据的高效利用。

       值得注意的是,尽管ChatGLM2在数据组织和训练方法上存在不足,改进如Firefly方法的实现能够显著提升多轮对话模型的训练效果和数据利用率。通过合理的数据格式和loss计算策略,训练多轮对话大模型能够达到更高效、更充分的训练状态,实现更好的对话生成质量。实践证明,即使简化数据组织形式,多轮对话模型也能展现出卓越的性能,这一方法值得在实际应用中进一步探索和优化。

ChatGLM-6B大模型Docker NVIDIA 离线部署

       为实现ChatGLM-6B大模型的Docker NVIDIA离线部署,需满足以下前置条件:

       1. 确保Docker及NVIDIA Docker扩展包已离线安装完成。

       2. 基础CUDA及CUDNN镜像已加载。

       接下来,执行离线安装步骤:

       1. **下载离线依赖包**:在具备互联网连接的Linux服务器或Windows的Ubuntu子系统中安装Docker并下载基础镜像。随后,下载ChatGLM-6B或ChatGLM2-6B的源码,存放在指定目录内。

       2. **下载模型文件**:选择通过Hugging Face、清华大学网盘或个人百度网盘下载模型文件。

       3. **离线环境部署**:将下载的离线包传输至GPU服务器。确保服务器已按照前述文章配置Docker及CUDA/CUDNN镜像。文件放置于指定目录,包括源代码、模型文件、Python依赖包等。

       部署过程包括:

       1. **离线依赖包安装**:执行安装命令确保所有依赖包在容器中可用。

       2. **修改本地模型路径**:调整web_demo.py文件中的路径设置,确保模型文件在容器内正确引用。

       3. **支持任意地址访问**:在Docker启动参数中添加server_name,以允许外部访问服务。

       4. **启动服务**:运行Docker容器,完成部署。可访问/{ ip}:>来访问服务。

       注意**问题排查**与**文件传输优化**:

       1. **访问不通**:确保服务启动正常,检查防火墙端口设置。

       2. **大文件传输**:使用Linux的7z程序进行分卷压缩,避免Windows自带工具导致的解压问题。在Linux上合并分卷文件使用如下命令。

更多内容请点击【焦点】专栏