diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git "a/00.\347\234\237\345\256\236\351\235\242\350\257\225\351\242\230/README.md" "b/00.\347\234\237\345\256\236\351\235\242\350\257\225\351\242\230/README.md" deleted file mode 100644 index ef5293d..0000000 --- "a/00.\347\234\237\345\256\236\351\235\242\350\257\225\351\242\230/README.md" +++ /dev/null @@ -1 +0,0 @@ -## 个人经历面试题 \ No newline at end of file diff --git "a/00.\347\234\237\345\256\236\351\235\242\350\257\225\351\242\230/\344\274\201\344\270\232A.md" "b/00.\347\234\237\345\256\236\351\235\242\350\257\225\351\242\230/\344\274\201\344\270\232A.md" deleted file mode 100644 index 3d7a14d..0000000 --- "a/00.\347\234\237\345\256\236\351\235\242\350\257\225\351\242\230/\344\274\201\344\270\232A.md" +++ /dev/null @@ -1,84 +0,0 @@ -# 企业A - -# 一面 - -### Transformer部分 - -1. Transformer整体介绍 -2. Self-attention 的机制和原理 -3. self-attention为什么用qkv,使用qv可以不? -4. 计算A→B的注意力和B→A的注意力的区别,如果使用qv能不能区分这两个 - -### 微调部分 - -1. 为什么需要微调?如果需要专业的数据,外挂数据库就可以解决的。 -2. 数据集怎么获取? -3. 介绍LoRA微调,及其微调中的一些重要参数 -4. 微调中碰到那些问题? -5. 微调的硬件设备是怎么样的? -6. 如果显存不够,怎么解决? -7. 微调的Loss是怎么变化的? -8. 微调完成后,怎么测试实际效果? -9. 除了LoRA,还用过其他微调的方法吗? - -### 分布式训练 - -1. 介绍各个并行,数据并行、模型并行 -2. 介绍MoE,MoE怎么使用到大模型上 -3. MoE并行 - -### 训练部分 - -1. 训练时间怎么计算? -2. 参数量怎么计算? -3. 英文到中文的词表映射怎么做? -4. DPO算法 -5. 介绍PPO算法 - -### 场景题 - -**背景**:假设做一个智能客服(提问有顺序),消费者提出问题,智能客服回答;整个流程有一定的顺序。有三个外挂数据库,一个负责业务流程,一个回答专业问题,剩下一个忘记了。将消费者的提问,结合这三个数据库中的数据,组成prompt,送到大模型中生成答案。 - -Q:一个问题经过多个数据库,prompt太长了,怎么解决这个问题? - -A:1:压缩prompt长度,对比多个不同的prompt,选择与问题相关的prompt,尽可能短;2:消费者提的问题,可以使用实体命名识别等技术,抽取关键字构造prompt,而不是全部构造prompt - -Q:这个流程直接送给大模型效果不太好,应该怎么处理: - -A:分阶段,分步骤处理。一个模型处理一部分问题,而不是把整个任务流程丢给大模型处理。 - -# 二面 - -### 技术问题 - -1. 介绍项目中的LoRA微调? -2. 微调的时候,出现了什么问题? -3. 还有了解其他微调技术吗?详细讲述一下。 - - 具体了解有四大类大模型微调技术: - 1. 增加额外参数:Prefix tuning, prompt tuning - 2. 指定更新一部分参数:BitFit - 3. 重参数化微调:LoRA,AdaptLoRA,QLoRA - 4. 混合高效微调:UniPELT -4. 了解RAG技术吗?详细讲述一下 - -### LLM宏观问题 - -1. 你是什么时候关注大模型的? -2. 了解国内的大模型有哪些吗? - 1. ChatGLM, 文心,讯飞大模型 。。。。 -3. 你对大模型未来的方向怎么看? - 1. 底层研究方面: - 1. Nvidia算力增长,对Transformer进一步优化,媲美CNN的速度; - 2. 大模型架构会以Transformer decoder为主题,研究较多的变种。 - 2. 大模型研究方面: - 1. 参数进一步增加,性能进一步提升。 - 2. 通过模型持续学习、增加记忆机制、突破这三元组知识表示方法等进一步提升大模型认知能力。 - 3. 在模型本身方面,多模态、多语言、面向垂直领域的新模型也会成为研究重点。 - 3. 大模型应用方面:使用大模型门槛会大大降低,促使形成“大模型+少量数据微调”的AI工业化开发模式: - 1. 降成本,提速度:推理,模型剪枝,模型压缩 - 2. 搭平台:大公司会提供一站式大模型开发应用平台,提供模型在线构建、微调、部署、发布的全流程服务,能够支持成百上千个应用的开发和部署。 - -### 新了解到的知识 - -1. 0-1 LLM和 deepseek全量微调在公司的垂直领域业务上效果最好,其次是ChatGLM4和文心4不开源的接口。 -2. 在大模型部署方面,还是vLLM效果最好;而 Nvidia 的TensorRT-LLM效果不太行,容易出现很多问题 diff --git "a/00.\347\234\237\345\256\236\351\235\242\350\257\225\351\242\230/\344\274\201\344\270\232C.md" "b/00.\347\234\237\345\256\236\351\235\242\350\257\225\351\242\230/\344\274\201\344\270\232C.md" deleted file mode 100644 index e09d7e9..0000000 --- "a/00.\347\234\237\345\256\236\351\235\242\350\257\225\351\242\230/\344\274\201\344\270\232C.md" +++ /dev/null @@ -1,56 +0,0 @@ -# 企业C - -# 一面 - -### 技术问题 - -1. ChatGLM3 + RAG项目流程 -2. 微调数据集如果获取,数据集如何构造为微调数据集? -3. LoRA微调原理 -4. LoRA微调的主要参数有那几个? - 1. 主要三个:`r`、 $\alpha$、微调位置 -5. 还了解其他微调的方式吗? - -### Leetcode - -[105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)](https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/ "105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)") - -```c++ -class Solution { -public: - TreeNode* buildTree(vector& preorder, vector& inorder) { - return this->pre_inorder_build_tree(preorder, 0, preorder.size() - 1, inorder, 0, inorder.size() - 1); - } - -private: - TreeNode* pre_inorder_build_tree(std::vector& preorder, int pre_start_idx, int pre_end_idx, - std::vector& inorder, int in_start_idx, int in_end_idx) { - if (pre_start_idx > pre_end_idx) { - return nullptr; - } - - // 创建根节点,根节点的值使用前序遍历的第一个 - TreeNode* root = new TreeNode(preorder[pre_start_idx]); - - // 在中序遍历中找到根节点,划分为两个数组,分别是左右子树的, - int root_idx = in_start_idx; - for (; root_idx <= in_end_idx; root_idx++) { - if (root->val == inorder[root_idx]) { - break; - } - } - - // 左子树的长度 - int left_lens = root_idx - in_start_idx; - - // 创建左子树 - root->left = this->pre_inorder_build_tree(preorder, pre_start_idx + 1, pre_start_idx + left_lens, - inorder, in_start_idx, root_idx - 1); - // 创建右子树 - root->right = this->pre_inorder_build_tree(preorder, pre_start_idx + left_lens + 1, pre_end_idx, - inorder, root_idx + 1, in_end_idx); - - return root; - } -}; -``` diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/1.llm\346\246\202\345\277\265/1.llm\346\246\202\345\277\265.md" "b/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/1.llm\346\246\202\345\277\265/1.llm\346\246\202\345\277\265.md" deleted file mode 100644 index 923c4dc..0000000 --- "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/1.llm\346\246\202\345\277\265/1.llm\346\246\202\345\277\265.md" +++ /dev/null @@ -1,163 +0,0 @@ -# 1.llm概念 - -\[toc] - -### 1.目前 主流的开源模型体系 有哪些? - -目前主流的开源LLM(语言模型)模型体系包括以下几个: - -1. **GPT(Generative Pre-trained Transformer)系列**:由OpenAI发布的一系列基于Transformer架构的语言模型,包括GPT、GPT-2、GPT-3等。GPT模型通过在大规模无标签文本上进行预训练,然后在特定任务上进行微调,具有很强的生成能力和语言理解能力。 -2. **BERT(Bidirectional Encoder Representations from Transformers)**:由Google发布的一种基于Transformer架构的双向预训练语言模型。BERT模型通过在大规模无标签文本上进行预训练,然后在下游任务上进行微调,具有强大的语言理解能力和表征能力。 -3. **XLNet**:由CMU和Google Brain发布的一种基于Transformer架构的自回归预训练语言模型。XLNet模型通过自回归方式预训练,可以建模全局依赖关系,具有更好的语言建模能力和生成能力。 -4. **RoBERTa**:由Facebook发布的一种基于Transformer架构的预训练语言模型。RoBERTa模型在BERT的基础上进行了改进,通过更大规模的数据和更长的训练时间,取得了更好的性能。 -5. **T5(Text-to-Text Transfer Transformer)**:由Google发布的一种基于Transformer架构的多任务预训练语言模型。T5模型通过在大规模数据集上进行预训练,可以用于多种自然语言处理任务,如文本分类、机器翻译、问答等。 - -这些模型在自然语言处理领域取得了显著的成果,并被广泛应用于各种任务和应用中。 - -### 2.prefix LM 和 causal LM 区别是什么? - -Prefix LM(前缀语言模型)和Causal LM(因果语言模型)是两种不同类型的语言模型,它们的区别在于生成文本的方式和训练目标。 - -#### 2.1 Prefix LM - -Prefix LM其实是Encoder-Decoder模型的变体,为什么这样说?解释如下: - -1. 在标准的Encoder-Decoder模型中,Encoder和Decoder各自使用一个独立的Transformer -2. 而在Prefix LM,Encoder和Decoder则共享了同一个Transformer结构,在Transformer内部通过Attention Mask机制来实现。 - -与标准Encoder-Decoder类似,**Prefix LM在Encoder部分采用Auto Encoding (AE-自编码)模式,即前缀序列中任意两个token都相互可见,而Decoder部分采用Auto Regressive (AR-自回归)模式,即待生成的token可以看到Encoder侧所有token(包括上下文)和Decoder侧已经生成的token,但不能看未来尚未产生的token**。 - -下面的图很形象地解释了Prefix LM的Attention Mask机制(左)及流转过程(右)。 - -Prefix LM的代表模型有UniLM、T5、GLM(清华滴\~) - -#### 2.2 Causal LM - -Causal LM是因果语言模型,目前流行地大多数模型都是这种结构,别无他因,因为GPT系列模型内部结构就是它,还有开源界的LLaMa也是。 - -Causal LM只涉及到Encoder-Decoder中的Decoder部分,采用Auto Regressive模式,直白地说,就是**根据历史的token来预测下一个token,也是在Attention Mask这里做的手脚**。 - -参照着Prefix LM,可以看下Causal LM的Attention Mask机制(左)及流转过程(右)。 - -![](image/image_kIdEv4PBrq.png) - -#### 2.3 总结 - -1. **Prefix LM**:前缀语言模型是一种生成模型,它在生成每个词时都可以考虑之前的上下文信息。在生成时,前缀语言模型会根据给定的前缀(即部分文本序列)预测下一个可能的词。这种模型可以用于文本生成、机器翻译等任务。 -2. **Causal LM**:因果语言模型是一种自回归模型,它只能根据之前的文本生成后续的文本,而不能根据后续的文本生成之前的文本。在训练时,因果语言模型的目标是预测下一个词的概率,给定之前的所有词作为上下文。这种模型可以用于文本生成、语言建模等任务。 - -总结来说,前缀语言模型可以根据给定的前缀生成后续的文本,而因果语言模型只能根据之前的文本生成后续的文本。它们的训练目标和生成方式略有不同,适用于不同的任务和应用场景。 - -### 3.大模型LLM的 训练目标 - -大型语言模型(Large Language Models,LLM)的训练目标通常是**最大似然估计(Maximum Likelihood Estimation,MLE)**。最大似然估计是一种统计方法,用于从给定数据中估计概率模型的参数。 - -在LLM的训练过程中,使用的数据通常是大量的文本语料库。训练目标是**最大化模型生成训练数据中观察到的文本序列的概率**。具体来说,对于每个文本序列,模型根据前面的上下文生成下一个词的条件概率分布,并通过最大化生成的词序列的概率来优化模型参数。 - -为了最大化似然函数,可以使用梯度下降等优化算法来更新模型参数,使得模型生成的文本序列的概率逐步提高。在训练过程中,通常会使用批量训练(batch training)的方法,通过每次处理一小批数据样本来进行参数更新。 - -### 4.涌现能力是啥原因? - -[大语言模型的涌现能力:现象与解释 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/621438653 "大语言模型的涌现能力:现象与解释 - 知乎 (zhihu.com)") - -涌现能力(Emergent Ability)是指**模型在训练过程中能够生成出令人惊喜、创造性和新颖的内容或行为**。这种能力使得模型能够超出其训练数据所提供的内容,并产生出具有创造性和独特性的输出。 - -涌现能力的产生可以归因于以下几个原因: - -1. **任务的评价指标不够平滑**:因为很多任务的评价指标不够平滑,导致我们现在看到的涌现现象。如果评价指标要求很严格,要求一字不错才算对,那么Emoji\_movie任务我们就会看到涌现现象的出现。但是,如果我们把问题形式换成多选题,就是给出几个候选答案,让LLM选,那么随着模型不断增大,任务效果在持续稳定变好,但涌现现象消失,如上图图右所示。这说明评价指标不够平滑,起码是一部分任务看到涌现现象的原因。 -2. **复杂任务** **vs** **子任务**:展现出涌现现象的任务有一个共性,就是任务往往是由多个子任务构成的复杂任务。也就是说,最终任务过于复杂,如果仔细分析,可以看出它由多个子任务构成,这时候,子任务效果往往随着模型增大,符合 Scaling Law,而最终任务则体现为涌现现象。 -3. **用** **Grokking** (顿悟)**来解释涌现**:对于某个任务T,尽管我们看到的预训练数据总量是巨大的,但是与T相关的训练数据其实数量很少。当我们推大模型规模的时候,往往会伴随着增加预训练数据的数据量操作,这样,当模型规模达到某个点的时候,与任务T相关的数据量,突然就达到了最小要求临界点,于是我们就看到了这个任务产生了Grokking现象。 - -尽管涌现能力为模型带来了创造性和独特性,但也需要注意其生成的内容可能存在偏差、错误或不完整性。因此,在应用和使用涌现能力强的模型时,需要谨慎评估和验证生成的输出,以确保其质量和准确性。 - -### 5.为何现在的大模型大部分是Decoder only结构 - -1. **Encoder的低秩问题**:Encoder的双向注意力会存在低秩问题,这可能会削弱模型表达能力,就生成任务而言,引入双向注意力并无实质好处。 -2. **更好的Zero-Shot性能、更适合于大语料自监督学习**:decoder-only 模型在没有任何 tuning 数据的情况下、zero-shot 表现最好,而 encoder-decoder 则需要在一定量的标注数据上做 multitask finetuning 才能激发最佳性能。 -3. **效率问题**:decoder-only支持一直复用KV-Cache,对多轮对话更友好,因为每个Token的表示之和它之前的输入有关,而encoder-decoder和PrefixLM就难以做到。 - -### 6.大模型架构介绍 - -Transformer 模型一开始是用来做 seq2seq 任务的,所以它包含 Encoder 和 Decoder 两个部分;他们两者的区别主要是,**Encoder 在抽取序列中某一个词的特征时能够看到整个序列中所有的信息,即上文和下文同时看到**;而 **Decoder 中因为有 mask 机制的存在,使得它在编码某一个词的特征时只能看到自身和它之前的文本信息**。 - -首先概述几种主要的架构: - -- 以BERT为代表的**encoder-only** -- 以T5和BART为代表的**encoder-decoder** -- 以GPT为代表的**decoder-only**, -- 以UNILM9为代表的PrefixLM(相比于GPT只改了attention mask,前缀部分是双向,后面要生成的部分是单向的causal mask%) - -![](image/image_KoG36YaWZ7.png) - -### 6.LLMs复读机问题 - -#### 6.1 什么是 LLMs 复读机问题? - -LLMs复读机问题(LLMs Parroting Problem)是指大型语言模型在生成文本时过度依赖输入文本的复制,而缺乏创造性和独特性。当面对一个问题或指令时,模型可能会简单地复制输入文本的一部分或全部内容,并将其作为生成的输出,而不是提供有意义或新颖的回应。 - -#### 6.2 为什么会出现 LLMs 复读机问题? - -1. **数据偏差**:大型语言模型通常是通过预训练阶段使用大规模无标签数据进行训练的。如果训练数据中存在大量的重复文本或者某些特定的句子或短语出现频率较高,模型在生成文本时可能会倾向于复制这些常见的模式。 -2. **训练目标的限制**:大型语言模型的训练通常是基于自监督学习的方法,通过预测下一个词或掩盖词来学习语言模型。这样的训练目标可能使得模型更倾向于生成与输入相似的文本,导致复读机问题的出现。 -3. **缺乏多样性的训练数据**:虽然大型语言模型可以处理大规模的数据,但如果训练数据中缺乏多样性的语言表达和语境,模型可能无法学习到足够的多样性和创造性,导致复读机问题的出现。 -4. **模型结构和参数设置**:大型语言模型的结构和参数设置也可能对复读机问题产生影响。例如,模型的注意力机制和生成策略可能导致模型更倾向于复制输入的文本。 - -#### 6.3 如何缓解 LLMs 复读机问题? - -为了缓解LLMs复读机问题,可以尝试以下方法: - -1. **多样性训练数据**:在训练阶段,使用多样性的语料库来训练模型,避免数据偏差和重复文本的问题。这可以包括从不同领域、不同来源和不同风格的文本中获取数据。 -2. **引入噪声**:在生成文本时,引入一些随机性或噪声,例如通过采样不同的词或短语,或者引入随机的变换操作,以增加生成文本的多样性。这可以通过在生成过程中对模型的输出进行采样或添加随机性来实现。 -3. **温度参数调整**:温度参数是用来控制生成文本的多样性的一个参数。通过调整温度参数的值,可以控制生成文本的独创性和多样性。较高的温度值会增加随机性,从而减少复读机问题的出现。 -4. **Beam搜索调整**:在生成文本时,可以调整Beam搜索算法的参数。Beam搜索是一种常用的生成策略,它在生成过程中维护了一个候选序列的集合。通过调整Beam大小和搜索宽度,可以控制生成文本的多样性和创造性。 -5. **后处理和过滤**:对生成的文本进行后处理和过滤,去除重复的句子或短语,以提高生成文本的质量和多样性。可以使用文本相似度计算方法或规则来检测和去除重复的文本。 -6. **人工干预和控制**:对于关键任务或敏感场景,可以引入人工干预和控制机制,对生成的文本进行审查和筛选,确保生成结果的准确性和多样性。 - -需要注意的是,缓解LLMs复读机问题是一个复杂的任务,没有一种通用的解决方案。不同的方法可能适用于不同的场景和任务,需要根据具体情况进行选择和调整。此外,解决复读机问题还需要综合考虑数据、训练目标、模型架构和生成策略等多个因素,需要进一步的研究和实践来提高大型语言模型的生成文本多样性和创造性。 - -### 7.LLMs输入句子长度理论上可以无限长吗? - -**理论上来说,LLMs(大型语言模型)可以处理任意长度的输入句子,但实际上存在一些限制和挑战**。下面是一些相关的考虑因素: - -1. **计算资源**:生成长句子需要更多的计算资源,包括内存和计算时间。由于LLMs通常是基于神经网络的模型,计算长句子可能会导致内存不足或计算时间过长的问题。 -2. **模型训练和推理**:训练和推理长句子可能会面临一些挑战。在训练阶段,处理长句子可能会导致梯度消失或梯度爆炸的问题,影响模型的收敛性和训练效果。在推理阶段,生成长句子可能会增加模型的错误率和生成时间。 -3. **上下文建模**:LLMs是基于上下文建模的模型,长句子的上下文可能会更加复杂和深层。模型需要能够捕捉长句子中的语义和语法结构,以生成准确和连贯的文本。 - -### 8.什么情况用Bert模型,什么情况用LLaMA、ChatGLM类大模型,咋选? - -选择使用哪种大模型,如Bert、LLaMA或ChatGLM,取决于具体的应用场景和需求。下面是一些指导原则: - -1. **Bert模型**:Bert是一种预训练的语言模型,**适用于各种自然语言处理任务**,如文本分类、命名实体识别、语义相似度计算等。如果你的任务是通用的文本处理任务,而不依赖于特定领域的知识或语言风格,Bert模型通常是一个不错的选择。Bert由一个Transformer编码器组成,更适合于NLU相关的任务。 -2. **LLaMA模型**:LLaMA(Large Language Model Meta AI)包含从 7B 到 65B 的参数范围,训练使用多达14,000亿tokens语料,具有常识推理、问答、数学推理、代码生成、语言理解等能力。LLaMA由一个Transformer解码器组成。训练预料主要为以英语为主的拉丁语系,不包含中日韩文。所以适合于英文文本生成的任务。 -3. **ChatGLM模型**:ChatGLM是一个面向对话生成的语言模型,适用于构建聊天机器人、智能客服等对话系统。如果你的应用场景需要模型能够生成连贯、流畅的对话回复,并且需要处理对话上下文、生成多轮对话等,ChatGLM模型可能是一个较好的选择。ChatGLM的架构为Prefix decoder,训练语料为中英双语,中英文比例为1:1。所以适合于中文和英文文本生成的任务。 - -在选择模型时,还需要考虑以下因素: - -- 数据可用性:不同模型可能需要不同类型和规模的数据进行训练。确保你有足够的数据来训练和微调所选择的模型。 -- 计算资源:大模型通常需要更多的计算资源和存储空间。确保你有足够的硬件资源来支持所选择的模型的训练和推理。 -- 预训练和微调:大模型通常需要进行预训练和微调才能适应特定任务和领域。了解所选择模型的预训练和微调过程,并确保你有相应的数据和时间来完成这些步骤。 - -最佳选择取决于具体的应用需求和限制条件。在做出决策之前,建议先进行一些实验和评估,以确定哪种模型最适合你的应用场景。 - -### 9.各个专业领域是否需要各自的大模型来服务? - -各个专业领域通常需要各自的大模型来服务,原因如下: - -1. **领域特定知识**:不同领域拥有各自特定的知识和术语,需要针对该领域进行训练的大模型才能更好地理解和处理相关文本。例如,在医学领域,需要训练具有医学知识的大模型,以更准确地理解和生成医学文本。 -2. **语言风格和惯用语**:各个领域通常有自己独特的语言风格和惯用语,这些特点对于模型的训练和生成都很重要。专门针对某个领域进行训练的大模型可以更好地掌握该领域的语言特点,生成更符合该领域要求的文本。 -3. **领域需求的差异**:不同领域对于文本处理的需求也有所差异。例如,金融领域可能更关注数字和统计数据的处理,而法律领域可能更关注法律条款和案例的解析。因此,为了更好地满足不同领域的需求,需要专门针对各个领域进行训练的大模型。 -4. **数据稀缺性**:某些领域的数据可能相对较少,无法充分训练通用的大模型。针对特定领域进行训练的大模型可以更好地利用该领域的数据,提高模型的性能和效果。 - -尽管需要各自的大模型来服务不同领域,但也可以共享一些通用的模型和技术。例如,通用的大模型可以用于处理通用的文本任务,而领域特定的模型可以在通用模型的基础上进行微调和定制,以适应特定领域的需求。这样可以在满足领域需求的同时,减少模型的重复训练和资源消耗。 - -### 10.如何让大模型处理更长的文本? - -要让大模型处理更长的文本,可以考虑以下几个方法: - -1. **分块处理**:将长文本分割成较短的片段,然后逐个片段输入模型进行处理。这样可以避免长文本对模型内存和计算资源的压力。在处理分块文本时,可以使用重叠的方式,即将相邻片段的一部分重叠,以保持上下文的连贯性。 -2. **层次建模**:通过引入层次结构,将长文本划分为更小的单元。例如,可以将文本分为段落、句子或子句等层次,然后逐层输入模型进行处理。这样可以减少每个单元的长度,提高模型处理长文本的能力。 -3. **部分生成**:如果只需要模型生成文本的一部分,而不是整个文本,可以只输入部分文本作为上下文,然后让模型生成所需的部分。例如,输入前一部分文本,让模型生成后续的内容。 -4. **注意力机制**:注意力机制可以帮助模型关注输入中的重要部分,可以用于处理长文本时的上下文建模。通过引入注意力机制,模型可以更好地捕捉长文本中的关键信息。 -5. **模型结构优化**:通过优化模型结构和参数设置,可以提高模型处理长文本的能力。例如,可以增加模型的层数或参数量,以增加模型的表达能力。还可以使用更高效的模型架构,如Transformer等,以提高长文本的处理效率。 - -需要注意的是,处理长文本时还需考虑计算资源和时间的限制。较长的文本可能需要更多的内存和计算时间,因此在实际应用中需要根据具体情况进行权衡和调整。 diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/README.md" "b/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/README.md" deleted file mode 100644 index 6715e3a..0000000 --- "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/README.md" +++ /dev/null @@ -1,15 +0,0 @@ -# 01.大语言模型简介 - -### 大模型发展历程 - -[1.语言模型](1.语言模型/1.语言模型.md "1.语言模型") - -### 常见大模型 - -[llama系列模型](llama系列模型/llama系列模型.md "llama系列模型") - -[chatglm系列模型](chatglm系列模型/chatglm系列模型.md "chatglm系列模型") - -### 一些题目 - -[1.llm概念](1.llm概念/1.llm概念.md "1.llm概念") diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/README.md" "b/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/README.md" deleted file mode 100644 index a8d8460..0000000 --- "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/README.md" +++ /dev/null @@ -1,17 +0,0 @@ -# 02.大语言模型基础 - -### Transformer模型 - -[1.attention](1.attention/1.attention.md "1.attention") - -[2.layer\_normalization](2.layer_normalization/2.layer_normalization.md "2.layer_normalization") - -[3.位置编码](3.位置编码/3.位置编码.md "3.位置编码") - -[4.tokenize分词](4.tokenize分词/4.tokenize分词.md "4.tokenize分词") - -[4.token及模型参数](4.token及模型参数/4.token及模型参数.md "4.token及模型参数") - -[5.激活函数](5.激活函数/5.激活函数.md "5.激活函数") - -### 大语言模型结构 diff --git "a/03.\350\257\255\350\250\200\346\250\241\345\236\213\350\256\255\347\273\203\346\225\260\346\215\256\351\233\206/03.\350\257\255\350\250\200\346\250\241\345\236\213\350\256\255\347\273\203\346\225\260\346\215\256\351\233\206.md" "b/03.\350\257\255\350\250\200\346\250\241\345\236\213\350\256\255\347\273\203\346\225\260\346\215\256\351\233\206/03.\350\257\255\350\250\200\346\250\241\345\236\213\350\256\255\347\273\203\346\225\260\346\215\256\351\233\206.md" deleted file mode 100644 index 989aa4d..0000000 --- "a/03.\350\257\255\350\250\200\346\250\241\345\236\213\350\256\255\347\273\203\346\225\260\346\215\256\351\233\206/03.\350\257\255\350\250\200\346\250\241\345\236\213\350\256\255\347\273\203\346\225\260\346\215\256\351\233\206.md" +++ /dev/null @@ -1,111 +0,0 @@ -# 03.语言模型训练数据集 - -\[toc] - -### 1.SFT(有监督微调)的数据集格式? - -对于大语言模型的训练中,SFT(Supervised Fine-Tuning)的数据集格式可以采用以下方式: - -1. 输入数据:输入数据是一个文本序列,通常是一个句子或者一个段落。每个样本可以是一个字符串或者是一个tokenized的文本序列。 -2. 标签数据:标签数据是与输入数据对应的标签或类别。标签可以是单个类别,也可以是多个类别的集合。对于多分类任务,通常使用one-hot编码或整数编码来表示标签。 -3. 数据集划分:数据集通常需要划分为训练集、验证集和测试集。训练集用于模型的训练,验证集用于调整模型的超参数和监控模型的性能,测试集用于评估模型的最终性能。 -4. 数据集格式:数据集可以以文本文件(如CSV、JSON等)或数据库的形式存储。每个样本包含输入数据和对应的标签。可以使用表格形式存储数据,每一列代表一个特征或标签。 - -下面是一个示例数据集的格式: - -```bash -Input,Label -"This is a sentence.",1 -"Another sentence.",0 -... -``` - -在这个示例中,**输入数据是一个句子,标签是一个二分类的标签**(1代表正例,0代表负例)。每一行代表一个样本,第一列是输入数据,第二列是对应的标签。 - -需要注意的是,具体的数据集格式可能会因任务类型、数据来源和使用的深度学习框架而有所不同。因此,在进行SFT训练时,建议根据具体任务和框架的要求来定义和处理数据集格式。 - -### 2.RM(奖励模型)的数据格式? - -在大语言模型训练中,RM(Reward Model,奖励模型)的数据格式可以采用以下方式: - -1. 输入数据:输入数据是一个文本序列,通常是一个句子或者一个段落。每个样本可以是一个字符串或者是一个tokenized的文本序列。 -2. 奖励数据:奖励数据是与输入数据对应的奖励或评分。奖励可以是一个实数值,表示对输入数据的评价。也可以是一个离散的标签,表示对输入数据的分类。奖励数据可以是人工标注的,也可以是通过其他方式(如人工评估、强化学习等)得到的。 -3. 数据集格式:数据集可以以文本文件(如CSV、JSON等)或数据库的形式存储。每个样本包含输入数据和对应的奖励数据。可以使用表格形式存储数据,每一列代表一个特征或标签。 - -下面是一个示例数据集的格式: - -```bash -Input,Reward -"This is a sentence.",0.8 -"Another sentence.",0.2 -... -``` - -在这个示例中,输入数据是一个句子,**奖励数据是一个实数值,表示对输入数据的评价**。每一行代表一个样本,第一列是输入数据,第二列是对应的奖励数据。 - -需要注意的是,具体的数据集格式可能会因任务类型、数据来源和使用的深度学习框架而有所不同。因此,在使用RM进行大语言模型训练时,建议根据具体任务和框架的要求来定义和处理数据集格式。 - -### 3.PPO(强化学习)的数据格式? - -在大语言模型训练中,PPO(Proximal Policy Optimization,近端策略优化)是一种常用的强化学习算法。PPO的数据格式可以采用以下方式: - -1. 输入数据:输入数据是一个文本序列,通常是一个句子或者一个段落。每个样本可以是一个字符串或者是一个tokenized的文本序列。 -2. 奖励数据:奖励数据是与输入数据对应的奖励或评分。奖励可以是一个实数值,表示对输入数据的评价。也可以是一个离散的标签,表示对输入数据的分类。奖励数据可以是人工标注的,也可以是通过其他方式(如人工评估、模型评估等)得到的。 -3. 动作数据:动作数据是模型在给定输入数据下的输出动作。对于语言模型,动作通常是生成的文本序列。动作数据可以是一个字符串或者是一个tokenized的文本序列。 -4. 状态数据:状态数据是模型在给定输入数据和动作数据下的状态信息。对于语言模型,状态数据可以是模型的隐藏状态或其他中间表示。状态数据的具体形式可以根据具体任务和模型结构进行定义。 -5. 数据集格式:数据集可以以文本文件(如CSV、JSON等)或数据库的形式存储。每个样本包含输入数据、奖励数据、动作数据和状态数据。可以使用表格形式存储数据,每一列代表一个特征或标签。 - -下面是一个示例数据集的格式: - -```bash -Input,Reward,Action,State - "This is a sentence.",0.8,"This is a generated sentence.",[0.1, 0.2, 0.3, ...] -"Another sentence.",0.2,"Another generated sentence.",[0.4, 0.5, 0.6, ...] -... -``` - -在这个示例中,输入数据是一个句子,奖励数据是一个实数值,动作数据是生成的句子,状态数据是模型的隐藏状态。每一行代表一个样本,第一列是输入数据,第二列是对应的奖励数据,第三列是生成的动作数据,第四列是状态数据。 - -需要注意的是,具体的数据集格式可能会因任务类型、数据来源和使用的深度学习框架而有所不同。因此,在使用PPO进行大语言模型训练时,建议根据具体任务和框架的要求来定义和处理数据集格式。 - -### 4.找数据集哪里找? - -在训练自己的大语言模型时,可以从以下几个途径找到合适的数据集: - -1. **公开数据集**:有许多公开可用的数据集可供使用,涵盖了各种领域和任务。例如,Common Crawl、Wikipedia、OpenWebText、BookCorpus等都是常用的大规模文本数据集,可以用于语言模型的训练。 -2. **开放数据平台**:许多组织和机构提供了开放的数据平台,可以获取各种类型的数据。例如,Kaggle、UCI Machine Learning Repository、Google Dataset Search等平台都提供了丰富的数据集资源。 -3. **学术界研究**:许多学术研究项目会公开其使用的数据集,可以通过相关论文或项目页面找到这些数据集。例如,NLP领域的一些会议和竞赛(如ACL、EMNLP、CoNLL、GLUE等)提供了公开的数据集供研究使用。 -4. **数据收集和爬取**:如果没有合适的公开数据集,您可以自己进行数据收集和爬取。这可以通过爬虫技术从互联网上收集相关的文本数据。需要注意的是,在进行数据收集和爬取时,需要遵守法律法规和网站的使用条款,并确保获得数据的合法使用权。 -5. **数据增强**:如果您已经有了一些初始的数据集,但觉得数量不够,可以考虑使用数据增强技术来扩充数据。数据增强可以通过对原始数据进行一些变换、替换、合成等操作来生成新的样本。 - -无论从哪个途径获取数据集,都需要注意数据的质量、版权和隐私等问题。确保您有合法的使用权,并遵守相关的法律和伦理规范。 - -### 5.微调需要多少条数据? - -根据 Scaling Laws,随着模型大小、数据集大小和用于训练的计算浮点数的增加,模型的性能会提高。并且为了获得最佳性能,所有三个因素**必须同时放大**。一般来说对于给定模型的理想训练数据集 token 数量大约是模型中参数数量的20倍。 - -### 6.有哪些大模型的训练集? - -以下是一些常用的大语言模型训练集的示例: - -1. Common Crawl:这是一个由互联网上抓取的大规模文本数据集,包含了来自各种网站的文本内容。它是一个常用的数据集,可用于语言模型的训练。 -2. Wikipedia:维基百科是一个包含大量结构化文本的在线百科全书。维基百科的内容丰富多样,涵盖了各种领域的知识,可以作为语言模型训练的数据集。 -3. OpenWebText:这是一个从互联网上抓取的开放文本数据集,类似于Common Crawl。它包含了大量的网页文本,可以作为语言模型的训练数据。 -4. BookCorpus:这是一个包含了大量图书文本的数据集,用于语言模型的训练。它包括了各种类型的图书,涵盖了广泛的主题和领域。 -5. News articles:新闻文章是另一个常用的语言模型训练集。可以通过从新闻网站、新闻API或新闻数据库中收集新闻文章来构建训练集。 -6. 其他领域特定数据集:根据具体任务和应用,可以使用特定领域的数据集来训练语言模型。例如,在医学领域,可以使用医学文献或医疗记录作为训练数据;在法律领域,可以使用法律文书或法律条款作为训练数据。 - -需要注意的是,使用这些数据集时,应该遵守数据的版权和使用规定,确保合法的使用权。此外,还可以通过数据增强技术,如数据合成、数据变换等,来扩充训练集的规模和多样性。 - -### 7.进行领域大模型预训练应用哪些数据集比较好? - -进行领域大模型预训练时,可以使用以下几种数据集来获得更好的效果: - -1. 领域特定文本数据集:收集与目标领域相关的文本数据集,例如专业领域的论文、报告、文档、书籍等。这些数据集可以提供领域内的专业术语、上下文和特定领域的知识。 -2. 领域内的网页内容:从目标领域相关的网页抓取文本内容。可以通过爬虫技术从相关网站上获取与目标领域相关的网页文本数据。 -3. 领域内的新闻文章:收集与目标领域相关的新闻文章。新闻文章通常包含了领域内的最新信息和事件,可以帮助模型了解领域内的动态和趋势。 -4. 行业报告和白皮书:获取与目标领域相关的行业报告、白皮书和研究文献。这些文献通常包含了领域内的专业分析、统计数据和趋势预测,可以帮助模型了解行业背景和发展趋势。 -5. 社交媒体数据:收集与目标领域相关的社交媒体数据,如推特、微博、论坛等。社交媒体上的内容通常反映了人们在目标领域中的讨论、观点和问题,可以帮助模型了解领域内的热点和用户需求。 -6. 领域内的对话数据:获取与目标领域相关的对话数据,如客服对话、问答平台数据等。这些对话数据可以帮助模型学习领域内的常见问题、解决方案和用户需求。 - -在选择数据集时,应该确保数据的质量和合法性,并遵守相关的法律和伦理规范。同时,还可以考虑使用数据增强技术,如数据合成、数据变换等,来扩充训练集的规模和多样性。 diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/README.md" "b/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/README.md" deleted file mode 100644 index 33a24cb..0000000 --- "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/README.md" +++ /dev/null @@ -1,40 +0,0 @@ -# 04.分布式训练 - -### 1.基础知识 - -[1.概述](1.概述/1.概述.md "1.概述") - -[2.数据并行](2.数据并行/2.数据并行.md "2.数据并行") - -[3.流水线并行](3.流水线并行/3.流水线并行.md "3.流水线并行") - -[4.张量并行](4.张量并行/4.张量并行.md "4.张量并行") - -[5.序列并行](5.序列并行/5.序列并行.md "5.序列并行") - -[6.多维度混合并行](6.多维度混合并行/6.多维度混合并行.md "6.多维度混合并行") - -[7.自动并行](7.自动并行/7.自动并行.md "7.自动并行") - -[8.moe并行](8.moe并行/8.moe并行.md "8.moe并行") - -[9.总结](9.总结/9.总结.md "9.总结") - -### 2.DeepSpeed - -[deepspeed介绍](deepspeed介绍/deepspeed介绍.md "deepspeed介绍") - -### 3.软硬件 - -[1.显存问题](1.显存问题/1.显存问题.md "1.显存问题") - -### 3.一些题目 - -[分布式训练题目](分布式训练题目/分布式训练题目.md "分布式训练题目") - -参考资料: - -- [大模型分布式训练并行技术(九)-总结 - 掘金 (juejin.cn)](https://juejin.cn/post/7290740395913969705 "大模型分布式训练并行技术(九)-总结 - 掘金 (juejin.cn)") -- [https://www.zhangzhenhu.com/deepspeed/index.html](https://www.zhangzhenhu.com/deepspeed/index.html "https://www.zhangzhenhu.com/deepspeed/index.html") -- [https://blog.csdn.net/zwqjoy/article/details/130732601](https://blog.csdn.net/zwqjoy/article/details/130732601 "https://blog.csdn.net/zwqjoy/article/details/130732601") -- [https://techdiylife.github.io/](https://techdiylife.github.io/ "https://techdiylife.github.io/") diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/README.md" "b/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/README.md" deleted file mode 100644 index 651162c..0000000 --- "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/README.md" +++ /dev/null @@ -1,29 +0,0 @@ -# 05.有监督微调 - -### 理论 - -[1.基本概念](1.基本概念/1.基本概念.md "1.基本概念") - -[2.prompting](2.prompting/2.prompting.md "2.prompting") - -[3.adapter-tuning](3.adapter-tuning/3.adapter-tuning.md "3.adapter-tuning") - -[4.lora](4.lora/4.lora.md "4.lora") - -[5.总结](5.总结/5.总结.md "5.总结") - -### 微调实战 - -[llama2微调](llama2微调/llama2微调.md "llama2微调") - -[ChatGLM3微调](ChatGLM3微调/ChatGLM3微调.md "ChatGLM3微调") - -### 一些题目 - -[1.微调](1.微调/1.微调.md "1.微调") - -[2.预训练](2.预训练/2.预训练.md "2.预训练") - -参考资料: - -- [liguodongiot/llm-action](https://github.com/liguodongiot/llm-action#llm微调实战 "liguodongiot/llm-action") diff --git "a/06.\346\216\250\347\220\206/README.md" "b/06.\346\216\250\347\220\206/README.md" deleted file mode 100644 index fce39a7..0000000 --- "a/06.\346\216\250\347\220\206/README.md" +++ /dev/null @@ -1,21 +0,0 @@ -# 06.推理 - -### 推理框架 - -[0.llm推理框架简单总结](0.llm推理框架简单总结/0.llm推理框架简单总结.md "0.llm推理框架简单总结") - -[1.vllm](1.vllm/1.vllm.md "1.vllm") - -[2.text_generation\_inference](2.text_generation_inference/2.text_generation_inference.md "2.text_generation_inference") - -[3.faster_transformer](3.faster_transformer/3.faster_transformer.md "3.faster_transformer") - -[4.trt_llm](4.trt_llm/4.trt_llm.md "4.trt_llm") - -### 推理优化技术 - -[llm推理优化技术](llm推理优化技术/llm推理优化技术.md "llm推理优化技术") - -### 一些题目 - -[1.推理](1.推理/1.推理.md "1.推理") diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/README.md" "b/07.\345\274\272\345\214\226\345\255\246\344\271\240/README.md" deleted file mode 100644 index 5c9dc60..0000000 --- "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/README.md" +++ /dev/null @@ -1,21 +0,0 @@ -# 07.强化学习 - -### 强化学习原理 - -[策略梯度(pg)](策略梯度(pg)/策略梯度(pg).md "策略梯度(pg)") - -[近端策略优化(ppo)](近端策略优化(ppo)/近端策略优化(ppo).md "近端策略优化(ppo)") - -### RLHF - -[大模型RLHF:PPO原理与源码解读](大模型RLHF:PPO原理与源码解读/大模型RLHF:PPO原理与源码解读.md "大模型RLHF:PPO原理与源码解读") - -[DPO](DPO/DPO.md "DPO") - -### 一些题目 - -[1.rlhf相关](1.rlhf相关/1.rlhf相关.md "1.rlhf相关") - -[2.强化学习](2.强化学习/2.强化学习.md "2.强化学习") - - diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/README.md" "b/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/README.md" deleted file mode 100644 index 0809eec..0000000 --- "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/README.md" +++ /dev/null @@ -1,13 +0,0 @@ -# 08.检索增强rag - -### RAG - -[检索增强llm](检索增强llm/检索增强llm.md "检索增强llm") - -[rag(检索增强生成)技术](rag(检索增强生成)技术/rag(检索增强生成)技术.md "rag(检索增强生成)技术") - - - -### Agent - -[大模型agent技术](大模型agent技术/大模型agent技术.md "大模型agent技术") diff --git "a/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/README.md" "b/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/README.md" deleted file mode 100644 index d05e38e..0000000 --- "a/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/README.md" +++ /dev/null @@ -1,11 +0,0 @@ -# 09.大语言模型评估 - -### 模型评估 - -[1.评测](1.评测/1.评测.md "1.评测") - -### LLM幻觉 - -[1.大模型幻觉](1.大模型幻觉/1.大模型幻觉.md "1.大模型幻觉") - -[2.幻觉来源与缓解](2.幻觉来源与缓解/2.幻觉来源与缓解.md "2.幻觉来源与缓解") diff --git "a/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/README.md" "b/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/README.md" deleted file mode 100644 index 28030b5..0000000 --- "a/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/README.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 10.大语言模型应用 - -### 思维链提示 - -[1.思维链(cot)](1.思维链(cot)/1.思维链(cot).md "1.思维链(cot)") - -### LangChain框架 - -[1.langchain](1.langchain/1.langchain.md "1.langchain") diff --git "a/98.LLMs\347\233\270\345\205\263\350\257\276\347\250\213/README.md" "b/98.LLMs\347\233\270\345\205\263\350\257\276\347\250\213/README.md" deleted file mode 100644 index 72a187b..0000000 --- "a/98.LLMs\347\233\270\345\205\263\350\257\276\347\250\213/README.md" +++ /dev/null @@ -1,15 +0,0 @@ -## LLMs相关课程推荐 - -### 1.清华大模型公开课 - -- 视频连接:https://www.bilibili.com/video/BV1UG411p7zv -- 文档资料:[OpenBMB - 让大模型飞入千家万户](https://www.openbmb.org/community/course) - - - - - - - - - diff --git "a/99.\345\217\202\350\200\203\350\265\204\346\226\231/README.md" "b/99.\345\217\202\350\200\203\350\265\204\346\226\231/README.md" deleted file mode 100644 index c1931c8..0000000 --- "a/99.\345\217\202\350\200\203\350\265\204\346\226\231/README.md" +++ /dev/null @@ -1,9 +0,0 @@ -# 99.参考资料 - -- [大模型(LLMs) 算法工程师相关的面试题](https://github.com/km1994/LLMs_interview_notes "大模型(LLMs) 算法工程师相关的面试题") -- [epoch次数设置问题](https://mp.weixin.qq.com/s/DBP_eafGeKMEuSIma9Z9Tg "epoch次数设置问题") -- [大模型训练入门实战](https://techdiylife.github.io/big-model-training/deepspeed/LLM-state-of-GPT.html "大模型训练入门实战") -- [大模型训练避坑指南](https://mp.weixin.qq.com/s/s3aPTe11-w_ELL7uZJCI2Q "大模型训练避坑指南") -- [算法工程师笔记](https://mingchao.wang/ "算法工程师笔记") -- [深度学习自然语言处理](https://github.com/DA-southampton/NLP_ability "深度学习自然语言处理") -- [养生的控制人 - 知乎 (zhihu.com)](https://www.zhihu.com/people/yilan-zhong-shan-xiao-29-98 "养生的控制人 - 知乎 (zhihu.com)") diff --git a/README.md b/README.md index 89a1ad1..011d07f 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,12 @@ 本仓库为大模型面试相关概念,由本人参考网络资源整理,欢迎阅读,如果对你有用,麻烦点一下 `start`,谢谢! -为了在低资源情况下,学习大模型,进行动手实践,创建 [tiny-llm-zh](https://github.com/wdndev/tiny-llm-zh)仓库,旨在构建一个小参数量的中文Llama2大语言模型,方便学习,欢迎学习交流。 +为了在低资源情况下,学习大模型,进行动手实践,创建 [tiny-llm-zh](https://github.com/wdndev/tiny-llm-zh)仓库,旨在构建一个小参数量的中文大语言模型,方便学习,欢迎学习交流。 ## 在线阅读 -本仓库相关文章已放在个人博客中,欢迎阅读: +在线阅读链接:[LLMs Interview Note](http://wdndev.github.io/llm_interview_note) -在线阅读链接:[LLMs Interview Note](http://wdndev.github.io/note/llm/llm_concept/llm%E5%85%AB%E8%82%A1.html) ## 注意: @@ -24,156 +23,135 @@ ## 目录 -### [01.大语言模型简介](01.大语言模型简介/README.md) - -##### 1.1 大模型发展历程 - -1. [语言模型](01.大语言模型简介/1.语言模型/1.语言模型.md "1.语言模型") - -##### 1.2 常见大模型 - -1. [llama系列模型](01.大语言模型简介/llama系列模型/llama系列模型.md ) -2. [chatglm系列模型](01.大语言模型简介/chatglm系列模型/chatglm系列模型.md) - -##### 1.3 LLM基础题目 - -### [02.大语言模型基础](02.大语言模型基础/README.md) - -##### 2.1 Transformer模型 - -1. [attention](02.大语言模型基础/1.attention/1.attention.md) -2. [layer_normalization](02.大语言模型基础/2.layer_normalization/2.layer_normalization.md) -3. [位置编码](02.大语言模型基础/3.位置编码/3.位置编码.md) -4. [tokenize分词](02.大语言模型基础/4.tokenize分词/4.tokenize分词.md) -5. [token及模型参数](02.大语言模型基础/4.token及模型参数/4.token及模型参数.md) -6. [激活函数](02.大语言模型基础/5.激活函数/5.激活函数.md ) - -##### 2.2 大语言模型结构 - -### [03.语言模型训练数据集](03.语言模型训练数据集/03.语言模型训练数据集.md) - -### [04.分布式训练](04.分布式训练/README.md) - -##### 4.1 基础知识 - -1. [概述](04.分布式训练/1.概述/1.概述.md) -2. [数据并行](04.分布式训练/2.数据并行/2.数据并行.md) -3. [流水线并行](04.分布式训练/3.流水线并行/3.流水线并行.md) -4. [张量并行](04.分布式训练/4.张量并行/4.张量并行.md) -5. [序列并行](04.分布式训练/5.序列并行/5.序列并行.md) -6. [多维度混合并行](04.分布式训练/6.多维度混合并行/6.多维度混合并行.md) -7. [自动并行](04.分布式训练/7.自动并行/7.自动并行.md) -8. [moe并行](04.分布式训练/8.moe并行/8.moe并行.md ) -9. [总结](04.分布式训练/9.总结/9.总结.md ) - -##### 4.2 DeepSpeed - -1. DeepSpeed介绍 - -##### 4.3 软硬件 - -1. 显存问题 - -##### 4.4 分布式相关题目 - -### [05.有监督微调](05.有监督微调/README.md) - -##### 5.1 理论 - -1. [基本概念](05.有监督微调/1.基本概念/1.基本概念.md) -2. [prompting](05.有监督微调/2.prompting/2.prompting.md) -3. [adapter-tuning](05.有监督微调/3.adapter-tuning/3.adapter-tuning.md) -4. [lora](05.有监督微调/4.lora/4.lora.md) -5. [总结](05.有监督微调/5.总结/5.总结.md) - -##### 5.2 微调实战 - -1. LLaMa2微调 - -##### 5.3 有监督微调相关题目 - -1. 微调 -2. 预训练 - -### [06.推理](06.推理/README.md) - -##### 6.1 推理框架 - -1. [llm推理框架简单总结](06.推理/0.llm推理框架简单总结/0.llm推理框架简单总结.md "0.llm推理框架简单总结") -2. [vLLM](06.推理/1.vllm/1.vllm.md "1.vllm") -3. [Text Generation Inference](06.推理/2.text_generation_inference/2.text_generation_inference.md "2.text_generation_inference") -4. [Faster Transformer](06.推理/3.faster_transformer/3.faster_transformer.md "3.faster_transformer") -5. [TRT LLM](06.推理/4.trt_llm/4.trt_llm.md "4.trt_llm") - -##### 6.2 推理优化技术 - -1. [LLM推理优化技术](06.推理/llm推理优化技术/llm推理优化技术.md "llm推理优化技术") -2. [LLM推理常见参数](06.推理/LLM推理常见参数/LLM推理常见参数.md) - - -##### 6.3 推理相关题目 - -1. [推理](06.推理/1.推理/1.推理.md "1.推理") - -### [07.强化学习](07.强化学习/README.md) - -##### 7.1 强化学习原理 - -1. [策略梯度(pg)](07.强化学习/策略梯度(pg)/策略梯度(pg).md "策略梯度(pg)") -2. [近端策略优化(ppo)](07.强化学习/近端策略优化(ppo)/近端策略优化(ppo).md) - -##### 7.2 RLHF - -1. [大模型RLHF:PPO原理与源码解读](07.强化学习/大模型RLHF:PPO原理与源码解读/大模型RLHF:PPO原理与源码解读.md) -2. [DPO](07.强化学习/DPO/DPO.md) - -##### 7.3 一些题目 - -1. [rlhf相关](07.强化学习/1.rlhf相关/1.rlhf相关.md "1.rlhf相关") -2. [强化学习](07.强化学习/2.强化学习/2.强化学习.md "2.强化学习") - -### [08.检索增强rag](08.检索增强rag/README.md) - -##### 8.1 RAG - -1. [检索增强llm](08.检索增强rag/检索增强llm/检索增强llm.md) - -2. [rag(检索增强生成)技术](08.检索增强rag/rag(检索增强生成)技术/rag(检索增强生成)技术.md) - -##### 8.2 Agent - -1. [大模型agent技术](08.检索增强rag/大模型agent技术/大模型agent技术.md) - -### [09.大语言模型评估](09.大语言模型评估/README.md) - -##### 9.1 模型评估 - -1. [评测](09.大语言模型评估/1.评测/1.评测.md) - -##### 9.2 LLM幻觉 - -1. [大模型幻觉](09.大语言模型评估/1.大模型幻觉/1.大模型幻觉.md) -2. [幻觉来源与缓解](09.大语言模型评估/2.幻觉来源与缓解/2.幻觉来源与缓解.md) - -### [10.大语言模型应用](10.大语言模型应用/README.md) - -##### 10.1 思维链(CoT) - -1. [思维链(cot)](10.大语言模型应用/1.思维链(cot)/1.思维链(cot).md "1.思维链(cot)") - - - - -##### 10.2 LangChain 框架 - -1. [langchain](10.大语言模型应用/1.langchain/1.langchain.md "1.langchain") - -### [98.LLMs相关课程](98.LLMs相关课程/README.md) - -### [99.参考资料](99.参考资料/README.md ) +* [首页](/) +* [真实面试题](/docs/ch1) +* [01.大语言模型基础](/docs/01.大语言模型基础/) + * [1.1 大模型发展历程](/docs/01.大语言模型基础/) + * [1.语言模型](/docs/01.大语言模型基础/1.语言模型/1.语言模型.md "1.语言模型") + * [1.2 分词与词向量]() + * [1.分词](/docs/01.大语言模型基础/1.分词/1.分词.md) + * [2.jieba分词用法及原理](/docs/01.大语言模型基础/2.jieba分词用法及原理/2.jieba分词用法及原理.md) + * [3.词性标注](/docs/01.大语言模型基础/3.词性标注/3.词性标注.md) + * [4.句法分析](/docs/01.大语言模型基础/4.句法分析/4.句法分析.md "4.句法分析") + * [5.词向量](/docs/01.大语言模型基础/5.词向量/5.词向量.md "5.词向量") + * [1.3 语言模型基础知识](/docs/01.大语言模型基础/) + * [Word2Vec](/docs/01.大语言模型基础/Word2Vec/Word2Vec.md "Word2Vec") + * [NLP三大特征抽取器(CNN/RNN/TF)](/docs/01.大语言模型基础/NLP三大特征抽取器(CNN-RNN-TF)/NLP三大特征抽取器(CNN-RNN-TF).md) + * [NLP面试题](/docs/01.大语言模型基础/NLP面试题/NLP面试题.md "NLP面试题") + * [LLM为什么Decoder only架构]( "LLM为什么Decoder only架构") + * [1.4 深度学习](/docs/01.大语言模型基础/) + * [1.激活函数](/docs/01.大语言模型基础/1.激活函数/1.激活函数.md) + * [1.5 一些题目](/docs/01.大语言模型基础/) + * [1.llm概念](/docs/01.大语言模型基础/1.llm概念/1.llm概念.md) +* [02.大语言模型架构](/docs/02.大语言模型架构/) + * [2.1 Transformer模型](/docs/02.大语言模型架构/) + * [1.attention](/docs/02.大语言模型架构/1.attention/1.attention.md "1.attention") + * [2.layer\_normalization](/docs/02.大语言模型架构/2.layer_normalization/2.layer_normalization.md "2.layer_normalization") + * [3.位置编码](/docs/02.大语言模型架构/3.位置编码/3.位置编码.md "3.位置编码") + * [4.tokenize分词](/docs/02.大语言模型架构/4.tokenize分词/4.tokenize分词.md "4.tokenize分词") + * [5.token及模型参数](/docs/02.大语言模型架构/5.token及模型参数/5.token及模型参数.md "5.token及模型参数") + * [6.激活函数](/docs/02.大语言模型架构/6.激活函数/6.激活函数.md "6.激活函数") + * [2.2 注意力](/docs/02.大语言模型架构/) + * [MHA\_MQA\_GQA](/docs/02.大语言模型架构/MHA_MQA_GQA/MHA_MQA_GQA.md "MHA_MQA_GQA") + * [2.3 解码部分](/docs/02.大语言模型架构/) + * [解码策略(Top-k & Top-p & Temperature)]( "解码策略(Top-k & Top-p & Temperature)") + * [2.4 BERT](/docs/02.大语言模型架构/) + * [bert细节](/docs/02.大语言模型架构/bert细节/bert细节.md "bert细节") + * [Transformer架构细节](/docs/02.大语言模型架构/Transformer架构细节/Transformer架构细节.md "Transformer架构细节") + * [bert变种](/docs/02.大语言模型架构/bert变种/bert变种.md "bert变种") + * [2.5 常见大模型](/docs/02.大语言模型架构/) + * [llama系列模型](/docs/02.大语言模型架构/llama系列模型/llama系列模型.md "llama系列模型") + * [chatglm系列模型](/docs/02.大语言模型架构/chatglm系列模型/chatglm系列模型.md "chatglm系列模型") + * [llama 2代码详解]( "llama 2代码详解") + * [llama 3]( "llama 3") + * [2.6 MoE](/docs/02.大语言模型架构/) + * [1.MoE论文](/docs/02.大语言模型架构/1.MoE论文/1.MoE论文.md "1.MoE论文") + * [2.MoE经典论文简牍](/docs/02.大语言模型架构/2.MoE经典论文简牍/2.MoE经典论文简牍.md "2.MoE经典论文简牍") + * [3.LLM MoE :Switch Transformers]( "3.LLM MoE :Switch Transformers") +* [03.训练数据集](/docs/03.训练数据集/) + * [3.1 数据集](/docs/03.训练数据集/) + * [数据格式](/docs/03.训练数据集/数据格式/数据格式.md "数据格式") + * [3.2 模型参数](/docs/03.训练数据集/) +* [04.分布式训练](/docs/04.分布式训练/) + * [4.1 基础知识](/docs/04.分布式训练/) + * [1.概述](/docs/04.分布式训练/1.概述/1.概述.md "1.概述") + * [2.数据并行](/docs/04.分布式训练/2.数据并行/2.数据并行.md "2.数据并行") + * [3.流水线并行](/docs/04.分布式训练/3.流水线并行/3.流水线并行.md "3.流水线并行") + * [4.张量并行](/docs/04.分布式训练/4.张量并行/4.张量并行.md "4.张量并行") + * [5.序列并行](/docs/04.分布式训练/5.序列并行/5.序列并行.md "5.序列并行") + * [6.多维度混合并行](/docs/04.分布式训练/6.多维度混合并行/6.多维度混合并行.md "6.多维度混合并行") + * [7.自动并行](/docs/04.分布式训练/7.自动并行/7.自动并行.md "7.自动并行") + * [8.moe并行](/docs/04.分布式训练/8.moe并行/8.moe并行.md "8.moe并行") + * [9.总结](/docs/04.分布式训练/9.总结/9.总结.md "9.总结") + * [4.2 DeepSpeed](/docs/04.分布式训练/) + * [deepspeed介绍](/docs/04.分布式训练/deepspeed介绍/deepspeed介绍.md "deepspeed介绍") + * [4.3 Megatron](/docs/04.分布式训练/) + * [4.4 训练加速](/docs/04.分布式训练/) + * [4.5 一些有用的文章](/docs/04.分布式训练/) + * [4.6 一些题目](/docs/04.分布式训练/) + * [1.分布式训练题目](/docs/04.分布式训练/分布式训练题目/分布式训练题目.md "分布式训练题目") + * [2.显存问题](/docs/04.分布式训练/1.显存问题/1.显存问题.md "1.显存问题") +* [05.有监督微调](/docs/05.有监督微调/) + * [5.1 理论](/docs/05.有监督微调/) + * [1.基本概念](/docs/05.有监督微调/1.基本概念/1.基本概念.md "1.基本概念") + * [2.prompting](/docs/05.有监督微调/2.prompting/2.prompting.md "2.prompting") + * [3.adapter-tuning](/docs/05.有监督微调/3.adapter-tuning/3.adapter-tuning.md "3.adapter-tuning") + * [4.lora](/docs/05.有监督微调/4.lora/4.lora.md "4.lora") + * [5.总结](/docs/05.有监督微调/5.总结/5.总结.md "5.总结") + * [5.2 微调实战](/docs/05.有监督微调/) + * [llama2微调](/docs/05.有监督微调/llama2微调/llama2微调.md "llama2微调") + * [ChatGLM3微调](/docs/05.有监督微调/ChatGLM3微调/ChatGLM3微调.md "ChatGLM3微调") + * [5.3 一些题目](/docs/05.有监督微调/) + * [1.微调](/docs/05.有监督微调/1.微调/1.微调.md "1.微调") + * [2.预训练](/docs/05.有监督微调/2.预训练/2.预训练.md "2.预训练") +* [06.推理](/docs/06.推理/) + * [6.1 推理框架](/docs/06.推理/) + * [0.llm推理框架简单总结](/docs/06.推理/0.llm推理框架简单总结/0.llm推理框架简单总结.md "0.llm推理框架简单总结") + * [1.vllm](/docs/06.推理/1.vllm/1.vllm.md "1.vllm") + * [2.text_generation\_inference](/docs/06.推理/2.text_generation_inference/2.text_generation_inference.md "2.text_generation_inference") + * [3.faster_transformer](/docs/06.推理/3.faster_transformer/3.faster_transformer.md "3.faster_transformer") + * [4.trt_llm](/docs/06.推理/4.trt_llm/4.trt_llm.md "4.trt_llm") + * [6.2 推理优化技术](/docs/06.推理/) + * [llm推理优化技术](/docs/06.推理/llm推理优化技术/llm推理优化技术.md "llm推理优化技术") + * [6.3 量化](/docs/06.推理/) + * [6.4 vLLM](/docs/06.推理/) + * [6.5 一些题目](/docs/06.推理/) + * [1.推理](/docs/06.推理/1.推理/1.推理.md "1.推理") +* [07.强化学习](/docs/07.强化学习) + * [7.1 强化学习原理](/docs/07.强化学习) + * [策略梯度(pg)](/docs/07.强化学习/策略梯度(pg)/策略梯度(pg).md "策略梯度(pg)") + * [近端策略优化(ppo)](/docs/07.强化学习/近端策略优化(ppo)/近端策略优化(ppo).md "近端策略优化(ppo)") + * [7.2 RLHF](/docs/07.强化学习) + * [大模型RLHF:PPO原理与源码解读](/docs/07.强化学习/大模型RLHF:PPO原理与源码解读/大模型RLHF:PPO原理与源码解读.md "大模型RLHF:PPO原理与源码解读") + * [DPO](/docs/07.强化学习/DPO/DPO.md "DPO") + * [7.3 一些题目](/docs/07.强化学习) + * [1.rlhf相关](/docs/07.强化学习/1.rlhf相关/1.rlhf相关.md "1.rlhf相关") + * [2.强化学习](/docs/07.强化学习/2.强化学习/2.强化学习.md "2.强化学习") +* [08.检索增强RAG](/docs/08.检索增强rag/) + * [8.1 RAG](/docs/08.检索增强rag/) + * [检索增强llm](/docs/08.检索增强rag/检索增强llm/检索增强llm.md "检索增强llm") + * [rag(检索增强生成)技术](/docs/08.检索增强rag/rag(检索增强生成)技术/rag(检索增强生成)技术.md "rag(检索增强生成)技术") + * [8.2 Agent](/docs/08.检索增强rag/) + * [大模型agent技术](/docs/08.检索增强rag/大模型agent技术/大模型agent技术.md "大模型agent技术") +* [09.大语言模型评估](/docs/09.大语言模型评估/) + * [9.1 模型评估](/docs/09.大语言模型评估/) + * [1.评测](/docs/09.大语言模型评估/1.评测/1.评测.md "1.评测") + * [9.2 LLM幻觉](/docs/09.大语言模型评估/) + * [1.大模型幻觉](/docs/09.大语言模型评估/1.大模型幻觉/1.大模型幻觉.md "1.大模型幻觉") + * [2.幻觉来源与缓解](/docs/09.大语言模型评估/2.幻觉来源与缓解/2.幻觉来源与缓解.md "2.幻觉来源与缓解") +* [10.大语言模型应用](/docs/10.大语言模型应用/) + * [10.1 思维链提示](/docs/10.大语言模型应用/) + * [1.思维链(cot)](/docs/10.大语言模型应用/1.思维链(cot)/1.思维链(cot).md "1.思维链(cot)") + * [10.2 LangChain框架](/docs/10.大语言模型应用/) + * [1.langchain](/docs/10.大语言模型应用/1.langchain/1.langchain.md "1.langchain") +* [98.相关课程](/docs/98.相关课程/) +* [99.参考资料](/docs/99.参考资料/) ## 更新记录 +- 2024.05.04 : 使用 docsify 构建在线版本 +- 2024.05.01 : 解码参数,策略 +- 2024.04.15 : BERT细节 - 2024.03.19 : 推理参数 - 2024.03.17 : 强化学习部分,PG,PPO,RLHF,DPO - 2024.03.13 : 强化学习题目 diff --git a/_sidebar.md b/_sidebar.md new file mode 100644 index 0000000..46553cc --- /dev/null +++ b/_sidebar.md @@ -0,0 +1,123 @@ +* [首页](/) +* [真实面试题](/docs/ch1) +* [01.大语言模型基础](/docs/01.大语言模型基础/) + * [1.1 大模型发展历程](/docs/01.大语言模型基础/) + * [1.语言模型](/docs/01.大语言模型基础/1.语言模型/1.语言模型.md "1.语言模型") + * [1.2 分词与词向量]() + * [1.分词](/docs/01.大语言模型基础/1.分词/1.分词.md) + * [2.jieba分词用法及原理](/docs/01.大语言模型基础/2.jieba分词用法及原理/2.jieba分词用法及原理.md) + * [3.词性标注](/docs/01.大语言模型基础/3.词性标注/3.词性标注.md) + * [4.句法分析](/docs/01.大语言模型基础/4.句法分析/4.句法分析.md "4.句法分析") + * [5.词向量](/docs/01.大语言模型基础/5.词向量/5.词向量.md "5.词向量") + * [1.3 语言模型基础知识](/docs/01.大语言模型基础/) + * [Word2Vec](/docs/01.大语言模型基础/Word2Vec/Word2Vec.md "Word2Vec") + * [NLP三大特征抽取器(CNN/RNN/TF)](/docs/01.大语言模型基础/NLP三大特征抽取器(CNN-RNN-TF)/NLP三大特征抽取器(CNN-RNN-TF).md) + * [NLP面试题](/docs/01.大语言模型基础/NLP面试题/NLP面试题.md "NLP面试题") + * [LLM为什么Decoder only架构]( "LLM为什么Decoder only架构") + * [1.4 深度学习](/docs/01.大语言模型基础/) + * [1.激活函数](/docs/01.大语言模型基础/1.激活函数/1.激活函数.md) + * [1.5 一些题目](/docs/01.大语言模型基础/) + * [1.llm概念](/docs/01.大语言模型基础/1.llm概念/1.llm概念.md) +* [02.大语言模型架构](/docs/02.大语言模型架构/) + * [2.1 Transformer模型](/docs/02.大语言模型架构/) + * [1.attention](/docs/02.大语言模型架构/1.attention/1.attention.md "1.attention") + * [2.layer\_normalization](/docs/02.大语言模型架构/2.layer_normalization/2.layer_normalization.md "2.layer_normalization") + * [3.位置编码](/docs/02.大语言模型架构/3.位置编码/3.位置编码.md "3.位置编码") + * [4.tokenize分词](/docs/02.大语言模型架构/4.tokenize分词/4.tokenize分词.md "4.tokenize分词") + * [5.token及模型参数](/docs/02.大语言模型架构/5.token及模型参数/5.token及模型参数.md "5.token及模型参数") + * [6.激活函数](/docs/02.大语言模型架构/6.激活函数/6.激活函数.md "6.激活函数") + * [2.2 注意力](/docs/02.大语言模型架构/) + * [MHA\_MQA\_GQA](/docs/02.大语言模型架构/MHA_MQA_GQA/MHA_MQA_GQA.md "MHA_MQA_GQA") + * [2.3 解码部分](/docs/02.大语言模型架构/) + * [解码策略(Top-k & Top-p & Temperature)]( "解码策略(Top-k & Top-p & Temperature)") + * [2.4 BERT](/docs/02.大语言模型架构/) + * [bert细节](/docs/02.大语言模型架构/bert细节/bert细节.md "bert细节") + * [Transformer架构细节](/docs/02.大语言模型架构/Transformer架构细节/Transformer架构细节.md "Transformer架构细节") + * [bert变种](/docs/02.大语言模型架构/bert变种/bert变种.md "bert变种") + * [2.5 常见大模型](/docs/02.大语言模型架构/) + * [llama系列模型](/docs/02.大语言模型架构/llama系列模型/llama系列模型.md "llama系列模型") + * [chatglm系列模型](/docs/02.大语言模型架构/chatglm系列模型/chatglm系列模型.md "chatglm系列模型") + * [llama 2代码详解]( "llama 2代码详解") + * [llama 3]( "llama 3") + * [2.6 MoE](/docs/02.大语言模型架构/) + * [1.MoE论文](/docs/02.大语言模型架构/1.MoE论文/1.MoE论文.md "1.MoE论文") + * [2.MoE经典论文简牍](/docs/02.大语言模型架构/2.MoE经典论文简牍/2.MoE经典论文简牍.md "2.MoE经典论文简牍") + * [3.LLM MoE :Switch Transformers]( "3.LLM MoE :Switch Transformers") +* [03.训练数据集](/docs/03.训练数据集/) + * [3.1 数据集](/docs/03.训练数据集/) + * [数据格式](/docs/03.训练数据集/数据格式/数据格式.md "数据格式") + * [3.2 模型参数](/docs/03.训练数据集/) +* [04.分布式训练](/docs/04.分布式训练/) + * [4.1 基础知识](/docs/04.分布式训练/) + * [1.概述](/docs/04.分布式训练/1.概述/1.概述.md "1.概述") + * [2.数据并行](/docs/04.分布式训练/2.数据并行/2.数据并行.md "2.数据并行") + * [3.流水线并行](/docs/04.分布式训练/3.流水线并行/3.流水线并行.md "3.流水线并行") + * [4.张量并行](/docs/04.分布式训练/4.张量并行/4.张量并行.md "4.张量并行") + * [5.序列并行](/docs/04.分布式训练/5.序列并行/5.序列并行.md "5.序列并行") + * [6.多维度混合并行](/docs/04.分布式训练/6.多维度混合并行/6.多维度混合并行.md "6.多维度混合并行") + * [7.自动并行](/docs/04.分布式训练/7.自动并行/7.自动并行.md "7.自动并行") + * [8.moe并行](/docs/04.分布式训练/8.moe并行/8.moe并行.md "8.moe并行") + * [9.总结](/docs/04.分布式训练/9.总结/9.总结.md "9.总结") + * [4.2 DeepSpeed](/docs/04.分布式训练/) + * [deepspeed介绍](/docs/04.分布式训练/deepspeed介绍/deepspeed介绍.md "deepspeed介绍") + * [4.3 Megatron](/docs/04.分布式训练/) + * [4.4 训练加速](/docs/04.分布式训练/) + * [4.5 一些有用的文章](/docs/04.分布式训练/) + * [4.6 一些题目](/docs/04.分布式训练/) + * [1.分布式训练题目](/docs/04.分布式训练/分布式训练题目/分布式训练题目.md "分布式训练题目") + * [2.显存问题](/docs/04.分布式训练/1.显存问题/1.显存问题.md "1.显存问题") +* [05.有监督微调](/docs/05.有监督微调/) + * [5.1 理论](/docs/05.有监督微调/) + * [1.基本概念](/docs/05.有监督微调/1.基本概念/1.基本概念.md "1.基本概念") + * [2.prompting](/docs/05.有监督微调/2.prompting/2.prompting.md "2.prompting") + * [3.adapter-tuning](/docs/05.有监督微调/3.adapter-tuning/3.adapter-tuning.md "3.adapter-tuning") + * [4.lora](/docs/05.有监督微调/4.lora/4.lora.md "4.lora") + * [5.总结](/docs/05.有监督微调/5.总结/5.总结.md "5.总结") + * [5.2 微调实战](/docs/05.有监督微调/) + * [llama2微调](/docs/05.有监督微调/llama2微调/llama2微调.md "llama2微调") + * [ChatGLM3微调](/docs/05.有监督微调/ChatGLM3微调/ChatGLM3微调.md "ChatGLM3微调") + * [5.3 一些题目](/docs/05.有监督微调/) + * [1.微调](/docs/05.有监督微调/1.微调/1.微调.md "1.微调") + * [2.预训练](/docs/05.有监督微调/2.预训练/2.预训练.md "2.预训练") +* [06.推理](/docs/06.推理/) + * [6.1 推理框架](/docs/06.推理/) + * [0.llm推理框架简单总结](/docs/06.推理/0.llm推理框架简单总结/0.llm推理框架简单总结.md "0.llm推理框架简单总结") + * [1.vllm](/docs/06.推理/1.vllm/1.vllm.md "1.vllm") + * [2.text_generation\_inference](/docs/06.推理/2.text_generation_inference/2.text_generation_inference.md "2.text_generation_inference") + * [3.faster_transformer](/docs/06.推理/3.faster_transformer/3.faster_transformer.md "3.faster_transformer") + * [4.trt_llm](/docs/06.推理/4.trt_llm/4.trt_llm.md "4.trt_llm") + * [6.2 推理优化技术](/docs/06.推理/) + * [llm推理优化技术](/docs/06.推理/llm推理优化技术/llm推理优化技术.md "llm推理优化技术") + * [6.3 量化](/docs/06.推理/) + * [6.4 vLLM](/docs/06.推理/) + * [6.5 一些题目](/docs/06.推理/) + * [1.推理](/docs/06.推理/1.推理/1.推理.md "1.推理") +* [07.强化学习](/docs/07.强化学习) + * [7.1 强化学习原理](/docs/07.强化学习) + * [策略梯度(pg)](/docs/07.强化学习/策略梯度(pg)/策略梯度(pg).md "策略梯度(pg)") + * [近端策略优化(ppo)](/docs/07.强化学习/近端策略优化(ppo)/近端策略优化(ppo).md "近端策略优化(ppo)") + * [7.2 RLHF](/docs/07.强化学习) + * [大模型RLHF:PPO原理与源码解读](/docs/07.强化学习/大模型RLHF:PPO原理与源码解读/大模型RLHF:PPO原理与源码解读.md "大模型RLHF:PPO原理与源码解读") + * [DPO](/docs/07.强化学习/DPO/DPO.md "DPO") + * [7.3 一些题目](/docs/07.强化学习) + * [1.rlhf相关](/docs/07.强化学习/1.rlhf相关/1.rlhf相关.md "1.rlhf相关") + * [2.强化学习](/docs/07.强化学习/2.强化学习/2.强化学习.md "2.强化学习") +* [08.检索增强RAG](/docs/08.检索增强rag/) + * [8.1 RAG](/docs/08.检索增强rag/) + * [检索增强llm](/docs/08.检索增强rag/检索增强llm/检索增强llm.md "检索增强llm") + * [rag(检索增强生成)技术](/docs/08.检索增强rag/rag(检索增强生成)技术/rag(检索增强生成)技术.md "rag(检索增强生成)技术") + * [8.2 Agent](/docs/08.检索增强rag/) + * [大模型agent技术](/docs/08.检索增强rag/大模型agent技术/大模型agent技术.md "大模型agent技术") +* [09.大语言模型评估](/docs/09.大语言模型评估/) + * [9.1 模型评估](/docs/09.大语言模型评估/) + * [1.评测](/docs/09.大语言模型评估/1.评测/1.评测.md "1.评测") + * [9.2 LLM幻觉](/docs/09.大语言模型评估/) + * [1.大模型幻觉](/docs/09.大语言模型评估/1.大模型幻觉/1.大模型幻觉.md "1.大模型幻觉") + * [2.幻觉来源与缓解](/docs/09.大语言模型评估/2.幻觉来源与缓解/2.幻觉来源与缓解.md "2.幻觉来源与缓解") +* [10.大语言模型应用](/docs/10.大语言模型应用/) + * [10.1 思维链提示](/docs/10.大语言模型应用/) + * [1.思维链(cot)](/docs/10.大语言模型应用/1.思维链(cot)/1.思维链(cot).md "1.思维链(cot)") + * [10.2 LangChain框架](/docs/10.大语言模型应用/) + * [1.langchain](/docs/10.大语言模型应用/1.langchain/1.langchain.md "1.langchain") +* [98.相关课程](/docs/98.相关课程/) +* [99.参考资料](/docs/99.参考资料/) \ No newline at end of file diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.llm\346\246\202\345\277\265/1.llm\346\246\202\345\277\265.md" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.llm\346\246\202\345\277\265/1.llm\346\246\202\345\277\265.md" new file mode 100644 index 0000000..47a77f2 --- /dev/null +++ "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.llm\346\246\202\345\277\265/1.llm\346\246\202\345\277\265.md" @@ -0,0 +1,163 @@ +# 1.llm概念 + +\[toc] + +### 1.目前 主流的开源模型体系 有哪些? + +目前主流的开源LLM(语言模型)模型体系包括以下几个: + +1. **GPT(Generative Pre-trained Transformer)系列**:由OpenAI发布的一系列基于Transformer架构的语言模型,包括GPT、GPT-2、GPT-3等。GPT模型通过在大规模无标签文本上进行预训练,然后在特定任务上进行微调,具有很强的生成能力和语言理解能力。 +2. **BERT(Bidirectional Encoder Representations from Transformers)**:由Google发布的一种基于Transformer架构的双向预训练语言模型。BERT模型通过在大规模无标签文本上进行预训练,然后在下游任务上进行微调,具有强大的语言理解能力和表征能力。 +3. **XLNet**:由CMU和Google Brain发布的一种基于Transformer架构的自回归预训练语言模型。XLNet模型通过自回归方式预训练,可以建模全局依赖关系,具有更好的语言建模能力和生成能力。 +4. **RoBERTa**:由Facebook发布的一种基于Transformer架构的预训练语言模型。RoBERTa模型在BERT的基础上进行了改进,通过更大规模的数据和更长的训练时间,取得了更好的性能。 +5. **T5(Text-to-Text Transfer Transformer)**:由Google发布的一种基于Transformer架构的多任务预训练语言模型。T5模型通过在大规模数据集上进行预训练,可以用于多种自然语言处理任务,如文本分类、机器翻译、问答等。 + +这些模型在自然语言处理领域取得了显著的成果,并被广泛应用于各种任务和应用中。 + +### 2.prefix LM 和 causal LM 区别是什么? + +Prefix LM(前缀语言模型)和Causal LM(因果语言模型)是两种不同类型的语言模型,它们的区别在于生成文本的方式和训练目标。 + +#### 2.1 Prefix LM + +Prefix LM其实是Encoder-Decoder模型的变体,为什么这样说?解释如下: + +1. 在标准的Encoder-Decoder模型中,Encoder和Decoder各自使用一个独立的Transformer +2. 而在Prefix LM,Encoder和Decoder则共享了同一个Transformer结构,在Transformer内部通过Attention Mask机制来实现。 + +与标准Encoder-Decoder类似,**Prefix LM在Encoder部分采用Auto Encoding (AE-自编码)模式,即前缀序列中任意两个token都相互可见,而Decoder部分采用Auto Regressive (AR-自回归)模式,即待生成的token可以看到Encoder侧所有token(包括上下文)和Decoder侧已经生成的token,但不能看未来尚未产生的token**。 + +下面的图很形象地解释了Prefix LM的Attention Mask机制(左)及流转过程(右)。 + +Prefix LM的代表模型有UniLM、T5、GLM(清华滴\~) + +#### 2.2 Causal LM + +Causal LM是因果语言模型,目前流行地大多数模型都是这种结构,别无他因,因为GPT系列模型内部结构就是它,还有开源界的LLaMa也是。 + +Causal LM只涉及到Encoder-Decoder中的Decoder部分,采用Auto Regressive模式,直白地说,就是**根据历史的token来预测下一个token,也是在Attention Mask这里做的手脚**。 + +参照着Prefix LM,可以看下Causal LM的Attention Mask机制(左)及流转过程(右)。 + +![](image/image_ZPQiHay1ZD.png) + +#### 2.3 总结 + +1. **Prefix LM**:前缀语言模型是一种生成模型,它在生成每个词时都可以考虑之前的上下文信息。在生成时,前缀语言模型会根据给定的前缀(即部分文本序列)预测下一个可能的词。这种模型可以用于文本生成、机器翻译等任务。 +2. **Causal LM**:因果语言模型是一种自回归模型,它只能根据之前的文本生成后续的文本,而不能根据后续的文本生成之前的文本。在训练时,因果语言模型的目标是预测下一个词的概率,给定之前的所有词作为上下文。这种模型可以用于文本生成、语言建模等任务。 + +总结来说,前缀语言模型可以根据给定的前缀生成后续的文本,而因果语言模型只能根据之前的文本生成后续的文本。它们的训练目标和生成方式略有不同,适用于不同的任务和应用场景。 + +### 3.大模型LLM的 训练目标 + +大型语言模型(Large Language Models,LLM)的训练目标通常是**最大似然估计(Maximum Likelihood Estimation,MLE)**。最大似然估计是一种统计方法,用于从给定数据中估计概率模型的参数。 + +在LLM的训练过程中,使用的数据通常是大量的文本语料库。训练目标是**最大化模型生成训练数据中观察到的文本序列的概率**。具体来说,对于每个文本序列,模型根据前面的上下文生成下一个词的条件概率分布,并通过最大化生成的词序列的概率来优化模型参数。 + +为了最大化似然函数,可以使用梯度下降等优化算法来更新模型参数,使得模型生成的文本序列的概率逐步提高。在训练过程中,通常会使用批量训练(batch training)的方法,通过每次处理一小批数据样本来进行参数更新。 + +### 4.涌现能力是啥原因? + +[大语言模型的涌现能力:现象与解释 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/621438653 "大语言模型的涌现能力:现象与解释 - 知乎 (zhihu.com)") + +涌现能力(Emergent Ability)是指**模型在训练过程中能够生成出令人惊喜、创造性和新颖的内容或行为**。这种能力使得模型能够超出其训练数据所提供的内容,并产生出具有创造性和独特性的输出。 + +涌现能力的产生可以归因于以下几个原因: + +1. **任务的评价指标不够平滑**:因为很多任务的评价指标不够平滑,导致我们现在看到的涌现现象。如果评价指标要求很严格,要求一字不错才算对,那么Emoji\_movie任务我们就会看到涌现现象的出现。但是,如果我们把问题形式换成多选题,就是给出几个候选答案,让LLM选,那么随着模型不断增大,任务效果在持续稳定变好,但涌现现象消失,如上图图右所示。这说明评价指标不够平滑,起码是一部分任务看到涌现现象的原因。 +2. **复杂任务** **vs** **子任务**:展现出涌现现象的任务有一个共性,就是任务往往是由多个子任务构成的复杂任务。也就是说,最终任务过于复杂,如果仔细分析,可以看出它由多个子任务构成,这时候,子任务效果往往随着模型增大,符合 Scaling Law,而最终任务则体现为涌现现象。 +3. **用** **Grokking** (顿悟)**来解释涌现**:对于某个任务T,尽管我们看到的预训练数据总量是巨大的,但是与T相关的训练数据其实数量很少。当我们推大模型规模的时候,往往会伴随着增加预训练数据的数据量操作,这样,当模型规模达到某个点的时候,与任务T相关的数据量,突然就达到了最小要求临界点,于是我们就看到了这个任务产生了Grokking现象。 + +尽管涌现能力为模型带来了创造性和独特性,但也需要注意其生成的内容可能存在偏差、错误或不完整性。因此,在应用和使用涌现能力强的模型时,需要谨慎评估和验证生成的输出,以确保其质量和准确性。 + +### 5.为何现在的大模型大部分是Decoder only结构 + +1. **Encoder的低秩问题**:Encoder的双向注意力会存在低秩问题,这可能会削弱模型表达能力,就生成任务而言,引入双向注意力并无实质好处。 +2. **更好的Zero-Shot性能、更适合于大语料自监督学习**:decoder-only 模型在没有任何 tuning 数据的情况下、zero-shot 表现最好,而 encoder-decoder 则需要在一定量的标注数据上做 multitask finetuning 才能激发最佳性能。 +3. **效率问题**:decoder-only支持一直复用KV-Cache,对多轮对话更友好,因为每个Token的表示之和它之前的输入有关,而encoder-decoder和PrefixLM就难以做到。 + +### 6.大模型架构介绍 + +Transformer 模型一开始是用来做 seq2seq 任务的,所以它包含 Encoder 和 Decoder 两个部分;他们两者的区别主要是,**Encoder 在抽取序列中某一个词的特征时能够看到整个序列中所有的信息,即上文和下文同时看到**;而 **Decoder 中因为有 mask 机制的存在,使得它在编码某一个词的特征时只能看到自身和它之前的文本信息**。 + +首先概述几种主要的架构: + +- 以BERT为代表的**encoder-only** +- 以T5和BART为代表的**encoder-decoder** +- 以GPT为代表的**decoder-only**, +- 以UNILM9为代表的PrefixLM(相比于GPT只改了attention mask,前缀部分是双向,后面要生成的部分是单向的causal mask%) + +![](image/image_FTjn7ZU5Xf.png) + +### 6.LLMs复读机问题 + +#### 6.1 什么是 LLMs 复读机问题? + +LLMs复读机问题(LLMs Parroting Problem)是指大型语言模型在生成文本时过度依赖输入文本的复制,而缺乏创造性和独特性。当面对一个问题或指令时,模型可能会简单地复制输入文本的一部分或全部内容,并将其作为生成的输出,而不是提供有意义或新颖的回应。 + +#### 6.2 为什么会出现 LLMs 复读机问题? + +1. **数据偏差**:大型语言模型通常是通过预训练阶段使用大规模无标签数据进行训练的。如果训练数据中存在大量的重复文本或者某些特定的句子或短语出现频率较高,模型在生成文本时可能会倾向于复制这些常见的模式。 +2. **训练目标的限制**:大型语言模型的训练通常是基于自监督学习的方法,通过预测下一个词或掩盖词来学习语言模型。这样的训练目标可能使得模型更倾向于生成与输入相似的文本,导致复读机问题的出现。 +3. **缺乏多样性的训练数据**:虽然大型语言模型可以处理大规模的数据,但如果训练数据中缺乏多样性的语言表达和语境,模型可能无法学习到足够的多样性和创造性,导致复读机问题的出现。 +4. **模型结构和参数设置**:大型语言模型的结构和参数设置也可能对复读机问题产生影响。例如,模型的注意力机制和生成策略可能导致模型更倾向于复制输入的文本。 + +#### 6.3 如何缓解 LLMs 复读机问题? + +为了缓解LLMs复读机问题,可以尝试以下方法: + +1. **多样性训练数据**:在训练阶段,使用多样性的语料库来训练模型,避免数据偏差和重复文本的问题。这可以包括从不同领域、不同来源和不同风格的文本中获取数据。 +2. **引入噪声**:在生成文本时,引入一些随机性或噪声,例如通过采样不同的词或短语,或者引入随机的变换操作,以增加生成文本的多样性。这可以通过在生成过程中对模型的输出进行采样或添加随机性来实现。 +3. **温度参数调整**:温度参数是用来控制生成文本的多样性的一个参数。通过调整温度参数的值,可以控制生成文本的独创性和多样性。较高的温度值会增加随机性,从而减少复读机问题的出现。 +4. **Beam搜索调整**:在生成文本时,可以调整Beam搜索算法的参数。Beam搜索是一种常用的生成策略,它在生成过程中维护了一个候选序列的集合。通过调整Beam大小和搜索宽度,可以控制生成文本的多样性和创造性。 +5. **后处理和过滤**:对生成的文本进行后处理和过滤,去除重复的句子或短语,以提高生成文本的质量和多样性。可以使用文本相似度计算方法或规则来检测和去除重复的文本。 +6. **人工干预和控制**:对于关键任务或敏感场景,可以引入人工干预和控制机制,对生成的文本进行审查和筛选,确保生成结果的准确性和多样性。 + +需要注意的是,缓解LLMs复读机问题是一个复杂的任务,没有一种通用的解决方案。不同的方法可能适用于不同的场景和任务,需要根据具体情况进行选择和调整。此外,解决复读机问题还需要综合考虑数据、训练目标、模型架构和生成策略等多个因素,需要进一步的研究和实践来提高大型语言模型的生成文本多样性和创造性。 + +### 7.LLMs输入句子长度理论上可以无限长吗? + +**理论上来说,LLMs(大型语言模型)可以处理任意长度的输入句子,但实际上存在一些限制和挑战**。下面是一些相关的考虑因素: + +1. **计算资源**:生成长句子需要更多的计算资源,包括内存和计算时间。由于LLMs通常是基于神经网络的模型,计算长句子可能会导致内存不足或计算时间过长的问题。 +2. **模型训练和推理**:训练和推理长句子可能会面临一些挑战。在训练阶段,处理长句子可能会导致梯度消失或梯度爆炸的问题,影响模型的收敛性和训练效果。在推理阶段,生成长句子可能会增加模型的错误率和生成时间。 +3. **上下文建模**:LLMs是基于上下文建模的模型,长句子的上下文可能会更加复杂和深层。模型需要能够捕捉长句子中的语义和语法结构,以生成准确和连贯的文本。 + +### 8.什么情况用Bert模型,什么情况用LLaMA、ChatGLM类大模型,咋选? + +选择使用哪种大模型,如Bert、LLaMA或ChatGLM,取决于具体的应用场景和需求。下面是一些指导原则: + +1. **Bert模型**:Bert是一种预训练的语言模型,**适用于各种自然语言处理任务**,如文本分类、命名实体识别、语义相似度计算等。如果你的任务是通用的文本处理任务,而不依赖于特定领域的知识或语言风格,Bert模型通常是一个不错的选择。Bert由一个Transformer编码器组成,更适合于NLU相关的任务。 +2. **LLaMA模型**:LLaMA(Large Language Model Meta AI)包含从 7B 到 65B 的参数范围,训练使用多达14,000亿tokens语料,具有常识推理、问答、数学推理、代码生成、语言理解等能力。LLaMA由一个Transformer解码器组成。训练预料主要为以英语为主的拉丁语系,不包含中日韩文。所以适合于英文文本生成的任务。 +3. **ChatGLM模型**:ChatGLM是一个面向对话生成的语言模型,适用于构建聊天机器人、智能客服等对话系统。如果你的应用场景需要模型能够生成连贯、流畅的对话回复,并且需要处理对话上下文、生成多轮对话等,ChatGLM模型可能是一个较好的选择。ChatGLM的架构为Prefix decoder,训练语料为中英双语,中英文比例为1:1。所以适合于中文和英文文本生成的任务。 + +在选择模型时,还需要考虑以下因素: + +- 数据可用性:不同模型可能需要不同类型和规模的数据进行训练。确保你有足够的数据来训练和微调所选择的模型。 +- 计算资源:大模型通常需要更多的计算资源和存储空间。确保你有足够的硬件资源来支持所选择的模型的训练和推理。 +- 预训练和微调:大模型通常需要进行预训练和微调才能适应特定任务和领域。了解所选择模型的预训练和微调过程,并确保你有相应的数据和时间来完成这些步骤。 + +最佳选择取决于具体的应用需求和限制条件。在做出决策之前,建议先进行一些实验和评估,以确定哪种模型最适合你的应用场景。 + +### 9.各个专业领域是否需要各自的大模型来服务? + +各个专业领域通常需要各自的大模型来服务,原因如下: + +1. **领域特定知识**:不同领域拥有各自特定的知识和术语,需要针对该领域进行训练的大模型才能更好地理解和处理相关文本。例如,在医学领域,需要训练具有医学知识的大模型,以更准确地理解和生成医学文本。 +2. **语言风格和惯用语**:各个领域通常有自己独特的语言风格和惯用语,这些特点对于模型的训练和生成都很重要。专门针对某个领域进行训练的大模型可以更好地掌握该领域的语言特点,生成更符合该领域要求的文本。 +3. **领域需求的差异**:不同领域对于文本处理的需求也有所差异。例如,金融领域可能更关注数字和统计数据的处理,而法律领域可能更关注法律条款和案例的解析。因此,为了更好地满足不同领域的需求,需要专门针对各个领域进行训练的大模型。 +4. **数据稀缺性**:某些领域的数据可能相对较少,无法充分训练通用的大模型。针对特定领域进行训练的大模型可以更好地利用该领域的数据,提高模型的性能和效果。 + +尽管需要各自的大模型来服务不同领域,但也可以共享一些通用的模型和技术。例如,通用的大模型可以用于处理通用的文本任务,而领域特定的模型可以在通用模型的基础上进行微调和定制,以适应特定领域的需求。这样可以在满足领域需求的同时,减少模型的重复训练和资源消耗。 + +### 10.如何让大模型处理更长的文本? + +要让大模型处理更长的文本,可以考虑以下几个方法: + +1. **分块处理**:将长文本分割成较短的片段,然后逐个片段输入模型进行处理。这样可以避免长文本对模型内存和计算资源的压力。在处理分块文本时,可以使用重叠的方式,即将相邻片段的一部分重叠,以保持上下文的连贯性。 +2. **层次建模**:通过引入层次结构,将长文本划分为更小的单元。例如,可以将文本分为段落、句子或子句等层次,然后逐层输入模型进行处理。这样可以减少每个单元的长度,提高模型处理长文本的能力。 +3. **部分生成**:如果只需要模型生成文本的一部分,而不是整个文本,可以只输入部分文本作为上下文,然后让模型生成所需的部分。例如,输入前一部分文本,让模型生成后续的内容。 +4. **注意力机制**:注意力机制可以帮助模型关注输入中的重要部分,可以用于处理长文本时的上下文建模。通过引入注意力机制,模型可以更好地捕捉长文本中的关键信息。 +5. **模型结构优化**:通过优化模型结构和参数设置,可以提高模型处理长文本的能力。例如,可以增加模型的层数或参数量,以增加模型的表达能力。还可以使用更高效的模型架构,如Transformer等,以提高长文本的处理效率。 + +需要注意的是,处理长文本时还需考虑计算资源和时间的限制。较长的文本可能需要更多的内存和计算时间,因此在实际应用中需要根据具体情况进行权衡和调整。 diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/1.llm\346\246\202\345\277\265/image/image_KoG36YaWZ7.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.llm\346\246\202\345\277\265/image/image_FTjn7ZU5Xf.png" similarity index 100% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/1.llm\346\246\202\345\277\265/image/image_KoG36YaWZ7.png" rename to "docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.llm\346\246\202\345\277\265/image/image_FTjn7ZU5Xf.png" diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/1.llm\346\246\202\345\277\265/image/image_kIdEv4PBrq.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.llm\346\246\202\345\277\265/image/image_ZPQiHay1ZD.png" similarity index 100% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/1.llm\346\246\202\345\277\265/image/image_kIdEv4PBrq.png" rename to "docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.llm\346\246\202\345\277\265/image/image_ZPQiHay1ZD.png" diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\345\210\206\350\257\215/1.\345\210\206\350\257\215.md" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\345\210\206\350\257\215/1.\345\210\206\350\257\215.md" new file mode 100644 index 0000000..c512203 --- /dev/null +++ "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\345\210\206\350\257\215/1.\345\210\206\350\257\215.md" @@ -0,0 +1,84 @@ +# 1.分词 + +## **1.概述** + +分词是自然语言处理的基础,分词准确度直接决定了后面的词性标注、句法分析、词向量以及文本分析的质量。**英文语句使用空格将单词进行分隔**,除了某些特定词,如how many,New York等外,大部分情况下不需要考虑分词问题。但**中文不同,天然缺少分隔符**,需要读者自行分词和断句。故在做中文自然语言处理时,需要先进行分词。 + +## **2.中文分词难点** + +中文分词不像英文那样,天然有空格作为分隔。而且中文词语组合繁多,分词很容易产生歧义。因此中文分词一直以来都是NLP的一个重点,也是一个难点。难点主要集中在**分词标准,切分歧义和未登录词**三部分。 + +### 2.1 **分词标准** + +比如人名,有的算法认为姓和名应该分开,有的认为不应该分开。这需要制定一个相对统一的标准。又例如“花草”,有的人认为是一个词,有的人认为应该划分开为两个词“花/草”。某种意义上,**中文分词可以说是一个没有明确定义的问题**。 + +### 2.2 **切分歧义** + +不同的切分结果会有不同的含义,这又包含如下几种情况 + +1. **组合型歧义**:分词粒度不同导致的不同切分结果。比如“中华人民共和国”,粗粒度的分词结果为“中华人民共和国”,细粒度的分词结果为“中华/人民/共和国”。这种问题需要根据使用场景来选择。在文本分类,情感分析等文本分析场景下,粗粒度划分较好。而在搜索引擎场景下,为了保证recall,细粒度的划分则较好。jieba分词可以根据用户选择的模式,输出粗粒度或者细粒度的分词结果,十分灵活。 另外,有时候汉字串AB中,AB A B可以同时成词,这个时候也容易产生组合型歧义。比如“他/将/来/网商银行”,“他/将来/想/应聘/网商银行”。这需要通过整句话来区分。 组合型歧义描述的是AB A B均可以同时成词的汉字串,它是可以预测的,故也有专家称之为“固有型歧义” +2. **交集型歧义**:不同切分结果共用相同的字,前后组合的不同导致不同的切分结果。比如“商务处女干事”,可以划分为“商务处/女干事”,也可以划分为“商务/处女/干事”。这也需要通过整句话来区分。交集型歧义前后组合,变化很多,难以预测,故也有专家称之为“偶发型歧义”。 +3. **真歧义**:本身语法或语义没有问题,即使人工切分也会产生歧义。比如“下雨天留客天天留人不留”,可以划分为“下雨天/留客天/天留/人不留”,也可以划分为“下雨天/留客天/天留人不/留”。此时通过整句话还没法切分,只能通过上下文语境来进行切分。如果是不想留客,则切分为前一个。否则切分为后一个。 + +有专家统计过,中文文本中的切分歧义出现频次为1.2次/100汉字,其中交集型歧义和组合型歧义占比为12:1。而对于真歧义,一般出现的概率不大。 + +### 2.3 **未登录词** + +也叫新词发现,或者生词,未被词典收录的词。未登录词分为如下几种类型 + +1. 新出现的词汇,比如一些网络热词,如“超女”“给力”等 +2. 专有名词,主要是人名 地名 组织机构,比如“南苏丹”“特朗普” “花呗”“借呗”等。 +3. 专业名词和研究领域词语,比如“苏丹红” “禽流感” +4. 其他专有名词,比如新出现的电影名、产品名、书籍名等。 + +**未登录词对于分词精度的影响远远超过歧义切分**。**未登录词识别难度也很大**,主要原因有 + +1. 未登录词增长速度往往比词典更新速度快很多,因此很难利用更新词典的方式解决未登录词问题。不过词典越大越全,分词精度也会越高。因此一个大而全的词典还是相当重要的。 +2. 未登录词都是由普通词汇构成,长度不定,也没有明显的边界标志词 +3. 未登录词还有可能与上下文中的其他词汇构成交集型歧义。 +4. 未登录词中还有可能夹杂着英语字母等其他符号,这也带来了很大难度。比如“e租宝”。 + +对于词典中不包含的未登录词,无法基于字符串匹配来进行识别。此时**基于统计的分词算法就可以大显身手了**,**jieba分词采用了HMM隐马尔科夫模型和viterbi算法来解决未登录词问题**。下一篇文章我们会详细分析这个算法过程。 + +## **3.中文分词算法** + +当前的分词算法主要分为两类,**基于词典的规则匹配方法**,和**基于统计的机器学习方法**。 + +### **3.1 基于词典的分词算法** + +基于词典的分词算法,本质上就是**字符串匹配**。将待匹配的字符串基于一定的算法策略,和一个足够大的词典进行字符串匹配,如果匹配命中,则可以分词。根据不同的匹配策略,又分为**正向最大匹配法,逆向最大匹配法,双向匹配分词,全切分路径选择**等。 + +**最大匹配法**主要分为三种: + +1. **正向最大匹配法**,从左到右对语句进行匹配,匹配的词越长越好。比如“商务处女干事”,划分为“商务处/女干事”,而不是“商务/处女/干事”。这种方式切分会有歧义问题出现,比如“结婚和尚未结婚的同事”,会被划分为“结婚/和尚/未/结婚/的/同事”。 +2. **逆向最大匹配法**,从右到左对语句进行匹配,同样也是匹配的词越长越好。比如“他从东经过我家”,划分为“他/从/东/经过/我家”。这种方式同样也会有歧义问题,比如“他们昨日本应该回来”,会被划分为“他们/昨/日本/应该/回来”。 +3. **双向匹配分词**,则同时采用正向最大匹配和逆向最大匹配,选择二者分词结果中**词数较少者**。但这种方式同样会产生歧义问题,比如“他将来上海”,会被划分为“他/将来/上海”。由此可见,词数少也不一定划分就正确。 + +**全切分路径选择**,将所有可能的切分结果全部列出来,从中选择最佳的切分路径。分为两种选择方法 + +1. **n最短路径方法**。将所有的切分结果组成有向无环图,切词结果作为节点,词和词之间的边赋予权重,找到权重和最小的路径即为最终结果。比如可以通过词频作为权重,找到一条总词频最大的路径即可认为是最佳路径。 +2. **n元语法模型**。同样采用n最短路径,只不过路径构成时会考虑词的上下文关系。一元表示考虑词的前后一个词,二元则表示考虑词的前后两个词。然后根据语料库的统计结果,找到概率最大的路径。 + +### **3.2 基于统计的分词算法** + +基于统计的分词算法,本质上是一个序列标注问题。将语句中的字,**按照他们在词中的位置进行标注**。标注主要有:B(词开始的一个字),E(词最后一个字),M(词中间的字,可能多个),S(一个字表示的词)。例如“网商银行是蚂蚁金服微贷事业部的最重要产品”,标注后结果为“BMMESBMMEBMMMESBMEBE”,对应的分词结果为“网商银行/是/蚂蚁金服/微贷事业部/的/最重要/产品”。 + +基于统计分析方法,得到序列标注结果,就可以得到分词结果了。这类算法基于机器学习或者现在火热的深度学习,主要有HMM,CRF,SVM,以及深度学习等。 + +1. **HMM,隐马尔科夫模型**。隐马尔科夫模型在机器学习中应用十分广泛,它包含观测序列和隐藏序列两部分。对应到NLP中,语句是观测序列,而序列标注结果是隐藏序列。任何一个HMM都可以由一个五元组来描述:观测序列,隐藏序列,隐藏态起始概率,隐藏态之间转换概率(转移概率),隐藏态表现为观测值的概率(发射概率)。其中起始概率,转移概率和发射概率可以通过大规模语料统计来得到。从隐藏态初始状态出发,计算下一个隐藏态的概率,并依次计算后面所有的隐藏态转移概率。序列标注问题就转化为了求解概率最大的隐藏状态序列问题。**jieba分词中使用HMM模型来处理未登录词**问题,并利用viterbi算法来计算观测序列(语句)最可能的隐藏序列(BEMS标注序列)。 +2. **CRF,条件随机场**。也可以描述输入序列和输出序列之间关系。只不过它是基于条件概率来描述模型的。详细的这儿就不展开了。 +3. **深度学习**。将语句作为输入,分词结果作为标注,可以进行有监督学习。训练生成模型,从而对未知语句进行预测。 + +## **4.分词质量和性能** + +中文分词对于自然语言处理至关重要,评价一个分词引擎性能的指标主要有分词准确度和分词速度两方面。分词准确度直接影响后续的词性标注,句法分析,文本分析等环节。分词速度则对自然语言处理的实时性影响很大。下图为几种常用分词引擎在准确度和速度方面的对比。 + +![](image/image_O2BQbdaBYT.png) + +![](image/image_2z7QdbWnX2.png) + +由上可见,想要做准确度很高的通用型分词引擎是多么的困难。如果对准确度要求很高,可以尝试开发特定领域的分词引擎。比如专门针对金融领域。同时从图中可见,作为一款开源的通用型分词引擎,jieba分词的准确度和速度都还是不错的。后面会详细讲解jieba分词的用法及其原理。 + +## **5.总结** + +中文分词是中文自然语言处理中的一个重要环节,为后面的词向量编码,词性标注,句法分析以及文本分析打下了坚实的基础。同时,由于中文缺少空格等分隔符,并且汉字间的组合特别多,很容易产生歧义,这些都加大了中文分词的难度。基于词典的字符串匹配算法和基于统计的分词算法,二者各有优缺点,我们可以考虑结合使用。随着深度学习的兴起,我们可以考虑利用深度学习来进行序列标注和中文分词。 diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\345\210\206\350\257\215/image/image_2z7QdbWnX2.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\345\210\206\350\257\215/image/image_2z7QdbWnX2.png" new file mode 100644 index 0000000..60dd34e Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\345\210\206\350\257\215/image/image_2z7QdbWnX2.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\345\210\206\350\257\215/image/image_O2BQbdaBYT.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\345\210\206\350\257\215/image/image_O2BQbdaBYT.png" new file mode 100644 index 0000000..5b41dbd Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\345\210\206\350\257\215/image/image_O2BQbdaBYT.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/1.\346\277\200\346\264\273\345\207\275\346\225\260.md" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/1.\346\277\200\346\264\273\345\207\275\346\225\260.md" new file mode 100644 index 0000000..1201205 --- /dev/null +++ "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/1.\346\277\200\346\264\273\345\207\275\346\225\260.md" @@ -0,0 +1,291 @@ +# 1.激活函数 + +### 1.激活函数作用 + +神经网络是线性的,无法解决非线性的问题,加入激活函数就是给模型引入非线性能力; + +不同的激活函数,特点和作用不同: + +- `Sigmoid`和`tanh`的特点是将输出限制在`(0,1)`和`(-1,1)`之间,说明`Sigmoid`和`tanh`适合做概率值的处理,例如LSTM中的各种门;而`ReLU`就不行,因为`ReLU`无最大值限制,可能会出现很大值。 +- `ReLU`适合用于深层网络的训练,而`Sigmoid`和`tanh`则不行,因为它们会出现梯度消失。 + +### 2.梯度爆炸和梯度消失 + +模型中的梯度爆炸和梯度消失问题: + +1. 激活函数导致的梯度消失,像 `sigmoid `和 `tanh` 都会导致梯度消失; +2. 矩阵连乘也会导致梯度消失,这个原因导致的梯度消失无法通过更换激活函数来避免。直观的说就是在反向传播时,梯度会连乘,当梯度都小于1.0时,就会出现梯度消失;当梯度都大于1.0时,就会出现梯度爆炸。 + +如何解决梯度爆炸和梯度消失问题: + +1. 上述第一个问题只需要使用像 ReLU 这种激活函数就可以解决; +2. 上述第二个问题没有能够完全解决的方法,目前有一些方法可以很大程度上进行缓解该问题,比如:对梯度做截断解决梯度爆炸问题、残差连接、normalize。由于使用了残差连接和 normalize 之后梯度消失和梯度爆炸已经极少出现了,所以目前可以认为该问题已经解决了。 + +### 3.Sigmoid + +Sigmoid函数公式: + +$$ +\sigma(z)=\frac{1}{1+e^{-z}} +$$ + +导数公式: + +$$ +\sigma^{\prime}(z)=\sigma(z)(1-\sigma(z)) +$$ + +![](image/image_6zR9l2rasJ.png) + +优点: + +- 平滑,易于求导; +- 取值范围是`(0, 1)`,可直接用于求概率值的问题或者分类问题;比如 LSTM 中的门,二分类或者多标签分类问题; + +缺点: + +- **计算量大**,包含幂运算,以及除法运算; +- sigmoid 导数的取值范围是 `[0, 0.25]`,最大值都是小于 1 的,反向传播时又是"链式传导",**经过几次相乘之后很容易就会出现梯度消失的问题**; +- **sigmoid 的输出的均值不是0**(即zero-centered),这会导致当前层接收到上一层的非0均值的信号作为输入,随着网络的加深,会改变数据的原始分布; + +### 4.Tanh + +Tanh的函数公式为: + +$$ +\begin{aligned} \tanh (z) & =\frac{e^{z}-e^{-z}}{e^{z}+e^{-z}} \\ & =\frac{2}{1+e^{-2 z}}-1\end{aligned} +$$ + +> 从上述公式的第二行可以看出,tanh 函数可以由 sigmoid 函数经过平移和拉伸得到。tanh 函数的取值范围是`(-1, 1)`。 + +导数公式 + +$$ +\tanh (x)^{\prime}=\frac{\left(e^{x}+e^{-x}\right)^{2}-\left(e^{x}-e^{-x}\right)^{2}}{\left(e^{x}+e^{-x}\right)^{2}}=1-(\tanh (x))^{2} +$$ + +![](image/image_UBkA2B4TXM.png) + +tanh 函数可以理解为是**基于 sigmoid 函数的一种改进的激活函数**,所以对于 sigmoid 函数的缺点,它能够解决一部分。但是 tanh 函数依然有着不少的缺点。tanh 函数的特点如下: + +- 它的输出范围是`(-1, 1)`,解决了 sigmoid 函数输出的均值不是0(zero-centered)的问题; +- tanh 的导数取值范围是`(0, 1)`,可以看出其在反向传播的"链式传导"过程中的梯度消失问题要比 sigmoid 函数要好一些,但是其依然存在着梯度消失问题; +- **幂运算依然存在,计算量比较大**; + +### 5.ReLU系列 + +#### 5.1 ReLU + +`ReLU `全称为 Rectified Linear Unit,即修正线性单元函数。该函数的公式比较简单,相应的公式和图像如下表所示。 + +![](image/image_QNh8iUWMvD.png) + +相比于 `sigmoid`、`tanh `这两个激活函数,`ReLU `激活函数的优缺点如下: + +- 当 `z>0` 时,ReLU 激活函数的导数恒为常数1,这就避免了 sigmoid 和 tanh 会在神经网络层数比较深的时候出现的梯度消失的问题; +- 计算复杂度低,不再含有幂运算,只需要一个阈值就能够得到其导数; +- 经过实际实验发现,**使用 ReLU 作为激活函数,模型收敛的速度比 sigmoid 和 tanh 快**; +- 当 `z<0`时,ReLU 激活函数的导数恒为常数0,这既带来了一些有利的方面,也导致了一些坏的方面,分别进行描述。 + - 有利的方面:在深度学习中,目标是从大量数据中学习到关键特征,也就是把密集矩阵转化为稀疏矩阵,保留数据的关键信息,去除噪音,这样的模型就有了鲁棒性。ReLU 激活函数中将 `z<0`的部分置为0,就是产生稀疏矩阵的过程。 + - 坏的方面:将 `z<0`的部分梯度直接置为0会导致 Dead ReLU Problem(神经元坏死现象)。**可能会导致部分神经元不再对输入数据做响应,无论输入什么数据,该部分神经元的参数都不会被更新**。(这个问题是一个非常严重的问题,后续不少工作都是在解决这个问题) +- ReLU 有可能会导致梯度爆炸问题,解决方法是梯度截断; +- ReLU 的输出不是 0 均值的,这个和 sigmoid 类似。(后续的优化工作 ELU 在该问题上解决的比较好,ELU 的输出是近似为0的) + +#### 5.2 Leaky ReLU + +为了解决 ReLU 的 Dead ReLU 问题,提出了 渗漏整流线性单元(Leaky ReLU),该方法是 ReLU 的一个变体。其在`z>0`的部分与ReLU一样保持不变;在`z<0`的部分,采用一个非常小的斜率0.01,其公式如下: + +$$ +Leaky \operatorname{ReLU}(z)=\left\{\begin{array}{ll}0.01 z & \text { if } z \leqslant 0 \\ z & \text { if } z>0\end{array}\right. +$$ + +其图像如下所示: + +![](image/image_Q2b0vDHio-.png) + +该方法是 ReLU 的一个变体,能够在一定程度上解决 Dead ReLU 问题,但是该方法的缺点是**效果并不稳定**,所以实际实验中使用该方法的并不多。 + +#### 5.3 PReLU, RReLU + +PReLU 的全称为 Parametric Relu;PReLU 的全称为 Random ReLU。 + +这两个方法和 Leaky ReLU 类似,都是 ReLU 的变体。也都是为了解决 Dead ReLU 问题而提出来的。 + +Leaky ReLU 是在`z<0`时,设置了一个较小的常数0.01作为斜率。由于这种常数值的斜率并不好,所以 PReLU 提出了可学习的斜率,RReLU 提出了随机的斜率,两者具体的公式如下。 + +PReLU的公式如下,这里的$\alpha$是可学习的: + +$$ +\operatorname{PReLU}(z)=\left\{\begin{array}{ll}\alpha \cdot z & \text { if } z \leqslant 0 \\ z & \text { if } z>0\end{array}\right. +$$ + +RReLU 的公式如下,这里的 $\alpha$是从一个高斯分布中随机产生的,在训练过程中每次这个 $\alpha$ 都是不相同的;在推理时会将这个$\alpha$都是不相同的;在推理时会将这个 + +$$ +\operatorname{RReLU}(z)=\left\{\begin{array}{ll}\alpha \cdot z & \text { if } z \leqslant 0 \\ z & \text { if } z>0\end{array}\right. +$$ + +PReLU 和 RReLU 的图像如下所示: + +![](image/image_pTCgmAW5XL.png) + +#### 5.4 ELU(指数线性单元) + +ELU 的提出也解决了 ReLU 的问题。与 ReLU 相比,ELU 有负值,这会使激活的平均值接近零,让模型学习得更快。 + +![](image/image_AlZPXN0gs1.png) + +$$ +\mathrm{g}(x)=\operatorname{ELU}(x)=\left\{\begin{aligned} x, & x>0 \\ \alpha\left(\mathrm{e}^{x}-1\right), & x \leqslant 0\end{aligned}\right. +$$ + +其中 $\alpha$不是固定的,是通过反向传播学习出来的。ELU的一个小问题是需要exp计算,运算量会更大一些。 + +- 融合了sigmoid和ReLU,左侧具有软饱和性,右侧无饱和性。 +- 右侧线性部分使得ELU能够缓解梯度消失,而左侧软饱能够让ELU对输入变化或噪声更鲁棒。 +- ELU的输出均值接近于零,所以收敛速度更快。 + +### 6.GeLU + +> 出自2016年的论文《Gaussian Error Linear Units (GELUs)》 + +先描述一下 GELU 这个激活函数直觉上是基于一个什么思路设计出来的。然后再具体看其如何近似求解、如何代码实现。 + +#### 6.1 介绍 + +先看一下 ReLU 激活函数是怎样做的,该函数中包含两种映射:一个是恒等映射(identity mapping),当输入值大于零时就是恒等映射;一个是置零映射(zero mapping),当输入值小于等于零时就是置零映射。 + +参考 ReLU 激活函数,设计另外一个包含恒等映射和置零映射的激活函数,并且参考 ReLU 函数来看,新激活函数应该有如下性质: + +1. 在输入 `x` 满足某些条件时,为恒等映射; +2. 在输入 `x` 满足另外一些条件时,为置零映射; +3. 在输入 `x` 是一个较大的正值时,更希望为恒等映射;在输入 `x` 为一个较小的负值时,更希望是一个置零映射; + +以上就是想要新设计的激活函数的性质。 + +下面的图7和图8是标准正态分布的概率密度函数和累积分布函数的图像。接下来根据下图8中的累积分布函数设计一个新的函数。 + +符号定义:输入值用 $x$ 表示,$ϕ(⋅)$表示下图8中的正态分布的累积分布函数,$f(⋅)$表示新设计的函数。 + +设计的新函数:给定输入值 $x$,函数 $f(x)$的输出值以 $ϕ(x)$的概率采用恒等映射,以 $1−ϕ(x)$的概率采用置零映射。也就是下述公式: + +$$ +\begin{aligned} f(x) & =x \cdot \phi(x)+0 \cdot(1-\phi(x)) \\ & =x \cdot \phi(x)\end{aligned} +$$ + +然后看一下,新设计的这个公式是否满足上述的激活函数性质。前两条是肯定满足的,主要看一下第3条性质: + +- 当输入 $x$ 是一个较大的正值时,从图8中可以看出 $ϕ(x)$的函数图像逐渐趋近于1,由于函数 $f(x)$的输出值以 $ϕ(x)$的概率采用恒等映射,所以有接近于1的概率采用恒等映射; +- 当输入 $x$ 是一个较小的负值时,$ϕ(x)$趋近于0,由于函数 $f(x)$以 $1−ϕ(x)$的概率采用置零映射,所以有接近于1的概率采用置零映射; + +可以看出新设计的这个函数是满足上述激活函数的性质的。 + +为了更直观描述设计该函数时的直觉,上述都是采用图8进行描述的,上述公式如果使用图7中的概率密度函数就是如下形式: + +$$ +\begin{aligned} f(x) & =x \cdot p(X 这里描述的设计 GELU 函数的直觉思路是非常简化的版本,只是为了易于理解。实际在设计这个函数时还需要考虑更多的因素,比如该函数的那几条性质和 ReLU 很像,已经有了 ReLU 为什么还要设计这个函数,这个函数在理论上是否能够解决 ReLU 的存在的 Dead ReLU 等问题; + +#### 6.2 函数及导数 + +GeLU 公式为: + +$$ +G E L U=x \cdot \phi(x) +$$ + +使用该函数作为激活函数时,需要求解其导数。对其求导可得: + +$$ +\begin{aligned} \frac{d}{d x} G E L U & =\phi(x)+x \frac{d}{d x} \phi(x) \\ & =\phi(x)+x \cdot p(X=x)\end{aligned} +$$ + +其中$X$是随机变量,$p(X=x)$是图7中的标准正态分布概率密度函数中,随机变量取值为$x$时的值。 + +GELU 函数及其导数的图像如下所示。可以看出其函数图像和 ReLU 非常相似,其导数图像也和 ReLU 的导数图像非常相似,不过该图像是连续的。 + +![](image/image_d4oXH2wHCZ.png) + +GELU 激活函数的优缺点: + +- 从其函数图像可以看出,在负值区域,不再全为0,这解决了 Dead ReLU 问题; +- GELU 函数是处处连续、光滑可导的; + +#### 6.3 精确计算 + +对于 GeLU 的加速计算有两种方法。 + +第一种方法是精确求解。有一个函数为 Gauss Error function (gef),由于使用率非常高所以在常见的库(比如TensorFlow、PyTorch)中都有针对该函数的优化,该函数的公式如下。 + +$$ +\operatorname{erf}(y)=\frac{2}{\sqrt{\pi}} \int_{0}^{y} e^{-t^{2}} d t +$$ + +所以如果能够先求解出$erf(\cdot)$,再由该函数求解出 $\phi(x)$,那么可以加快计算。下面省略具体的推导过程,直接给出计算公式: + +$$ +\phi(x)=\frac{1+\operatorname{erf}\left(\frac{x}{\sqrt{2}}\right)}{2} +$$ + +另一种方法是不精确求解,而是求解其近似值。为了加速计算,还可以使用近似计算的方式。GELU 的近似公式如下所示: + +$$ +G E L U=0.5 * x\left(1+\tanh \left[\sqrt{\frac{2}{\pi}}\left(x+0.044715 x^{3}\right)\right]\right) +$$ + +### 7.Swish + +> 出自2017年的论文《Searching for Activation Functions》 + +该激活函数的公式为: + +$$ +f(x)=x \cdot \sigma(x) +$$ + +Swish导数: + +$$ +\begin{array}{l}f^{\prime}(x) \\ =\sigma(x)+x \cdot \sigma(x) \cdot(1-\sigma(x)) \\ =x \cdot \sigma(x)+\sigma(x)(1-x \cdot \sigma(x)) \\ =f(x)+\sigma(x) \cdot(1-f(x))\end{array} +$$ + +该激活函数的图像为: + +![](image/image_b8KrMUlxex.png) + +Swish特点: + +- 和ReLU一样,没有上边界,因此不会出现梯度饱和现象 +- 有下边界,可以产生更强的正则化效果(x左半轴慢慢趋近于0) +- 非单调 +- 处处连续且可到,更容易训练 + +关于正则化效果:x轴越靠近左半轴,纵坐标的值越小,甚至接近于0,如果x值是-10,那么经过激活之后的值接近于0,那么就可以一定程度上过滤掉一部分信息,起到[正则化](https://so.csdn.net/so/search?q=正则化\&spm=1001.2101.3001.7020 "正则化")的效果。 + +### 8.GLU + +PaLM 和 LLaMA 中都使用 SwiGLU 替换了 FFN + +> 出自2017年的论文 [Language Modeling with Gated Convolutional Networks](https://arxiv.org/pdf/1612.08083.pdf "Language Modeling with Gated Convolutional Networks") + +GLU 全称为 Gated Linear Unit,即**门控线性单元函数**。 + +参考ReLU激活函数,激活函数GLU的公式为如下公式的形式 + +$$ +\operatorname{GLU}(x)=x \otimes \sigma(g(x)) +$$ + +这里有一个新符号 $g(x)$表示的是向量$x$经过一层MLP或者卷积,$⊗$表示两个向量逐元素相乘,$σ$ 表示sigmoid函数。 + +当$\sigma(g(x))$趋近于0时表示对$x$进行阻断,当$\sigma(g(x))$趋近于1时表示允许$x$通过,以此实现门控激活函数的效果。 diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_6zR9l2rasJ.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_6zR9l2rasJ.png" new file mode 100644 index 0000000..8d1919d Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_6zR9l2rasJ.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_AlZPXN0gs1.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_AlZPXN0gs1.png" new file mode 100644 index 0000000..acf3f9e Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_AlZPXN0gs1.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_Q2b0vDHio-.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_Q2b0vDHio-.png" new file mode 100644 index 0000000..675adee Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_Q2b0vDHio-.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_QNh8iUWMvD.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_QNh8iUWMvD.png" new file mode 100644 index 0000000..ae22436 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_QNh8iUWMvD.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_UBkA2B4TXM.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_UBkA2B4TXM.png" new file mode 100644 index 0000000..237dd9b Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_UBkA2B4TXM.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_b8KrMUlxex.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_b8KrMUlxex.png" new file mode 100644 index 0000000..1948232 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_b8KrMUlxex.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_d4oXH2wHCZ.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_d4oXH2wHCZ.png" new file mode 100644 index 0000000..f058d40 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_d4oXH2wHCZ.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_pTCgmAW5XL.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_pTCgmAW5XL.png" new file mode 100644 index 0000000..cde11ca Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_pTCgmAW5XL.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_xXCb_c_3eT.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_xXCb_c_3eT.png" new file mode 100644 index 0000000..ccbe03b Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_xXCb_c_3eT.png" differ diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/1.\350\257\255\350\250\200\346\250\241\345\236\213/1.\350\257\255\350\250\200\346\250\241\345\236\213.md" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\350\257\255\350\250\200\346\250\241\345\236\213/1.\350\257\255\350\250\200\346\250\241\345\236\213.md" similarity index 86% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/1.\350\257\255\350\250\200\346\250\241\345\236\213/1.\350\257\255\350\250\200\346\250\241\345\236\213.md" rename to "docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\350\257\255\350\250\200\346\250\241\345\236\213/1.\350\257\255\350\250\200\346\250\241\345\236\213.md" index a49fce3..e158aa1 100644 --- "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/1.\350\257\255\350\250\200\346\250\241\345\236\213/1.\350\257\255\350\250\200\346\250\241\345\236\213.md" +++ "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.\350\257\255\350\250\200\346\250\241\345\236\213/1.\350\257\255\350\250\200\346\250\241\345\236\213.md" @@ -59,9 +59,9 @@ $$ 其中 $T≥0$ 是一个控制我们**希望从语言模型中得到多少随机性的温度参数**: -- T=0:确定性地在每个位置 i 选择最可能的令牌 $x_{i}$ -- T=1:从纯语言模型“正常(normally)”采样 -- T=∞:从整个词汇表上的均匀分布中采样 +- T=0:确定性地在每个位置 i 选择最可能的令牌 $x_{i}$ +- T=1:从纯语言模型“正常(normally)”采样 +- T=∞:从整个词汇表上的均匀分布中采样 然而,如果我们仅将概率提高到 $1/T$ 的次方,**概率分布可能不会加和到 1**。我们可以**通过重新标准化分布来解决这个问题**。我们将标准化版本 $p_{T}(x_{i}∣x_{1:i−1})∝p(x_{i}∣x_{1:i−1})^{1/T}$称为**退火条件概率分布。** 例如: @@ -90,10 +90,10 @@ $$ ### 1.2总结 -- 语言模型是序列 $x_{1:L}$ 的概率分布 p。 -- 直观上,一个好的语言模型应具有语言能力和世界知识。 -- 自回归语言模型允许有效地生成给定提示 $x_{1:i}$ 的补全 $x_{i+1:L}$。 -- 温度可以用来控制生成中的变异量。 +- 语言模型是序列 $x_{1:L}$ 的概率分布 p。 +- 直观上,一个好的语言模型应具有语言能力和世界知识。 +- 自回归语言模型允许有效地生成给定提示 $x_{1:i}$ 的补全 $x_{i+1:L}$。 +- 温度可以用来控制生成中的变异量。 ## 2.大模型相关历史回顾 @@ -147,14 +147,14 @@ $$ 语言模型首先被用于需要生成文本的实践应用: -- 1970年代的语音识别(输入:声音信号,输出:文本) -- 1990年代的机器翻译(输入:源语言的文本,输出:目标语言的文本) +- 1970年代的语音识别(输入:声音信号,输出:文本) +- 1990年代的机器翻译(输入:源语言的文本,输出:目标语言的文本) 噪声信道模型。当时解决这些任务的主要模型是噪声信道模型。以语音识别为例: -- 我们假设有一些从某个分布p中抽取的文本 -- 这些文本被转换为语音(声音信号) -- 然后给定语音,我们希望恢复(最有可能的)文本。这可以通过贝叶斯定理实现: +- 我们假设有一些从某个分布p中抽取的文本 +- 这些文本被转换为语音(声音信号) +- 然后给定语音,我们希望恢复(最有可能的)文本。这可以通过贝叶斯定理实现: $p(\text{text} \mid \text{speech}) \propto \underbrace{p(\text{text})}_\text{language model} \underbrace{p(\text{speech} \mid \text{text})}_\text{acoustic model}.$ @@ -202,13 +202,13 @@ $$ 自2003年以来,神经语言建模的两个关键发展包括: -- **Recurrent Neural Networks**(RNNs),包括长短期记忆(LSTMs),使得一个令牌$x_{i}$的条件分布可以依赖于整个上下文 $x_{1:i−1}$ (有效地使 $n=∞$ ),但这些模型难以训练。 -- **Transformers**是一个较新的架构(于2017年为机器翻译开发),再次返回固定上下文长度n,但更易于训练(并利用了GPU的并行性)。此外,n可以对许多应用程序“足够大”(GPT-3使用的是n=2048)。 +- **Recurrent Neural Networks**(RNNs),包括长短期记忆(LSTMs),使得一个令牌$x_{i}$的条件分布可以依赖于整个上下文 $x_{1:i−1}$ (有效地使 $n=∞$ ),但这些模型难以训练。 +- **Transformers**是一个较新的架构(于2017年为机器翻译开发),再次返回固定上下文长度n,但更易于训练(并利用了GPU的并行性)。此外,n可以对许多应用程序“足够大”(GPT-3使用的是n=2048)。 ### 2.2总结 -- 语言模型最初是在信息理论的背景下研究的,可以用来估计英语的熵。 -- N-gram模型在计算上极其高效,但在统计上效率低下。 -- N-gram模型在短上下文长度中与另一个模型(用于语音识别的声学模型或用于机器翻译的翻译模型)联合使用是有用的。 -- 神经语言模型在统计上是高效的,但在计算上是低效的。 -- 随着时间的推移,训练大型神经网络已经变得足够可行,神经语言模型已经成为主导的模型范式。 +- 语言模型最初是在信息理论的背景下研究的,可以用来估计英语的熵。 +- N-gram模型在计算上极其高效,但在统计上效率低下。 +- N-gram模型在短上下文长度中与另一个模型(用于语音识别的声学模型或用于机器翻译的翻译模型)联合使用是有用的。 +- 神经语言模型在统计上是高效的,但在计算上是低效的。 +- 随着时间的推移,训练大型神经网络已经变得足够可行,神经语言模型已经成为主导的模型范式。 diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.jieba\345\210\206\350\257\215\347\224\250\346\263\225\345\217\212\345\216\237\347\220\206/2.jieba\345\210\206\350\257\215\347\224\250\346\263\225\345\217\212\345\216\237\347\220\206.md" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.jieba\345\210\206\350\257\215\347\224\250\346\263\225\345\217\212\345\216\237\347\220\206/2.jieba\345\210\206\350\257\215\347\224\250\346\263\225\345\217\212\345\216\237\347\220\206.md" new file mode 100644 index 0000000..c3b913a --- /dev/null +++ "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.jieba\345\210\206\350\257\215\347\224\250\346\263\225\345\217\212\345\216\237\347\220\206/2.jieba\345\210\206\350\257\215\347\224\250\346\263\225\345\217\212\345\216\237\347\220\206.md" @@ -0,0 +1,859 @@ +# 2.jieba分词用法及原理 + +## **1.概述** + +上篇文章分析了自然语言处理,特别是中文处理中,分词的几个主要难点。为了解决这些难点,提出了**基于字符串匹配的算法**和**基于统计的分词算法**。针对当前的几种分词引擎,对其分词准确度和速度进行了评估。jieba分词作为一个开源项目,在准确度和速度方面均不错,是我们平时常用的分词工具。本文将对jieba分词的使用方法以及原理进行讲解,便于在理解jieba分词原理的同时,加深对前文讲解的分词难点和算法的理解。 + +### 1.1 特点 + +Jieba库分词有4种模式,最常用的还是前3种 + +1. **精确模式**\*\*:**就是把一段文本精确地切分成若干个中文单词,若干个中文单词之间经过组合,就精确地还原为之前的文本。其中**不存在冗余单词 \*\*。 +2. **全模式**\*\*:**将一段文本中所有可能的词语都扫描出来,可能有一段文本它可以切分成不同的模式,或者有不同的角度来切分变成不同的词语,在全模式下,Jieba库会将各种不同的组合都挖掘出来。分词后的信息再组合起来**会有冗余,不再是原来的文本 \*\*。 +3. **搜索引擎模式****:** 在精确模式基础上,对发现的那些长的词语,我们会对它再次切分,进而适合搜索引擎对短词语的索引和搜索。**也有冗余**。 +4. **paddle模式**:利用PaddlePaddle深度学习框架,训练序列标注(双向GRU)网络模型实现分词。同时支持词性标注。paddle模式使用需安装paddlepaddle-tiny,`pip install paddlepaddle-tiny==1.6.1`。目前paddle模式支持jieba v0.40及以上版本。jieba v0.40以下版本,请升级jieba,`pip install jieba --upgrade` 。 + +### 1.2 安装说明 + +代码对 Python 2/3 均兼容 + +- 全自动安装:`easy_install jieba` 或者 `pip install jieba` / `pip3 install jieba` +- 半自动安装:先下载 [http://pypi.python.org/pypi/jieba/](http://pypi.python.org/pypi/jieba/ "http://pypi.python.org/pypi/jieba/") ,解压后运行 `python setup.py install` +- 手动安装:将 jieba 目录放置于当前目录或者 site-packages 目录 +- 通过 `import jieba` 来引用 +- 如果需要使用paddle模式下的分词和词性标注功能,请先安装paddlepaddle-tiny,`pip install paddlepaddle-tiny==1.6.1`。 + +### 1.3 算法 + +- 基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图 (DAG) +- 采用了**动态规划查找最大概率路径, 找出基于词频的最大切分组合** +- 对于**未登录词**,**采用了基于汉字成词能力的 HMM 模型,使用了 Viterbi 算法** + +## **2.jieba分词用法** + +jieba分词是一个开源项目,地址为:[fxsjy/jieba: 结巴中文分词](https://github.com/fxsjy/jieba "fxsjy/jieba: 结巴中文分词") + +它在分词准确度和速度方面均表现不错。其功能和用法如下。 + +### **2.1 分词** + +`jieba.cut` 方法接受四个输入参数: + +- 需要分词的字符串; +- `cut_all `参数用来控制是否采用全模式; +- `HMM` 参数用来控制是否使用 HMM 模型; +- `use_paddle` 参数用来控制是否使用paddle模式下的分词模式,paddle模式采用延迟加载方式,通过enable\_paddle接口安装paddlepaddle-tiny,并且import相关代码; + +`jieba.cut_for_search` 方法接受两个参数: + +- 需要分词的字符串; +- 是否使用 HMM 模型。该方法适合用于搜索引擎构建倒排索引的分词,粒度比较细 + +待分词的字符串可以是 unicode 或 UTF-8 字符串、GBK 字符串。注意:不建议直接输入 GBK 字符串,可能无法预料地错误解码成 UTF-8 + +`jieba.cut` 以及 `jieba.cut_for_search` 返回的结构都是一个可迭代的 generator,可以使用 for 循环来获得分词后得到的每一个词语(unicode),或者用 + +`jieba.lcut` 以及 `jieba.lcut_for_search` 直接返回 list + +`jieba.Tokenizer(dictionary=DEFAULT_DICT)` 新建自定义分词器,可用于同时使用不同词典。`jieba.dt` 为默认分词器,所有全局分词相关函数都是该分词器的映射。 + +支持三种分词模式 + +```python +# encoding=utf-8 +import jieba + +seg_list = jieba.cut("我来到北京清华大学", cut_all=True) +print("Full Mode: " + "/ ".join(seg_list)) # 全模式 + +seg_list = jieba.cut("我来到北京清华大学", cut_all=False) +print("Default Mode: " + "/ ".join(seg_list)) # 精确模式 + +seg_list = jieba.cut("他来到了网易杭研大厦") # 默认是精确模式 +print(", ".join(seg_list)) + +seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造") # 搜索引擎模式 +print(", ".join(seg_list)) + +``` + +输出为 + +```text +【全模式】: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学 + +【精确模式】: 我/ 来到/ 北京/ 清华大学 + +【新词识别】:他, 来到, 了, 网易, 杭研, 大厦 (此处,“杭研”并没有在词典中,但是也被Viterbi算法识别出来了) + +【搜索引擎模式】: 小明, 硕士, 毕业, 于, 中国, 科学, 学院, 科学院, 中国科学院, 计算, 计算所, 后, 在, 日本, 京都, 大学, 日本京都大学, 深造 + +``` + +### **2.2 添加自定义词典** + +- 开发者可以指定自己自定义的词典,以便包含 jieba 词库里没有的词。虽然 jieba 有新词识别能力,但是自行添加新词可以保证更高的正确率 +- 用法: `jieba.load_userdict(file_name)` , file\_name 为文件类对象或自定义词典的路径 +- 词典格式和 `dict.txt` 一样,一个词占一行;每一行分三部分:词语、词频(可省略)、词性(可省略),用空格隔开,顺序不可颠倒。`file_name` 若为路径或二进制方式打开的文件,则文件必须为 UTF-8 编码。 +- 词频省略时使用自动计算的能保证分出该词的词频。 + +使用起来很简单,我们先创建一个文件,比如`user_dict.txt`,其中每一行代表一个新词,分别为词语,词频,词性。如下: + +```text +创新办 3 i +云计算 5 +凱特琳 nz +台中 + +``` + +然后在代码中分词前,加载这个自定义词典即可。更改分词器(默认为 `jieba.dt`)的 `tmp_dir` 和 `cache_file` 属性,可分别指定缓存文件所在的文件夹及其文件名,用于受限的文件系统。 + +```python +jieba.load_userdict("user_dict.txt") + +``` + +加载自定义词典的分词效果: + +```text +之前: 李小福 / 是 / 创新 / 办 / 主任 / 也 / 是 / 云 / 计算 / 方面 / 的 / 专家 / + +加载自定义词库后: 李小福 / 是 / 创新办 / 主任 / 也 / 是 / 云计算 / 方面 / 的 / 专家 / + +``` + +### **2.3 调整词典** + +- 使用 `add_word(word, freq=None, tag=None)` 和 `del_word(word)` 可在程序中动态修改词典。 +- 使用 `suggest_freq(segment, tune=True)` 可调节单个词语的词频,使其能(或不能)被分出来。 +- 注意:自动计算的词频在使用 HMM 新词发现功能时可能无效。 + +```python +# 1 使用del_word()使得某个词语不会出现 +print('/'.join(jieba.cut('如果放到post中将出错。', HMM=False))) +如果/放到/post/中将/出错/。 + +jieba.del_word("中将") +print('/'.join(jieba.cut('如果放到post中将出错。', HMM=False))) +如果/放到/post/中/将/出错/。 + +# 2 使用add_word()添加新词到字典中 +print('/'.join(jieba.cut('「台中」正确应该不会被切开', HMM=False))) +「/台/中/」/正确/应该/不会/被/切开 + +jieba.add_word("台中") +print('/'.join(jieba.cut('「台中」正确应该不会被切开', HMM=False))) +「/台中/」/正确/应该/不会/被/切开 + +# 3 使用suggest_freq()调整某个词语的词频,使得其在设置的词频高是能分出,词频低时不能分出 +jieba.suggest_freq('台中', True) +69 +print('/'.join(jieba.cut('「台中」正确应该不会被切开', HMM=False))) +「/台中/」/正确/应该/不会/被/切开 + +``` + +### **2.4 关键词提取** + +关键词提取,将文本中最能表达文本含义的词语抽取出来,有点类似于论文的关键词或者摘要。关键词抽取可以采取: + +#### (1)**基于TF-IDF的关键词抽取算法** + +**目标是获取文本中词频高,也就是TF大的,且语料库其他文本中词频低的,也就是IDF大的**。这样的词可以作为文本的标志,用来区分其他文本。 + +API函数 + +- `jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())` + - `sentence` 为待提取的文本 + - `topK` 为返回几个 TF/IDF 权重最大的关键词,默认值为 20 + - `withWeight` 为是否一并返回关键词权重值,默认值为 False + - `allowPOS` 仅包括指定词性的词,默认值为空,即不筛选 +- `jieba.analyse.TFIDF(idf_path=None)` ,新建 TFIDF 实例,`idf_path` 为 IDF 频率文件 + +代码示例 + +```python +from jieba import analyse +# 引入TF-IDF关键词抽取接口 +tfidf = analyse.extract_tags + +# 原始文本 +text = "线程是程序执行时的最小单位,它是进程的一个执行流,\ + 是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,\ + 线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。\ + 线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。\ + 同样多线程也可以实现并发操作,每个请求分配一个线程来处理。" + +# 基于TF-IDF算法进行关键词抽取 +keywords = tfidf(text) +print "keywords by tfidf:" +# 输出抽取出的关键词 +for keyword in keywords: + print keyword + "/", + + +# 输出为: +keywords by tfidf: +线程/ CPU/ 进程/ 调度/ 多线程/ 程序执行/ 每个/ 执行/ 堆栈/ 局部变量/ 单位/ 并发/ 分派/ 一个/ 共享/ 请求/ 最小/ 可以/ 允许/ 分配/ + +``` + +#### **(2)基于TextRank的关键词抽取算法** + +1. 先将文本进行分词和词性标注,将特定词性的词(比如名词)作为节点添加到图中。 +2. 出现在一个窗口中的词语之间形成一条边,窗口大小可设置为2\~10之间,它表示一个窗口中有多少个词语。 +3. 对节点根据入度节点个数以及入度节点权重进行打分,入度节点越多,且入度节点权重大,则打分高。 +4. 然后根据打分进行降序排列,输出指定个数的关键词。 + +API函数 + +- `jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v')) `直接使用,接口相同,注意默认过滤词性。 +- `jieba.analyse.TextRank() `新建自定义 TextRank 实例 +- 算法论文: [TextRank: Bringing Order into Texts](http://web.eecs.umich.edu/~mihalcea/papers/mihalcea.emnlp04.pdf "TextRank: Bringing Order into Texts") + +代码示例 + +```python +from jieba import analyse +# 引入TextRank关键词抽取接口 +textrank = analyse.textrank + +# 原始文本 +text = "线程是程序执行时的最小单位,它是进程的一个执行流,\ + 是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,\ + 线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。\ + 线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。\ + 同样多线程也可以实现并发操作,每个请求分配一个线程来处理。" + +print "\nkeywords by textrank:" +# 基于TextRank算法进行关键词抽取 +keywords = textrank(text) +# 输出抽取出的关键词 +for keyword in keywords: + print keyword + "/", + +# 输出为: +keywords by textrank: +线程/ 进程/ 调度/ 单位/ 操作/ 请求/ 分配/ 允许/ 基本/ 共享/ 并发/ 堆栈/ 独立/ 执行/ 分派/ 组成/ 资源/ 实现/ 运行/ 处理/ + +``` + +### **2.5 词性标注** + +利用`jieba.posseg`模块来进行词性标注,会给出分词后每个词的词性。词性标示兼容ICTCLAS 汉语词性标注集,可查阅网站 + +API函数 + +- `jieba.posseg.POSTokenizer(tokenizer=None)` 新建自定义分词器,`tokenizer` 参数可指定内部使用的 `jieba.Tokenizer` 分词器。`jieba.posseg.dt` 为默认词性标注分词器。 +- 标注句子分词后每个词的词性,采用和 ictclas 兼容的标记法。 +- 除了jieba默认分词模式,提供paddle模式下的词性标注功能。paddle模式采用延迟加载方式,通过`enable_paddle()`安装`paddlepaddle-tiny`,并且import相关代码; + +代码示例 + +```python +import jieba.posseg as pseg +words = pseg.cut("我爱北京天安门") +for word, flag in words: +... print('%s %s' % (word, flag)) +... +我 r # 代词 +爱 v # 动词 +北京 ns # 名词 +天安门 ns # 名词 + +``` + +paddle模式词性标注对应表如下: + +paddle模式词性和专名类别标签集合如下表,其中词性标签 24 个(小写字母),专名类别标签 4 个(大写字母)。 + +| 标签 | 含义 | 标签 | 含义 | 标签 | 含义 | 标签 | 含义 | +| --- | ---- | --- | ---- | --- | ---- | ---- | ---- | +| n | 普通名词 | f | 方位名词 | s | 处所名词 | t | 时间 | +| nr | 人名 | ns | 地名 | nt | 机构名 | nw | 作品名 | +| nz | 其他专名 | v | 普通动词 | vd | 动副词 | vn | 名动词 | +| a | 形容词 | ad | 副形词 | an | 名形词 | d | 副词 | +| m | 数量词 | q | 量词 | r | 代词 | p | 介词 | +| c | 连词 | u | 助词 | xc | 其他虚词 | w | 标点符号 | +| PER | 人名 | LOC | 地名 | ORG | 机构名 | TIME | 时间 | + +### **2.6 并行分词** + +将文本按行分隔后,每行由一个jieba分词进程处理,之后进行归并处理,输出最终结果。这样可以大大提高分词速度。 + +原理:将目标文本按行分隔后,把各行文本分配到多个 Python 进程并行分词,然后归并结果,从而获得分词速度的可观提升 + +基于 python 自带的 multiprocessing 模块,目前暂不支持 Windows + +用法: + +- `jieba.enable_parallel(4)` # 开启并行分词模式,参数为并行进程数 +- `jieba.disable_parallel()` # 关闭并行分词模式 + +```python +jieba.enable_parallel(4) # 开启并行分词模式,参数为并行进程数 +jieba.disable_parallel() # 关闭并行分词模式 + +``` + +实验结果:在 4 核 3.4GHz Linux 机器上,对金庸全集进行精确分词,获得了 1MB/s 的速度,是单进程版的 3.3 倍。 + +**注意**:并行分词仅支持默认分词器 `jieba.dt` 和 `jieba.posseg.dt`。 + +### **2.7 Tokenize:返回词语在原文的起止位置** + +注意,输入参数只接受 unicode + +#### 默认模式 + +```python +result = jieba.tokenize(u'永和服装饰品有限公司') +for tk in result: + print("word %s\t\t start: %d \t\t end:%d" % (tk[0],tk[1],tk[2])) + +# 输出为 +word 永和 start: 0 end:2 +word 服装 start: 2 end:4 +word 饰品 start: 4 end:6 +word 有限公司 start: 6 end:10 + +``` + +#### 搜索模式 + +```python +result = jieba.tokenize(u'永和服装饰品有限公司', mode='search') +for tk in result: + print("word %s\t\t start: %d \t\t end:%d" % (tk[0],tk[1],tk[2])) + +# 输出为 +word 永和 start: 0 end:2 +word 服装 start: 2 end:4 +word 饰品 start: 4 end:6 +word 有限 start: 6 end:8 +word 公司 start: 8 end:10 +word 有限公司 start: 6 end:10 + +``` + +### 2.8 命令模式 + +使用示例:`python -m jieba news.txt > cut_result.txt` + +命令行选项(翻译) + +```python +使用: python -m jieba [options] filename + +结巴命令行界面。 + +固定参数: + filename 输入文件 + +可选参数: + -h, --help 显示此帮助信息并退出 + -d [DELIM], --delimiter [DELIM] + 使用 DELIM 分隔词语,而不是用默认的' / '。 + 若不指定 DELIM,则使用一个空格分隔。 + -p [DELIM], --pos [DELIM] + 启用词性标注;如果指定 DELIM,词语和词性之间 + 用它分隔,否则用 _ 分隔 + -D DICT, --dict DICT 使用 DICT 代替默认词典 + -u USER_DICT, --user-dict USER_DICT + 使用 USER_DICT 作为附加词典,与默认词典或自定义词典配合使用 + -a, --cut-all 全模式分词(不支持词性标注) + -n, --no-hmm 不使用隐含马尔可夫模型 + -q, --quiet 不输出载入信息到 STDERR + -V, --version 显示版本信息并退出 + +如果没有指定文件名,则使用标准输入。 +``` + +`--help` 选项输出: + +```bash +$> python -m jieba --help +Jieba command line interface. + +positional arguments: + filename input file + +optional arguments: + -h, --help show this help message and exit + -d [DELIM], --delimiter [DELIM] + use DELIM instead of ' / ' for word delimiter; or a + space if it is used without DELIM + -p [DELIM], --pos [DELIM] + enable POS tagging; if DELIM is specified, use DELIM + instead of '_' for POS delimiter + -D DICT, --dict DICT use DICT as dictionary + -u USER_DICT, --user-dict USER_DICT + use USER_DICT together with the default dictionary or + DICT (if specified) + -a, --cut-all full pattern cutting (ignored with POS tagging) + -n, --no-hmm don't use the Hidden Markov Model + -q, --quiet don't print loading messages to stderr + -V, --version show program's version number and exit + +If no filename specified, use STDIN instead. +``` + +### **2.9 延迟加载机制** + +jieba 采用延迟加载,`import jieba` 和 `jieba.Tokenizer()` 不会立即触发词典的加载,一旦有必要才开始加载词典构建前缀字典。如果你想手工初始 jieba,也可以手动初始化。 + +```python +import jieba +jieba.initialize() # 手动初始化(可选) + +``` + +## **3.jieba分词源码结构** + +分词的jieba源码版本为0.39。代码结构如下 + +![](image/image_3brJ-d-XDF.png) + +主要的模块如下 + +1. 基本API的封装,在Tokenizer类中,相当于一个外观类。如`cut` `del_word` `add_word` `enable_parallel initialize` 等 +2. 基于字符串匹配的分词算法,包含一个很大很全的词典,即`dict.txt`文件 +3. 基于统计的分词算法,实现了HMM隐马尔科夫模型。jieba分词使用了字符串分词和统计分词,结合了二者的优缺点。 +4. 关键词提取,实现了TFIDF和TextRank两种无监督学习算法 +5. 词性标注,实现了HMM隐马尔科夫模型和viterbi算法 + +## **4.jieba分词原理分析** + +jieba分词综合了**基于字符串匹配**的算法和**基于统计**的算法,其分词步骤为 + +1. 初始化。加载词典文件,获取每个词语和它出现的词数 +2. 切分短语。利用正则,将文本切分为一个个语句,之后对语句进行分词 +3. 构建DAG。通过字符串匹配,构建所有可能的分词情况的有向无环图,也就是DAG +4. 构建节点最大路径概率,以及结束位置。计算每个汉字节点到语句结尾的所有路径中的最大概率,并记下最大概率时在DAG中对应的该汉字成词的结束位置。 +5. 构建切分组合。根据节点路径,得到词语切分的结果,也就是分词结果。 +6. HMM新词处理:对于新词,也就是dict.txt中没有的词语,通过统计方法来处理,jieba中采用了HMM隐马尔科夫模型来处理。 +7. 返回分词结果:通过yield将上面步骤中切分好的词语逐个返回。yield相对于list,可以节约存储空间。 + +### **4.1 初始化** + +词典是基于字符串匹配的分词算法的关键所在,决定了最终分词的准确度。jieba词典dict.txt是jieba作者采集了超大规模的语料数据,统计得到的。有5M,包含349,046条词语。每一行对应一个词语,包含词语 词数 词性三部分。如下 + +```text +凤凰寺 22 ns +凤凰山 311 ns +凤凰岭 15 ns +凤凰岭村 2 ns +凤凰木 3 ns + +``` + +初始化时,先加载词典文件dict.txt,遍历每一行,生成词语-词数的键值对和总词数,并将生成结果保存到cache中,下次直接从cache中读取即可。代码如下,删除了无关的log打印。只需要看关键节点代码即可,不提倡逐行逐行阅读代码,最重要的是理解代码执行的主要流程和关键算法。 + +```python +def initialize(self, dictionary=None): + # 获取词典路径 + if dictionary: + abs_path = _get_abs_path(dictionary) + if self.dictionary == abs_path and self.initialized: + return + else: + self.dictionary = abs_path + self.initialized = False + else: + abs_path = self.dictionary + + with self.lock: + try: + with DICT_WRITING[abs_path]: + pass + except KeyError: + pass + if self.initialized: + return + + # 获取cache_file + default_logger.debug("Building prefix dict from %s ..." % (abs_path or 'the default dictionary')) + t1 = time.time() + if self.cache_file: + cache_file = self.cache_file + # default dictionary + elif abs_path == DEFAULT_DICT: + cache_file = "jieba.cache" + # custom dictionary + else: + cache_file = "jieba.u%s.cache" % md5( + abs_path.encode('utf-8', 'replace')).hexdigest() + cache_file = os.path.join( + self.tmp_dir or tempfile.gettempdir(), cache_file) + # prevent absolute path in self.cache_file + tmpdir = os.path.dirname(cache_file) + + # 加载cache_file + load_from_cache_fail = True + if os.path.isfile(cache_file) and (abs_path == DEFAULT_DICT or + os.path.getmtime(cache_file) > os.path.getmtime(abs_path)): + try: + with open(cache_file, 'rb') as cf: + self.FREQ, self.total = marshal.load(cf) + load_from_cache_fail = False + except Exception: + load_from_cache_fail = True + + # cache_file不存在或者加载失败时,加载原始词典 + if load_from_cache_fail: + wlock = DICT_WRITING.get(abs_path, threading.RLock()) + DICT_WRITING[abs_path] = wlock + with wlock: + # 加载原始词典,得到每个词与其词数的键值对,以及总词数。单个词数除以总词数,即可计算词频 + self.FREQ, self.total = self.gen_pfdict(self.get_dict_file()) + try: + # 保存加载的原始词典到cache_file中 + fd, fpath = tempfile.mkstemp(dir=tmpdir) + with os.fdopen(fd, 'wb') as temp_cache_file: + marshal.dump( + (self.FREQ, self.total), temp_cache_file) + _replace_file(fpath, cache_file) + except Exception: + + try: + del DICT_WRITING[abs_path] + except KeyError: + pass + + self.initialized = True + + +# 加载原始词典 + def gen_pfdict(self, f): + lfreq = {} + ltotal = 0 + f_name = resolve_filename(f) + + # 遍历词典每一行,一行包含一个词,词数,以及词性 + for lineno, line in enumerate(f, 1): + try: + line = line.strip().decode('utf-8') + # 取出词语和它的词数 + word, freq = line.split(' ')[:2] + freq = int(freq) + # 将词语和它的词数构造成键值对 + lfreq[word] = freq + # 计算总词数,这个是为了以后计算某个词的词频,词频越大,则改词出现的概率越大 + ltotal += freq + # 遍历词语中的每个字,如果该字没有出现在词典中,则建立其词语-词数键值对,词数设置为0 + for ch in xrange(len(word)): + wfrag = word[:ch + 1] + if wfrag not in lfreq: + lfreq[wfrag] = 0 + except ValueError: + raise ValueError( + 'invalid dictionary entry in %s at Line %s: %s' % (f_name, lineno, line)) + f.close() + # 返回词语-词数的键值对,以及总词数 + return lfreq, ltotal + +``` + +初始化可以简单理解为,**读取词典文件,构建词语-词数键值对,方便后面步骤中查词典,也就是字符串匹配**。 + +### **4.2. 切分短语** + +使用汉字正则,切分出连续的汉字和英文字符,形成一段段短语。可以理解为以**空格 逗号 句号**为分隔,将输入文本切分为一个个短语,之后会基于一个个短语来分词。代码如下 + +```python +def cut(self, sentence, cut_all=False, HMM=True): + # 编码转换,utf-8或gbk + sentence = strdecode(sentence) + + # 根据是否全模式,以及是否采用HMM隐马尔科夫,来设置正则re_han re_skip,以及cut_block + if cut_all: + re_han = re_han_cut_all + re_skip = re_skip_cut_all + else: + re_han = re_han_default + re_skip = re_skip_default + if cut_all: + cut_block = self.__cut_all + elif HMM: + cut_block = self.__cut_DAG + else: + cut_block = self.__cut_DAG_NO_HMM + + # 将输入文本按照空格 逗号 句号等字符进行分割,生成一个个语句子串 + blocks = re_han.split(sentence) + + # 遍历语句子串 + for blk in blocks: + if not blk: + continue + if re_han.match(blk): + # 对语句进行分词 + for word in cut_block(blk): + yield word + else: + tmp = re_skip.split(blk) + for x in tmp: + if re_skip.match(x): + yield x + elif not cut_all: + for xx in x: + yield xx + else: + yield x + +``` + +1. 首先进行将语句转换为UTF-8或者GBK。 +2. 然后根据用户指定的模式,设置cut的真正实现。 +3. 然后根据正则,将输入文本分为一个个语句。 +4. 最后遍历语句,对每个语句单独进行分词。 + +### **4.3 构建DAG** + +下面我们来分析默认模式,也就是精确模式下的分词过程。先来看`__cut_DAG`方法。 + +```python +def __cut_DAG(self, sentence): + # 得到语句的有向无环图DAG + DAG = self.get_DAG(sentence) + # 动态规划,计算从语句末尾到语句起始,DAG中每个节点到语句结束位置的最大路径概率,以及概率最大时节点对应词语的结束位置 + route = {} + self.calc(sentence, DAG, route) + x = 0 + buf = '' + N = len(sentence) + while x < N: + # y表示词语的结束位置,x为词语的起始位置 + y = route[x][1] + 1 + # 从起始位置x到结束位置y,取出一个词语 + l_word = sentence[x:y] + + if y - x == 1: + # 单字,一个汉字构成的一个词语 + buf += l_word + else: + # 多汉字词语 + if buf: + if len(buf) == 1: + yield buf + buf = '' + else: + if not self.FREQ.get(buf): + # 词语不在字典中,也就是新词,使用HMM隐马尔科夫模型进行分割 + recognized = finalseg.cut(buf) + for t in recognized: + yield t + else: + for elem in buf: + yield elem + buf = '' + yield l_word + # 该节点取词完毕,跳到下一个词语的开始位置 + x = y + + # 通过yield,逐词返回上一步切分好的词语 + if buf: + if len(buf) == 1: + yield buf + elif not self.FREQ.get(buf): + recognized = finalseg.cut(buf) + for t in recognized: + yield t + else: + for elem in buf: + yield elem + +``` + +主体步骤如下 + +1. 得到语句的有向无环图DAG +2. 动态规划构建Route,计算从语句末尾到语句起始,DAG中每个节点到语句结束位置的最大路径概率,以及概率最大时节点对应词语的结束位置 +3. 遍历每个节点的Route,组装词语组合。 +4. 如果词语不在字典中,也就是新词,使用HMM隐马尔科夫模型进行分割 +5. 通过yield将词语逐个返回。 + +下面我们来看构建DAG的过程。先遍历一个个切分好的短语,对这些短语来进行分词。首先要构建短语的有向无环图DAG。查词典进行字符串匹配的过程中,可能会出现好几种可能的切分方式,将这些组合构成有向无环图,如下图所示 + +![](image/image_50yzSTNyQc.png) + +可以看到,构成了两条路径: + +DAG中记录了某个词的开始位置和它可能的结束位置。开始位置作为key,结束位置是一个list。比如位置0的DAG表达为 `{0: [1, 2]}`, 也就是说0位置为词的开始位置时,1,2位置都有可能是词的结束位置。上面语句的完整DAG为 + +```text +{ + 0: [1, 2], + 1: [2, 3], + 2: [3], + 3: [4, 5], + 4: [5] +} + +``` + +DAG构建过程的代码如下: + +```python +# 获取语句的有向无环图 +def get_DAG(self, sentence): + self.check_initialized() + DAG = {} + N = len(sentence) + for k in xrange(N): + tmplist = [] + i = k + frag = sentence[k] + while i < N and frag in self.FREQ: + if self.FREQ[frag]: + tmplist.append(i) + i += 1 + frag = sentence[k:i + 1] + if not tmplist: + tmplist.append(k) + DAG[k] = tmplist + return DAG + +``` + +### **4.4 构建节点最大路径概率,以及结束位置** + +中文一般形容词在前面,而相对来说更关键的名词和动词在后面。考虑到这一点,**jieba中对语句,从右向左反向计算路径的最大概率,这个类似于逆向最大匹配**。`每个词的概率 = 字典中该词的词数 / 字典总词数`。对于上图构建每个节点的最大路径概率的过程如下: + +```python +p(5)= 1, +p(4)= max(p(5) * p(4->5)), +p(3)= max(p(4) * p(4->5), p(5) * p(3->5)), # 对于节点3,他有3->4, 3->5两条路径,我们取概率最大的路径作为节点3的路径概率,并记下概率最大时节点3的结束位置 +p(2) = max(p(3) * p(2->3)) +p(1) = max(p(2) * p(1->2), p(3) * p(1->3)) +p(0) = max(p(1) * p(0->1), p(2) * p(0->2)) + +``` + +对应代码如下 + +```python +def calc(self, sentence, DAG, route): + N = len(sentence) + route[N] = (0, 0) + logtotal = log(self.total) + for idx in xrange(N - 1, -1, -1): + # route[idx] = (该汉字到最后一个汉字的最大路径概率, 最大路径概率时该汉字对应的词语结束位置) + # 遍历DAG中该汉字节点的结束位置,也就是DAG[idx],计算idx到x之间构成的词语的概率,然后乘以x到语句结束位置的最大概率,即可得到idx到语句结束的路径最大概率 + route[idx] = max((log(self.FREQ.get(sentence[idx:x + 1]) or 1) - logtotal + route[x + 1][0], x) for x in DAG[idx]) + +``` + +### **4.5 构建切分组合** + +从节点0开始,按照步骤4中构建的最大路径概率以及结束位置,取出节点0的结束位置,构成词语。如果是单字词语,则直接通过yield返回。如果词语在字典中,也直接通过yield返回。如果词语不在字典中,也就是新词,则需要通过HMM隐马尔科夫模型来分割。节点0处理完毕,则跳到下一个词语的开始处进行处理,直至到达语句末尾。 + +代码参见`__cut_DAG()`,也就是主体流程代码。 + +### **4.6 HMM新词处理** + +对于新词,也就是`dict.txt`中没有的词语,通过统计方法来处理,jieba中采用了HMM隐马尔科夫模型。回顾下HMM的五要素:**观测序列,隐藏序列,发射概率,起始概率,转移概率**。由这五大要素可以对短语建模。 + +**通过语料大规模训练,可以得到发射概率,起始概率和转移概率。通过viterbi算法,可以得到概率最大的隐藏序列**,也就是 BEMS标注序列,通过BEMS就可以对语句进行分词了。观察发现,新词被分成二字词语的概率很大。 + +转移概率在`prob_trans.py`中,如下 + +```python +P={'B': {'E': -0.510825623765990, 'M': -0.916290731874155}, # exp后为概率,此处为{'E': 0.6, 'M': 0.4} + 'E': {'B': -0.5897149736854513, 'S': -0.8085250474669937}, + 'M': {'E': -0.33344856811948514, 'M': -1.2603623820268226}, + 'S': {'B': -0.7211965654669841, 'S': -0.6658631448798212}} + +``` + +起始概率在`prob_start.py`中,如下 + +```python +P={'B': -0.26268660809250016, + 'E': -3.14e+100, + 'M': -3.14e+100, + 'S': -1.4652633398537678} + +# exp后为概率,此处为{'B': 0.769, 'E': 0, 'M': 0, 'S': 0.231} + +``` + +隐马尔科夫模型处理代码主要为 + +```python +# 通过HMM隐马尔科夫模型获取语句的BEMS序列标注,并通过它来进行分词 +def __cut(sentence): + global emit_P + # 通过viterbi算法和start_P, trans_P, emit_P三个训练好的概率,得到语句对应的BEMS序列标注 + prob, pos_list = viterbi(sentence, 'BMES', start_P, trans_P, emit_P) + begin, nexti = 0, 0 + + # 得到分词结果。根据上面得到pos_list, 也就是语句对应的BEMS序列,来对原始语句进行分词。 + for i, char in enumerate(sentence): + pos = pos_list[i] + if pos == 'B': + # 词语开始 + begin = i + elif pos == 'E': + # 词语结束,可以根据begin开始位置来返回分词词语了 + yield sentence[begin:i + 1] + nexti = i + 1 + elif pos == 'S': + # 单字词语,直接返回 + yield char + nexti = i + 1 + + # 理论上不会走到下面这儿,只是以防万一 + if nexti < len(sentence): + yield sentence[nexti:] + +``` + +viterbi算法的代码如下 + +```python +# 通过viterbi算法,由观测序列,也就是语句,来得到隐藏序列,也就是BEMS标注序列 +# obs为语句,states为"BEMS"四种状态, +# start_p为起始概率, trans_p为转移概率, emit_p为发射概率,三者通过语料训练得到 +def viterbi(obs, states, start_p, trans_p, emit_p): + V = [{}] # 每个汉字的每个BEMS状态的最大概率。 + path = {} # 分词路径 + + # 初始化每个state,states为"BEMS" + for y in states: + V[0][y] = start_p[y] + emit_p[y].get(obs[0], MIN_FLOAT) + path[y] = [y] + + # 逐字进行处理 + for t in xrange(1, len(obs)): + V.append({}) + newpath = {} + # 遍历每个状态 + for y in states: + # 得到某状态到某个字的发射概率 + em_p = emit_p[y].get(obs[t], MIN_FLOAT) + # 计算前一个状态到本状态的最大概率和它的前一个状态 + (prob, state) = max( + [(V[t - 1][y0] + trans_p[y0].get(y, MIN_FLOAT) + em_p, y0) for y0 in PrevStatus[y]]) + # 将该汉字下的某状态(BEMS)的最大概率记下来 + V[t][y] = prob + # 记录状态转换路径 + newpath[y] = path[state] + [y] + path = newpath + + # 尝试合并ES两种状态,因为ES经常可以组成一个完整词语 + (prob, state) = max((V[len(obs) - 1][y], y) for y in 'ES') + + # 返回语句的BEMS序列 + return (prob, path[state]) + +``` + +### **4.7 返回分词结果** + +通过yield将上面步骤中切分好的词语逐个返回。yield相对于list,可以节约存储空间。 + +## **5.总结** + +jiaba分词是一款十分优秀的开源分词引擎,它结合了基于字符串匹配的算法和基于统计的算法。使用最大概率路径动态规划算法,进行字符串匹配,可以在分词速度快的同时,保持较高的分词精度。使用HMM隐马尔科夫模型对新词进行分词,可以有效解决字符串匹配无法识别新词的难点。阅读它的源码有利于我们加深对分词难点和算法的理解,也能加深对HMM隐马尔卡尔模型这种常用的机器学习算法的理解。 diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.jieba\345\210\206\350\257\215\347\224\250\346\263\225\345\217\212\345\216\237\347\220\206/image/image_3brJ-d-XDF.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.jieba\345\210\206\350\257\215\347\224\250\346\263\225\345\217\212\345\216\237\347\220\206/image/image_3brJ-d-XDF.png" new file mode 100644 index 0000000..1cc1f5d Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.jieba\345\210\206\350\257\215\347\224\250\346\263\225\345\217\212\345\216\237\347\220\206/image/image_3brJ-d-XDF.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.jieba\345\210\206\350\257\215\347\224\250\346\263\225\345\217\212\345\216\237\347\220\206/image/image_50yzSTNyQc.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.jieba\345\210\206\350\257\215\347\224\250\346\263\225\345\217\212\345\216\237\347\220\206/image/image_50yzSTNyQc.png" new file mode 100644 index 0000000..1e1a8f4 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.jieba\345\210\206\350\257\215\347\224\250\346\263\225\345\217\212\345\216\237\347\220\206/image/image_50yzSTNyQc.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\350\257\215\346\200\247\346\240\207\346\263\250/3.\350\257\215\346\200\247\346\240\207\346\263\250.md" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\350\257\215\346\200\247\346\240\207\346\263\250/3.\350\257\215\346\200\247\346\240\207\346\263\250.md" new file mode 100644 index 0000000..28d212c --- /dev/null +++ "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\350\257\215\346\200\247\346\240\207\346\263\250/3.\350\257\215\346\200\247\346\240\207\346\263\250.md" @@ -0,0 +1,284 @@ +# 3.词性标注 + +## **1.概述** + +词性标注在自然语言处理中也属于基础性的模块,为句法分析、信息抽取等工作打下基础。和分词一样,中文词性标注也存在着很多难点,比如**一词多词性,未登录词处理**等诸多问题。**通过基于字符串匹配的字典查询算法和基于统计的词性标注算法**,可以很好的解决这些问题。一般需要先将语句进行分词,然后再进行词性标注。 + +## **2.词性标注难点** + +词性作为词语基本的语法属性,是词语和语句的关键性特征。词性种类也很多,ICTCLAS 汉语词性标注集归纳的词性种类及其表示见 [ICTCLAS 汉语词性标注集](https://www.cnblogs.com/chenbjin/p/4341930.html "ICTCLAS 汉语词性标注集") + +词性标注中的难点主要有 + +1. 相对于英文,中文缺少词形态变化,**不能从词的形态来识别词性** +2. **一词多词性很常见**。统计发现,一词多词性的概率高达22.5%。而且越常用的词,多词性现象越严重。比如“研究”既可以是名词(“基础性研究”),也可以是动词(“研究计算机科学”)。 +3. **词性划分标准不统一**。词类划分粒度和标记符号等,目前还没有一个广泛认可的统一的标准。比如LDC标注语料中,将汉语一级词性划分为33类,而北京大学语料库则将其划分为26类。词类划分标准和标记符号的不统一,以及分词规范的含糊,都给词性标注带来了很大的困难。jieba分词采用了使用较为广泛的ICTCLAS 汉语词性标注集规范。 +4. **未登录词问题**。和分词一样,未登录词的词性也是一个比较大的课题。未登录词不能通过查找字典的方式获取词性,可以采用HMM隐马尔科夫模型等基于统计的算法。 + +## **3.词性标注算法** + +和分词一样,词性标注算法也分为两大类,**基于字符串匹配的字典查找算法**和**基于统计的算法**。jieba分词就综合了两种算法,对于分词后识别出来的词语,直接从字典中查找其词性。而对于**未登录词,则采用HMM隐马尔科夫模型和viterbi算法来识别**。 + +### **3.1 基于字符串匹配的字典查找算法** + +**先对语句进行分词,然后从字典中查找每个词语的词性,对其进行标注即可**。jieba词性标注中,对于识别出来的词语,就是采用了这种方法。这种方法比较简单,通俗易懂,但是不能解决一词多词性的问题,因此存在一定的误差。 + +下图即为jieba分词中的词典的一部分词语。每一行对应一个词语,分为三部分,分别为词语名 词数 词性。因此分词完成后只需要在字典中查找该词语的词性即可对其完成标注。 + +### **3.2 基于统计的词性标注算法** + +和分词一样,也可以**通过HMM隐马尔科夫模型来进行词性标注**。观测序列即为分词后的语句,隐藏序列即为经过标注后的词性标注序列。起始概率 发射概率和转移概率和分词中的含义大同小异,可以通过大规模语料统计得到。观测序列到隐藏序列的计算可以通过viterbi算法,利用统计得到的起始概率 发射概率和转移概率来得到。得到隐藏序列后,就完成了词性标注过程。 + +## **4.jieba词性标注原理** + +jieba在分词的同时,可以进行词性标注。利用`jieba.posseg`模块来进行词性标注,会给出分词后每个词的词性。词性标示兼容ICTCLAS 汉语词性标注集,可查阅网站 + +```python +import jieba.posseg as pseg +words = pseg.cut("我爱北京天安门") +for word, flag in words: +... print('%s %s' % (word, flag)) +... +我 r # 代词 +爱 v # 动词 +北京 ns # 名词 +天安门 ns # 名词 + +``` + +下面来对`pseg.cut()`进行详细的分析,其主要流程为 + +1. **准备工作**:check字典是否初始化好,如果没有则先初始化字典。将语句转为UTF-8或者GBK。根据正则匹配,将输入文本分隔成一个个语句。 +2. **遍历语句list,对每个语句进行单独分词和词性标注**。 +3. **对于未登录词,使用HMM隐马尔科夫模型处理**。 + +### **4.1 准备工作** + +准备工作中做的事情和jieba分词基本一致,check字典是否初始化好,如果没有则先初始化字典。将语句转为UTF-8或者GBK。根据正则匹配,将输入文本分隔成一个个语句。代码如下。 + +```python +def __cut_internal(self, sentence, HMM=True): + # 如果没有字典没有初始化,则先加载字典。否则直接使用字典缓存即可。 + self.makesure_userdict_loaded() + + # 将语句转为UTF-8或者GBK + sentence = strdecode(sentence) + + # 根据正则匹配,将输入文本分隔成一个个语句。分隔符包括空格 逗号 句号等。 + blocks = re_han_internal.split(sentence) + + # 根据是否采用了HMM模型来进行不同方法的选择 + if HMM: + cut_blk = self.__cut_DAG + else: + cut_blk = self.__cut_DAG_NO_HMM + + # 遍历正则匹配分隔好的语句,对每个语句进行单独的分词和词性标注 + for blk in blocks: + if re_han_internal.match(blk): + # 分词和词性标注 + for word in cut_blk(blk): + yield word + else: + tmp = re_skip_internal.split(blk) + for x in tmp: + if re_skip_internal.match(x): + yield pair(x, 'x') + else: + for xx in x: + if re_num.match(xx): + yield pair(xx, 'm') + elif re_eng.match(x): + yield pair(xx, 'eng') + else: + yield pair(xx, 'x') + +``` + +### **4.2 遍历语句,进行分词和词性标注** + +步骤和jieba分词基本一致,主体步骤如下,详细的每个步骤见 + +1. 得到语句的有向无环图DAG +2. 动态规划构建Route,计算从语句末尾到语句起始,DAG中每个节点到语句结束位置的最大路径概率,以及概率最大时节点对应词语的结束位置 +3. 遍历每个节点的Route,组装词语组合。 +4. 如果词语不在字典中,也就是新词,使用HMM隐马尔科夫模型进行分割 +5. 通过yield将词语逐个返回。 + +```python +def __cut_DAG(self, sentence): + # 构建DAG有向无环图,得到语句分词所有可能的路径 + DAG = self.tokenizer.get_DAG(sentence) + route = {} + + # 动态规划,计算从语句末尾到语句起始,DAG中每个节点到语句结束位置的最大路径概率,以及概率最大时节点对应词语的结束位置 + self.tokenizer.calc(sentence, DAG, route) + + # 遍历每个节点的Route,组装词语组合。 + x = 0 + buf = '' + N = len(sentence) + while x < N: + # y表示词语的结束位置,x为词语的起始位置 + y = route[x][1] + 1 + # 从起始位置x到结束位置y,取出一个词语 + l_word = sentence[x:y] + if y - x == 1: + # 单字,一个汉字构成的一个词语 + buf += l_word + else: + # 多汉字词语 + if buf: + if len(buf) == 1: + # 单字直接从字典中取出其词性。使用pair将分词和词性一起输出。 + yield pair(buf, self.word_tag_tab.get(buf, 'x')) + elif not self.tokenizer.FREQ.get(buf): + # 词语不在字典中,也就是新词,使用HMM隐马尔科夫模型进行分割 + recognized = self.__cut_detail(buf) + for t in recognized: + yield t + else: + # 词语在字典中,直接查找字典并取出词性。 + for elem in buf: + yield pair(elem, self.word_tag_tab.get(elem, 'x')) + buf = '' + yield pair(l_word, self.word_tag_tab.get(l_word, 'x')) + + # 该节点取词完毕,跳到下一个词语的开始位置 + x = y + + # 通过yield,逐词返回上一步切分好的词语 + if buf: + if len(buf) == 1: + yield pair(buf, self.word_tag_tab.get(buf, 'x')) + elif not self.tokenizer.FREQ.get(buf): + recognized = self.__cut_detail(buf) + for t in recognized: + yield t + else: + for elem in buf: + yield pair(elem, self.word_tag_tab.get(elem, 'x')) + + +``` + +其中`word_tag_tab`在初始化加载词典阶段构建得到,它使用词语为key,对应词性为value。代码如下 + +```python +def load_word_tag(self, f): + self.word_tag_tab = {} + f_name = resolve_filename(f) + + # 遍历字典的每一行。每一行对应一个词语。包含词语 词数 词性三部分 + for lineno, line in enumerate(f, 1): + try: + # 去除首尾空格符 + line = line.strip().decode("utf-8") + if not line: + continue + # 利用空格将一行分隔为词语 词数 词性三部分 + word, _, tag = line.split(" ") + # 使用词语为key,词性为value,构造Dict + self.word_tag_tab[word] = tag + except Exception: + raise ValueError( + 'invalid POS dictionary entry in %s at Line %s: %s' % (f_name, lineno, line)) + f.close() + +``` + +### **4.3 未登录词,HMM隐马尔科夫模型处理** + +和分词一样,词性标注中,也使用HMM隐马尔科夫模型来处理未登录词。通过大规模语料统计,得到起始概率 发射概率和转移概率。分别对应`prob_start.py` `prob_emit.py`和`prob_trans.py`三个文件,他们给出了词语在BEMS四种情况下,每种词性对应的概率。然后使用viterbi算法,利用得到的三个概率,将观测序列(分词后的语句)转化得到隐藏序列(词性标注序列)。这样就完成了未登录词的词性标注。代码如下。 + +```python +# 通过HMM隐马尔科夫模型获取词性标注序列,解决未登录的问题 +def __cut(self, sentence): + # 通过viterbi算法,利用三个概率,由语句观测序列,得到词性标注隐藏序列 + # prob为 + # pos_list对应每个汉字,包含分词标注BEMS和词语词性两部分。 + prob, pos_list = viterbi( + sentence, char_state_tab_P, start_P, trans_P, emit_P) + begin, nexti = 0, 0 + + # 遍历语句的每个汉字,如果是E或者S时,也就是词语结束或者单字词语,则分隔得到词语和词性pair + for i, char in enumerate(sentence): + pos = pos_list[i][0] + if pos == 'B': + # B表示词语的开始 + begin = i + elif pos == 'E': + # E表示词语的结束,此时输出词语和他的词性 + yield pair(sentence[begin:i + 1], pos_list[i][1]) + nexti = i + 1 + elif pos == 'S': + # S表示单字词语,此时也输出词语和他的词性 + yield pair(char, pos_list[i][1]) + nexti = i + 1 + + # 一般不会走到这儿,以防万一。对剩余的所有汉字一起输出一个词语和词性。 + if nexti < len(sentence): + yield pair(sentence[nexti:], pos_list[nexti][1]) + +``` + +观测序列到隐藏序列的计算,则通过viterbi算法实现。代码如下 + +```python +# 通过viterbi算法,由观测序列,也就是语句,来得到隐藏序列,也就是BEMS标注序列和词性标注序列 +# obs为语句,states为"BEMS"四种状态, +# start_p为起始概率, trans_p为转移概率, emit_p为发射概率,三者通过语料训练得到 +def viterbi(obs, states, start_p, trans_p, emit_p): + V = [{}] # 每个汉字的每个BEMS状态的最大概率。 + mem_path = [{}] # 分词路径 + + # 初始化每个state,states为"BEMS" + all_states = trans_p.keys() + for y in states.get(obs[0], all_states): # init + V[0][y] = start_p[y] + emit_p[y].get(obs[0], MIN_FLOAT) + mem_path[0][y] = '' + + # 逐字进行处理 + for t in xrange(1, len(obs)): + V.append({}) + mem_path.append({}) + #prev_states = get_top_states(V[t-1]) + prev_states = [ + x for x in mem_path[t - 1].keys() if len(trans_p[x]) > 0] + + prev_states_expect_next = set( + (y for x in prev_states for y in trans_p[x].keys())) + obs_states = set( + states.get(obs[t], all_states)) & prev_states_expect_next + + if not obs_states: + obs_states = prev_states_expect_next if prev_states_expect_next else all_states + + # 遍历每个状态 + for y in obs_states: + # 计算前一个状态到本状态的最大概率和它的前一个状态 + prob, state = max((V[t - 1][y0] + trans_p[y0].get(y, MIN_INF) + + emit_p[y].get(obs[t], MIN_FLOAT), y0) for y0 in prev_states) + # 将该汉字下的某状态(BEMS)的最大概率记下来 + V[t][y] = prob + # 记录状态转换路径 + mem_path[t][y] = state + + last = [(V[-1][y], y) for y in mem_path[-1].keys()] + # if len(last)==0: + # print obs + prob, state = max(last) + + route = [None] * len(obs) + i = len(obs) - 1 + while i >= 0: + route[i] = state + state = mem_path[i][state] + i -= 1 + return (prob, route) + +``` + +## **5.总结** + +jieba可以在分词的同时,完成词性标注,因此标注速度可以得到保证。通过查询字典的方式获取识别词的词性,通过HMM隐马尔科夫模型来获取未登录词的词性,从而完成整个语句的词性标注。但可以看到查询字典的方式不能解决一词多词性的问题,也就是词性歧义问题。故精度上还是有所欠缺的。 diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.\345\217\245\346\263\225\345\210\206\346\236\220/4.\345\217\245\346\263\225\345\210\206\346\236\220.md" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.\345\217\245\346\263\225\345\210\206\346\236\220/4.\345\217\245\346\263\225\345\210\206\346\236\220.md" new file mode 100644 index 0000000..a5fc223 --- /dev/null +++ "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.\345\217\245\346\263\225\345\210\206\346\236\220/4.\345\217\245\346\263\225\345\210\206\346\236\220.md" @@ -0,0 +1,51 @@ +# 4.句法分析 + +## **1.概述** + +句法分析也是自然语言处理中的基础性工作,它分析句子的句法结构(主谓宾结构)和词汇间的依存关系(并列,从属等)。通过句法分析,可以为语义分析,情感倾向,观点抽取等NLP应用场景打下坚实的基础。 + +随着深度学习在NLP中的使用,特别是本身携带句法关系的LSTM模型的应用,句法分析已经变得不是那么必要了。但是,在句法结构十分复杂的长语句,以及标注样本较少的情况下,句法分析依然可以发挥出很大的作用。因此研究句法分析依然是很有必要的。 + +## **2.句法分析分类** + +句法分析分为两类,一类是分析句子的主谓宾、定状补的句法结构。另一类是分析词汇间的依存关系,如并列、从属、比较、递进等。下面详细讲解。 + +### **2.1 句法结构分析** + +句法结构分析,识别句子的主谓宾、定状补,**并分析各成分之间的关系**. + +通过句法结构分析,就能够分析出语句的主干,以及各成分间关系。对于复杂语句,仅仅通过词性分析,不能得到正确的语句成分关系。 + +句法结构分析的标注如下 + +![](image/image_0FMBp4fbBs.png) + +### **2.2 语义依存关系分析** + +语义依存关系分析,识别词汇间的从属、并列、递进等关系,可以获得较深层的语义信息。如以下三个不同的表达方式,表达了同一个语义信息。可见语义依存关系不受句法结构的影响。 + +语义依存关系偏向于介词等非实词的在语句中的作用,而句法结构分析则更偏向于名词、动词、形容词等实词。如张三 -> 吃的关系为施加关系Agt,苹果->吃的关系为受事关系Pat。依存关系标注比较多,就不一一列举了。 + +## **3.句法分析工具** + +句法分析算法比较复杂,我们就不展开了。可以参考文章[NLP底层技术之句法分析](https://blog.csdn.net/qq_28031525/article/details/79187080 "NLP底层技术之句法分析")。介绍下几个句法分析工具。 + +哈工大LTP: [语言云(语言技术平台云 LTP-Cloud)](https://www.ltp-cloud.com/ "语言云(语言技术平台云 LTP-Cloud)") + +斯坦福句法分析工具Stanford Parser:[The Stanford Natural Language Processing Group](https://nlp.stanford.edu/software/lex-parser.shtml "The Stanford Natural Language Processing Group") + +当前句法分析难度还很大,准确度不高。哈工大的LTP也只能做到80%左右的准确率。 + +## **4.深度学习和句法分析** + +基于深度学习的RNN和LSTM序列模型,本身可以携带很多句法结构和依存关系等深层信息。同时,句法分析树结构也可以和深度学习结合起来。利用句法分析树可以构建LSTM网络(tree-lstm), 从而对语句进行文本摘要,情感分析。那是否基于句法分析树的LSTM(tree-lstm)就一定比单纯的双向LSTM(bi-lstm)效果好吗? + +研究表明,很多情况下,单纯的bi-lstm,比基于句法分析树的tree-lstm效果更好 + +![](image/image_qmnRnNmiSj.png) + +这主要是因为当前句法分析准确度不高,只有90%左右。如果是句子成分关系很复杂,则准确率更低。因此给lstm网络带来了很大的噪声,从而导致了tree-lstm模型准确度的降低。但是tree-lstm可以使用较少的标注语料,而且在句子结构复杂的长语句上,表现更好。因此当语料较少且句子结构很复杂时,可以考虑使用tree-lstm。相关文章可以参考:[哈工大车万翔:自然语言处理中的深度学习模型是否依赖于树结构?](https://mp.weixin.qq.com/s?__biz=MzIxMjAzNDY5Mg==\&mid=209300177\&idx=1\&sn=4d24467ee27da15ae05effaa0ded9332\&scene=2\&srcid=1015LyJAMxAtArMzdyKyIRHh\&from=timeline\&isappinstalled=0#rd "哈工大车万翔:自然语言处理中的深度学习模型是否依赖于树结构?") + +## **5.总结** + +句法分析是自然语言处理中的基础性工作,在文本分析 观点抽取 情感分析等场景下可以广泛应用。句法分析当前难度还很高,准确率也有待提升。受制于句法分析准确率问题,基于句法结构树的LSTM深度学习网络的准确率还有待进一步提升。总之,句法分析,任重而道远。 diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.\345\217\245\346\263\225\345\210\206\346\236\220/image/image_0FMBp4fbBs.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.\345\217\245\346\263\225\345\210\206\346\236\220/image/image_0FMBp4fbBs.png" new file mode 100644 index 0000000..8cee440 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.\345\217\245\346\263\225\345\210\206\346\236\220/image/image_0FMBp4fbBs.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.\345\217\245\346\263\225\345\210\206\346\236\220/image/image_qmnRnNmiSj.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.\345\217\245\346\263\225\345\210\206\346\236\220/image/image_qmnRnNmiSj.png" new file mode 100644 index 0000000..d1c7d2a Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.\345\217\245\346\263\225\345\210\206\346\236\220/image/image_qmnRnNmiSj.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/5.\350\257\215\345\220\221\351\207\217/5.\350\257\215\345\220\221\351\207\217.md" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/5.\350\257\215\345\220\221\351\207\217/5.\350\257\215\345\220\221\351\207\217.md" new file mode 100644 index 0000000..fb5e858 --- /dev/null +++ "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/5.\350\257\215\345\220\221\351\207\217/5.\350\257\215\345\220\221\351\207\217.md" @@ -0,0 +1,306 @@ +# 5.词向量 + +## **1.概述** + +词向量和分词一样,也是自然语言处理中的基础性工作。**词向量一方面解决了词语的编码问题,另一方面也解决了词的同义关系**,使得基于LSTM等深度学习模型的自然语言处理成为了可能。和分词不同,中英文文本,均需要进行词向量编码。 + +## **2.词向量工具** + +2013年Google开源了`word2vec`工具,它可以进行词向量训练,加载已有模型进行增量训练,求两个词向量相似度,求与某个词接近的词语,等等。功能十分丰富,基本能满足我们对于词向量的需求。下面详细讲解怎么使用`word2vec` + +### **2.1 模型训练** + +词向量模型训练只需要有训练语料即可,语料越丰富准确率越高,属于无监督学习。后面会讲词向量训练算法和代码实现,这儿先说怎么利用`word2vec`工具进行词向量模型训练。 + +```python +# gensim是自然语言处理的一个重要Python库,它包括了Word2vec +import gensim +from gensim.models import word2vec + +# 语句,由原始语句经过分词后划分为的一个个词语 +sentences = [['网商银行', '体验', '好'], ['网商银行','转账','快']] + +# 使用word2vec进行训练 +# min_count: 词语频度,低于这个阈值的词语不做词向量 +# size:每个词对应向量的维度,也就是向量长度 +# workers:并行训练任务数 +model = word2vec.Word2Vec(sentences, size=256, min_count=1) + +# 保存词向量模型,下次只需要load就可以用了 +model.save("word2vec_atec") + +``` + +### **2.2 增量训练** + +有时候我们语料不是很丰富,但都是针对的某个垂直场景的,比如网商银行相关的语料。此时训练词向量时,可以先基于一个已有的模型进行增量训练,这样就可以得到包含特定语料的比较准确的词向量了。 + +```python +# 先加载已有模型 +model = gensim.models.Word2Vec.load("word2vec_atec") + +# 进行增量训练 +corpus = [['网商银行','余利宝','收益','高'],['贷款','发放','快']] # 新增语料 +model.build_vocab(corpus, update=True) # 训练该行 +model.train(corpus, total_examples=model.corpus_count, epochs=model.iter) + +# 保存增量训练后的新模型 +model.save("../data/word2vec_atec") + +``` + +### **2.3 求词语相似度** + +可以利用词向量来求两个词语的相似度。词向量的余弦夹角越小,则相似度越高。 + +```python +# 验证词相似程度 +print model.wv.similarity('花呗'.decode('utf-8'), '借呗'.decode('utf-8')) + +``` + +### **2.4 求与词语相近的多个词语** + +```python +for i in model.most_similar(u"我"): + print i[0],i[1] + +``` + +## **3.词向量训练算法** + +词向量可以通过使用大规模语料进行无监督学习训练得到,常用的算法有`CBOW`连续词袋模型和`skip-gram`跳字模型。二者没有本质的区别,算法框架完全相同。区别在于,**CBOW利用上下文来预测中心词。而skip-gram则相反,利用中心词来预测上下文**。比如对于语料 `{“The”, “cat”, “jump”, “over”, “the”, “puddle”}` ,CBOW利用上下文`{“The”, “cat”, “over”, “the”, “puddle”} `预测中心词“jump”,而skip-gram则利用jump来预测上下文的词,比如jump->cat, jump->over。一般来说,**CBOW适合小规模训练语料,对其进行平滑处理。skip-gram适合大规模训练语料,可以基于滑窗随机选择上下文词语**。word2vec模型训练时默认采用skip-gram。 + +## **4.词向量训练代码实现** + +下面来看一个基于skip-gram的词向量训练的代码实现,这样就能够skip-gram算法有比较深刻的理解。CBOW算法和skip-gram基本相同。代码来自TensorFlow官方教程 + +```python +# -*- coding: utf-8 -*- +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import collections +import math +import os +import random +import zipfile + +import numpy as np +from six.moves import urllib +from six.moves import xrange # pylint: disable=redefined-builtin +import tensorflow as tf + +# 1 下载语料文件,并校验文件字节数是否正确 +url = 'http://mattmahoney.net/dc/' +def maybe_download(filename, expected_bytes): + if not os.path.exists(filename): + urllib.request.urlretrieve(url + filename, filename) + statinfo = os.stat(filename) + if (statinfo.st_size == expected_bytes): + print("get text and verified") + else: + raise Exception("text size is not correct") + + return filename + +filename = maybe_download("text8.zip", 31344016) + + +# 2 语料处理,弄成一个个word组成的list, 以空格作为分隔符。 +# 如果是中文语料,这一步还需要进行分词 +def read_data(filename): + with zipfile.ZipFile(filename) as f: + data = tf.compat.as_str(f.read(f.namelist()[0])).split() + return data + +vocabulay = read_data(filename) +print("total word size %d" % len(vocabulay)) +print("100 words at first: ", vocabulay[0:100]) + +# 3 词表制作,根据出现频率排序,序号代表这个单词。词语编码的一种常用方式 +def build_dataset(words, n_words): + count = [["UNK", -1]] + count.extend(collections.Counter(words).most_common(n_words - 1)) + dictionay = dict() + for word, _ in count: + # 利用按照出现频率排序好的词语的位置,来代表这个词语 + dictionay[word] = len(dictionay) + + # data包含语料库中的所有词语,低频的词语标注为UNK。这些词语都是各不相同的 + data = list() + unk_count = 0 + for word in words: + if word in dictionay: + index = dictionay[word] + else: + index = 0 + unk_count += 1 + data.append(index) + count[0][1] = unk_count # unk的个数 + + # 将key value reverse一下,使用数字来代表这个词语 + reversed_dictionary = dict(zip(dictionay.values(), dictionay.keys())) + return data, count, dictionay, reversed_dictionary + +VOC_SIZE = 50000 +data, count, dictionary, reversed_dictionary = build_dataset(vocabulay, VOC_SIZE) +del vocabulay +print("most common words", count[0:5]) +# 打印前10个单词的数字序号 +print("sample data", data[:10], [reversed_dictionary[i] for i in data[:10]]) + +# 4 生成训练的batch label对 +data_index = 0 +# skip_window表示与target中心词相关联的上下文的长度。整个Buffer为 (2 * skip_window + 1),从skip_window中随机选取num_skips个单词作为label +# 最后形成 target->label1 target->label2的batch label对组合 +def generate_batch(batch_size, num_skips, skip_window): + global data_index + batch = np.ndarray(shape=(batch_size), dtype=np.int32) + labels = np.ndarray(shape=(batch_size, 1), dtype=np.int32) + + # 将skip_window的数据组合放入Buffer中 + span = 2 * skip_window + 1 + buffer = collections.deque(maxlen=span) + for _ in range(span): + buffer.append(data[data_index]) + data_index = (data_index + 1) % len(data) # 防止超出data数组范围,因为batch可以取很多次迭代。所以可以循环重复 + + # num_skips表示一个Buffer中选取几个batch->label对,每一对为一个batch,故需要batch_size // num_skips个Buffer + for i in range(batch_size // num_skips): + target = skip_window + targets_to_avoid = [skip_window] + + # 一个Buffer内部寻找num_skips个label + for j in range(num_skips): + # 寻找label的位置,总共会有num_skips个label + while target in targets_to_avoid: # 中间那个为batch,不能选为target.也不能重复选target + target = random.randint(0, span - 1) + targets_to_avoid.append(target) + + # 中心位置为batch,随机选取的num_skips个其他位置的为label + batch[i * num_skips + j] = buffer[skip_window] # + labels[i * num_skips + j, 0] = buffer[target] # 遍历选取的label + + # 一个Buffer内的num_skips找完之后,向后移动一位,将单词加入Buffer内,并将Buffer内第一个单词移除,从而形成新的Buffer + buffer.append(data[data_index]) + data_index = (data_index + 1) % len(data) + + # 所有batch都遍历完之后,重新调整data_index指针位置 + data_index = (data_index + len(data) - span) % len(data) + + return batch, labels + +batch, labels = generate_batch(batch_size=8, num_skips=2, skip_window=1) +for i in range(8): + print(batch[1], reversed_dictionary[batch[i]], "->", labels[i, 0], reversed_dictionary[labels[i, 9]]) + +# 5 构造训练模型 +batch_size = 128 +embedding_size = 128 # 词向量为128维,也就是每一个word转化为的vec是128维的 +skip_window = 1 # 滑窗大小为1, 也就是每次取中心词前后各一个词 +num_skips = 2 # 每次取上下文的两个词 + +# 模型验证集, 对前100个词进行验证,每次验证16个词 +valid_size = 16 +valid_window = 100 +valid_examples = np.random.choice(valid_window, valid_size, replace=False) + +# 噪声词数量 +num_sampled = 64 + +graph= tf.Graph() +with graph.as_default(): + train_inputs = tf.placeholder(tf.int32, shape=[batch_size]) + train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1]) + valid_dataset = tf.constant(valid_examples, dtype=tf.int32) # 验证集 + + with tf.device("/cpu:0"): + # 构造embeddings, 50000个词语,每个词语为长度128的向量 + embeddings = tf.Variable(tf.random_uniform([VOC_SIZE, embedding_size], -1.0, 1.0)) + embed = tf.nn.embedding_lookup(embeddings, train_inputs) + + nce_weights = tf.Variable(tf.truncated_normal([VOC_SIZE, embedding_size], stddev=1.0 / math.sqrt(embedding_size))) + nce_biases = tf.Variable(tf.zeros([VOC_SIZE])) + + # 利用nce loss将多分类问题转化为二分类问题,从而使得词向量训练成为可能,不然分类会是上万的量级 + loss = tf.reduce_mean( + tf.nn.nce_loss( + weights=nce_weights, + biases=nce_biases, + labels=train_labels, + inputs=embed, # inputs为经过embeddings词向量之后的train_inputs + num_sampled=num_sampled, # 噪声词 + num_classes=VOC_SIZE, + ) + ) + optimizer = tf.train.GradientDescentOptimizer(1.0).minimize(loss) + + # 归一化embeddings + norm = tf.sqrt(tf.reduce_sum(tf.square(embeddings), 1, keep_dims=True)) + normalized_embeddings = embeddings / norm + + valid_embeddings = tf.nn.embedding_lookup(normalized_embeddings, valid_dataset) + similarity = tf.matmul(valid_embeddings, normalized_embeddings, transpose_b=True) + + init = tf.global_variables_initializer() + + +# 6 训练 +num_steps = 100000 +with tf.Session(graph=graph) as session: + init.run() + + average_loss = 0 + for step in xrange(num_steps): + # 构建batch,并进行feed + batch_inputs, batch_labels = generate_batch(batch_size, num_skips, skip_window) + feed_dict = {train_inputs: batch_inputs, train_labels: batch_labels} + + # run optimizer和loss,跑模型 + _, loss_val = session.run([optimizer, loss], feed_dict=feed_dict) + average_loss += loss_val + + if step % 2000 == 0 and step > 0: + average_loss /= 2000 + print("average loss at step ", step, ": ", average_loss) + average_loss = 0 + + # 1万步,验证一次 + if step % 10000 == 0: + sim = similarity.eval() + for i in xrange(valid_size): + valid_word = reversed_dictionary[valid_examples[i]] + top_k = 8 + nearest = (-sim[i, :]).argsort()[1: top_k+1] + log_str = "Nearest to %s:" % valid_word + for k in xrange(top_k): + close_word = reversed_dictionary[nearest[k]] + log_str = '%s %s,' % (log_str, close_word) + print(log_str) + + final_embeddings = normalized_embeddings.eval() + + +``` + +流程还是很简单的,关键在第四步batch的构建,和第五步训练模型的构建,步骤如下 + +1. 下载语料文件,并校验文件字节数是否正确。这儿只是一个demo,语料也很小,只有100M。如果想得到比较准确的词向量,一般需要通过爬虫获取维基百科,网易新闻等既丰富又相对准确的语料素材。一般需要几十上百G的corpus,即语料。谷歌根据不同的语料预训练了一些词向量,参考 [Embedding/Chinese-Word-Vectors](https://github.com/Embedding/Chinese-Word-Vectors "Embedding/Chinese-Word-Vectors") +2. 语料处理,文本切割为一个个词语。英文的话以空格为分隔符进行切分即可(有误差,但还好)。中文的话需要通过分词工具进行分割。 +3. 词表制作,词语预编码。根据词语出现频率排序,序号代表这个单词。词语编码的一种常用方式。 +4. 生成训练的batch label对。这是比较关键的一步,也是体现skip-gram算法的一步。 + +- 先取出滑窗范围的一组词,如滑窗大小为5,则取出5个词。 +- 位于中心的词为中心词,比如滑窗大小为5,则第三个词为中心词。其他词则称为上下文。 +- 从上下文中随机取出`num_skip`个词,比如`num_skip`为2,则从4个上下文词语中取2个。通过随机选取提高了一定的泛化性 +- 得到`num_skip`个中心词->上下文的x->y词组 +- 将滑窗向右移动一个位置,继续这些步骤,直到滑窗到达文本最后 + +1. 构造训练模型,这一步也很关键。利用nce loss将多分类问题转化为二分类问题,optimizer优化方法采用随机梯度下降。 +2. 开始真正的训练。这一步比较常规化。送入第四步构建的batch进行feed,跑optimizer和loss,并进行相关信息打印即可。训练结束后,即可得到调整完的词向量模型。 + +## **5.总结** + +基于深度学习的词向量训练方法,具有算法简单通用,语料获取容易,泛化性好的优点。通过学习官方代码,可以对skip-gram等词向量训练算法有比较深入的理解。词向量在文本分析,文本摘要,情感分析等领域都是必须的预处理,可以大大提高自然语言处理的准确度。 diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/LLM\344\270\272\344\273\200\344\271\210Decoder only\346\236\266\346\236\204/LLM\344\270\272\344\273\200\344\271\210Decoder only\346\236\266\346\236\204.md" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/LLM\344\270\272\344\273\200\344\271\210Decoder only\346\236\266\346\236\204/LLM\344\270\272\344\273\200\344\271\210Decoder only\346\236\266\346\236\204.md" new file mode 100644 index 0000000..06466ce --- /dev/null +++ "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/LLM\344\270\272\344\273\200\344\271\210Decoder only\346\236\266\346\236\204/LLM\344\270\272\344\273\200\344\271\210Decoder only\346\236\266\346\236\204.md" @@ -0,0 +1,32 @@ +# LLM为什么Decoder only架构 + +> [为什么现在的LLM都是Decoder only的架构?](https://blog.csdn.net/TFATS/article/details/133100383 "为什么现在的LLM都是Decoder only的架构?") + +LLM 是 “Large Language Model” 的简写,目前一般指百亿参数以上的语言模型, 主要面向文本生成任务。跟小尺度模型(10亿或以内量级)的“百花齐放”不同,目前LLM的一个现状是Decoder-only架构的研究居多,像OpenAI一直坚持Decoder-only的GPT系列就不说了,即便是Google这样的并非全部押注在Decoder-only的公司,也确实投入了不少的精力去研究Decoder-only的模型,如PaLM就是其中之一。那么,为什么Decoder-only架构会成为LLM的主流选择呢? + +Transformer 模型一开始是用来做 seq2seq 任务的,所以它包含 Encoder 和 Decoder 两个部分;他们两者的区别主要是,**Encoder 在抽取序列中某一个词的特征时能够看到整个序列中所有的信息,即上文和下文同时看到**;而 **Decoder 中因为有 mask 机制的存在,使得它在编码某一个词的特征时只能看到自身和它之前的文本信息**。 + +首先概述几种主要的架构: + +- 以BERT为代表的**encoder-only** +- 以T5和BART为代表的**encoder-decoder** +- 以GPT为代表的**decoder-only**, +- 以UNILM9为代表的PrefixLM(相比于GPT只改了attention mask,前缀部分是双向,后面要生成的部分是单向的causal mask%) + +![](image/image_FTjn7ZU5Xf.png) + +然后说明要比较的对象: 首先**淘汰掉BERT这种encoder-only,因为它用masked language modeling预训练,不擅长做生成任务**,做NLUQ一般也需要有监督的下游数据微调: 相比之下decoder-only的模型用next token prediction%预训练,兼顾理解和生成,在各种下游任务上的zero-shot和few-shot泛化性能·都很好。我们需要讨论的是,为啥引入了一部分双向attention的encoder-decoder和Prefix-LM没有被大部分大模型工作采用? (它们也能兼顾理解和生成,泛化性能也不错) + +### 1.Encoder的低秩问题 + +LLM之所以主要都用Decoder-only架构,除了训练效率和工程实现上的优势外,在理论上是因为**Encoder的双向注意力会存在低秩问题,这可能会削弱模型表达能力**,就生成任务而言,引入双向注意力并无实质好处。而Encoder-Decoder架构之所以能够在某些场景下表现更好,大概只是因为它多了一倍参数。所以,在同等参数量、同等推理成本下,Decoder-only架构就是最优选择了。(参考:[为什么现在的LLM都是Decoder-only的架构?](https://kexue.fm/archives/9529 "为什么现在的LLM都是Decoder-only的架构?")) + +### 2.更好的Zero-Shot性能、更适合于大语料自监督学习 + +首先,对 encoder-decoder 与 decoder-only 的比较早已有之。先把目光放放到模型参数动辄100B之前的时代,看看小一点的模型参数量下、两个架构各有什么优势——Google Brain 和 HuggingFace联合发表的 What Language Model Architecture and Pretraining Objective Work Best for Zero-Shot Generalization? 曾经在5B的参数量级下对比了两者性能。 + +论文最主要的一个结论是:**decoder-only 模型在没有任何 tuning 数据的情况下、zero-shot 表现最好,而 encoder-decoder 则需要在一定量的标注数据上做 multitask finetuning 才能激发最佳性能。** 而目前的Large LM的训练范式还是在大规模语料上做自监督学习,很显然,Zero-Shot性能更好的decoder-only架构才能更好地利用这些无标注数据。此外,Instruct GPT在自监督学习外还引入了RLHF作辅助学习。RLHF本身也不需要人工提供任务特定的标注数据,仅需要在LLM生成的结果上作排序。虽然目前没有太多有关RLHF + encoder-decoder的相关实验,直觉上RLHF带来的提升可能还是不如multitask finetuning,毕竟前者本质只是ranking、引入监督信号没有后者强。 + +### 3.效率问题 + +decoder-only支持一直复用KV-Cache,对多轮对话更友好,因为每个Token的表示之和它之前的输入有关,而encoder-decoder和PrefixLM就难以做到。 diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\344\270\211\345\244\247\347\211\271\345\276\201\346\212\275\345\217\226\345\231\250\357\274\210CNN-RNN-TF\357\274\211/NLP\344\270\211\345\244\247\347\211\271\345\276\201\346\212\275\345\217\226\345\231\250\357\274\210CNN-RNN-TF\357\274\211.md" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\344\270\211\345\244\247\347\211\271\345\276\201\346\212\275\345\217\226\345\231\250\357\274\210CNN-RNN-TF\357\274\211/NLP\344\270\211\345\244\247\347\211\271\345\276\201\346\212\275\345\217\226\345\231\250\357\274\210CNN-RNN-TF\357\274\211.md" new file mode 100644 index 0000000..0dd94ea --- /dev/null +++ "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\344\270\211\345\244\247\347\211\271\345\276\201\346\212\275\345\217\226\345\231\250\357\274\210CNN-RNN-TF\357\274\211/NLP\344\270\211\345\244\247\347\211\271\345\276\201\346\212\275\345\217\226\345\231\250\357\274\210CNN-RNN-TF\357\274\211.md" @@ -0,0 +1,53 @@ +# NLP三大特征抽取器(CNN/RNN/TF) + +> 摘自文章:[自然语言处理三大特征抽取器](https://zhuanlan.zhihu.com/p/54743941 "自然语言处理三大特征抽取器") + +**结论**:RNN已经基本完成它的历史使命,将来会逐步退出历史舞台;CNN如果改造得当,将来还是有希望有自己在NLP领域的一席之地;而Transformer明显会很快成为NLP里担当大任的最主流的特征抽取器。 + +NLP任务的特点:输入是个一维线性序列;输入不定长;单词或句子的位置关系很重要;句子中长距离特征对于语义理解也很重要。 + +> **一个特征抽取器是否适配问题领域的特点,有时候决定了它的成败,而很多模型改进的方向,其实就是改造得使得它更匹配领域问题的特性**。 + +#### RNN + +采取线性序列结构不断从前往后收集输入信息,但这种线性序列结构在反向传播的时候存在优化困难问题,因为反向传播路径太长,容易导致严重的梯度消失或梯度爆炸问题。为了解决这个问题,后来引入了LSTM和GRU模型,通过增加中间状态信息直接向后传播,以此缓解梯度消失问题,获得了很好的效果,于是很快LSTM和GRU成为RNN的标准模型。经过不断优化,后来NLP又从图像领域借鉴并引入了attention机制(从这两个过程可以看到不同领域的相互技术借鉴与促进作用),叠加网络把层深作深,以及引入Encoder-Decoder框架,这些技术进展极大拓展了RNN的能力以及应用效果。 + +RNN的结构天然适配解决NLP的问题,NLP的输入往往是个不定长的线性序列句子,而RNN本身结构就是个可以接纳不定长输入的由前向后进行信息线性传导的网络结构,而在LSTM引入三个门后,对于捕获长距离特征也是非常有效的。所以RNN特别适合NLP这种线形序列应用场景,这是RNN为何在NLP界如此流行的根本原因。 + +![](image/image_g_anBE563B.png) + +RNN在新时代面临的两个问题: + +1. 一些新模型的崛起:特殊改造的CNN;Transformer +2. RNN结构存在序列依赖,对大规模并行非常不友好 + +#### CNN + +CNN捕获的特征其实的单词的`k-gram`片段信息,`k`的大小决定了能捕获多远距离的特征。 + +目前NLP界主流的CNN: + +![](image/image_m5T92pMvsC.png) + +通常由1-D卷积层来叠加深度,使用Skip Connection来辅助优化,也可以引入Dilated CNN等手段。 + +CNN的卷积层其实是保留了相对位置信息的,CNN的并行计算能力,那是非常强的。 + +#### Transformer + +![](image/image_1vuLUX3FGo.png) + +自然语言一般是个不定长的句子,那么这个不定长问题怎么解决呢?Transformer做法跟CNN是类似的,一般设定输入的最大长度,如果句子没那么长,则用Padding填充,这样整个模型输入起码看起来是定长的了。 + +#### 三大抽取器比较 + +1. **语义特征提取能力**:Transformer在这方面的能力非常显著地超过RNN和CNN,RNN和CNN两者能力差不太多。 +2. **长距离特征捕获能力**:原生CNN特征抽取器在这方面极为显著地弱于RNN和Transformer,Transformer微弱优于RNN模型(尤其在主语谓语距离小于13时),能力由强到弱排序为Transformer>RNN>>CNN; 但在比较远的距离上(主语谓语距离大于13),RNN微弱优于Transformer,所以综合看,可以认为Transformer和RNN在这方面能力差不太多,而CNN则显著弱于前两者。 +3. **任务综合特征抽取能力(机器翻译)**:Transformer综合能力要明显强于RNN和CNN,而RNN和CNN看上去表现基本相当,貌似CNN表现略好一些。 +4. **并行计算能力及运行效率**:RNN在并行计算方面有严重缺陷,这是它本身的序列依赖特性导致的;对于CNN和Transformer来说,因为它们不存在网络中间状态不同时间步输入的依赖关系,所以可以非常方便及自由地做并行计算改造。Transformer和CNN差不多,都远远远远强于RNN。 + +#### 综合排名 + +***单从任务综合效果方面来说,Transformer明显优于CNN,CNN略微优于RNN。速度方面Transformer和CNN明显占优,RNN在这方面劣势非常明显。*** + +三者的结合:向Transformer靠拢 diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\344\270\211\345\244\247\347\211\271\345\276\201\346\212\275\345\217\226\345\231\250\357\274\210CNN-RNN-TF\357\274\211/image/image_1vuLUX3FGo.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\344\270\211\345\244\247\347\211\271\345\276\201\346\212\275\345\217\226\345\231\250\357\274\210CNN-RNN-TF\357\274\211/image/image_1vuLUX3FGo.png" new file mode 100644 index 0000000..e5a0380 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\344\270\211\345\244\247\347\211\271\345\276\201\346\212\275\345\217\226\345\231\250\357\274\210CNN-RNN-TF\357\274\211/image/image_1vuLUX3FGo.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\344\270\211\345\244\247\347\211\271\345\276\201\346\212\275\345\217\226\345\231\250\357\274\210CNN-RNN-TF\357\274\211/image/image_g_anBE563B.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\344\270\211\345\244\247\347\211\271\345\276\201\346\212\275\345\217\226\345\231\250\357\274\210CNN-RNN-TF\357\274\211/image/image_g_anBE563B.png" new file mode 100644 index 0000000..bdf11d6 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\344\270\211\345\244\247\347\211\271\345\276\201\346\212\275\345\217\226\345\231\250\357\274\210CNN-RNN-TF\357\274\211/image/image_g_anBE563B.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\344\270\211\345\244\247\347\211\271\345\276\201\346\212\275\345\217\226\345\231\250\357\274\210CNN-RNN-TF\357\274\211/image/image_m5T92pMvsC.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\344\270\211\345\244\247\347\211\271\345\276\201\346\212\275\345\217\226\345\231\250\357\274\210CNN-RNN-TF\357\274\211/image/image_m5T92pMvsC.png" new file mode 100644 index 0000000..92213d4 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\344\270\211\345\244\247\347\211\271\345\276\201\346\212\275\345\217\226\345\231\250\357\274\210CNN-RNN-TF\357\274\211/image/image_m5T92pMvsC.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\351\235\242\350\257\225\351\242\230/NLP\351\235\242\350\257\225\351\242\230.md" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\351\235\242\350\257\225\351\242\230/NLP\351\235\242\350\257\225\351\242\230.md" new file mode 100644 index 0000000..447a86e --- /dev/null +++ "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\351\235\242\350\257\225\351\242\230/NLP\351\235\242\350\257\225\351\242\230.md" @@ -0,0 +1,168 @@ +# NLP面试题 + +### 1.BERT + +#### 1.1 基础知识 + +BERT(Bidirectional Encoder Representations from Transformers)是谷歌提出,作为一个Word2Vec的替代者,其在NLP领域的11个方向大幅刷新了精度,可以说是近年来自残差网络最优突破性的一项技术了。论文的主要特点以下几点: + +1. 使用了双向Transformer作为算法的主要框架,之前的模型是从左向右输入一个文本序列,或者将 left-to-right 和 right-to-left 的训练结合起来,实验的结果表明,双向训练的语言模型对语境的理解会比单向的语言模型更深刻; +2. 使用了Mask Language Model(MLM)和 Next Sentence Prediction(NSP) 的多任务训练目标; +3. 使用更强大的机器训练更大规模的数据,使BERT的结果达到了全新的高度,并且Google开源了BERT模型,用户可以直接使用BERT作为Word2Vec的转换矩阵并高效的将其应用到自己的任务中。 + +BERT 只利用了 Transformer 的 encoder 部分。因为BERT 的目标是生成语言模型,所以只需要 encoder 机制。 + +BERT有两个任务: + +1. Masked LM (MLM) : 在将单词序列输入给 BERT 之前,每个序列中有 15% 的单词被 `[MASK]` token 替换。 然后模型尝试基于序列中其他未被 mask 的单词的上下文来预测被掩盖的原单词。在BERT的实验中,15%的WordPiece Token会被随机Mask掉。在训练模型时,一个句子会被多次喂到模型中用于参数学习,但是Google并没有在每次都mask掉这些单词,而是在确定要Mask掉的单词之后,80%的概率会直接替换为`[Mask]`,10%的概率将其替换为其它任意单词,10%的概率会保留原始Token。 + 1. **80% 的 tokens 会被替换为 \[MASK] token**:**是 Masked LM 中的主要部分,可以在不泄露 label 的情况下融合真双向语义信息**; + 2. **10% 的 tokens 会称替换为随机的 token** :因为需要在最后一层随机替换的这个 token 位去预测它真实的词,而模型并不知道这个 token 位是被随机替换的,就迫使模型尽量在每一个词上都学习到一个 全局语境下的表征,因而也能够让 BERT 获得更好的语境相关的词向量(**这正是解决一词多义的最重要特性**); + 3. \*\*10% 的 tokens 会保持不变但需要被预测 \*\*:这样能够给模型一定的 bias ,相当于是额外的奖励,将模型对于词的表征能够拉向词的 真实表征 +2. Next Sentence Prediction (NSP) : 在 BERT 的训练过程中,模型接收成对的句子作为输入,并且预测其中第二个句子是否在原始文档中也是后续句子。 + 1. 在训练期间,50% 的输入对在原始文档中是前后关系,另外 50% 中是从语料库中随机组成的,并且是与第一句断开的。 + 2. 在第一个句子的开头插入 `[CLS]` 标记,表示该特征用于分类模型,对非分类模型,该符号可以省去,在每个句子的末尾插入 `[SEP]` 标记,表示分句符号,用于断开输入语料中的两个句子。 + +ERT的输入的编码向量(长度是512)是3个嵌入特征的单位和,这三个词嵌入特征是: + +1. **位置嵌入(Position Embedding)**:位置嵌入是指将单词的位置信息编码成特征向量,位置嵌入是向模型中引入单词位置关系的至关重要的一环; +2. **WordPiece 嵌入**:WordPiece是指将单词划分成一组有限的公共子词单元,能在单词的有效性和字符的灵活性之间取得一个折中的平衡。例如上图的示例中‘playing’被拆分成了‘play’和‘ing’; +3. **分割嵌入(Segment Embedding)**:用于区分两个句子,例如B是否是A的下文(对话场景,问答场景等)。对于句子对,第一个句子的特征值是0,第二个句子的特征值是1。」 + +### 2.文本嵌入 + +在传统的NLP中,将单词视为离散符号,然后可以用one-hot向量表示。向量的维度是整个词汇表中单词的数量。单词作为离散符号的问题在于,对于one-hot向量来说,没有自然的相似性概念。 + +因此,另一种方法是学习在向量本身中编码相似性。核心思想是一个词的含义是由经常出现在其旁边的单词给出的。 + +文本嵌入是字符串的实值向量表示。为每个单词建立一个密集的向量,选择它以便类似于类似上下文中出现的单词的向量。 + +在词嵌入中最流行的应该是Word2vec,它是由谷歌(Mikolov)开发的模型,其中固定词汇表中的每个词都由一个向量表示。然后,通过文本中的每个位置`t`,其中有一个中心词`c`和上下文词`o`。 + +Word2vec有两个变体: + +![](image/image_X49t5d33gM.png) + +1. `Skip-Gram`:考虑一个包含`k`个连续项的上下文窗口。然后,跳过其中一个单词,尝试学习一个神经网络,该网络可以获得除跳过的所有术语外的所有术语,并预测跳过的术语。 + 因此,如果两个单词在大语料库中反复共享相似的上下文,那么这些术语的嵌入向量将具有相似的向量。 +2. `Continuous Bag of Words`:在一个大的语料库中获取大量的句子,每当看到一个词,就会联想到周围的词。然后,将上下文单词输入到神经网络,并预测该上下文中心的单词。当有数千个这样的上下文单词和中心单词时,就有了一个神经网络数据集的实例。训练神经网络,最后编码的隐藏层输出表示一个特定的词嵌入。当通过大量的句子进行训练时,类似上下文中的单词会得到相似的向量。 + +对`Skip-Gram`和`CBOW`的一个吐槽就是它们都是基于窗口的模型,这意味着语料库的共现统计不能被有效使用,导致次优的嵌入(suboptimal embeddings)。 + +### 3.对比BERT、OpenAI GPT、ELMo架构之间的差异 + +- `BERT`使用双向Encoder,模型的表示在所有层中,共同依赖于左右两侧的上下文 +- `OpenAI GPT`使用单向Encoder,利用了 Transformer 的编码器作为语言模型进行预训练的,之后特定的自然语言处理任务在其基础上进行微调即可。 +- `ELMo`使用独立训练的从左到右和从右到左LSTM级联来生成下游任务的特征。是一种双层双向的 LSTM 结构,其训练的语言模型可以学习到句子左右两边的上下文信息,但此处所谓的上下文信息并不是真正意义上的上下文。 + +三种模型中只有BERT表征基于所有层左右两侧语境。 + +![](image/image_iTMYNBqhpw.png) + +### 4.Word2Vec中为什么使用负采样(negtive sample)? + +负采样是另一种用来提高Word2Vec效率的方法,它是基于这样的观察:训练一个神经网络意味着使用一个训练样本就要稍微调整一下神经网络中所有的权重,这样才能够确保预测训练样本更加精确,**如果能设计一种方法每次只更新一部分权重,那么计算复杂度将大大降低**。 + +将以上观察引入Word2Vec就是:当通过(”fox”, “quick”)词对来训练神经网络时,回想起这个神经网络的“标签”或者是“正确的输出”是一个one-hot向量。也就是说,对于神经网络中对应于”quick”这个单词的神经元对应为1,而其他上千个的输出神经元则对应为0。 + +使用负采样,通过随机选择一个较少数目(比如说5个)的“负”样本来更新对应的权重。(在这个条件下,“负”单词就是希望神经网络输出为0的神经元对应的单词)。并且仍然为“正”单词更新对应的权重(也就是当前样本下”quick”对应的神经元仍然输出为1)。 + +负采样这个点引入word2vec非常巧妙,两个作用: + +1. **加速了模型计算** +2. **保证了模型训练的效果**,其一 模型每次只需要更新采样的词的权重,不用更新所有的权重,那样会很慢,其二 中心词其实只跟它周围的词有关系,位置离着很远的词没有关系,也没必要同时训练更新,作者这点非常聪明。 + +### 5.word2vec 相比之前的 Word Embedding 方法好在什么地方? + +无论是`CBOW`还是`Skip-Gram`,本质还是要**基于word和context做文章**,即可以理解为模型在学习word和context的co-occurrence。 + +Word2vec训练方面采用的HSoftmax以及负采样确实可以认为是创新不大。但Word2vec流行的主要原因也不在于此。主要原因在于以下3点: + +1. **极快的训练速度**。以前的语言模型优化的目标是MLE,只能说词向量是其副产品。Mikolov应该是第一个提出抛弃MLE(和困惑度)指标,就是要学习一个好的词嵌入。如果不追求MLE,模型就可以大幅简化,去除隐藏层。再利用HSoftmax以及负采样的加速方法,可以使得训练在小时级别完成。而原来的语言模型可能需要几周时间。 +2. **一个很酷炫的man-woman=king-queen的示例**。这个示例使得人们发现词嵌入还可以这么玩,并促使词嵌入学习成为了一个研究方向,而不再仅仅是神经网络中的一些参数。 +3. word2vec里有大量的tricks,比如噪声分布如何选?如何采样?如何负采样?等等。这些tricks虽然摆不上台面,但是对于得到一个好的词向量至关重要。 + +### 6.NLP预训练发展史:从Word Embedding到BERT + +图像预训练 → word embedding → word2vec → elmo → transformer → gpt → bert → GPT 234 + +### 7.NLP三大特征抽取器(CNN/RNN/TF) + +> 摘自文章:[自然语言处理三大特征抽取器](https://zhuanlan.zhihu.com/p/54743941 "自然语言处理三大特征抽取器") + +**结论**:RNN已经基本完成它的历史使命,将来会逐步退出历史舞台;CNN如果改造得当,将来还是有希望有自己在NLP领域的一席之地;而Transformer明显会很快成为NLP里担当大任的最主流的特征抽取器。 + +NLP任务的特点:输入是个一维线性序列;输入不定长;单词或句子的位置关系很重要;句子中长距离特征对于语义理解也很重要。 + +> **一个特征抽取器是否适配问题领域的特点,有时候决定了它的成败,而很多模型改进的方向,其实就是改造得使得它更匹配领域问题的特性**。 + +#### RNN + +采取线性序列结构不断从前往后收集输入信息,但这种线性序列结构在反向传播的时候存在优化困难问题,因为反向传播路径太长,容易导致严重的梯度消失或梯度爆炸问题。为了解决这个问题,后来引入了LSTM和GRU模型,通过增加中间状态信息直接向后传播,以此缓解梯度消失问题,获得了很好的效果,于是很快LSTM和GRU成为RNN的标准模型。经过不断优化,后来NLP又从图像领域借鉴并引入了attention机制(从这两个过程可以看到不同领域的相互技术借鉴与促进作用),叠加网络把层深作深,以及引入Encoder-Decoder框架,这些技术进展极大拓展了RNN的能力以及应用效果。 + +RNN的结构天然适配解决NLP的问题,NLP的输入往往是个不定长的线性序列句子,而RNN本身结构就是个可以接纳不定长输入的由前向后进行信息线性传导的网络结构,而在LSTM引入三个门后,对于捕获长距离特征也是非常有效的。所以RNN特别适合NLP这种线形序列应用场景,这是RNN为何在NLP界如此流行的根本原因。 + +![](image/image_g_anBE563B.png) + +RNN在新时代面临的两个问题: + +1. 一些新模型的崛起:特殊改造的CNN;Transformer +2. RNN结构存在序列依赖,对大规模并行非常不友好 + +#### CNN + +CNN捕获的特征其实的单词的`k-gram`片段信息,`k`的大小决定了能捕获多远距离的特征。 + +目前NLP界主流的CNN: + +![](image/image_m5T92pMvsC.png) + +通常由1-D卷积层来叠加深度,使用Skip Connection来辅助优化,也可以引入Dilated CNN等手段。 + +CNN的卷积层其实是保留了相对位置信息的,CNN的并行计算能力,那是非常强的。 + +#### Transformer + +![](image/image_1vuLUX3FGo.png) + +自然语言一般是个不定长的句子,那么这个不定长问题怎么解决呢?Transformer做法跟CNN是类似的,一般设定输入的最大长度,如果句子没那么长,则用Padding填充,这样整个模型输入起码看起来是定长的了。 + +#### 三大抽取器比较 + +1. 语义特征提取能力:Transformer在这方面的能力非常显著地超过RNN和CNN,RNN和CNN两者能力差不太多。 +2. 长距离特征捕获能力:原生CNN特征抽取器在这方面极为显著地弱于RNN和Transformer,Transformer微弱优于RNN模型(尤其在主语谓语距离小于13时),能力由强到弱排序为Transformer>RNN>>CNN; 但在比较远的距离上(主语谓语距离大于13),RNN微弱优于Transformer,所以综合看,可以认为Transformer和RNN在这方面能力差不太多,而CNN则显著弱于前两者。 +3. 任务综合特征抽取能力(机器翻译):Transformer综合能力要明显强于RNN和CNN,而RNN和CNN看上去表现基本相当,貌似CNN表现略好一些。 +4. 并行计算能力及运行效率:RNN在并行计算方面有严重缺陷,这是它本身的序列依赖特性导致的;对于CNN和Transformer来说,因为它们不存在网络中间状态不同时间步输入的依赖关系,所以可以非常方便及自由地做并行计算改造。Transformer和CNN差不多,都远远远远强于RNN。 + +#### 综合排名 + +***单从任务综合效果方面来说,Transformer明显优于CNN,CNN略微优于RNN。速度方面Transformer和CNN明显占优,RNN在这方面劣势非常明显。*** + +三者的结合:向Transformer靠拢 + +### 8.常用参数更新方法 + +**梯度下降**:在一个方向上更新和调整模型的参数,来最小化损失函数。 + +**随机梯度下降(Stochastic gradient descent,SGD)** 对每个训练样本进行参数更新,每次执行都进行一次更新,且执行速度更快。 + +为了避免SGD和标准梯度下降中存在的问题,一个改进方法为**小批量梯度下降**(Mini Batch Gradient Descent),因为对每个批次中的n个训练样本,这种方法只执行一次更新。 + +使用小批量梯度下降的优点是: + +1\) 可以减少参数更新的波动,最终得到效果更好和更稳定的收敛。 + +2\) 还可以使用最新的深层学习库中通用的矩阵优化方法,使计算小批量数据的梯度更加高效。 + +3\) 通常来说,小批量样本的大小范围是从50到256,可以根据实际问题而有所不同。 + +4\) 在训练神经网络时,通常都会选择小批量梯度下降算法。 + +**SGD方法中的高方差振荡使得网络很难稳定收敛**,所以有研究者提出了一种称为**动量(Momentum)的技术**,通过优化相关方向的训练和弱化无关方向的振荡,来加速SGD训练。 + +**Nesterov梯度加速法**,通过使网络更新与误差函数的斜率相适应,并依次加速SGD,也可根据每个参数的重要性来调整和更新对应参数,以执行更大或更小的更新幅度。 + +**AdaDelta方法**是AdaGrad的延伸方法,它倾向于解决其学习率衰减的问题。Adadelta不是累积所有之前的平方梯度,而是将累积之前梯度的窗口限制到某个固定大小w。 + +**Adam算法**即自适应时刻估计方法(Adaptive Moment Estimation),能计算每个参数的自适应学习率。这个方法不仅存储了AdaDelta先前平方梯度的指数衰减平均值,而且保持了先前梯度M(t)的指数衰减平均值,这一点与动量类似。 + +Adagrad方法是通过参数来调整合适的学习率η,对稀疏参数进行大幅更新和对频繁参数进行小幅更新。因此,Adagrad方法非常适合处理稀疏数据。 diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\351\235\242\350\257\225\351\242\230/image/image_X49t5d33gM.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\351\235\242\350\257\225\351\242\230/image/image_X49t5d33gM.png" new file mode 100644 index 0000000..a102f34 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\351\235\242\350\257\225\351\242\230/image/image_X49t5d33gM.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\351\235\242\350\257\225\351\242\230/image/image_iTMYNBqhpw.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\351\235\242\350\257\225\351\242\230/image/image_iTMYNBqhpw.png" new file mode 100644 index 0000000..7b57c85 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/NLP\351\235\242\350\257\225\351\242\230/image/image_iTMYNBqhpw.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/README.md" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/README.md" new file mode 100644 index 0000000..f1d9cae --- /dev/null +++ "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/README.md" @@ -0,0 +1,35 @@ +# 01.大语言模型基础 + +### 1.1 大模型发展历程 + +[1.语言模型](/docs/01.大语言模型基础/1.语言模型/1.语言模型.md "1.语言模型") + +### 1.2 分词与词向量 + +[1.分词](/docs/01.大语言模型基础/1.分词/1.分词.md "1.分词") + +[2.jieba分词用法及原理](/docs/01.大语言模型基础/2.jieba分词用法及原理/2.jieba分词用法及原理.md "2.jieba分词用法及原理") + +[3.词性标注](/docs/01.大语言模型基础/3.词性标注/3.词性标注.md "3.词性标注") + +[4.句法分析](/docs/01.大语言模型基础/4.句法分析/4.句法分析.md "4.句法分析") + +[5.词向量](/docs/01.大语言模型基础/5.词向量/5.词向量.md "5.词向量") + +### 1.3 语言模型基础知识 + +[Word2Vec](/docs/01.大语言模型基础/Word2Vec/Word2Vec.md "Word2Vec") + +[NLP三大特征抽取器(CNN/RNN/TF)](/docs/01.大语言模型基础/NLP三大特征抽取器(CNN-RNN-TF)/NLP三大特征抽取器(CNN-RNN-TF).md "NLP三大特征抽取器(CNN/RNN/TF)") + +[NLP面试题](/docs/01.大语言模型基础/NLP面试题/NLP面试题.md "NLP面试题") + +[LLM为什么Decoder only架构]( "LLM为什么Decoder only架构") + +### 1.4 深度学习 + +[1.激活函数](/docs/01.大语言模型基础/1.激活函数/1.激活函数.md "1.激活函数") + +### 1.5 一些题目 + +[1.llm概念](/docs/01.大语言模型基础/1.llm概念/1.llm概念.md "1.llm概念") diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/Word2Vec.md" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/Word2Vec.md" new file mode 100644 index 0000000..af074a8 --- /dev/null +++ "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/Word2Vec.md" @@ -0,0 +1,102 @@ +# Word2Vec + +> 文章来源:[Word2Vec详解 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/61635013 "Word2Vec详解 - 知乎 (zhihu.com)") + +## 1.Word2Vec概述 + +Word2Vec是google在2013年推出的一个NLP工具,它的特点**是能够将单词转化为向量来表示,这样词与词之间就可以定量的去度量他们之间的关系,挖掘词之间的联系**。 + +用词向量来表示词并不是Word2Vec的首创,在很久之前就出现了。最早的词向量采用One-Hot编码,又称为一位有效编码,每个词向量维度大小为整个词汇表的大小,对于每个具体的词汇表中的词,将对应的位置置为1。比如下面的5个词组成的词汇表, + +![](image/image_xegDedbBm7.png) + +采用One-Hot编码方式来表示词向量非常简单,但缺点也是显而易见的, + +- 一方面实际使用的**词汇表很大**,经常是百万级以上,这么高维的数据处理起来会消耗大量的计算资源与时间。 +- 另一方面,One-Hot编码中所有词向量之间彼此正交,**没有体现词与词之间的相似关系**。 + +Distributed representation可以解决One-Hot编码存在的问题,它的思路是**通过训练,将原来One-Hot编码的每个词都映射到一个较短的词向量上来**,而这个较短的词向量的维度可以由自己在训练时根据任务需要来指定。 + +下图是采用Distributed representation的一个例子,将词汇表里的词用 "Royalty", "Masculinity", "Femininity" 和 "Age"4个维度来表示,King这个词对应的词向量可能是`(0.99,0.99,0.05,0.7)`。当然在实际情况中,并不能对词向量的每个维度做一个很好的解释。 + +![](image/image_8x5OKKQXHk.png) + +有了用Distributed Representation表示的较短的词向量,就可以较容易的分析词之间的关系了,比如将词的维度降维到2维,有一个有趣的研究表明,用下图的词向量表示词时,可以发现: + +![](image/image_P7NvzKzBBs.png) + +![](image/image_jD259cCWll.png) + +可见只要得到了词汇表里所有词对应的词向量,那么就可以做很多有趣的事情了。不过,怎么训练才能得到合适的词向量呢?针对这个问题,Google的Tomas Mikolov在他的论文中提出了`CBOW`和`Skip-gram`两种神经网络模型。 + +## 2.Word2Vec原理 + +Word2Vec 的训练模型本质上是**只具有一个隐含层的神经元网络**(如下图)。 + +![](image/image_khsPd3FdE0.png) + +它的输入是采用One-Hot编码的词汇表向量,它的输出也是One-Hot编码的词汇表向量。 + +使用所有的样本,训练这个神经元网络,等到收敛之后,从输入层到隐含层的那些权重,便是每一个词的采用Distributed Representation的词向量。比如,上图中单词的Word embedding后的向量便是矩阵$W_{V×N}$ 的第`i`行的转置。这样就把原本维数为`V`的词向量变成了维数为`N`的词向量(N远小于V),并且词向量间保留了一定的相关关系。 + +Google的Mikolov在关于Word2Vec的论文中提出了`CBOW`和`Skip-gram`两种模型,\*\*`CBOW`****适合于数据集较小的情况,而****`Skip-Gram`\*\***在大型语料中表现更好**。 + +- 其中CBOW如下图左部分所示,使用围绕目标单词的其他单词(语境)作为输入,在映射层做加权处理后输出目标单词。 +- 与**CBOW根据语境预测目标单词**不同,**Skip-gram根据当前单词预测语境**,如下图右部分所示。 + +假如有一个句子“`There is an apple on the table`”作为训练数据,CBOW的输入为(is,an,on,the),输出为apple。而Skip-gram的输入为apple,输出为(is,an,on,the)。 + +![](image/image_oEXNCWcnIM.png) + +## **3.CBOW** + +![](image/image_7LTScdZ8Fc.png) + +1. 输入层:**上下文单词的One-Hot编码词向量,V为词汇表单词个数**,C为上下文单词个数。以上文那句话为例,这里C=4,所以模型的输入是(is,an,on,the)4个单词的One-Hot编码词向量。 +2. 初始化一个权重矩阵 $W_{V×N}$ ,然后用所有输入的One-Hot编码词向量左乘该矩阵,得到维数为N的向量 $ω_1,ω_2,…,ω_c$ ,这里的`N`根据任务需要设置。 +3. 将所得的向量 $ω_1,ω_2,…,ω_c$ 相加求平均作为隐藏层向量`h`。 +4. 初始化另一个权重矩阵 $W_{N×V}^{'}$ ,用隐藏层向量$h$左乘 $W_{N×V}^{'}$ ,再经激活函数处理得到$V$维的向量$y$,$y$的每一个元素代表相对应的每个单词的概率分布。 +5. $y$中概率最大的元素所指示的单词为预测出的中间词(target word)与true label的One-Hot编码词向量做比较,误差越小越好(根据误差更新两个权重矩阵) + +在训练前需要定义好损失函数(一般为交叉熵代价函数),采用梯度下降算法更新$W$和$W'$。 + +训练完毕后,输入层的每个单词与矩阵W相乘得到的向量的就是Distributed Representation表示的词向量,也叫做word embedding。因为One-Hot编码词向量中只有一个元素为1,其他都为0,所以第`i`个词向量乘以矩阵$W$得到的就是矩阵的第`i`行,所以这个矩阵也叫做look up table,有了look up table就可以免去训练过程,直接查表得到单词的词向量了。 + +## **4.Skip-gram** + +![](image/image_5vkeXTD1a8.png) + +在前面的章节中,已经介绍过**Skip-Gram是给定input word来预测上下文**,其模型结构如上图所示。 + +它的做法是,将一个词所在的上下文中的词作为输出,而那个词本身作为输入,也就是说,给出一个词,希望预测可能出现的上下文的词。通过在一个大的语料库训练,得到一个从输入层到隐含层的权重模型。“apple”的上下文词是(’there’, ’is’, ’an’, ’on’, ’the’, ’table’ ).那么以apple的One-Hot词向量作为输入,输出则是(’there’, ’is’, ’an’, ’on’, ’the’, ’table’)的One-Hot词向量。训练完成后,就得到了每个词到隐含层的每个维度的权重,就是每个词的向量(和CBOW中一样)。接下来具体介绍如何训练神经网络。 + +假如有一个句子“There is an apple on the table”。 + +1. 首先选句子中间的一个词作为输入词,例如选取“`apple`”作为input word; +2. 有了input word以后,再定义一个叫做`skip_window`的参数,它代表着从当前input word的一侧(左边或右边)选取词的数量。如果设置`skip_window=2`,那么最终获得窗口中的词(包括input word在内)就是\[‘is’,’an’,’apple’,’on’,’the’ ]。`skip_window=2`代表着选取左input word左侧2个词和右侧2个词进入窗口,所以整个窗口大小`span=2x2=4`。另一个参数叫`num_skips`,它代表着从整个窗口中选取多少个不同的词作为output word,当`skip_window=2`,`num_skips=2`时,将会得到两组 (input word, output word) 形式的训练数据,即 ('apple', 'an'),('apple', 'one')。 +3. 神经网络基于这些训练数据中每对单词出现的次数习得统计结果,并输出一个概率分布,这个概率分布代表着到我们词典中每个词有多大可能性跟input word同时出现。举个例子,如果向神经网络模型中输入一个单词“中国“,那么最终模型的输出概率中,像“英国”, ”俄罗斯“这种相关词的概率将远高于像”苹果“,”蝈蝈“非相关词的概率。因为”英国“,”俄罗斯“在文本中更大可能在”中国“的窗口中出现。我们将通过给神经网络输入文本中成对的单词来训练它完成上面所说的概率计算。 +4. 通过梯度下降和反向传播更新矩阵$W$ +5. $W$中的行向量即为每个单词的Word embedding表示 + +在前面两节中介绍了`CBOW`和`Skip-gram`最理想情况下的实现,即训练迭代两个矩阵$W$和$W’$,之后在输出层采用softmax函数来计算输出各个词的概率。但在实际应用中这种方法的训练开销很大,不具有很强的实用性,为了使得模型便于训练,有学者提出了\*\*`Hierarchical Softmax`**和**`Negative Sampling`\*\*两种改进方法。 + +## 5.Hierarchical Softmax + +Hierarchical Softmax对原模型的改进主要有两点, + +1. 第一点是**从输入层到隐藏层的映射**,没有采用原先的与矩阵W相乘然后相加求平均的方法,而是直接对所有输入的词向量**求和**。假设输入的词向量为(0,1,0,0)和(0,0,0,1),那么隐藏层的向量为(0,1,0,1)。 +2. 第二点改进是**采用哈夫曼树来替换了原先的从隐藏层到输出层的矩阵W’**。哈夫曼树的叶节点个数为词汇表的单词个数V,一个叶节点代表一个单词,而从根节点到该叶节点的路径确定了这个单词最终输出的词向量。 + +![](image/image_jkX9FV_w5q.png) + +具体来说,这棵哈夫曼树除了根结点以外的所有非叶节点中都含有一个由参数`θ`确定的sigmoid函数,不同节点中的`θ`不一样。训练时隐藏层的向量与这个sigmoid函数进行运算,根据结果进行分类,若分类为负类则沿左子树向下传递,编码为0;若分类为正类则沿右子树向下传递,编码为1。 + +## 6.Negative Sampling + +尽管哈夫曼树的引入为模型的训练缩短了许多开销,**但对于一些不常见、较生僻的词汇,哈夫曼树在计算它们的词向量时仍然需要做大量的运算**。 + +负采样是另一种用来提高Word2Vec效率的方法,它是基于这样的观察:训练一个神经网络意味着使用一个训练样本就要稍微调整一下神经网络中所有的权重,这样才能够确保预测训练样本更加精确,**如果能设计一种方法每次只更新一部分权重,那么计算复杂度将大大降低**。 + +将以上观察引入Word2Vec就是:当通过(”fox”, “quick”)词对来训练神经网络时,回想起这个神经网络的“标签”或者是“正确的输出”是一个one-hot向量。也就是说,对于神经网络中对应于”quick”这个单词的神经元对应为1,而其他上千个的输出神经元则对应为0。 + +使用负采样,通过随机选择一个较少数目(比如说5个)的“负”样本来更新对应的权重。(在这个条件下,“负”单词就是希望神经网络输出为0的神经元对应的单词)。并且仍然为“正”单词更新对应的权重(也就是当前样本下”quick”对应的神经元仍然输出为1)。 diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_5vkeXTD1a8.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_5vkeXTD1a8.png" new file mode 100644 index 0000000..63c9597 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_5vkeXTD1a8.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_7LTScdZ8Fc.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_7LTScdZ8Fc.png" new file mode 100644 index 0000000..5514a2b Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_7LTScdZ8Fc.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_8x5OKKQXHk.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_8x5OKKQXHk.png" new file mode 100644 index 0000000..2ad5fe7 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_8x5OKKQXHk.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_P7NvzKzBBs.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_P7NvzKzBBs.png" new file mode 100644 index 0000000..1f2c883 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_P7NvzKzBBs.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_jD259cCWll.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_jD259cCWll.png" new file mode 100644 index 0000000..259e821 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_jD259cCWll.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_jkX9FV_w5q.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_jkX9FV_w5q.png" new file mode 100644 index 0000000..7da20b4 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_jkX9FV_w5q.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_khsPd3FdE0.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_khsPd3FdE0.png" new file mode 100644 index 0000000..b0d7535 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_khsPd3FdE0.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_oEXNCWcnIM.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_oEXNCWcnIM.png" new file mode 100644 index 0000000..3b22c1a Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_oEXNCWcnIM.png" differ diff --git "a/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_xegDedbBm7.png" "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_xegDedbBm7.png" new file mode 100644 index 0000000..4c11a53 Binary files /dev/null and "b/docs/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/Word2Vec/image/image_xegDedbBm7.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/1.MoE\350\256\272\346\226\207.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/1.MoE\350\256\272\346\226\207.md" new file mode 100644 index 0000000..780af56 --- /dev/null +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/1.MoE\350\256\272\346\226\207.md" @@ -0,0 +1,237 @@ +# 1.MoE论文 + +参考文章: + +- [Mixture of Experts-Introduction](https://abdulkaderhelwan.medium.com/mixture-of-experts-introduction-39f244a4ff05 "Mixture of Experts-Introduction") +- [Understanding the Mixture-of-Experts Model in Deep Learning](https://medium.com/@jain.sm/understanding-the-mixture-of-experts-model-in-deep-learning-71d2e20650ac "Understanding the Mixture-of-Experts Model in Deep Learning") + +论文相关: + +- 论文名称:Outrageously Large Neural Networks: The Sparsely-Gated Mixture-of-Experts Layer +- 论文地址:[Outrageously Large Neural Networks: The Sparsely-Gated Mixture-of-Experts Layer](https://arxiv.org/abs/1701.06538 "Outrageously Large Neural Networks: The Sparsely-Gated Mixture-of-Experts Layer") + +混合专家(Mixture of Experts,MoE)就像是神经网络世界中的一种团队合作技术。想象一下,把一项大任务分解成更小的部分,让不同的专家来处理每个部分。然后,有一个聪明的法官,他根据情况决定遵循哪位专家的建议,所有这些建议都融合在一起。 + +尽管它最初是用神经网络来解释的,但你可以将这个想法用于任何类型的专家或模型。这有点像你把不同的味道结合在一起做一道美味的菜,这属于一组很酷的综合学习方法,称为元学习。 + +因此,在本文中,将了解专家组合模型的技巧。 + +## 1.摘要 + +- 神经网络的**吸收信息的容量(capacity)受限于**参数数目。 +- **条件计算(conditional computation)****针对于每个样本,** ​**激活网络的部分子网络进行计算**,它在理论上已证明,可以作为一种显著增加模型容量的方法。 +- 在实际中,在牺牲少量计算效率的情况下,实现了 **1000 倍**的**模型容量(model capacity)** 的提升。 +- 引入了**稀疏门控专家混合层(Sparsely-Gated Mixture-of-Experts Layer)**,包括数以千计的前馈子网络。对于每一个样本,有一个**可训练的门控网络(gating network)会计算这些**专家(指前馈子网络)**的**稀疏组合。 +- 把**专家混合(MoE)应用于**语言建模和**机器翻译**任务中,对于这些任务,从训练语料库中吸收的巨量知识,是十分关键的。 +- 在我们提出的模型架构里,MoE 包含 1370 亿个参数,以卷积的方式放在**堆叠 LSTM 层**之间。 +- 在大型语言建模和及其翻译的基准测试中,该模型以更少的计算成本,实现了比最先进方法更好的结果。 + +## 2.介绍和相关工作 + +### 2.1 条件计算 + +**充分利用训练数据和模型大小的规模**,一直以来都是深度学习成功的关键。 + +- 当训练集足够大,增加神经网络的容量(即参数数目),可以得到更高的预测准确度。 +- 对于传统的深度学习模型,**对每一个样本都会激活整个模型**,这会导致在训练成本上,以**大约二次方的速度增长**,因为**模型大小和训练样本数目都增加了**。 +- 当前计算能力和分布式计算的进展,并不能满足这样的需求。 + +因此有很多工作提出了各种形式的条件计算,**它们在不显著增加计算成本的情况下**\*\*,尽量增加模型的容量\*\*。 + +- 在这些算法里,**以每个样本为基础(on a per-example basis)**,会**激活或冻结**网络中的大部分。 +- 这种**门控决策机制**,可以是**二进制的**,也可以是**稀疏而连续的**;可以是**随机性的**,也可以是**确定性的**。 +- 门控决策通过有各种形式的强化学习和反向传播来训练。 + +![](image/image_p_tlx5W7De.png) + +> Figure 1:MoE 层嵌入到循环语言模型中。在本例中,稀疏的门控函数选择**两个专家**来执行计算。门控网络会调整专家的输出。 + +尽管这种思想在理论上很有前景,但是目前为止,还没有工作展现在模型容量、训练时间或模型质量上有足够的提升。我们把原因归结为这些挑战: + +- 现代计算设备(特别是 GPU),相比**分支(branching)而言,在**数值计算上更快。 +- 大的批量大小对于性能很关键。而条件计算减少了批量大小。 +- 网络带宽会成为性能瓶颈。 +- 损失项可能对于实现好的效果是必需的,因此损失项可能会影响模型质量和负载平衡。 +- 对于大型数据集,模型容量是最关键的。目前条件计算的文献处理的图像识别数据集都相对太小了,难以为大模型提供足够多的信号。 + +本文首先解决了上述挑战,并且最后看到了条件计算的前景。 + +- 我们得到了 1000 倍的模型容量提升,只花费了少量计算开销 +- 得到的结果也优于最顶尖的结果 + +### 2.2 本文方法:稀疏门控专家混合层 + +我们的条件计算方法,就是引入了一个新的通用神经网络组件类型:**稀疏门控专家混合层**。 + +MoE 包含: + +- 一些专家,每个专家都是一个**简单的前馈神经网络**。 +- 一个**可训练的门控网络**,它会挑选专家的一个稀疏组合,用来处理每个输入。 +- 所有网络都是**使用反向传播联合训练**的。 + +尽管该技术是通用的,但是本文聚焦在语言建模和机器翻译任务中(这些任务都受益于非常大的模型)。 + +- 具体说来,如图一所示,我们把 MoE **以卷积的方式(convolutionally)放在**多层 LSTM 层之间。 +- 在文本的每个位置上,就会调用 MoE 一次,进而**可能选择不同的专家组合**。 +- 不同的专家**会倾向于变得高度专业化(基于语法和语义)**。 + +## 3.混合专家层的结构 + +### 3.1 MoE层 + +MoE 层包括 : + +- n 个“**专家网络**”:$E1,⋯,En$。 +- 一个**门控网络** $G$,其输出是一个稀疏的 $n$ 维向量。 + +尽管从理论上讲,每个专家网络只要保持一致的输入大小和输出大小就可以了;但是,在本文的研究里,我们限制了专家网络具有相同的网络结构,而网络参数保持独立。 + +给定输入 $x$,定义 $G(x)$是门控网络的输出;$Ei(x)$ 是第 $i$ 个专家网络的输出。于是 MoE 模块的输出为: + +$$ +y=\sum_{i=1}^{n} G(x)_{i} E_{i}(x) +$$ + +基于 $G(x)$ 输出的稀疏性,可以节省计算量。 + +- 当 $G(x)i=0$时,我们无需计算 $Ei(x)$。 +- 在我们的实验中,我们**有数以千计的专家**,但是针对每个样本,只需要用到**少量的专家**。 +- 如果专家数目非常大,我们可能要采用**层次化的 MoE**;本文我们不会使用层次化的 MoE,相关细节感兴趣可以见附录 B。 + +![](image/image_udZNHrE3rb.png) + +### 3.2 层次化MoE + +如果专家数量很大,**可以通过使用两级层次MoE来降低分支因子**。在分层MoE中,主选通网络选择“专家”的稀疏加权组合,每个专家本身就是具有自己选通网络的专家的二次混合。 + +主选通网络是$Gprimary$,次选通网络为$(G1,G2,…,Ga)$,专家网络为$(E0,0,E0,1,…,Ea,b)$。MoE的输出由以下公式给出: + +$$ +y_{H}=\sum_{i=1}^{a} \sum_{j=1}^{b} G_{p r i m a r y}(x)_{i} \cdot G_{i}(x)_{j} \cdot E_{i, j}(x) +$$ + +### 3.3 门控网络 + +#### (1)Softmax Gating + +一种朴素的想法是,用一个矩阵乘上输入,然后经过一个 Softmax 函数,这种方法实际上是一种非稀疏的门控函数: + +$$ +G_{\sigma}(x)=\operatorname{Softmax}\left(x \cdot W_{g}\right) +$$ + +#### (2)Noise Top-K Gating + +在 Softmax 门控网络基础上,\*\*加入两个元素:\*\***稀疏性和噪声**。在执行 Softmax 函数之前: + +我们加入了**可调的高斯噪声**,噪声项是为了帮助**负载均衡(load balancing)**,我们在附录 A 有详细讨论。 + +并且**保留前 k 个值**,其他设置为 $-\infty$。这种稀疏性是为了节省计算资源,**尽管这种形式的稀疏性,从理论上会造成一些可怕的输出间断性**,**但在实际使用中,并没有观察到这种问题**。 + +每个分量的噪音量,通过另一个可训练的权重矩阵 $W_{noise}$ 来控制。 + +$$ +G(x)=\operatorname{Softmax}(\operatorname{KeepTopK}(H(x), k)) +$$ + +$$ +H(x)_{i}=\left(x \cdot W_{g}\right)_{i}+ StandardNormal ()\cdot \operatorname{Softplus}\left(\left(x \cdot W_{\text {noise }}\right)_{i}\right) +$$ + +$$ +KeepTopK (v, k)_{i}=\left\{\begin{array}{ll}v_{i} & \text { if } v_{i} \text { is in the top } k \text { elements of } v \\ -\infty & \text { otherwise. }\end{array}\right. +$$ + +### 3.4训练门控网络 + +使用**简单的反向传播**来训练门控网络以及接下来的模型。 + +## 4.解决性能挑战 + +### 4.1 批量减小问题(The Shrinking Batch Problem) + +由于门控网络对每个样本,在 $n$ 个专家中,选择 $k$ 个。那么对于 $b$个样本的批次,每个转接都会收到更加更加小的批次(大概 $\frac{kb}{n} << b$)。这会导致朴素的 MoE 实现**在专家数量增加时,非常低效**。解决批量减小问题,就是需要让**原始的批量大小尽可能的大**。然而,批量大小会收到内存的限制。我们提出如下技术来提高批量大小: + +- **混合数据并行和模型并行(Mixing Data Parallelism and Model Parallelism)**:相当于变相的扩大b,假设有d个device,每个device上一次处理b个样本,那么在这次训练中,batch=bd,从而每个expert会接收kbd/n个样本。 +- 充分利用卷积 +- 增加循环 MoE 的批量大小 + +### 4.2 网络带宽 + +## 5.平衡专家的利用率 + +我们观察到,门控网络倾向于收敛到**一种不好的状态,即对相同的少量专家,总是会得到较大的权重**。**这种不平衡是不断自我强化的**,随着更好的专家不断训练学习,它们更有可能被门控网络选中。面对这种问题,过去文献有的用**硬性约束**,有的用**软性约束**。 + +而我们采用**软性约束方法**。我们定义对**于一个批次训练样本**的**专家重要度(the importance of an expert)**,即该专家**在一个批次上的门控输出值的和**。并且定义损失项 $L_{importance}$ ,加入到模型的总损失上。该损失项等于**所有专家重要度的方差的平方**,再加上一个手工调节的比例因子 $w_{important}$。这个损失项**会鼓励所有专家有相同的重要度**。 + +$$ +Importance (X)=\sum_{x \in X} G(x) +$$ + +$$ +L_{\text {importance }}(X)=w_{\text {importance }} \cdot C V(\text { Importance }(X))^{2} +$$ + +尽管现在的损失函数可以保证相同的重要度,**专家仍然可能接收到差异很大的样本数目**。例如,某些专家可能接收到少量的大权重的样本;而某些专家可能接收到更多的小权重的样本。为了解决这个问题,我们引入了第二个损失函数:$L_{load} $,它可以保证负载均衡。附录 A 会包含该函数的定义。 + +## 6.实验 + +### 6.1 10 亿词汇的语言建模基准 + +MoE模型:所提出的模型由两个堆叠的LSTM层组成,它们之间有一个MoE层。 + +使用包含4、32和256名专家的平面MoE以及包含256、1024和4096名专家的分层MoE来训练模型。 + +每个专家都有大约100万个参数。 + +对于所有MoE层,每次输入都有4名专家活跃。 + +![](image/image_VVSwgu-e_M.png) + +左图:有4名始终活跃的专家的模型与计算匹配的基线模型表现相似(不足为奇),而最大的模型(4096名专家)在测试集上的困惑度降低了24%,令人印象深刻。 + +右图:与LSTM模型相比,MoE模型在相似的计算预算下实现了更低的困惑。 + +![](image/image_I0Th7l69St.png) + +对于没有MoE的基线模型,观察到的计算效率在1.07–1.29 TFLOPS/GPU之间。 + +对于所提出的低计算MoE模型,计算效率在0.74-0.90 TFLOPS/GPU之间,但4专家模型没有充分利用可用的并行性。 + +计算量最高的MoE模型在1.56 TFLOPS/GPU时效率更高,这可能是由于矩阵更大。 + +### 6.2 1000 亿词汇的谷歌新闻语料库 + +![](image/image_z1BDUvARQu.png) + +当训练超过1000亿个单词时,测试困惑度显著提高,达到65536个专家(680亿个参数),比计算匹配的基线低39%,但在131072个专家时会下降,这可能是稀疏性过大的结果。 + +### 6.3 机器翻译 + +这里使用的MoE模型是[GNMT](https://sh-tsang.medium.com/review-googles-neural-machine-translation-system-bridging-the-gap-between-human-and-machine-518595d87226 "GNMT")的修改版本。 + +为了减少计算,编码器和解码器中的LSTM层的数量分别从9和8减少到3和2。 + +MoE层被插入编码器(在层2和3之间)和解码器(在层1和2之间)中。每个MoE层包含多达2048名专家,每个专家都有大约200万个参数,总共为模型增加了大约80亿个参数。 + +![](image/image_YgHtgi4GYy.png) + +> **Results on WMT’14 En>Fr newstest2014** + +![](image/image_0Q2avdKexQ.png) + +> **Results on WMT’14 En>De newstest2014** + +所提出的方法在WMT’14 En>Fr和En>De基准上获得了40.56和26.03的BLEU分数,优于GNMT和Deep-Att。 + +![](image/image_9vVrb4vP--.png) + +在Google Production数据集上,MoE模型在训练了六分之一的时间后,测试BLEU得分也提高了1.01。 + +![](image/image_kO6_ltd0be.png) + +## 7.结论 + +- 该工作是第一个展现**基于深度网络的条件计算**的重大胜利。 +- 我们探讨了设计考虑、条件计算的挑战、从算法和工程上的解决方案。 +- 虽然我们聚焦在文本领域上,条件计算仍然可以在其他领域发挥作用。我们期望有更多条件计算的实现和应用。 diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_0Q2avdKexQ.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_0Q2avdKexQ.png" new file mode 100644 index 0000000..acfdba8 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_0Q2avdKexQ.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_9vVrb4vP--.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_9vVrb4vP--.png" new file mode 100644 index 0000000..786b53e Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_9vVrb4vP--.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_I0Th7l69St.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_I0Th7l69St.png" new file mode 100644 index 0000000..1e88fd8 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_I0Th7l69St.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_VVSwgu-e_M.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_VVSwgu-e_M.png" new file mode 100644 index 0000000..05c746a Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_VVSwgu-e_M.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_YgHtgi4GYy.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_YgHtgi4GYy.png" new file mode 100644 index 0000000..06c3edd Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_YgHtgi4GYy.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_kO6_ltd0be.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_kO6_ltd0be.png" new file mode 100644 index 0000000..0857c43 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_kO6_ltd0be.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_p_tlx5W7De.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_p_tlx5W7De.png" new file mode 100644 index 0000000..c960eee Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_p_tlx5W7De.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_udZNHrE3rb.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_udZNHrE3rb.png" new file mode 100644 index 0000000..1389963 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_udZNHrE3rb.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_z1BDUvARQu.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_z1BDUvARQu.png" new file mode 100644 index 0000000..6b89cab Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.MoE\350\256\272\346\226\207/image/image_z1BDUvARQu.png" differ diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/1.attention.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/1.attention.md" similarity index 59% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/1.attention.md" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/1.attention.md" index 662ac67..066ba86 100644 --- "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/1.attention.md" +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/1.attention.md" @@ -16,17 +16,17 @@ Attention机制的关键是引入一种机制来动态地计算输入序列中 具体的计算步骤如下: -- **计算查询(Query)**:查询是当前时间步的输入,用于和序列中其他位置的信息进行比较。 -- **计算键(Key)和值(Value)**:键表示序列中其他位置的信息,值是对应位置的表示。键和值用来和查询进行比较。 -- **计算注意力权重**:通过将查询和键进行内积运算,然后应用softmax函数,得到注意力权重。这些权重表示了在当前时间步,模型应该关注序列中其他位置的重要程度。 -- **加权求和**:根据注意力权重将值进行加权求和,得到当前时间步的输出。 +- **计算查询(Query)**:查询是当前时间步的输入,用于和序列中其他位置的信息进行比较。 +- **计算键(Key)和值(Value)**:键表示序列中其他位置的信息,值是对应位置的表示。键和值用来和查询进行比较。 +- **计算注意力权重**:通过将查询和键进行内积运算,然后应用softmax函数,得到注意力权重。这些权重表示了在当前时间步,模型应该关注序列中其他位置的重要程度。 +- **加权求和**:根据注意力权重将值进行加权求和,得到当前时间步的输出。 在Transformer中,Self-Attention 被称为"Scaled Dot-Product Attention",其计算过程如下: -1. 对于输入序列中的每个位置,通过计算其与所有其他位置之间的相似度得分(通常通过点积计算)。 -2. 对得分进行缩放处理,以防止梯度爆炸。 -3. 将得分用softmax函数转换为注意力权重,以便计算每个位置的加权和。 -4. 使用注意力权重对输入序列中的所有位置进行加权求和,得到每个位置的自注意输出。 +1. 对于输入序列中的每个位置,通过计算其与所有其他位置之间的相似度得分(通常通过点积计算)。 +2. 对得分进行缩放处理,以防止梯度爆炸。 +3. 将得分用softmax函数转换为注意力权重,以便计算每个位置的加权和。 +4. 使用注意力权重对输入序列中的所有位置进行加权求和,得到每个位置的自注意输出。 $$ Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt{d_k}})V @@ -56,10 +56,10 @@ self-attention实际只是attention中的一种特殊情况,因此k=v是没有 讲自己熟悉的就可: -- **Scaled Dot-Product Attention**: 这是Transformer模型中最常用的Attention机制,用于计算查询向量(Q)与键向量(K)之间的相似度得分,然后使用注意力权重对值向量(V)进行加权求和。 -- **Multi-Head Attention**: 这是Transformer中的一个改进,通过同时使用多组独立的注意力头(多个QKV三元组),并在输出时将它们拼接在一起。这样的做法允许模型在不同的表示空间上学习不同类型的注意力模式。 -- **Relative Positional Encoding**: 传统的Self-Attention机制在处理序列时并未直接考虑位置信息,而相对位置编码引入了位置信息,使得模型能够更好地处理序列中不同位置之间的关系。 -- **Transformer-XL**: 一种改进的Transformer模型,通过使用循环机制来扩展Self-Attention的上下文窗口,从而处理更长的序列依赖性。 +- **Scaled Dot-Product Attention**: 这是Transformer模型中最常用的Attention机制,用于计算查询向量(Q)与键向量(K)之间的相似度得分,然后使用注意力权重对值向量(V)进行加权求和。 +- **Multi-Head Attention**: 这是Transformer中的一个改进,通过同时使用多组独立的注意力头(多个QKV三元组),并在输出时将它们拼接在一起。这样的做法允许模型在不同的表示空间上学习不同类型的注意力模式。 +- **Relative Positional Encoding**: 传统的Self-Attention机制在处理序列时并未直接考虑位置信息,而相对位置编码引入了位置信息,使得模型能够更好地处理序列中不同位置之间的关系。 +- **Transformer-XL**: 一种改进的Transformer模型,通过使用循环机制来扩展Self-Attention的上下文窗口,从而处理更长的序列依赖性。 #### **1.7 self-attention 在计算的过程中,如何对padding位做mask?** @@ -107,8 +107,8 @@ Attention的计算是在内积之后进行softmax,主要涉及的运算是$e^{ 相应地,解决方法就有两个: -1. 像NTK参数化那样,在内积之后除以 $\sqrt{d}$,使q⋅k的方差变为1,对应$e^3,e^{−3}$都不至于过大过小,这样softmax之后也不至于变成one hot而梯度消失了,这也是常规的Transformer如BERT里边的Self Attention的做法 -2. 另外就是不除以 $\sqrt{d}$,但是初始化q,k的全连接层的时候,其初始化方差要多除以一个d,这同样能使得使q⋅k的初始方差变为1,T5采用了这样的做法。 +1. 像NTK参数化那样,在内积之后除以 $\sqrt{d}$,使q⋅k的方差变为1,对应$e^3,e^{−3}$都不至于过大过小,这样softmax之后也不至于变成one hot而梯度消失了,这也是常规的Transformer如BERT里边的Self Attention的做法 +2. 另外就是不除以 $\sqrt{d}$,但是初始化q,k的全连接层的时候,其初始化方差要多除以一个d,这同样能使得使q⋅k的初始方差变为1,T5采用了这样的做法。 ### 3.BERT @@ -118,13 +118,13 @@ BERT可以使用字粒度(character-level)和词粒度(word-level)两种 字粒度(Character-level): -- **优点**:处理未登录词(Out-of-Vocabulary,OOV):字粒度可以处理任意字符串,包括未登录词,不需要像词粒度那样遇到未登录词就忽略或使用特殊标记。对于少见词和低频词,字粒度可以学习更丰富的字符级别表示,使得模型能够更好地捕捉词汇的细粒度信息。 -- **缺点**:计算复杂度高:使用字粒度会导致输入序列的长度大大增加,进而增加模型的计算复杂度和内存消耗。需要更多的训练数据:字粒度模型对于少见词和低频词需要更多的训练数据来学习有效的字符级别表示,否则可能会导致过拟合。 +- **优点**:处理未登录词(Out-of-Vocabulary,OOV):字粒度可以处理任意字符串,包括未登录词,不需要像词粒度那样遇到未登录词就忽略或使用特殊标记。对于少见词和低频词,字粒度可以学习更丰富的字符级别表示,使得模型能够更好地捕捉词汇的细粒度信息。 +- **缺点**:计算复杂度高:使用字粒度会导致输入序列的长度大大增加,进而增加模型的计算复杂度和内存消耗。需要更多的训练数据:字粒度模型对于少见词和低频词需要更多的训练数据来学习有效的字符级别表示,否则可能会导致过拟合。 词粒度(Word-level): -- **优点**:计算效率高:使用词粒度可以大大减少输入序列的长度,从而降低模型的计算复杂度和内存消耗。学习到更加稳定的词级别表示:词粒度模型可以学习到更加稳定的词级别表示,特别是对于高频词和常见词,有更好的表示能力。 -- **缺点**:处理未登录词(OOV):词粒度模型无法处理未登录词,遇到未登录词时需要采用特殊处理(如使用未登录词的特殊标记或直接忽略)。对于多音字等形态复杂的词汇,可能无法准确捕捉其细粒度的信息。 +- **优点**:计算效率高:使用词粒度可以大大减少输入序列的长度,从而降低模型的计算复杂度和内存消耗。学习到更加稳定的词级别表示:词粒度模型可以学习到更加稳定的词级别表示,特别是对于高频词和常见词,有更好的表示能力。 +- **缺点**:处理未登录词(OOV):词粒度模型无法处理未登录词,遇到未登录词时需要采用特殊处理(如使用未登录词的特殊标记或直接忽略)。对于多音字等形态复杂的词汇,可能无法准确捕捉其细粒度的信息。 #### **3.2 BERT的Encoder与Decoder掩码有什么区别?** @@ -162,18 +162,18 @@ BERT在第一句前会加一个 \[CLS] 标志,**最后一层该位对应向量 学习率warm-up策略的具体做法是,在训练开始的若干个步骤(通常是一小部分训练数据的迭代次数)内,**将学习率逐渐从一个较小的初始值增加到预定的最大学习率**。在这个过程中,学习率的变化是线性的,即学习率在warm-up阶段的每个步骤按固定的步幅逐渐增加。学习率warm-up的目的是为了解决BERT在训练初期的两个问题: -- **不稳定性**:在训练初期,由于模型参数的随机初始化以及模型的复杂性,模型可能处于一个较不稳定的状态。此时使用较大的学习率可能导致模型的参数变动太大,使得模型很难收敛,学习率warm-up可以在这个阶段将学习率保持较小,提高模型训练的稳定性。 -- **避免过拟合**:BERT模型往往需要较长的训练时间来获得高质量的表示。如果在训练的早期阶段就使用较大的学习率,可能会导致模型在训练初期就过度拟合训练数据,降低模型的泛化能力。通过学习率warm-up,在训练初期使用较小的学习率,可以避免过度拟合,等模型逐渐稳定后再使用较大的学习率进行更快的收敛。 +- **不稳定性**:在训练初期,由于模型参数的随机初始化以及模型的复杂性,模型可能处于一个较不稳定的状态。此时使用较大的学习率可能导致模型的参数变动太大,使得模型很难收敛,学习率warm-up可以在这个阶段将学习率保持较小,提高模型训练的稳定性。 +- **避免过拟合**:BERT模型往往需要较长的训练时间来获得高质量的表示。如果在训练的早期阶段就使用较大的学习率,可能会导致模型在训练初期就过度拟合训练数据,降低模型的泛化能力。通过学习率warm-up,在训练初期使用较小的学习率,可以避免过度拟合,等模型逐渐稳定后再使用较大的学习率进行更快的收敛。 #### **3.8 在BERT应用中,如何解决长文本问题?** 在BERT应用中,处理长文本问题有以下几种常见的解决方案: -- **截断与填充**:将长文本截断为固定长度或者进行填充。BERT模型的输入是一个固定长度的序列,因此当输入的文本长度超过模型的最大输入长度时,需要进行截断或者填充。通常,可以根据任务的要求,选择适当的最大长度,并对文本进行截断或者填充,使其满足模型输入的要求。 -- **Sliding Window**:将长文本分成多个短文本,然后分别输入BERT模型。这种方法被称为Sliding Window技术。具体来说,将长文本按照固定的步长切分成多个片段,然后分别输入BERT模型进行处理。每个片段的输出可以进行进一步的汇总或者融合,得到最终的表示。 -- **Hierarchical Model**:使用分层模型来处理长文本,其中底层模型用于处理短文本片段,然后将不同片段的表示进行汇总或者融合得到整个长文本的表示。这样的分层模型可以充分利用BERT模型的表示能力,同时处理长文本。 -- **Longformer、BigBird等模型**:使用专门针对长文本的模型,如Longformer和BigBird。这些模型采用了不同的注意力机制,以处理超长序列,并且通常在处理长文本时具有更高的效率。 -- **Document-Level Model**:将文本看作是一个整体,而不是将其拆分成句子或段落,然后输入BERT模型进行处理。这样的文档级模型可以更好地捕捉整个文档的上下文信息,但需要更多的计算资源。 +- **截断与填充**:将长文本截断为固定长度或者进行填充。BERT模型的输入是一个固定长度的序列,因此当输入的文本长度超过模型的最大输入长度时,需要进行截断或者填充。通常,可以根据任务的要求,选择适当的最大长度,并对文本进行截断或者填充,使其满足模型输入的要求。 +- **Sliding Window**:将长文本分成多个短文本,然后分别输入BERT模型。这种方法被称为Sliding Window技术。具体来说,将长文本按照固定的步长切分成多个片段,然后分别输入BERT模型进行处理。每个片段的输出可以进行进一步的汇总或者融合,得到最终的表示。 +- **Hierarchical Model**:使用分层模型来处理长文本,其中底层模型用于处理短文本片段,然后将不同片段的表示进行汇总或者融合得到整个长文本的表示。这样的分层模型可以充分利用BERT模型的表示能力,同时处理长文本。 +- **Longformer、BigBird等模型**:使用专门针对长文本的模型,如Longformer和BigBird。这些模型采用了不同的注意力机制,以处理超长序列,并且通常在处理长文本时具有更高的效率。 +- **Document-Level Model**:将文本看作是一个整体,而不是将其拆分成句子或段落,然后输入BERT模型进行处理。这样的文档级模型可以更好地捕捉整个文档的上下文信息,但需要更多的计算资源。 ### 4.MHA & MQA & MGA @@ -188,12 +188,12 @@ MultiHead(Q,K,V)=Concat(head_1,...,head_h)W^O \\ where ~ head_i = Attention(QW_i^Q, KW_i^K, VW_i^V) $$ -其中映射由权重矩阵完成:$ W^Q_i \in \mathbb{R}^{d_{{model}} \times d_k} - $, $W^K_i \in \mathbb{R}^{d_{\text{model}} \times d_k}$, $W^V_i \in \mathbb{R}^{d_{\text{model}} \times d_v}$和$W^O_i \in \mathbb{R}^{hd_v \times d_{\text{model}} }$。 +其中映射由权重矩阵完成:$W^Q_i \in \mathbb{R}^{d_{{model}} \times d_k} + $, $W^K_i \in \mathbb{R}^{d_{\text{model}} \times d_k}$, $W^V_i \in \mathbb{R}^{d_{\text{model}} \times d_v}$和$W^O_i \in \mathbb{R}^{hd_v \times d_{\text{model}} }$。 -![](image/image_a986Bo3w29.png) +![](image/image_bfiZnT0f5w.png) -![](image/image_csg11SLMny.png) +![](image/image_XVu-CvbRqc.png) **多头注意力作用** @@ -201,9 +201,9 @@ $$ **为什么要做多头注意力机制呢**? -- 一个 dot product 的注意力里面,没有什么可以学的参数。具体函数就是内积,为了识别不一样的模式,希望有不一样的计算相似度的办法。加性 attention 有一个权重可学,也许能学到一些内容。 -- multi-head attention 给 h 次机会去学习 不一样的投影的方法,使得在投影进去的度量空间里面能够去匹配不同模式需要的一些相似函数,然后把 h 个 heads 拼接起来,最后再做一次投影。 -- 每一个头 hi 是把 Q,K,V 通过 可以学习的 Wq, Wk, Wv 投影到 dv 上,再通过注意力函数,得到 headi。 +- 一个 dot product 的注意力里面,没有什么可以学的参数。具体函数就是内积,为了识别不一样的模式,希望有不一样的计算相似度的办法。加性 attention 有一个权重可学,也许能学到一些内容。 +- multi-head attention 给 h 次机会去学习 不一样的投影的方法,使得在投影进去的度量空间里面能够去匹配不同模式需要的一些相似函数,然后把 h 个 heads 拼接起来,最后再做一次投影。 +- 每一个头 hi 是把 Q,K,V 通过 可以学习的 Wq, Wk, Wv 投影到 dv 上,再通过注意力函数,得到 headi。 #### (2)MQA @@ -213,16 +213,16 @@ MQA的思想其实比较简单,MQA 与 MHA 不同的是,**MQA 让所有的 > Multi-query attention is identical except that the different heads share a single set of keys and values. -![](image/image_1fMJ0cZQXX.png) +![](image/image_N-MRyK7Kjn.png) 在 Multi-Query Attention 方法中只会保留一个单独的key-value头,这样**虽然可以提升推理的速度,但是会带来精度上的损失**。《Multi-Head Attention:Collaborate Instead of Concatenate 》这篇论文的第一个思路是**基于多个 MQA 的 checkpoint 进行 finetuning,来得到了一个质量更高的 MQA 模型**。这个过程也被称为 Uptraining。 具体分为两步: -1. 对多个 MQA 的 checkpoint 文件进行融合,融合的方法是: 通过对 key 和 value 的 head 头进行 mean pooling 操作,如下图。 -2. 对融合后的模型使用少量数据进行 finetune 训练,重训后的模型大小跟之前一样,但是效果会更好 +1. 对多个 MQA 的 checkpoint 文件进行融合,融合的方法是: 通过对 key 和 value 的 head 头进行 mean pooling 操作,如下图。 +2. 对融合后的模型使用少量数据进行 finetune 训练,重训后的模型大小跟之前一样,但是效果会更好 -![](image/image_JHN2n_l4Ek.png) +![](image/image_J3LRkcY0rt.png) #### (3)GQA @@ -230,17 +230,17 @@ Google 在 2023 年发表的一篇 [《GQA: Training Generalized Multi-Query Tra 如下图所示, -- 在 **MHA(Multi Head Attention)** 中,每个头有自己单独的 key-value 对; -- 在 **MQA(Multi Query Attention)** 中只会有一组 key-value 对; -- 在 **GQA(Grouped Query Attention)** 中,会对 attention 进行分组操作,query 被分为 N 组,每个组共享一个 Key 和 Value 矩阵。 +- 在 **MHA(Multi Head Attention)** 中,每个头有自己单独的 key-value 对; +- 在 **MQA(Multi Query Attention)** 中只会有一组 key-value 对; +- 在 **GQA(Grouped Query Attention)** 中,会对 attention 进行分组操作,query 被分为 N 组,每个组共享一个 Key 和 Value 矩阵。 -![](image/image_sWdrRn_dLW.png) +![](image/image_jBnali-wuO.png) GQA-N 是指具有 N 组的 Grouped Query Attention。GQA-1具有单个组,因此具有单个Key 和 Value,等效于MQA。而GQA-H具有与头数相等的组,等效于MHA。 在基于 Multi-head 多头结构变为 Grouped-query 分组结构的时候,也是采用跟上图一样的方法,对每一组的 key-value 对进行 mean pool 的操作进行参数融合。**融合后的模型能力更综合,精度比 Multi-query 好,同时速度比 Multi-head 快**。 -![](image/image_oVa7e8dTfS.png) +![](image/image_mcpY8Z5rJG.png) #### (4)总结 @@ -252,7 +252,7 @@ GQA(Grouped-Query Attention)是分组查询注意力,**GQA将查询头分 GQA介于MHA和MQA之间。GQA 综合 MHA 和 MQA ,既不损失太多性能,又能利用 MQA 的推理加速。不是所有 Q 头共享一组 KV,而是分组一定头数 Q 共享一组 KV,比如上图中就是两组 Q 共享一组 KV。 -![](image/image_Ru8bnKKe6a.png) +![](image/image_25Hri7grcr.png) ### 5.Flash Attention @@ -260,18 +260,18 @@ GQA介于MHA和MQA之间。GQA 综合 MHA 和 MQA ,既不损失太多性能, Flash Attention的主要目的是加速和节省内存,主要贡献包括: -- 计算softmax时候不需要全量input数据,可以分段计算; -- 反向传播的时候,不存储attention matrix (N^2的矩阵),而是只存储softmax归一化的系数。 +- 计算softmax时候不需要全量input数据,可以分段计算; +- 反向传播的时候,不存储attention matrix ($N^2$的矩阵),而是只存储softmax归一化的系数。 #### 5.1 动机 不同硬件模块之间的带宽和存储空间有明显差异,例如下图中左边的三角图,最顶端的是GPU种的`SRAM`,它的容量非常小但是带宽非常大,以A100 GPU为例,它有108个流式多核处理器,每个处理器上的片上SRAM大小只有192KB,因此A100总共的SRAM大小是$192KB\times 108 = 20MB$,但是其吞吐量能高达19TB/s。而A100 GPU `HBM`(High Bandwidth Memory也就是我们常说的GPU显存大小)大小在40GB\~80GB左右,但是带宽只与1.5TB/s。 -![](image/image_vrcUKagqmY.png) +![](image/image_JdHeyN9KuN.png) 下图给出了标准的注意力机制的实现流程,可以看到因为`HBM`的大小更大,**我们平时写pytorch代码的时候最常用到的就是HBM,所以对于HBM的读写操作非常频繁,而SRAM利用率反而不高**。 -![](image/image_xFB7r0ffBw.png) +![](image/image_T3mOuzLLlx.png) FlashAttention的主要动机就是**希望把SRAM利用起来**,但是难点就在于SRAM太小了,一个普通的矩阵乘法都放不下去。FlashAttention的解决思路就是将计算模块进行分解,拆成一个个小的计算任务。 @@ -294,7 +294,7 @@ $$ 因为Softmax都是按行计算的,所以我们考虑一行切分成两部分的情况,即原本的一行数据$x \in \mathbb{R}^{2 B}=\left[x^{(1)}, x^{(2)}\right]$ -![](image/image_dI43hDFDdf.png) +![](image/image_I2wpAfCOTM.png) 可以看到计算不同块的$f(x)$值时,乘上的系数是不同的,但是最后化简后的结果都是指数函数减去了整行的最大值。以$x^{(1)}$ 为例, @@ -306,16 +306,16 @@ $$ FlashAttention旨在避免从 HBM(High Bandwidth Memory)中读取和写入注意力矩阵,这需要做到: -1. 目标一:在不访问整个输入的情况下计算softmax函数的缩减;**将输入分割成块,并在输入块上进行多次传递,从而以增量方式执行softmax缩减**。 -2. 目标二:在后向传播中不能存储中间注意力矩阵。标准Attention算法的实现需要将计算过程中的S、P写入到HBM中,而这些中间矩阵的大小与输入的序列长度有关且为二次型,因此**Flash Attention就提出了不使用中间注意力矩阵,通过存储归一化因子来减少HBM内存的消耗。** +1. 目标一:在不访问整个输入的情况下计算softmax函数的缩减;**将输入分割成块,并在输入块上进行多次传递,从而以增量方式执行softmax缩减**。 +2. 目标二:在后向传播中不能存储中间注意力矩阵。标准Attention算法的实现需要将计算过程中的S、P写入到HBM中,而这些中间矩阵的大小与输入的序列长度有关且为二次型,因此**Flash Attention就提出了不使用中间注意力矩阵,通过存储归一化因子来减少HBM内存的消耗。** FlashAttention算法流程如下图所示: -![](image/image_8bLwsIsXaX.png) +![](image/image_xdtEZOlGec.png) 为方便理解,下图将FlashAttention的计算流程可视化出来了,简单理解就是每一次只计算一个block的值,通过多轮的双for循环完成整个注意力的计算。 -![](image/image_wTr5XFrxJ0.png) +![](image/image_bck1Jw3P5A.png) ### 6.Transformer常见问题 @@ -323,11 +323,11 @@ FlashAttention算法流程如下图所示: 最简单情况:没有残差连接、没有 layernorm、 attention 单头、没有投影。看和 RNN 区别 -- attention 对输入做一个加权和,加权和 进入 point-wise MLP。(画了多个红色方块 MLP, 是一个权重相同的 MLP) -- point-wise MLP 对 每个输入的点 做计算,得到输出。 -- attention 作用:把整个序列里面的信息抓取出来,做一次汇聚 aggregation +- attention 对输入做一个加权和,加权和 进入 point-wise MLP。(画了多个红色方块 MLP, 是一个权重相同的 MLP) +- point-wise MLP 对 每个输入的点 做计算,得到输出。 +- attention 作用:把整个序列里面的信息抓取出来,做一次汇聚 aggregation -![](image/image_j1pIwzyUXi.png) +![](image/image_eb5Z7pLEGk.png) RNN 跟 transformer **异:如何传递序列的信**息 @@ -343,66 +343,66 @@ RNN 跟 transformer **同:语义空间的转换 + 关注点** **Transformer为何使用多头注意力机制?**(为什么不使用一个头) -- 多头保证了transformer可以注意到不同子空间的信息,捕捉到更加丰富的特征信息。可以类比CNN中同时使用**多个滤波器**的作用,直观上讲,多头的注意力**有助于网络捕捉到更丰富的特征/信息。** +- 多头保证了transformer可以注意到不同子空间的信息,捕捉到更加丰富的特征信息。可以类比CNN中同时使用**多个滤波器**的作用,直观上讲,多头的注意力**有助于网络捕捉到更丰富的特征/信息。** **Transformer为什么Q和K使用不同的权重矩阵生成,为何不能使用同一个值进行自身的点乘?** (注意和第一个问题的区别) -- 使用Q/K/V不相同可以保证在不同空间进行投影,增强了表达能力,提高了泛化能力。 -- 同时,由softmax函数的性质决定,实质做的是一个soft版本的arg max操作,得到的向量接近一个one-hot向量(接近程度根据这组数的数量级有所不同)。如果令Q=K,那么得到的模型大概率会得到一个类似单位矩阵的attention矩阵,**这样self-attention就退化成一个point-wise线性映射**。这样至少是违反了设计的初衷。 +- 使用Q/K/V不相同可以保证在不同空间进行投影,增强了表达能力,提高了泛化能力。 +- 同时,由softmax函数的性质决定,实质做的是一个soft版本的arg max操作,得到的向量接近一个one-hot向量(接近程度根据这组数的数量级有所不同)。如果令Q=K,那么得到的模型大概率会得到一个类似单位矩阵的attention矩阵,**这样self-attention就退化成一个point-wise线性映射**。这样至少是违反了设计的初衷。 **Transformer计算attention的时候为何选择点乘而不是加法?两者计算复杂度和效果上有什么区别?** -- K和Q的点乘是为了得到一个attention score 矩阵,用来对V进行提纯。K和Q使用了不同的W\_k, W\_Q来计算,可以理解为是在不同空间上的投影。正因为有了这种不同空间的投影,增加了表达能力,这样计算得到的attention score矩阵的泛化能力更高。 -- 为了计算更快。矩阵加法在加法这一块的计算量确实简单,但是作为一个整体计算attention的时候相当于一个隐层,整体计算量和点积相似。在效果上来说,从实验分析,两者的效果和dk相关,dk越大,加法的效果越显著。 +- K和Q的点乘是为了得到一个attention score 矩阵,用来对V进行提纯。K和Q使用了不同的W\_k, W\_Q来计算,可以理解为是在不同空间上的投影。正因为有了这种不同空间的投影,增加了表达能力,这样计算得到的attention score矩阵的泛化能力更高。 +- 为了计算更快。矩阵加法在加法这一块的计算量确实简单,但是作为一个整体计算attention的时候相当于一个隐层,整体计算量和点积相似。在效果上来说,从实验分析,两者的效果和dk相关,dk越大,加法的效果越显著。 **为什么在进行softmax之前需要对attention进行scaled(为什么除以dk的平方根)**,并使用公式推导进行讲解 -- 这取决于softmax函数的特性,如果softmax内计算的数数量级太大,会输出近似one-hot编码的形式,导致梯度消失的问题,所以需要scale -- 那么至于为什么需要用维度开根号,假设向量q,k满足各分量独立同分布,均值为0,方差为1,那么qk点积均值为0,方差为dk,从统计学计算,若果让qk点积的方差控制在1,需要将其除以dk的平方根,是的softmax更加平滑 +- 这取决于softmax函数的特性,如果softmax内计算的数数量级太大,会输出近似one-hot编码的形式,导致梯度消失的问题,所以需要scale +- 那么至于为什么需要用维度开根号,假设向量q,k满足各分量独立同分布,均值为0,方差为1,那么qk点积均值为0,方差为dk,从统计学计算,若果让qk点积的方差控制在1,需要将其除以dk的平方根,是的softmax更加平滑 **在计算attention score的时候如何对padding做mask操作?** -- padding位置置为负无穷(一般来说-1000就可以),再对attention score进行相加。对于这一点,涉及到batch\_size之类的,具体的大家可以看一下实现的源代码,位置在这里:[https://github.com/huggingface/transformers/blob/aa6a29bc25b663e1311c5c4fb96b004cf8a6d2b6/src/transformers/modeling\_bert.py#L720](https://link.zhihu.com/?target=https://github.com/huggingface/transformers/blob/aa6a29bc25b663e1311c5c4fb96b004cf8a6d2b6/src/transformers/modeling_bert.py#L720 "https://github.com/huggingface/transformers/blob/aa6a29bc25b663e1311c5c4fb96b004cf8a6d2b6/src/transformers/modeling_bert.py#L720") -- padding位置置为负无穷而不是0,是因为后续在softmax时,$e^0=1$,不是0,计算会出现错误;而$e^{-\infty} = 0$,所以取负无穷 +- padding位置置为负无穷(一般来说-1000就可以),再对attention score进行相加。对于这一点,涉及到batch\_size之类的,具体的大家可以看一下实现的源代码,位置在这里:[https://github.com/huggingface/transformers/blob/aa6a29bc25b663e1311c5c4fb96b004cf8a6d2b6/src/transformers/modeling\_bert.py#L720](https://link.zhihu.com/?target=https://github.com/huggingface/transformers/blob/aa6a29bc25b663e1311c5c4fb96b004cf8a6d2b6/src/transformers/modeling_bert.py#L720 "https://github.com/huggingface/transformers/blob/aa6a29bc25b663e1311c5c4fb96b004cf8a6d2b6/src/transformers/modeling_bert.py#L720") +- padding位置置为负无穷而不是0,是因为后续在softmax时,$e^0=1$,不是0,计算会出现错误;而$e^{-\infty} = 0$,所以取负无穷 **为什么在进行多头注意力的时候需要对每个head进行降维?**(可以参考上面一个问题) -- 将原有的**高维空间转化为多个低维空间**并再最后进行拼接,形成同样维度的输出,借此丰富特性信息 - - 基本结构:Embedding + Position Embedding,Self-Attention,Add + LN,FN,Add + LN +- 将原有的**高维空间转化为多个低维空间**并再最后进行拼接,形成同样维度的输出,借此丰富特性信息 + - 基本结构:Embedding + Position Embedding,Self-Attention,Add + LN,FN,Add + LN **为何在获取输入词向量之后需要对矩阵乘以embedding size的开方?意义是什么?** -- embedding matrix的初始化方式是xavier init,这种方式的方差是1/embedding size,因此乘以embedding size的开方使得embedding matrix的方差是1,在这个scale下可能更有利于embedding matrix的收敛。 +- embedding matrix的初始化方式是xavier init,这种方式的方差是1/embedding size,因此乘以embedding size的开方使得embedding matrix的方差是1,在这个scale下可能更有利于embedding matrix的收敛。 **简单介绍一下Transformer的位置编码?有什么意义和优缺点?** -- 因为self-attention是位置无关的,无论句子的顺序是什么样的,通过self-attention计算的token的hidden embedding都是一样的,这显然不符合人类的思维。因此要有一个办法能够在模型中表达出一个token的位置信息,transformer使用了固定的positional encoding来表示token在句子中的绝对位置信息。 +- 因为self-attention是位置无关的,无论句子的顺序是什么样的,通过self-attention计算的token的hidden embedding都是一样的,这显然不符合人类的思维。因此要有一个办法能够在模型中表达出一个token的位置信息,transformer使用了固定的positional encoding来表示token在句子中的绝对位置信息。 **你还了解哪些关于位置编码的技术,各自的优缺点是什么?**(参考上一题) -- 相对位置编码(RPE)1.在计算attention score和weighted value时各加入一个可训练的表示相对位置的参数。2.在生成多头注意力时,把对key来说将绝对位置转换为相对query的位置3.复数域函数,已知一个词在某个位置的词向量表示,可以计算出它在任何位置的词向量表示。前两个方法是词向量+位置编码,属于亡羊补牢,复数域是生成词向量的时候即生成对应的位置信息。 +- 相对位置编码(RPE)1.在计算attention score和weighted value时各加入一个可训练的表示相对位置的参数。2.在生成多头注意力时,把对key来说将绝对位置转换为相对query的位置3.复数域函数,已知一个词在某个位置的词向量表示,可以计算出它在任何位置的词向量表示。前两个方法是词向量+位置编码,属于亡羊补牢,复数域是生成词向量的时候即生成对应的位置信息。 **简单讲一下Transformer中的残差结构以及意义。** -- 就是ResNet的优点,解决梯度消失 +- 就是ResNet的优点,解决梯度消失 **为什么transformer块使用LayerNorm而不是BatchNorm?LayerNorm 在Transformer的位置是哪里?** -- LN:针对每个样本序列进行Norm,没有样本间的依赖。对一个序列的不同特征维度进行Norm -- CV使用BN是认为channel维度的信息对cv方面有重要意义,如果对channel维度也归一化会造成不同通道信息一定的损失。而同理nlp领域认为句子长度不一致,并且各个batch的信息没什么关系,因此只考虑句子内信息的归一化,也就是LN。 +- LN:针对每个样本序列进行Norm,没有样本间的依赖。对一个序列的不同特征维度进行Norm +- CV使用BN是认为channel维度的信息对cv方面有重要意义,如果对channel维度也归一化会造成不同通道信息一定的损失。而同理nlp领域认为句子长度不一致,并且各个batch的信息没什么关系,因此只考虑句子内信息的归一化,也就是LN。 **简答讲一下BatchNorm技术,以及它的优缺点。** -- 优点: - - 第一个就是可以解决内部协变量偏移,简单来说训练过程中,各层分布不同,增大了学习难度,BN缓解了这个问题。当然后来也有论文证明BN有作用和这个没关系,而是可以使**损失平面更加的平滑**,从而加快的收敛速度。 - - 第二个优点就是缓解了**梯度饱和问题**(如果使用sigmoid激活函数的话),加快收敛。 -- 缺点: - - 第一个,batch\_size较小的时候,效果差。这一点很容易理解。BN的过程,使用 整个batch中样本的均值和方差来模拟全部数据的均值和方差,在batch\_size 较小的时候,效果肯定不好。 - - 第二个缺点就是 BN 在RNN中效果比较差。 +- 优点: + - 第一个就是可以解决内部协变量偏移,简单来说训练过程中,各层分布不同,增大了学习难度,BN缓解了这个问题。当然后来也有论文证明BN有作用和这个没关系,而是可以使**损失平面更加的平滑**,从而加快的收敛速度。 + - 第二个优点就是缓解了**梯度饱和问题**(如果使用sigmoid激活函数的话),加快收敛。 +- 缺点: + - 第一个,batch\_size较小的时候,效果差。这一点很容易理解。BN的过程,使用 整个batch中样本的均值和方差来模拟全部数据的均值和方差,在batch\_size 较小的时候,效果肯定不好。 + - 第二个缺点就是 BN 在RNN中效果比较差。 **简单描述一下Transformer中的前馈神经网络?使用了什么激活函数?相关优缺点?** -- ReLU +- ReLU $$ FFN(x)=max(0,~ xW_1+b_1)W_2+b_2 @@ -410,28 +410,28 @@ $$ **Encoder端和Decoder端是如何进行交互的?**(在这里可以问一下关于seq2seq的attention知识) -- Cross Self-Attention,Decoder提供Q,Encoder提供K,V +- Cross Self-Attention,Decoder提供Q,Encoder提供K,V **Decoder阶段的多头自注意力和encoder的多头自注意力有什么区别?**(为什么需要decoder自注意力需要进行 sequence mask) -- 让输入序列只看到过去的信息,不能让他看到未来的信息 +- 让输入序列只看到过去的信息,不能让他看到未来的信息 **Transformer的并行化提现在哪个地方?Decoder端可以做并行化吗?** -- Encoder侧:模块之间是串行的,一个模块计算的结果做为下一个模块的输入,互相之前有依赖关系。从每个模块的角度来说,注意力层和前馈神经层这两个子模块单独来看都是可以并行的,不同单词之间是没有依赖关系的。 -- Decode引入sequence mask就是为了并行化训练,Decoder推理过程没有并行,只能一个一个的解码,很类似于RNN,这个时刻的输入依赖于上一个时刻的输出。 +- Encoder侧:模块之间是串行的,一个模块计算的结果做为下一个模块的输入,互相之前有依赖关系。从每个模块的角度来说,注意力层和前馈神经层这两个子模块单独来看都是可以并行的,不同单词之间是没有依赖关系的。 +- Decode引入sequence mask就是为了并行化训练,Decoder推理过程没有并行,只能一个一个的解码,很类似于RNN,这个时刻的输入依赖于上一个时刻的输出。 **简单描述一下wordpiece model 和 byte pair encoding,有实际应用过吗?** -- 传统词表示方法无法很好的处理未知或罕见的词汇(OOV问题),传统词tokenization方法不利于模型学习词缀之间的关系” -- BPE(字节对编码)或二元编码是一种简单的数据压缩形式,其中最常见的一对连续字节数据被替换为该数据中不存在的字节。后期使用时需要一个替换表来重建原始数据。 -- 优点:可以有效地平衡词汇表大小和步数(编码句子所需的token次数)。 -- 缺点:基于贪婪和确定的符号替换,不能提供带概率的多个分片结果。 +- 传统词表示方法无法很好的处理未知或罕见的词汇(OOV问题),传统词tokenization方法不利于模型学习词缀之间的关系” +- BPE(字节对编码)或二元编码是一种简单的数据压缩形式,其中最常见的一对连续字节数据被替换为该数据中不存在的字节。后期使用时需要一个替换表来重建原始数据。 +- 优点:可以有效地平衡词汇表大小和步数(编码句子所需的token次数)。 +- 缺点:基于贪婪和确定的符号替换,不能提供带概率的多个分片结果。 **Transformer训练的时候学习率是如何设定的?Dropout是如何设定的,位置在哪里?Dropout 在测试的需要有什么需要注意的吗?** -- Dropout测试的时候记得对输入整体呈上dropout的比率 +- Dropout测试的时候记得对输入整体呈上dropout的比率 **引申一个关于bert问题,bert的mask为何不学习transformer在attention处进行屏蔽score的技巧?** -- BERT和transformer的目标不一致,bert是语言的预训练模型,需要充分考虑上下文的关系,而transformer主要考虑句子中第i个元素与前i-1个元素的关系。 +- BERT和transformer的目标不一致,bert是语言的预训练模型,需要充分考虑上下文的关系,而transformer主要考虑句子中第i个元素与前i-1个元素的关系。 diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_Ru8bnKKe6a.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_25Hri7grcr.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_Ru8bnKKe6a.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_25Hri7grcr.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_dI43hDFDdf.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_I2wpAfCOTM.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_dI43hDFDdf.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_I2wpAfCOTM.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_JHN2n_l4Ek.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_J3LRkcY0rt.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_JHN2n_l4Ek.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_J3LRkcY0rt.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_vrcUKagqmY.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_JdHeyN9KuN.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_vrcUKagqmY.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_JdHeyN9KuN.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_1fMJ0cZQXX.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_N-MRyK7Kjn.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_1fMJ0cZQXX.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_N-MRyK7Kjn.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_xFB7r0ffBw.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_T3mOuzLLlx.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_xFB7r0ffBw.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_T3mOuzLLlx.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_csg11SLMny.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_XVu-CvbRqc.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_csg11SLMny.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_XVu-CvbRqc.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_wTr5XFrxJ0.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_bck1Jw3P5A.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_wTr5XFrxJ0.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_bck1Jw3P5A.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_a986Bo3w29.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_bfiZnT0f5w.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_a986Bo3w29.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_bfiZnT0f5w.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_j1pIwzyUXi.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_eb5Z7pLEGk.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_j1pIwzyUXi.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_eb5Z7pLEGk.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_sWdrRn_dLW.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_jBnali-wuO.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_sWdrRn_dLW.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_jBnali-wuO.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_oVa7e8dTfS.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_mcpY8Z5rJG.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_oVa7e8dTfS.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_mcpY8Z5rJG.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_8bLwsIsXaX.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_xdtEZOlGec.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/1.attention/image/image_8bLwsIsXaX.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/1.attention/image/image_xdtEZOlGec.png" diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215.md" new file mode 100644 index 0000000..e3452af --- /dev/null +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215.md" @@ -0,0 +1,358 @@ +# 2.MoE经典论文简牍 + +参考资料: + +- [MoE (Mixture-of-Experts) 经典文章简读]( "MoE (Mixture-of-Experts) 经典文章简读") +- [Mixture-of-Experts (MoE) 经典论文一览](https://zhuanlan.zhihu.com/p/542465517 "Mixture-of-Experts (MoE) 经典论文一览") + +## 1.开创工作 + +### 1.1 Adaptive mixtures of local experts, Neural Computation'1991 + +- 期刊/会议:Neural Computation (1991) +- 论文链接:[https://readpaper.com/paper/2150884987](https://readpaper.com/paper/2150884987 "https://readpaper.com/paper/2150884987") +- 代表性作者:Michael Jordan, Geoffrey Hinton + +这是大多数MoE论文都引用的最早的一篇文章,发表于1991年,作者中有两个大家熟知的大佬:Michael Jordan 和 Geoffrey Hinton。 + +提出了一种新的监督学习过程,**一个系统中包含多个分开的网络,每个网络去处理全部训练样本的一个子集**。这种方式可以看做是把多层网络进行了**模块化的转换**。 + +假设我们已经知道数据集中存在一些天然的子集(比如来自不同的domain,不同的topic),那么用单个模型去学习,就会受到很多干扰(interference),导致学习很慢、泛化困难。这时,我们可以使用多个模型(即专家,expert)去学习,使用一个门网络(gating network)来决定每个数据应该被哪个模型去训练,这样就可以减轻不同类型样本之间的干扰。 + +其实这种做法,也不是该论文第一次提出的,更早就有人提出过类似的方法。对于一个样本 c,第 i 个 expert 的输出为 $\mathbf{o}_i^c$,理想的输出是 $\mathbf{d}^c$,那么损失函数就这么计算: + +$$ +\mathrm{E}^{\mathrm{c}}=\left\|\mathbf{d}^{\mathrm{c}}-\sum_{\mathrm{i}} \mathrm{p}_{\mathrm{i}}^{\mathrm{c}} \mathbf{o}_{\mathrm{i}}^{\mathrm{c}}\right\|^{2} +$$ + +其中 $p_i^c$ 是 gating network 分配给每个 expert 的权重,相当于多个 expert 齐心协力来得到当前样本 c 的输出。 + +这是一个很自然的设计方式,但是存在一个问题——**不同的 expert 之间的互相影响会非常大**,一个expert的参数改变了,其他的都会跟着改变,即所谓牵一发而动全身。这样的设计,最终的结果就是一个样本会使用很多的expert来处理。于是,这篇文章设计了一种新的方式,**调整了一下loss的设计,来鼓励不同的expert之间进行竞争**: + +$$ +E^{\mathrm{c}}=\sum_{i} p_{i}^{c}\left\|\mathbf{d}^{c}-\mathbf{o}_{i}^{\mathrm{c}}\right\|^{2} +$$ + +就是**让不同的 expert 单独计算 loss,然后在加权求和得到总体的 loss**。这样的话,每个专家,都有独立判断的能力,而不用依靠其他的 expert 来一起得到预测结果。下面是一个示意图: + +![](image/image_D7Q_-tp2dm.png) + +在这种设计下,我们将 experts 和 gating network 一起进行训练,最终的系统就会倾向于让一个 expert 去处理一个样本。 + +上面的**两个 loss function,其实长得非常像,但是一个是鼓励合作,一个是鼓励竞争**。这一点还是挺启发人的。 + +论文还提到另外一个很启发人的 trick,就是上面那个损失函数,作者在实际做实验的时候,用了一个变体,使得效果更好: + +$$ +Original : \mathrm{E}^{\mathrm{c}}=\sum_{i} \mathrm{p}_{\mathrm{i}}^{\mathrm{c}}\left\|\mathbf{d}^{\mathrm{c}}-\mathbf{o}_{\mathrm{i}}^{\mathrm{c}}\right\|^{2} +$$ + +$$ +Modified : \mathrm{E}^{\mathrm{c}}=-\log \sum_{\mathrm{i}} \mathrm{p}_{\mathrm{i}}^{\mathrm{C}} \mathrm{e}^{-\frac{1}{2}\left\|\mathrm{~d}^{\mathrm{c}}-\mathbf{o}_{\mathrm{i}}^{\mathrm{c}}\right\|^{2}} +$$ + +对比一下可以看出,在计算每个 expert 的损失之后,**先把它给指数化了再进行加权求和,最后取了log**。这也是一个我们在论文中经常见到的技巧。这样做有什么好处呢,我们可以对比一下二者在反向传播的时候有什么样的效果,使用$ E^c $对 第 i 个 expert 的输出求导,分别得到: + +$$ +original ~derivative: \frac{\partial E^{c}}{\partial \mathbf{o}_{i}^{c}}=-2 p_{i}^{c}\left(\mathbf{d}^{c}-\mathbf{o}_{i}^{c}\right) +$$ + +$$ +new~derivative: \frac{\partial E^{c}}{\partial \mathbf{o}_{i}^{c}}=-\left[\frac{p_{i}^{c} e^{-\frac{1}{2}\left\|\mathbf{d}^{c}-\mathbf{o}_{i}^{c}\right\|^{2}}}{\sum_{j} p_{j}^{c} e^{-\frac{1}{2}\left\|\mathbf{d}^{c}-\mathbf{o}_{j}^{c}\right\|^{2}}}\right]\left(\mathbf{d}^{c}-\mathbf{o}_{i}^{c}\right) +$$ + +可以看到,**前者的导数,只会跟当前 expert 有关,但后者则还考虑其他 experts 跟当前 sample c 的匹配程度**。换句话说,如果当前 sample 跟其他的 experts 也比较匹配,那么 $E^c $对 第 i 个 expert 的输出的导数也会相对更小一下。(其实看这个公式,跟我们现在遍地的对比学习loss真的很像!很多道理都是相通的) + +以上就是这篇文章的理论部分,其实很简单,但它提到的MoE的设计,启发了后续无数的工作。 + +接下来一篇则是时隔20多年后的另一篇经典论文,可能也是大家更熟悉的MoE工作。 + +### 1.2 Outrageously Large Neural Networks: The Sparsely-Gated Mixture-of-Experts Layer, ICLR'17 + +- 期刊/会议:ICLR'17 +- 论文链接:[https://readpaper.com/paper/2952339051](https://readpaper.com/paper/2952339051 "https://readpaper.com/paper/2952339051") +- 代表性作者:Quoc Le, Geoffrey Hinton, Jeff Dean + +在 2010 至 2015 年间,两个独立的研究领域为混合专家模型 (MoE) 的后续发展做出了显著贡献: + +1. **组件专家**:在传统的 MoE 设置中,整个系统由一个门控网络和多个专家组成。在支持向量机 (SVMs) 、高斯过程和其他方法的研究中,MoE 通常被视为整个模型的一部分。然而,Eigen、Ranzato 和 Ilya 的研究 探索了将 MoE 作为更深层网络的一个组件。这种方法**允许将 MoE 嵌入到多层网络中的某一层,使得模型既大又高效**。 +2. **条件计算(Conditional Computation)**:传统的神经网络通过每一层处理所有输入数据。在这一时期,Yoshua Bengio 等研究人员开始探索**基于输入 token 动态激活或停用网络组件**的方法。 + +在 2017 年,Shazeer 等人将这一概念应用于 137B 的 LSTM 。通过引入稀疏性,这项工作在保持极高规模的同时实现了快速的推理速度。在牺牲极少的计算效率的情况下,把模型规模提升**1000多倍**。 + +这篇文章,从title上就可以看出来它的背景和目的——希望做出极大的神经网络。在此之前,有很多 **conditional computational** 的工作,在理论上可以在有限的计算成本内把模型做的非常大,但是那些方法在具体实现的时候,有各种各样的问题。这篇文章提出了 Sparsely-Gated Mixture-of-Experts layer ,声称终于解决了传统 conditional computational 的问题,在牺牲极少的计算效率的情况下,把模型规模提升1000多倍。 + +#### (1)Sparsely-Gated Mixture-of-Experts layer + +跟1991年那个工作对比,这里的MoE主要有两个区别: + +- **Sparsely-Gated**:不是所有expert都会起作用,而是极少数的expert会被使用来进行推理。这种稀疏性,也使得我们可以使用海量的experts来把模型容量做的超级大。 +- **token-level**:前面那个文章,是 sample-level 的,即不同的样本,使用不同的experts,但是这篇则是 token-level 的,一个句子中不同的token使用不同的experts。 + +这篇文章是在RNN的结构上加入了MoE layer: + +![](image/image_1x57Hvfk4-.png) + +如图所示,每个token对应的position,都会有一个MoE Layer,每个MoE layer中包含了一堆的experts,每个expert都是一个小型的FFN,还有一个gating network会根据当前position的输入,选择少数几个expert来进行计算。 + +#### (2)Gating Network + +设 $G(x)$ 和 $E_i(x) $分别是 gating network 和第 i 个 expert 的输出,那么对于在当前position的输入x,输出就是所有 experts 的加权和: + +$$ +\mathrm{y}=\sum_{\mathrm{i}=1}^{\mathrm{n}} \mathrm{G}(\mathrm{x})_{\mathrm{i}} \mathrm{E}_{\mathrm{i}}(\mathrm{x}) +$$ + +(跟第一篇论文的第一个公式类似) + +但是这里我们可能有上千个 experts,如果每个都算的话,计算量会非常大,所以这里的一个关键就是希望 G(x) 的输出是稀疏的,只有部分的 experts 的权重是大于 0 的,其余等于 0 的 expert 直接不参与计算。 + +首先看传统的 gating network 如何设计: + +$$ +\mathrm{G}_{\sigma}(\mathrm{x})=\operatorname{Softmax}\left(\mathrm{x} \cdot \mathrm{W}_{\mathrm{g}}\right) +$$ + +然后,作者**加入了 sparsity 和 noise**: + +$$ +\mathrm{G}(\mathrm{x})=\operatorname{Softmax}(\operatorname{KeepTopK}(\mathrm{H}(\mathrm{x}), \mathrm{k})) +$$ + +$$ +\mathrm{H}(\mathrm{x})_{\mathrm{i}}=\left(\mathrm{x} \cdot \mathrm{W}_{\mathrm{g}}\right)_{\mathrm{i}}+\operatorname{StandardNormal}() \cdot \operatorname{Softplus}\left(\left(\mathrm{x} \cdot \mathrm{W}_{\text {noise }}\right)_{\mathrm{i}}\right) +$$ + +$$ +\operatorname{KeepTopK}(\mathrm{v}, \mathrm{k})_{\mathrm{i}}=\left\{\begin{array}{ll}\mathrm{v}_{\mathrm{i}}, & \text { if } \mathrm{v}_{\mathrm{i}} \text { intopKelements. } \\ -\infty, & \text { otherwise. }\end{array}\right. +$$ + +总而言之,**sparsity 是通过 TopK sampling 的方式实现的,对于非 TopK 的部分,由于值是负无穷,这样在经过 softmax 之后就会变成 0,就相当于关门了**。noise 项则可以使得不同 expert 的负载更加均衡。在具体实验中,作者使用的K=2\~4. + +#### (3)Expert Balancing + +作者在实验中发现,不同 experts 在竞争的过程中,会出现“**赢者通吃**”的现象:前期变现好的 expert 会更容易被 gating network 选择,导致最终只有少数的几个 experts 真正起作用。因此作者**额外增加了一个 loss,来缓解这种不平衡现象**,公式如下: + +$$ +\operatorname{Importance}(\mathrm{X})=\sum_{\mathrm{x} \in \mathrm{X}} \mathrm{G}(\mathrm{x}) +$$ + +$$ +\mathrm{L}(\mathrm{X})=\lambda \cdot \mathrm{CV}(\text { Importance }(\mathrm{X}))^{2} +$$ + +其中 X 代表的是一个batch的样本,把一个batch所有样本的gating weights加起来,然后计算变异系数( coefficient of variation)。总之,**这个反映了不同 experts 之间不平衡的程度**。最后这个 loss 会加到总体 loss 中,鼓励不同的 experts 都发挥各自的作用。 + +上面就是 Sparsely-Gated MoE的主要理论,作者主要在 language modeling 和 machine translation 两个任务上做了实验,因为这两个任务,都是特别受益于大数据和大模型的,而本文的MoE的作用主要就在于极大地扩大了模型容量——通过MoE,把RNN-based网络做到了137B(1.3千亿)参数的规模,还是挺震撼的。效果自然也是极好的。 + +经过训练呢,作者发现不同的 experts 确实分化出了不同的“专业”: + +![](image/image_rVDNuxgPVj.png) + +上面的两篇,是MoE系列工作的基础,接下来介绍的工作,都是近几年的比较出名的工作: + +## 2.使用 MoE 开发超大模型 + +### 2.1 GShard: Scaling Giant Models with Conditional Computation and Automatic Sharding, ICLR'21 + +- 期刊/会议:ICLR'21 +- 论文链接:[https://readpaper.com/paper/3040573126](https://readpaper.com/paper/3040573126 "https://readpaper.com/paper/3040573126") + +GShard,按照文章的说法,是第一个将MoE的思想拓展到Transformer上的工作。具体的做法是,把Transformer的encoder和decoder中,**每隔一个(every other)的FFN层,替换成position-wise 的 MoE 层**,使用的都是 Top-2 gating network。 + +![](image/image_lQMB2Iboc6.png) + +1. **标准 Transformer(a)**:是标准的Transformer编码器,其中每个 token 通过一个标准的 FFN。 +2. **MoE Transformer(b)**:将每隔一个的 FFN 层替换为 MoE 层。这意味着在编码器中,不再是每个 token 都通过相同的 FFN,而是通过一个由多个专家组成的 MoE 层。 +3. **MoE跨设备分片(c)**:它展示了 MoE 层是如何在多个设备上进行分片的。GShard MoE 层中的**专家网络(experts)被分布在不同的设备上**。每个专家网络负责处理一部分输入数据,并且每个 token 根据门控机制的输出被分配到一个或两个专家网络中。这样,整个 MoE 层的计算被分散到了多个设备上,每个设备负责处理一部分计算任务。 + +实现 **MoE 跨设备分片的关键技术是模型并行化(model parallelism)和数据并行化(data parallelism)的结合**。在模型并行化中,模型的不同部分(在这里是 MoE 层的专家网络)被分配到不同的设备上。在数据并行化中,输入数据(token)被分割成多个部分,每个部分被分配给不同的设备进行处理。 + +为了实现这种分片,论文中提到的 GShard 模块提供了一套 API 和编译器扩展,允许用户在模型代码中简单地注释关键张量,指定它们应该如何在设备集群上进行分片。这样,编译器就可以自动地将计算图(computation graph)转换为可以在多个设备上并行执行的程序,而不需要用户手动处理复杂的数据分片和通信逻辑。 + +由于专家被分配到不同设备,可以并行计算,因此大大提升了模型的计算效率,这也解释了为什么 MoE 可以实现更大模型参数、更低训练成本。 + +为了保持负载平衡和训练效率,GShard 的作者除了引入上节 Sparsely-Gated MoE 中的辅助 loss 外,还引入了一些关键变化: + +- **随机路由****:** 在 Top-2 设置中,GShard 始终选择排名最高的专家,但第二个专家是根据其权重比例随机选择的。 +- **专家容量****:** 可以设定一个阈值,定义一个专家能处理多少 token。如果两个专家的容量都达到上限,token 就会溢出,并通过残差连接传递到下一层,或在某些情况下被完全丢弃。专家容量是 MoE 中最重要的概念之一。为什么需要专家容量呢?因为所有张量的形状在编译时是静态确定的,无法提前知道多少 token 会分配给每个专家,因此需要一个固定的容量因子。 + +**注意:** 在推理过程中,只有部分专家被激活。同时,有些计算过程是共享的,例如自注意力 (self-attention) 机制,它适用于所有 token。**这就解释了为什么我们可以使用相当于 12B Dense 模型的计算资源来运行一个包含 8 个专家的 47B 模型**。如果我们采用 Top-2 门控,模型会使用高达 14B 的参数。但是,由于自注意力操作 (专家间共享) 的存在,实际上模型运行时使用的参数数量是 12B。 + +文中还提到了很多其他设计: + +- **Expert capacity balancing**:强制每个expert处理的tokens数量在一定范围内 +- **Local group dispatching**:通过把一个batch内所有的tokens分组,来实现并行化计算 +- **Auxiliary loss**:也是为了缓解“赢者通吃”问题 +- **Random routing**:在Top-2 gating的设计下,两个expert如何更高效地进行routing + +### 2.2 Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity, JMLR'22 + +- 期刊/会议:JMLR'22 +- 论文链接:[https://readpaper.com/paper/4568736324836663297](https://readpaper.com/paper/4568736324836663297 "https://readpaper.com/paper/4568736324836663297") + +虽然发表是2022年才在发表在JMLR上,Swith Transformer实际上在21年就提出了。它是在**T5模型的基础上加入了MoE设计**,并在C4数据集上预训练,得到了一个“又快又好”的预训练大模型。 + +Swith Transformer 的主要亮点在于——**简化了MoE的routing算法,从而大大提高了计算效率。** + +结构如下: + +![](image/image_cnGyuh6Kw3.png) + +Swith Transformer 在论文中提到其设计的指导原则是——**尽可能地把Transformer模型的参数量做大!**(同时以一种简单高效的实现方式) + +跟其他MoE模型的一个显著不同就是,**Switch Transformer 的 gating network 每次只 route 到 1 个 expert**,而其他的模型都是至少2个。这样就是最稀疏的MoE了,因此单单从MoE layer的计算效率上讲是最高的了。 + +下图展示了在同样的计算开销下,增大 experts 个数带来的性能提升,反正就是全面吊打T5,而且效率还一样: + +![](image/image_3niPTBi3o0.png) + +### 2.3 GLaM: Efficient Scaling of Language Models with Mixture-of-Experts, 2021 + +- 年份:2021 +- 论文链接:[https://readpaper.com/paper/4568736324836663297](https://readpaper.com/paper/4568736324836663297 "https://readpaper.com/paper/4568736324836663297") +- Google Blog:[https://ai.googleblog.com/2021/12/more-efficient-in-context-learning-with.html](https://ai.googleblog.com/2021/12/more-efficient-in-context-learning-with.html "https://ai.googleblog.com/2021/12/more-efficient-in-context-learning-with.html") + +这是Google在2021年推出的一个超大模型,比GPT-3大三倍,但是由于使用了Sparse MoE的设计,训练成本却只有GPT-3的1/3,而且在29个NLP任务上超越了GPT-3。 + +下面这个来自Google Blog的动图很形象地展示了GLaM的结构: + +![](image/202207161754344_nuPlFNzwnm.gif) + +其实我们可以发现,跟GShard几乎一模一样。 + +![](image/image_xsMOpXbwwg.png) + +上表展示了GLaM跟其他大模型的对比。可以看到,虽然GLaM的总参数量有1.2T,但是在计算式实际激活的参数量只有96B,所以在inference的时候,比GPT-3等dense model要快得多。 + +GLaM使用的数据量也比Switch-Transformer等要大得多: + +![](image/image_3z0xeTLkc7.png) + +反正最终的结果,是一个比GPT-3更快更强大的通用LM。 + +### 2.4 小结 + +上面的三篇文章(GShard,Switch-Transformer,GLaM)都是希望通过MoE的方式把模型做得尽可能的大,大到普通人玩不起(动辄使用几百个experts),下面介绍的两篇文章,则更加亲民一点,是关于如何利用MoE去压缩模型、提高效率: + +## 3.使用 MoE 来使模型轻量化 + +### 3.1 Go Wider Instead of Deeper, AAAI'22 + +- 期刊/会议:AAAI'22 +- 论文链接:[https://readpaper.com/paper/3184020733](https://readpaper.com/paper/3184020733 "https://readpaper.com/paper/3184020733") + +这个文章名字比较唬人,思路也比较新颖,所以介绍一下。 + +它提出了名为 WideNet 的结构,想解决的主要问题是,如何**在压缩模型参数量的情况下取得更好的效果**。比如Albert通过参数共享机制降低了BERT的参数量,像tiny-bert之类的则是减少了Transformer的层数,但他们的性能都有了显著的下降。这篇文章提出,**首先通过层之间的参数共享,来压缩模型大小,然后我们使用MoE的设计,扩大模型容量**(但是模型在feed forward的时候计算量并没怎么提升),这样就可以达到“既要模型参数少,还要模型效果好”的效果。示意图如下: + +![](image/image_WMSl4mCQ7U.png) + +咋一看,似乎跟前面几个文章一模一样,但这里有一个重要区别:**使用了recurrence机制**,即层之间的参数共享(MoE layer也共享)。另外,为了增加学习的多样性,**normalization layer 并不共享**。 + +具体实现时,这里使用总共4个experts,每次选择Top2. + +这样做的结果也挺不错: + +![](image/image_IigTUYPzCu.png) + +### 3.2 MoEBERT: from BERT to Mixture-of-Experts via Importance-Guided Adaptation, NAACL'22 + +- 期刊/会议:NAACL'22 +- 论文链接:[https://readpaper.com/paper/4614341372211634177](https://readpaper.com/paper/4614341372211634177 "https://readpaper.com/paper/4614341372211634177") + +这一篇文章,则是结合了 MoE 和 knowledge distillation,在提升 inference 速度的情况下,还能提高效果。主要想解决传统的distillation方法掉点的问题。具体做法是把一个**预训练好**的模型(比如BERT)的FFN层分解成多个experts,这样在计算的时候速度可以大幅提高(相当于只激活原始FFN网络的一部分)。然后再通过模型蒸馏把原始模型的知识蒸馏到MoE版本的模型中。 + +注意这个文章其实跟上面介绍的WideNet类似,也是为了减少参数量。但有一个区别在于,WideNet是自己从头开始pre-train的,但是本文的MoEBERT则是想尽可能地把已经pre-train好的模型迁移过来,通过distillation的方式在downstream task上直接学。 + +因此,如果按照传统的方式让模型自由的去学习不同的experts,效果可能不好,因为你没有大量的数据来预训练。所以这里涉及到一个关键步骤—— **Importance-Guided Adaptation**: + +在把 Transformer 中的FFN layer 改造成 MoE layer 时,我们先去计算 FFN layer 各个 neuron 的 importance,计算公式如下: + +$$ +I_{j}=\sum_{(x, y) \in \mathcal{D}}\left|\left(\mathbf{w}_{j}^{1}\right)^{\top} \nabla_{\mathbf{w}_{j}^{1}} \mathcal{L}(x, y)+\left(\mathbf{w}_{j}^{2}\right)^{\top} \nabla_{\mathbf{w}_{j}^{2}} \mathcal{L}(x, y)\right| +$$ + +这里的 $w^1$ 和 $w^2$ 分别是 FFN layer 的某个 neuron 的输出和输出 weights vector,这个 importance score 也被应用于很多 model pruning 的工作中来衡量网络的某个 unit 的重要性。然后,在把 FFN 分解的时候,我们**取最重要的一部分 neurons 在每个expert 中共享**,剩下的部分平均分配到每个 expert。由于共享机制的存在,一定会多出一些 neurons,这部分就直接丢弃。(注意,这里我们并没有增加模型的参数量,而只是把一个全连接的FFN层,分解成多个sub-networks,加起来的参数量实际上是一样的) + +这个示意图很形象: + +![](image/image_iYtKkZD0Ug.png) + +另外一个值得注意的点在于 expert routing 的方式,这里没有使用一个 gating network,而是**在训练前直接给每个 token 都随机分配了一个 expert** (具体是通过一个 hash function)。 + +在distillation部分,这里使用的逐层的distillation MSE loss,以及最后预测概率的 KL loss,二者加起来就是distillation 所使用的 loss。然后,再和原本自己的 CE loss 加起来,就是总体模型训练的loss。这里是直接在downstream dataset上面进行训练,属于 task-specific distillation。 + +![](image/image_c6fklKPWPX.png) + +实验的结果也验证了 MoEBERT可以在同样参数量(effective parameters,MoE layer中只考虑被激活的experts)的情况下超越其他 distillation baselines。 + +值得注意的时,这里的baselines中,task-agnostic的方法都使用了预训练,而task-specific都没有预训练。总体上看,使用了预训练的模型,效果都会更好一些,但是MoEBERT打破了这个规律,在只使用task dataset的情况下,取得了SOTA的结果。 + +![](image/image_BiVZc3sw9g.png) + +图a验证了前面提到的 Importance-Guided Adaptation 的有效性;图b则是验证了通过hash function的方式,而不是 trainable gating的方式来进行routing 的有效性。 + +## 4.ST-MOE + +之前讨论的负载均衡损失可能会导致稳定性问题。我们可以使用许多方法来稳定稀疏模型的训练,但这可能会牺牲模型质量。例如,引入 dropout 可以提高稳定性,但会导致模型质量下降。 + +### 4.1 用 Router z-loss 稳定模型训练 + +在论文 [ST-MOE: Designing Stable and Transferable Sparse Expert Models](https://arxiv.org/pdf/2202.08906.pdf "ST-MOE: Designing Stable and Transferable Sparse Expert Models") 中,作者提出了一种新的辅助损失函数,称为 **Router z-loss**,**用于提高稀疏模型的训练稳定性,同时保持或稍微提高模型质量**。这个损失函数是针对稀疏专家模型中的路由器(router)部分设计的,路由器负责将输入的 token 路由到最合适的专家(expert)层。 + +在 MoE 模型中,每个输入 token 可能被路由到多个专家,但通常只有一个专家层会被激活。为了确保路由器能够稳定地工作并产生高质量的输出,作者引入了 Router z-loss。**这个损失函数的目标是鼓励路由器产生较小的logits 值,因为较大的 logits 值在 softmax 激活函数中会导致较大的梯度,这可能会引起训练不稳定**。 + +Router z-loss 的定义如下: + +$$ +L_{z}(\boldsymbol{x})=\frac{1}{B} \sum_{i=1}^{B}\left(\log \sum_{j=1}^{N} e^{x_{j}^{(i)}}\right)^{2} +$$ + +其中, B 是 batch 中的 token 数量, N 是专家的数量, ${x}\in \mathbb{R}^{B\times N}$ 是路由器的 logits。这个损失函数通过惩罚较大的 logits 值来工作,因为这些值在 softmax 函数中会导致较大的梯度。通过这种方式,Router z-loss 有助于减少训练过程中的不稳定性,并可能提高模型的泛化能力。 + +### 4.2 专家如何学习? + +ST-MoE 的研究者们发现,**Encorder 中不同的专家倾向于专注于特定类型的 token 或浅层概念**。例如,某些专家可能专门处理标点符号,而其他专家则专注于专有名词等。与此相反,Decorder 中的专家通常具有较低的专业化程度。此外,研究者们还对这一模型进行了多语言训练。尽管人们可能会预期每个专家处理一种特定语言,但实际上并非如此。由于 token 路由和负载均衡的机制,没有任何专家被特定配置以专门处理某一特定语言。 + +### 4.3 专家的数量对预训练有何影响? + +增加更多专家可以提升处理样本的效率和加速模型的运算速度,但这些优势随着专家数量的增加而递减 (尤其是当专家数量达到 256 或 512 之后更为明显)。同时,这也意味着在推理过程中,需要更多的显存来加载整个模型。值得注意的是,Switch Transformers 的研究表明,其在大规模模型中的特性在小规模模型下也同样适用,即便是每层仅包含 2、4 或 8 个专家。 + +### 4.4 Fine-Tuning MoE 模型 + +稠密模型和稀疏模型在过拟合的动态表现上存在显著差异。**稀疏模型更易于出现过拟合现象**,因此在处理这些模型时,尝试更强的内部正则化措施是有益的,比如**使用更高比例的 dropout**。例如,可以为稠密层设定一个较低的 dropout 率,而为稀疏层设置一个更高的 dropout 率,以此来优化模型性能。 + +在 Fine-Tuning 过程中是否使用辅助损失是一个需要决策的问题。ST-MoE 的作者尝试关闭辅助损失,发现即使高达 11% 的 token 被丢弃,模型的质量也没有显著受到影响。token 丢弃可能是一种正则化形式,有助于防止过拟合。 + +实验观察到,在相同的预训练 PPL 下,稀疏模型在下游任务中的表现不如对应的稠密模型,特别是在理解任务 (如 SuperGLUE) 上。另一方面,对于知识密集型任务 (如 TriviaQA),稀疏模型的表现异常出色。作者还观察到,在Fine-Tuning 过程中,较少的专家的数量有助于改善性能。另一个关于泛化问题确认的发现是,模型在小型任务上表现较差,但在大型任务上表现良好。 + +![](image/image_hMVmIJ_f_u.png) + +> 在小任务 (左图) 中,我们可以看到明显的过拟合,因为稀疏模型在验证集中的表现要差得多。在较大的任务 (右图) 中,MoE 则表现良好。 + +**一种可行的 Fine-Tuning 策略是尝试冻结所有非专家层的权重。实践中,这会导致性能大幅下降,可以尝试相反的方法:仅冻结 MoE 层的参数**。实验结果显示,这种方法几乎与更新所有参数的效果相当。这种做法可以加速 Fine-Tuning 过程,并降低显存需求。 + +![](image/image_Jm65z_ylUq.png) + +> 通过仅冻结 MoE 层,我们可以在保持模型效果的同时加快训练速度 + +在 Fine-Tuning MoE 时还需要考虑的一个问题是,它们有需要特殊设置的超参数,例如,**稀疏模型往往更适合使用较小的 batch size 和较高的学习率**,这样可以获得更好的训练效果。 + +![](image/image_ZTbIIpd07A.png) + +> 提高学习率和降低batch size可以提升稀疏模型微调效果 + +## 5.结语 + +以上总结了一下笔者在阅读 MoE 相关文献时印象较深的几篇文章,上述所阅读的文献主要与NLP相关的,其实 MoE 在各个领域中的应用已经十分广泛。比如Google提出的多模态MoE模型——LIMoE: + +![](https://cdn.jsdelivr.net/gh/beyondguo/mdnice_pictures/typora/202207162019899.gif) + +另外,跟 MoE 的理念相关的还有很多有趣的工作,比如: + +**Diverse Ensemble Evolution: Curriculum Data-Model Marriage**, NeurIPS'18 + +**Diversity and Depth in Per-Example Routing Models**, ICLR'21 + +MoE 的思想,其实十分符合 Google 提出的 Pathways 愿景,也更加符合通用人工智能的设计理念。虽然目前 MoE 的工作,多数都是开发“超级模型”,但是上面列举的一些工作也表明 MoE 的用途还有很多,可以启发很多方向上方法的改进。 diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/202207161754344_nuPlFNzwnm.gif" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/202207161754344_nuPlFNzwnm.gif" new file mode 100644 index 0000000..b404c44 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/202207161754344_nuPlFNzwnm.gif" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_1x57Hvfk4-.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_1x57Hvfk4-.png" new file mode 100644 index 0000000..0c06dc1 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_1x57Hvfk4-.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_3niPTBi3o0.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_3niPTBi3o0.png" new file mode 100644 index 0000000..baa57f7 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_3niPTBi3o0.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_3z0xeTLkc7.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_3z0xeTLkc7.png" new file mode 100644 index 0000000..75ba2f4 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_3z0xeTLkc7.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_BiVZc3sw9g.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_BiVZc3sw9g.png" new file mode 100644 index 0000000..da0ca70 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_BiVZc3sw9g.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_D7Q_-tp2dm.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_D7Q_-tp2dm.png" new file mode 100644 index 0000000..f57e2e6 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_D7Q_-tp2dm.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_IigTUYPzCu.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_IigTUYPzCu.png" new file mode 100644 index 0000000..96682f3 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_IigTUYPzCu.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_Jm65z_ylUq.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_Jm65z_ylUq.png" new file mode 100644 index 0000000..fec1a12 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_Jm65z_ylUq.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_WMSl4mCQ7U.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_WMSl4mCQ7U.png" new file mode 100644 index 0000000..bfcd2c3 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_WMSl4mCQ7U.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_ZTbIIpd07A.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_ZTbIIpd07A.png" new file mode 100644 index 0000000..f935da3 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_ZTbIIpd07A.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_c6fklKPWPX.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_c6fklKPWPX.png" new file mode 100644 index 0000000..1b45752 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_c6fklKPWPX.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_cnGyuh6Kw3.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_cnGyuh6Kw3.png" new file mode 100644 index 0000000..c758980 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_cnGyuh6Kw3.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_hMVmIJ_f_u.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_hMVmIJ_f_u.png" new file mode 100644 index 0000000..5075ef3 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_hMVmIJ_f_u.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_iYtKkZD0Ug.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_iYtKkZD0Ug.png" new file mode 100644 index 0000000..e4638c1 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_iYtKkZD0Ug.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_lQMB2Iboc6.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_lQMB2Iboc6.png" new file mode 100644 index 0000000..f59c111 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_lQMB2Iboc6.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_rVDNuxgPVj.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_rVDNuxgPVj.png" new file mode 100644 index 0000000..44b05bd Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_rVDNuxgPVj.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_xsMOpXbwwg.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_xsMOpXbwwg.png" new file mode 100644 index 0000000..a33a557 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.MoE\347\273\217\345\205\270\350\256\272\346\226\207\347\256\200\347\211\215/image/image_xsMOpXbwwg.png" differ diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.layer_normalization/2.layer_normalization.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.layer_normalization/2.layer_normalization.md" similarity index 61% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.layer_normalization/2.layer_normalization.md" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.layer_normalization/2.layer_normalization.md" index 9f8e875..9ca3889 100644 --- "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.layer_normalization/2.layer_normalization.md" +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.layer_normalization/2.layer_normalization.md" @@ -6,8 +6,8 @@ **为什么要进行BN呢?** -1. 在深度神经网络训练的过程中,通常以输入网络的每一个mini-batch进行训练,这样每个batch具有不同的分布,使模型训练起来特别困难。 -2. Internal Covariate Shift (ICS) 问题:在训练的过程中,激活函数会改变各层数据的分布,随着网络的加深,这种改变(差异)会越来越大,使模型训练起来特别困难,收敛速度很慢,会出现梯度消失的问题。 +1. 在深度神经网络训练的过程中,通常以输入网络的每一个mini-batch进行训练,这样每个batch具有不同的分布,使模型训练起来特别困难。 +2. Internal Covariate Shift (ICS) 问题:在训练的过程中,激活函数会改变各层数据的分布,随着网络的加深,这种改变(差异)会越来越大,使模型训练起来特别困难,收敛速度很慢,会出现梯度消失的问题。 **BN的主要思想:** 针对每个神经元,**使数据在进入激活函数之前,沿着通道计算每个batch的均值、方差,‘强迫’数据保持均值为0,方差为1的正态分布,** 避免发生梯度消失。具体来说,就是把第1个样本的第1个通道,加上第2个样本第1个通道 ...... 加上第 N 个样本第1个通道,求平均,得到通道 1 的均值(注意是除以 N×H×W 而不是单纯除以 N,最后得到的是一个代表这个 batch 第1个通道平均值的数字,而不是一个 H×W 的矩阵)。求通道 1 的方差也是同理。对所有通道都施加一遍这个操作,就得到了所有通道的均值和方差。 @@ -15,24 +15,24 @@ **BN算法过程:** -- 沿着通道计算每个batch的均值 -- 沿着通道计算每个batch的方差 -- 做归一化 -- 加入缩放和平移变量$\gamma$和 $\beta$ +- 沿着通道计算每个batch的均值 +- 沿着通道计算每个batch的方差 +- 做归一化 +- 加入缩放和平移变量$\gamma$和 $\beta$ **加入缩放和平移变量的原因是:****保证每一次数据经过归一化后还保留原有学习来的特征,同时又能完成归一化操作,加速训练****。** 这两个参数是用来学习的参数。 **BN的作用:** -1. 允许较大的学习率; -2. 减弱对初始化的强依赖性 -3. 保持隐藏层中数值的均值、方差不变,让数值更稳定,为后面网络提供坚实的基础; -4. 有轻微的正则化作用(相当于给隐藏层加入噪声,类似Dropout) +1. 允许较大的学习率; +2. 减弱对初始化的强依赖性 +3. 保持隐藏层中数值的均值、方差不变,让数值更稳定,为后面网络提供坚实的基础; +4. 有轻微的正则化作用(相当于给隐藏层加入噪声,类似Dropout) **BN存在的问题:** -1. 每次是在一个batch上计算均值、方差,如果batch size太小,则计算的均值、方差不足以代表整个数据分布。 -2. **batch size太大:** 会超过内存容量;需要跑更多的epoch,导致总训练时间变长;会直接固定梯度下降的方向,导致很难更新。 +1. 每次是在一个batch上计算均值、方差,如果batch size太小,则计算的均值、方差不足以代表整个数据分布。 +2. **batch size太大:** 会超过内存容量;需要跑更多的epoch,导致总训练时间变长;会直接固定梯度下降的方向,导致很难更新。 #### 1.2 Layer Norm @@ -65,9 +65,9 @@ nn.LayerNorm(normalized_shape, eps=1e-05, elementwise_affine=True, device=None, ``` -- `normalized_shape`:归一化的维度,int(最后一维)list(list里面的维度),还是以(2,2,4)为例,如果输入是int,则必须是4,如果是list,则可以是\[4], \[2,4], \[2,2,4],即最后一维,倒数两维,和所有维度 -- `eps`:加在分母方差上的偏置项,防止分母为0 -- `elementwise_affine`:是否使用可学习的参数 $\gamma$ 和 $\beta$ ,前者开始为1,后者为0,设置该变量为True,则二者均可学习随着训练过程而变化 +- `normalized_shape`:归一化的维度,int(最后一维)list(list里面的维度),还是以(2,2,4)为例,如果输入是int,则必须是4,如果是list,则可以是\[4], \[2,4], \[2,2,4],即最后一维,倒数两维,和所有维度 +- `eps`:加在分母方差上的偏置项,防止分母为0 +- `elementwise_affine`:是否使用可学习的参数 $\gamma$ 和 $\beta$ ,前者开始为1,后者为0,设置该变量为True,则二者均可学习随着训练过程而变化 Layer Normalization (LN) 的一个优势是不需要批训练,在单条数据内部就能归一化。LN不依赖于batch size和输入sequence的长度,因此可以用于batch size为1和RNN中。**LN用于RNN效果比较明显,但是在CNN上,效果不如BN**。 @@ -119,21 +119,21 @@ $$ Deep Norm是对Post-LN的的改进,具体的: -![](image/image_tBur6fdXlq.png) +![](image/image_fcdX03TpGw.png) -- DeepNorm在进行Layer Norm之前会以 $\alpha$ 参数扩大残差连接 -- 在Xavier参数初始化过程中以 $\beta$ 减小部分参数的初始化范围 +- DeepNorm在进行Layer Norm之前会以 $\alpha$ 参数扩大残差连接 +- 在Xavier参数初始化过程中以 $\beta$ 减小部分参数的初始化范围 一些模型的具体参数使用方法如下: -![](image/image_z_QzsiMH0n.png) +![](image/image_ITQgjCSDK3.png) 论文中,作者认为 Post-LN 的不稳定性部分来自于**梯度消失**以及**太大的模型更新**,同时,有以下几个理论分析 -- 定义了“预期模型更新”的概念表示 模型更新的规模量级 -- 证明了 $W^Q$和 $W^K$不会改变注意力输出大小数量级的界限,因而 $\beta$ 并没有缩小这部分参数 -- 模型倾向于**累积每个子层的更新**,从而**导致模型更新量呈爆炸式增长**,从而使早期优化变得不稳定 -- 使用Deep Norm 的 "预期模型更新",在参数 $\alpha, \beta$ 取值适当的时候,以**常数为界** +- 定义了“预期模型更新”的概念表示 模型更新的规模量级 +- 证明了 $W^Q$和 $W^K$不会改变注意力输出大小数量级的界限,因而 $\beta$ 并没有缩小这部分参数 +- 模型倾向于**累积每个子层的更新**,从而**导致模型更新量呈爆炸式增长**,从而使早期优化变得不稳定 +- 使用Deep Norm 的 "预期模型更新",在参数 $\alpha, \beta$ 取值适当的时候,以**常数为界** 同时,作者通过实验证实了Deep Norm在训练深层transformer模型的时候具备近乎恒定的更新规模,成功训练了1000层transformer的模型,认为Deep Norm在**具备 Post-LN 的良好性能 的同时又有 Pre-LN 的稳定训练** @@ -143,32 +143,32 @@ Deep Norm是对Post-LN的的改进,具体的: 常用的Normalization方法主要有: -- Batch Normalization(BN,2015年)、 -- Layer Normalization(LN,2016年)、 -- Instance Normalization(IN,2017年)、 -- Group Normalization(GN,2018年)。 +- Batch Normalization(BN,2015年)、 +- Layer Normalization(LN,2016年)、 +- Instance Normalization(IN,2017年)、 +- Group Normalization(GN,2018年)。 它们都是从激活函数的输入来考虑、做文章的,以不同的方式**对激活函数的输入进行 Norm** 的。 将输入的 **feature map shape** 记为\*\*`[N, C, H, W]`\*\*,其中N表示batch size,即N个样本;C表示通道数;H、W分别表示特征图的高度、宽度。这几个方法主要的区别就是在: -1. BN是在batch上,对N、H、W做归一化,而保留通道 C 的维度。**BN对较小的batch size效果不好。BN适用于固定深度的前向神经网络**,如CNN,不适用于RNN; -2. LN在通道方向上,对C、H、W归一化,主要对RNN效果明显; -3. IN在图像像素上,对H、W做归一化,用在风格化迁移; -4. GN将channel分组,然后再做归一化。 +1. BN是在batch上,对N、H、W做归一化,而保留通道 C 的维度。**BN对较小的batch size效果不好。BN适用于固定深度的前向神经网络**,如CNN,不适用于RNN; +2. LN在通道方向上,对C、H、W归一化,主要对RNN效果明显; +3. IN在图像像素上,对H、W做归一化,用在风格化迁移; +4. GN将channel分组,然后再做归一化。 -![](image/image_H-qqhIZN7R.png) +![](image/image_Mokps-OIR4.png) **比喻成一摞书,这摞书总共有 N 本,每本有 C 页,每页有 H 行,每行 有W 个字符。** -1. BN 求均值时,相当于把这些书按页码一一对应地加起来(例如第1本书第36页,第2本书第36页......),再除以每个页码下的字符总数:N×H×W,因此可以把 BN 看成求“平均书”的操作(注意这个“平均书”每页只有一个字),求标准差时也是同理。 -2. LN 求均值时,相当于把每一本书的所有字加起来,再除以这本书的字符总数:C×H×W,即求整本书的“平均字”,求标准差时也是同理。 -3. IN 求均值时,相当于把一页书中所有字加起来,再除以该页的总字数:H×W,即求每页书的“平均字”,求标准差时也是同理。 -4. GN 相当于把一本 C 页的书平均分成 G 份,每份成为有 C/G 页的小册子,求每个小册子的“平均字”和字的“标准差”。 +1. BN 求均值时,相当于把这些书按页码一一对应地加起来(例如第1本书第36页,第2本书第36页......),再除以每个页码下的字符总数:N×H×W,因此可以把 BN 看成求“平均书”的操作(注意这个“平均书”每页只有一个字),求标准差时也是同理。 +2. LN 求均值时,相当于把每一本书的所有字加起来,再除以这本书的字符总数:C×H×W,即求整本书的“平均字”,求标准差时也是同理。 +3. IN 求均值时,相当于把一页书中所有字加起来,再除以该页的总字数:H×W,即求每页书的“平均字”,求标准差时也是同理。 +4. GN 相当于把一本 C 页的书平均分成 G 份,每份成为有 C/G 页的小册子,求每个小册子的“平均字”和字的“标准差”。 ### 3.Post-LN 和 Pre-LN -![](image/image_Si5uzH-BcO.png) +![](image/image_b-krqJfMii.png) 左边是原版Transformer的Post-LN,即将LN放在addition之后;右边是改进之后的Pre-LN,即把LN放在FFN和MHA之前。 @@ -176,15 +176,15 @@ Deep Norm是对Post-LN的的改进,具体的: 目前比较明确的结论是:**同一设置之下,Pre Norm结构往往更容易训练,但最终效果通常不如Post Norm**。Pre Norm更容易训练好理解,因为它的恒等路径更突出,但为什么它效果反而没那么好呢?[为什么Pre Norm的效果不如Post Norm? ](https://kexue.fm/archives/9009 "为什么Pre Norm的效果不如Post Norm? ") -![](image/image_2_HYkL7k8X.png) +![](image/image_VptxQJRer9.png) 参考资料: -- [Batch Normalization](https://arxiv.org/pdf/1502.03167.pdf "Batch Normalization") -- [Layer Normalization](https://arxiv.org/abs/1607.06450 "Layer Normalization") -- [Instance Normalization](https://arxiv.org/pdf/1607.08022.pdf "Instance Normalization") -- [Group Normalization](https://arxiv.org/pdf/1803.08494.pdf "Group Normalization") -- [Root Mean Square Layer Normalization](https://arxiv.org/abs/1910.07467 "Root Mean Square Layer Normalization") -- [Group Normalization](https://arxiv.org/abs/1803.08494 "Group Normalization") -- [Deep Normalization](https://link.zhihu.com/?target=https://arxiv.org/pdf/2203.00555.pdf "Deep Normalization") -- [A Survey of Large Language Models](https://arxiv.org/abs/2303.18223 "A Survey of Large Language Models") +- [Batch Normalization](https://arxiv.org/pdf/1502.03167.pdf "Batch Normalization") +- [Layer Normalization](https://arxiv.org/abs/1607.06450 "Layer Normalization") +- [Instance Normalization](https://arxiv.org/pdf/1607.08022.pdf "Instance Normalization") +- [Group Normalization](https://arxiv.org/pdf/1803.08494.pdf "Group Normalization") +- [Root Mean Square Layer Normalization](https://arxiv.org/abs/1910.07467 "Root Mean Square Layer Normalization") +- [Group Normalization](https://arxiv.org/abs/1803.08494 "Group Normalization") +- [Deep Normalization](https://link.zhihu.com/?target=https://arxiv.org/pdf/2203.00555.pdf "Deep Normalization") +- [A Survey of Large Language Models](https://arxiv.org/abs/2303.18223 "A Survey of Large Language Models") diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.layer_normalization/image/image_z_QzsiMH0n.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.layer_normalization/image/image_ITQgjCSDK3.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.layer_normalization/image/image_z_QzsiMH0n.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.layer_normalization/image/image_ITQgjCSDK3.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.layer_normalization/image/image_H-qqhIZN7R.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.layer_normalization/image/image_Mokps-OIR4.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.layer_normalization/image/image_H-qqhIZN7R.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.layer_normalization/image/image_Mokps-OIR4.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.layer_normalization/image/image_2_HYkL7k8X.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.layer_normalization/image/image_VptxQJRer9.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.layer_normalization/image/image_2_HYkL7k8X.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.layer_normalization/image/image_VptxQJRer9.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.layer_normalization/image/image_Si5uzH-BcO.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.layer_normalization/image/image_b-krqJfMii.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.layer_normalization/image/image_Si5uzH-BcO.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.layer_normalization/image/image_b-krqJfMii.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.layer_normalization/image/image_tBur6fdXlq.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.layer_normalization/image/image_fcdX03TpGw.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/2.layer_normalization/image/image_tBur6fdXlq.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/2.layer_normalization/image/image_fcdX03TpGw.png" diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/3.LLM MoE \357\274\232Switch Transformers.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/3.LLM MoE \357\274\232Switch Transformers.md" new file mode 100644 index 0000000..7b88fce --- /dev/null +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/3.LLM MoE \357\274\232Switch Transformers.md" @@ -0,0 +1,322 @@ +# 3.LLM MoE :Switch Transformers + +## 0.前言 + +GPT-4远不止1万亿,甚至,还是8个2200亿参数组成的混合专家模型(**MoE**)。 + +2023年6月,美国知名骇客George Hotz在接受采访时透露,GPT-4由8个220B模型组成。这么算来,8 x 220B = 1.76万亿。就连PyTorch的创建者Soumith Chintala对此也深信不疑。 + +MoE 应用于大模型,GPT-4并不是第一个。在2022年的时候,Google 就提出了MoE大模型**Switch Transformer**,模型大小是1571B,Switch Transformer在预训练任务上显示出比 T5-XXL(11B) 模型更高的样本效率。在相同的训练时间和计算资源下,Switch Transformer 能够达到更好的性能。 + +除了GPT-4和Switch Transformer,国内的团队DeepSeek 也**开源了国内首个 MoE** 大模型 **DeepSeekMoE**。 + +- DeepSeekMoE **2B可接近2B Dense,仅用了17.5%计算量。** +- DeepSeekMoE **16B性能比肩 LLaMA2 7B 的同时,仅用了40%计算量。** +- DeepSeekMoE **145B 优于Google 的MoE大模型GShard,而且仅用 28.5%计算量即可匹配 67B Dense 模型的性能。** + +## 1.什么是MoE大模型? + +MoE,全称为Mixed Expert Models,翻译过来就是混合专家模型。MoE并不是什么最新技术,早在1991年的时候,论文[Adaptive Mixture of Local Experts](https://www.cs.toronto.edu/~hinton/absps/jjnh91.pdf "Adaptive Mixture of Local Experts")就提出了MoE。 + +**模型规模是提升模型性能的关键因素之一**,这也是为什么今天的大模型能取得成功。在有限的计算资源预算下,用更少的训练步数训练一个更大的模型,往往比用更多的步数训练一个较小的模型效果更佳。 + +MoE 的一个显著优势是它们**能够在远少于 Dense 模型所需的计算资源下进行有效的预训练**。这意味着在相同的计算预算条件下,可以显著扩大模型或数据集的规模。特别是在预训练阶段,与稠密模型相比,混合专家模型通常能够更快地达到相同的质量水平。 + +MoE基于Transformer架构,主要由两部分组成: + +- **稀疏 MoE 层**\*\*:\*\* 这些层代替了传统 Transformer 模型中的前馈网络 (FFN) 层。MoE 层包含若干“专家”(例如 8 个),每个专家本身是一个独立的神经网络。在实际应用中,这些专家通常是前馈网络 (FFN),但它们也可以是更复杂的网络结构。 +- **门控网络或路由**: 这个部分用于决定哪些 token 被发送到哪个专家。例如,在下图中,“More”这个 token 可能被发送到第二个专家,而“Parameters”这个 token 被发送到第一个专家。有时,一个 token 甚至可以被发送到多个专家。token 的路由方式是 MoE 使用中的一个关键点,因为路由器由学习的参数组成,并且与网络的其他部分一同进行预训练。 + +![](image/image_tuuC2Qgzr-.png) + +> Google Switch Transformer论文中的MoE结构 + +总结来说,在混合专家模型 (MoE) 中,将传统 Transformer 模型中的每个前馈网络 (FFN) 层替换为 MoE 层,其中 MoE 层由两个核心部分组成: **一个路由器(或者叫门控网络)和若干数量的专家**。 + +## 2.MoE大模型具备哪些优势? + +MoE的最大优势就是与Dense模型相比,**在相同计算资源下,训练速度更快,而且可以训练更大的模型**。比如Google的Switch Transformer,模型大小是T5-XXL的15倍,在相同计算资源下,Switch Transformer模型在达到固定困惑度 PPL 时,比T5-XXL模型**快4倍**。 + +相同计算资源下,Google的MoE大模型能够**在相同计算资源下,以更快的速度达到相同的PPL,而且模型是T5的15倍**;DeepSeek的16B MoE大模型,仅在40%的计算量的情况下,性能和LLaMA 2 7B效果比肩。 + +总结MoE大模型优点,主要有以下几点点: + +1. **训练速度更快,效果更好**\*\*。\*\* +2. **相同参数,推理成本低**\*\*。\*\* +3. **扩展性好**,允许模型在保持计算成本不变的情况下增加参数数量,这使得它能够扩展到非常大的模型规模,如万亿参数模型。 +4. **多任务学习能力**:MoE在多任务学习中具备很好的新能(比如Switch Transformer在所有101种语言上都显示出了性能提升,证明了其在多任务学习中的有效性)。 + +而MoE大模型的缺点,主要有以下4点: + +1. **训练稳定性**:MoE在训练过程中可能会遇到稳定性问题。 +2. **通信成本**:在分布式训练环境中,MoE的专家路由机制可能会增加通信成本,尤其是在模型规模较大时。 +3. **模型复杂性**:MoE的设计相对复杂,可能需要更多的工程努力来实现和优化。 +4. **下游任务性能**:MoE由于其稀疏性,使得在Fine-tuning过程中容易出现过拟合。 + +接下来,就介绍下MoE的主要原理。通过后面的介绍,主要需要回答以下3个问题: + +1. **MoE为什么可以实现更大模型参数、更低训练成本?** +2. **MoE如何解决训练稳定性问题?** +3. **MoE如何解决Fine-Tuning过程中的过拟合问题?** + +## 3.Switch Transformers + +尽管 MoE 显示出了很大的潜力,但是由于复杂性、通信成本以及训练和微调过程的不稳定性,模型广泛采用仍需要优化。 + +而在2022年,Google 提出的 [Switch Transformers](https://arxiv.org/pdf/2101.03961.pdf "Switch Transformers") 一定程度缓解了这些问题。Switch Transformers 是一项非常激动人心的工作,它深入研究了这些话题。作者在 Hugging Face 上发布了一个 [1.6 万亿参数的 MoE](https://huggingface.co/google/switch-c-2048 "1.6 万亿参数的 MoE"),拥有 2048 个专家,可以使用 `transformers` 库来运行它。Switch Transformers 实现了与 T5-XXL 相比 4 倍的预训练速度提升。 + +Switch Transformers\*\* 简化了 MoE 路由算法,设计了直观的改进模型,降低了通信和计算成本\*\*。Switch Transformers 的训练方法减轻了不稳定性,并且首次展示了用较低精度(bfloat16)格式训练大型稀疏模型的可能性。 + +**和 T5 Base、T5 Large 相比,Switch Transformers 在相同计算资源情况下获得了高达 7 倍的预训练速度**。在多语言实验中,Switch Transformers 在所有 101 种语言测试中都取得了提升。Switch Transformers 通过在爬虫语料库上预训练了一个高大万亿参数规模的模型,实现了与 T5-XXL 相比4倍的加速。 + +![](image/image_LrMLT8kaVX.png) + +> 左图:增加模型稀疏性(更多专家),loss逐渐降低(图中256e表示256个 experts) +> 右图:Switch Transformers 和 T5-Base 的对比(相同计算资源) + +上图中,模型参数随着专家数量的增加而增加,但保持了相同的计算成本(FLOPs per token)。这表明模型在保持计算效率的同时,能够利用更多的参数来提高性能。 + +右图中比较了使用相同计算资源下,Switch Transformer 和 T5-Base 的 PPL。可以看到 Switch Transformer 模型在保持相同计算资源的情况下,相对于 T5-Base 有显著的提升,而且专家数越多(模型参数越多、模型更稀疏),效果越好。 + +### 3.1 Switch Transformer 主要优化 + +Swith Transformer 在论文中提到其设计的指导原则是——**尽可能地把 Transformer 模型的参数量做大**\*\*!\*\*(同时以一种简单高效的实现方式) + +和其他 MoE 模型的一个显著不同就是,**Switch Transformer 的门控网络每次只路由到 1 个 expert**,也就是每次只选取 top1 的专家,而其他的模型都是至少 2 个。这样就是最稀疏的 MoE 了,因此单单从 MoE layer 的计算效率上讲是最高的了。下图是 Switch Transformer 的模型结构。 + +![](image/image_WYGAroS1fy.png) + +> Switch Transformer encoder模块,使用稀疏的Switch FFN替换原来Dense FFN + +与最初使用至少两个专家的想法相反,Switch Transformer 采用了简化的单专家策略,每次只选择一个专家。这种方法的效果包括: + +- 减少了路由计算,一个 token 每次只路由到一个专家 +- 每个专家的 batch size(专家容量、Expert Capacity) 至少可以减半 +- 简化路由的实现,降低了 MoE 中的通信成本 + +### 3.2 Switch Routing + +上面提到了 Switch Transformer 可以降低每个专家的**专家容量**,那么什么是专家容量? + +**专家容量(Expert Capacity)** 是指每个专家在模型中处理的 token 数。专家容量的计算方式如下: + +$$ +Expert~ Capacity =\left(\frac{\text { tokens per batch }}{\text { number of experts }}\right) \times capacity~factor +$$ + +**这里为什么要计算一个专家容量?这个专家容量又有什么作用?** + +在编译时,所有 tensor 的形状都是静态确定的。这意味着在编译阶段,模型的架构和数据布局已经被定义,包括模型的层数、每层的输入和输出维度等。 + +尽管 tensor 的形状是静态的,但**在训练和推理过程中,模型的计算是动态的**。这是因为模型中的路由器(门控网络)会根据输入数据动态地将 token 分配给不同的专家。这种动态性要求模型能够在运行时灵活地处理数据分布。 + +而这个**专家容量的作用就是将 batch 中的总 token 数平均分配给所有专家**。然后,为了应对 token 分布不均的情况,会通过一个容量因子(capacity factor)来扩展每个专家的容量。 + +**容量因子**是一个大于 1.0 的数,它的作用是为每个专家提供额外的缓冲空间,以容纳可能超出平均分配的 token。这样,即使某些专家接收到的 token 数量超过了平均值,也能够处理这些额外的 token,而不会因为容量不足而导致计算跳过。 + +下图是不同容量因子下的动态路由。 + +![](image/image_NLod4PlUXs.png) + +> 不同容量因子下的动态路由 + +如图所示,容量因子` Capacity Factor = 1.0`的时候,输入6个 token,那么每个专家的专家容量等于 2(`Expert Capacity = 6/3 * 1 = 2`),Expert 1 被分配到了 3 个 token,超出了专家容量,这些超出的 token 被称为“溢出 token”(图(左)中的虚线部分)。**对于这些溢出的 token,模型会跳过计算,直接将 token 的表示通过残差连接传递到下一层**。 + +而如果容量因子 `Capacity Factor = 1.5`,这时专家容量等于 3,每个专家就能处理 3 个 token(图(右))。 + +虽然增加容量因子可以减少 token 溢出,但是它也有缺点。**如果容量因子设置得过高,会导致计算资源和内存的浪费**,因为模型会为可能永远不会用到的 token 分配额外的资源。在论文中,Switch Transformers 在低容量因子 (例如 1 至 1.25) 下表现出色。 + +下表是不同容量因子的效果对比。 + +**表 1:Switch Transformer 和 MoE 的效果对比** + +| 模型 | 容量因子 | 训练100k steps后的负对数困惑度(越大越好) | 模型到达指定负对数困惑度(-1.5)所需时间(单位小时) | 训练速度(每秒处理的样本数) | +| ------------ | ---- | -------------------------- | ---------------------------- | -------------- | +| T5-Base | | -1.731 | 没有达到 | 1600 | +| T5-Large | | -1.550 | 131.1 | 470 | +| MoE-Base | 2.0 | -1.547 | 68.7 | 840 | +| Switch-Base | 2.0 | -1.554 | 72.8 | 860 | +| MoE-Base | 1.25 | -1.559 | 72.8 | 790 | +| Switch-Base | 1.25 | -1.553 | 65.0 | 910 | +| MoE-Base | 1.0 | -1.572 | 80.1 | 860 | +| Switch-Base | 1.0 | -1.561 | 62.8 | 1000 | +| Switch-Base+ | 1.0 | -1.534 | 67.6 | 780 | + +- 以上模型都是在相同的计算资源(32核)和硬件(TPUv3)上进行训练的。 +- 所有 MoE 和 Switch Transformer 模型都使用 128 个专家。 +- 为了达到负对数困惑度为-1.50,所有模型都需要进行超过 100k steps 的预训练。 +- Switch-Base+:对于这个模型,作者增加了模型的大小,直到其训练速度与 MoE 模型相匹配。这通过增加模型的隐藏层大小(从768增加到896)和 head 的数量(从14增加到16)来实现。 +- T5-Base 在训练的 100k 步内没有达到这个负对数困惑度:这表示在给定的训练步数内,T5-Base 模型没有达到设定的效果,这可能是由于其性能不如 Switch Transformer 或 MoE Transformer 模型。 + +Switch Transformer 的作者还重新审视并简化了负载均衡损失。通过合理设置负载均衡损失的系数,可以在训练过程中实现专家之间的良好负载分布。下面介绍下具体实现。 + +### 3.3 不同的负载均衡损失 + +在稀疏模型中,专家的数量通常分布在多个设备上,每个专家负责处理一部分输入数据。理想情况下,每个专家应该处理相同数量的数据,以实现资源的均匀利用。然而,**在实际训练过程中,由于数据分布的不均匀性,某些专家可能会处理更多的数据,而其他专家可能会处理较少的数据**。这种不均衡可能导致训练效率低下,因为某些专家可能会过载,而其他专家则可能闲置。为了解决这个问题,论文中引入了一种**辅助损失函数**,以促进专家之间的负载均衡。 + +给定 N 个专家,索引为`i=1` 到 `N` ,以及一个包含 T 个 token 的 $batch~ B$ ,辅助 loss 计算为向量 $f$和 $P$ 的缩放点积。表示如下: + +$$ +auxiliary ~loss =\alpha \cdot N \cdot \sum_{i=1}^{N} f_{i} \cdot P_{i} +$$ + +其中, $f_i$ 是 batch 中分配给专家 `i` 的 token 占比,计算方式为 batch 中被路由到专家 `i` 的 token 数除以总token 数,表示如下: + +$$ +f_{i}=\frac{1}{T} \sum_{x \in \mathcal{B}} \mathbb{I}\{\operatorname{argmax} p(x)=i\} +$$ + +$P_i$ 是所有输入token 被路由到专家 `i` 的概率,表示如下: + +$$ +P_{i}=\frac{1}{T} \sum_{x \in \mathcal{B}} p_{i}(x) +$$ + +其中 $p_i\left( x \right)$ 是给定 token xx 被路由到专家 `i` 的概率。 + +由于希望 batch 中的所有 token 能够均匀地分配给N个专家。这意味着每个专家应该处理相同数量的token,即每个专家处理的 token 比例应该是 `1/N` 。 + +通过最小化公式的辅助 loss,可以鼓励这种均匀路由。当 token 均匀分布时,这个损失会被最小化。 + +最终的 loss 被乘以专家数量 `N` ,这样即使专家数量变化,loss 也能保持恒定。这是因为在均匀路由情况下$\sum_{i=1}^{N}\left(f_{i} \cdot P_{i}\right)=\sum_{i=1}^{N}\left(\frac{1}{N} \cdot \frac{1}{N}\right)=\frac{1}{N}$ 。 + +$\alpha$ 是一个超参数,用于调整辅助 loss 的权重。论文中选择了 $\alpha=10^{-2}$ ,这个值足够大,可以确保负载均衡,同时又足够小,不会压倒主要的交叉熵目标(即主要的训练损失)。论文实验了从 $10^{-1}$ 到 $10^{-5}$ 的$\alpha$ 值范围,发现 $10^{-2} $的值可以快速平衡负载,同时不会干扰训练损失。 + +### 3.4 稀疏路由和负载均衡loss的合并效果 + +前面介绍了 Switch Transformer 的主要优化:**稀疏路由和负载均衡损失**。下面介绍一下将这两项优化合并在一起的实验效果。 + +实验设置如下: + +- 首先从 C4 数据集上进行预训练,使用 MLM(Masked Language Modeling) 作为预训练目标。在这个任务中,模型被训练来预测被 mask 的 token。 +- 对比 Switch Transformer 与 MoE Transformer 以及 T5。Switch Transformer 在计算量(FLOPs)上与 T5-Base 匹配,即每个 token 应用的计算量相同。MoE Transformer 使用 top-2 路由。 +- 所有模型都在相同的硬件(TPUv3)上进行了相同数量的步骤训练。 + +实验结论如下(可以参见前面的**表** 1): + +- Switch Transformer 在速度和效果上都优 MoE Transformer。对于固定的计算量和时间,Switch Transformer 实现了最佳结果。 +- Switch Transformer 的计算量小于同等参数的 MoE 模型。如果将 Switch Transformer 的规模增加到匹配MoE Transformer 的训练速度,那么它在每个步骤上都优于所有 MoE 模型。 +- Switch Transformer 在较低的容量因子(1.0, 1.25)下表现更好。较低的专家容量表明在大模型中,模型内存非常稀缺,容量因子应尽可能小。 + +### 3.5 改进训练和Fine-Tuning技术 + +#### (1)**精度选择** + +作者还尝试了混合精度的方法,例如用 `bfloat16` 精度训练专家,同时对其余计算使用全精度进行。较低的精度可以减少处理器间的通信成本、计算成本以及存储 tensor 的内存。然而,在最初的实验中,当专家和门控网络都使用 `bfloat16` 精度训练时,出现了不稳定的训练现象。这种不稳定性主要是由路由计算引起的,因为路由涉及指数函数等操作,这些操作对精度要求较高。因此,为了保持计算的稳定性和精确性,保持更高的精度是重要的。为了减轻不稳定性,路由过程也使用了全精度。 + +下面的表 2 显示了混合精度训练的效果,将路由器输入转换为 float32,同时保持其他部分的精度为 bfloat16。这种策略允许模型在几乎与 bfloat16 精度相同的训练速度下,实现与 float32 训练相当的稳定性。 + +表2:不同精度效果对比 + +| 模型精度选择 | 效果(负对数困惑度) | 训练速度(每秒处理样本数) | +| ---------------------- | ---------- | ------------- | +| Switch-Base (float32) | -1.718 | 1160 | +| Switch-Base (bfloat16) | -3.780 | 1390 | +| Switch-Base (混合精度) | -1.716 | 1390 | + +实验表明,使用混合精度的 Switch-Base 在固定步数的早期训练中,其效果(以负对数困惑度为衡量标准)与使用 float32 训练的模型相似,同时速度接近 bfloat16。 + +#### **(2)更小的参数初始化** + +在深度学习中,适当的权重初始化对于模型的成功训练至关重要。作者观察到,在 Switch Transformer 模型中,这一点尤其明显。 + +**为了提高模型的稳定性,作者建议减少默认的 Transformer 初始化规模**。在 Transformer 模型中,权重矩阵通常是从一个截断的正态分布,其均值为0,标准差由一个超参数 s 决定。作者建议将这个初始化超参数 s 从默认值1.0 减少 10 倍,即 s = 0.1。这种较小的初始化规模有助于提高模型效果和减少训练过程中的不稳定性。 + +表3:减小参数初始化规模可以提升训练稳定性 + +| 权重初始化规模 | 负对数困惑度 | 负对数困惑度标准差 | +| ------- | ------ | --------- | +| 0.1倍初始化 | -2.72 | 0.01 | +| 1.0倍初始化 | -3.60 | 0.68 | + +表 3 中的数据表明,通**过减少初始化规模,模型效果和稳定性得到了提升**。这种改进对于大模型,如 Switch Transformer,尤其重要。 + +#### **(3)Fine-Tuning 过程正则化** + +为了解决 Fine-Tuning 过程中的过拟合问题,作者提出了增加 dropout的策略,特别是在专家层(expert layers)中。他们称之为“expert dropout”,即**在 Fine-Tuning 时只在专家层增加 dropout 率**。 + +表 4显示了在 Fine-Tuning Switch Transformer 时,不同 dropout 率的实验结果。这些模型是在 C4 数据集上预训练的,然后进行了 Fine-Tuning。 + +表4:Fine-Tuning 过程中正则化效果 + +| 模型(dropout) | GLUE | CNNDM | SQuAD | SuperGLUE | +| --------------------------------- | ---- | ----- | ----- | --------- | +| T5-Base (d=0.1) | 82.9 | 19.6 | 83.5 | 72.4 | +| Switch-Base (d=0.1) | 84.7 | 19.1 | 83.7 | 73.0 | +| Switch-Base (d=0.2) | 84.4 | 19.2 | 83.9 | 73.2 | +| Switch-Base (d=0.3) | 83.9 | 19.6 | 83.4 | 70.7 | +| Switch-Base (d=0.1, expert d=0.4) | 85.2 | 19.6 | 83.7 | 73.0 | + +通过这种 expert dropout 策略,有效地减少了过拟合的风险,同时保持了模型在下游任务上的性能。这种**正则化方法对于处理具有大量参数的稀疏模型特别有用,因为它可以帮助模型更好地泛化到未见过的数据**。 + +### 3.6 高效训练:数据、模型、专家并行 + +**任意增加专家数量会导致收益递减**(如图3所示)。这意味着在某个点之后,继续增加专家数量不会显著提高模型性能。但是可以通过增加模型的维度,如模型的隐藏层大小(dmodel)或前馈网络的维度(dff)来继续提升模型效果。但是这样又会导致显存和内存开销增加,这时候就可以通过并行技术,解决高效训练问题。 + +这里补充一下关于各种并行的方法的解释。标准的数据并行的定义是一个 batch 的数据在不同的 device 上并行处理,这时每一个 device 上都保存了模型的一份完整拷贝,前向计算完进行梯度汇总和更新。模型并行表示模型不同的参数(层、组件)分配到不同的 device 上,处理一个 batch 的数据。 + +![](image/image_fYyHHa7LOd.png) + +> 图(a)模型权重的分配方式 + +![](image/image_-deX9IG43V.png) + +> (b)数据的分配方式 + +图(a)表示模型权重的分配方式,图(b)表示数据的分配方式,**一种颜色表示一个矩阵**(a unique weight matrix)。其中每一个方格表示一个 core。 + +#### (1)**数据并行(Data Parallelism)** + +**第一列**表示数据并行,模型权重拷贝 16 份,16 个同一种颜色矩阵分别表示一个完整的模型,图(b)则是一个完整的矩阵,这里可以理解为 16 个模型计算完成后由于存在梯度汇总再更新的步骤,所以整体更新的是一个batch,因此这里 Data Parallelism 是一个唯一的矩阵。简单来说就是模型复制,数据并行。 + +![](image/image_r-uahMUvCX.png) + +> 数据并行 + +#### **(2)模型并行(Model Parallelism)** + +模型并行部分从模型侧看出来,16个 cores 维护的是一个整体的模型,但是每一个 core 只分配到其中部分模型参数(图(a)),同一个 batch 数据在所有的 core 上计算(图(b)),由于 1 个 core 中分布了不同的模型权重,每次计算完都需要和其他的 core 进行通信。 + +![](image/image_oYDNYHHf06.png) + +> 模型并行 + +#### **(3)模型和数据并行** + +总共有 N 个 cores,其中 $N=n\times m$ , n 代表数据并行维度上的分割因子, m 代表模型并行维度上的分割因子。现在每个 core 处理的是 B/n 个 token 以及 $d_{ff}/m$ 个权重。 + +![](image/image_l24ZjlTWIN.png) + +> 模型和数据并行 + +#### **(4)专家和数据并行** + +每个专家分配到一个 core 上,同时数据也切分成16份,如下图所示: + +![](image/image_rmYq1_4hQe.png) + +> 专家和数据并行 + +#### **(5)专家、模型和数据并行** + +最后将专家、模型、数据并行合并在一起,如下图所示: + +![](image/image_p7Ug5n5jNr.png) + +> 模型、专家和数据并行 + +## 4.总结 + +本文系统性地介绍了混合专家模型(MoE),主要介绍了针对 MoE 的高效训练方法,以及如何提升训练和 Fine-Tuning 的效果。现在我们回答下开篇提出的三个问题。 + +**第一个问题:MoE 为什么能够实现在低成本下训练更大的模型。** + +这主要是因为稀疏路由的原因,每个 token 只会选择 top-k 个专家进行计算。同时可以使用模型并行、专家并行和数据并行,优化 MoE 的训练效率。而负载均衡损失可提升每个 device 的利用率。 + +**第二个问题:MoE 如何解决训练稳定性问题?** + +可以通过混合精度训练、更小的参数初始化,以及 Router z-loss 提升训练的稳定性。 + +**第三个问题:MoE 如何解决 Fine-Tuning 过程中的过拟合问题?** + +可以通过更大的 dropout (主要针对 expert)、更大的学习率、更小的 batch size。目前看到的主要是预训练的优化,针对 Fine-Tuning 的优化主要是一些常规的手段。 diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_-deX9IG43V.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_-deX9IG43V.png" new file mode 100644 index 0000000..14a8241 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_-deX9IG43V.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_LrMLT8kaVX.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_LrMLT8kaVX.png" new file mode 100644 index 0000000..976ccf7 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_LrMLT8kaVX.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_NLod4PlUXs.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_NLod4PlUXs.png" new file mode 100644 index 0000000..a2d89fb Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_NLod4PlUXs.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_WYGAroS1fy.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_WYGAroS1fy.png" new file mode 100644 index 0000000..90acd0c Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_WYGAroS1fy.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_fYyHHa7LOd.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_fYyHHa7LOd.png" new file mode 100644 index 0000000..3620a2e Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_fYyHHa7LOd.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_l24ZjlTWIN.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_l24ZjlTWIN.png" new file mode 100644 index 0000000..793bb59 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_l24ZjlTWIN.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_oYDNYHHf06.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_oYDNYHHf06.png" new file mode 100644 index 0000000..79fc249 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_oYDNYHHf06.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_p7Ug5n5jNr.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_p7Ug5n5jNr.png" new file mode 100644 index 0000000..0f48659 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_p7Ug5n5jNr.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_r-uahMUvCX.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_r-uahMUvCX.png" new file mode 100644 index 0000000..dfb2d47 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_r-uahMUvCX.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_rmYq1_4hQe.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_rmYq1_4hQe.png" new file mode 100644 index 0000000..4518e85 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_rmYq1_4hQe.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_tuuC2Qgzr-.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_tuuC2Qgzr-.png" new file mode 100644 index 0000000..b6aac7a Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.LLM MoE \357\274\232Switch Transformers/image/image_tuuC2Qgzr-.png" differ diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\344\275\215\347\275\256\347\274\226\347\240\201/3.\344\275\215\347\275\256\347\274\226\347\240\201.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.\344\275\215\347\275\256\347\274\226\347\240\201/3.\344\275\215\347\275\256\347\274\226\347\240\201.md" similarity index 89% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\344\275\215\347\275\256\347\274\226\347\240\201/3.\344\275\215\347\275\256\347\274\226\347\240\201.md" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.\344\275\215\347\275\256\347\274\226\347\240\201/3.\344\275\215\347\275\256\347\274\226\347\240\201.md" index 4304b73..96f4e22 100644 --- "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\344\275\215\347\275\256\347\274\226\347\240\201/3.\344\275\215\347\275\256\347\274\226\347\240\201.md" +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.\344\275\215\347\275\256\347\274\226\347\240\201/3.\344\275\215\347\275\256\347\274\226\347\240\201.md" @@ -4,8 +4,8 @@ 不同于RNN、CNN等模型,对于Transformer模型来说,位置编码的加入是必不可少的,因为**纯粹的Attention模块是无法捕捉输入顺序的,即无法区分不同位置的Token**。为此我们大体有两个选择: -1. 想办法将位置信息融入到输入中,这构成了绝对位置编码的一般做法; -2. 想办法微调一下Attention结构,使得它有能力分辨不同位置的Token,这构成了相对位置编码的一般做法。 +1. 想办法将位置信息融入到输入中,这构成了绝对位置编码的一般做法; +2. 想办法微调一下Attention结构,使得它有能力分辨不同位置的Token,这构成了相对位置编码的一般做法。 #### 1.1 绝对位置编码 @@ -177,19 +177,19 @@ $$ **绝对位置编码** -- 最原始的正余弦位置编码(即sinusoidal位置编码)是一种绝对位置编码,但从其原理中的正余弦的和差化积公式来看,引入的其实也是相对位置编码。 -- 优势: 实现简单,可预先计算好,不用参与训练,速度快。 -- 劣势: 没有外推性,即如果预训练最大长度为512的话,那么最多就只能处理长度为512的句子,再长就处理不了了。当然,也可以将超过512的位置向量随机初始化,然后继续微调。 +- 最原始的正余弦位置编码(即sinusoidal位置编码)是一种绝对位置编码,但从其原理中的正余弦的和差化积公式来看,引入的其实也是相对位置编码。 +- 优势: 实现简单,可预先计算好,不用参与训练,速度快。 +- 劣势: 没有外推性,即如果预训练最大长度为512的话,那么最多就只能处理长度为512的句子,再长就处理不了了。当然,也可以将超过512的位置向量随机初始化,然后继续微调。 **相对位置编码** -- 经典相对位置编码RPR式的讲解可看我的博客:相对位置编码之RPR式:《Self-Attention with Relative Position Representations》论文笔记 【在k, v中注入相对位置信息】 -- 优势: 直接地体现了相对位置信号,效果更好。具有外推性,处理长文本能力更强。 +- 经典相对位置编码RPR式的讲解可看我的博客:相对位置编码之RPR式:《Self-Attention with Relative Position Representations》论文笔记 【在k, v中注入相对位置信息】 +- 优势: 直接地体现了相对位置信号,效果更好。具有外推性,处理长文本能力更强。 **RoPE** -- RoPE通过绝对位置编码的方式实现相对位置编码,综合了绝对位置编码和相对位置编码的优点。 -- 主要就是**对attention中的q, k向量注入了绝对位置信息,然后用更新的q,k向量做attention中的内积就会引入相对位置信息了**。 +- RoPE通过绝对位置编码的方式实现相对位置编码,综合了绝对位置编码和相对位置编码的优点。 +- 主要就是**对attention中的q, k向量注入了绝对位置信息,然后用更新的q,k向量做attention中的内积就会引入相对位置信息了**。 ### 2.旋转位置编码 RoPE篇 @@ -305,11 +305,11 @@ $$ Alibi 的方法也算较为粗暴,是直接**作用在attention score中,给 attention score 加上一个预设好的偏置矩阵,相当于 q 和 k 相对位置差 1 就加上一个 -1 的偏置**。其实相当于假设两个 token 距离越远那么相互贡献也就越低。 -![](image/image_sRfDn86YHn.png) +![](image/image_B907xoFOlR.png) 其中**Alibi 位置编码是不需要通过训练的**,给定的预设矩阵中还会乘上`m`的调节因子,`m`的设置与attention的头数有关,是2的指数差值。论文中也做了尝试把m作为学习参数,但是并没有获得更好的效果。 -![](image/image_e0fzVFqKmF.png) +![](image/image_Jk8-citHHy.png) Alibi 位置编码的**外推性比旋转位置编码外推性要好一些**,旋转位置编码也是基于正余弦三角式位置编码改进融入相对位置信息,但是正余弦三角式位置编码外推性缺点也很明显,看起来是不需要训练可以直接推演无限长度位置编码,但是忽略了一点就是周期性函数必须进行位置衰减,到远处的位置信息趋于直线震荡,基本很难有位置信息区分了,所以外推性比训练式的好不了多少,旋转位置编码基于此改进的自然也是如此。 @@ -341,7 +341,7 @@ Alibi 相当于在k和q向量内积上加入分数上的偏置,来体现出来 可以提前预留多几维,训练阶段设为0,推理阶段直接改为其他数字,这就是外推(Extrapolation)。 -![](image/image_p4jUVT_9qM.png) +![](image/image_KqvSV8SjTV.png) 然而,训练阶段预留的维度一直是0,如果推理阶段改为其他数字,效果不见得会好,因为模型对没被训练过的情况不一定具有适应能力。也就是说,**由于某些维度的训练数据不充分,所以直接进行外推通常会导致模型的性能严重下降**。 @@ -349,7 +349,7 @@ Alibi 相当于在k和q向量内积上加入分数上的偏置,来体现出来 就是将2000以内压缩到1000以内,比如通过除以2,1749就变成了874.5,然后转为三维向量\[8,7,4.5]输入到原来的模型中。从绝对数值来看,新的\[7,4,9]实际上对应的是1498,是原本对应的2倍,映射方式不一致;从相对数值来看,原本相邻数字的差距为1,现在是0.5,最后一个维度更加“拥挤”。所以,做了内插修改后,通常都需要微调训练,以便模型重新适应拥挤的映射关系。 -![](image/image_zja_LE75cO.png) +![](image/image_iDIO40wFKR.png) 不过,内插方案也不尽完美,当处理范围进一步增大时,相邻差异则更小,并且这个相邻差异变小集中在个位数,剩下的百位、十位,还是保留了相邻差异为1。换句话说,**内插方法使得不同维度的分布情况不一样,每个维度变得不对等起来,模型进一步学习难度也更大**。 @@ -357,25 +357,25 @@ Alibi 相当于在k和q向量内积上加入分数上的偏置,来体现出来 有没有不用新增维度,又能保持相邻差距的方案呢?**进制转换**!三个数字的10进制编码可以表示0~999,如果是16进制呢?它最大可以表示163−1=4095>1999。所以,只需要转到16进制,如1749变为\[6,13,5],那么三维向量就可以覆盖目标范围,代价是每个维度的数字从0~9变为0~15。 -![](image/image_roAlJ2RG42.png) +![](image/image_B-wc2bgveY.png) 这个进制转换的思想,实际上就对应着文章开头提到的NTK-aware scaled RoPE! ##### (5)总结 -1. 直接外推的效果不大行; -2. 内插如果不微调,效果也很差; -3. NTK-RoPE不微调就取得了非平凡(但有所下降)的外推结果; -4. 加入$logn$来集中注意力确实有帮助。 +1. 直接外推的效果不大行; +2. 内插如果不微调,效果也很差; +3. NTK-RoPE不微调就取得了非平凡(但有所下降)的外推结果; +4. 加入$logn$来集中注意力确实有帮助。 参考资料: -- [https://spaces.ac.cn/archives/9675](https://spaces.ac.cn/archives/9675 "https://spaces.ac.cn/archives/9675") +- [https://spaces.ac.cn/archives/9675](https://spaces.ac.cn/archives/9675 "https://spaces.ac.cn/archives/9675") #### 4.3 为了做到长度外推性,需要解决两个主要问题 -1. **预测时位置编码的外推**:没见过的就无法保证很好的泛化,不仅学习式位置编码如此;像正弦位置编码、RoPE也有这样的问题,它们自身虽然不用学习,但是会影响上层参数的学习; -2. **预测时序列更长,导致注意力相比训练时更分散**:序列长度增大意味着attention分布的熵增大了,注意力更分散了; +1. **预测时位置编码的外推**:没见过的就无法保证很好的泛化,不仅学习式位置编码如此;像正弦位置编码、RoPE也有这样的问题,它们自身虽然不用学习,但是会影响上层参数的学习; +2. **预测时序列更长,导致注意力相比训练时更分散**:序列长度增大意味着attention分布的熵增大了,注意力更分散了; #### 4.4 长度外推性的预测 @@ -385,12 +385,12 @@ Alibi 相当于在k和q向量内积上加入分数上的偏置,来体现出来 为什么目前市面上的LLM鲜有使用呢(据目前所知,好像只有BLOOM/MPT/采用了ALiBi)?可能的原因: -1. 专注于长度外推性的工作主要是在21/22年后才逐渐出现,效果尚未经过充分检验; -2. 长度外推性的评测指标与LLM的评测指标并不完全match:目前长度外推性主要看PPL,这其实不够全面。PPL这类语言模型的指标,可能更关注局部上下文的预测,因此局部注意力相关的方案可能在这类评测上天然占优。 -3. 目前的长度外推性工作似乎更多的在强调外推性如何如何,但更重要的应该还是max\_length内的效果,从LLM的角度来看,应该在保证max\_length内的效果后再去追求外推性。比如,从GLM的消融实验来看,ALiBi的效果还是不如RoPE的。 +1. 专注于长度外推性的工作主要是在21/22年后才逐渐出现,效果尚未经过充分检验; +2. 长度外推性的评测指标与LLM的评测指标并不完全match:目前长度外推性主要看PPL,这其实不够全面。PPL这类语言模型的指标,可能更关注局部上下文的预测,因此局部注意力相关的方案可能在这类评测上天然占优。 +3. 目前的长度外推性工作似乎更多的在强调外推性如何如何,但更重要的应该还是max\_length内的效果,从LLM的角度来看,应该在保证max\_length内的效果后再去追求外推性。比如,从GLM的消融实验来看,ALiBi的效果还是不如RoPE的。 参考资料: -- [让研究人员绞尽脑汁的Transformer位置编码](https://kexue.fm/archives/8130 "让研究人员绞尽脑汁的Transformer位置编码") -- [Transformer升级之路:10、RoPE是一种β进制编码](https://spaces.ac.cn/archives/9675 "Transformer升级之路:10、RoPE是一种β进制编码") -- [开源LLM大模型位置编码探索](https://zhuanlan.zhihu.com/p/631003833 "开源LLM大模型位置编码探索") +- [让研究人员绞尽脑汁的Transformer位置编码](https://kexue.fm/archives/8130 "让研究人员绞尽脑汁的Transformer位置编码") +- [Transformer升级之路:10、RoPE是一种β进制编码](https://spaces.ac.cn/archives/9675 "Transformer升级之路:10、RoPE是一种β进制编码") +- [开源LLM大模型位置编码探索](https://zhuanlan.zhihu.com/p/631003833 "开源LLM大模型位置编码探索") diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_roAlJ2RG42.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_B-wc2bgveY.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_roAlJ2RG42.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_B-wc2bgveY.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_sRfDn86YHn.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_B907xoFOlR.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_sRfDn86YHn.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_B907xoFOlR.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_e0fzVFqKmF.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_Jk8-citHHy.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_e0fzVFqKmF.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_Jk8-citHHy.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_p4jUVT_9qM.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_KqvSV8SjTV.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_p4jUVT_9qM.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_KqvSV8SjTV.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_zja_LE75cO.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_iDIO40wFKR.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_zja_LE75cO.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/3.\344\275\215\347\275\256\347\274\226\347\240\201/image/image_iDIO40wFKR.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.tokenize\345\210\206\350\257\215/4.tokenize\345\210\206\350\257\215.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/4.tokenize\345\210\206\350\257\215/4.tokenize\345\210\206\350\257\215.md" similarity index 70% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.tokenize\345\210\206\350\257\215/4.tokenize\345\210\206\350\257\215.md" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/4.tokenize\345\210\206\350\257\215/4.tokenize\345\210\206\350\257\215.md" index 48f87af..573407e 100644 --- "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.tokenize\345\210\206\350\257\215/4.tokenize\345\210\206\350\257\215.md" +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/4.tokenize\345\210\206\350\257\215/4.tokenize\345\210\206\350\257\215.md" @@ -15,9 +15,9 @@ tokenize有三种粒度:**word/subword/char** -- **word/词**,词,是最自然的语言单元。对于英文等自然语言来说,存在着天然的分隔符,如空格或一些标点符号等,对词的切分相对容易。但是对于一些东亚文字包括中文来说,就需要某种分词算法才行。顺便说一下,Tokenizers库中,基于规则切分部分,**采用了spaCy和Moses两个库**。如果基于词来做词汇表,由于长尾现象的存在,**这个词汇表可能会超大**。像Transformer XL库就用到了一个**26.7万**个单词的词汇表。这需要极大的embedding matrix才能存得下。embedding matrix是用于查找取用token的embedding vector的。这对于内存或者显存都是极大的挑战。常规的词汇表,**一般大小不超过5万**。 -- **char/字符**,即最基本的字符,如英语中的'a','b','c'或中文中的'你','我','他'等。而一般来讲,字符的数量是**少量有限**的。这样做的问题是,由于字符数量太小,我们在为每个字符学习嵌入向量的时候,每个向量就容纳了太多的语义在内,学习起来非常困难。 -- **subword/子词级**,它介于字符和单词之间。比如说'Transformers'可能会被分成'Transform'和'ers'两个部分。这个方案**平衡了词汇量和语义独立性**,是相对较优的方案。它的处理原则是,**常用词应该保持原状,生僻词应该拆分成子词以共享token压缩空间**。 +- **word/词**,词,是最自然的语言单元。对于英文等自然语言来说,存在着天然的分隔符,如空格或一些标点符号等,对词的切分相对容易。但是对于一些东亚文字包括中文来说,就需要某种分词算法才行。顺便说一下,Tokenizers库中,基于规则切分部分,**采用了spaCy和Moses两个库**。如果基于词来做词汇表,由于长尾现象的存在,**这个词汇表可能会超大**。像Transformer XL库就用到了一个**26.7万**个单词的词汇表。这需要极大的embedding matrix才能存得下。embedding matrix是用于查找取用token的embedding vector的。这对于内存或者显存都是极大的挑战。常规的词汇表,**一般大小不超过5万**。 +- **char/字符**,即最基本的字符,如英语中的'a','b','c'或中文中的'你','我','他'等。而一般来讲,字符的数量是**少量有限**的。这样做的问题是,由于字符数量太小,我们在为每个字符学习嵌入向量的时候,每个向量就容纳了太多的语义在内,学习起来非常困难。 +- **subword/子词级**,它介于字符和单词之间。比如说'Transformers'可能会被分成'Transform'和'ers'两个部分。这个方案**平衡了词汇量和语义独立性**,是相对较优的方案。它的处理原则是,**常用词应该保持原状,生僻词应该拆分成子词以共享token压缩空间**。 ### 2.常用的tokenize算法 @@ -29,17 +29,17 @@ BPE,即字节对编码。其核心思想在于将**最常出现的子词对合 BPE是一种基于数据压缩算法的分词方法。它通过不断地合并出现频率最高的字符或者字符组合,来构建一个词表。具体来说,BPE的运算过程如下: -1. 将所有单词按照字符分解为字母序列。例如:“hello”会被分解为\["h","e","l","l","o"]。 -2. 统计每个字母序列出现的频率,将频率最高的序列合并为一个新序列。 -3. 重复第二步,直到达到预定的词表大小或者无法再合并。 +1. 将所有单词按照字符分解为字母序列。例如:“hello”会被分解为\["h","e","l","l","o"]。 +2. 统计每个字母序列出现的频率,将频率最高的序列合并为一个新序列。 +3. 重复第二步,直到达到预定的词表大小或者无法再合并。 词表大小通常先增加后减小 每次合并后词表可能出现3种变化: -- `+1`,表明加入合并后的新字词,同时原来的2个子词还保留(2个字词不是完全同时连续出现) -- `+0`,表明加入合并后的新字词,同时原来的2个子词中一个保留,一个被消解(一个字词完全随着另一个字词的出现而紧跟着出现) -- `-1`,表明加入合并后的新字词,同时原来的2个子词都被消解(2个字词同时连续出现) +- `+1`,表明加入合并后的新字词,同时原来的2个子词还保留(2个字词不是完全同时连续出现) +- `+0`,表明加入合并后的新字词,同时原来的2个子词中一个保留,一个被消解(一个字词完全随着另一个字词的出现而紧跟着出现) +- `-1`,表明加入合并后的新字词,同时原来的2个子词都被消解(2个字词同时连续出现) 举例如下: @@ -184,14 +184,14 @@ $$ S=\left[t_{1}, t_{2}, t_{3}, \ldots, t_{n}\right] $$ -比如说 $ P(ed) $的概率比$P(e) + P(d)$ 单独出现的概率更大,可能比他们具有最大的互信息值,也就是两子词在语言模型上具有较强的关联性。 +比如说 $P(ed) $的概率比$P(e) + P(d)$ 单独出现的概率更大,可能比他们具有最大的互信息值,也就是两子词在语言模型上具有较强的关联性。 那wordPiece和BPE的区别: -- **BPE**: apple 当词表有appl 和 e的时候,apple优先编码为 appl和e(即使原始预料中 app 和 le 的可能性更大) -- **wordPiece**:根据原始语料, app和le的概率更大 +- **BPE**: apple 当词表有appl 和 e的时候,apple优先编码为 appl和e(即使原始预料中 app 和 le 的可能性更大) +- **wordPiece**:根据原始语料, app和le的概率更大 -#### 2.4 Unigram +#### 2.3 Unigram 与BPE或者WordPiece不同,Unigram的算法思想是**从一个巨大的词汇表出发**,再**逐渐删除trim down其中的词汇**,直到size满足预定义。 @@ -223,5 +223,5 @@ SentencePiece,顾名思义,它是**把一个句子看作一个整体,再 参考资料: -- [https://www.jianshu.com/p/d4de091d1367](https://www.jianshu.com/p/d4de091d1367 "https://www.jianshu.com/p/d4de091d1367") -- [BPE、WordPiece、Unigram LM、SentencePiece](https://www.zhaokangkang.com/article/6843fe1d-f846-4eae-9fd1-cf10fdfb5d15#e2f263f3686246ba82740ff94691f08a "BPE、WordPiece、Unigram LM、SentencePiece") +- [https://www.jianshu.com/p/d4de091d1367](https://www.jianshu.com/p/d4de091d1367 "https://www.jianshu.com/p/d4de091d1367") +- [BPE、WordPiece、Unigram LM、SentencePiece](https://www.zhaokangkang.com/article/6843fe1d-f846-4eae-9fd1-cf10fdfb5d15#e2f263f3686246ba82740ff94691f08a "BPE、WordPiece、Unigram LM、SentencePiece") diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260.md" similarity index 84% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260.md" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260.md" index 7ff7fbc..9c38145 100644 --- "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260.md" +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260.md" @@ -1,16 +1,16 @@ -# 4.token及模型参数 +# 5.token及模型参数 参考资料: -- [https://zhuanlan.zhihu.com/p/636812912](https://zhuanlan.zhihu.com/p/636812912 "https://zhuanlan.zhihu.com/p/636812912") -- [https://mp.weixin.qq.com/s/DVH-vlOpGik8iwW4KnPlkw](https://mp.weixin.qq.com/s/DVH-vlOpGik8iwW4KnPlkw "https://mp.weixin.qq.com/s/DVH-vlOpGik8iwW4KnPlkw") -- [https://mp.weixin.qq.com/s/DBP\_eafGeKMEuSIma9Z9Tg](https://mp.weixin.qq.com/s/DBP_eafGeKMEuSIma9Z9Tg "https://mp.weixin.qq.com/s/DBP_eafGeKMEuSIma9Z9Tg") +- [https://zhuanlan.zhihu.com/p/636812912](https://zhuanlan.zhihu.com/p/636812912 "https://zhuanlan.zhihu.com/p/636812912") +- [https://mp.weixin.qq.com/s/DVH-vlOpGik8iwW4KnPlkw](https://mp.weixin.qq.com/s/DVH-vlOpGik8iwW4KnPlkw "https://mp.weixin.qq.com/s/DVH-vlOpGik8iwW4KnPlkw") +- [https://mp.weixin.qq.com/s/DBP\_eafGeKMEuSIma9Z9Tg](https://mp.weixin.qq.com/s/DBP_eafGeKMEuSIma9Z9Tg "https://mp.weixin.qq.com/s/DBP_eafGeKMEuSIma9Z9Tg") ### 1.**预训练模型表现影响因素** -- **模型表现强依赖于模型规模**(模型参数量`N`(Embedding除外)、训练Token数`D`、训练总计算量`C`); -- 平滑幂定律:模型表现与三个因子均遵循幂定律,不受另外两个因子限制; -- 在给定计算量预算下,模型参数量以及训练Token数应该同比提升,对应模型参数量需要的训练Token数如下: +- **模型表现强依赖于模型规模**(模型参数量`N`(Embedding除外)、训练Token数`D`、训练总计算量`C`); +- 平滑幂定律:模型表现与三个因子均遵循幂定律,不受另外两个因子限制; +- 在给定计算量预算下,模型参数量以及训练Token数应该同比提升,对应模型参数量需要的训练Token数如下: | Parameters | FLOPs | FLOPs (in Gopher unit) | Tokens | | ----------- | -------- | ---------------------- | -------------- | @@ -28,23 +28,23 @@ ### 2.预训练数据 Token 重复 是否影响 模型性能? -- **多轮epoch的训练会降低模型性能;** -- 更大规模的数据集会缓解重复epochs对模型性能下降的影响; -- 提高数据集的质量也无法挽救重复训练带来的过拟合; -- 小计算量模型的过拟合趋势与大计算量的差不多; -- 多样的训练目标不一定减轻多Epoch的性能下降; -- Dropout是一个被大语言模型忽视的正则技术,虽然慢,但是可以降低多epochs的影响; -- 在训练过程中逐渐使用dropout是有效的策略; +- **多轮epoch的训练会降低模型性能;** +- 更大规模的数据集会缓解重复epochs对模型性能下降的影响; +- 提高数据集的质量也无法挽救重复训练带来的过拟合; +- 小计算量模型的过拟合趋势与大计算量的差不多; +- 多样的训练目标不一定减轻多Epoch的性能下降; +- Dropout是一个被大语言模型忽视的正则技术,虽然慢,但是可以降低多epochs的影响; +- 在训练过程中逐渐使用dropout是有效的策略; ### 3.SFT需要训练Token数? -- 少量高质量、多样性的数据,也可以训练出效果优秀的SFT模型 +- 少量高质量、多样性的数据,也可以训练出效果优秀的SFT模型 ### 4.为什么要考虑在重复的数据集上做多次训练? 在此前的研究中,大家发现大语言模型的规模和训练数据集中tokens的数量对模型的性能有很大的影响。大模型扩展定律都认为模型的规模与训练数据的规模必须同时扩大才能让模型产生更好的性能。但是,tokens数量似乎并不是很足够,如下图所示是作者研究的模型参数规模增长和目前互联网是可用的数据集tokens数量增长情况: -![](image/image_p0CVK8f1Tc.png) +![](image/image_CG7OJORVWt.png) 在这幅图中,蓝色的虚线是互联网上数据集中tokens数量预估结果,高质量文本中tokens数量每年增长只有4%-5%,与世界经济增长率差不多,但是显著慢于模型规模的增长。例如,MetaAI训练的LLaMA-65B模型用了1.4万亿tokens,而2023年全球的tokens估计只有9万亿!按照目前模型规模的发展情况,在2023年-2027年几年的时间里,我们的模型将把全球所有数据集的tokens都训练完成,此后,我们很可能陷入缺少tokens训练的地步,这被作者称为**tokens危机**。 @@ -60,7 +60,7 @@ 首先是模型参数规模的增长与模型需要的tokens数量基本是呈线性的。 -![](image/image__6ReD_RWJg.png) +![](image/image_t2KBUfJ3-G.png) 这意味如果你**要充分训练一个LLM,需要根据它的参数数量来收集足够的tokens**。 @@ -70,7 +70,7 @@ 如下图所示,可以看到,**数据集重复的次数越多,模型的性能越差**: -![](image/image__RIe9qzIP8.png) +![](image/image_TtdSRIixZx.png) 此外,**如果tokens数量不够,模型参数规模越大,越容易出现过拟合的现象**! @@ -82,7 +82,7 @@ 在这个实验中,作者将重复的次数固定,然后看模型在不同规模数据集上重复训练的性能影响。如下图所示: -![](image/image_M80rkYuSPF.png) +![](image/image_3E6bYgN2OX.png) 可以看到,当在227227个tokens和229229个tokens上重复训练2828次之后发现,前者更容易出现过拟合,而229229tokens的数据集上重复训练,模型性能下降不明显。 @@ -90,7 +90,7 @@ Taylor在训练Galactica模型时候认为他之所以用4 epochs能提高训练效果可能是因为他的数据集质量更好。然而,本文的作者发现,**相对更高质量的数据集并不能降低重复训练带来的影响**。 -![](image/image_-0zIQNE83Y.png) +![](image/image_E7N8lnAOor.png) 作者用相同的重复策略在C4数据集和Wikipedia数据集上分别训练模型,发现二者都会因为重复训练带来模型性能的下降。这里的Wikipedia数据集质量相对C4更好一点。**说明相对提高数据集质量可能不会影响重复训练的负面效应**。 @@ -98,7 +98,7 @@ Taylor在训练Galactica模型时候认为他之所以用4 epochs能提高训练 模型规模的增长其实表现在2个方面,一个是**模型参数**,一个是**模型所需要的计算量**。模型参数相同的情况下,采用不同的模型架构所需要的FLOPs是不同的。作者对比了MoE架构,并采用ParamShare方法降低相同参数模型的FLOPs。 -![](image/image_xbKUVRRQfD.png) +![](image/image_KGvYMToOVc.png) 经过测试发现,**FLOPs较大的模型性能会更好一点,但是依然无法有效降低重复训练带来的模型损失**。 @@ -122,7 +122,7 @@ Taylor在训练Galactica模型时候认为他之所以用4 epochs能提高训练 在目前超过100亿参数规模的大语言模型中,如GPT-3、PaLM、LLaMA等,都没有使用dropout(可能是因为太慢了)。而前面说的Galactica训练使用了,这是Galactica能够训练4Epochs提升性能的最重要的原因。 -![](image/image_GawTDZf_6n.png) +![](image/image_OHcQHE5neP.png) #### 7.2 在训练过程中逐渐使用dropout是有效的策略 diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_M80rkYuSPF.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_3E6bYgN2OX.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_M80rkYuSPF.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_3E6bYgN2OX.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_p0CVK8f1Tc.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_CG7OJORVWt.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_p0CVK8f1Tc.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_CG7OJORVWt.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_-0zIQNE83Y.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_E7N8lnAOor.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_-0zIQNE83Y.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_E7N8lnAOor.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_xbKUVRRQfD.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_KGvYMToOVc.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_xbKUVRRQfD.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_KGvYMToOVc.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_GawTDZf_6n.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_OHcQHE5neP.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_GawTDZf_6n.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_OHcQHE5neP.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image__RIe9qzIP8.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_TtdSRIixZx.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image__RIe9qzIP8.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_TtdSRIixZx.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image__6ReD_RWJg.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_t2KBUfJ3-G.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/4.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image__6ReD_RWJg.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/5.token\345\217\212\346\250\241\345\236\213\345\217\202\346\225\260/image/image_t2KBUfJ3-G.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/5.\346\277\200\346\264\273\345\207\275\346\225\260/5.\346\277\200\346\264\273\345\207\275\346\225\260.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/6.\346\277\200\346\264\273\345\207\275\346\225\260/6.\346\277\200\346\264\273\345\207\275\346\225\260.md" similarity index 93% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/5.\346\277\200\346\264\273\345\207\275\346\225\260/5.\346\277\200\346\264\273\345\207\275\346\225\260.md" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/6.\346\277\200\346\264\273\345\207\275\346\225\260/6.\346\277\200\346\264\273\345\207\275\346\225\260.md" index 3a328bf..aa9cc8f 100644 --- "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/5.\346\277\200\346\264\273\345\207\275\346\225\260/5.\346\277\200\346\264\273\345\207\275\346\225\260.md" +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/6.\346\277\200\346\264\273\345\207\275\346\225\260/6.\346\277\200\346\264\273\345\207\275\346\225\260.md" @@ -1,4 +1,4 @@ -# 5.激活函数 +# 6.激活函数 \[toc] @@ -14,9 +14,9 @@ $$ 假设输入是一个向量 $x$,FFN块的计算过程如下: -1. 第一层全连接层(线性变换):$z = xW1 + b1$ 其中,W1 是第一层全连接层的权重矩阵,b1 是偏置向量。 -2. 激活函数:$a = g(z)$ 其中,g() 是激活函数,常用的激活函数有ReLU(Rectified Linear Unit)等。 -3. 第二层全连接层(线性变换):$y = aW2 + b2$ 其中,W2 是第二层全连接层的权重矩阵,b2 是偏置向量。 +1. 第一层全连接层(线性变换):$z = xW1 + b1$ 其中,W1 是第一层全连接层的权重矩阵,b1 是偏置向量。 +2. 激活函数:$a = g(z)$ 其中,g() 是激活函数,常用的激活函数有ReLU(Rectified Linear Unit)等。 +3. 第二层全连接层(线性变换):$y = aW2 + b2$ 其中,W2 是第二层全连接层的权重矩阵,b2 是偏置向量。 增大前馈子层隐状态的维度有利于提 升最终翻译结果的质量,因此,前馈子层隐状态的维度一般比自注意力子层要大。 @@ -32,7 +32,7 @@ $$ GeLU(x) = 0.5 \times x \times (1 + tanh(\sqrt{\frac{2}{\pi}} \times (x + 0.044715 \times x^3))) $$ -其中,`tanh() `是双曲正切函数,`sqrt()` 是平方根函数,$ \pi $是圆周率。 +其中,`tanh() `是双曲正切函数,`sqrt()` 是平方根函数,$\pi $是圆周率。 ```python import numpy as np @@ -41,7 +41,7 @@ def GELU(x): return 0.5 * x * (1 + np.tanh(np.sqrt(2 / np.pi) * (x + 0.044715 * np.power(x, 3)))) ``` -![](image/image_Kq6D-el8AR.png) +![](image/image_IPa0sZKGAr.png) 相对于 Sigmoid 和 Tanh 激活函数,ReLU 和 GeLU 更为准确和高效,因为它们在神经网络中的梯度消失问题上表现更好。而 ReLU 和 GeLU 几乎没有梯度消失的现象,可以更好地支持深层神经网络的训练和优化。 @@ -59,7 +59,7 @@ $$ 其中,$sigmoid()$ 是Sigmoid函数,$x$ 是输入,$\beta$ 是一个可调节的超参数。 -![](image/image_wVuqGXVkdW.png) +![](image/image_6evrfUSHQC.png) Swish函数的特点是在接近零的区域表现得类似于线性函数,而在远离零的区域则表现出非线性的特性。相比于其他常用的激活函数(如ReLU、tanh等),Swish函数在某些情况下能够提供更好的性能和更快的收敛速度。 @@ -103,7 +103,7 @@ $$ GeLU(x) = 0.5 \times x \times (1 + tanh(\sqrt{\frac{2}{\pi}} \times (x + 0.044715 \times x^3))) $$ -其中,`tanh() `是双曲正切函数,`sqrt()` 是平方根函数,$ \pi $是圆周率。 +其中,`tanh() `是双曲正切函数,`sqrt()` 是平方根函数,$\pi $是圆周率。 在公式中,GeLU函数首先对输入向量 x 进行一个非线性变换,然后通过一系列的数学运算得到最终的输出值。 diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/5.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_wVuqGXVkdW.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/6.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_6evrfUSHQC.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/5.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_wVuqGXVkdW.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/6.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_6evrfUSHQC.png" diff --git "a/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/5.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_Kq6D-el8AR.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/6.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_IPa0sZKGAr.png" similarity index 100% rename from "02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\237\272\347\241\200/5.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_Kq6D-el8AR.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/6.\346\277\200\346\264\273\345\207\275\346\225\260/image/image_IPa0sZKGAr.png" diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/MHA_MQA_GQA/MHA_MQA_GQA.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/MHA_MQA_GQA/MHA_MQA_GQA.md" new file mode 100644 index 0000000..d126c7e --- /dev/null +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/MHA_MQA_GQA/MHA_MQA_GQA.md" @@ -0,0 +1,224 @@ +# MHA\_MQA\_GQA + +## 1.总结 + +- 在 **MHA(Multi Head Attention)** 中,每个头有自己单独的 key-value 对;标准的多头注意力机制,h个Query、Key 和 Value 矩阵。 +- 在 **MQA(Multi Query Attention)** 中只会有一组 key-value 对;多查询注意力的一种变体,也是用于自回归解码的一种注意力机制。与MHA不同的是,**MQA 让所有的头之间共享同一份 Key 和 Value 矩阵,每个头只单独保留了一份 Query 参数,从而大大减少 Key 和 Value 矩阵的参数量**。 +- 在 **GQA(Grouped Query Attention)**中,会对 attention 进行分组操作,query 被分为 N 组,每个组共享一个 Key 和 Value 矩阵**GQA将查询头分成G组,每个组共享一个Key 和 Value 矩阵**。GQA-G是指具有G组的grouped-query attention。GQA-1具有单个组,因此具有单个Key 和 Value,等效于MQA。而GQA-H具有与头数相等的组,等效于MHA。 + +![](image/image_jBnali-wuO.png) + +GQA-N 是指具有 N 组的 Grouped Query Attention。GQA-1具有单个组,因此具有单个Key 和 Value,等效于MQA。而GQA-H具有与头数相等的组,等效于MHA。 + +GQA介于MHA和MQA之间。GQA 综合 MHA 和 MQA ,既不损失太多性能,又能利用 MQA 的推理加速。不是所有 Q 头共享一组 KV,而是分组一定头数 Q 共享一组 KV,比如上图中就是两组 Q 共享一组 KV。 + +## 2.代码实现 + +### 2.1 MHA + +多头注意力机制是Transformer模型中的核心组件。在其设计中,"多头"意味着该机制并不只计算一种注意力权重,而是并行计算多种权重,每种权重都从不同的“视角”捕获输入的不同信息。 + +1. 为输入序列中的每个元素计算q, k, v,这是通过将输入此向量与三个权重矩阵相乘实现的: + $$ + \begin{aligned} q & =x W_{q} \\ k & =x W_{k} \\ v & =x W_{v}\end{aligned} + $$ + 其中,$x$是输入词向量,$W_q$, $W_k$和$W_v$是q, k, v的权重矩阵 +2. 计算q, k 注意力得分:$\operatorname{score}(q, k)=\frac{q \cdot k^{T}}{\sqrt{d_{k}}}$,其中,$d_k$是k的维度 +3. 使用softmax得到注意力权重:$\operatorname{Attention}(q, K)=\operatorname{softmax}(\operatorname{score}(q, k))$ +4. 使用注意力权重和v,计算输出:$Output =\operatorname{Attention}(q, K) \cdot V$ +5. 拼接多头输出,乘以$W_O$,得到最终输出:$MultiHeadOutput = Concat \left(\right. Output ^{1}, Output ^{2}, \ldots, Output \left.^{H}\right) W_{O}$ + +代码实现 + +```python +import torch +from torch import nn +class MutiHeadAttention(torch.nn.Module): + def __init__(self, hidden_size, num_heads): + super(MutiHeadAttention, self).__init__() + self.num_heads = num_heads + self.head_dim = hidden_size // num_heads + + ## 初始化Q、K、V投影矩阵 + self.q_linear = nn.Linear(hidden_size, hidden_size) + self.k_linear = nn.Linear(hidden_size, hidden_size) + self.v_linear = nn.Linear(hidden_size, hidden_size) + + ## 输出线性层 + self.o_linear = nn.Linear(hidden_size, hidden_size) + + def forward(self, hidden_state, attention_mask=None): + batch_size = hidden_state.size()[0] + + query = self.q_linear(hidden_state) + key = self.k_linear(hidden_state) + value = self.v_linear(hidden_state) + + query = self.split_head(query) + key = self.split_head(key) + value = self.split_head(value) + + ## 计算注意力分数 + attention_scores = torch.matmul(query, key.transpose(-1, -2)) / torch.sqrt(torch.tensor(self.head_dim)) + + if attention_mask != None: + attention_scores += attention_mask * -1e-9 + + ## 对注意力分数进行归一化 + attention_probs = torch.softmax(attention_scores, dim=-1) + + output = torch.matmul(attention_probs, value) + + ## 对注意力输出进行拼接 + output = output.transpose(-1, -2).contiguous().view(batch_size, -1, self.head_dim * self.num_heads) + + output = self.o_linear(output) + + return output + + + def split_head(self, x): + batch_size = x.size()[0] + return x.view(batch_size, -1, self.num_heads, self.head_dim).transpose(1,2) + + + + +``` + +### 2.2 MQA + +上图最右侧,直观上就是在计算多头注意力的时候,query仍然进行分头,和多头注意力机制相同,而key和value只有一个头。 + +正常情况在计算多头注意力分数的时候,query、key的维度是相同的,所以可以直接进行矩阵乘法,但是在多查询注意力(MQA)中,query的维度为 `[batch_size, num_heads, seq_len, head_dim]`,key和value的维度为 `[batch_size, 1, seq_len, head_dim]`。这样就无法直接进行矩阵的乘法,为了完成这一乘法,可以采用torch的广播乘法 + +```python +## 多查询注意力 +import torch +from torch import nn +class MutiQueryAttention(torch.nn.Module): + def __init__(self, hidden_size, num_heads): + super(MutiQueryAttention, self).__init__() + self.num_heads = num_heads + self.head_dim = hidden_size // num_heads + + ## 初始化Q、K、V投影矩阵 + self.q_linear = nn.Linear(hidden_size, hidden_size) + self.k_linear = nn.Linear(hidden_size, self.head_dim) ### + self.v_linear = nn.Linear(hidden_size, self.head_dim) ### + + ## 输出线性层 + self.o_linear = nn.Linear(hidden_size, hidden_size) + + def forward(self, hidden_state, attention_mask=None): + batch_size = hidden_state.size()[0] + + query = self.q_linear(hidden_state) + key = self.k_linear(hidden_state) + value = self.v_linear(hidden_state) + + query = self.split_head(query) + key = self.split_head(key, 1) + value = self.split_head(value, 1) + + ## 计算注意力分数 + attention_scores = torch.matmul(query, key.transpose(-1, -2)) / torch.sqrt(torch.tensor(self.head_dim)) + + if attention_mask != None: + attention_scores += attention_mask * -1e-9 + + ## 对注意力分数进行归一化 + attention_probs = torch.softmax(attention_scores, dim=-1) + + output = torch.matmul(attention_probs, value) + + output = output.transpose(-1, -2).contiguous().view(batch_size, -1, self.head_dim * self.num_heads) + + output = self.o_linear(output) + + return output + + + + + def split_head(self, x, head_num=None): + + batch_size = x.size()[0] + + if head_num == None: + return x.view(batch_size, -1, self.num_heads, self.head_dim).transpose(1,2) + else: + return x.view(batch_size, -1, head_num, self.head_dim).transpose(1,2) + + +``` + +相比于多头注意力,多查询注意力在W\_k和W\_v的维度映射上有所不同,还有就是计算注意力分数采用的是广播机制,计算最后的output也是广播机制,其他的与多头注意力完全相同。 + +### 2.3 GQA + +GQA将MAQ中的key、value的注意力头数设置为一个能够被原本的注意力头数整除的一个数字,也就是group数。 + +不同的模型使用GQA有着不同的实现方式,但是总体的思路就是这么实现的,注意,***设置的组一定要能够被注意力头数整除。*** + +```python +## 分组注意力查询 +import torch +from torch import nn +class GroupQueryAttention(torch.nn.Module): + def __init__(self, hidden_size, num_heads, group_num): + super(MutiQueryAttention, self).__init__() + self.num_heads = num_heads + self.head_dim = hidden_size // num_heads + self.group_num = group_num + + ## 初始化Q、K、V投影矩阵 + self.q_linear = nn.Linear(hidden_size, hidden_size) + self.k_linear = nn.Linear(hidden_size, self.group_num * self.head_dim) + self.v_linear = nn.Linear(hidden_size, self.group_num * self.head_dim) + + ## 输出线性层 + self.o_linear = nn.Linear(hidden_size, hidden_size) + + def forward(self, hidden_state, attention_mask=None): + batch_size = hidden_state.size()[0] + + query = self.q_linear(hidden_state) + key = self.k_linear(hidden_state) + value = self.v_linear(hidden_state) + + query = self.split_head(query) + key = self.split_head(key, self.group_num) + value = self.split_head(value, self.group_num) + + ## 计算注意力分数 + attention_scores = torch.matmul(query, key.transpose(-1, -2)) / torch.sqrt(torch.tensor(self.head_dim)) + + if attention_mask != None: + attention_scores += attention_mask * -1e-9 + + ## 对注意力分数进行归一化 + attention_probs = torch.softmax(attention_scores, dim=-1) + + output = torch.matmul(attention_probs, value) + + output = output.transpose(-1, -2).contiguous().view(batch_size, -1, self.head_dim * self.num_heads) + + output = self.o_linear(output) + + return output + + + + + def split_head(self, x, group_num=None): + + batch_size,seq_len = x.size()[:2] + + if group_num == None: + return x.view(batch_size, -1, self.num_heads, self.head_dim).transpose(1,2) + else: + x = x.view(batch_size, -1, group_num, self.head_dim).transpose(1,2) + x = x[:, :, None, :, :].expand(batch_size, group_num, self.num_heads // group_num, seq_len, self.head_dim).reshape(batch_size, self.num_heads // group_num * group_num, seq_len, self.head_dim) + return x +``` diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/README.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/README.md" new file mode 100644 index 0000000..ed108a3 --- /dev/null +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/README.md" @@ -0,0 +1,51 @@ +# 02.大语言模型架构 + +### 2.1 Transformer模型 + +[1.attention](/docs/02.大语言模型架构/1.attention/1.attention.md "1.attention") + +[2.layer\_normalization](/docs/02.大语言模型架构/2.layer_normalization/2.layer_normalization.md "2.layer_normalization") + +[3.位置编码](/docs/02.大语言模型架构/3.位置编码/3.位置编码.md "3.位置编码") + +[4.tokenize分词](/docs/02.大语言模型架构/4.tokenize分词/4.tokenize分词.md "4.tokenize分词") + +[5.token及模型参数](/docs/02.大语言模型架构/5.token及模型参数/5.token及模型参数.md "5.token及模型参数") + +[6.激活函数](/docs/02.大语言模型架构/6.激活函数/6.激活函数.md "6.激活函数") + +### 2.2 注意力 + +[MHA\_MQA\_GQA](/docs/02.大语言模型架构/MHA_MQA_GQA/MHA_MQA_GQA.md "MHA_MQA_GQA") + +### 2.3 解码部分 + +[解码策略(Top-k & Top-p & Temperature)]( "解码策略(Top-k & Top-p & Temperature)") + +### 2.4 BERT + +[bert细节](/docs/02.大语言模型架构/bert细节/bert细节.md "bert细节") + +[Transformer架构细节](/docs/02.大语言模型架构/Transformer架构细节/Transformer架构细节.md "Transformer架构细节") + +[bert变种](/docs/02.大语言模型架构/bert变种/bert变种.md "bert变种") + +### 2.5 常见大模型 + +[llama系列模型](/docs/02.大语言模型架构/llama系列模型/llama系列模型.md "llama系列模型") + +[chatglm系列模型](/docs/02.大语言模型架构/chatglm系列模型/chatglm系列模型.md "chatglm系列模型") + +[llama 2代码详解]( "llama 2代码详解") + +[llama 3]( "llama 3") + +### 2.6 MoE + +[1.MoE论文](/docs/02.大语言模型架构/1.MoE论文/1.MoE论文.md "1.MoE论文") + +[2.MoE经典论文简牍](/docs/02.大语言模型架构/2.MoE经典论文简牍/2.MoE经典论文简牍.md "2.MoE经典论文简牍") + +[3.LLM MoE :Switch Transformers]( "3.LLM MoE :Switch Transformers") + + diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/Transformer\346\236\266\346\236\204\347\273\206\350\212\202.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/Transformer\346\236\266\346\236\204\347\273\206\350\212\202.md" new file mode 100644 index 0000000..607f377 --- /dev/null +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/Transformer\346\236\266\346\236\204\347\273\206\350\212\202.md" @@ -0,0 +1,320 @@ +# Transformer架构细节 + +![](image/image_N4T6xFNXi8.png) + +![](image/image_IpVyzjaIsA.png) + +## 1.Transformer各个模块的作用 + +### (1)Encoder模块 + +- 经典的Transformer架构中的Encoder模块包含6个Encoder Block. +- 每个Encoder Block包含两个⼦模块, 分别是多头⾃注意⼒层, 和前馈全连接层. + - 多头⾃注意⼒层采⽤的是⼀种Scaled Dot-Product Attention的计算⽅式, 实验结果表 明, Multi-head可以在更细致的层⾯上提取不同head的特征, ⽐单⼀head提取特征的 效果更佳. + - 前馈全连接层是由两个全连接层组成, 线性变换中间增添⼀个Relu激活函数, 具体的 维度采⽤4倍关系, 即多头⾃注意⼒的d\_model=512, 则层内的变换维度d\_ff=2048. + +### (2)Decoder模块 + +- 经典的Transformer架构中的Decoder模块包含6个Decoder Block. +- 每个Decoder Block包含3个⼦模块, 分别是多头⾃注意⼒层, Encoder-Decoder Attention 层, 和前馈全连接层. + - 多头⾃注意⼒层采⽤和Encoder模块⼀样的Scaled Dot-Product Attention的计算⽅ 式, 最⼤的 区别在于**需要添加look-ahead-mask,** 即遮掩"未来的信息". + - Encoder-Decoder Attention层和上⼀层多头⾃注意⼒层最主要的区别在于Q != K = V, 矩阵Q来源于上⼀层Decoder Block的输出, 同时K, V来源于Encoder端的输出. + - 前馈全连接层和Encoder中完全⼀样. + +### (3)Add & Norm模块 + +- Add & Norm模块接在每⼀个Encoder Block和Decoder Block中的每⼀个⼦层的后⾯. +- 对于每⼀个Encoder Block, ⾥⾯的两个⼦层后⾯都有Add & Norm. +- 对于每⼀个Decoder Block, ⾥⾯的三个⼦层后⾯都有Add & Norm. +- Add表示残差连接, 作⽤是为了将信息⽆损耗的传递的更深, 来增强模型的拟合能⼒. +- Norm表示LayerNorm, 层级别的数值标准化操作, 作⽤是防⽌参数过⼤过⼩导致的学习过程异常 , 模型收敛特别慢的问题. + +### (4)位置编码器Positional Encoding + +- Transformer中采⽤三⻆函数来计算位置编码. +- 因为三⻆函数是周期性函数, 不受序列⻓度的限制, ⽽且这种计算⽅式可以对序列中不同位置的编码的重要程度同等看待 + +## 2.Decoder端训练和预测的输入 + +1. 在Transformer结构中的Decoder模块的输⼊, 区分于不同的Block, 最底层的Block输⼊有其特殊的地⽅。第⼆层到第六层的输⼊⼀致, 都是上⼀层的输出和Encoder的输出。 +2. 最底层的Block在**训练阶段**, 每⼀个time step的输⼊是上⼀个time step的输⼊加上真实标 签序列向后移⼀位. 具体来看, 就是每⼀个time step的输⼊序列会越来越⻓, 不断的将之前的 输⼊融合进来. + ```text + 假设现在的真实标签序列等于"How are you?", + 当time step=1时, 输⼊张量为⼀个特殊的token, ⽐如"SOS"; + 当time step=2时, 输⼊张量为"SOS How"; + 当time step=3时, 输⼊张量为"SOS How are"; + 以此类推... + ``` +3. 最底层的Block在**训练阶段**, 真实的代码实现中, 采⽤的是MASK机制来模拟输⼊序列不断添 加的过程. +4. 最底层的Block在**预测阶段**, 每⼀个time step的输⼊是从time step=0开始, ⼀直到上⼀个 time step的预测值的累积拼接张量. 具体来看, 也是随着每⼀个time step的输⼊序列会越来越长. 相⽐于训练阶段最⼤的不同是这⾥不断拼接进来的token是每⼀个time step的预测值, ⽽不是训练阶段每⼀个time step取得的groud truth值 + ```纯文本 + 当time step=1时, 输⼊的input_tensor="SOS", 预测出来的输出值是output_tensor="What"; + 当time step=2时, 输⼊的input_tensor="SOS What", 预测出来的输出值是output_tensor="is"; + 当time step=3时, 输⼊的input_tensor="SOS What is", 预测出来的输出值是output_tensor="the"; + 当time step=4时, 输⼊的input_tensor="SOS What is the", 预测出来的输出值是output_tensor="matter"; + 当time step=5时, 输⼊的input_tensor="SOS What is the matter", 预测出来的输出值是output_tensor="?"; + 当time step=6时, 输⼊的input_tensor="SOS What is the matter ?", 预测出来的输出值是output_tensor="EOS", 代表句⼦的结束符, 说明解码结束, 预测结束. + + ``` + +## 3.Self-attention + +> Transformer中⼀直强调的self-attention是什么? 为什么能 发挥如此⼤的作⽤? 计算的时候如果不使⽤三元组(Q, K, V), ⽽ 仅仅使⽤(Q, V)或者(K, V)或者(V)⾏不⾏? + +### (1)self-attention的机制和原理 + +self-attention是⼀种通过⾃身和⾃身进⾏关联的attention机制, 从⽽得到更好的 representation来表达⾃身. + +self-attention是attention机制的⼀种特殊情况: 在self-attention中, Q=K=V, **序列中的每个单词(token)都和该序列中的其他所有单词 (token)进⾏attention规则的计算.** + +attention机制计算的特点在于, 可以**直接跨越⼀句话中不同距离的token, 可以远距离的学习到序列的知识依赖和语序结构.** + +![](image/image_M3kWTuKKV3.png) + +- 从上图中可以看到, self-attention可以远距离的捕捉到语义层⾯的特征(it的指代对象是 animal). +- 应⽤传统的RNN, LSTM, 在获取⻓距离语义特征和结构特征的时候, **需要按照序列顺序依次 计算, 距离越远的联系信息的损耗越⼤, 有效提取和捕获的可能性越⼩.** +- 但是应⽤self-attention时, 计算过程中会直接将句⼦中任意两个token的联系通过⼀个计算 步骤直接联系起来, + +### (2)关于self-attention为什么要使⽤(Q, K, V)三元组⽽不是其他形式 + +⾸先⼀条就是从分析的⻆度看, 查询Query是⼀条独⽴的序列信息, 通过关键词Key的提示作⽤, 得到最终语义的真实值Value表达, 数学意义更充分, 完备. + +这⾥不使用(K, V)或者(V)没有什么必须的理由, 也没有相关的论⽂来严格阐述⽐较试验的结果差异, 所以可以作为开放性问题未来去探索, 只要明确在经典self-attention实现中⽤的是三元组就好 + +## 4.Self-attention归一化和放缩 + +### (1)self-attention中的归⼀化概述 + +**训练上的意义**:随着词嵌⼊维度d\_k的增⼤, q \* k 点积后的结果也会增⼤, 在训练时会将 softmax函数推入梯度⾮常⼩的区域, 可能出现梯度消失的现象, 造成模型收敛困难. + +**数学上的意义**: 假设q和k的统计变量是满⾜标准正态分布的独⽴随机变量, 意味着q和k满⾜均 值为0, ⽅差为1。\*\* 那么q和k的点积结果就是均值为0, ⽅差为\*\*$d_k$**, 为了抵消这种⽅差被放⼤**$d_k$\*\* 倍的影响, 在计算中主动将点积缩放\*\*​$\frac{1}{\sqrt(d_k)}$, 这样点积后的结果依然满⾜均值为0, ⽅差为 1。 + +### (2)softmax的梯度变化 + +这⾥我们分3个步骤来解释softmax的梯度问题: + +#### 第⼀步: softmax函数的输⼊分布是如何影响输出的 + +对于⼀个输⼊向量x, softmax函数将其做了⼀个归⼀化的映射, ⾸先通过⾃然底数e将输⼊元素之间的差距先"拉⼤", 然后再归⼀化为⼀个新的分布。 **在这个过程中假设某个输⼊x 中最⼤的元素下标是k, 如果输⼊的数量级变⼤(就是x中的每个分量绝对值都很⼤), 那么在数学上会造成y\_k的值⾮常接近1。** + +具体⽤⼀个例⼦来演示, 假设输⼊的向量$x = [a, a, 2a]$, 那么随便给⼏个不同数量级的值来看看对y3产⽣的影响 + +```纯文本 +a = 1时, y3 = 0.5761168847658291 +a = 10时, y3 = 0.9999092083843412 +a = 100时, y3 = 1.0 +``` + +采⽤⼀段实例代码将a在不同取值下, 对应的y3全部画出来, 以曲线的形式展示: + +```python +from math import exp +from matplotlib import pyplot as plt +import numpy as np +f = lambda x: exp(x * 2) / (exp(x) + exp(x) + exp(x * 2)) +x = np.linspace(0, 100, 100) +y_3 = [f(x_i) for x_i in x] +plt.plot(x, y_3) +plt.show() +``` + +![](image/image_9d1SPjXTXO.png) + +从上图可以很清楚的看到输⼊元素的数量级对softmax最终的分布影响⾮常之⼤。 + +**结论**: **在输⼊元素的数量级较⼤时, softmax函数⼏乎将全部的概率分布都分配给了最⼤值分量所对应的标签** + +#### 第⼆步: softmax函数在反向传播的过程中是如何梯度求导的 + +首先,定义神经网络的输入和输出 + +$$ +设X=[x_1,x_2,..., x_n], Y=softmax(X)=[y_1, y_2,..., y_3] \\ +则~y_i=\frac{e^{x_i}}{\sum_{j=1}^{n} e^{x_j}},~显然~ \sum_{j=1}^{n} e^{x_j}=1 +$$ + +反向传播就是输出端的损失函数对输⼊端求偏导的过程, 这⾥要分两种情况, + +\*\*(1)当 \*\*$i=j$**时:** + +$$ +\begin{aligned} +\frac{\partial y_{i}}{\partial x_{j}}& =\frac{\partial y_i}{\partial x_i} \\ +&=\frac{\partial}{\partial x_i}(\frac{e^{x_i}}{\sum_k e^{x_k}}) \\ +&=\frac{(e^{x_i})'(\sum_k e^{x_k})-e^{x_i}(\sum_k e^{x_k})'}{(\sum_k e^{x_k})^2} \\ +&=\frac{e^{x_i}\cdot(\sum_ke^{x_k})-e^{x_i}\cdot e^{x_i}}{(\sum_ke^{x_k})^2} \\ +&=\frac{e^{x_i}\cdot(\sum_k e^{x_k})}{(\sum_k e^{x_k})^2}-\frac{e^{x_i}\cdot e^{x_i}}{(\sum_k e^{x_k})^2} \\ +&=\frac{e^{x_i}}{\sum_k e^{x_k}}-\frac{e^{x_i}}{\sum_k e^{x_k}}\cdot\frac{e^{x_i}}{\sum_k e^{x_k}} \\ +&=y_i-y_i\cdot y_i \\ +&=y_i(1-y_i) +\end{aligned} +$$ + +**(2)当**$ i ≠ j$**时:** + +$$ +\begin{aligned} +\frac{\partial y_{i}}{\partial x_{j}} & =\frac{\partial}{\partial x_{j}}\left(\frac{e^{x_{i}}}{\sum_{k} e^{x_{k}}}\right) \\ +& =\frac{\left(e^{x_{i}}\right)^{\prime}\left(\sum_{k} e^{x_{k}}\right)-e^{x_{i}}\left(\sum_{k} e^{x_{k}}\right)^{\prime}}{\left(\sum_{k} e^{x_{k}}\right)^{2}} \\ +& =\frac{0 \cdot\left(\sum_{k} e^{x_{k}}\right)-e^{x_{i}} \cdot e^{x_{j}}}{\left(\sum_{k} e^{x_{k}}\right)^{2}} \\ +& =-\frac{e^{x_{i}} \cdot e^{x_{j}}}{\left(\sum_{k} e^{x_{k}}\right)^{2}} \\ +& =-\frac{e^{x_{i}}}{\sum_{k} e^{x_{k}}} \cdot \frac{e^{x_{i}}}{\sum_{k} e^{x_{k}}} \\ +& =-y_{i} \cdot y_{i} +\end{aligned} +$$ + +经过对两种情况分别的求导计算, 可以得出最终的结论如下: + +$$ +\begin{aligned} +& 综上所述:\frac{\partial y_i}{\partial x_j}=\begin{cases}y_i-y_i\cdot y_i,&\text{i=j}\\ \\ 0-y_i\cdot y_i,&\text{i}\neq\text{j}\end{cases} \\ +& 所以:\frac{\partial Y}{\partial X}=diag(Y)-Y^T\cdot Y(当Y的shape为(1,n)时) +\end{aligned} +$$ + +#### 第三步: softmax函数出现梯度消失现象的原因 + +根据第二步中softmax函数的求导结果, 可以将最终的结果以矩阵形式展开如下: + +$$ +\frac{\partial g(X)}{\partial X} \approx\left[\begin{array}{cccc} +\hat{y}_{1} & 0 & \cdots & 0 \\ +0 & \hat{y}_{2} & \cdots & 0 \\ +\vdots & \vdots & \ddots & \vdots \\ +0 & 0 & \cdots & \hat{y}_{d} +\end{array}\right]-\left[\begin{array}{cccc} +\hat{y}_{1}^{2} & \hat{y}_{1} \hat{y}_{2} & \cdots & \hat{y}_{1} \hat{y}_{d} \\ +\hat{y}_{2} \hat{y}_{1} & \hat{y}_{2}^{2} & \cdots & \hat{y}_{2} \hat{y}_{d} \\ +\vdots & \vdots & \ddots & \vdots \\ +\hat{y}_{d} \hat{y}_{1} & \hat{y}_{d} \hat{y}_{2} & \cdots & \hat{y}_{d}^{2} +\end{array}\right] +$$ + +根据第一步中的讨论结果, 当输入x的分量值较大时, softmax函数会将大部分概率分配给最大的元素, 假设最大元素是x1, 那么softmax的输出分布将产生一个接近one-hot的结果张量y\_ = \[1, 0, 0,..., 0], 此时结果矩阵变为: + +$$ +\frac{\partial g(X)}{\partial X} \approx\left[\begin{array}{cccc}1 & 0 & \cdots & 0 \\ 0 & 0 & \cdots & 0 \\ & & & \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & 0\end{array}\right]-\left[\begin{array}{cccc}1 & 0 & \cdots & 0 \\ 0 & 0 & \cdots & 0 \\ & & & \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & 0\end{array}\right]=0 +$$ + +结论:综上可以得出,\*\* 所有的梯度都消失为0(接近于0), 参数几乎无法更新, 模型收敛困难\*\*. + +### (3)维度与点积大小的关系 + +针对为什么维度会影响点积的大小, 原始论文中有这样的一点解释如下: + +```纯文本 +To illustrate why the dot products get large, assume that the components of q and k are independent random variables with mean 0 and variance 1. Then their doct product,q*k = (q1k1+q2k2+......+q(d_k)k(d_k)), has mean 0 and variance d_k. + +``` + +分两步对其进行一个推导, 首先就是假设向量q和k的各个分量是相互独立的随机变量, $X = q_i$, $Y = k_i$, X和Y各自有d\_k个分量, 也就是向量的维度等于d\_k, 有$E(X) = E(Y) = 0$, 以及$D(X) = D(Y) = 1$. + +可以得到$E(XY) = E(X)E(Y) = 0 * 0 = 0$ + +同理, 对于$D(XY)$推导如下: + +$$ +\begin{aligned} +D(XY)& =E(X^2\cdot Y^2)-[E(XY)]^2 \\ +&=E(X^2)E(Y^2)-[E(X)E(Y)]^2 \\ +&=E(X^2-0^2)E(Y^2-0^2)-[E(X)E(Y)]^2 \\ +&=E(X^2-[E(X)]^2)E(Y^2-[E(Y)]^2)-[E(X)E(Y)]^2 \\ +&=D(X)D(Y)-[E(X)E(Y)]^2 \\ +&=1\times1-\left(0\times0\right)^2 \\ +&=1 +\end{aligned} +$$ + +根据期望和方差的性质, 对于互相独立的变量满足下式: + +$$ +\begin{gathered} +E(\sum_{i}Z_{i})=\sum_{i}E(Z_{i}), \\ +D(\sum_{i}Z_{i})=\sum_{i}D(Z_{i}) +\end{gathered} +$$ + +根据上面的公式, 可以很轻松的得出q\*k的均值为$E(qk) = 0$, $D(qk) = d_k$。所以方差越大, **对应的qk的点积就越大, 这样softmax的输出分布就会更偏向最大值所在的分量**。一个技巧就是将点积除以$\sqrt{d_k}$ 将方差在数学上重新"拉回1", 如下所示 + +$$ +D(\frac{q\cdot k}{\sqrt{d_k}})=\frac{d_k}{(\sqrt{d_k})^2}=1 +$$ + +最终的结论:**通过数学上的技巧将方差控制在1, 也就有效的控制了点积结果的发散, 也就控制了对应的梯度消失的问题**! + +## 5.Multi-head Attention + +### (1)采⽤Multi-head Attention的原因 + +1. 原始论⽂中提到进⾏Multi-head Attention的原因是将模型分为多个头, **可以形成多个子空间间, 让模型去关注不同方面的信息**, 最后再将各个⽅⾯的信息综合起来得到更好的效果. +2. 多个头进⾏attention计算最后再综合起来, 类似于CNN中采⽤多个卷积核的作⽤, 不同的卷 积核提取不同的特征, **关注不同的部分, 最后再进行融合**. +3. 直观上讲, **多头注意力有助于神经网络捕捉到更丰富的特征信息**. + +#### (2)Multi-head Attention的计算⽅式 + +1. Multi-head Attention和单⼀head的Attention唯⼀的区别就在于,\*\* 其对特征张量的最后⼀个维度进行了分割, ⼀般是对词嵌入的embedding\_dim=512进⾏切割成head=8, \*\*这样每⼀个head的嵌⼊维度就是512/8=64, 后续的Attention计算公式完全⼀致, 只不过是在64这个维度上进⾏⼀系列的矩阵运算⽽已. +2. 在head=8个头上分别进⾏注意⼒规则的运算后, 简单采用拼接**concat**的⽅式对结果张量进 ⾏融合就得到了Multi-head Attention的计算结果. + +## 6.Transformer和RNN + +### (1)Transformer的并行计算 + +对于Transformer⽐传统序列模型RNN/LSTM具备优势的第⼀⼤原因就是强⼤的并⾏计算能力. + +对于RNN来说, 任意时刻`t`的输⼊是时刻t的输⼊`x(t)`和上⼀时刻的隐藏层输出`h(t-1)`, 经过运算后得到当前时刻隐藏层的输出`h(t)`, 这个`h(t)`也即将作为下⼀时刻`t+1`的输⼊的⼀部分. 这个计算过程是RNN的本质特征, RNN的历史信息是需要通过这个时间步⼀步⼀步向后传递的. 而**这就意味着RNN序列后⾯的信息只能等到前⾯的计算结束后, 将历史信息通过hidden state传递给后⾯才能开始计算, 形成链式的序列依赖关系, 无法实现**并行. + +对于Transformer结构来说, 在self-attention层, ⽆论序列的⻓度是多少, 都可以⼀次性计算所有单词之间的注意⼒关系, 这个attention的计算是同步的, 可以实现并⾏. + +### (2)Transformer的特征抽取能力 + +对于Transformer⽐传统序列模型RNN/LSTM具备优势的第⼆⼤原因就是强⼤的特征抽取能力 。 + +Transformer因为采⽤了Multi-head Attention结构和计算机制, 拥有⽐RNN/LSTM更强⼤的特征抽取能⼒, 这⾥并不仅仅由理论分析得来, 而是⼤量的试验数据和对⽐结果, 清楚的展示了Transformer的特征抽取能⼒远远胜于RNN/LSTM. + +**注意**: 不是越先进的模型就越无敌, 在很多具体的应⽤中RNN/LSTM依然⼤有⽤武之地, 要具体问题具体分析 + +## 7.Transformer代替seq2seq? + +### (1)seq2seq的两大缺陷 + +1. seq2seq架构的第⼀⼤缺陷是将Encoder端的所有信息**压缩成⼀个固定⻓度的语义向量中, ⽤这个固定的向量来代表编码器端的全部信息. 这样既会造成信息的损耗**, 也⽆法让Decoder 端在解码的时候去⽤注意⼒聚焦哪些是更重要的信息. +2. seq2seq架构的第二大缺陷是**无法并行**, 本质上和RNN/LSTM无法并行的原因⼀样. + +### (2)Transformer的改进 + +Transformer架构同时解决了seq2seq的两⼤缺陷, 既可以并⾏计算, ⼜应⽤Multi-head Attention机制来解决Encoder固定编码的问题, 让Decoder在解码的每⼀步可以通过注意⼒去 关注编码器输出中最重要的那些部分. + +## 8.Transformer并行化 + +### (1)Encoder并行化 + +![](image/image_R3X8BJhzuq.png) + +1. 上图最底层绿⾊的部分, 整个序列所有的token可以并⾏的进⾏Embedding操作, 这⼀层的处理是没有依赖关系的. +2. 上图第⼆层⼟⻩⾊的部分, 也就是Transformer中最重要的self-attention部分, 这⾥对于任意⼀个单词⽐如x1, 要计算x1对于其他所有token的注意⼒分布, 得到z1. 这个过程是具有依赖性的, 必须等到序列中所有的单词完成Embedding才可以进⾏。因此这⼀步是不能并⾏处理的。 但是从另⼀个⻆度看, 我们真实计算注意⼒分布的时候, 采⽤的都是矩阵运算, 也就是可以⼀次性的计算出所有token的注意⼒张量, 从这个⻆度看也算是实现了并行, 只是矩阵运算的"并行"和词嵌⼊的"并行"概念上不同⽽已. +3. 上图第三层蓝⾊的部分, 也就是前馈全连接层, 对于不同的向量z之间也是没有依赖关系的, 所以这⼀层是可以实现并行化处理的. 也就是所有的向量z输⼊Feed Forward⽹络的计算可以同步进⾏, 互不⼲扰 + +### (2)Decoder的并行化 + +![](image/image_fzuad0FC4i.png) + +1. Decoder模块在训练阶段采用了并行化处理。 其中Self-Attention和Encoder-Decoder Attention两个子层的并行化也是在进行矩阵乘法, 和Encoder的理解是一致的. 在进行Embedding和Feed Forward的处理时, 因为各个token之间没有依赖关系, 所以也是可以完全并行化处理的, 这里和Encoder的理解也是一致的. +2. Decoder模块在预测阶段基本上不认为采用了并行化处理. 因为第一个time step的输入只是一个"SOS", 后续每一个time step的输入也只是依次添加之前所有的预测token. +3. **注意:** 最重要的区别是训练阶段目标文本如果有20个token, 在训练过程中是一次性的输入给Decoder端, 可以做到一些子层的并行化处理. 但是在预测阶段, 如果预测的结果语句总共有20个token, 则需要重复处理20次循环的过程, 每次的输入添加进去一个token, 每次的输入序列比上一次多一个token, 所以不认为是并行处理. + +### (3)总结 + +**Transformer架构中Encoder模块的并行化机制** + +- **Encoder模块在训练阶段和测试阶段都可以实现完全相同的并行化.** +- Encoder模块在Embedding层, Feed Forward层, Add & Norm层都是可以并行化的. +- Encoder模块在self-attention层, 因为各个token之间存在依赖关系, 无法独立计算, 不是真正意义上的并行化. +- Encoder模块在self-attention层, 因为采用了矩阵运算的实现方式, 可以一次性的完成所有注意力张量的计算, 也是另一种"并行化"的体现. + +**Transformer架构中Decoder模块的并行化机制** + +- **Decoder模块在训练阶段可以实现并行化**. +- Decoder模块在训练阶段的Embedding层, Feed Forward层, Add & Norm层都是可以并行化的. +- Decoder模块在self-attention层, 以及Encoder-Decoder Attention层, 因为各个token之间存在依赖关系, 无法独立计算, 不是真正意义上的并行化. +- Decoder模块在self-attention层, 以及Encoder-Decoder Attention层, 因为采用了矩阵运算的实现方式, 可以一次性的完成所有注意力张量的计算, 也是另一种"并行化"的体现. +- **Decoder模块在预测计算不能并行化处理.** diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_9d1SPjXTXO.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_9d1SPjXTXO.png" new file mode 100644 index 0000000..fca3244 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_9d1SPjXTXO.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_IpVyzjaIsA.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_IpVyzjaIsA.png" new file mode 100644 index 0000000..c0c13f7 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_IpVyzjaIsA.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_M3kWTuKKV3.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_M3kWTuKKV3.png" new file mode 100644 index 0000000..06665a3 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_M3kWTuKKV3.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_N4T6xFNXi8.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_N4T6xFNXi8.png" new file mode 100644 index 0000000..195604c Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_N4T6xFNXi8.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_R3X8BJhzuq.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_R3X8BJhzuq.png" new file mode 100644 index 0000000..fe751aa Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_R3X8BJhzuq.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_fzuad0FC4i.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_fzuad0FC4i.png" new file mode 100644 index 0000000..b0ec529 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/Transformer\346\236\266\346\236\204\347\273\206\350\212\202/image/image_fzuad0FC4i.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/bert\345\217\230\347\247\215/bert\345\217\230\347\247\215.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/bert\345\217\230\347\247\215/bert\345\217\230\347\247\215.md" new file mode 100644 index 0000000..aa528fc --- /dev/null +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/bert\345\217\230\347\247\215/bert\345\217\230\347\247\215.md" @@ -0,0 +1,170 @@ +# bert变种 + +### 1.RoBERTa + +> 原论文链接: [https://arxiv.org/pdf/1907.11692.pdf](https://arxiv.org/pdf/1907.11692.pdf "https://arxiv.org/pdf/1907.11692.pdf") + +RoBERTa 的全称是 Robustly optimized BERT approach。 + +RoBERTa 是在 bert 的基础上做了一些改进,这些改进并不是设计什么新颖的结构,而是尽量使模型得到更充分的预训练,释放 bert 模型的潜力。 + +改进共有四个方面: + +- **使用更大的 batch-size,更大的数据集,做更充分的训练**; +- 使用的数据中具有更大的 sequence length,而不是像 bert 中会掺杂一些短句; +- **移除 NSP 任务**:这里的实验结果表明,不使用NSP的效果要优于使用NSP +- **将静态 mask 机制改为动态 mask 机制**; + +另外还有一个是 **tokenize 时使用的是与 GPT-2 相同的 BPE 策略**。 + +做了上述改进之后,指标有所提升。 + +### 2.ALBERT + +> 原文链接:[https://openreview.net/pdf?id=H1eA7AEtvS](https://openreview.net/pdf?id=H1eA7AEtvS "https://openreview.net/pdf?id=H1eA7AEtvS") + +ALBERT 的全称为 A Lite BERT。所以从名字可以看出,这个模型的目的是想搞一个比 Bert 更小、更轻量级的模型。这个模型相比于 Bert 在三个方面做了修改。 + +#### 2.1 对Embedding 层的参数做因式分解 + +> 符号说明:将 embedding 层向量的维度定义为 `E`,将 transformer 层中向量的维度定义为 `H`,在 Bert 中 `E` 与 `H` 是相等的。 + +在 Bert 模型中,embedding 层的向量维度与 transformer 层的向量维度是相同的,该文作者认为这两者没有必要相同,原因有二: + +- 一般来说,模型不同的层学到的信息是不同的,按照 ELMo 模型中的分析,**靠近输入的层学到的是语法信息,离输入较远的层学到的是语义信息**。在本文中作者认为,embedding 层中学到的向量应该是没有上下文(context)信息的,而 transformer 层中学到的向量是包含上下文(context)信息的。所以从这个角度来说由于需要存储更复杂的上下文(context)信息,transformer 层中的向量维度 `H` 应该要远大于 embedding 层中的向量维度 `E`。 +- 另外一个方面则是因为\*\* embedding 的参数量在整个模型的参数量中占比是比较高的\*\*,而 embedding 层在训练时更新的又比较稀疏(这个结论是哪来的?)所以减少 embedding 层的参数量是合理的。 + +基于上述两个原因,本文提出的方法是 **embedding 权重矩阵的维度是`V * E`**(这里的 `E < H` ),**得到 embedding 的向量之后再通过一个 ****`E * H`**** 的权重矩阵投影到 transformer 层的隐空间上**。改进前后 embedding 层的参数量分别为: + +- 改进前的参数量:`V * E`,这里 `V` 表示 vocab 的个数,并且 `E` 与 `H` 相等。以 bert-base 模型为例,参数量为 21128 \* 768 = 16226304,约为 16M; +- 改进后的参数量:`V * E + E * H`,这里 `E` 是小于 `H` 的。还是以 bert-base 模型为例,假设 embedding 层的向量维度 `E` 为 128,参数量为 21128 \* 128 + 128 \* 768 = 2802688,约为 2.8M; + +可以看出 embedding 层的参数量大幅减少。 + +#### 2.2 跨层参数共享 + +这部分的做法很容易理解,就是**所有的 transformer 层共享相同的参数,也就是说实际上只有一个 transformer 层的权重**,然后会多次经过这个 transformer 层。比如 bert-base 有 12 层 transformer,改成 ALBERT就是数据会经过同一个 transformer 层 12 次,如下图: + +![](image/image_4Gyqd19sq_.png) + +#### 2.3 将 NSP 任务换成了 SOP 任务 + +SOP 的全称为 sentence order prediction。 + +在该文章之前已经有些文章发现,bert 的论文中的 NSP 任务没有什么作用。该论文任务 NSP 任务之所以没有作用,是因为其太简单了,所以在其基础上设计了一个难度更高的新任务,也就是 SOP 任务。**SOP 任务就是预测两句话有没有被交换过顺序**。 + +### 3.spanBERT + +SpanBERT是提出对BERT进行的一些简单修正,重新实现的BERT,其中它在三个方面进行的改进:1、将token mask改成spanmask。2、损失函数加上SBO损失。3、去掉NSP。 + +#### 3.1 将token mask改成span mask + +不采用随机mask的方法,而是采用mask掉一定的连续token。 + +原生BERT中对mask的位置是随机的,后面有改进为mask的时候如果一个单词被拆分成不同的word piece,那么这些token一起被mask(广义上的mask)。本文作者把这个推广到span级别:每次mask的时候,先从[几何分布](https://link.zhihu.com/?target=https://baike.baidu.com/item/%E5%87%A0%E4%BD%95%E5%88%86%E5%B8%83 "几何分布") 中采样出一个span长度,然后从均匀分布中采样span的起始位置。 + +#### 3.2 增加由边界预测mask的任务(SBO) + +在很多任务中,会用到利用span的边界作为span本身的表示(比如coreference resolution),作者受此启发,增加了一个利用边界token预测span的任务。 + +序列$X=\left(x_{1}, \ldots x_{n}\right)$,其中$Y \subseteq X$,有被mask的span $\left(x_{s}, \ldots, x_{e}\right)$,其中`s`和`e`分别代表开始和结尾。我们通过外边界$x_{s-1}$和$x_{e+1}$来预测被mask掉的全部token。 + +如果被mask掉的单词的位置为 $p_i$,那么预测可以表示为: + +$$ +y_{i}=f\left(x_{s-1}, x_{e+1}, p_{i}\right) +$$ + +论文中f的实现用的是两层带GeLU激活函数的全连接网络。 + +#### 3.3 去掉NSP + +# 4.XLNet + +XLNet是由卡内基梅隆大学和Google大脑联合提出的一种算法,其沿用了自回归的语言模型,并利用排列语言模型合并了bert的优点,同时集成transformer-xl对于长句子的处理,达到了SOTA的效果。 + +#### 4.1 AR和AE + +- AR:Autoregressive Language Modeling +- AE: Autoencoding Language Modeling + +XLNet 的出发点就是:能否融合AR LM 和 AE LM 两者的优点。具体来说就是,站在 AR 的角度,如何引入和双向语言模型等价的效果. + +#### 4.2 排列语言模型(Permutation Language Model) + +作者发现,只要在 AR中再加入一个步骤,就能够完美地将AR与AE的优点统一起来,那就是提出**Permutation Language Model**(PLM)。 + +![](image/image_36pl-589i_.png) + +具体实现方式是,通过**随机取一句话的一种排列,然后将末尾一定量的词给“遮掩”**(和 BERT 里的直接替换 “\[MASK]” 有些不同)掉,最后**用 AR 的方式来按照这种排列依次预测被“遮掩”掉的词**。 + +![](image/image_On3o9XHhM0.png) + +我们可以发现通过随机取排列(Permutation)中的一种,就能非常巧妙地通过 **AR 的单向方式来习得双向信息**了。 + +论文中 Permutation 具体的实现方式是通过直接对 Transformer 的 **Attention Mask** 进行操作。 + +![](image/image_QdKCNi1Ipa.png) + +比如说序号依次为 1234 的句子,先随机取一种排列3241。于是根据这个排列就做出类似上图的 Attention Mask。先看第1行,因为在新的排列方式中 1 在最后一个,根据从左到右 AR 方式,1 就能看到 234 全部,于是第一行的 234 位置是红色的(没有遮盖掉,会用到),以此类推。第2行,因为 2 在新排列是第二个,只能看到 3,于是 3 位置是红色。第 3 行,因为 3 在第一个,看不到其他位置,所以全部遮盖掉... + +#### 4.3 Two-Stream Self-Attention + +为了实现 Permutation 加上 AR 预测过程,首先我们会发现,打乱顺序后位置信息非常重要,同时对每个位置来说,需要预测的是内容信息(对应位置的词),于是输入就不能包含内容信息,不然模型学不到东西,只需要直接从输入复制到输出就好了。 + +于是这里就造成了**位置信息与内容信息的割裂**,因此在 BERT 这样的位置信息加内容信息输入 Self-Attention (自注意力) 的流(Stream)之外,作者还增加了另一个**只有位置信息作为 Self-Attention****中 query 输入的流**。文中将前者称为 **Content Stream**,而后者称为 **Query Stream**。 + +这样就能利用 Query Stream 在对需要预测位置进行预测的同时,又不会泄露当前位置的内容信息。具体操作就是用两组隐状态(hidden states) *`g`* 和 `ℎ` 。其中 *`g`* 只有位置信息,作为 Self-Attention 里的 Q。 `ℎ` 包含内容信息,则作为 K 和 V。具体表示如下图(a)所示: + +![](image/image_hxNT4Qvpj9.png) + +上图中我们需要理解两点: + +- 第一点,最下面一层蓝色的 Content Stream 的输入是 $e(x_i)$ ,这个很好懂就是 $x$ 对应的词向量 (Embedding),不同词对应不同向量,但看旁边绿色的 Query Stream,就会觉得很奇怪,为什么都是一样的 $w$ ?这个和Relative Positional Encoding 有关。 +- 第二点,Query stream attention图中为了便于说明,只将当前位置之外的 h 作为 K 和 V,但实际上实现中应该是所有时序上的 h 都作为 K 和 V,最后再交给上图中的 Query stream 的 Attention Mask 来完成位置的遮盖。 + +#### 4.4 Partial Prediction + +XLNet还使用了部分预测(Partial Prediction)的方法。因为LM是从第一个Token预测到最后一个Token,在预测的起始阶段,上文信息很少而不足以支持Token的预测,这样可能会对分布产生误导,从而使得模型收敛变慢。为此,XLNet只预测后面一部分的Token,而把前面的所有Token都当作上下文。 + +具体来说,对长度为T的句子,我们选取一个超参数K,使得后面`1/K`的Token用来预测,前面`1-1/K`的Token用作上下文。注意,`K`越大,上下文越多,模型预测就越精确。 + +#### 4.5 Transformer-XL + +对于过长序列,如果分段来进行处理,往往会遗漏信息,且效果会下降,那么xlnet借鉴了Transformer-XL的思想,设置一个保留上一个片段的信息,在训练时进行更新。 + +### 5.AR和AE + +![](image/image_OtgnXs1k5H.png) + +#### 5.1 自回归语言模型(AutoRegressive LM) + +AR语言模型:指的是,**依据前面(或后面)出现的tokens来预测当前时刻的token**,代表有 ELMO, GPT等。 + +> GPT 就是典型的自回归语言模型。ELMO 尽管看上去利用了上文,也利用了下文,但是本质上仍然是自回归 LM,这个跟模型具体怎么实现有关系。ELMO 是分别做了两个方向的自回归 LM(从左到右以及从右到左两个方向的语言模型),然后把 LSTM 的两个方向的隐状态拼接到一起,来体现双向语言模型这个事情的。所以其本质上仍然是自回归语言模型 + +给定文本序列$\mathbf{x}=\left[x_{1}, \ldots, x_{T}\right]$,语言模型的目标是调整参数使得训练数据上的似然函数最大: + +$$ +\max _{\theta} \log p_{\theta}(\mathbf{x})=\sum_{t=1}^{T} \log p_{\theta}\left(x_{t} \mid \mathbf{x}_{ GeLU:在激活中引入了随机正则的思想,根据当前input大于其余inputs的概率进行随机正则化,即为在mask时依赖输入的数据分布,即x越小越有可能被mask掉,因此服从伯努利分布$\operatorname{Bernoulli}(\phi(x))$,其中,$\phi(x)=P(X \leq x)$ +> ReLU:缺乏随机因素,只用0和1 + +### 3.10 MLM任务,对于在数据中随机选择 15% 的标记,其中80%被换位\[mask],10%不变、10%随机替换其他单词,原因是什么? + +典型的Denosing Autoencoder的思路,**那些被Mask掉的单词就是在输入侧加入的所谓噪音**。类似BERT这种预训练模式,被称为DAE LM。因此总结来说BERT模型 `[Mask]` 标记就是**引入噪音**的手段。 + +预测一个词汇时,模型并不知道输入对应位置的词汇是否为正确的词汇( 10%概率),这就迫使模型更多地依赖于上下文信息去预测词汇,并且赋予了模型一定的纠错能力。 + +两个缺点: + +1. 因为Bert用于下游任务微调时, `[MASK]`标记不会出现,它只出现在预训练任务中。这就造成了预训练和微调之间的不匹配,微调不出现`[MASK]`这个标记,模型好像就没有了着力点、不知从哪入手。所以只将80%的替换为`[mask]`,但这也只是缓解、不能解决。 +2. 相较于传统语言模型,Bert的每批次训练数据中只有 15% 的标记被预测,这导致模型需要更多的训练步骤来收敛。 + +### 3.11其mask相对于CBOW有什么异同点? + +**相同点**: + +- CBOW的核心思想是:给定上下文,根据它的上文 Context-Before 和下文 Context-after 去预测input word。 +- 而BERT本质上也是这么做的,但是BERT的做法是给定一个句子,会随机Mask 15%的词,然后让BERT来预测这些Mask的词。 + +**不同点**: + +1. 在CBOW中,每个单词都会成为input word,而BERT不是这么做的,原因是这样做的话,训练数据就太大了,而且训练时间也会非常长。 +2. 对于输入数据部分,CBOW中的输入数据只有待预测单词的上下文,而BERT的输入是带有`[MASK]` token的“完整”句子,也就是说**BERT在输入端将待预测的input word用`[MASK]`token代替了**。 +3. 通过CBOW模型训练后,每个单词的word embedding是唯一的,因此并不能很好**的处理一词多义的问题**,而BERT模型得到的word embedding(token embedding)融合了上下文的信息,就算是同一个单词,在不同的上下文环境下,得到的word embedding是不一样的。 + +### 3.12 对于长度较长的语料,如何训练? + +对于长文本,有两种处理方式,截断和切分。 + +- **截断**:一般来说文本中最重要的信息是开始和结尾,因此文中对于长文本做了截断处理。 + 1. head-only:保留前510个字符 + 2. tail-only:保留后510个字符 + 3. head+tail:保留前128个和后382个字符 +- **切分**: 将文本分成k段,每段的输入和Bert常规输入相同,第一个字符是\[CLS]表示这段的加权信息。文中使用了Max-pooling, Average pooling和self-attention结合这些片段的表示。 + +## 4.BERT损失函数 + +Bert 损失函数组成:第一部分是来自 Mask-LM 的单词级别分类任务;另一部分是句子级别的分类任务; + +优点:通过这两个任务的联合学习,可以使得 BERT 学习到的表征既有 token 级别信息,同时也包含了句子级别的语义信息。 + +$$ +L\left(\theta, \theta_{1}, \theta_{2}\right)=L_{1}\left(\theta, \theta_{1}\right)+L_{2}\left(\theta, \theta_{2}\right) +$$ + +- $\theta$: BERT 中 Encoder 部分的参数; +- $\theta_{1} $: 是 Mask-LM 任务中在 Encoder 上所接的输出层中的参数; +- $\theta_{2}$ :是句子预测任务中在 Encoder 接上的分类器参数; + +在第一部分的损失函数中,如果被 mask 的词集合为 M,因为它是一个词典大小 |V| 上的多分类问题,所用的损失函数叫做负对数似然函数(且是最小化,等价于最大化对数似然函数),那么具体说来有: + +$$ +L_{1}\left(\theta, \theta_{1}\right)=-\sum_{i=1}^{M} \log p\left(m=m_{i} \mid \theta, \theta_{1}\right), m_{i} \in[1,2, \ldots,|V|] +$$ + +在第二部分的损失函数中,在句子预测任务中,也是一个分类问题的损失函数: + +$$ +L_{2}\left(\theta, \theta_{2}\right)=-\sum_{j=1}^{N} \log p\left(n=n_{i} \mid \theta, \theta_{2}\right), n_{i} \in[ IsNext, NotNext ] +$$ + +## 5.模型优缺点和局限性 + +### 5.1 BERT优点 + +1. Transformer Encoder因为有Self-attention机制,因此BERT自带双向功能 +2. 计算可并行化 +3. 微调成本小 +4. 因为双向功能以及多层Self-attention机制的影响,使得BERT必须使用Cloze版的语言模型Masked-LM来完成token级别的预训练 +5. 为了获取比词更高级别的句子级别的语义表征,BERT加入了Next Sentence Prediction来和Masked-LM一起做联合训练 +6. 为了适配多任务下的迁移学习,BERT设计了更通用的输入层和输出层 + +### 5.2 BERT缺点 + +1. `[MASK]`标记在实际预测中不会出现,训练时用过多`[MASK]`影响模型表现 +2. 每个batch只有15%的token被预测,所以BERT收敛得比left-to-right模型要慢(它们会预测每个token) +3. task1的随机遮挡策略略显粗犷,推荐阅读《Data Nosing As Smoothing In Neural Network Language Models》 +4. BERT对硬件资源的消耗巨大(大模型需要16个tpu,历时四天;更大的模型需要64个tpu,历时四天。 + +### 5.3 BERT局限性 + +从XLNet论文中,提到了BERT的两个缺点,分别如下 + +1. 被**mask掉的单词之间是有关系的**,比如”New York is a city”,”New”和”York”两个词,那么给定”is a city”的条件下”New”和”York”并不独立,因为”New York”是一个实体,看到”New”则后面出现”York”的概率要比看到”Old”后面出现”York”概率要大得多。 + 但是需要注意的是,这个问题并不是什么大问题,甚至可以说对最后的结果并没有多大的影响,因为本身BERT预训练的语料就是海量的(动辄几十个G),所以如果训练数据足够大,其实不靠当前这个例子,靠其它例子,也能弥补被Mask单词直接的相互关系问题,因为总有其它例子能够学会这些单词的相互依赖关系。 +2. BERT的在预训练时会出现特殊的`[MASK]`,但是它在下游的fine-tune中不会出现,这就出现了**预训练阶段和fine-tune阶段不一致的问题**。其实这个问题对最后结果产生多大的影响也是不够明确的,因为后续有许多BERT相关的预训练模型仍然保持了`[MASK]`标记,也取得了很大的结果,而且很多数据集上的结果也比BERT要好。但是确确实实引入`[MASK]`标记,也是为了构造自编码语言模型而采用的一种折中方式。 +3. BERT在分词后做`[MASK]`会产生的一个问题,为了解决OOV的问题,通常会把一个词切分成更细粒度的WordPiece。BERT在Pretraining的时候是随机Mask这些WordPiece的,这就可能出现**只Mask一个词的一部分的情况**,这样它只需要记住一些词(WordPiece的序列)就可以完成这个任务,而不是根据上下文的语义关系来预测出来的。类似的中文的词”模型”也可能被Mask部分(其实用”琵琶”的例子可能更好,因为这两个字只能一起出现而不能单独出现),这也会让预测变得容易。为了解决这个问题,很自然的想法就是词作为一个整体要么都Mask要么都不Mask,这就是所谓的Whole Word Masking。这是一个很简单的想法,对于BERT的代码修改也非常少,只是修改一些Mask的那段代码。 diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/bert\347\273\206\350\212\202/image/image_yNdkRulkSC.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/bert\347\273\206\350\212\202/image/image_yNdkRulkSC.png" new file mode 100644 index 0000000..9952ad4 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/bert\347\273\206\350\212\202/image/image_yNdkRulkSC.png" differ diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/chatglm\347\263\273\345\210\227\346\250\241\345\236\213/chatglm\347\263\273\345\210\227\346\250\241\345\236\213.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/chatglm\347\263\273\345\210\227\346\250\241\345\236\213/chatglm\347\263\273\345\210\227\346\250\241\345\236\213.md" similarity index 56% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/chatglm\347\263\273\345\210\227\346\250\241\345\236\213/chatglm\347\263\273\345\210\227\346\250\241\345\236\213.md" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/chatglm\347\263\273\345\210\227\346\250\241\345\236\213/chatglm\347\263\273\345\210\227\346\250\241\345\236\213.md" index 768d29f..390ad1e 100644 --- "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/chatglm\347\263\273\345\210\227\346\250\241\345\236\213/chatglm\347\263\273\345\210\227\346\250\241\345\236\213.md" +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/chatglm\347\263\273\345\210\227\346\250\241\345\236\213/chatglm\347\263\273\345\210\227\346\250\241\345\236\213.md" @@ -6,9 +6,9 @@ 主流的预训练框架主要有三种: -1. **autoregressive自回归模型(AR模型)**:代表作GPT。本质上是一个left-to-right的语言模型。**通常用于生成式任务**,在长文本生成方面取得了巨大的成功,比如自然语言生成(NLG)领域的任务:摘要、翻译或抽象问答。当扩展到十亿级别参数时,表现出了少样本学习能力。缺点是单向注意力机制,在NLU任务中,无法完全捕捉上下文的依赖关系。 -2. **autoencoding自编码模型(AE模型)**:代表作BERT。是**通过某个降噪目标(比如MLM)训练的双向文本编码器**。编码器会产出适用于NLU任务的上下文表示,但无法直接用于文本生成。 -3. **encoder-decoder(Seq2seq模型)**:代表作T5。采用双向注意力机制,**通常用于条件生成任务**,比如文本摘要、机器翻译等。 +1. **autoregressive自回归模型(AR模型)**:代表作GPT。本质上是一个left-to-right的语言模型。**通常用于生成式任务**,在长文本生成方面取得了巨大的成功,比如自然语言生成(NLG)领域的任务:摘要、翻译或抽象问答。当扩展到十亿级别参数时,表现出了少样本学习能力。缺点是单向注意力机制,在NLU任务中,无法完全捕捉上下文的依赖关系。 +2. **autoencoding自编码模型(AE模型)**:代表作BERT。是**通过某个降噪目标(比如MLM)训练的双向文本编码器**。编码器会产出适用于NLU任务的上下文表示,但无法直接用于文本生成。 +3. **encoder-decoder(Seq2seq模型)**:代表作T5。采用双向注意力机制,**通常用于条件生成任务**,比如文本摘要、机器翻译等。 三种预训练框架各有利弊,没有一种框架在以下三种领域的表现最佳:自然语言理解(NLU)、无条件生成以及条件生成。T5曾经尝试使用MTL的方式统一上述框架,然而自编码和自回归目标天然存在差异,简单的融合自然无法继承各个框架的优点。 @@ -20,10 +20,10 @@ GLM特点 -1. **自编码思想**:在输入文本中,随机删除连续的tokens。 -2. **自回归思想**:顺序重建连续tokens。在使用自回归方式预测缺失tokens时,模型既可以访问corrupted文本,又可以访问之前已经被预测的spans。 -3. **span shuffling + 二维位置编码技术**。 -4. 通过改变缺失spans的数量和长度,自回归空格填充目标可以为条件生成以及无条件生成任务预训练语言模型。 +1. **自编码思想**:在输入文本中,随机删除连续的tokens。 +2. **自回归思想**:顺序重建连续tokens。在使用自回归方式预测缺失tokens时,模型既可以访问corrupted文本,又可以访问之前已经被预测的spans。 +3. **span shuffling + 二维位置编码技术**。 +4. 通过改变缺失spans的数量和长度,自回归空格填充目标可以为条件生成以及无条件生成任务预训练语言模型。 ### (1)自回归空格填充任务 @@ -35,31 +35,31 @@ $$ GLM自回归空格填充任务的技术细节: -1. 输入$x$可以被分成两部分:Part A是被mask的文本 $x_{\text {corrupt }}$,Part B由masked spans组成。假设原始输入文本是$[x1, x2, x3, x4, x5, x6]$,采样的两个文本片段是$[x3]$以及$[x5, x6]$。那么mask后的文本序列是:$x1, x2, [M], x4, [M]$,即Part A;同时我们需要对Part B的片段进行shuffle。每个片段使用`[S]`填充在开头作为输入,使用`[E]`填充在末尾作为输出。 -2. **二维位置编码**:Transformer使用位置编码来标记tokens中的绝对和相对位置。在GLM中,使用二维位置编码,第一个位置id用来标记Part A中的位置,第二个位置id用来表示跨度内部的相对位置。这两个位置id会通过embedding表被投影为两个向量,最终都会被加入到输入token的embedding表达中。 -3. 观察GLM中自定义attention mask的设计,非常巧妙: - 1. Part A中的tokens彼此可见,但是不可见B中的任意tokens。 - 2. Part B tokens可见Part A。 - 3. Part B tokens可见B中过去的tokens,不可见B中未来的tokens。 -4. 采样方式:文本片段的采样遵循泊松分布,重复采样,直到原始tokens中有15%被mask。 -5. 总结:模型可以自动学习双向encoder(Part A)以及单向decoder(Part B)。 +1. 输入$x$可以被分成两部分:Part A是被mask的文本 $x_{\text {corrupt }}$,Part B由masked spans组成。假设原始输入文本是$[x1, x2, x3, x4, x5, x6]$,采样的两个文本片段是$[x3]$以及$[x5, x6]$。那么mask后的文本序列是:$x1, x2, [M], x4, [M]$,即Part A;同时我们需要对Part B的片段进行shuffle。每个片段使用`[S]`填充在开头作为输入,使用`[E]`填充在末尾作为输出。 +2. **二维位置编码**:Transformer使用位置编码来标记tokens中的绝对和相对位置。在GLM中,使用二维位置编码,第一个位置id用来标记Part A中的位置,第二个位置id用来表示跨度内部的相对位置。这两个位置id会通过embedding表被投影为两个向量,最终都会被加入到输入token的embedding表达中。 +3. 观察GLM中自定义attention mask的设计,非常巧妙: + 1. Part A中的tokens彼此可见,但是不可见B中的任意tokens。 + 2. Part B tokens可见Part A。 + 3. Part B tokens可见B中过去的tokens,不可见B中未来的tokens。 +4. 采样方式:文本片段的采样遵循泊松分布,重复采样,直到原始tokens中有15%被mask。 +5. 总结:模型可以自动学习双向encoder(Part A)以及单向decoder(Part B)。 -![](image/image_rZxRps6PF-.png) +![](image/image_7XH6B72KuJ.png) ### (2)多目标预训练 上述方法适合于NLU任务。作者希望可以训练一个既可以解决NLU任务,又具备文本生成能力的模型。因此除了空格填充目标之外,还需要增加一个生成长文本目标的任务。具体包含以下两个目标: -1. **文档级别**。从文档中采样一个文本片段进行mask,且片段长度为文档长度的50%~100%。这个目标用于长文本生成。 -2. **句子级别**。限制被mask的片段必须是完整句子。多个片段需覆盖原始tokens的15%。这个目标是用于预测完整句子或者段落的seq2seq任务。 +1. **文档级别**。从文档中采样一个文本片段进行mask,且片段长度为文档长度的50%~100%。这个目标用于长文本生成。 +2. **句子级别**。限制被mask的片段必须是完整句子。多个片段需覆盖原始tokens的15%。这个目标是用于预测完整句子或者段落的seq2seq任务。 ### (3)模型结构 GLM在原始single Transformer的基础上进行了一些修改: -1. 重组了LN和残差连接的顺序; -2. 使用单个线性层对输出token进行预测; -3. 激活函数从ReLU换成了GeLU。 +1. 重组了LN和残差连接的顺序; +2. 使用单个线性层对输出token进行预测; +3. 激活函数从ReLU换成了GeLU。 但我觉得这部分的修改比较简单常见。核心和亮点还是空格填充任务的设计。 @@ -71,7 +71,7 @@ GLM在原始single Transformer的基础上进行了一些修改: 其实,预训练时,对较长的文本片段进行mask,以确保GLM的文本生成能力。但是在微调的时候,相当于将NLU任务也转换成了生成任务,这样其实是为了适应预训练的目标。但难免有一些牵强。 -![](image/image_Pjabhc46zO.png) +![](image/image_C9tS8f50K8.png) | | | | | | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | @@ -82,17 +82,17 @@ GLM在原始single Transformer的基础上进行了一些修改: ## 2.1 主要创新 -1. **更长的上下文**:**基于 **[**FlashAttention**](https://github.com/HazyResearch/flash-attention "FlashAttention")** 技术**,将基座模型的上下文长度(Context Length)由 ChatGLM-6B 的 **2K 扩展到了 32K**,并在对话阶段使用 8K 的上下文长度训练。对于更长的上下文,发布了 [ChatGLM2-6B-32K](https://huggingface.co/THUDM/chatglm2-6b-32k "ChatGLM2-6B-32K") 模型。[LongBench](https://github.com/THUDM/LongBench "LongBench") 的测评结果表明,在等量级的开源模型中,ChatGLM2-6B-32K 有着较为明显的竞争优势。 -2. **更强大的性能**:基于 ChatGLM 初代模型的开发经验,全面升级了 ChatGLM2-6B 的基座模型。ChatGLM2-6B **使用了 **[**GLM**](https://github.com/THUDM/GLM "GLM")** 的混合目标函数**,经过了 1.4T 中英标识符的预训练与人类偏好对齐训练,[评测结果](https://github.com/THUDM/ChatGLM2-6B#评测结果 "评测结果")显示,相比于初代模型,ChatGLM2-6B 在 MMLU(+23%)、CEval(+33%)、GSM8K(+571%) 、BBH(+60%)等数据集上的性能取得了大幅度的提升,在同尺寸开源模型中具有较强的竞争力。 -3. **更高效的推理**:基于 [Multi-Query Attention](http://arxiv.org/abs/1911.02150 "Multi-Query Attention") 技术,ChatGLM2-6B 有更高效的推理速度和更低的显存占用:在官方的模型实现下,推理速度相比初代提升了 42%,INT4 量化下,6G 显存支持的对话长度由 1K 提升到了 8K。 -4. **更开放的协议**:ChatGLM2-6B 权重对学术研究**完全开放**,在填写[问卷](https://open.bigmodel.cn/mla/form "问卷")进行登记后**亦允许免费商业使用**。 +1. **更长的上下文**:**基于 **[**FlashAttention**](https://github.com/HazyResearch/flash-attention "FlashAttention")** 技术**,将基座模型的上下文长度(Context Length)由 ChatGLM-6B 的 **2K 扩展到了 32K**,并在对话阶段使用 8K 的上下文长度训练。对于更长的上下文,发布了 [ChatGLM2-6B-32K](https://huggingface.co/THUDM/chatglm2-6b-32k "ChatGLM2-6B-32K") 模型。[LongBench](https://github.com/THUDM/LongBench "LongBench") 的测评结果表明,在等量级的开源模型中,ChatGLM2-6B-32K 有着较为明显的竞争优势。 +2. **更强大的性能**:基于 ChatGLM 初代模型的开发经验,全面升级了 ChatGLM2-6B 的基座模型。ChatGLM2-6B **使用了 **[**GLM**](https://github.com/THUDM/GLM "GLM")** 的混合目标函数**,经过了 1.4T 中英标识符的预训练与人类偏好对齐训练,[评测结果](https://github.com/THUDM/ChatGLM2-6B#评测结果 "评测结果")显示,相比于初代模型,ChatGLM2-6B 在 MMLU(+23%)、CEval(+33%)、GSM8K(+571%) 、BBH(+60%)等数据集上的性能取得了大幅度的提升,在同尺寸开源模型中具有较强的竞争力。 +3. **更高效的推理**:基于 [Multi-Query Attention](http://arxiv.org/abs/1911.02150 "Multi-Query Attention") 技术,ChatGLM2-6B 有更高效的推理速度和更低的显存占用:在官方的模型实现下,推理速度相比初代提升了 42%,INT4 量化下,6G 显存支持的对话长度由 1K 提升到了 8K。 +4. **更开放的协议**:ChatGLM2-6B 权重对学术研究**完全开放**,在填写[问卷](https://open.bigmodel.cn/mla/form "问卷")进行登记后**亦允许免费商业使用**。 ## 2.2 与ChatGLM的变化 -1. **使用了RoPE替换二维位置编码**。这也是GLM中提出的亮点设计之一。但是目前大部分主流的LLMs都在使用RoPE,所以大势所趋。当前版本仍然采用了最初的RoPE设计,事实上现在的RoPE经过了xPOS→线性内插→NTK-Aware Scaled RoPE→…若干次进化。 -2. **Multi-Query Attention**:这是一种共享机制的Attention,相比Multi-Head Attention,其Query部分没有区别,Key和Value可以只用一个Head。计算时,对Key和Value进行expand或者repeat操作,使它们填充到与Query一样的维度,后续计算就与Multi-Head Attention没区别。 -3. **Attention Mask**: V1的attention mask分了2部分,Part A和Part B,Part A部分是双向Attention(代码中的[prefix\_attention\_mask](https://huggingface.co/THUDM/chatglm-6b/blob/main/modeling_chatglm.py#L963 "prefix_attention_mask")),Part B部分是Causal Attention(原代码文件中的get\_masks函数)。在V2版本,全部换成了Causal Attention,不再区分是Part A还是Part B,**完全变成了decoder-only的架构**。 -4. **多目标任务**:Chat版本主要还是用的gMask生成式任务,但是在V1版本的代码还能看到mask、gMask等字样,V2已经摒弃了这些特殊token,原因与Attention Mask一致,均因为变成了decoder-only的架构,不再需要区分Part A和Part B。 +1. **使用了RoPE替换二维位置编码**。这也是GLM中提出的亮点设计之一。但是目前大部分主流的LLMs都在使用RoPE,所以大势所趋。当前版本仍然采用了最初的RoPE设计,事实上现在的RoPE经过了xPOS→线性内插→NTK-Aware Scaled RoPE→…若干次进化。 +2. **Multi-Query Attention**:这是一种共享机制的Attention,相比Multi-Head Attention,其Query部分没有区别,Key和Value可以只用一个Head。计算时,对Key和Value进行expand或者repeat操作,使它们填充到与Query一样的维度,后续计算就与Multi-Head Attention没区别。 +3. **Attention Mask**: V1的attention mask分了2部分,Part A和Part B,Part A部分是双向Attention(代码中的[prefix\_attention\_mask](https://huggingface.co/THUDM/chatglm-6b/blob/main/modeling_chatglm.py#L963 "prefix_attention_mask")),Part B部分是Causal Attention(原代码文件中的get\_masks函数)。在V2版本,全部换成了Causal Attention,不再区分是Part A还是Part B,**完全变成了decoder-only的架构**。 +4. **多目标任务**:Chat版本主要还是用的gMask生成式任务,但是在V1版本的代码还能看到mask、gMask等字样,V2已经摒弃了这些特殊token,原因与Attention Mask一致,均因为变成了decoder-only的架构,不再需要区分Part A和Part B。 # 3.ChatGLM-3 @@ -100,9 +100,9 @@ GLM在原始single Transformer的基础上进行了一些修改: 相对于ChatGLM,ChatGLM2、ChatGLM3模型上的变化: -1. 词表的大小从ChatGLM的150528缩小为65024 (一个直观的体验是ChatGLM2、3加载比ChatGLM快不少) -2. **位置编码从每个GLMBlock一份提升为全局一份** -3. **SelfAttention之后的前馈网络有不同**。ChatGLM用GELU(Gaussian Error Linear Unit)做激活;ChatGLM用Swish-1做激活。而且ChatGLM2、3应该是修正了之前的一个bug,因为GLU(Gated Linear Unit)本质上一半的入参是用来做门控制的,不需要输出到下层,所以ChatGLM2、3看起来前后维度不一致(27392->13696)反而是正确的。 +1. 词表的大小从ChatGLM的150528缩小为65024 (一个直观的体验是ChatGLM2、3加载比ChatGLM快不少) +2. **位置编码从每个GLMBlock一份提升为全局一份** +3. **SelfAttention之后的前馈网络有不同**。ChatGLM用GELU(Gaussian Error Linear Unit)做激活;ChatGLM用Swish-1做激活。而且ChatGLM2、3应该是修正了之前的一个bug,因为GLU(Gated Linear Unit)本质上一半的入参是用来做门控制的,不需要输出到下层,所以ChatGLM2、3看起来前后维度不一致(27392->13696)反而是正确的。 # 4.模型架构比较 diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/chatglm\347\263\273\345\210\227\346\250\241\345\236\213/image/image_rZxRps6PF-.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/chatglm\347\263\273\345\210\227\346\250\241\345\236\213/image/image_7XH6B72KuJ.png" similarity index 100% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/chatglm\347\263\273\345\210\227\346\250\241\345\236\213/image/image_rZxRps6PF-.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/chatglm\347\263\273\345\210\227\346\250\241\345\236\213/image/image_7XH6B72KuJ.png" diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/chatglm\347\263\273\345\210\227\346\250\241\345\236\213/image/image_Pjabhc46zO.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/chatglm\347\263\273\345\210\227\346\250\241\345\236\213/image/image_C9tS8f50K8.png" similarity index 100% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/chatglm\347\263\273\345\210\227\346\250\241\345\236\213/image/image_Pjabhc46zO.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/chatglm\347\263\273\345\210\227\346\250\241\345\236\213/image/image_C9tS8f50K8.png" diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 2\344\273\243\347\240\201\350\257\246\350\247\243/image/image_A9pk34559l.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 2\344\273\243\347\240\201\350\257\246\350\247\243/image/image_A9pk34559l.png" new file mode 100644 index 0000000..6f467cc Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 2\344\273\243\347\240\201\350\257\246\350\247\243/image/image_A9pk34559l.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 2\344\273\243\347\240\201\350\257\246\350\247\243/image/image_T2T_LiM5FT.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 2\344\273\243\347\240\201\350\257\246\350\247\243/image/image_T2T_LiM5FT.png" new file mode 100644 index 0000000..ec5e1bf Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 2\344\273\243\347\240\201\350\257\246\350\247\243/image/image_T2T_LiM5FT.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 2\344\273\243\347\240\201\350\257\246\350\247\243/image/image_XJgG9to7qe.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 2\344\273\243\347\240\201\350\257\246\350\247\243/image/image_XJgG9to7qe.png" new file mode 100644 index 0000000..fdd9440 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 2\344\273\243\347\240\201\350\257\246\350\247\243/image/image_XJgG9to7qe.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 2\344\273\243\347\240\201\350\257\246\350\247\243/image/image_uEydesOS3K.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 2\344\273\243\347\240\201\350\257\246\350\247\243/image/image_uEydesOS3K.png" new file mode 100644 index 0000000..6c93f48 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 2\344\273\243\347\240\201\350\257\246\350\247\243/image/image_uEydesOS3K.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 2\344\273\243\347\240\201\350\257\246\350\247\243/llama 2\344\273\243\347\240\201\350\257\246\350\247\243.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 2\344\273\243\347\240\201\350\257\246\350\247\243/llama 2\344\273\243\347\240\201\350\257\246\350\247\243.md" new file mode 100644 index 0000000..e331e55 --- /dev/null +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 2\344\273\243\347\240\201\350\257\246\350\247\243/llama 2\344\273\243\347\240\201\350\257\246\350\247\243.md" @@ -0,0 +1,526 @@ +# llama 2代码详解 + +> 文章摘自:[Llama 2详解 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/649756898 "Llama 2详解 - 知乎 (zhihu.com)") + +## **0.前言** + +LLM(Large Language Model)应该是今年深度学习领域一项具有革命性的技术突破,因为ChatGPT3.5/4没有开源,所以本文选择Meta AI半开源的LLM 模型 [Llama 2](https://ai.meta.com/llama/ "Llama 2"),该模型也是Hugging Face [open\_llm\_leaderboard](https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard "open_llm_leaderboard")的榜首模型 + +> 所谓半开源即只有inference过程没有train过程 + +老样子: + +- paper : [https://arxiv.org/abs/2307.09288](https://link.zhihu.com/?target=https%3A//arxiv.org/abs/2307.09288 "https://arxiv.org/abs/2307.09288") +- code :[https://github.com/facebookresearch/llama](https://link.zhihu.com/?target=https%3A//github.com/facebookresearch/llama "https://github.com/facebookresearch/llama") +- 笔者逐行注释的code : [https://github.com/sunkx109/llama](https://link.zhihu.com/?target=https%3A//github.com/sunkx109/llama "https://github.com/sunkx109/llama") + +## **1.处理流程** + +首先在了解Llama 2模型结构细节之前,先来看一看大语言模型通常的处理流程: + +### 1.1 常见大模型处理流程 + +#### (1)**输入数据** + +LLM的输入数据是一段文本,可以是一个句子或一段话。文本通常被表示成单词或字符的序列。 + +```text +[君不见黄河之水天上来,奔流到海不复回。君不见高堂明镜悲白发,朝如青丝暮成雪。...五花马、千金裘,呼儿将出换美酒,与尔同销万古愁] +``` + +#### (2)**Tokenization** + +之后需要将文本进行Tokenization,**将其切分成单词或字符,形成Token序列**。之后再将文本映射成模型可理解的输入形式,将文本序列转换为整数索引序列(这个索引就是单词或字符在语料库中的index),这个过程通常由一些开源的文本Tokenzier工具,如sentencepiece等来处理 + +```text +序列化-> +['BOS','君','不','见','黄','河','之','水','天','上','来',',' ,'奔','流','到'...'与','尔','同','销','万','古','愁','EOS'] + +假设语料库索引化-> +['BOS','10','3','67','89','21','45','55','61','4','324','565' ,'789','6567','786'...'7869','9','3452','563','56','66','77','EOS'] +``` + +#### (3)**Embedding** + +文本信息经过Tokenization之后变成了token序列,而Embedding则继续**将每个Token映射为一个实数向量**,为Embeding Vector + +```text +'BOS'-> [p_{00},p_{01},p_{02},...,p_{0d-1}] +'10' -> [p_{10},p_{11},p_{12},...,p_{1d-1}] +'3' -> [p_{20},p_{21},p_{22},...,p_{2d-1}] +... +'EOS'-> [p_{n0},p_{n1},p_{n2},...,p_{nd-1}] +``` + +#### (4)**位置编码** + +对于Token序列中的每个位置,添加位置编码(Positional Encoding)向量,以提供关于Token在序列中位置的信息。位置编码是为了**区分不同位置的Token,并为模型提供上下文关系的信息**。 + +```text +[p_{00},p_{01},p_{02},...,p_{0d-1}] [pe_{00},pe_{01},pe_{02},...,pe_{0d-1}] +[p_{10},p_{11},p_{12},...,p_{1d-1}] [pe_{10},pe_{11},pe_{12},...,pe_{1d-1}] +[p_{20},p_{21},p_{22},...,p_{2d-1}] + [pe_{20},pe_{21},pe_{22},...,pe_{2d-1}] +... ... +[p_{n0},p_{n1},p_{n2},...,p_{nd-1}] [pe_{n0},pe_{n1},pe_{n2} ,...,pe_{nd-1}] +``` + +#### (5)**Transformer** + +在生成任务中,模型只需要用到Transformer 的decoder阶段,即Decoder-Only,比如GPT、LLaMA 都是。 + +#### (6)**自回归生成** + +在生成任务中,使用自回归(Autoregressive)方式,即**逐个生成输出序列中的每个Token**。在解码过程中,每次生成一个Token时,使用前面已生成的内容作为上下文,来帮助预测下一个Token。 + +```python +model = LLaMA2() +def generate(inputs, n_tokens_to_generate): + for _ in range(n_tokens_to_generate): # auto-regressive decode loop + output = model(inputs) # model forward pass + next = np.argmax(output[-1]) # greedy sampling + inputs.append(next) # append prediction to input + return inputs[len(inputs) - n_tokens_to_generate :] # only return generated tokens + +input = [p0, p1,p2] #对应['BOS','君','不'] +output_ids = generate(input, 3) # 假设生成 ['p3','p4','p5'] +output_ids = decode(output_ids) # 通过Tokenization解码 +output_tokens = [vocab[i] for i in output_ids] # "见" "黄" "河" +``` + +#### (7)**输出处理** + +生成的Token序列通过一个输出层,通常是线性变换加上Softmax函数,将每个位置的概率分布转换为对应Token的概率。根据概率,选择概率最高的Token或者作为模型的预测结果。或者其他的的方法生成next token ,比如: + +```python +def sample_top_p(probs, p): + #从给定的概率分布中采样一个token,采样的方式是先对概率进行排序,然后计算累积概率, + #然后选择累积概率小于p的部分,最后在这部分中随机选择一个token。 + probs_sort, probs_idx = torch.sort(probs, dim=-1, descending=True) #给定的概率降序排序 + probs_sum = torch.cumsum(probs_sort, dim=-1) #从第一个元素开始,依次将序列中的每个元素与前面所有元素的和相加得到的 + mask = probs_sum - probs_sort > p + probs_sort[mask] = 0.0 #将累计和减去当前值>p的地方全部置0,留下来的就是概率较大的 + probs_sort.div_(probs_sort.sum(dim=-1, keepdim=True)) #归一化下 + next_token = torch.multinomial(probs_sort, num_samples=1) # 从归一化之后的样本抽取一个样本 + next_token = torch.gather(probs_idx, -1, next_token) #从原始probs_idx找到next_token所对应的index + return next_token +``` + +### **1. 2 Code** + +本段代码在`llama/generation.py`中的generate函数,为了便于梳理逻辑笔者这里做了一些裁剪 + +```python +@torch.inference_mode() +def generate(prompt_tokens: List[List[int]], #提示的tokens + max_gen_len: int, #最大生成长度 + temperature: float = 0.6, + top_p: float = 0.9, + logprobs: bool = False, + echo: bool = False, +) -> Tuple[List[List[int]], Optional[List[List[float]]]]: + ... + min_prompt_len = min(len(t) for t in prompt_tokens) # 提示句子中最短的提示长度 + max_prompt_len = max(len(t) for t in prompt_tokens) # 提示句子中最长的提示长度 + ... + total_len = min(params.max_seq_len, max_gen_len + max_prompt_len) #最终要生成字总长度 + pad_id = self.tokenizer.pad_id #填充字,在tokenizer中定义的填充字 + # 生成一个shape 为(提示token的组数,total_len) 初始字符为pad_id的tokens + tokens = torch.full((bsz, total_len), pad_id, dtype=torch.long, device="cuda") + ...# 接着将prompt_tokens填充至tokens + prev_pos = 0 #初始位置为0 + eos_reached = torch.tensor([False] * bsz, device="cuda") # 用于判断prompt中的每个句子是否已经处理完成 + input_text_mask = tokens != pad_id #mask 标记那些不是填充字的地方 + for cur_pos in range(min_prompt_len, total_len): + #初始时加载prompt部分进行预测第一个生成的token + logits = self.model.forward(tokens[:, prev_pos:cur_pos], prev_pos) # 以每个句子中的[prev_pos:cur_pos]部分作为输入去推理 + if logprobs: + # 如果开启了计算概率,就会把当前输出的序列logits,与原始提示中的序列右移一位之后 + token_logprobs[:, prev_pos + 1 : cur_pos + 1] = -F.cross_entropy( + input=logits.transpose(1, 2), + target=tokens[:, prev_pos + 1 : cur_pos + 1], #shape=(bst,cur_pos-prev_pos) + reduction="none", + ignore_index=pad_id, #这里需要注意一下,ignore_index参数的作用是忽略target中为pad_id所对应的logits分量 + #也就说当target右移到了pad_id,那么他与logits计算的loss不对整体loss产生影响,也就是你预测的是啥就是啥 + #target也不知道正确答案了 + ) + if temperature > 0: + probs = torch.softmax(logits[:, -1] / temperature, dim=-1) #带温度系数的softmax + next_token = sample_top_p(probs, top_p) #按sample_top_p的方式取next_token + else: + next_token = torch.argmax(logits[:, -1], dim=-1) #之间取概率最大的next_token + # only replace token if prompt has already been generated + ...#再将生成的next_token填入cur_pos位置 + tokens[:, cur_pos] = next_token + prev_pos = cur_pos + ... #更改eos_reached的值,但所有句子全部生成完毕时退出 + +#最后按照生成的tokens的顺序返回即可 +``` + +## **2.模型结构** + +可以说目前主流的LLM处理模型都是基于Transformer而进行构建的,Llama 2也不例外,而LLM这种生成式的任务是根据给定输入文本序列的上下文信息预测下一个单词或token,所以LLM模型通常只需要使用到Transformer Decoder部分,而所谓Decoder相对于Encoder就是在计算`Q*K`时引入了Mask以确保当前位置只能关注前面已经生成的内容。 + +Llama 2的模型结构与标准的Transformer Decoder结构基本一致,主要由32个 Transformer Block 组成,不同之处主要包括以下几点: + +1. 前置的**RMSNorm**层 +2. Q在与K相乘之前,先使用**RoPE**进行位置编码 +3. **K V Cache**,并采用**Group Query Attention** +4. FeedForward层 + +那么下文将结合具体的代码来展开聊一聊这些差异 + +### **2.1 RMSNorm** + +Transformer中的Normalization层一般都是采用LayerNorm来对Tensor进行归一化,LayerNorm的公式如下: + +$$ +\begin{aligned} \text { LayerNorm }: y & =\frac{x-E[x]}{\sqrt{\operatorname{Var}[x]+\epsilon}} * \gamma+\beta \\ E[x] & =\frac{1}{N} \sum_{i=1}^{N} x_{i} \\ \operatorname{Var}[x] & =\frac{1}{N} \sum_{i=1}^{N}\left(x_{i}-E[x]\right)^{2}\end{aligned} +$$ + +而[RMSNorm](https://arxiv.org/pdf/1910.07467.pdf "RMSNorm")就是LayerNorm的变体,\*\*RMSNorm省去了求均值的过程,也没有了偏置 **$\beta$** \*\*,即 + +$$ +\begin{aligned} \text { RMSNorm : } y & =\frac{x}{\sqrt{\operatorname{Mean}\left(x^{2}\right)+\epsilon}} * \gamma \\ \operatorname{Mean}\left(x^{2}\right) & =\frac{1}{N} \sum_{i=1}^{N} x_{i}^{2}\end{aligned} +$$ + +> 其中 $\gamma$ 和 $\beta$ 为可学习的参数 + +```python +# RMSNorm +class RMSNorm(torch.nn.Module): + def __init__(self, dim: int, eps: float = 1e-6): + super().__init__() + self.eps = eps # ε + self.weight = nn.Parameter(torch.ones(dim)) #可学习参数γ + + def _norm(self, x): + # RMSNorm + return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps) + + def forward(self, x): + output = self._norm(x.float()).type_as(x) + return output * self.weight +``` + +### **2.2.RoPE** + +Llama 2 在对序列进行位置编码时,也与标准Transformer不一样,**Llama 2的位置编码在每个Attention层中分别对Q K 进行**[**RoPE位置编码**](https://arxiv.org/pdf/2104.09864.pdf "RoPE位置编码")**,而不是在Transformer Block之前进行一次位置编码**,也就是说每次计算Attention时都分别要对Q K做位置编码(llama 2 官方代码中是这么干的)。 + +一次输入数据经过tokenization之后,会得到一组单词索引序列 $\{w_0,w_1,w_2,...,w_n\} $,之后经过embedding处理后也就变成了 $\{ x_0,x_1,x_2,...,x_n\}$ ,embedding后的序列通过Linear层将输入数据 $x_i $转换为对应的 $q_i,k_i,v_i$ ,之后 便会对 $q_i,k_i$ 两者做RoPE位置编码,之后便计算Attention + +> 其中 $x_i$ 为第 i 个单词索引序列所对应的 d 维词嵌入向量 $\{x_{i_0},x_{i_1},x_{i_2},...,x_{i_{d-1}} \}$ + +#### **(1)绝对位置编码** + +在标准的Transformer中通常是在整个网络进入Transformer Block之前做一个位置编码,如下图所示 + +![](image/image_A9pk34559l.png) + +比较经典的位置编码用公式表达就是,其中 $p_{i,2t}$ 表示第`i`嵌入向量 xix\_i 的第`2t`个位置的位置编码 + +$$ +\begin{aligned} f_{\{q, k, v\}}\left(x_{i}, i\right) & =W_{\{q, k, v\}}\left(x_{i}+p_{i}\right) \\ p_{i, 2 t} & =\sin \left(\frac{i}{10000^{\frac{2 t}{d}}}\right) \\ p_{i, 2 t+1} & =\cos \left(\frac{i}{10000^{\frac{2 t}{d}}}\right)\end{aligned} +$$ + +#### **(2)旋转位置编码** + +首先,在介绍RoPE时,先抛出一个问题:RoPE解决了一个什么问题? + +在位置编码上,使用旋转位置嵌入(Rotary Positional Embeddings,RoPE)代替原有的绝 对位置编码。RoPE 借助了**复数的思想**,出发点是**通过绝对位置编码的方式实现相对位置编码**。其目标是通过下述运算来给 `q`,`k` 添加绝对位置信息: + +$$ +\tilde{\boldsymbol{q}}_{m}=f(\boldsymbol{q}, m), \tilde{\boldsymbol{k}}_{n}=f(\boldsymbol{k}, n) +$$ + +经过上述操作后,$\tilde{\boldsymbol{q}}_{m}$和$\tilde{\boldsymbol{k}}_{n}$就带有位置m和n的绝对位置信息。 + +最终可以得到二维情况下用复数表示的 RoPE: + +$$ +f(\boldsymbol{q}, m)=R_{f}(\boldsymbol{q}, m) e^{i \Theta_{f}(\boldsymbol{q}, m)}=\|\boldsymbol{q}\| e^{i(\Theta(\boldsymbol{q})+m \theta)}=\boldsymbol{q} e^{i m \theta} +$$ + +根据复数乘法的几何意义,上述变换实际上是对应向量旋转,所以位置向量称为“旋转式位置编 码”。还可以使用矩阵形式表示 + +$$ +f(\boldsymbol{q}, m)=\left(\begin{array}{cc}\cos m \theta & -\sin \cos m \theta \\ \sin m \theta & \cos m \theta\end{array}\right)\left(\begin{array}{l}\boldsymbol{q}_{0} \\ \boldsymbol{q}_{1}\end{array}\right) +$$ + +根据内积满足线性叠加的性质,任意偶数维的 RoPE,都可以表示为二维情形的拼接,即: + +$$ +f(\boldsymbol{q}, m)=\underbrace{\left(\begin{array}{ccccccc}\cos m \theta_{0} & -\sin m \theta_{0} & 0 & 0 & \cdots & 0 & 0 \\ \sin m \theta_{0} & \cos m \theta_{0} & 0 & 0 & \cdots & 0 & 0 \\ 0 & 0 & \cos m \theta_{1} & -\sin m \theta_{1} & \cdots & 0 & 0 \\ 0 & 0 & \sin m \theta_{1} & \cos m \theta_{1} & \cdots & 0 & 0 \\ \cdots & \cdots & \cdots & \cdots & \ddots & \cdots & \cdots \\ 0 & 0 & 0 & 0 & \cdots & \cos m \theta_{d / 2-1} & -\sin m \theta_{d / 2-1} \\ 0 & 0 & 0 & 0 & \cdots & \sin m \theta_{d / 2-1} & \cos m \theta_{d / 2-1}\end{array}\right)}_{\boldsymbol{R}_{d}}\left(\begin{array}{c}\boldsymbol{q}_{0} \\ \boldsymbol{q}_{1} \\ \boldsymbol{q}_{2} \\ \boldsymbol{q}_{3} \\ \cdots \\ \boldsymbol{q}_{d-2} \\ \boldsymbol{q}_{d-1}\end{array}\right) +$$ + +![](image/image_QzGxZVzHBf.png) + +#### **(3) RoPE Code** + +```python +def precompute_freqs_cis(dim: int, end: int, theta: float = 10000.0): + # 计算词向量元素两两分组以后,每组元素对应的旋转角度 + # arange生成[0,2,4...126] + freqs = 1.0 / (theta ** (torch.arange(0, dim, 2)[: (dim // 2)].float() / dim)) + # t = [0,....end] + t = torch.arange(end, device=freqs.device) # type: ignore + # t为列向量 freqs为行向量做外积 + # freqs.shape = (t.len(),freqs.len()) #shape (end,dim//2) + freqs = torch.outer(t, freqs).float() # type: ignore + # 生成复数 + # torch.polar(abs,angle) -> abs*cos(angle) + abs*sin(angle)*j + freqs_cis = torch.polar(torch.ones_like(freqs), freqs) # complex64 + # freqs_cis.shape = (end,dim//2) + return freqs_cis + +def reshape_for_broadcast(freqs_cis: torch.Tensor, x: torch.Tensor): + # ndim为x的维度数 ,此时应该为4 + ndim = x.ndim + assert 0 <= 1 < ndim + assert freqs_cis.shape == (x.shape[1], x.shape[-1]) + shape = [d if i == 1 or i == ndim - 1 else 1 for i, d in enumerate(x.shape)] + # (1,x.shape[1],1,x.shape[-1]) + return freqs_cis.view(*shape) + +def apply_rotary_emb( + xq: torch.Tensor, + xk: torch.Tensor, + freqs_cis: torch.Tensor, +) -> Tuple[torch.Tensor, torch.Tensor]: + # xq.shape = [bsz, seqlen, self.n_local_heads, self.head_dim] + # xq_.shape = [bsz, seqlen, self.n_local_heads, self.head_dim//2 , 2] + # torch.view_as_complex用于将二维向量转换为复数域 torch.view_as_complex即([x,y]) -> (x+yj) + # 所以经过view_as_complex变换后xq_.shape = [bsz, seqlen, self.n_local_heads, self.head_dim//2] + xq_ = torch.view_as_complex(xq.float().reshape(*xq.shape[:-1], -1, 2)) + xk_ = torch.view_as_complex(xk.float().reshape(*xk.shape[:-1], -1, 2)) + + + freqs_cis = reshape_for_broadcast(freqs_cis, xq_) # freqs_cis.shape = (1,x.shape[1],1,x.shape[-1]) + + # xq_ 与freqs_cis广播哈达玛积 + # [bsz, seqlen, self.n_local_heads, self.head_dim//2] * [1,seqlen,1,self.head_dim//2] + # torch.view_as_real用于将复数再转换回实数向量, 再经过flatten展平第4个维度 + # [bsz, seqlen, self.n_local_heads, self.head_dim//2] ->[bsz, seqlen, self.n_local_heads, self.head_dim//2,2 ] ->[bsz, seqlen, self.n_local_heads, self.head_dim] + xq_out = torch.view_as_real(xq_ * freqs_cis).flatten(3) + xk_out = torch.view_as_real(xk_ * freqs_cis).flatten(3) + return xq_out.type_as(xq), xk_out.type_as(xk) +# 精简版Attention +class Attention(nn.Module): + def __init__(self, args: ModelArgs): + super().__init__() + self.wq = Linear(...) + self.wk = Linear(...) + self.wv = Linear(...) + + self.freqs_cis = precompute_freqs_cis(dim, max_seq_len * 2) + + def forward(self, x: torch.Tensor): + bsz, seqlen, _ = x.shape + xq, xk, xv = self.wq(x), self.wk(x), self.wv(x) + xq = xq.view(bsz, seqlen, self.n_local_heads, self.head_dim) + xk = xk.view(bsz, seqlen, self.n_local_kv_heads, self.head_dim) + xv = xv.view(bsz, seqlen, self.n_local_kv_heads, self.head_dim) + # attention 操作之前,应用旋转位置编码 + xq, xk = apply_rotary_emb(xq, xk, freqs_cis=freqs_cis) + #... + # 进行后续Attention计算 + scores = torch.matmul(xq, xk.transpose(1, 2)) / math.sqrt(dim) + scores = F.softmax(scores.float(), dim=-1) + output = torch.matmul(scores, xv) # (batch_size, seq_len, dim) + # ...... +``` + +### **2.3.KV Cache & GQA** + +#### **(1)KV Cache** + +大模型推理性能优化的一个常用技术是KV Cache,那么什么是K V Cache呢?首先这里的K V 值得分别是Attention计算时的KV,而非哈希存储引擎中的Key和Value,这里的Cache也不是那个会发生Cache Missing的Cache , 这里的K V Cache就是将Attention 中的KV缓存下来,通过空间换时间的方式来加速计算Attention。 + +从第一节处理流程中可以知道,在**LLama 2模型的推理阶段是采用自回归的方式来进行推理,即每一个Token的生成都是由之前所有生成的所有token作为输入而得到的**。 + +![](image/image_uEydesOS3K.png) + +举个例子,假设有这样一个生成任务 + +```text +In [1]: {prompt:"将进酒:"} +Out [1]: 将进酒:人 + +In [2]: 将进酒:人 +Out [2]: 将进酒:人生 + +In [3]: 将进酒:人生 +Out [3]: 将进酒:人生得 + +In [4]: 将进酒:人生得 +Out [4]: 将进酒:人生得意 + +In [5]: 将进酒:人生得意 +Out [5]: 将进酒:人生得意需 + + +In [6]: 将进酒:人生得意需 +Out [6]: 将进酒:人生得意需尽 + +In [7]: 将进酒:人生得意需尽 +Out [7]: 将进酒:人生得意需尽欢 +``` + +而第四次的处理过程是用"将进酒:人生得" 来预测下一个"意"字,所以需要把 **"将进酒:人生得"** 进行token化后再进行Attention计算,即$Softmax(Q*K^T)*V$ ,如下图所示 + +![](image/image_T2T_LiM5FT.png) + +不难发现在第三次处理的时候,就已经把 **"将进酒:人生"** 所对应的Q,K,V进行过相关的运算,所以没必要在对他们进行Attention计算,这样就能节省大部分算力,由此K V Cache便是来解决这个问题的:**通过将每次计算的K和V缓存下来,之后新的序列进来时只需要从KV Cache中读取之前的KV值即可,就不需要再去重复计算之前的KV了**。此外,对于Q也不用将序列对应的所有 $Q_i $都计算出来,只需要计算最新的 $Q_{newtoken}$ , (即此时句子长度为1), K V同理,所以用简易代码描述一下这个过程就是 + +```python +def mha(x, c_attn, c_proj, n_head, kvcache=None): # [n_seq, n_embd] -> [n_seq, n_embd] + # qkv projection + # when we pass kvcache, n_seq = 1. so we will compute new_q, new_k and new_v + x = linear(x, **c_attn) # [n_seq, n_embd] -> [n_seq, 3*n_embd] + # split into qkv + qkv = np.split(x, 3, axis=-1) # [n_seq, 3*n_embd] -> [3, n_seq, n_embd] + if kvcache: + # qkv + new_q, new_k, new_v = qkv # new_q, new_k, new_v = [1, n_embd] + old_k, old_v = kvcache + k = np.vstack([old_k, new_k]) # k = [n_seq, n_embd], where n_seq = prev_n_seq + 1 + v = np.vstack([old_v, new_v]) # v = [n_seq, n_embd], where n_seq = prev_n_seq + 1 + qkv = [new_q, k, v] +``` + +> 至于为什么不用缓存Q? 我理解这是一种单向注意机机制,他只管每次进来的token与past tokens的注意力,而past tokens不会管后面token的注意力,所以就不需要 $Q_{past \_tokens}$ ,也就不需要缓存Q,**这里如果读者有更好的理解欢迎指出** + +另外,利用KV Cache技术能节省多少计算量呢?大家有兴趣可以看看[分析transformer模型的参数量、计算量、中间激活、KV cache](https://zhuanlan.zhihu.com/p/649756898/ "分析transformer模型的参数量、计算量、中间激活、KV cache") + +#### **(2)MQA & GQA** + +但转念一下,可是K,V 真的能缓存的了吗?我们来算笔账,以Llama 7B模型为例,`hidden_size`为4096,也就说每个K,V有4096 个数据,假设是半精度浮点数据float16,一个Transformer Block中就有 `4096* 2 *2 = 16KB`的单序列 K,V缓存空间,而Llama 2一共32个Transformer Block,所以单序列整个模型需要`16 * 32 = 512KB`的缓存空间,那多序列呢?如果此时句子长度为1024 ,那是不是就得512MB 的缓存空间了。而现在英伟达最好的卡 H100 的 SRAM 缓存大概是 50MB,而 A100 则是 40MB. 而 7B 模型都这样,175B 模型就更不用说了。 + +既然SRAM 放不下,放到DRAM(GPU显存)行不行呢?答案是可以,但要牺牲性能。学过CUDA编程,知道全局内存(GPU)的读写速度要要远低于共享内存和寄存器,由此便会导致一个问题: **Memory Wall(内存墙)**。所谓内存墙简单点说就是你处理器ALU太快,但是你内存读写速度太慢跟不上,这就会导致ALU算晚之后在那等着你数据搬运过来,进而影响性能。 + +那么该如何解决呢?答案无非是从硬件层面和软件层面来说:从硬件层面,可以使用HBM(高速带宽内存)提高读取速度,或者抛弃冯诺依曼架构,改变计算单元从内存读数据的方式,不再以计算单元为中心,而以存储为中心,做成计算和存储一体的“**存内计算**”,比如"**忆阻器**"。而从软件层面就是优化算法,由此便引入Llama 2所使用的[GQA (Group Query Attention)](https://arxiv.org/pdf/2305.13245.pdf "GQA (Group Query Attention)") + +为了简单明了说明MQA GQA这里用GQA原论文的一个图来表示 + +![](image/image_XJgG9to7qe.png) + +就如图例所言,多头注意力机制(MHA)就是多个头各自拥有自己的Q,K,V来算各自的Self-Attention,而MQA(Multi Query Attention)就是Q依然保持多头,但是K,V只有一个,所有多头的Q共享一个K,V ,这样做虽然能最大程度减少KV Cache所需的缓存空间,但是可想而知参数的减少意味着精度的下降,所以为了在精度和计算之间做一个trade-off,GQA (Group Query Attention)孕育而生,即Q依然是多头,但是分组共享K,V,即减少了K,V缓存所需的缓存空间,也暴露了大部分参数不至于精度损失严重 + +#### **(3) Code** + +这一部分最后结合Llama 2的代码来看看他们的具体实现(为了篇幅做了一些简化) + +```python +def repeat_kv(x: torch.Tensor, n_rep: int) -> torch.Tensor: + """torch.repeat_interleave(x, dim=2, repeats=n_rep)""" + bs, slen, n_kv_heads, head_dim = x.shape + # 根据n_rep,拓展KV + if n_rep == 1: + return x + return (x[:, :, :, None, :].expand(bs, slen, n_kv_heads, n_rep, head_dim).reshape(bs, slen, n_kv_heads * n_rep, head_dim)) +class Attention(nn.Module): + def __init__(self, args: ModelArgs): + super().__init__() + ... + self.n_local_heads = args.n_heads // model_parallel_size #Q的头数 + self.n_local_kv_heads = self.n_kv_heads // model_parallel_size #KV的头数 + self.n_rep = self.n_local_heads // self.n_local_kv_heads + ... + self.wq = ColumnParallelLinear(args.dim,args.n_heads * self.head_dim, # Q的头数* head_dim + ...) + self.wk = ColumnParallelLinear(args.dim,self.n_kv_heads * self.head_dim, # K的头数* head_dim + ...) + self.wv = ColumnParallelLinear(args.dim,self.n_kv_heads * self.head_dim,# V的头数* head_dim + ...) + self.wo = RowParallelLinear(args.n_heads * self.head_dim,args.dim,... ) + + self.cache_k = torch.zeros((args.max_batch_size,args.max_seq_len,self.n_local_kv_heads, #KV的头数 + self.head_dim,)).cuda() + self.cache_v = torch.zeros((args.max_batch_size,args.max_seq_len,self.n_local_kv_heads,#KV的头数 + self.head_dim,)).cuda() + def forward( + self, + x: torch.Tensor, + start_pos: int, + freqs_cis: torch.Tensor, + mask: Optional[torch.Tensor], + ): + bsz, seqlen, _ = x.shape + xq, xk, xv = self.wq(x), self.wk(x), self.wv(x) + + xq = xq.view(bsz, seqlen, self.n_local_heads, self.head_dim) + xk = xk.view(bsz, seqlen, self.n_local_kv_heads, self.head_dim) + xv = xv.view(bsz, seqlen, self.n_local_kv_heads, self.head_dim) + + xq, xk = apply_rotary_emb(xq, xk, freqs_cis=freqs_cis) #嵌入RoPE位置编码 + ... + # 按此时序列的句子长度把kv添加到cache中 + # 初始在prompt阶段seqlen>=1, 后续生成过程中seqlen==1 + self.cache_k[:bsz, start_pos : start_pos + seqlen] = xk + self.cache_v[:bsz, start_pos : start_pos + seqlen] = xv + # 读取新进来的token所计算得到的k和v + keys = self.cache_k[:bsz, : start_pos + seqlen] + values = self.cache_v[:bsz, : start_pos + seqlen] + + # repeat k/v heads if n_kv_heads < n_heads + keys = repeat_kv(keys, self.n_rep) # (bs, seqlen, n_local_heads, head_dim) + values = repeat_kv(values, self.n_rep) # (bs, seqlen, n_local_heads, head_dim) + + xq = xq.transpose(1, 2) # (bs, n_local_heads, seqlen, head_dim) + keys = keys.transpose(1, 2) + values = values.transpose(1, 2) + #计算q*k + scores = torch.matmul(xq, keys.transpose(2, 3)) / math.sqrt(self.head_dim) + if mask is not None: + #加入mask,使得前面的token在于后面的token计算attention时得分为0,mask掉 + scores = scores + mask # (bs, n_local_heads, seqlen, cache_len + seqlen) + scores = F.softmax(scores.float(), dim=-1).type_as(xq) + output = torch.matmul(scores, values) # (bs, n_local_heads, seqlen, head_dim) + output = output.transpose(1, 2).contiguous().view(bsz, seqlen, -1) + return self.wo(output) +``` + +### **2.4 FeedForward** + +与标准的Transformer一样,经过Attention层之后就进行FeedForward层的处理,但LLama2的FeedForward与标准的Transformer FeedForward有一些细微的差异,这块没啥好讲的,看代码就行,需要注意的地方就是SiLU激活函数 + +$$ +\operatorname{SiLU}(x)=x * \operatorname{Sigmoid}(x)=\frac{x}{1+e^{-x}} +$$ + +```python +class FeedForward(nn.Module): + def __init__( + self, + dim: int, + hidden_dim: int, + multiple_of: int, + ffn_dim_multiplier: Optional[float], + ): + super().__init__() + hidden_dim = int(2 * hidden_dim / 3) + # custom dim factor multiplier + if ffn_dim_multiplier is not None: + hidden_dim = int(ffn_dim_multiplier * hidden_dim) + hidden_dim = multiple_of * ((hidden_dim + multiple_of - 1) // multiple_of) + # Linear 1 + self.w1 = ColumnParallelLinear(...) + # Linear 2 + self.w2 = RowParallelLinear(...) + # Linear 3 + self.w3 = ColumnParallelLinear(...) + def forward(self, x): + return self.w2(F.silu(self.w1(x)) * self.w3(x)) +``` + +### **参考资料** + +\[1] [一文看懂 LLaMA 中的旋转式位置编码](https://zhuanlan.zhihu.com/p/642884818 "一文看懂 LLaMA 中的旋转式位置编码") + +\[2] [Transformer升级之路:2、博采众长的旋转式位置编码](https://spaces.ac.cn/archives/8265 "Transformer升级之路:2、博采众长的旋转式位置编码") + +\[3] \[大模型推理性能优化之KV Cache解读]\([https://zhuanlan.zhihu.com/p/630832593](https://zhuanlan.zhihu.com/p/630832593 "https://zhuanlan.zhihu.com/p/630832593")) + +\[4] [分析transformer模型的参数量、计算量、中间激活、KV cache](https://zhuanlan.zhihu.com/p/624740065 "分析transformer模型的参数量、计算量、中间激活、KV cache") + +\[5] [为什么现在大家都在用 MQA 和 GQA?](https://mp.weixin.qq.com/s/_4OxoRLxhOcjGf0Q4Tvp2Q "为什么现在大家都在用 MQA 和 GQA?") diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/image/image_IvQxAiuPj-.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/image/image_IvQxAiuPj-.png" new file mode 100644 index 0000000..834b5d7 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/image/image_IvQxAiuPj-.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/image/image_by6m8VjSm2.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/image/image_by6m8VjSm2.png" new file mode 100644 index 0000000..39b3e8c Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/image/image_by6m8VjSm2.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/image/image_f7aV2UuNc7.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/image/image_f7aV2UuNc7.png" new file mode 100644 index 0000000..af35f8c Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/image/image_f7aV2UuNc7.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/image/image_uLhKN6r6M4.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/image/image_uLhKN6r6M4.png" new file mode 100644 index 0000000..daf7006 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/image/image_uLhKN6r6M4.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/image/image_xHBq-aoxIb.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/image/image_xHBq-aoxIb.png" new file mode 100644 index 0000000..752926d Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/image/image_xHBq-aoxIb.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/llama 3.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/llama 3.md" new file mode 100644 index 0000000..f9cd954 --- /dev/null +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama 3/llama 3.md" @@ -0,0 +1,109 @@ +# llama 3 + +## 0.简介 + +Meta LLaMA3 强势发布,迄今为止功能最强大的公开可用的 LLM。此版本是在 15 万亿个 Token 上预训练的语言模型,具有 8B 和 70B 两种参数规模,可以支持广泛的用户场景,在各种行业基准上取得了最先进的性能,并提供一些了新功能,包括改进的推理能力,这些都是同时期最好的开源模型。除此之外,LLaMA3还有400B参数的模型正在训练中。 + +## 1.改进亮点 + +1. **参数规模与模型架构**:Llama 3提供了8B和70B两种参数规模的模型,参数数量的增加使得模型能够捕捉和学习更复杂的语言模式。同时,Llama 3**采用了标准的纯解码器(decoder-only)Transformer架构,并引入了Group Query Attention(GQA)技术**,提高了模型的推理效率和处理长文本的能力。 +2. **训练数据集的扩展**:Llama 3的训练数据集比Llama 2大了7倍,包含了超过**15万亿个token**,其中包括4倍的代码数据,这使得Llama 3在理解和生成代码方面更加出色。 +3. **性能提升**:通过改进的预训练和后训练过程,Llama 3在减少错误拒绝率、提升响应对齐和增加模型响应多样性方面取得了显著进步。 +4. **安全性增强**:引入了Llama Guard 2等新的信任和安全工具,以及Code Shield和CyberSec Eval 2,增强了模型的安全性和可靠性。 +5. **多语言支持**:Llama 3在预训练数据中加入了超过30种语言的高质量非英语数据,为未来的多语言能力打下了基础。 + +| | **训练数据** | **模型参数** | **上下文长度** | **GQA** | **训练Token数** | **知识截止** | +| ------- | ----------- | -------- | --------- | ------- | ------------ | ----------- | +| Llama 3 | 公开在线数据的新组合。 | 8B | 8k | Yes | 15T+ | 2023 年 3 月 | +| | 公开在线数据的新组合。 | 70B | 8k | Yes | 15T+ | 2023 年 12 月 | + +> 注意:训练Token数仅指预训练数据。 + +## 2.模型架构 + +### 2.1 通用GPT架构 + +主流的大语言模型都采用了Transformer\[架构,它是一个基于多层自注意力(Self-attention)的神经网络模型。 + +原始的Transformer由编码器(Encoder)和解码器(Decoder)两个部分构成,同时,这两个部分也可以独立使用。例如基于编码器的BERT 模型和基于解码器的GPT模型。 + +Llama模型与GPT类似,也是采用了基于解码器的架构。在原始Transformer解码器的基础上,Llama进行了如下改动: + +- 为了增强训练稳定性,采用前置的\*\*RMSNorm \*\*作为层归一化方法。 +- 为了提高模型性能,采用\*\*SwiGLU \*\*作为激活函数。 +- 为了更好地建模长序列数据,采用\*\*RoPE \*\*作为位置编码。 +- 为了平衡效率和性能,部分模型采用了分组查询注意力机制 **(Grouped-Query Attention, GQA)**。 + +具体来说,首先将输入的token序列通过词嵌入(word embedding)矩阵转化为词向量序列。然后,词向量序列作为隐藏层状态依次通过𝐿个解码器层,并在最后使用RMSNorm进行归一化。归一化后的隐藏层状态将作为最后的输出。 + +在每个解码器层中,输入的隐藏层状态首先通过RMSNorm归一化然后被送入注意力模块。注意力模块的输出将和归一化前的隐藏层状态进行残差连接。之后,新的隐藏层状态进行RMSNorm归一化,然后被送入前馈网络层。类似地,前馈网络层的输出同样进行残差连接,作为解码器层的输出。 + +### 2.2 llama3改进 + +1. **解码器架构**:Llama 3采用了解码器架构,这是一种标准的Transformer模型架构,主要用于处理自然语言生成任务。 +2. **分词器和词汇量**:Llama 3使用了具有**128K**个token的分词器,这使得模型能够更高效地编码语言,从而显著提升性能。 +3. **分组查询注意力(GQA)**:为了提高推理效率,Llama 3在8B和70B模型中都采用了**GQA技术**。这种技术通过将注意力机制中的查询分组,减少了计算量,同时保持了模型的性能。 +4. **长序列处理**:Llama 3支持长达**8,192**个token的序列,使用掩码(masking)技术确保自注意力(self-attention)不会跨越文档边界,这对于处理长文本尤其重要。 +5. **预训练数据集**:Llama 3在超过**15TB**的token上进行了预训练,这个数据集不仅规模巨大,而且质量高,为模型提供了丰富的语言信息。 +6. **多语言数据**:为了支持多语言能力,Llama 3的预训练数据集包含了超过5%的非英语高质量数据,涵盖了超过30种语言。 +7. **数据过滤和质量控制**:Llama 3的开发团队开发了一系列数据过滤管道,包括启发式过滤器、NSFW过滤器、语义去重方法和文本分类器,以确保训练数据的高质量。 +8. **扩展性和并行化**:Llama 3的训练过程中采用了数据并行化、模型并行化和流水线并行化,这些技术的应用使得模型能够高效地在大量GPU上进行训练。 +9. **指令微调(Instruction Fine-Tuning)**:Llama 3在预训练模型的基础上,通过指令微调进一步提升了模型在特定任务上的表现,如对话和编程任务。 + +## 3.数据工程 + +LLaMA3 使用了超过 \*\*15T \*\*的 Tokens 进行预训练,这数据全部从公开来源收集。训练数据集比 LLaMA2 使用的数据集大七倍,并且包含四倍多的代码。并且 LLaMA3 预训练数据集中有超过 5% 的数据由涵盖 30 多种语言的高质量非英语数据组成。 + +为了确保 LLaMA3 接受最高质量数据的训练,**开发了一系列数据过滤pipeline**。这些流水线包括使用**启发式过滤器、NSFW 过滤器、语义重复数据删除和文本分类器来预测数据质量**。发现前几代 LLaMA 非常擅长识别高质量数据,因此**使用 LLaMA2 作为文本质量分类器生成训练数据为 LLaMA3 提供支持**。 + +此外,还进行了广泛的实验,以评估在最终预训练数据集中混合不同来源的数据的最佳方法。这些实验使我们能够选择一个数据组合,确保 LLaMA3 在各种场景(包括编码、历史知识等)中表现良好。 + +## 4.训练方法 + +与Llama-2类似,Llama-3系列也有两个模型——预训练模型Llama-3和微调后的模型Llama-3-Instruct。 + +在预训练阶段,为了有效地利用预训练数据,Llama-3投入了大量精力来扩大预训练。具体而言,通过为下游基准测试制定一系列**扩展法则(scaling laws)**,使得在训练之前就能预测出模型在关键任务上的性能,进而**选择最佳的数据组合**。 + +在这一过程中,Llama-3对扩展法则有了一些新的观察。例如,根据DeepMind 团队提出的Chinchilla 扩展法则,**8B模型的最优训练数据量约为200B token,但实验发现,即使训练了两个数量级的数据后,模型性能仍在继续提高**。在多达15T token上进行训练后,8B和70B参数的模型都继续以**对数线性**的方式提升性能。 + +为了训练最大的 LLaMA3 模型,**结合了三种类型的并行策略**:数据并行、模型并行和流水线并行。当同时在 16K GPU 上进行训练时,最高效可实现每个 GPU 超过 400 TFLOPS 的计算利用率。 + +为了最大限度地延长 GPU 的正常运行时间,开发了一种**先进的训练堆栈**,可以自动执行错误检测、处理和维护。同时,还极大地改进了硬件可靠性和静默数据损坏检测机制,开发了新的可扩展存储系统,以减少检查点和回滚的开销。这些改进使总体有效训练时间超过 95%。综合起来,这些改进使 LLaMA3 的训练效率比 LLaMA2 提高了约三倍。 + +## 5.指令微调优化 + +为了充分释放预训练模型在聊天场景中的潜力,还对指令微调方法进行了创新。后训练方法是**监督微调(SFT)、拒绝采样、近端策略优化(PPO)和直接策略优化(DPO)的组合**。SFT 中使用的提示质量以及 PPO 和 DPO 中使用的偏好排名对对齐模型的性能有着巨大的影响。在模型质量方面的一些最大改进来自于仔细整理这些数据并对人类标注者提供的标注进行多轮质量保证。 + +通过 PPO 和 DPO 从偏好排名中学习也极大地提高了 LLaMA3 在推理和编码任务上的性能。我们发现,如果你向模型提出一个它难以回答的推理问题,该模型有时会产生正确的推理轨迹:模型知道如何产生正确的答案,但不知道如何选择它。对偏好排名的训练使模型能够学习如何选择它。 + +## 6.性能 + +### 6.1 预训练模型性能 + +在众多基准测试中,8B模型超越了Mistral 7B和Gemma 7B,70B模型则战胜了Gemini Pro 1.0和Mixtral 8x22B。 + +![](image/image_IvQxAiuPj-.png) + +### 6.2 指令微调模型性能 + +Meta官方数据显示,在各自参数规模上,Llama-3 8B和70B版本都取得了不错的成绩。8B模型在众多基准测试中均胜过Gemma 7B和Mistral 7B Instruct,而70B模型超越了闭源模型Claude 3 Sonnet,对比谷歌的Gemini Pro 1.5性能也是相当。 + +![](image/image_by6m8VjSm2.png) + +### 6.3 人工评估结果 + +在 Llama 3 的开发过程中,研究了标准基准上的模型性能,并寻求优化现实场景的性能。为此,**开发了一套新的高质量人类评估集**。该评估集包含 1800 个提示,涵盖 12 个关键用例:寻求建议、头脑风暴、分类、封闭式问答、编码、创意写作、抽取、扮演一个角色/人物、开放式问答、推理、重写和总结。为了防止模型在此评估集上意外过度拟合,即使我们自己的建模团队也无法访问它。 + +下图显示了针对 Claude Sonnet、Mistral Medium 和 GPT-3.5 对这些类别和提示进行人工评估的汇总结果。 + +![](image/image_f7aV2UuNc7.png) + +## 7.LLaMA3-400B 正在训练中 + +LLaMA3 最大的模型有超过 400B 个参数,但该模型仍在训练中。基于 LLaMA3-400B 的早期检查点的性能测试如下: + +![](image/image_xHBq-aoxIb.png) + +值得注意的是,根据英伟达科学家Jim Fan的整理,Llama3 400B基本逼近Claude-3-Opus和GPT-4-turbo,这将意味着开源社区即将迎来GPT-4级大模型。 + +![](image/image_uLhKN6r6M4.png) diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_qmvGov6InM.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_AX8lFJosne.png" similarity index 100% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_qmvGov6InM.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_AX8lFJosne.png" diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_0k3hgI9kua.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_HL-FiPNnSG.png" similarity index 100% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_0k3hgI9kua.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_HL-FiPNnSG.png" diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_bwL9N_jV5y.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_KbWpfqtyqV.png" similarity index 100% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_bwL9N_jV5y.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_KbWpfqtyqV.png" diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_8RALg7fgFy.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_Li8zwpP-Yl.png" similarity index 100% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_8RALg7fgFy.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_Li8zwpP-Yl.png" diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_GeouZkLgrp.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_OOCoNO9X-g.png" similarity index 100% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_GeouZkLgrp.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_OOCoNO9X-g.png" diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_J0G-X9Ruu6.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_Pkz7Xv5qpC.png" similarity index 100% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_J0G-X9Ruu6.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_Pkz7Xv5qpC.png" diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_8_B_nbHsni.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_QzGxZVzHBf.png" similarity index 100% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_8_B_nbHsni.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_QzGxZVzHBf.png" diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_6g6JVd5GoX.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_SyfakZa0oX.png" similarity index 100% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_6g6JVd5GoX.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_SyfakZa0oX.png" diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_re5i75TH6P.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_XM9VQqYPki.png" similarity index 100% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_re5i75TH6P.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_XM9VQqYPki.png" diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_JKcphokS6S.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_ia9gxLh7hr.png" similarity index 100% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_JKcphokS6S.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_ia9gxLh7hr.png" diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_-1IrqoZB3h.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_xtVnhccmX6.png" similarity index 100% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_-1IrqoZB3h.png" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/image/image_xtVnhccmX6.png" diff --git "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/llama\347\263\273\345\210\227\346\250\241\345\236\213.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/llama\347\263\273\345\210\227\346\250\241\345\236\213.md" similarity index 79% rename from "01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/llama\347\263\273\345\210\227\346\250\241\345\236\213.md" rename to "docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/llama\347\263\273\345\210\227\346\250\241\345\236\213.md" index aeeb187..0259ea5 100644 --- "a/01.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\347\256\200\344\273\213/llama\347\263\273\345\210\227\346\250\241\345\236\213/llama\347\263\273\345\210\227\346\250\241\345\236\213.md" +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/llama\347\263\273\345\210\227\346\250\241\345\236\213/llama\347\263\273\345\210\227\346\250\241\345\236\213.md" @@ -10,7 +10,7 @@ Open and Efficient Foundation Language Models (Open但没完全Open的LLaMA) LLaMA 所采用的 Transformer 结构和细节,与标准的 Transformer 架构不同的地方包括采用了**前置层归一化(Pre-normalization)**并使用 **RMSNorm 归一化函数** (Normalizing Function)、激活函数更换为** SwiGLU**,并使用了**旋转位置嵌入(RoP)**,整体 Transformer 架构与 GPT-2 类似。 -![](image/image_8RALg7fgFy.png) +![](image/image_Li8zwpP-Yl.png) ## 1.2 RMSNorm归一化函数 @@ -24,8 +24,8 @@ $$ \bar{a}_{i}=\frac{a_{i}}{R M S(\boldsymbol{a})} $$ -此外,RMSNorm 还可以引入可学习的缩放因子 $ g_ -i $和偏移参数 $b_i$,从而得到 $\bar{a}_{i}=\frac{a_{i}}{\operatorname{RMS}(\boldsymbol{a})} g_{i}+b_{i}$。 RMSNorm 在 HuggingFace Transformer 库中代码实现如下所示: +此外,RMSNorm 还可以引入可学习的缩放因子 $g_ +i $和偏移参数 $b_i$,从而得到 $\bar{a}_{i}=\frac{a_{i}}{\operatorname{RMS}(\boldsymbol{a})} g_{i}+b_{i}$。 RMSNorm 在 HuggingFace Transformer 库中代码实现如下所示: ```python class LlamaRMSNorm(nn.Module): @@ -61,13 +61,13 @@ $$ \operatorname{Swish}_{\beta}(\boldsymbol{x})=\boldsymbol{x} \sigma(\boldsymbol{\beta} \boldsymbol{x}) $$ -其中,$σ(x)$ 是 Sigmoid 函数。下图给出了 Swish 激活函数在参数 $β$ 不同取值下的形状。可以看 到当 $β$ 趋近于 0 时,Swish 函数趋近于线性函数 $y = x$,当 $ β $趋近于无穷大时,Swish 函数趋近于 ReLU 函数,$β$ 取值为 1 时,Swish 函数是光滑且非单调。在 HuggingFace 的 Transformer 库中 Swish1 函数使用 silu 函数代替。 +其中,$σ(x)$ 是 Sigmoid 函数。下图给出了 Swish 激活函数在参数 $β$ 不同取值下的形状。可以看 到当 $β$ 趋近于 0 时,Swish 函数趋近于线性函数 $y = x$,当 $β $趋近于无穷大时,Swish 函数趋近于 ReLU 函数,$β$ 取值为 1 时,Swish 函数是光滑且非单调。在 HuggingFace 的 Transformer 库中 Swish1 函数使用 silu 函数代替。 -![](image/image_bwL9N_jV5y.png) +![](image/image_KbWpfqtyqV.png) -![](image/image_6g6JVd5GoX.png) +![](image/image_SyfakZa0oX.png) -LLaMA中直接将FFN中的ReLU替换为SwiGLU,并将维度放缩为$(2/3) ⋅ 4d$。这样设计的原因是:维度放缩为 $(2/3) ⋅ 4d$ 后,其计算复杂度为 $(112/9) ⋅ d^3 + (8/3) ⋅ d$ ,普通的 $4d$ 纬度的计算复杂度为 $20 ⋅ d^3$ 。 +LLaMA中直接将FFN中的ReLU替换为SwiGLU,并将维度放缩为$(2/3) ⋅ 4d$ ## 1.4 旋转位置嵌入(RoPE) @@ -97,7 +97,7 @@ $$ f(\boldsymbol{q}, m)=\underbrace{\left(\begin{array}{ccccccc}\cos m \theta_{0} & -\sin m \theta_{0} & 0 & 0 & \cdots & 0 & 0 \\ \sin m \theta_{0} & \cos m \theta_{0} & 0 & 0 & \cdots & 0 & 0 \\ 0 & 0 & \cos m \theta_{1} & -\sin m \theta_{1} & \cdots & 0 & 0 \\ 0 & 0 & \sin m \theta_{1} & \cos m \theta_{1} & \cdots & 0 & 0 \\ \cdots & \cdots & \cdots & \cdots & \ddots & \cdots & \cdots \\ 0 & 0 & 0 & 0 & \cdots & \cos m \theta_{d / 2-1} & -\sin m \theta_{d / 2-1} \\ 0 & 0 & 0 & 0 & \cdots & \sin m \theta_{d / 2-1} & \cos m \theta_{d / 2-1}\end{array}\right)}_{\boldsymbol{R}_{d}}\left(\begin{array}{c}\boldsymbol{q}_{0} \\ \boldsymbol{q}_{1} \\ \boldsymbol{q}_{2} \\ \boldsymbol{q}_{3} \\ \cdots \\ \boldsymbol{q}_{d-2} \\ \boldsymbol{q}_{d-1}\end{array}\right) $$ -![](image/image_8_B_nbHsni.png) +![](image/image_QzGxZVzHBf.png) RoPE 在 HuggingFace Transformer 库中代码实现如下所示: @@ -179,11 +179,11 @@ Alpaca是在**LLaMA基础上使用52K指令数据精调的预训练模型**, ## 2.2 微调方法 -1. 第一步:构造175条self-instruct 种子示例任务 -2. 第二步:基于上述种子任务,利 用text-davinci-003爬取指令数据 -3. 第三步:使用爬取下来的52K指令 数据在LLaMA上进行精调,最终 得到Alpaca +1. 第一步:构造175条self-instruct 种子示例任务 +2. 第二步:基于上述种子任务,利 用text-davinci-003爬取指令数据 +3. 第三步:使用爬取下来的52K指令 数据在LLaMA上进行精调,最终 得到Alpaca -![](image/image_qmvGov6InM.png) +![](image/image_AX8lFJosne.png) ## 2.3 Self-instruct数据构造 @@ -203,11 +203,11 @@ Alpaca是在**LLaMA基础上使用52K指令数据精调的预训练模型**, ## 2.4 指令数据格式 -- `instruction`: 描述模型需要执行的指令内容 -- `input`(可选): 任务上下文或输入信息,例如当指令是“对文章进行总结”,则input是文章内容 -- `output`: 由text-davinci-003生成的针对指令的回复 +- `instruction`: 描述模型需要执行的指令内容 +- `input`(可选): 任务上下文或输入信息,例如当指令是“对文章进行总结”,则input是文章内容 +- `output`: 由text-davinci-003生成的针对指令的回复 -![](image/image_0k3hgI9kua.png) +![](image/image_HL-FiPNnSG.png) # 3.Llama-2 @@ -219,13 +219,13 @@ Llama 2: Open Foundation and Fine-Tuned Chat Models 与一代LLaMA主要区别体现在**更多的训练数据、更⻓的上下文窗口、GQA技术**等 -![](image/image_re5i75TH6P.png) +![](image/image_XM9VQqYPki.png) 模型结构的变动主要是体现在**GQA**和**FFN**缩放上 -- **MHA改成GQA**:整体参数量会有减少 -- **FFN模块矩阵维度有扩充**:增强泛化能力,整体参数量增加 -- **上下文长度是llama两倍**(长度从2048->4096) 训练语料增加约 40%,体现在1.4T->2.0T的Tokens llama2-34B和llama2-70B使用了GQA,加速模型训练和推理速度 +- **MHA改成GQA**:整体参数量会有减少 +- **FFN模块矩阵维度有扩充**:增强泛化能力,整体参数量增加 +- **上下文长度是llama两倍**(长度从2048->4096) 训练语料增加约 40%,体现在1.4T->2.0T的Tokens llama2-34B和llama2-70B使用了GQA,加速模型训练和推理速度 ## 3.2 GQA @@ -233,17 +233,17 @@ GQA和MQA都是注意力的变体,其中多个查询头关注相同的键和 MHA、GQA、MQA的区别和联系,具体的优点如下: -- `Mutil-Head Attention` 因为自回归模型生成回答时,需要前面生成的KV缓存起来,来加速计算。 -- `Multi-Query Attention` 多个头之间可以共享KV对,因此速度上非常有优势,实验验证大约减少30-40%吞吐。 -- `Group Query Attention` 没有像MQA那么极端,将query分组,组内共享KV,效果接近MQA,速度上与MQA可比较。 +- `Mutil-Head Attention` 因为自回归模型生成回答时,需要前面生成的KV缓存起来,来加速计算。 +- `Multi-Query Attention` 多个头之间可以共享KV对,因此速度上非常有优势,实验验证大约减少30-40%吞吐。 +- `Group Query Attention` 没有像MQA那么极端,将query分组,组内共享KV,效果接近MQA,速度上与MQA可比较。 -![](image/image_JKcphokS6S.png) +![](image/image_ia9gxLh7hr.png) Llama-2中使用了8个KV映射,即GQA-8,**GQA在多数任务上与MHA效果相当,且平均效果优于MQA;GQA和MQA均比MHA有更好的吞吐量** ## 3.3 源码 -![](image/image_-1IrqoZB3h.png) +![](image/image_xtVnhccmX6.png) # 4.Code Llama @@ -255,13 +255,13 @@ Llama-2中使用了8个KV映射,即GQA-8,**GQA在多数任务上与MHA效果 亮点: -- 免费供学术研究和商用 -- 支持100K上下文 -- “神秘”34B版接近GPT-4效果 +- 免费供学术研究和商用 +- 支持100K上下文 +- “神秘”34B版接近GPT-4效果 ## 4.2 模型训练流程 -![](image/image_GeouZkLgrp.png) +![](image/image_OOCoNO9X-g.png) ## 4.3 Code Infilling Task (7B/13B only) @@ -269,23 +269,23 @@ Llama-2中使用了8个KV映射,即GQA-8,**GQA在多数任务上与MHA效果 方法: -- 从完整的代码中选择一部分进行掩码(mask)并替换为``符号,构成上下文 -- 利用自回归的方法,根据上下文信息预测解码出被mask的代码部分 +- 从完整的代码中选择一部分进行掩码(mask)并替换为``符号,构成上下文 +- 利用自回归的方法,根据上下文信息预测解码出被mask的代码部分 -![](image/image_J0G-X9Ruu6.png) +![](image/image_Pkz7Xv5qpC.png) # 5.总结 **LLaMA** -- 开源大模型繁荣发展的开端,一系列相关工作均基于LLaMA开展 -- 模型规模7B、13B、33B、65B满足了开发者和研究者的不同需求 +- 开源大模型繁荣发展的开端,一系列相关工作均基于LLaMA开展 +- 模型规模7B、13B、33B、65B满足了开发者和研究者的不同需求 **Alpaca**:通过少量的指令精调赋予LLaMA指令理解与执行的能力 **Llama-2** -- LLaMA的二代模型,相关模型性能进一步提升,模型可商用 -- 推出官方对⻬的Chat版本模型,采用了完整的RLHF链条 +- LLaMA的二代模型,相关模型性能进一步提升,模型可商用 +- 推出官方对⻬的Chat版本模型,采用了完整的RLHF链条 **Code Llama**:专注于代码能力的LLaMA模型,最好的模型代码能力接近GPT-4效果,模型可商用 diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image_9gYWmmepwO.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image_9gYWmmepwO.png" new file mode 100644 index 0000000..2d61257 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image_9gYWmmepwO.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image_Ny0Q02PMxt.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image_Ny0Q02PMxt.png" new file mode 100644 index 0000000..92ac88f Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image_Ny0Q02PMxt.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image__JLu-EWfqO.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image__JLu-EWfqO.png" new file mode 100644 index 0000000..843d155 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image__JLu-EWfqO.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image_ci6Y3cvZrl.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image_ci6Y3cvZrl.png" new file mode 100644 index 0000000..c574bd4 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image_ci6Y3cvZrl.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image_i2MAU6x-Kx.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image_i2MAU6x-Kx.png" new file mode 100644 index 0000000..3cd41d8 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image_i2MAU6x-Kx.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image_vNWSVaHeJE.png" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image_vNWSVaHeJE.png" new file mode 100644 index 0000000..f4e7f69 Binary files /dev/null and "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/image/image_vNWSVaHeJE.png" differ diff --git "a/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperature\357\274\211.md" "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperature\357\274\211.md" new file mode 100644 index 0000000..be9e4fa --- /dev/null +++ "b/docs/02.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\346\236\266\346\236\204/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperatu/\350\247\243\347\240\201\347\255\226\347\225\245\357\274\210Top-k & Top-p & Temperature\357\274\211.md" @@ -0,0 +1,243 @@ +# 解码策略(Top-k & Top-p & Temperature) + +## 0.简介 + +在大模型训练好之后,如何对训练好的模型进行解码(decode)是一个火热的研究话题。 + +一般给模型传入的解码参数如下所示。 + +```json +{ + "top_k": 10, + "temperature": 0.95, + "num_beams": 1, + "top_p": 0.8, + "repetition_penalty": 1.5, + "max_tokens": 30000, + "message": [ + { + "content": "你好!", + "role": "user" + } + ] +} +``` + +在自然语言任务中,通常使用一个预训练的大模型(比如GPT)来根据给定的输入文本(比如一个开头或一个问题)生成输出文本(比如一个答案或一个结尾)。为了生成输出文本,需要让模型逐个预测每个 token ,直到达到一个终止条件(如一个标点符号或一个最大长度)。在每一步,模型会给出一个概率分布,表示它对下一个单词的预测。例如,如果输入的文本是“我最喜欢的”,那么模型可能会给出下面的概率分布: + +![](image/image_vNWSVaHeJE.png) + +那么,应该如何从这个概率分布中选择下一个单词呢?以下是几种常用的方法: + +- **贪心解码**(Greedy Decoding):直接选择概率最高的单词。这种方法简单高效,但是可能会导致生成的文本过于单调和重复。 +- **随机采样**(Random Sampling):按照概率分布随机选择一个单词。这种方法可以增加生成的多样性,但是可能会导致生成的文本不连贯和无意义。 +- **Beam Search**:维护一个大小为 k 的候选序列集合,每一步从每个候选序列的概率分布中选择概率最高的 k 个单词,然后保留总概率最高的 k 个候选序列。这种方法可以平衡生成的质量和多样性,但是可能会导致生成的文本过于保守和不自然。 + +以上方法都有各自的问题,而 **top-k 采样和 top-p 采样是介于贪心解码和随机采样之间的方法**,也是目前大模型解码策略中常用的方法。 + +## 2.top-k采样 + +在上面的例子中,如果使用**贪心策略**,那么选择的 token 必然就是“女孩”。 + +**贪心解码**是一种合理的策略,但也有一些缺点。例如,**输出可能会陷入重复循环**。想想智能手机自动建议中的建议。当你不断地选择建议最高的单词时,它可能会变成重复的句子。 + +**Top-k 采样**是对前面“贪心策略”的优化,它从排名前 k 的 token 中进行抽样,允许其他分数或概率较高的token 也有机会被选中。在很多情况下,这种抽样带来的随机性有助于提高生成质量。 + +**top-k 采样**的思路是,在每一步,只从概率最高的 k 个单词中进行随机采样,而不考虑其他低概率的单词。例如,如果 k=2,那么只从女孩、鞋子中选择一个单词,而不考虑大象、西瓜等其他单词。这样可以避免采样到一些不合适或不相关的单词,同时也可以保留一些有趣或有创意的单词。 + +下面是 top-k 采样的例子: + +![](image/image_9gYWmmepwO.png) + +通过调整 k 的大小,即可控制采样列表的大小。“贪心策略”其实就是 k = 1的 top-k 采样。 + +![](image/image__JLu-EWfqO.png) + +下面是top-k 的代码实现: + +```python +import torch +from labml_nn.sampling import Sampler + +# Top-k Sampler +class TopKSampler(Sampler): + # k is the number of tokens to pick + # sampler is the sampler to use for the top-k tokens + # sampler can be any sampler that takes a logits tensor as input and returns a token tensor; e.g. `TemperatureSampler`. + def __init__(self, k: int, sampler: Sampler): + self.k = k + self.sampler = sampler + + # Sample from logits + def __call__(self, logits: torch.Tensor): + # New logits filled with −∞; i.e. zero probability + zeros = logits.new_ones(logits.shape) * float('-inf') + # Pick the largest k logits and their indices + values, indices = torch.topk(logits, self.k, dim=-1) + # Set the values of the top-k selected indices to actual logits. + # Logits of other tokens remain −∞ + zeros.scatter_(-1, indices, values) + # Sample from the top-k logits with the specified sampler. + return self.sampler(zeros) +``` + +总结一下,top-k 有以下有点: + +- 它可以根据不同的输入文本动态调整候选单词的数量,而不是固定为 k 个。这是因为不同的输入文本可能会导致不同的概率分布,有些分布可能比较平坦,有些分布可能比较尖锐。如果分布比较平坦,那么前 k 个单词可能都有相近的概率,那么我们就可以从中进行随机采样;如果分布比较尖锐,那么前 k 个单词可能会占据绝大部分概率,那么我们就可以近似地进行贪心解码。 +- 它可以通过调整 k 的大小来控制生成的多样性和质量。一般来说,**k 越大,生成的多样性越高,但是生成的质量越低;k 越小,生成的质量越高,但是生成的多样性越低**。因此,可以根据不同的任务和场景来选择合适的k 值。 +- 它可以与其他解码策略结合使用,例如温度调节(Temperature Scaling)、重复惩罚(Repetition Penalty)、长度惩罚(Length Penalty)等,来进一步优化生成的效果。 + +但是 top-k 也有一些缺点,比如: + +- 它可能会导致生成的文本不符合常识或逻辑。这是因为\*\* top-k 采样只考虑了单词的概率,而没有考虑单词之间的语义和语法关系\*\*。例如,如果输入文本是“我喜欢吃”,那么即使饺子的概率最高,也不一定是最合适的选择,因为可能用户更喜欢吃其他食物。 +- 它可能会导致生成的文本过于简单或无聊。这是因为 top-k 采样只考虑了概率最高的 k 个单词,而**没有考虑其他低概率但有意义或有创意的单词**。例如,如果输入文本是“我喜欢吃”,那么即使苹果、饺子和火锅都是合理的选择,也不一定是最有趣或最惊喜的选择,因为可能用户更喜欢吃一些特别或新奇的食物。 + +因此,通常会考虑 top-k 和其它策略结合,比如 top-p。 + +## 3.top-p采样 + +top-k 有一个缺陷,那就是“k 值取多少是最优的?”非常难确定。于是出现了动态设置 token 候选列表大小策略——即核采样(Nucleus Sampling)。 + +top-p 采样的思路是,在每一步,**只从累积概率超过某个阈值 p 的最小单词集合中进行随机采样,而不考虑其他低概率的单词**。这种方法也被称为**核采样(nucleus sampling)**,因为它只关注概率分布的核心部分,而忽略了尾部部分。例如,如果 p=0.9,那么我们只从累积概率达到 0.9 的最小单词集合中选择一个单词,而不考虑其他累积概率小于 0.9 的单词。这样可以避免采样到一些不合适或不相关的单词,同时也可以保留一些有趣或有创意的单词。 + +下图展示了 top-p 值为 0.9 的 Top-p 采样效果: + +![](image/image_i2MAU6x-Kx.png) + +top-p 值通常设置为比较高的值(如0.75),目的是限制低概率 token 的长尾。**可以同时使用 top-k 和 top-p。如果 k 和 p 同时启用,则 p 在 k 之后起作用**。 + +下面是 top-p 代码实现的例子: + +```python +import torch +from torch import nn + +from labml_nn.sampling import Sampler + +class NucleusSampler(Sampler): + """ + ## Nucleus Sampler + """ + def __init__(self, p: float, sampler: Sampler): + """ + :param p: is the sum of probabilities of tokens to pick $p$ + :param sampler: is the sampler to use for the selected tokens + """ + self.p = p + self.sampler = sampler + # Softmax to compute $P(x_i | x_{1:i-1})$ from the logits + self.softmax = nn.Softmax(dim=-1) + + def __call__(self, logits: torch.Tensor): + """ + Sample from logits with Nucleus Sampling + """ + + # Get probabilities $P(x_i | x_{1:i-1})$ + probs = self.softmax(logits) + + # Sort probabilities in descending order + sorted_probs, indices = torch.sort(probs, dim=-1, descending=True) + + # Get the cumulative sum of probabilities in the sorted order + cum_sum_probs = torch.cumsum(sorted_probs, dim=-1) + + # Find the cumulative sums less than $p$. + nucleus = cum_sum_probs < self.p + + # Prepend ones so that we add one token after the minimum number + # of tokens with cumulative probability less that $p$. + nucleus = torch.cat([nucleus.new_ones(nucleus.shape[:-1] + (1,)), nucleus[..., :-1]], dim=-1) + + # Get log probabilities and mask out the non-nucleus + sorted_log_probs = torch.log(sorted_probs) + sorted_log_probs[~nucleus] = float('-inf') + + # Sample from the sampler + sampled_sorted_indexes = self.sampler(sorted_log_probs) + + # Get the actual indexes + res = indices.gather(-1, sampled_sorted_indexes.unsqueeze(-1)) + + # + return res.squeeze(-1) +``` + +## 3.Temperature采样 + +Temperature 采样受统计热力学的启发,高温意味着更可能遇到低能态。在概率模型中,logits 扮演着能量的角色,可以**通过将 logits 除以温度来实现温度采样,然后将其输入 Softmax 并获得采样概率**。 + +**越低的温度使模型对其首选越有信心,而高于1的温度会降低信心。0温度相当于 argmax 似然,而无限温度相当于均匀采样**。 + +Temperature 采样中的温度与玻尔兹曼分布有关,其公式如下所示: + +$$ +\rho_{i}=\frac{1}{Q} e^{-\epsilon_{i} / k T}=\frac{e^{-\varepsilon i / k T}}{\sum j=1^{M} e^{-\epsilon_{j} / k T}} +$$ + +其中 $\rho_i$ 是状态 i 的概率, $\epsilon_i$ 是状态 i 的能量, k 是波兹曼常数, T 是系统的温度, M 是系统所能到达的所有量子态的数目。 + +有机器学习背景的朋友第一眼看到上面的公式会觉得似曾相识。没错,上面的公式跟 Softmax 函数 : + +$$ +\operatorname{Softmax}\left(z_{i}\right)=\frac{e^{z_{i}}}{\sum_{c=1}^{C} e^{z_{c}}} +$$ + +很相似,本质上就是在 Softmax 函数上添加了温度(T)这个参数。Logits 根据我们的温度值进行缩放,然后传递到 Softmax 函数以计算新的概率分布。 + +上面“我喜欢漂亮的\_\_ \_”这个例子中,初始温度 T=1 ,直观看一下 T 取不同值的情况下,概率会发生什么变化: + +![](image/image_ci6Y3cvZrl.png) + +通过上图可以清晰地看到,**随着温度的降低,模型愈来愈越倾向选择”女孩“;另一方面,随着温度的升高,分布变得越来越均匀**。当 T=50时,选择”西瓜“的概率已经与选择”女孩“的概率相差无几了。 + +![](image/image_Ny0Q02PMxt.png) + +通常来说,温度与模型的“创造力”有关。但事实并非如此。温度只是调整单词的概率分布。其最终的宏观效果是,**在较低的温度下,我们的模型更具确定性,而在较高的温度下,则不那么确定**。 + +下面是 Temperature 采样的代码实现: + +```python +import torch +from torch.distributions import Categorical + +from labml_nn.sampling import Sampler + +class TemperatureSampler(Sampler): + """ + ## Sampler with Temperature + """ + def __init__(self, temperature: float = 1.0): + """ + :param temperature: is the temperature to sample with + """ + self.temperature = temperature + + def __call__(self, logits: torch.Tensor): + """ + Sample from logits + """ + + # Create a categorical distribution with temperature adjusted logits + dist = Categorical(logits=logits / self.temperature) + + # Sample + return dist.sample() +``` + +## 4.联合采样(top-k & top-p & Temperature) + +通常是将 **top-k、top-p、Temperature 联合起来使用**。使用的先后顺序是` top-k->top-p->Temperature`。 + +还是以前面的例子为例。 + +首先设置 `top-k = 3`,表示保留概率最高的3个 token。这样就会保留女孩、鞋子、大象这3个 token。 + +- 女孩:0.664 +- 鞋子:0.199 +- 大象:0.105 + +接下来,可以使用 top-p 的方法,保留概率的累计和达到 0.8 的单词,也就是选取女孩和鞋子这两个 token。接着使用 Temperature = 0.7 进行归一化,变成: + +- 女孩:0.660 +- 鞋子:0.340 diff --git "a/docs/03.\350\256\255\347\273\203\346\225\260\346\215\256\351\233\206/README.md" "b/docs/03.\350\256\255\347\273\203\346\225\260\346\215\256\351\233\206/README.md" new file mode 100644 index 0000000..c89ccaf --- /dev/null +++ "b/docs/03.\350\256\255\347\273\203\346\225\260\346\215\256\351\233\206/README.md" @@ -0,0 +1,7 @@ +# 03.训练数据集 + +### 3.1 数据集 + +[数据格式](/docs/03.训练数据集/数据格式/数据格式.md "数据格式") + +### 3.2 模型参数 diff --git "a/docs/03.\350\256\255\347\273\203\346\225\260\346\215\256\351\233\206/\346\225\260\346\215\256\346\240\274\345\274\217/\346\225\260\346\215\256\346\240\274\345\274\217.md" "b/docs/03.\350\256\255\347\273\203\346\225\260\346\215\256\351\233\206/\346\225\260\346\215\256\346\240\274\345\274\217/\346\225\260\346\215\256\346\240\274\345\274\217.md" new file mode 100644 index 0000000..98560da --- /dev/null +++ "b/docs/03.\350\256\255\347\273\203\346\225\260\346\215\256\351\233\206/\346\225\260\346\215\256\346\240\274\345\274\217/\346\225\260\346\215\256\346\240\274\345\274\217.md" @@ -0,0 +1,111 @@ +# 数据格式 + +\[toc] + +### 1.SFT(有监督微调)的数据集格式? + +对于大语言模型的训练中,SFT(Supervised Fine-Tuning)的数据集格式可以采用以下方式: + +1. 输入数据:输入数据是一个文本序列,通常是一个句子或者一个段落。每个样本可以是一个字符串或者是一个tokenized的文本序列。 +2. 标签数据:标签数据是与输入数据对应的标签或类别。标签可以是单个类别,也可以是多个类别的集合。对于多分类任务,通常使用one-hot编码或整数编码来表示标签。 +3. 数据集划分:数据集通常需要划分为训练集、验证集和测试集。训练集用于模型的训练,验证集用于调整模型的超参数和监控模型的性能,测试集用于评估模型的最终性能。 +4. 数据集格式:数据集可以以文本文件(如CSV、JSON等)或数据库的形式存储。每个样本包含输入数据和对应的标签。可以使用表格形式存储数据,每一列代表一个特征或标签。 + +下面是一个示例数据集的格式: + +```bash +Input,Label +"This is a sentence.",1 +"Another sentence.",0 +... +``` + +在这个示例中,**输入数据是一个句子,标签是一个二分类的标签**(1代表正例,0代表负例)。每一行代表一个样本,第一列是输入数据,第二列是对应的标签。 + +需要注意的是,具体的数据集格式可能会因任务类型、数据来源和使用的深度学习框架而有所不同。因此,在进行SFT训练时,建议根据具体任务和框架的要求来定义和处理数据集格式。 + +### 2.RM(奖励模型)的数据格式? + +在大语言模型训练中,RM(Reward Model,奖励模型)的数据格式可以采用以下方式: + +1. 输入数据:输入数据是一个文本序列,通常是一个句子或者一个段落。每个样本可以是一个字符串或者是一个tokenized的文本序列。 +2. 奖励数据:奖励数据是与输入数据对应的奖励或评分。奖励可以是一个实数值,表示对输入数据的评价。也可以是一个离散的标签,表示对输入数据的分类。奖励数据可以是人工标注的,也可以是通过其他方式(如人工评估、强化学习等)得到的。 +3. 数据集格式:数据集可以以文本文件(如CSV、JSON等)或数据库的形式存储。每个样本包含输入数据和对应的奖励数据。可以使用表格形式存储数据,每一列代表一个特征或标签。 + +下面是一个示例数据集的格式: + +```bash +Input,Reward +"This is a sentence.",0.8 +"Another sentence.",0.2 +... +``` + +在这个示例中,输入数据是一个句子,**奖励数据是一个实数值,表示对输入数据的评价**。每一行代表一个样本,第一列是输入数据,第二列是对应的奖励数据。 + +需要注意的是,具体的数据集格式可能会因任务类型、数据来源和使用的深度学习框架而有所不同。因此,在使用RM进行大语言模型训练时,建议根据具体任务和框架的要求来定义和处理数据集格式。 + +### 3.PPO(强化学习)的数据格式? + +在大语言模型训练中,PPO(Proximal Policy Optimization,近端策略优化)是一种常用的强化学习算法。PPO的数据格式可以采用以下方式: + +1. 输入数据:输入数据是一个文本序列,通常是一个句子或者一个段落。每个样本可以是一个字符串或者是一个tokenized的文本序列。 +2. 奖励数据:奖励数据是与输入数据对应的奖励或评分。奖励可以是一个实数值,表示对输入数据的评价。也可以是一个离散的标签,表示对输入数据的分类。奖励数据可以是人工标注的,也可以是通过其他方式(如人工评估、模型评估等)得到的。 +3. 动作数据:动作数据是模型在给定输入数据下的输出动作。对于语言模型,动作通常是生成的文本序列。动作数据可以是一个字符串或者是一个tokenized的文本序列。 +4. 状态数据:状态数据是模型在给定输入数据和动作数据下的状态信息。对于语言模型,状态数据可以是模型的隐藏状态或其他中间表示。状态数据的具体形式可以根据具体任务和模型结构进行定义。 +5. 数据集格式:数据集可以以文本文件(如CSV、JSON等)或数据库的形式存储。每个样本包含输入数据、奖励数据、动作数据和状态数据。可以使用表格形式存储数据,每一列代表一个特征或标签。 + +下面是一个示例数据集的格式: + +```bash +Input,Reward,Action,State + "This is a sentence.",0.8,"This is a generated sentence.",[0.1, 0.2, 0.3, ...] +"Another sentence.",0.2,"Another generated sentence.",[0.4, 0.5, 0.6, ...] +... +``` + +在这个示例中,输入数据是一个句子,奖励数据是一个实数值,动作数据是生成的句子,状态数据是模型的隐藏状态。每一行代表一个样本,第一列是输入数据,第二列是对应的奖励数据,第三列是生成的动作数据,第四列是状态数据。 + +需要注意的是,具体的数据集格式可能会因任务类型、数据来源和使用的深度学习框架而有所不同。因此,在使用PPO进行大语言模型训练时,建议根据具体任务和框架的要求来定义和处理数据集格式。 + +### 4.找数据集哪里找? + +在训练自己的大语言模型时,可以从以下几个途径找到合适的数据集: + +1. **公开数据集**:有许多公开可用的数据集可供使用,涵盖了各种领域和任务。例如,Common Crawl、Wikipedia、OpenWebText、BookCorpus等都是常用的大规模文本数据集,可以用于语言模型的训练。 +2. **开放数据平台**:许多组织和机构提供了开放的数据平台,可以获取各种类型的数据。例如,Kaggle、UCI Machine Learning Repository、Google Dataset Search等平台都提供了丰富的数据集资源。 +3. **学术界研究**:许多学术研究项目会公开其使用的数据集,可以通过相关论文或项目页面找到这些数据集。例如,NLP领域的一些会议和竞赛(如ACL、EMNLP、CoNLL、GLUE等)提供了公开的数据集供研究使用。 +4. **数据收集和爬取**:如果没有合适的公开数据集,您可以自己进行数据收集和爬取。这可以通过爬虫技术从互联网上收集相关的文本数据。需要注意的是,在进行数据收集和爬取时,需要遵守法律法规和网站的使用条款,并确保获得数据的合法使用权。 +5. **数据增强**:如果您已经有了一些初始的数据集,但觉得数量不够,可以考虑使用数据增强技术来扩充数据。数据增强可以通过对原始数据进行一些变换、替换、合成等操作来生成新的样本。 + +无论从哪个途径获取数据集,都需要注意数据的质量、版权和隐私等问题。确保您有合法的使用权,并遵守相关的法律和伦理规范。 + +### 5.微调需要多少条数据? + +根据 Scaling Laws,随着模型大小、数据集大小和用于训练的计算浮点数的增加,模型的性能会提高。并且为了获得最佳性能,所有三个因素**必须同时放大**。一般来说对于给定模型的理想训练数据集 token 数量大约是模型中参数数量的20倍。 + +### 6.有哪些大模型的训练集? + +以下是一些常用的大语言模型训练集的示例: + +1. Common Crawl:这是一个由互联网上抓取的大规模文本数据集,包含了来自各种网站的文本内容。它是一个常用的数据集,可用于语言模型的训练。 +2. Wikipedia:维基百科是一个包含大量结构化文本的在线百科全书。维基百科的内容丰富多样,涵盖了各种领域的知识,可以作为语言模型训练的数据集。 +3. OpenWebText:这是一个从互联网上抓取的开放文本数据集,类似于Common Crawl。它包含了大量的网页文本,可以作为语言模型的训练数据。 +4. BookCorpus:这是一个包含了大量图书文本的数据集,用于语言模型的训练。它包括了各种类型的图书,涵盖了广泛的主题和领域。 +5. News articles:新闻文章是另一个常用的语言模型训练集。可以通过从新闻网站、新闻API或新闻数据库中收集新闻文章来构建训练集。 +6. 其他领域特定数据集:根据具体任务和应用,可以使用特定领域的数据集来训练语言模型。例如,在医学领域,可以使用医学文献或医疗记录作为训练数据;在法律领域,可以使用法律文书或法律条款作为训练数据。 + +需要注意的是,使用这些数据集时,应该遵守数据的版权和使用规定,确保合法的使用权。此外,还可以通过数据增强技术,如数据合成、数据变换等,来扩充训练集的规模和多样性。 + +### 7.进行领域大模型预训练应用哪些数据集比较好? + +进行领域大模型预训练时,可以使用以下几种数据集来获得更好的效果: + +1. 领域特定文本数据集:收集与目标领域相关的文本数据集,例如专业领域的论文、报告、文档、书籍等。这些数据集可以提供领域内的专业术语、上下文和特定领域的知识。 +2. 领域内的网页内容:从目标领域相关的网页抓取文本内容。可以通过爬虫技术从相关网站上获取与目标领域相关的网页文本数据。 +3. 领域内的新闻文章:收集与目标领域相关的新闻文章。新闻文章通常包含了领域内的最新信息和事件,可以帮助模型了解领域内的动态和趋势。 +4. 行业报告和白皮书:获取与目标领域相关的行业报告、白皮书和研究文献。这些文献通常包含了领域内的专业分析、统计数据和趋势预测,可以帮助模型了解行业背景和发展趋势。 +5. 社交媒体数据:收集与目标领域相关的社交媒体数据,如推特、微博、论坛等。社交媒体上的内容通常反映了人们在目标领域中的讨论、观点和问题,可以帮助模型了解领域内的热点和用户需求。 +6. 领域内的对话数据:获取与目标领域相关的对话数据,如客服对话、问答平台数据等。这些对话数据可以帮助模型学习领域内的常见问题、解决方案和用户需求。 + +在选择数据集时,应该确保数据的质量和合法性,并遵守相关的法律和伦理规范。同时,还可以考虑使用数据增强技术,如数据合成、数据变换等,来扩充训练集的规模和多样性。 diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\230\276\345\255\230\351\227\256\351\242\230/1.\346\230\276\345\255\230\351\227\256\351\242\230.md" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\230\276\345\255\230\351\227\256\351\242\230/1.\346\230\276\345\255\230\351\227\256\351\242\230.md" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\230\276\345\255\230\351\227\256\351\242\230/1.\346\230\276\345\255\230\351\227\256\351\242\230.md" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\230\276\345\255\230\351\227\256\351\242\230/1.\346\230\276\345\255\230\351\227\256\351\242\230.md" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\230\276\345\255\230\351\227\256\351\242\230/image/image_v5zrA5FZ1Y.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\230\276\345\255\230\351\227\256\351\242\230/image/image_v5zrA5FZ1Y.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\230\276\345\255\230\351\227\256\351\242\230/image/image_v5zrA5FZ1Y.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\230\276\345\255\230\351\227\256\351\242\230/image/image_v5zrA5FZ1Y.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/1.\346\246\202\350\277\260.md" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/1.\346\246\202\350\277\260.md" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/1.\346\246\202\350\277\260.md" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/1.\346\246\202\350\277\260.md" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_-tuqRkUrTn.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_-tuqRkUrTn.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_-tuqRkUrTn.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_-tuqRkUrTn.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_0BOIRLvIJN.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_0BOIRLvIJN.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_0BOIRLvIJN.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_0BOIRLvIJN.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_G-gi_5V_1p.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_G-gi_5V_1p.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_G-gi_5V_1p.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_G-gi_5V_1p.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_MgTrkKeM2Y.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_MgTrkKeM2Y.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_MgTrkKeM2Y.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_MgTrkKeM2Y.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_SZBLANWZcs.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_SZBLANWZcs.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_SZBLANWZcs.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_SZBLANWZcs.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_auVu9e0Uwe.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_auVu9e0Uwe.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_auVu9e0Uwe.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_auVu9e0Uwe.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_dWNc6w3FgY.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_dWNc6w3FgY.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_dWNc6w3FgY.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_dWNc6w3FgY.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_i9Fb110BaP.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_i9Fb110BaP.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_i9Fb110BaP.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_i9Fb110BaP.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_iQfO1rQilr.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_iQfO1rQilr.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_iQfO1rQilr.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_iQfO1rQilr.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_j5sDPbely8.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_j5sDPbely8.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_j5sDPbely8.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_j5sDPbely8.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_wpjKkGQJAt.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_wpjKkGQJAt.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_wpjKkGQJAt.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_wpjKkGQJAt.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_xMrKSVuEHQ.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_xMrKSVuEHQ.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_xMrKSVuEHQ.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/1.\346\246\202\350\277\260/image/image_xMrKSVuEHQ.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/2.\346\225\260\346\215\256\345\271\266\350\241\214.md" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/2.\346\225\260\346\215\256\345\271\266\350\241\214.md" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/2.\346\225\260\346\215\256\345\271\266\350\241\214.md" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/2.\346\225\260\346\215\256\345\271\266\350\241\214.md" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_Dkqm9-ELHY.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_Dkqm9-ELHY.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_Dkqm9-ELHY.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_Dkqm9-ELHY.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_Iy2hNrDMWR.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_Iy2hNrDMWR.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_Iy2hNrDMWR.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_Iy2hNrDMWR.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_M4-uEmUjmI.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_M4-uEmUjmI.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_M4-uEmUjmI.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_M4-uEmUjmI.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_QGkvNKIWaB.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_QGkvNKIWaB.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_QGkvNKIWaB.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_QGkvNKIWaB.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_TeKe8sDfM0.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_TeKe8sDfM0.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_TeKe8sDfM0.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_TeKe8sDfM0.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_UISm6js_KZ.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_UISm6js_KZ.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_UISm6js_KZ.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_UISm6js_KZ.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_VgnDYnASLJ.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_VgnDYnASLJ.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_VgnDYnASLJ.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_VgnDYnASLJ.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image__OtJk1TbkM.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image__OtJk1TbkM.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image__OtJk1TbkM.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image__OtJk1TbkM.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image__WO4Gb_gi5.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image__WO4Gb_gi5.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image__WO4Gb_gi5.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image__WO4Gb_gi5.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_eNJ6FyULtl.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_eNJ6FyULtl.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_eNJ6FyULtl.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_eNJ6FyULtl.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_xx1P6SZT2R.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_xx1P6SZT2R.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_xx1P6SZT2R.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/2.\346\225\260\346\215\256\345\271\266\350\241\214/image/image_xx1P6SZT2R.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214.md" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214.md" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214.md" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214.md" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_-LFelNoH_T.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_-LFelNoH_T.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_-LFelNoH_T.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_-LFelNoH_T.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_-zAXfAICIZ.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_-zAXfAICIZ.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_-zAXfAICIZ.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_-zAXfAICIZ.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_45-emO92lm.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_45-emO92lm.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_45-emO92lm.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_45-emO92lm.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_5CPpxFik4j.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_5CPpxFik4j.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_5CPpxFik4j.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_5CPpxFik4j.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_D3L5nfRf84.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_D3L5nfRf84.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_D3L5nfRf84.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_D3L5nfRf84.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_LyMglwmO80.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_LyMglwmO80.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_LyMglwmO80.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_LyMglwmO80.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_NUJdgT2VC9.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_NUJdgT2VC9.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_NUJdgT2VC9.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_NUJdgT2VC9.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_QQfBFCQCGT.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_QQfBFCQCGT.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_QQfBFCQCGT.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_QQfBFCQCGT.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_TXAvC6K7_l.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_TXAvC6K7_l.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_TXAvC6K7_l.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_TXAvC6K7_l.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_VYOFXjru4b.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_VYOFXjru4b.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_VYOFXjru4b.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_VYOFXjru4b.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_XNdOKM79mF.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_XNdOKM79mF.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_XNdOKM79mF.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_XNdOKM79mF.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_Za-MgpelvZ.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_Za-MgpelvZ.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_Za-MgpelvZ.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_Za-MgpelvZ.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image__DoHSWCunA.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image__DoHSWCunA.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image__DoHSWCunA.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image__DoHSWCunA.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image__QXZkXF8ko.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image__QXZkXF8ko.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image__QXZkXF8ko.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image__QXZkXF8ko.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_go7z-J0Qh1.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_go7z-J0Qh1.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_go7z-J0Qh1.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_go7z-J0Qh1.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_q8sI8FoYKn.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_q8sI8FoYKn.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_q8sI8FoYKn.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_q8sI8FoYKn.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_tR4sS6fzEJ.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_tR4sS6fzEJ.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_tR4sS6fzEJ.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/3.\346\265\201\346\260\264\347\272\277\345\271\266\350\241\214/image/image_tR4sS6fzEJ.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/4.\345\274\240\351\207\217\345\271\266\350\241\214.md" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/4.\345\274\240\351\207\217\345\271\266\350\241\214.md" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/4.\345\274\240\351\207\217\345\271\266\350\241\214.md" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/4.\345\274\240\351\207\217\345\271\266\350\241\214.md" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_-qwT9-UIxA.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_-qwT9-UIxA.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_-qwT9-UIxA.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_-qwT9-UIxA.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_-u9XHKpRLE.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_-u9XHKpRLE.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_-u9XHKpRLE.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_-u9XHKpRLE.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_2RPv_sfzcH.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_2RPv_sfzcH.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_2RPv_sfzcH.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_2RPv_sfzcH.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_7I73oCbzb-.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_7I73oCbzb-.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_7I73oCbzb-.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_7I73oCbzb-.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_99Ji-kbokD.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_99Ji-kbokD.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_99Ji-kbokD.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_99Ji-kbokD.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_9pFyQ7hULv.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_9pFyQ7hULv.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_9pFyQ7hULv.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_9pFyQ7hULv.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_AcxOQBm8rp.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_AcxOQBm8rp.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_AcxOQBm8rp.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_AcxOQBm8rp.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_IA8zN9k2qY.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_IA8zN9k2qY.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_IA8zN9k2qY.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_IA8zN9k2qY.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_LsRWnHMfld.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_LsRWnHMfld.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_LsRWnHMfld.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_LsRWnHMfld.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_XYhiRcuHQ5.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_XYhiRcuHQ5.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_XYhiRcuHQ5.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_XYhiRcuHQ5.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_ek2XbnbB_C.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_ek2XbnbB_C.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_ek2XbnbB_C.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_ek2XbnbB_C.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_gHVUUzptSn.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_gHVUUzptSn.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_gHVUUzptSn.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_gHVUUzptSn.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_gY_gg0csJG.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_gY_gg0csJG.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_gY_gg0csJG.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_gY_gg0csJG.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_iOtv5wnjYj.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_iOtv5wnjYj.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_iOtv5wnjYj.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_iOtv5wnjYj.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_n5I7D_9IS8.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_n5I7D_9IS8.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_n5I7D_9IS8.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_n5I7D_9IS8.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_oo3H-DV6Rs.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_oo3H-DV6Rs.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_oo3H-DV6Rs.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_oo3H-DV6Rs.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_vvgWkBjMLS.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_vvgWkBjMLS.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_vvgWkBjMLS.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_vvgWkBjMLS.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_ytgqm394It.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_ytgqm394It.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_ytgqm394It.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/4.\345\274\240\351\207\217\345\271\266\350\241\214/image/image_ytgqm394It.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/5.\345\272\217\345\210\227\345\271\266\350\241\214.md" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/5.\345\272\217\345\210\227\345\271\266\350\241\214.md" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/5.\345\272\217\345\210\227\345\271\266\350\241\214.md" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/5.\345\272\217\345\210\227\345\271\266\350\241\214.md" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_8D99dcO3UW.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_8D99dcO3UW.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_8D99dcO3UW.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_8D99dcO3UW.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_8o8tMFjMrJ.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_8o8tMFjMrJ.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_8o8tMFjMrJ.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_8o8tMFjMrJ.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_II8OK5PLXN.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_II8OK5PLXN.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_II8OK5PLXN.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_II8OK5PLXN.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_IcmPA4afgc.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_IcmPA4afgc.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_IcmPA4afgc.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_IcmPA4afgc.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_KY_hSeezc5.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_KY_hSeezc5.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_KY_hSeezc5.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_KY_hSeezc5.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_T5shdA4Vmm.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_T5shdA4Vmm.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_T5shdA4Vmm.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_T5shdA4Vmm.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_aTQUWGQQ90.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_aTQUWGQQ90.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_aTQUWGQQ90.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_aTQUWGQQ90.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_ftsDHEJpB3.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_ftsDHEJpB3.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_ftsDHEJpB3.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_ftsDHEJpB3.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_tkc2Nhn1RJ.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_tkc2Nhn1RJ.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_tkc2Nhn1RJ.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/5.\345\272\217\345\210\227\345\271\266\350\241\214/image/image_tkc2Nhn1RJ.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214.md" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214.md" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214.md" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214.md" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_9MhlIzGPSn.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_9MhlIzGPSn.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_9MhlIzGPSn.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_9MhlIzGPSn.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_YtAUDmNynT.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_YtAUDmNynT.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_YtAUDmNynT.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_YtAUDmNynT.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_bUIvBaOcRU.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_bUIvBaOcRU.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_bUIvBaOcRU.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_bUIvBaOcRU.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_hSdhjiBAKu.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_hSdhjiBAKu.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_hSdhjiBAKu.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_hSdhjiBAKu.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_k9CHrkio0V.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_k9CHrkio0V.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_k9CHrkio0V.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_k9CHrkio0V.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_nW2idHS-Lv.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_nW2idHS-Lv.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_nW2idHS-Lv.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_nW2idHS-Lv.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_rDgAztG68n.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_rDgAztG68n.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_rDgAztG68n.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_rDgAztG68n.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_t-u4XUpBo6.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_t-u4XUpBo6.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_t-u4XUpBo6.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_t-u4XUpBo6.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_xXH59JVt51.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_xXH59JVt51.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_xXH59JVt51.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/6.\345\244\232\347\273\264\345\272\246\346\267\267\345\220\210\345\271\266\350\241\214/image/image_xXH59JVt51.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/7.\350\207\252\345\212\250\345\271\266\350\241\214.md" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/7.\350\207\252\345\212\250\345\271\266\350\241\214.md" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/7.\350\207\252\345\212\250\345\271\266\350\241\214.md" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/7.\350\207\252\345\212\250\345\271\266\350\241\214.md" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_5wizpAjTVy.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_5wizpAjTVy.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_5wizpAjTVy.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_5wizpAjTVy.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_DhJ7JXYshm.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_DhJ7JXYshm.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_DhJ7JXYshm.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_DhJ7JXYshm.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_V_V_cu5gO7.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_V_V_cu5gO7.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_V_V_cu5gO7.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_V_V_cu5gO7.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_da7Gv3tpI7.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_da7Gv3tpI7.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_da7Gv3tpI7.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_da7Gv3tpI7.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_kJbRmn0uFd.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_kJbRmn0uFd.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_kJbRmn0uFd.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/7.\350\207\252\345\212\250\345\271\266\350\241\214/image/image_kJbRmn0uFd.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/8.moe\345\271\266\350\241\214.md" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/8.moe\345\271\266\350\241\214.md" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/8.moe\345\271\266\350\241\214.md" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/8.moe\345\271\266\350\241\214.md" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_CdnJaFJ-Sh.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_CdnJaFJ-Sh.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_CdnJaFJ-Sh.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_CdnJaFJ-Sh.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_JsKarTYofS.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_JsKarTYofS.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_JsKarTYofS.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_JsKarTYofS.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_LExU0lecXc.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_LExU0lecXc.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_LExU0lecXc.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_LExU0lecXc.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_LSI5n4Y_Cq.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_LSI5n4Y_Cq.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_LSI5n4Y_Cq.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_LSI5n4Y_Cq.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_TddAwpvHh4.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_TddAwpvHh4.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_TddAwpvHh4.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_TddAwpvHh4.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_bWbypkNk_f.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_bWbypkNk_f.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_bWbypkNk_f.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_bWbypkNk_f.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_c_hTTNj7-H.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_c_hTTNj7-H.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_c_hTTNj7-H.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_c_hTTNj7-H.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_o3KIpJmYzl.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_o3KIpJmYzl.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_o3KIpJmYzl.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_o3KIpJmYzl.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_qm5G_4eA9V.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_qm5G_4eA9V.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_qm5G_4eA9V.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/8.moe\345\271\266\350\241\214/image/image_qm5G_4eA9V.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/9.\346\200\273\347\273\223.md" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/9.\346\200\273\347\273\223.md" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/9.\346\200\273\347\273\223.md" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/9.\346\200\273\347\273\223.md" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_8nyg8mqBrr.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_8nyg8mqBrr.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_8nyg8mqBrr.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_8nyg8mqBrr.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_9pBuigB0k8.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_9pBuigB0k8.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_9pBuigB0k8.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_9pBuigB0k8.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_DvKxtx6ViN.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_DvKxtx6ViN.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_DvKxtx6ViN.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_DvKxtx6ViN.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_FX7c6wd2j8.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_FX7c6wd2j8.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_FX7c6wd2j8.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_FX7c6wd2j8.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_VgaXqNEAjT.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_VgaXqNEAjT.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_VgaXqNEAjT.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_VgaXqNEAjT.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_wV4LQK36sl.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_wV4LQK36sl.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_wV4LQK36sl.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/9.\346\200\273\347\273\223/image/image_wV4LQK36sl.png" diff --git "a/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/README.md" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/README.md" new file mode 100644 index 0000000..780c89c --- /dev/null +++ "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/README.md" @@ -0,0 +1,44 @@ +# 04.分布式训练 + +### 4.1 基础知识 + +[1.概述](/docs/04.分布式训练/1.概述/1.概述.md "1.概述") + +[2.数据并行](/docs/04.分布式训练/2.数据并行/2.数据并行.md "2.数据并行") + +[3.流水线并行](/docs/04.分布式训练/3.流水线并行/3.流水线并行.md "3.流水线并行") + +[4.张量并行](/docs/04.分布式训练/4.张量并行/4.张量并行.md "4.张量并行") + +[5.序列并行](/docs/04.分布式训练/5.序列并行/5.序列并行.md "5.序列并行") + +[6.多维度混合并行](/docs/04.分布式训练/6.多维度混合并行/6.多维度混合并行.md "6.多维度混合并行") + +[7.自动并行](/docs/04.分布式训练/7.自动并行/7.自动并行.md "7.自动并行") + +[8.moe并行](/docs/04.分布式训练/8.moe并行/8.moe并行.md "8.moe并行") + +[9.总结](/docs/04.分布式训练/9.总结/9.总结.md "9.总结") + +### 4.2 DeepSpeed + +[deepspeed介绍](/docs/04.分布式训练/deepspeed介绍/deepspeed介绍.md "deepspeed介绍") + +### 4.3 Megatron + +### 4.4 训练加速 + +### 4.5 一些有用的文章 + + +### 4.6 一些题目 + +[1.分布式训练题目](/docs/04.分布式训练/分布式训练题目/分布式训练题目.md "分布式训练题目") +[2.显存问题](/docs/04.分布式训练/1.显存问题/1.显存问题.md "1.显存问题") + +### 4.7 参考资料: + +- [大模型分布式训练并行技术(九)-总结 - 掘金 (juejin.cn)](https://juejin.cn/post/7290740395913969705 "大模型分布式训练并行技术(九)-总结 - 掘金 (juejin.cn)") +- [https://www.zhangzhenhu.com/deepspeed/index.html](https://www.zhangzhenhu.com/deepspeed/index.html "https://www.zhangzhenhu.com/deepspeed/index.html") +- [https://blog.csdn.net/zwqjoy/article/details/130732601](https://blog.csdn.net/zwqjoy/article/details/130732601 "https://blog.csdn.net/zwqjoy/article/details/130732601") +- [https://techdiylife.github.io/](https://techdiylife.github.io/ "https://techdiylife.github.io/") diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/deepspeed\344\273\213\347\273\215.md" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/deepspeed\344\273\213\347\273\215.md" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/deepspeed\344\273\213\347\273\215.md" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/deepspeed\344\273\213\347\273\215.md" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_6GC207ZU3O.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_6GC207ZU3O.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_6GC207ZU3O.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_6GC207ZU3O.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_B3Zt993aVo.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_B3Zt993aVo.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_B3Zt993aVo.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_B3Zt993aVo.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_JxB5Yju8gj.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_JxB5Yju8gj.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_JxB5Yju8gj.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_JxB5Yju8gj.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_UKoVaOXc-2.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_UKoVaOXc-2.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_UKoVaOXc-2.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_UKoVaOXc-2.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_XNjij0Z1Dh.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_XNjij0Z1Dh.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_XNjij0Z1Dh.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_XNjij0Z1Dh.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_cPVZ4KEjJ0.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_cPVZ4KEjJ0.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_cPVZ4KEjJ0.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_cPVZ4KEjJ0.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_hKE_Xt759j.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_hKE_Xt759j.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_hKE_Xt759j.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_hKE_Xt759j.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_l1dkF_7Tg7.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_l1dkF_7Tg7.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_l1dkF_7Tg7.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_l1dkF_7Tg7.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_pcdg2zZLBJ.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_pcdg2zZLBJ.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_pcdg2zZLBJ.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_pcdg2zZLBJ.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_psVU2KOWUS.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_psVU2KOWUS.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_psVU2KOWUS.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_psVU2KOWUS.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_tOHRS0iiUq.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_tOHRS0iiUq.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_tOHRS0iiUq.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_tOHRS0iiUq.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_vfi8OaGD7t.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_vfi8OaGD7t.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_vfi8OaGD7t.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/deepspeed\344\273\213\347\273\215/image/image_vfi8OaGD7t.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_-29OJSsEGa.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_-29OJSsEGa.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_-29OJSsEGa.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_-29OJSsEGa.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_03vp-6qX4J.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_03vp-6qX4J.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_03vp-6qX4J.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_03vp-6qX4J.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_JxcNXXGEhW.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_JxcNXXGEhW.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_JxcNXXGEhW.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_JxcNXXGEhW.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_Z-oZkXy20K.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_Z-oZkXy20K.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_Z-oZkXy20K.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_Z-oZkXy20K.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_oVkpJgjyas.png" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_oVkpJgjyas.png" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_oVkpJgjyas.png" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/image/image_oVkpJgjyas.png" diff --git "a/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256.md" "b/docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256.md" similarity index 100% rename from "04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256.md" rename to "docs/04.\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203\351\242\230\347\233\256.md" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/1.\345\237\272\346\234\254\346\246\202\345\277\265/1.\345\237\272\346\234\254\346\246\202\345\277\265.md" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/1.\345\237\272\346\234\254\346\246\202\345\277\265/1.\345\237\272\346\234\254\346\246\202\345\277\265.md" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/1.\345\237\272\346\234\254\346\246\202\345\277\265/1.\345\237\272\346\234\254\346\246\202\345\277\265.md" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/1.\345\237\272\346\234\254\346\246\202\345\277\265/1.\345\237\272\346\234\254\346\246\202\345\277\265.md" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/1.\345\237\272\346\234\254\346\246\202\345\277\265/image/image_PqXGwJv0Yq.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/1.\345\237\272\346\234\254\346\246\202\345\277\265/image/image_PqXGwJv0Yq.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/1.\345\237\272\346\234\254\346\246\202\345\277\265/image/image_PqXGwJv0Yq.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/1.\345\237\272\346\234\254\346\246\202\345\277\265/image/image_PqXGwJv0Yq.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/1.\345\276\256\350\260\203/1.\345\276\256\350\260\203.md" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/1.\345\276\256\350\260\203/1.\345\276\256\350\260\203.md" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/1.\345\276\256\350\260\203/1.\345\276\256\350\260\203.md" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/1.\345\276\256\350\260\203/1.\345\276\256\350\260\203.md" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/2.prompting.md" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/2.prompting.md" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/2.prompting.md" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/2.prompting.md" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_40NqpUES_a.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_40NqpUES_a.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_40NqpUES_a.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_40NqpUES_a.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_HpSoIk-rby.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_HpSoIk-rby.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_HpSoIk-rby.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_HpSoIk-rby.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_JK_NJWljAf.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_JK_NJWljAf.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_JK_NJWljAf.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_JK_NJWljAf.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_MvDVFdIXHx.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_MvDVFdIXHx.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_MvDVFdIXHx.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_MvDVFdIXHx.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_N0GynKSsYv.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_N0GynKSsYv.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_N0GynKSsYv.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_N0GynKSsYv.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_O1ohhtRoJK.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_O1ohhtRoJK.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_O1ohhtRoJK.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_O1ohhtRoJK.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_ODPDxLZXxv.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_ODPDxLZXxv.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_ODPDxLZXxv.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_ODPDxLZXxv.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_PK_6ja6ned.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_PK_6ja6ned.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_PK_6ja6ned.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_PK_6ja6ned.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_VPGeRtHSHY.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_VPGeRtHSHY.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_VPGeRtHSHY.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_VPGeRtHSHY.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_WIlIO26MUO.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_WIlIO26MUO.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_WIlIO26MUO.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_WIlIO26MUO.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_i-HuMOEtLN.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_i-HuMOEtLN.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_i-HuMOEtLN.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_i-HuMOEtLN.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_jRBYNUfmgf.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_jRBYNUfmgf.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_jRBYNUfmgf.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_jRBYNUfmgf.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_pd__nPs1DJ.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_pd__nPs1DJ.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_pd__nPs1DJ.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_pd__nPs1DJ.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_qgUAP0-443.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_qgUAP0-443.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_qgUAP0-443.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_qgUAP0-443.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_x-N9DXN9zx.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_x-N9DXN9zx.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_x-N9DXN9zx.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_x-N9DXN9zx.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_xEZzrN6jDv.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_xEZzrN6jDv.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_xEZzrN6jDv.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_xEZzrN6jDv.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_xXFqsk5IDJ.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_xXFqsk5IDJ.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_xXFqsk5IDJ.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_xXFqsk5IDJ.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_xcPTOrFxnQ.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_xcPTOrFxnQ.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_xcPTOrFxnQ.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.prompting/image/image_xcPTOrFxnQ.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.\351\242\204\350\256\255\347\273\203/2.\351\242\204\350\256\255\347\273\203.md" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.\351\242\204\350\256\255\347\273\203/2.\351\242\204\350\256\255\347\273\203.md" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.\351\242\204\350\256\255\347\273\203/2.\351\242\204\350\256\255\347\273\203.md" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/2.\351\242\204\350\256\255\347\273\203/2.\351\242\204\350\256\255\347\273\203.md" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/3.adapter-tuning.md" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/3.adapter-tuning.md" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/3.adapter-tuning.md" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/3.adapter-tuning.md" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_AD8nf5WyYR.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_AD8nf5WyYR.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_AD8nf5WyYR.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_AD8nf5WyYR.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_FlW55afpev.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_FlW55afpev.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_FlW55afpev.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_FlW55afpev.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_KqgaVNKyyA.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_KqgaVNKyyA.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_KqgaVNKyyA.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_KqgaVNKyyA.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_TrTIVIkHDz.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_TrTIVIkHDz.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_TrTIVIkHDz.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_TrTIVIkHDz.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_f78QMCCpBc.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_f78QMCCpBc.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_f78QMCCpBc.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_f78QMCCpBc.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_h1awQjoF6t.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_h1awQjoF6t.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_h1awQjoF6t.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_h1awQjoF6t.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_h7IGbTA3iH.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_h7IGbTA3iH.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_h7IGbTA3iH.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_h7IGbTA3iH.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_hGPuAhOYuq.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_hGPuAhOYuq.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_hGPuAhOYuq.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_hGPuAhOYuq.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_kTcNXvJ9RT.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_kTcNXvJ9RT.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_kTcNXvJ9RT.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_kTcNXvJ9RT.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_mUOiCXDkjL.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_mUOiCXDkjL.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_mUOiCXDkjL.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_mUOiCXDkjL.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_xHc-uesXd_.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_xHc-uesXd_.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_xHc-uesXd_.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_xHc-uesXd_.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_xR-SApNHn1.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_xR-SApNHn1.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_xR-SApNHn1.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/3.adapter-tuning/image/image_xR-SApNHn1.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/4.lora.md" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/4.lora.md" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/4.lora.md" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/4.lora.md" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_I4VgYdpjtc.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_I4VgYdpjtc.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_I4VgYdpjtc.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_I4VgYdpjtc.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_NlJY_w8Q3W.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_NlJY_w8Q3W.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_NlJY_w8Q3W.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_NlJY_w8Q3W.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_RyVh3u4p_e.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_RyVh3u4p_e.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_RyVh3u4p_e.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_RyVh3u4p_e.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_aqEEQ1KNX4.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_aqEEQ1KNX4.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_aqEEQ1KNX4.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_aqEEQ1KNX4.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_dgpQtBqmep.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_dgpQtBqmep.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_dgpQtBqmep.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_dgpQtBqmep.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_iOCK44hl6e.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_iOCK44hl6e.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_iOCK44hl6e.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_iOCK44hl6e.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_ndRpdEuBE2.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_ndRpdEuBE2.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_ndRpdEuBE2.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_ndRpdEuBE2.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_s4J7mHZiOj.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_s4J7mHZiOj.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_s4J7mHZiOj.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_s4J7mHZiOj.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_yEs0Aj_qVa.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_yEs0Aj_qVa.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_yEs0Aj_qVa.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/4.lora/image/image_yEs0Aj_qVa.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/5.\346\200\273\347\273\223/5.\346\200\273\347\273\223.md" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/5.\346\200\273\347\273\223/5.\346\200\273\347\273\223.md" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/5.\346\200\273\347\273\223/5.\346\200\273\347\273\223.md" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/5.\346\200\273\347\273\223/5.\346\200\273\347\273\223.md" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/5.\346\200\273\347\273\223/image/image_7LM4US2NjM.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/5.\346\200\273\347\273\223/image/image_7LM4US2NjM.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/5.\346\200\273\347\273\223/image/image_7LM4US2NjM.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/5.\346\200\273\347\273\223/image/image_7LM4US2NjM.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/5.\346\200\273\347\273\223/image/image_CfaWo0sE3k.png" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/5.\346\200\273\347\273\223/image/image_CfaWo0sE3k.png" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/5.\346\200\273\347\273\223/image/image_CfaWo0sE3k.png" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/5.\346\200\273\347\273\223/image/image_CfaWo0sE3k.png" diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/ChatGLM3\345\276\256\350\260\203/ChatGLM3\345\276\256\350\260\203.md" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/ChatGLM3\345\276\256\350\260\203/ChatGLM3\345\276\256\350\260\203.md" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/ChatGLM3\345\276\256\350\260\203/ChatGLM3\345\276\256\350\260\203.md" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/ChatGLM3\345\276\256\350\260\203/ChatGLM3\345\276\256\350\260\203.md" diff --git "a/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/README.md" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/README.md" new file mode 100644 index 0000000..9b4ae0b --- /dev/null +++ "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/README.md" @@ -0,0 +1,29 @@ +# 05.有监督微调 + +### 5.1 理论 + +[1.基本概念](/docs/05.有监督微调/1.基本概念/1.基本概念.md "1.基本概念") + +[2.prompting](/docs/05.有监督微调/2.prompting/2.prompting.md "2.prompting") + +[3.adapter-tuning](/docs/05.有监督微调/3.adapter-tuning/3.adapter-tuning.md "3.adapter-tuning") + +[4.lora](/docs/05.有监督微调/4.lora/4.lora.md "4.lora") + +[5.总结](/docs/05.有监督微调/5.总结/5.总结.md "5.总结") + +### 5.2 微调实战 + +[llama2微调](/docs/05.有监督微调/llama2微调/llama2微调.md "llama2微调") + +[ChatGLM3微调](/docs/05.有监督微调/ChatGLM3微调/ChatGLM3微调.md "ChatGLM3微调") + +### 5.3 一些题目 + +[1.微调](/docs/05.有监督微调/1.微调/1.微调.md "1.微调") + +[2.预训练](/docs/05.有监督微调/2.预训练/2.预训练.md "2.预训练") + +参考资料: + +- [liguodongiot/llm-action](https://github.com/liguodongiot/llm-action#llm微调实战 "liguodongiot/llm-action") diff --git "a/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/llama2\345\276\256\350\260\203/llama2\345\276\256\350\260\203.md" "b/docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/llama2\345\276\256\350\260\203/llama2\345\276\256\350\260\203.md" similarity index 100% rename from "05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/llama2\345\276\256\350\260\203/llama2\345\276\256\350\260\203.md" rename to "docs/05.\346\234\211\347\233\221\347\235\243\345\276\256\350\260\203/llama2\345\276\256\350\260\203/llama2\345\276\256\350\260\203.md" diff --git "a/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223.md" "b/docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223.md" similarity index 100% rename from "06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223.md" rename to "docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223.md" diff --git "a/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_-4q1hcUFNC.png" "b/docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_-4q1hcUFNC.png" similarity index 100% rename from "06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_-4q1hcUFNC.png" rename to "docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_-4q1hcUFNC.png" diff --git "a/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_0tYQQi0d38.png" "b/docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_0tYQQi0d38.png" similarity index 100% rename from "06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_0tYQQi0d38.png" rename to "docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_0tYQQi0d38.png" diff --git "a/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_4PUIvOuxYJ.png" "b/docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_4PUIvOuxYJ.png" similarity index 100% rename from "06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_4PUIvOuxYJ.png" rename to "docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_4PUIvOuxYJ.png" diff --git "a/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_A8QWAxUwiX.png" "b/docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_A8QWAxUwiX.png" similarity index 100% rename from "06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_A8QWAxUwiX.png" rename to "docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_A8QWAxUwiX.png" diff --git "a/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_NcQrpxCKKJ.png" "b/docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_NcQrpxCKKJ.png" similarity index 100% rename from "06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_NcQrpxCKKJ.png" rename to "docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_NcQrpxCKKJ.png" diff --git "a/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_ObtMjeksgh.png" "b/docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_ObtMjeksgh.png" similarity index 100% rename from "06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_ObtMjeksgh.png" rename to "docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_ObtMjeksgh.png" diff --git "a/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_jmbBzze8w0.png" "b/docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_jmbBzze8w0.png" similarity index 100% rename from "06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_jmbBzze8w0.png" rename to "docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_jmbBzze8w0.png" diff --git "a/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_mLcwDUFp9R.png" "b/docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_mLcwDUFp9R.png" similarity index 100% rename from "06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_mLcwDUFp9R.png" rename to "docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_mLcwDUFp9R.png" diff --git "a/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_pgeMGVaXdP.png" "b/docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_pgeMGVaXdP.png" similarity index 100% rename from "06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_pgeMGVaXdP.png" rename to "docs/06.\346\216\250\347\220\206/0.llm\346\216\250\347\220\206\346\241\206\346\236\266\347\256\200\345\215\225\346\200\273\347\273\223/image/image_pgeMGVaXdP.png" diff --git "a/06.\346\216\250\347\220\206/1.vllm/1.vllm.md" "b/docs/06.\346\216\250\347\220\206/1.vllm/1.vllm.md" similarity index 100% rename from "06.\346\216\250\347\220\206/1.vllm/1.vllm.md" rename to "docs/06.\346\216\250\347\220\206/1.vllm/1.vllm.md" diff --git "a/06.\346\216\250\347\220\206/1.vllm/image/1f439e6b9c254b6ca05d6d5709f14cdb_4hDnK6oN0S.gif" "b/docs/06.\346\216\250\347\220\206/1.vllm/image/1f439e6b9c254b6ca05d6d5709f14cdb_4hDnK6oN0S.gif" similarity index 100% rename from "06.\346\216\250\347\220\206/1.vllm/image/1f439e6b9c254b6ca05d6d5709f14cdb_4hDnK6oN0S.gif" rename to "docs/06.\346\216\250\347\220\206/1.vllm/image/1f439e6b9c254b6ca05d6d5709f14cdb_4hDnK6oN0S.gif" diff --git "a/06.\346\216\250\347\220\206/1.vllm/image/image_BBZ2hh9Lav.png" "b/docs/06.\346\216\250\347\220\206/1.vllm/image/image_BBZ2hh9Lav.png" similarity index 100% rename from "06.\346\216\250\347\220\206/1.vllm/image/image_BBZ2hh9Lav.png" rename to "docs/06.\346\216\250\347\220\206/1.vllm/image/image_BBZ2hh9Lav.png" diff --git "a/06.\346\216\250\347\220\206/1.vllm/image/image_ESR74_rMSn.png" "b/docs/06.\346\216\250\347\220\206/1.vllm/image/image_ESR74_rMSn.png" similarity index 100% rename from "06.\346\216\250\347\220\206/1.vllm/image/image_ESR74_rMSn.png" rename to "docs/06.\346\216\250\347\220\206/1.vllm/image/image_ESR74_rMSn.png" diff --git "a/06.\346\216\250\347\220\206/1.vllm/image/image_RYxUlteK5J.png" "b/docs/06.\346\216\250\347\220\206/1.vllm/image/image_RYxUlteK5J.png" similarity index 100% rename from "06.\346\216\250\347\220\206/1.vllm/image/image_RYxUlteK5J.png" rename to "docs/06.\346\216\250\347\220\206/1.vllm/image/image_RYxUlteK5J.png" diff --git "a/06.\346\216\250\347\220\206/1.vllm/image/image_T52eX-wNY8.png" "b/docs/06.\346\216\250\347\220\206/1.vllm/image/image_T52eX-wNY8.png" similarity index 100% rename from "06.\346\216\250\347\220\206/1.vllm/image/image_T52eX-wNY8.png" rename to "docs/06.\346\216\250\347\220\206/1.vllm/image/image_T52eX-wNY8.png" diff --git "a/06.\346\216\250\347\220\206/1.vllm/image/image__ioNLXE-HA.png" "b/docs/06.\346\216\250\347\220\206/1.vllm/image/image__ioNLXE-HA.png" similarity index 100% rename from "06.\346\216\250\347\220\206/1.vllm/image/image__ioNLXE-HA.png" rename to "docs/06.\346\216\250\347\220\206/1.vllm/image/image__ioNLXE-HA.png" diff --git "a/06.\346\216\250\347\220\206/1.vllm/image/image_gUW-KvieFC.png" "b/docs/06.\346\216\250\347\220\206/1.vllm/image/image_gUW-KvieFC.png" similarity index 100% rename from "06.\346\216\250\347\220\206/1.vllm/image/image_gUW-KvieFC.png" rename to "docs/06.\346\216\250\347\220\206/1.vllm/image/image_gUW-KvieFC.png" diff --git "a/06.\346\216\250\347\220\206/1.vllm/image/image_qWFFhRttML.png" "b/docs/06.\346\216\250\347\220\206/1.vllm/image/image_qWFFhRttML.png" similarity index 100% rename from "06.\346\216\250\347\220\206/1.vllm/image/image_qWFFhRttML.png" rename to "docs/06.\346\216\250\347\220\206/1.vllm/image/image_qWFFhRttML.png" diff --git "a/06.\346\216\250\347\220\206/1.vllm/image/image_rWYMhe1AGh.png" "b/docs/06.\346\216\250\347\220\206/1.vllm/image/image_rWYMhe1AGh.png" similarity index 100% rename from "06.\346\216\250\347\220\206/1.vllm/image/image_rWYMhe1AGh.png" rename to "docs/06.\346\216\250\347\220\206/1.vllm/image/image_rWYMhe1AGh.png" diff --git "a/06.\346\216\250\347\220\206/1.\346\216\250\347\220\206/1.\346\216\250\347\220\206.md" "b/docs/06.\346\216\250\347\220\206/1.\346\216\250\347\220\206/1.\346\216\250\347\220\206.md" similarity index 100% rename from "06.\346\216\250\347\220\206/1.\346\216\250\347\220\206/1.\346\216\250\347\220\206.md" rename to "docs/06.\346\216\250\347\220\206/1.\346\216\250\347\220\206/1.\346\216\250\347\220\206.md" diff --git "a/06.\346\216\250\347\220\206/2.text_generation_inference/2.text_generation_inference.md" "b/docs/06.\346\216\250\347\220\206/2.text_generation_inference/2.text_generation_inference.md" similarity index 100% rename from "06.\346\216\250\347\220\206/2.text_generation_inference/2.text_generation_inference.md" rename to "docs/06.\346\216\250\347\220\206/2.text_generation_inference/2.text_generation_inference.md" diff --git "a/06.\346\216\250\347\220\206/2.text_generation_inference/image/image_NpwIlkJUHn.png" "b/docs/06.\346\216\250\347\220\206/2.text_generation_inference/image/image_NpwIlkJUHn.png" similarity index 100% rename from "06.\346\216\250\347\220\206/2.text_generation_inference/image/image_NpwIlkJUHn.png" rename to "docs/06.\346\216\250\347\220\206/2.text_generation_inference/image/image_NpwIlkJUHn.png" diff --git "a/06.\346\216\250\347\220\206/3.faster_transformer/3.faster_transformer.md" "b/docs/06.\346\216\250\347\220\206/3.faster_transformer/3.faster_transformer.md" similarity index 100% rename from "06.\346\216\250\347\220\206/3.faster_transformer/3.faster_transformer.md" rename to "docs/06.\346\216\250\347\220\206/3.faster_transformer/3.faster_transformer.md" diff --git "a/06.\346\216\250\347\220\206/3.faster_transformer/image/image_RP616Yf0XC.png" "b/docs/06.\346\216\250\347\220\206/3.faster_transformer/image/image_RP616Yf0XC.png" similarity index 100% rename from "06.\346\216\250\347\220\206/3.faster_transformer/image/image_RP616Yf0XC.png" rename to "docs/06.\346\216\250\347\220\206/3.faster_transformer/image/image_RP616Yf0XC.png" diff --git "a/06.\346\216\250\347\220\206/3.faster_transformer/image/image_bW89N6VXxa.png" "b/docs/06.\346\216\250\347\220\206/3.faster_transformer/image/image_bW89N6VXxa.png" similarity index 100% rename from "06.\346\216\250\347\220\206/3.faster_transformer/image/image_bW89N6VXxa.png" rename to "docs/06.\346\216\250\347\220\206/3.faster_transformer/image/image_bW89N6VXxa.png" diff --git "a/06.\346\216\250\347\220\206/4.trt_llm/4.trt_llm.md" "b/docs/06.\346\216\250\347\220\206/4.trt_llm/4.trt_llm.md" similarity index 100% rename from "06.\346\216\250\347\220\206/4.trt_llm/4.trt_llm.md" rename to "docs/06.\346\216\250\347\220\206/4.trt_llm/4.trt_llm.md" diff --git "a/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260.md" "b/docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260.md" similarity index 100% rename from "06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260.md" rename to "docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260.md" diff --git "a/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/640 (1)_5Y5ZVQhUfP.gif" "b/docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/640 (1)_5Y5ZVQhUfP.gif" similarity index 100% rename from "06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/640 (1)_5Y5ZVQhUfP.gif" rename to "docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/640 (1)_5Y5ZVQhUfP.gif" diff --git "a/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_5C0Ca7_5gB.png" "b/docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_5C0Ca7_5gB.png" similarity index 100% rename from "06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_5C0Ca7_5gB.png" rename to "docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_5C0Ca7_5gB.png" diff --git "a/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_7t_2F8_dv_.png" "b/docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_7t_2F8_dv_.png" similarity index 100% rename from "06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_7t_2F8_dv_.png" rename to "docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_7t_2F8_dv_.png" diff --git "a/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_BwNP8uWX2Z.png" "b/docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_BwNP8uWX2Z.png" similarity index 100% rename from "06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_BwNP8uWX2Z.png" rename to "docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_BwNP8uWX2Z.png" diff --git "a/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_EZwLm0WLPO.png" "b/docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_EZwLm0WLPO.png" similarity index 100% rename from "06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_EZwLm0WLPO.png" rename to "docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_EZwLm0WLPO.png" diff --git "a/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_LK3V11ETTY.png" "b/docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_LK3V11ETTY.png" similarity index 100% rename from "06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_LK3V11ETTY.png" rename to "docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_LK3V11ETTY.png" diff --git "a/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_owrlRKptiN.png" "b/docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_owrlRKptiN.png" similarity index 100% rename from "06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_owrlRKptiN.png" rename to "docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_owrlRKptiN.png" diff --git "a/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_pZHPwzdINM.png" "b/docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_pZHPwzdINM.png" similarity index 100% rename from "06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_pZHPwzdINM.png" rename to "docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_pZHPwzdINM.png" diff --git "a/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_qIo2XMf4Dy.png" "b/docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_qIo2XMf4Dy.png" similarity index 100% rename from "06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_qIo2XMf4Dy.png" rename to "docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_qIo2XMf4Dy.png" diff --git "a/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_wXqz37qjwH.png" "b/docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_wXqz37qjwH.png" similarity index 100% rename from "06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_wXqz37qjwH.png" rename to "docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_wXqz37qjwH.png" diff --git "a/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_zYlCHt9cls.png" "b/docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_zYlCHt9cls.png" similarity index 100% rename from "06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_zYlCHt9cls.png" rename to "docs/06.\346\216\250\347\220\206/LLM\346\216\250\347\220\206\345\270\270\350\247\201\345\217\202\346\225\260/image/image_zYlCHt9cls.png" diff --git "a/docs/06.\346\216\250\347\220\206/README.md" "b/docs/06.\346\216\250\347\220\206/README.md" new file mode 100644 index 0000000..4c7b111 --- /dev/null +++ "b/docs/06.\346\216\250\347\220\206/README.md" @@ -0,0 +1,27 @@ +# 06.推理 + +### 6.1 推理框架 + +[0.llm推理框架简单总结](/docs/06.推理/0.llm推理框架简单总结/0.llm推理框架简单总结.md "0.llm推理框架简单总结") + +[1.vllm](/docs/06.推理/1.vllm/1.vllm.md "1.vllm") + +[2.text_generation\_inference](/docs/06.推理/2.text_generation_inference/2.text_generation_inference.md "2.text_generation_inference") + +[3.faster_transformer](/docs/06.推理/3.faster_transformer/3.faster_transformer.md "3.faster_transformer") + +[4.trt_llm](/docs/06.推理/4.trt_llm/4.trt_llm.md "4.trt_llm") + +### 6.2 推理优化技术 + +[llm推理优化技术](/docs/06.推理/llm推理优化技术/llm推理优化技术.md "llm推理优化技术") + +### 6.3 量化 + + +### 6.4 vLLM + + +### 6.5 一些题目 + +[1.推理](/docs/06.推理/1.推理/1.推理.md "1.推理") diff --git "a/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_AEKiGYL_qQ.png" "b/docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_AEKiGYL_qQ.png" similarity index 100% rename from "06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_AEKiGYL_qQ.png" rename to "docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_AEKiGYL_qQ.png" diff --git "a/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_AGCdnhUzLr.png" "b/docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_AGCdnhUzLr.png" similarity index 100% rename from "06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_AGCdnhUzLr.png" rename to "docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_AGCdnhUzLr.png" diff --git "a/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_BNdLa1BC7X.png" "b/docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_BNdLa1BC7X.png" similarity index 100% rename from "06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_BNdLa1BC7X.png" rename to "docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_BNdLa1BC7X.png" diff --git "a/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_FcaaSJJ5h_.png" "b/docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_FcaaSJJ5h_.png" similarity index 100% rename from "06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_FcaaSJJ5h_.png" rename to "docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_FcaaSJJ5h_.png" diff --git "a/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_Jh1fTO1EPP.png" "b/docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_Jh1fTO1EPP.png" similarity index 100% rename from "06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_Jh1fTO1EPP.png" rename to "docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_Jh1fTO1EPP.png" diff --git "a/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_LscREP6Kiz.png" "b/docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_LscREP6Kiz.png" similarity index 100% rename from "06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_LscREP6Kiz.png" rename to "docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_LscREP6Kiz.png" diff --git "a/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_OLpAPEiij9.png" "b/docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_OLpAPEiij9.png" similarity index 100% rename from "06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_OLpAPEiij9.png" rename to "docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_OLpAPEiij9.png" diff --git "a/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_QafcBySU-O.png" "b/docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_QafcBySU-O.png" similarity index 100% rename from "06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_QafcBySU-O.png" rename to "docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_QafcBySU-O.png" diff --git "a/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_VVO18J1gRS.png" "b/docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_VVO18J1gRS.png" similarity index 100% rename from "06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_VVO18J1gRS.png" rename to "docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_VVO18J1gRS.png" diff --git "a/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_lFEkt_VJOw.png" "b/docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_lFEkt_VJOw.png" similarity index 100% rename from "06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_lFEkt_VJOw.png" rename to "docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_lFEkt_VJOw.png" diff --git "a/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_pbAdMKk9tF.png" "b/docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_pbAdMKk9tF.png" similarity index 100% rename from "06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_pbAdMKk9tF.png" rename to "docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_pbAdMKk9tF.png" diff --git "a/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_uNjDdIhbrf.png" "b/docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_uNjDdIhbrf.png" similarity index 100% rename from "06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_uNjDdIhbrf.png" rename to "docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_uNjDdIhbrf.png" diff --git "a/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_zE-LAHnZ8C.png" "b/docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_zE-LAHnZ8C.png" similarity index 100% rename from "06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_zE-LAHnZ8C.png" rename to "docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/image/image_zE-LAHnZ8C.png" diff --git "a/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257.md" "b/docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257.md" similarity index 100% rename from "06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257.md" rename to "docs/06.\346\216\250\347\220\206/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257/llm\346\216\250\347\220\206\344\274\230\345\214\226\346\212\200\346\234\257.md" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/1.rlhf\347\233\270\345\205\263.md" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/1.rlhf\347\233\270\345\205\263.md" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/1.rlhf\347\233\270\345\205\263.md" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/1.rlhf\347\233\270\345\205\263.md" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_F6htmyYmr5.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_F6htmyYmr5.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_F6htmyYmr5.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_F6htmyYmr5.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_MIj6kv8upk.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_MIj6kv8upk.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_MIj6kv8upk.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_MIj6kv8upk.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_RJiT_yjAHw.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_RJiT_yjAHw.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_RJiT_yjAHw.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_RJiT_yjAHw.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_dE5qlpLKWz.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_dE5qlpLKWz.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_dE5qlpLKWz.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_dE5qlpLKWz.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_jidKpQWvRQ.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_jidKpQWvRQ.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_jidKpQWvRQ.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/1.rlhf\347\233\270\345\205\263/image/image_jidKpQWvRQ.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/2.\345\274\272\345\214\226\345\255\246\344\271\240/2.\345\274\272\345\214\226\345\255\246\344\271\240.md" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/2.\345\274\272\345\214\226\345\255\246\344\271\240/2.\345\274\272\345\214\226\345\255\246\344\271\240.md" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/2.\345\274\272\345\214\226\345\255\246\344\271\240/2.\345\274\272\345\214\226\345\255\246\344\271\240.md" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/2.\345\274\272\345\214\226\345\255\246\344\271\240/2.\345\274\272\345\214\226\345\255\246\344\271\240.md" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/DPO.md" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/DPO.md" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/DPO.md" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/DPO.md" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/image/image_lGnkS89SGZ.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/image/image_lGnkS89SGZ.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/image/image_lGnkS89SGZ.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/image/image_lGnkS89SGZ.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/image/image_okPAsQWVne.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/image/image_okPAsQWVne.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/image/image_okPAsQWVne.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/image/image_okPAsQWVne.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/image/image_udA7tRUhZv.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/image/image_udA7tRUhZv.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/image/image_udA7tRUhZv.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/DPO/image/image_udA7tRUhZv.png" diff --git "a/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/README.md" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/README.md" new file mode 100644 index 0000000..af81f3a --- /dev/null +++ "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/README.md" @@ -0,0 +1,21 @@ +# 07.强化学习 + +### 7.1 强化学习原理 + +[策略梯度(pg)](/docs/07.强化学习/策略梯度(pg)/策略梯度(pg).md "策略梯度(pg)") + +[近端策略优化(ppo)](/docs/07.强化学习/近端策略优化(ppo)/近端策略优化(ppo).md "近端策略优化(ppo)") + +### 7.2 RLHF + +[大模型RLHF:PPO原理与源码解读](/docs/07.强化学习/大模型RLHF:PPO原理与源码解读/大模型RLHF:PPO原理与源码解读.md "大模型RLHF:PPO原理与源码解读") + +[DPO](/docs/07.强化学习/DPO/DPO.md "DPO") + +### 7.3 一些题目 + +[1.rlhf相关](/docs/07.强化学习/1.rlhf相关/1.rlhf相关.md "1.rlhf相关") + +[2.强化学习](/docs/07.强化学习/2.强化学习/2.强化学习.md "2.强化学习") + + diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_ERN1ZS1gIZ.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_ERN1ZS1gIZ.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_ERN1ZS1gIZ.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_ERN1ZS1gIZ.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_S7YG1wh9l5.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_S7YG1wh9l5.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_S7YG1wh9l5.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_S7YG1wh9l5.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_UJo5yV8oUe.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_UJo5yV8oUe.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_UJo5yV8oUe.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_UJo5yV8oUe.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_WbUpMYZf_9.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_WbUpMYZf_9.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_WbUpMYZf_9.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_WbUpMYZf_9.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_Wp-x1ChMJK.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_Wp-x1ChMJK.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_Wp-x1ChMJK.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_Wp-x1ChMJK.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image__amAsvnuon.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image__amAsvnuon.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image__amAsvnuon.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image__amAsvnuon.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_keCqxZ7eg6.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_keCqxZ7eg6.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_keCqxZ7eg6.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_keCqxZ7eg6.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_nlFESPCvlS.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_nlFESPCvlS.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_nlFESPCvlS.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_nlFESPCvlS.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_ydA_4yGRGK.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_ydA_4yGRGK.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_ydA_4yGRGK.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/image/image_ydA_4yGRGK.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273.md" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273.md" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273.md" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273/\345\244\247\346\250\241\345\236\213RLHF\357\274\232PPO\345\216\237\347\220\206\344\270\216\346\272\220\347\240\201\350\247\243\350\257\273.md" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211/image/image_2MO52E-p2T.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211/image/image_2MO52E-p2T.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211/image/image_2MO52E-p2T.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211/image/image_2MO52E-p2T.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211/image/image_UxS2qchMFr.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211/image/image_UxS2qchMFr.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211/image/image_UxS2qchMFr.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211/image/image_UxS2qchMFr.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211.md" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211.md" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211.md" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211/\347\255\226\347\225\245\346\242\257\345\272\246\357\274\210pg\357\274\211.md" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo)/image/image_JE9uuZbeIs.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo)/image/image_JE9uuZbeIs.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo)/image/image_JE9uuZbeIs.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo)/image/image_JE9uuZbeIs.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo)/image/image_ttC1i0sOdU.png" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo)/image/image_ttC1i0sOdU.png" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo)/image/image_ttC1i0sOdU.png" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo)/image/image_ttC1i0sOdU.png" diff --git "a/07.\345\274\272\345\214\226\345\255\246\344\271\240/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo)/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo).md" "b/docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo)/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo).md" similarity index 100% rename from "07.\345\274\272\345\214\226\345\255\246\344\271\240/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo)/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo).md" rename to "docs/07.\345\274\272\345\214\226\345\255\246\344\271\240/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo)/\350\277\221\347\253\257\347\255\226\347\225\245\344\274\230\345\214\226(ppo).md" diff --git "a/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/README.md" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/README.md" new file mode 100644 index 0000000..aa8764c --- /dev/null +++ "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/README.md" @@ -0,0 +1,13 @@ +# 08.检索增强rag + +### 8.1 RAG + +[检索增强llm](/docs/08.检索增强rag/检索增强llm/检索增强llm.md "检索增强llm") + +[rag(检索增强生成)技术](/docs/08.检索增强rag/rag(检索增强生成)技术/rag(检索增强生成)技术.md "rag(检索增强生成)技术") + + + +### 8.2 Agent + +[大模型agent技术](/docs/08.检索增强rag/大模型agent技术/大模型agent技术.md "大模型agent技术") diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/image/image_C5NZymFSB9.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/image/image_C5NZymFSB9.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/image/image_C5NZymFSB9.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/image/image_C5NZymFSB9.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/image/image_iDQkbM_wzA.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/image/image_iDQkbM_wzA.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/image/image_iDQkbM_wzA.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/image/image_iDQkbM_wzA.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/image/lr3r0h6wjf_GML_ChOo9a.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/image/lr3r0h6wjf_GML_ChOo9a.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/image/lr3r0h6wjf_GML_ChOo9a.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/image/lr3r0h6wjf_GML_ChOo9a.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257.md" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257.md" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257.md" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257/rag\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211\346\212\200\346\234\257.md" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_-Wo-hu4jsx.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_-Wo-hu4jsx.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_-Wo-hu4jsx.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_-Wo-hu4jsx.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_0BZoHz0Hrm.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_0BZoHz0Hrm.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_0BZoHz0Hrm.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_0BZoHz0Hrm.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_0JLHH-D-FN.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_0JLHH-D-FN.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_0JLHH-D-FN.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_0JLHH-D-FN.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_0hyhpjiWKv.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_0hyhpjiWKv.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_0hyhpjiWKv.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_0hyhpjiWKv.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_1M8rS1UT_l.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_1M8rS1UT_l.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_1M8rS1UT_l.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_1M8rS1UT_l.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_1UFjkrnSoS.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_1UFjkrnSoS.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_1UFjkrnSoS.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_1UFjkrnSoS.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_4y9uVeKOTM.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_4y9uVeKOTM.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_4y9uVeKOTM.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_4y9uVeKOTM.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_545sPcH3Oc.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_545sPcH3Oc.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_545sPcH3Oc.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_545sPcH3Oc.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_6ySrlsmQ1I.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_6ySrlsmQ1I.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_6ySrlsmQ1I.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_6ySrlsmQ1I.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_8AUtnAVDXt.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_8AUtnAVDXt.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_8AUtnAVDXt.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_8AUtnAVDXt.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_8k9yh5KNYP.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_8k9yh5KNYP.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_8k9yh5KNYP.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_8k9yh5KNYP.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_9Oj8Viy2wS.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_9Oj8Viy2wS.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_9Oj8Viy2wS.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_9Oj8Viy2wS.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_AGC6Y2Fi25.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_AGC6Y2Fi25.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_AGC6Y2Fi25.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_AGC6Y2Fi25.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_ASnyOENkwT.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_ASnyOENkwT.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_ASnyOENkwT.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_ASnyOENkwT.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_BVOKvqfvZK.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_BVOKvqfvZK.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_BVOKvqfvZK.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_BVOKvqfvZK.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_DE6JiATALk.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_DE6JiATALk.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_DE6JiATALk.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_DE6JiATALk.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_DWEmuNMdTp.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_DWEmuNMdTp.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_DWEmuNMdTp.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_DWEmuNMdTp.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_E2RLxZnVCL.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_E2RLxZnVCL.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_E2RLxZnVCL.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_E2RLxZnVCL.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_EHZWvfuQi5.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_EHZWvfuQi5.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_EHZWvfuQi5.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_EHZWvfuQi5.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_F0Z_rNC5Z5.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_F0Z_rNC5Z5.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_F0Z_rNC5Z5.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_F0Z_rNC5Z5.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_FFLXEtjD3J.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_FFLXEtjD3J.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_FFLXEtjD3J.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_FFLXEtjD3J.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_FP7xAcdY7f.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_FP7xAcdY7f.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_FP7xAcdY7f.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_FP7xAcdY7f.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_FUi7ARKbxL.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_FUi7ARKbxL.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_FUi7ARKbxL.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_FUi7ARKbxL.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_GtGSSsOTAN.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_GtGSSsOTAN.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_GtGSSsOTAN.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_GtGSSsOTAN.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_Jf6uOCrHcl.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_Jf6uOCrHcl.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_Jf6uOCrHcl.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_Jf6uOCrHcl.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_K5LujQuc8H.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_K5LujQuc8H.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_K5LujQuc8H.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_K5LujQuc8H.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_K6fgkzCb8c.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_K6fgkzCb8c.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_K6fgkzCb8c.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_K6fgkzCb8c.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_LzR4KRX6Am.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_LzR4KRX6Am.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_LzR4KRX6Am.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_LzR4KRX6Am.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_M-018k1o7R.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_M-018k1o7R.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_M-018k1o7R.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_M-018k1o7R.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_NQYxr1JFU4.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_NQYxr1JFU4.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_NQYxr1JFU4.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_NQYxr1JFU4.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_NZsWVnUO94.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_NZsWVnUO94.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_NZsWVnUO94.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_NZsWVnUO94.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_O_XQx11f_b.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_O_XQx11f_b.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_O_XQx11f_b.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_O_XQx11f_b.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_Oc7QYPLdhZ.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_Oc7QYPLdhZ.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_Oc7QYPLdhZ.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_Oc7QYPLdhZ.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_Orv70B9vc8.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_Orv70B9vc8.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_Orv70B9vc8.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_Orv70B9vc8.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_QZ4n_GHunS.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_QZ4n_GHunS.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_QZ4n_GHunS.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_QZ4n_GHunS.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_S3Aas2H5u1.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_S3Aas2H5u1.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_S3Aas2H5u1.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_S3Aas2H5u1.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_UAuMnCapb-.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_UAuMnCapb-.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_UAuMnCapb-.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_UAuMnCapb-.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_V0xKeVhQOe.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_V0xKeVhQOe.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_V0xKeVhQOe.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_V0xKeVhQOe.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_VH5QXXd3Hp.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_VH5QXXd3Hp.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_VH5QXXd3Hp.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_VH5QXXd3Hp.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_VXkWhBOb1R.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_VXkWhBOb1R.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_VXkWhBOb1R.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_VXkWhBOb1R.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_XgsYXrJnkM.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_XgsYXrJnkM.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_XgsYXrJnkM.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_XgsYXrJnkM.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_ZqOLr2_7n6.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_ZqOLr2_7n6.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_ZqOLr2_7n6.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_ZqOLr2_7n6.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image__7tpxFnee0.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image__7tpxFnee0.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image__7tpxFnee0.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image__7tpxFnee0.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_aImEFclsmJ.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_aImEFclsmJ.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_aImEFclsmJ.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_aImEFclsmJ.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_fChgHErjqx.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_fChgHErjqx.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_fChgHErjqx.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_fChgHErjqx.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_h5ppzlGXZ6.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_h5ppzlGXZ6.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_h5ppzlGXZ6.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_h5ppzlGXZ6.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_hA9Jq9PVJD.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_hA9Jq9PVJD.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_hA9Jq9PVJD.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_hA9Jq9PVJD.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_imO1sW7q-G.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_imO1sW7q-G.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_imO1sW7q-G.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_imO1sW7q-G.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_j44u5GwFp6.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_j44u5GwFp6.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_j44u5GwFp6.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_j44u5GwFp6.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_kC58JNzXrW.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_kC58JNzXrW.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_kC58JNzXrW.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_kC58JNzXrW.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_kT9oErCPEL.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_kT9oErCPEL.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_kT9oErCPEL.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_kT9oErCPEL.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_nkrBI0ptQh.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_nkrBI0ptQh.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_nkrBI0ptQh.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_nkrBI0ptQh.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_oWYYPGVUfm.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_oWYYPGVUfm.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_oWYYPGVUfm.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_oWYYPGVUfm.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_pGtDvY-HED.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_pGtDvY-HED.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_pGtDvY-HED.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_pGtDvY-HED.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_pafJQkdFKt.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_pafJQkdFKt.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_pafJQkdFKt.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_pafJQkdFKt.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_r5nEQDLaqi.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_r5nEQDLaqi.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_r5nEQDLaqi.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_r5nEQDLaqi.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_rh8J63QQ50.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_rh8J63QQ50.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_rh8J63QQ50.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_rh8J63QQ50.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_s4jRAvb0oC.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_s4jRAvb0oC.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_s4jRAvb0oC.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_s4jRAvb0oC.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_tHwLAcZWJb.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_tHwLAcZWJb.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_tHwLAcZWJb.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_tHwLAcZWJb.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_tzPzaSmmIQ.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_tzPzaSmmIQ.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_tzPzaSmmIQ.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_tzPzaSmmIQ.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_ugDQJOmCKQ.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_ugDQJOmCKQ.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_ugDQJOmCKQ.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_ugDQJOmCKQ.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_wtbNfI9pbo.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_wtbNfI9pbo.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_wtbNfI9pbo.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/image/image_wtbNfI9pbo.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257.md" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257.md" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257.md" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257/\345\244\247\346\250\241\345\236\213agent\346\212\200\346\234\257.md" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/-7odlfea82_3dhsxoTUoM.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/-7odlfea82_3dhsxoTUoM.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/-7odlfea82_3dhsxoTUoM.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/-7odlfea82_3dhsxoTUoM.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/-s3r95515f_dQNgMLP8x3.webp" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/-s3r95515f_dQNgMLP8x3.webp" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/-s3r95515f_dQNgMLP8x3.webp" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/-s3r95515f_dQNgMLP8x3.webp" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/09jzx3c10e_6ahdUt6JDi.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/09jzx3c10e_6ahdUt6JDi.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/09jzx3c10e_6ahdUt6JDi.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/09jzx3c10e_6ahdUt6JDi.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/0_at8gi833_ASu3c3gFOm.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/0_at8gi833_ASu3c3gFOm.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/0_at8gi833_ASu3c3gFOm.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/0_at8gi833_ASu3c3gFOm.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/0nt5dmo6g-_zv32-fvOeG.svg" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/0nt5dmo6g-_zv32-fvOeG.svg" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/0nt5dmo6g-_zv32-fvOeG.svg" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/0nt5dmo6g-_zv32-fvOeG.svg" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/36wmybb209_tPlOQ7yxxx.webp" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/36wmybb209_tPlOQ7yxxx.webp" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/36wmybb209_tPlOQ7yxxx.webp" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/36wmybb209_tPlOQ7yxxx.webp" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/3ig65l2ybq_5MR5W4ZyeT.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/3ig65l2ybq_5MR5W4ZyeT.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/3ig65l2ybq_5MR5W4ZyeT.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/3ig65l2ybq_5MR5W4ZyeT.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/4x9fc4i_0r_X2ien8uvk1.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/4x9fc4i_0r_X2ien8uvk1.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/4x9fc4i_0r_X2ien8uvk1.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/4x9fc4i_0r_X2ien8uvk1.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/88xh886jei_TN_mdUEMel.jpeg" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/88xh886jei_TN_mdUEMel.jpeg" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/88xh886jei_TN_mdUEMel.jpeg" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/88xh886jei_TN_mdUEMel.jpeg" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/96q18_1xbq_GGAYzwntsw.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/96q18_1xbq_GGAYzwntsw.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/96q18_1xbq_GGAYzwntsw.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/96q18_1xbq_GGAYzwntsw.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/_duij-g5vy_Of0pZ8Z8xn.webp" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/_duij-g5vy_Of0pZ8Z8xn.webp" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/_duij-g5vy_Of0pZ8Z8xn.webp" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/_duij-g5vy_Of0pZ8Z8xn.webp" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/etz_ewki3z_V1-MnDWJWp.jpeg" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/etz_ewki3z_V1-MnDWJWp.jpeg" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/etz_ewki3z_V1-MnDWJWp.jpeg" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/etz_ewki3z_V1-MnDWJWp.jpeg" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/fprd8zqxkt_iYzAmAPXow.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/fprd8zqxkt_iYzAmAPXow.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/fprd8zqxkt_iYzAmAPXow.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/fprd8zqxkt_iYzAmAPXow.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/hvtl-j3m-w_BDJEP77q7V.webp" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/hvtl-j3m-w_BDJEP77q7V.webp" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/hvtl-j3m-w_BDJEP77q7V.webp" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/hvtl-j3m-w_BDJEP77q7V.webp" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/i86iadgfwk_xq517G5bik.webp" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/i86iadgfwk_xq517G5bik.webp" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/i86iadgfwk_xq517G5bik.webp" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/i86iadgfwk_xq517G5bik.webp" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/itxqktryzo_vzBQlvxC4S.jpeg" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/itxqktryzo_vzBQlvxC4S.jpeg" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/itxqktryzo_vzBQlvxC4S.jpeg" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/itxqktryzo_vzBQlvxC4S.jpeg" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/j6qrc_7jq1_ep5-hGcoXs.webp" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/j6qrc_7jq1_ep5-hGcoXs.webp" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/j6qrc_7jq1_ep5-hGcoXs.webp" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/j6qrc_7jq1_ep5-hGcoXs.webp" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/kl782vhbz9_bYN_jVromA.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/kl782vhbz9_bYN_jVromA.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/kl782vhbz9_bYN_jVromA.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/kl782vhbz9_bYN_jVromA.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/knuloe5g5l_qhXcmvem9Z.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/knuloe5g5l_qhXcmvem9Z.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/knuloe5g5l_qhXcmvem9Z.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/knuloe5g5l_qhXcmvem9Z.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/lnxah_g3hd_8SO-i3ytSj.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/lnxah_g3hd_8SO-i3ytSj.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/lnxah_g3hd_8SO-i3ytSj.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/lnxah_g3hd_8SO-i3ytSj.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/m010m6_j_w__Hvf941qcw.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/m010m6_j_w__Hvf941qcw.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/m010m6_j_w__Hvf941qcw.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/m010m6_j_w__Hvf941qcw.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/oo62b87hhs_2nr0DydDkI.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/oo62b87hhs_2nr0DydDkI.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/oo62b87hhs_2nr0DydDkI.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/oo62b87hhs_2nr0DydDkI.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/pagdp_5q1__sOo7mArpX_.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/pagdp_5q1__sOo7mArpX_.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/pagdp_5q1__sOo7mArpX_.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/pagdp_5q1__sOo7mArpX_.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/paomc13g0j_yrDeb7C4rv.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/paomc13g0j_yrDeb7C4rv.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/paomc13g0j_yrDeb7C4rv.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/paomc13g0j_yrDeb7C4rv.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/rx_3_v6bga_CcHqWr-98m.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/rx_3_v6bga_CcHqWr-98m.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/rx_3_v6bga_CcHqWr-98m.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/rx_3_v6bga_CcHqWr-98m.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/uepwk88u4-_zWv9MCSH7K.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/uepwk88u4-_zWv9MCSH7K.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/uepwk88u4-_zWv9MCSH7K.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/uepwk88u4-_zWv9MCSH7K.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/v0f4orzl_h_yGJuG_bdua.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/v0f4orzl_h_yGJuG_bdua.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/v0f4orzl_h_yGJuG_bdua.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/v0f4orzl_h_yGJuG_bdua.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/vwb__1luhn_Zt5fmtuoy1.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/vwb__1luhn_Zt5fmtuoy1.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/vwb__1luhn_Zt5fmtuoy1.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/vwb__1luhn_Zt5fmtuoy1.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/w9_m9smu46_Jnirp-dnV4.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/w9_m9smu46_Jnirp-dnV4.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/w9_m9smu46_Jnirp-dnV4.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/w9_m9smu46_Jnirp-dnV4.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/xi5bi0eqmz_osgd1m-T7I.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/xi5bi0eqmz_osgd1m-T7I.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/xi5bi0eqmz_osgd1m-T7I.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/xi5bi0eqmz_osgd1m-T7I.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/xsedk--wv0_Xd2E4iopao.webp" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/xsedk--wv0_Xd2E4iopao.webp" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/xsedk--wv0_Xd2E4iopao.webp" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/xsedk--wv0_Xd2E4iopao.webp" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/z37i04np4y_Ne3-iEXoLP.webp" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/z37i04np4y_Ne3-iEXoLP.webp" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/z37i04np4y_Ne3-iEXoLP.webp" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/z37i04np4y_Ne3-iEXoLP.webp" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/zl450wocuu_FlQ30ppSa8.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/zl450wocuu_FlQ30ppSa8.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/zl450wocuu_FlQ30ppSa8.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/zl450wocuu_FlQ30ppSa8.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/zx2o6-r03j_1oi9vLlWH_.png" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/zx2o6-r03j_1oi9vLlWH_.png" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/zx2o6-r03j_1oi9vLlWH_.png" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/image/zx2o6-r03j_1oi9vLlWH_.png" diff --git "a/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/\346\243\200\347\264\242\345\242\236\345\274\272llm.md" "b/docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/\346\243\200\347\264\242\345\242\236\345\274\272llm.md" similarity index 100% rename from "08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/\346\243\200\347\264\242\345\242\236\345\274\272llm.md" rename to "docs/08.\346\243\200\347\264\242\345\242\236\345\274\272rag/\346\243\200\347\264\242\345\242\236\345\274\272llm/\346\243\200\347\264\242\345\242\236\345\274\272llm.md" diff --git "a/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211.md" "b/docs/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211.md" similarity index 100% rename from "09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211.md" rename to "docs/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211.md" diff --git "a/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211/image/image_4vjiGLUsrJ.png" "b/docs/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211/image/image_4vjiGLUsrJ.png" similarity index 100% rename from "09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211/image/image_4vjiGLUsrJ.png" rename to "docs/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211/image/image_4vjiGLUsrJ.png" diff --git "a/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211/image/image_ceqa2Q6ZFX.png" "b/docs/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211/image/image_ceqa2Q6ZFX.png" similarity index 100% rename from "09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211/image/image_ceqa2Q6ZFX.png" rename to "docs/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211/image/image_ceqa2Q6ZFX.png" diff --git "a/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\350\257\204\346\265\213/1.\350\257\204\346\265\213.md" "b/docs/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\350\257\204\346\265\213/1.\350\257\204\346\265\213.md" similarity index 100% rename from "09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\350\257\204\346\265\213/1.\350\257\204\346\265\213.md" rename to "docs/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/1.\350\257\204\346\265\213/1.\350\257\204\346\265\213.md" diff --git "a/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/2.\345\271\273\350\247\211\346\235\245\346\272\220\344\270\216\347\274\223\350\247\243/2.\345\271\273\350\247\211\346\235\245\346\272\220\344\270\216\347\274\223\350\247\243.md" "b/docs/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/2.\345\271\273\350\247\211\346\235\245\346\272\220\344\270\216\347\274\223\350\247\243/2.\345\271\273\350\247\211\346\235\245\346\272\220\344\270\216\347\274\223\350\247\243.md" similarity index 100% rename from "09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/2.\345\271\273\350\247\211\346\235\245\346\272\220\344\270\216\347\274\223\350\247\243/2.\345\271\273\350\247\211\346\235\245\346\272\220\344\270\216\347\274\223\350\247\243.md" rename to "docs/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/2.\345\271\273\350\247\211\346\235\245\346\272\220\344\270\216\347\274\223\350\247\243/2.\345\271\273\350\247\211\346\235\245\346\272\220\344\270\216\347\274\223\350\247\243.md" diff --git "a/docs/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/README.md" "b/docs/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/README.md" new file mode 100644 index 0000000..5ed7982 --- /dev/null +++ "b/docs/09.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\350\257\204\344\274\260/README.md" @@ -0,0 +1,11 @@ +# 09.大语言模型评估 + +### 9.1 模型评估 + +[1.评测](/docs/09.大语言模型评估/1.评测/1.评测.md "1.评测") + +### 9.2 LLM幻觉 + +[1.大模型幻觉](/docs/09.大语言模型评估/1.大模型幻觉/1.大模型幻觉.md "1.大模型幻觉") + +[2.幻觉来源与缓解](/docs/09.大语言模型评估/2.幻觉来源与缓解/2.幻觉来源与缓解.md "2.幻觉来源与缓解") diff --git "a/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/1.langchain.md" "b/docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/1.langchain.md" similarity index 100% rename from "10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/1.langchain.md" rename to "docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/1.langchain.md" diff --git "a/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_83gYv9F_cd.png" "b/docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_83gYv9F_cd.png" similarity index 100% rename from "10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_83gYv9F_cd.png" rename to "docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_83gYv9F_cd.png" diff --git "a/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_HDf3HDA_cy.png" "b/docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_HDf3HDA_cy.png" similarity index 100% rename from "10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_HDf3HDA_cy.png" rename to "docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_HDf3HDA_cy.png" diff --git "a/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_T1-to3x5Zf.png" "b/docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_T1-to3x5Zf.png" similarity index 100% rename from "10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_T1-to3x5Zf.png" rename to "docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_T1-to3x5Zf.png" diff --git "a/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_cyIqBDjYXS.png" "b/docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_cyIqBDjYXS.png" similarity index 100% rename from "10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_cyIqBDjYXS.png" rename to "docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.langchain/image/image_cyIqBDjYXS.png" diff --git "a/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.\346\200\235\347\273\264\351\223\276\357\274\210cot\357\274\211/1.\346\200\235\347\273\264\351\223\276\357\274\210cot\357\274\211.md" "b/docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.\346\200\235\347\273\264\351\223\276\357\274\210cot\357\274\211/1.\346\200\235\347\273\264\351\223\276\357\274\210cot\357\274\211.md" similarity index 100% rename from "10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.\346\200\235\347\273\264\351\223\276\357\274\210cot\357\274\211/1.\346\200\235\347\273\264\351\223\276\357\274\210cot\357\274\211.md" rename to "docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.\346\200\235\347\273\264\351\223\276\357\274\210cot\357\274\211/1.\346\200\235\347\273\264\351\223\276\357\274\210cot\357\274\211.md" diff --git "a/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.\346\200\235\347\273\264\351\223\276\357\274\210cot\357\274\211/image/image_gnCtDhGhFV.png" "b/docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.\346\200\235\347\273\264\351\223\276\357\274\210cot\357\274\211/image/image_gnCtDhGhFV.png" similarity index 100% rename from "10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.\346\200\235\347\273\264\351\223\276\357\274\210cot\357\274\211/image/image_gnCtDhGhFV.png" rename to "docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/1.\346\200\235\347\273\264\351\223\276\357\274\210cot\357\274\211/image/image_gnCtDhGhFV.png" diff --git "a/docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/README.md" "b/docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/README.md" new file mode 100644 index 0000000..0ae88c4 --- /dev/null +++ "b/docs/10.\345\244\247\350\257\255\350\250\200\346\250\241\345\236\213\345\272\224\347\224\250/README.md" @@ -0,0 +1,9 @@ +# 10.大语言模型应用 + +### 10.1 思维链提示 + +[1.思维链(cot)](/docs/10.大语言模型应用/1.思维链(cot)/1.思维链(cot).md "1.思维链(cot)") + +### 10.2 LangChain框架 + +[1.langchain](/docs/10.大语言模型应用/1.langchain/1.langchain.md "1.langchain") diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/README.md" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/README.md" new file mode 100644 index 0000000..4936419 --- /dev/null +++ "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/README.md" @@ -0,0 +1,3 @@ +# 98.相关课程 + +[清华大模型公开课](清华大模型公开课/清华大模型公开课.md "清华大模型公开课") diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200.md" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200.md" new file mode 100644 index 0000000..36c2973 --- /dev/null +++ "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200.md" @@ -0,0 +1,228 @@ +# 1.NLP&大模型基础 + +# 1.自然语言处理 + +## 1.1 基础与应用 + +### (1)图灵测试 + +原名:Imitation Game + +采用一种行为注意的手段,尝试定义人工智能是不是具备人类智能的水平 + +- 1997年,人工智能在象棋方面战胜人类 +- 2011年,IBM Watson DeepQA在问答节目上战胜所有人类。 +- 2016年,Alpha go 在围棋方面战胜人类 + +### (2)NLP任务 + +基础任务: + +- 词性标注: +- 命名实体识别: +- 共指消解:用代词代替实体 +- 句法关系:互相依存关系 +- 中文自动分词: + +## 1.2 词表示 + +### (1)词表示 + +目的:**将单词转换为机器可以理解的符号** + +目标: + +- 词之间相似度的计算 +- 词之间语义的关系 + +### (2)用一组相关的词表示 + +**近义词,上位词**; + +问题: + +1. 词语之间的较小差异无法区分; +2. 词义会发生变化,出现新的词义; +3. 主观性的问题,受限于词典的标注; +4. 数据稀疏问题; +5. 大量的人工去构建、维护词典; + +### (3)one-hot表示 + +把每个词表示成独立的符号; + +和词表一样长的向量去找一维跟这个词相对应,整个向量的维度跟词表的长度是相当的; + +用来**表示文档时非常有效**,能较好地完成两个文档之间的相似度计算; + +但是,在表示词的时候会有问题:**会假设词根词之间的向量任意之间都是正交的**,导致任意两个词之间进行相似度计算都是0. + +$$ +similarity ( star, sun )=\left(v_{\text {star }}, v_{\text {sun }}\right)=0 +$$ + +### (4)上下文表示 + +一个词的词义由他经常出现在的位置的上下文有密切的关系 + +任何一个词都可以用他出现的维度或者重要性去进行表示,可以得到关于**每一个词的稠密向量**,就可以在这个空间里面利用稠密向量来计算两个词之间的相似度 + +问题: + +1. 词表变大,存储需求也会变大 +2. 有些词出现频度特别少,上下文少,这种方法不好表示 + +### (5)词嵌入 + +建立低维的稠密的向量空间,尝试把每一个词都学到这个空间里,用这个空间里的某一个位置所对应的向量来表示这个词, + +在这个空间里我们可以**自动的学习出来词与词之间可能存在的相对比较稳定的一些关系** + +![](image/image_1sxyMCLM9O.png) + +## 1.3 语言模型 + +目的:根据前文,预测下一个词 + +1. 计算一个词的序列成为一句合法的话的概率,**联合概率**:$P(W)=P\left(w_{1}, w_{2}, \cdots, w_{n}\right)$ +2. 根据前面说过的话,预测下一个词是什么,**条件概率**:$P\left(w_{n} \mid w_{1}, w_{2}, \cdots, w_{n-1}\right)$ + +![](image/image_xd7XXlstNC.png) + +基本假设:一个未来的词只会受到他前面的词的影响 + +$$ +\begin{array}{l}P(\text { Never }, \text { too }, \text { late }, \text { to }, \text { learn })= \\ \quad P(\text { Never }) \times P(\text { too } \mid \text { Never }) \times P(\text { late } \mid \text { Never }, \text { too }) \times \\ \quad P(\text { to } \mid \text { Never }, \text { too, late }) \times P(\text { learn } \mid \text { Never }, \text { too, late, to })\end{array} +$$ + +$$ +P( learn \mid Never, too, late, to )=\frac{P(\text { Never }, \text { too }, \text { late }, \text { to }, \text { learn })}{P(\text { Never }, \text { too }, \text { late }, \text { to })} +$$ + +语言模型:一个句子的联合概率=里面的每一个词基于前面已经出现的词的条件概率之积 + +$$ +P\left(w_{1}, w_{2}, \cdots, w_{n}\right)=\prod_{i} P\left(w_{i} \mid w_{1}, w_{2}, \cdots, w_{i-1}\right) +$$ + +## 1.4 N-gram Model + +**每一个词是一个单独的符号** + +`4-gram`只会考虑相邻的4个词,也就是前面出现的三个词来预测下一个词 + +$$ +P\left(w_{j} \mid\right. never to late to )=\frac{\text { count }\left(\text { too late to } w_{j}\right)}{\text { count }(\text { too late to })} +$$ + +`Bigram`就是`2-gram`,考虑连续出现的两个词,相当于只考虑前面出现的一个词,预测下一个词是什么 + +`Trigram`就是`3-gram` + +在一个大规模数据里统计连续出现的序列的频度,在深度学习出现之前一个非常重要的技术 + +遵守**Markov的假设**,只考虑前面的有限的几个词 + +$$ +P\left(w_{1}, w_{2}, \cdots, w_{n}\right) \approx \prod_{i} P\left(w_{i} \mid w_{i-k}, \cdots, w_{i-1}\right) +$$ + +$$ +P\left(w_{i} \mid w_{1}, w_{2}, \cdots, w_{i-1}\right) \approx P\left(w_{i} \mid w_{i-k}, \cdots, w_{i-1}\right) +$$ + +**问题:** + +1. 考虑的长度通常短,N多是2或者3,那上下文是1或2 +2. 背后还是会**假设所有词相互之间都是独立的**,上下文基于符号去做统计,不能理解词与词之间的相似度造成了什么 + +## 1.5 神经语言模型 + +**每一个词是一个低维的向量** + +用分布式的表示建构前文和当前词的预测条件概率 + +1. 把词表示成低维的向量 +2. 把低维的向量拼在一起,形成一个更高的上下文的向量 +3. 经过非线性的转换,用向量去预测下一个词是什么 + +通过对上下文的表示完成。 + +![](image/image_W01GPKGK_C.png) + +N-gram Model中每一个词是一个单独的符号,在Neural language Model中每一个词会被表示为一个向量。 + +相似的词会有一个相似的向量,就有可能在语境中发挥相似的作用。 + +# 2.大模型基础 + +## 2.1 大模型之旅 + +![](image/image_j00a9nXOb6.png) + +### (1)预训练大模型PLM + +GLUE上预训练的语言模型的结果优于人类的表现,反映了语言理解的能力 + +![](image/image_7nqQ0R96ob.png) + +### (2)大模型的特点 + +2018年以后,预训练大模型有以下三个特点: + +1. 参数量越来越大 +2. 数据越来越多 +3. 计算资源越来越大 + +![](image/image_Eecyhptyzw.png) + +近两年来,参数尺度以每年10倍左右的速度增长;数据量也随之增长,计算成本也越来越高 + +![](image/image_nRutXyfeE9.png) + +注:M-millions, b -billion。最后一列训练时间是使用单个NVIDIA V100 GPU训练的估计时间 + +## 2.2 大模型背后的范式 + +### (1)预训练 + 微调 + +在**预训练**阶段,预训练的语言模型从大规模的未标记数据中获取丰富的知识 + +然后,我们可以使用特定任务的训练数据对预训练的语言模型进行**微调**,以适应预训练的知识 + +![](image/image_J_0Q3PMNVl.png) + +预训练和微调的基本范例可以追溯到**迁移学习** + +人类可以应用以前学到的知识来更快地处理新问题,我们希望机器也有类似的能力 + +![](image/image_O-LiRHR3CT.png) + +迁移学习使用“预训练,然后微调”的框架来实现“知识获取,然后知识转移”。 + +在预训练模型的后续工作中,使用了特征-表征-迁移和参数-迁移 + +### (2)词嵌入Word2Vec + +Word2Vec使用两种主要的技术:CBOW(Continuous Bag of Words)和Skip-gram。两者均通过优化一个神经网络来训练词向量,但目标函数略有不同。 + +**CBOW (Continuous Bag of Words)**:CBOW模型预测的是目标词(中心词),而根据的是上下文词(周围的词)。具体来说,给定一个词的上下文,CBOW试图预测该词。 + +**Skip-gram**:Skip-gram与CBOW恰好相反。它的输入是中心词,输出则是上下文词。换句话说,它根据某个词来预测其周围的词。 + +![](image/image_YCB5vNp7JK.png) + +### (3)解决一词多义:ELMo + +- 使用RNN对大规模未标记数据进行语言建模 +- 使用预训练的RNN生成**上下文词嵌入** + +特定于任务的模型 + +![](image/image_4vxDFDb3ih.png) + +### (4)Transformer + +在Transformer的基础上,开发了一系列深度预训练模型,取代了更强大的浅层RNN + +![](image/image__YzbX0DiEt.png) diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_1sxyMCLM9O.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_1sxyMCLM9O.png" new file mode 100644 index 0000000..527e4d9 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_1sxyMCLM9O.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_4vxDFDb3ih.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_4vxDFDb3ih.png" new file mode 100644 index 0000000..0c2315a Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_4vxDFDb3ih.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_7nqQ0R96ob.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_7nqQ0R96ob.png" new file mode 100644 index 0000000..32c440a Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_7nqQ0R96ob.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_Eecyhptyzw.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_Eecyhptyzw.png" new file mode 100644 index 0000000..cf15ea5 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_Eecyhptyzw.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_J_0Q3PMNVl.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_J_0Q3PMNVl.png" new file mode 100644 index 0000000..f136fee Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_J_0Q3PMNVl.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_O-LiRHR3CT.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_O-LiRHR3CT.png" new file mode 100644 index 0000000..c660744 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_O-LiRHR3CT.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_W01GPKGK_C.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_W01GPKGK_C.png" new file mode 100644 index 0000000..cf975c5 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_W01GPKGK_C.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_YCB5vNp7JK.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_YCB5vNp7JK.png" new file mode 100644 index 0000000..1d20959 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_YCB5vNp7JK.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image__YzbX0DiEt.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image__YzbX0DiEt.png" new file mode 100644 index 0000000..7d17235 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image__YzbX0DiEt.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_j00a9nXOb6.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_j00a9nXOb6.png" new file mode 100644 index 0000000..72b5285 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_j00a9nXOb6.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_nRutXyfeE9.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_nRutXyfeE9.png" new file mode 100644 index 0000000..c3c0ec9 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_nRutXyfeE9.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_xd7XXlstNC.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_xd7XXlstNC.png" new file mode 100644 index 0000000..46e8c1e Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/1.NLP&\345\244\247\346\250\241\345\236\213\345\237\272\347\241\200/image/image_xd7XXlstNC.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200.md" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200.md" new file mode 100644 index 0000000..0129b3c --- /dev/null +++ "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200.md" @@ -0,0 +1,533 @@ +# 2.神经网络基础 + +# 1.神经网络组成部分 + +## 1.1 神经网络 + +### (1)神经元 + +人工神经网络:灵感来自于大脑中的生物神经网络 + +![](image/image_pEIxMExVIa.png) + +神经元是一个具有输入和一个输出和参数$w$,$b$的计算单元 + +$$ +h_{\boldsymbol{w}, b}(\boldsymbol{x})=f\left(\boldsymbol{w}^{T} \boldsymbol{x}+b\right) +$$ + +![](image/image_zphUo3uM0y.png) + +### (2)单层神经网络 + +![](image/image_SJV0taZcvo.png) + +### (3)多层神经网络 + +![](image/image_xpZc5s_g3x.png) + +$$ +\begin{array}{l}\boldsymbol{h}_{1}=f\left(\boldsymbol{W}_{1} \boldsymbol{x}+\boldsymbol{b}_{1}\right) \\ \boldsymbol{h}_{2}=f\left(\boldsymbol{W}_{2} \boldsymbol{h}_{1}+\boldsymbol{b}_{2}\right) \\ \boldsymbol{h}_{3}=f\left(\boldsymbol{W}_{3} \boldsymbol{h}_{2}+\boldsymbol{b}_{3}\right)\end{array} +$$ + +## 1.2 激活函数 + +如果神经网络中只存在线性运算的话,那么多层的神经网络其实可以被转化为单层的神经网络;所以我们**使用非线性的激活函数,防止多层的神经网络塌缩成单一的神经网络** + +### (1)Sigmoid + +$$ +f(z)=\frac{1}{1+e^{-z}} +$$ + +![](image/image_kqyTX_GZDQ.png) + +### (2)Tanh + +$$ +f(z)=\tanh (z)=\frac{e^{z}-e^{-z}}{e^{z}+e^{-z}} +$$ + +![](image/image_lQqOtaZ9cP.png) + +### (3)ReLU + +$$ +f(z)=\max (z, 0) +$$ + +![](image/image_3jrbFm1RZP.png) + +## 1.3 输出层 + +增加若干个隐层可以提高网络的表达能力,如果想要得到我们想要的输出结果,就需要添加网络的最后一层,即**输出层** + +![](image/image_Rx4hc2yzuG.png) + +# 2.训练方式 + +## 2.1 训练目标 + +### (1)均方根误差 + +$$ +\min _{\theta} J(\theta)=\min _{\theta} \frac{1}{N} \sum_{i=1}^{N}\left(y_{i}-F_{\theta}\left(x_{i}\right)\right)^{2} +$$ + +其中,$\theta$是神经网络参数 + +### (2)交叉熵 + +$$ +\min _{\theta} J(\theta)=\min _{\theta}-\frac{1}{N} \sum_{i=1}^{N} \log P_{\operatorname{model}}\left(F_{\theta}\left(x_{i}\right)=y_{i}\right) +$$ + +其中,$\theta$是神经网络参数 + +![](image/image_yKgjKE_QOX.png) + +## 2.2 随机梯度下降 + +更新规则: + +$$ +\theta^{\text {new }}=\theta^{\text {old }}-\alpha \nabla_{\theta} \mathrm{J}(\theta) +$$ + +其中,$\alpha + $是学习率 + +### (1)梯度 + +给定$n$个输入,$m$个输出的函数: + +$$ +\mathrm{F}(\boldsymbol{x})=\left[F_{1}\left(x_{1}, x_{2} \ldots x_{n}\right), F_{2}\left(x_{1}, x_{2} \ldots x_{n}\right) \ldots F_{m}\left(x_{1}, x_{2} \ldots x_{n}\right)\right] +$$ + +则输出为$m\times n$的雅可比矩阵 + +$$ +\frac{\partial \mathrm{F}}{\partial \boldsymbol{x}}=\left[\begin{array}{ccc}\frac{\partial \mathrm{F}_{1}}{\partial x_{1}} & \cdots & \frac{\partial \mathrm{F}_{1}}{\partial x_{n}} \\ \vdots & \ddots & \vdots \\ \frac{\partial \mathrm{F}_{\mathrm{m}}}{\partial x_{1}} & \cdots & \frac{\partial \mathrm{F}_{\mathrm{m}}}{\partial x_{n}}\end{array}\right] +$$ + +其中,$\left(\frac{\partial \mathrm{F}}{\partial x}\right)_{i j}=\frac{\partial \mathrm{F}_{\mathrm{i}}}{\partial x_{j}}$表示第i个输出对第j个输入求梯度。 + +### (2)链式求导法则 + +给定$s=\boldsymbol{u}^{T} \boldsymbol{h}, \boldsymbol{h}=f(\boldsymbol{z}), \boldsymbol{z}=\boldsymbol{W} \boldsymbol{x}+\boldsymbol{b}$,求$\frac{\partial s}{\partial \boldsymbol{b}}$ + +![](image/image_aka_vSyy84.png) + +## 2.3 反向传播 + +### (1)计算图 + +计算图:将神经网路的传播以图的形式表示。 + +- 源节点:输入 +- 内部节点:操作 +- 边传递操作:结果 + +$$ +\begin{array}{c}s=\boldsymbol{u}^{T} \boldsymbol{h} ~,~ \boldsymbol{h}=f(\mathbf{z}) ~,~ \boldsymbol{z}=\boldsymbol{W} \boldsymbol{x}+\boldsymbol{b} ~,~ \boldsymbol{x} \text { input }\end{array} +$$ + +![](image/image_nbfnd0PF_-.png) + +梯度回传:沿着边往回走,沿着梯度传递 + +![](image/image_gDZ5lIFi99.png) + +### (2)单个结点 + +节点接收到一个“上游梯度” + +目标是传递正确的“下游梯度” + +每个节点都有一个局部梯度( local gradient ),输出相对于输入的梯度 + +$$ +[downstream gradient] = [upstream gradient] \times +[local gradient] +$$ + +![](image/image_ArlHtXeqKN.png) + +### (3)示例 + +函数:$\begin{array}{c}f(x, y, z)=(x+y) \max (y, z) ~~,~~ x=1, y=2, z=0\end{array}$ + +前向传播: + +$$ +\begin{array}{c}a=x+y=3 \\ \mathrm{~b}=\max (y, z)=2 \\ f=a b=6\end{array} +$$ + +本地梯度(Local gradients): + +$$ +\begin{array}{c}\frac{\partial a}{\partial x}=1, \frac{\partial a}{\partial y}=1 \\ \frac{\partial b}{\partial y}=\mathbf{1}(y>z)=1, \frac{\partial b}{\partial z}=\mathbf{1}(z>y)=0 \\ \frac{\partial f}{\partial a}=b=2, \frac{\partial f}{\partial b}=a=3\end{array} +$$ + +初始计算图: + +![](image/image_UPXtLjRuaV.png) + +回传第一步: + +![](image/image_b10DIJUbSB.png) + +回传第二步(`*`): + +$$ +\frac{\partial f}{\partial a}=b=2, \frac{\partial f}{\partial b}=a=3 +$$ + +![](image/image_q_vrI0YlYv.png) + +回传第三步(`max`): + +$$ +\frac{\partial b}{\partial y}=\mathbf{1}(y>z)=1, \frac{\partial b}{\partial z}=\mathbf{1}(z>y)=0 +$$ + +![](image/image_HIMZQxzL9j.png) + +回传第四步(`+`): + +$$ +\frac{\partial a}{\partial x}=1, \frac{\partial a}{\partial y}=1 +$$ + +![](image/image_Um7-nt83IJ.png) + +计算最终梯度: + +![](image/image_x8Dn2pZmHH.png) + +# 3.词表示:Word2Vec + +Word2Vec:可以学到一些语义内涵,捕捉到语言学上的一些规律 + +## 3.1 Word2Vec + +Word2vec使用浅层神经网络将单词与分布式表示相关联 + +它可以捕获许多语言规则,例如: + +![](image/image_BE5k3g-tS6.png) + +Word2vec可以利用两种架构来生成单词的分布式表示: + +- Continuous bag-of-words (`CBOW`) +- Continuous `skip-gram` + +![](image/image_vF4PitptOH.png) + +## 3.2 滑动窗口 + +Word2vec使用一个固定大小的滑动窗口沿着句子移动 + +- 在每个窗口中,中间的单词是目标单词,其他单词是上下文单词 +- 给定上下文单词,CBOW预测目标单词的概率 +- 当给定目标词时,skip-gram预测上下文词的概率 + +滑动窗口大小为5 + +![](image/image_WjGN1pIJ2E.png) + +## 3.3 CBOW(Continuous Bag-of-Words) + +在CBOW架构中,**该模型给出一个周围上下文词的窗口来预测目标词** + +- 根据词袋假设:上下文词的顺序不影响预测 +- 假设窗口大小为5,`Never too late to learn` + +$$ +P( late \mid[ never, too, to, learn ]) +$$ + +![](image/image_VNXtPz4VyX.png) + +## 3.4 Continuous Skip-Gram + +在skip-gram架构中,该模型从目标词中预测上下文词 + +假设窗口大小为5,`Never too late to learn` + +$$ +P([ too, late ] \mid Never ), P([ Never, late, to ] \mid too ), \ldots +$$ + +Skip-gram每步预测一个上下文词,训练样本为: + +$$ +\begin{array}{l}P(\text { too } \mid \text { Never }), P(\text { late } \mid \text { Never }), P(\text { Never } \mid \text { too }), P(\text { late } \mid \text { too }), P(\text { to } \mid \text { too }), \ldots\end{array} +$$ + +![](image/image_zifXUOE8Ot.png) + +## 3.5 Softmax存在问题 + +当词汇量很大的时候 + +- Softmax对所有单词的每一步都依赖于大量的模型参数,这在计算上是不切实际的 +- 我们需要提高计算效率 + +事实上,在word2vec中我们**并不需要一个完整的概率模型**;word2vec主要有两种改进方法: + +- 负采样 +- 分层softmax + +## 3.6 负采样 + +当词汇表非常大,这意味着模型每一步都有大量的权重需要更新 + +负抽样的思想是,**每一步只更新一小部分权重** + +既然有词汇表并且知道上下文单词,**可以按概率选择几个不在上下文单词列表中的单词**: + +$$ +P\left(w_{i}\right)=\frac{f\left(w_{i}\right)^{3 / 4}}{\sum_{j=1}^{V} f\left(w_{j}\right)^{3 / 4}} +$$ + +其中,$f(w_i)$为$w_i$的频次,$3/4$为经验值 + +相比于$\frac{f\left(w_{i}\right)}{\sum_{j=1}^{V} f\left(w_{j}\right)}$,这可以增加低频词出现的概率。 + +假设我们只选取4个负采样词: + +![](image/image_yuqQ_neXbt.png) + +然后我们可以计算损失,并优化每一步的权重(不是所有的权重) + +- 假设有一个大小为300×10,000的权重矩阵,输出大小为5 +- 只需要更新300×5权重,这只占所有权重的0.05% + +## 3.7 其他一些细节 + +### (1)Sub-Sampling + +**罕见的单词可能更有可能携带不同的信息**,据此,Sub-Sampling有概率地丢弃单词: + +$$ +1-\sqrt{t / f(w)} +$$ + +其中,$f(w)$为单词频率,$t$是一个可调节的阈值吗 + +### (2)Soft sliding window + +**滑动窗口应该给较远的单词分配较少的权重** + +将滑动窗口最大的定义为 $S_{max}$,实际的滑动窗口大小在1和$S_{max}$之间随机选择 + +因此,那些靠近目标单词的单词更有可能出现在窗口中 + +# 4.通用神经网络 + +## 4.1 RNN + +### (1)顺序记忆 + +RNN的关键概念:**处理序列数据时的顺序存储器** + +定义:一种让大脑更容易识别序列模式的机制 + +RNN递归地更新序列内存以建模序列数据 + +### (2)RNN + +![](image/image_BV7NKV3ZeS.png) + +### (3)RNN单元 + +$$ +\begin{array}{c}h_{i}=\tanh \left(W_{x} x_{i}+W_{h} h_{i-1}+b\right) \\ y_{i}=F\left(h_{i}\right)\end{array} +$$ + +![](image/image_DcKR1TcouF.png) + +### (4)RNN语言模型 + +$W_h$参数是共享的 + +![](image/image_a--8AYMo_1.png) + +### (5)优缺点 + +优点: + +- 可以处理任何长度的输入 +- 模型尺寸不增加较长的输入 +- 跨时间步共享权重 +- 从许多后退步骤计算步骤 + +缺点: + +- 循环计算速度慢 +- 在实践中,很难从许多步骤中获取信息 + +### (6)梯度问题 + +RNN链比较长,**容易出现梯度消失或爆炸** + +$$ +h_{i}=\tanh \left(W_{x} x_{i}+W_{h} h_{i-1}+b\right) +$$ + +$$ +\Delta w_{1}=\frac{\partial \text { Loss }}{\partial w_{2}}=\frac{\partial \text { Loss }}{\partial h_{n}} \frac{\partial h_{n}}{\partial h_{n-1}} \frac{\partial h_{n-1}}{\partial h_{n-2}} \ldots \frac{\partial h_{3}}{\partial h_{2}} \frac{\partial h_{2}}{\partial w_{2}} +$$ + +![](image/image_wAj3CqKeNg.png) + +### (7)RNN变种 + +梯度消失问题的主要解决方案是**在递归中使用更复杂的隐单元计算** + +- GRU +- LSTM + +主要思想:**保持记忆,捕捉远距离的依赖** + +## 4.2 GRU(Gated Recurrent Unit) + +Vanilla RNN在下一个时间步直接计算隐藏层: + +$$ +h_{i}=\tanh \left(W_{x} x_{i}+W_{h} h_{i-1}+b\right) +$$ + +在原始RNN中,增加门控机制,主要用于平衡过去的信息和输入之间的影响。主要有两个门控单元: + +**更新门**(update gate):$z_{i}=\sigma\left(W_{x}^{(z)} x_{i}+W_{h}^{(z)} h_{i-1}+b^{(z)}\right)$ + +**重置门**(reset gate):$r_{i}=\sigma\left(W_{x}^{(r)} x_{i}+W_{h}^{(r)} h_{i-1}+b^{(r)}\right)$ + +**新的激活输出** $\tilde{h}_{i}$:$\tilde{h}_{i}=\tanh \left(W_{x} x_{i}+r_{i} * W_{h} h_{i-1}+b\right)$ + +最后的隐藏单元输出$h_i$:$h_{i}=z_{i} * h_{i-1}+\left(1-z_{i}\right) * \tilde{h}_{i}$ + +![](image/image_rnG7Cf7l9f.png) + +**示例** + +![](image/image_yn83Uu9YHd.png) + +如果重置门$r_i$ 接近于0 + +$$ +\tilde{h}_{i} \approx \tanh \left(W_{x} x_{i}+0 * W_{h} h_{i-1}+b\right) +$$ + +$$ +\tilde{h}_{i} \approx \tanh \left(W_{x} x_{i}+b\right) +$$ + +忽略先前的隐藏状态,这表明当前的激活与过去无关。例如,在一篇新文章的开头,过去的信息对于当前的激活是无用的。 + +更新门$z_i$控制与当前激活相比,过去的状态有多少是重要的。 + +如果$z_i$接近于1,然后可以通过许多时间步骤复制该单元中的信息! + +$$ +h_{i}=1 * h_{i-1}+(1-1) * \tilde{h}_{i}=h_{i-1} +$$ + +如果$z_i$接近于0,然后将信息放入该单元并完全取代历史信息 + +## 4.3 LSTM(Long Short-Term Memory network) + +LSTM是一种特殊的RNN,能够像GRU一样学习长期依赖关系; + +![](image/image_rL3cHIf8lQ.png) + +### (1)状态单元 $C_t$ + +LSTM的关键是单元状态$C_t$ + +![](image/image_jHKo1369ls.png) + +- 用于捕获长期依赖的额外向量 +- 直接贯穿整个链条,只有少量的线性交互作用 +- 易于删除或添加信息到细胞状态 + +### (2)遗忘门$f_t$ + +遗忘门:**决定从状态单元中丢弃哪些信息** + +$$ +f_{t}=\sigma\left(W_{f} \cdot\left[h_{t-1}, x_{t}\right]+b_{f}\right) +$$ + +![](image/image_DC8zhV325n.png) + +其中,$\left[h_{t-1}, x_{t}\right]$为拼接向量 + +如果$f_{t}=0$,则直接遗忘过去的信息。 + +### (3)输入门 $i_t$ + +**输入门**:决定在单元状态中存储什么信息; + +输入门$i_t$和新的候选状态信息 $\tilde{C}_{t}$ + +$$ +i_{t}=\sigma\left(W_{i} \cdot\left[h_{t-1}, x_{t}\right]+b_{i}\right) +$$ + +$$ +\tilde{C}_{t}=\tanh \left(W_{C} \cdot\left[h_{t-1}, x_{t}\right]+b_{C}\right) +$$ + +![](image/image_UTvdiK4BfH.png) + +更新就的状态信息 $C_{t-1}$,结合前两步的结果 + +$$ +C_{t}=f_{t} * C_{t-1}+i_{t} * \tilde{C}_{t} +$$ + +![](image/image_P4MIxkcNU8.png) + +### (4)输出门$o_t$ + +输出门:**决定输出什么信息** + +为特定的单词表示调整句子信息 + +$$ +o_{t}=\sigma\left(W_{o}\left[h_{t-1}, x_{t}\right]+b_{o}\right) +$$ + +$$ +h_{t}=o_{t} * \tanh \left(C_{t}\right) +$$ + +![](image/image_uybEKVLH6l.png) + +功能强大,特别是当堆叠和更深层时(每个隐藏层已经由深层内部网络计算) + +如果你有大量的数据,非常有用 + +## 4.4 双向RNN + +在传统的RNN中,当前状态只捕获过去的信息 + +$$ +h_{t}=f\left(x_{t-1}, \ldots, x_{2}, x_{1}\right) +$$ + +问题:在很多应用中,我们希望输出$y_t$依赖于整个输入序列 + +![](image/image_bhqS-UwJ0e.png) + +## 4.5 CNN + +![](image/image_FFrUnKW_xB.png) + +RNN vs CNN + +![](image/image_fzPorZTwNq.png) diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_3jrbFm1RZP.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_3jrbFm1RZP.png" new file mode 100644 index 0000000..7d07b41 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_3jrbFm1RZP.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_ArlHtXeqKN.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_ArlHtXeqKN.png" new file mode 100644 index 0000000..f8a196d Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_ArlHtXeqKN.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_BE5k3g-tS6.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_BE5k3g-tS6.png" new file mode 100644 index 0000000..254a794 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_BE5k3g-tS6.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_BV7NKV3ZeS.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_BV7NKV3ZeS.png" new file mode 100644 index 0000000..1efa101 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_BV7NKV3ZeS.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_DC8zhV325n.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_DC8zhV325n.png" new file mode 100644 index 0000000..326a1c4 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_DC8zhV325n.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_DcKR1TcouF.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_DcKR1TcouF.png" new file mode 100644 index 0000000..49d1093 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_DcKR1TcouF.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_FFrUnKW_xB.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_FFrUnKW_xB.png" new file mode 100644 index 0000000..76af920 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_FFrUnKW_xB.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_HIMZQxzL9j.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_HIMZQxzL9j.png" new file mode 100644 index 0000000..9f02bc8 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_HIMZQxzL9j.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_P4MIxkcNU8.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_P4MIxkcNU8.png" new file mode 100644 index 0000000..02287fd Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_P4MIxkcNU8.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_Rx4hc2yzuG.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_Rx4hc2yzuG.png" new file mode 100644 index 0000000..3c05251 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_Rx4hc2yzuG.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_SJV0taZcvo.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_SJV0taZcvo.png" new file mode 100644 index 0000000..d0954e9 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_SJV0taZcvo.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_UPXtLjRuaV.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_UPXtLjRuaV.png" new file mode 100644 index 0000000..b68f318 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_UPXtLjRuaV.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_UTvdiK4BfH.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_UTvdiK4BfH.png" new file mode 100644 index 0000000..4d9b95a Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_UTvdiK4BfH.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_Um7-nt83IJ.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_Um7-nt83IJ.png" new file mode 100644 index 0000000..42219c1 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_Um7-nt83IJ.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_VNXtPz4VyX.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_VNXtPz4VyX.png" new file mode 100644 index 0000000..274554e Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_VNXtPz4VyX.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_WjGN1pIJ2E.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_WjGN1pIJ2E.png" new file mode 100644 index 0000000..17b4e45 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_WjGN1pIJ2E.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_a--8AYMo_1.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_a--8AYMo_1.png" new file mode 100644 index 0000000..7c1d948 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_a--8AYMo_1.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_aka_vSyy84.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_aka_vSyy84.png" new file mode 100644 index 0000000..67dcbfc Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_aka_vSyy84.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_b10DIJUbSB.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_b10DIJUbSB.png" new file mode 100644 index 0000000..5c70506 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_b10DIJUbSB.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_bhqS-UwJ0e.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_bhqS-UwJ0e.png" new file mode 100644 index 0000000..26eb649 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_bhqS-UwJ0e.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_fzPorZTwNq.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_fzPorZTwNq.png" new file mode 100644 index 0000000..901caf4 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_fzPorZTwNq.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_gDZ5lIFi99.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_gDZ5lIFi99.png" new file mode 100644 index 0000000..153e94c Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_gDZ5lIFi99.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_jHKo1369ls.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_jHKo1369ls.png" new file mode 100644 index 0000000..4f61073 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_jHKo1369ls.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_kqyTX_GZDQ.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_kqyTX_GZDQ.png" new file mode 100644 index 0000000..354be96 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_kqyTX_GZDQ.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_lQqOtaZ9cP.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_lQqOtaZ9cP.png" new file mode 100644 index 0000000..5bc7b63 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_lQqOtaZ9cP.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_nbfnd0PF_-.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_nbfnd0PF_-.png" new file mode 100644 index 0000000..65be036 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_nbfnd0PF_-.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_pEIxMExVIa.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_pEIxMExVIa.png" new file mode 100644 index 0000000..58ca298 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_pEIxMExVIa.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_q_vrI0YlYv.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_q_vrI0YlYv.png" new file mode 100644 index 0000000..729869e Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_q_vrI0YlYv.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_rL3cHIf8lQ.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_rL3cHIf8lQ.png" new file mode 100644 index 0000000..6a192a7 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_rL3cHIf8lQ.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_rnG7Cf7l9f.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_rnG7Cf7l9f.png" new file mode 100644 index 0000000..74a7442 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_rnG7Cf7l9f.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_uybEKVLH6l.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_uybEKVLH6l.png" new file mode 100644 index 0000000..778c64f Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_uybEKVLH6l.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_vF4PitptOH.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_vF4PitptOH.png" new file mode 100644 index 0000000..d6a801b Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_vF4PitptOH.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_wAj3CqKeNg.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_wAj3CqKeNg.png" new file mode 100644 index 0000000..1e12827 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_wAj3CqKeNg.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_x8Dn2pZmHH.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_x8Dn2pZmHH.png" new file mode 100644 index 0000000..866bc07 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_x8Dn2pZmHH.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_xpZc5s_g3x.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_xpZc5s_g3x.png" new file mode 100644 index 0000000..f9cb591 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_xpZc5s_g3x.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_yKgjKE_QOX.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_yKgjKE_QOX.png" new file mode 100644 index 0000000..1c7570f Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_yKgjKE_QOX.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_yn83Uu9YHd.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_yn83Uu9YHd.png" new file mode 100644 index 0000000..3b59e6e Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_yn83Uu9YHd.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_yuqQ_neXbt.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_yuqQ_neXbt.png" new file mode 100644 index 0000000..2ee4411 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_yuqQ_neXbt.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_zifXUOE8Ot.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_zifXUOE8Ot.png" new file mode 100644 index 0000000..45fbc88 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_zifXUOE8Ot.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_zphUo3uM0y.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_zphUo3uM0y.png" new file mode 100644 index 0000000..68a93b3 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/2.\347\245\236\347\273\217\347\275\221\347\273\234\345\237\272\347\241\200/image/image_zphUo3uM0y.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/3.Transformer\345\237\272\347\241\200.md" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/3.Transformer\345\237\272\347\241\200.md" new file mode 100644 index 0000000..b8bc586 --- /dev/null +++ "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/3.Transformer\345\237\272\347\241\200.md" @@ -0,0 +1,393 @@ +# 3.Transformer基础 + +# 1.Transformer + +## 1.1 注意力机制 + +### (1)Seq2Seq注意力 + +传统的Seq2Seq序列模型存在信息瓶颈的问题 + +- 源句子编码的单向量需要捕获远举子的所有信息 +- 单向量限制了编码器的表示能力:信息瓶颈 + +![](image/image_a5wPU_cFb5.png) + +注意力机制: + +- 注意力提供了瓶颈问题的解决方案; +- 核心思想:**在解码器的每一步,专注于源序列的特定部分**。 + +### (2)Seq2Seq注意力机制 + +1. Encoder隐藏状态:$h_{1}, h_{2} \ldots, h_{N} \in \mathbb{R}^{h}$ +2. Decoder在$t$时刻的隐藏状态:$s_{t} \in \mathbb{R}^{h}$ +3. 在$t$时刻,计算注意力分数 $e_t$ : $e^{t}=\left[s_{t}^{T} h_{1}, \ldots, s_{t}^{T} h_{N}\right] \in \mathbb{R}^{N}$ +4. 使用softmax得到注意力分布$\alpha_t$ :$\alpha^{t}=\operatorname{softmax}\left(e^{t}\right) \in \mathbb{R}^{N}$ +5. 利用注意力分布计算编码器隐藏状态的加权和作为注意力输出 : $o_{t}=\sum_{i=1}^{N} \alpha_{i}^{t} h_{i} \in \mathbb{R}^{h}$ +6. 连接注意力输出和解码器隐藏状态来预测单词 :$\left[o_{t} ; s_{t}\right] \in \mathbb{R}^{2 h}$ + +![](image/image_EJ4Si-cwtZ.png) + +![](image/image_Ysno8YxWiH.png) + +![](image/image_hlja8b3bUT.png) + +![](image/image_KaV_YxKSi0.png) + +![](image/image_vXL3CEzMiY.png) + +### (3)注意力机制的变体 + +不同注意力分数的计算,有不同的变体,$\mathrm{e} \in \mathbb{R}^{N}$ + +#### Additive attention + +$$ +e_{i}=v^{T} \tanh \left(W_{1} h_{i}+W_{2} s\right) \in \mathbb{R} +$$ + +其中,$W_{1} \in \mathbb{R}^{d_{3} \times d_{1}}, W_{2} \in \mathbb{R}^{d_{3} \times d_{2}}$是权重矩阵,$v \in \mathbb{R}^{d_{3}}$是权重向量。 + +#### Basic dot-product attention + +$$ +e_{i}=s^{T} h_{i} \in \mathbb{R} +$$ + +假设向量$d_1=d_2$ + +#### Multiplicative attention + +$$ +e_{i}=s^{T} W h_{i} \in \mathbb{R}, \quad W \in \mathbb{R}^{d_{2} \times d_{1}} +$$ + +### (4)注意力通用定义 + +给定一个query向量和一组value向量,注意力技术根据query计算值的加权和 + +根据查询,**加权和是值的选择性汇总**。可以通过注意机制获得任意一组表征的固定大小的表征。 + +数学表示: + +- 如果存在value向量$\boldsymbol{h}_{1}, \boldsymbol{h}_{2} \ldots, \boldsymbol{h}_{N} \in \mathbb{R}^{d_{1}}$,query向量$\mathbf{s} \in \mathbb{R}^{d_{2}}$ +- 根据注意力分数$\mathbf{e} \in \mathbb{R}^{N}$,计算得到注意力输出$\mathbf{o} \in \mathbb{R}^{d_{1}}$ + +$$ +\boldsymbol{\alpha}=\operatorname{softmax}(\boldsymbol{e}) \in \mathbb{R}^{N} +$$ + +$$ +\boldsymbol{o}=\sum_{i=1}^{N} \alpha_{i} \boldsymbol{h}_{i} \in \mathbb{R}^{h} +$$ + +- 有几种不同的方法来计算的注意力分数$\mathbf{e} \in \mathbb{R}^{N}$ + +### (5)注意力机制的特点 + +**注意力解决Seq2Seq瓶颈问题**,解码器可以直接查看全部encoder输出 + +**注意力有助于消除梯度问题** + +注意力提供了一些可解释性,可以通过注意图找出解码器关注的是什么;注意力允许网络对齐相关的单词 + +![](image/image_UD-b1r9xov.png) + +## 1.2 Transformer结构 + +### (1)总览 + +- 架构:Encoder-Decoder +- 输入:byte pair encoding + positional encoding +- 模型:多个Encoder-Decoder 堆叠 +- 输出:翻译单词的概率 +- 损失函数:标准的交叉熵损失 + +![](image/image_V6m9qoBwRn.png) + +### (2)Input Encoding + +输入:byte pair encoding + positional encoding + +#### Byte Pair Encoding(BPE) + +一种分词算法。从字符词汇开始;将最常见的n-gram转换为新的n-gram。 + +之前使用空格,之类的切分,词表必定不会包含所有单词,所以BPE将单词切分为更小的词元。 + +通过将稀有词和未知词编码为子词单元序列来解决OOV (out of vocabulary)问题 + +- 在上面的例子中,OOV单词“最低”将被分割成“最低”。 +- “low”和“lowest”之间的关系可以概括为“smart”和“smartest”。 + +原始词汇表: + +![](image/image_bL0lVz1Jc5.png) + +1、将各个字母添加到词表中: + +```bash +l, o, w, e, r, n, w, s, t, i, d +``` + +2、将频次为9的`es`对添加进去 + +```bash +l, o, w, e, r, n, w, s, t, i, d, es +``` + +3、因为`s`不单独出现,是和`es`一起出现,删除`s` + +```bash +l, o, w, e, r, n, w, t, i, d, es +``` + +4、将频次为9的`est`对添加进去,且`es`不是单独出现,和`est`一起出现,删除`es` + +```bash +l, o, w, e, r, n, w, t, i, d, est +``` + +循环这个过程,直到达到词表的大小要求即可。 + +#### Positional Encoding(PE) + +Transformer block对位置不同的相同单词不敏感;添加位置编码 **,以便相同的单词在不同位置具有不同的表示** + +$$ +P E_{(p o s, 2 i)}=\sin \left(\right. pos \left./ 10000^{2 i / d}\right) +$$ + +$$ +P E_{(p o s, 2 i+1)}=\cos \left(p o s / 10000^{2 i / d}\right) +$$ + +其中,$i$为词嵌入索引,范围为$[0, d/2]$ + +#### Input + +`Input = BPE + PE` + +![](image/image_lW4HW8XXn9.png) + +### (3)Transformer Block + +#### Dot-Product Attention + +输入: + +- 一个query向量$q$,一组键值对 $(k, v)$ +- $q$、k向量维度为$d_k$ +- $v$向量维度为$d_v$ + +输出: + +- **输出是**$v$**向量的加权和** +- 每个值的权重由查询和对应键的点积计算: $A(q, K, V)=\sum_{i} \frac{e^{q \cdot k_{i}}}{\sum_{j} e^{q \cdot k_{j}}} v_{i}$ +- 堆叠多个query为一个矩阵Q: $A(Q, K, V)=\operatorname{softmax}\left(Q K^{T}\right) V$ + +图示: + +$$ +A(Q, K, V)=\operatorname{softmax}\left(Q K^{T}\right) V +$$ + +![](image/image_XQhMJwhy0b.png) + +#### Scaled Dot-Product Attention + +点积注意力问题: + +- **如果**$d_k$**维度过大,则**$q^T \cdot k$\*\* 的方差也会变得很大\*\*​ +- 经过softmax后的注意力分布变得会很尖锐,梯度会变得很小 + +解决方法: + +- 带有缩放的点积注意力:$A(Q, K, V)=\operatorname{softmax}\left(\frac{Q K^{T}}{\sqrt{d_{k}}}\right) V$ + +![](image/image_sKkoVGB-oM.png) + +#### Self-attention + +让词向量自己选择彼此 + +Q, K, V是从一个句子的单词向量中得到的 + +![](image/image_06bTQPVvB4.png) + +#### Multi-head Attention + +不同的head:相同的计算,不同的参数 + +连接所有输出并馈送到线性层 + +$$ +\operatorname{head}_{i}=\mathrm{A}\left(Q W_{i}^{Q}, K W_{i}^{K}, V W_{i}^{V}\right) +$$ + +$$ +\operatorname{MultiHead}(Q, K, V)=\operatorname{Concat}\left(\right. head _{1}, \ldots, head \left._{h}\right) W^{O} +$$ + +![](image/image_fm7vgNroVM.png) + +#### Encoder Block + +在每一层中,Q, K, V与前一层的输出相同 + +![](image/image_uJ3PcGCl4g.png) + +#### Decoder Block + +**Mask self-attention**:单词只能看前面的单词,mask用于遮掩Encoder输出的未来的信息 + +**Encoder-Decoder 注意力**:query来自解码器,而key和value来自编码器 + +![](image/image_5QDKZMEFMM.png) + +### (4)Trick + +- 残差连接 +- 层归一化:将输入向量变化为均值为0,方差为1的向量 +- 标签平滑 +- ADAM优化器 +- 在加入残差之前,在每一层的训练中Dropout +- 带波束搜索(beam search)和长度惩罚(length penalties)的自回归解码 + +### (5)优缺点 + +优点 + +- Transformer是一个强大的模型,在许多NLP任务中被证明是有效的 +- Transformer适合**并行化** +- 证明了**注意机制**的有效性 +- 它还提供了对最近NLP进展,如BERT和GPT + +缺点: + +- 架构难以优化,对模型修改敏感 +- 每层注意力计算的复杂度高$O(n^2)$,对输入文本长度有要求,最大不能超过512 + +# 2.PLM(Pretrained Language Models) + +## 2.1 语言模型 + +语言建模是**预测即将出现的单词**的任务,计算即将到来的单词K的条件概率。 + +$$ +P\left(w_{n} \mid w_{1}, w_{2}, \cdots, w_{n-1}\right) +$$ + +![](image/image_W3M4Qwcnwh.png) + +**语言建模**:最基本和最重要的NLP任务 + +- 包含多种语言理解知识,如语言知识和事实知识 +- 只需要纯文本,不需要任何人工注释 + +通过语言模型学习到的语言知识可以很容易地转移到其他NLP任务中 + +NLP迁移学习有三种代表性模型 + +- Word2vec +- Pre-trained RNN +- GPT & BERT + +## 2.2 PLMs(Pre-trained Langue Models) + +PLM:对其他NLP任务具有强大可移植性的语言模型。word2vec是第一个PLM,如今的PLM都是基于Transformer的模型。 + +主要有两个分支: + +1、**Feature-based 方法** + +- 基于特征的方法中最具有代表性的模型是word2vec +- 使用PLM的输出作为下游模型的输入 + +2、**Fine-tuning 方法** + +- 最具代表性的微调方法模型是BERT +- 语言模型也是下游模型,其参数将被更新。 + +### (1)GPT + +[论文精读 GPT、GPT-2、GPT-3 | 37.2° Blog (wdndev.github.io)](https://wdndev.github.io/paper_reading/2.5.GPT_GPT-2_GPT-3/ "论文精读 GPT、GPT-2、GPT-3 | 37.2° Blog (wdndev.github.io)") + +受Transformer在不同NLP任务中的成功启发,GPT是第一个基于Transformer预训练PLM的工作; + +在自然语言处理领域,有很多各式各样的的任务,如问答,文本分类等。然而,现有的无标签文本非常多,而有标签的文本很少,这使得在这些有标签文本训练一个好的分辨模型很难,因为数据集太少。因此GPT第一个版本主要就是为了解决这个问题而提出的一套针对语言模型的预训练方法,使得大量的无标签数据能够被使用,并且对预训练好的模型加以微调使其适用于许多的下游任务。 + +在微调时,构造与子任务相关的输入,从而之只需要很少改变模型架构。 + +GPT = Transformer + left-to-right LM + +GPT在下游任务上fine-tuned + +![](image/image_SuDgHJBHpH.png) + +### (2)BERT + +[论文精读 BERT | 37.2° Blog (wdndev.github.io)](https://wdndev.github.io/paper_reading/2.2.BERT/ "论文精读 BERT | 37.2° Blog (wdndev.github.io)") + +BERT的出现使得我们能够在一个大的数据集上面训练好一个比较深的神经网络,然后应用在很多的NLP任务上面,这样既简化了NLP任务的训练,又提升了它的性能,所以BERT和它之后的一系列工作使得自然语言处理在过去三年中有了质的飞跃。 + +**输入**: + +![](image/image_XUW3G_UU7q.png) + +## 2.3 Masked LM的应用 + +**基本思想**:**使用双向的信息去预测目标token** + +将不同域的对象一起输入,并根据输入的对象预测目标对象 + +### (1)跨语言LM预训练 + +Translation Language Modeling (TLM) + +TLM目标将**MLM扩展到平行句对**(例如,英语-法语);为了预测一个被屏蔽的英语单词,该模型可以同时关注英语句子及其法语翻译,并鼓励对齐英语和法语表示 + +翻译语言建模(TLM)的目标是利用并行数据改进跨语言语言模型的预训练 + +![](image/image_gXb_vGTILY.png) + +### (2)跨模态LM预训练 + +自动语音识别(ASR)的视频和文本对 + +通过使用预训练模型将分层向量量化应用于视频衍生的特征,生成一系列“视觉词” + +鼓励模型关注视频中的高级语义和较长时间动态 + +## 2.5 PLMs前沿技术 + +### (1)GPT-3 + +[论文精读 GPT、GPT-2、GPT-3 | 37.2° Blog (wdndev.github.io)](https://wdndev.github.io/paper_reading/2.5.GPT_GPT-2_GPT-3/ "论文精读 GPT、GPT-2、GPT-3 | 37.2° Blog (wdndev.github.io)") + +GPT-3:大规模的PLM + +![](image/image_9d8b7OS19A.png) + +### (2)T5 + +Encoder-Decoder架构 + +**将所有NLP任务重新构建为统一的文本到文本格式**,其中输入和输出始终是文本字符串 + +![](image/image_B73F5KWINM.png) + +### (3)MoE + +加强Encoder-Decoder与MoE(Mixture of Experts)数十亿的参数 + +Gshard 600B参数 + +Switch Transformer 1571b参数 + +![](image/image_Mv1eqZkQJa.png) + +# 3.Transformers API教程 + +[transformers 教程 - 知乎 (zhihu.com)](https://www.zhihu.com/column/c_1400131016443506688 "transformers 教程 - 知乎 (zhihu.com)") diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_06bTQPVvB4.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_06bTQPVvB4.png" new file mode 100644 index 0000000..1f5882a Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_06bTQPVvB4.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_5QDKZMEFMM.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_5QDKZMEFMM.png" new file mode 100644 index 0000000..eecf858 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_5QDKZMEFMM.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_9d8b7OS19A.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_9d8b7OS19A.png" new file mode 100644 index 0000000..f0b55f4 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_9d8b7OS19A.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_B73F5KWINM.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_B73F5KWINM.png" new file mode 100644 index 0000000..d61e693 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_B73F5KWINM.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_EJ4Si-cwtZ.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_EJ4Si-cwtZ.png" new file mode 100644 index 0000000..a0ad941 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_EJ4Si-cwtZ.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_KaV_YxKSi0.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_KaV_YxKSi0.png" new file mode 100644 index 0000000..b32a34d Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_KaV_YxKSi0.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_Mv1eqZkQJa.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_Mv1eqZkQJa.png" new file mode 100644 index 0000000..afbab36 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_Mv1eqZkQJa.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_SuDgHJBHpH.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_SuDgHJBHpH.png" new file mode 100644 index 0000000..cab9ba5 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_SuDgHJBHpH.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_UD-b1r9xov.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_UD-b1r9xov.png" new file mode 100644 index 0000000..99477ee Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_UD-b1r9xov.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_V6m9qoBwRn.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_V6m9qoBwRn.png" new file mode 100644 index 0000000..431752d Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_V6m9qoBwRn.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_W3M4Qwcnwh.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_W3M4Qwcnwh.png" new file mode 100644 index 0000000..3670805 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_W3M4Qwcnwh.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_XQhMJwhy0b.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_XQhMJwhy0b.png" new file mode 100644 index 0000000..5c73972 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_XQhMJwhy0b.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_XUW3G_UU7q.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_XUW3G_UU7q.png" new file mode 100644 index 0000000..f470e04 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_XUW3G_UU7q.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_Ysno8YxWiH.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_Ysno8YxWiH.png" new file mode 100644 index 0000000..354a18e Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_Ysno8YxWiH.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_a5wPU_cFb5.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_a5wPU_cFb5.png" new file mode 100644 index 0000000..7f52762 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_a5wPU_cFb5.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_bL0lVz1Jc5.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_bL0lVz1Jc5.png" new file mode 100644 index 0000000..061a43f Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_bL0lVz1Jc5.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_fm7vgNroVM.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_fm7vgNroVM.png" new file mode 100644 index 0000000..bf3ef02 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_fm7vgNroVM.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_gXb_vGTILY.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_gXb_vGTILY.png" new file mode 100644 index 0000000..88e01e0 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_gXb_vGTILY.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_hlja8b3bUT.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_hlja8b3bUT.png" new file mode 100644 index 0000000..aa0c48b Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_hlja8b3bUT.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_lW4HW8XXn9.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_lW4HW8XXn9.png" new file mode 100644 index 0000000..07e38cb Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_lW4HW8XXn9.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_sKkoVGB-oM.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_sKkoVGB-oM.png" new file mode 100644 index 0000000..dd5fb23 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_sKkoVGB-oM.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_uJ3PcGCl4g.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_uJ3PcGCl4g.png" new file mode 100644 index 0000000..a4c51f6 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_uJ3PcGCl4g.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_vXL3CEzMiY.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_vXL3CEzMiY.png" new file mode 100644 index 0000000..6c0b6ab Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/3.Transformer\345\237\272\347\241\200/image/image_vXL3CEzMiY.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/4.Prompt Tuning & Delta Tuning.md" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/4.Prompt Tuning & Delta Tuning.md" new file mode 100644 index 0000000..2d0018c --- /dev/null +++ "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/4.Prompt Tuning & Delta Tuning.md" @@ -0,0 +1,1107 @@ +# 4.Prompt Tuning & Delta Tuning + +# 1.Background + +## 1.1 Fine Tuning : BERT + +BERT不管输入是单句还是两句,它实际上会对每一个token产生一个表征,这些表征可以进行分类。 + +如果做的是token级别的分类任务,比如NER,那么这些token的表征会送到一个分类层中,来对每个token进行分类。 + +如果做的是句子级别的分类任务,那么一般会把这个`[CLS]` token,代表句子级别语义,送到分类层中。 + +也就是时候,BERT对于不同的任务,会将不同的表征送到分类层中去,比从零学习的神经网络效果会好很多。 + +![](image/image_yhS6QGPnZH.png) + +**BERT : 关系抽取** + +![](image/image_dcrMxiLpRX.png) + +![](image/image_kwTLCEoVcT.png) + +1. 用 \[CLS] 进行分类 +2. Mention Pooling, 实体之间的所有token,concat到一起,然后再接分类层。 +3. Mention Pooling, 区分不同实体,在embedding加入Token type embedding;最后实体之间的所有token,concat到一起,然后再接分类层。考虑位置信息。 +4. Entity Markers : 词表中增加特殊的字符 + +可以看到这些做法是非常经验性的,并且没有那么直观,最后我们都需要去训练一个分类器,即需要随机初始化一个分类层。将得到的表征喂给它,再和模型一起微调训练。 + +这种方式越来不不适应于我们现在的时代。 + +## 1.2 GPT + +GPT是一个生成模型,生成第`n`个token取决于前 `n-1` token的概率。 + +将最后一个隐藏状态馈送到线性输出层 + +$$ +P\left(y \mid x^{1}, \ldots, x^{m}\right)=\operatorname{softmax}\left(h_{l}^{m} W_{y}\right) +$$ + +![](image/image_phkvP3T9qq.png) + +## 1.3 T5 + +- Encoder-decoder架构,11B参数 +- 通过简单的演示将任务转换为`seq2seq`方式 +- 解码器经过训练以输出所需的Tokens + +假如要做情感分类任务,此时并不是输出0或1这种没有含义的表示。而是直接输出一个可以代表情感的单词,比如positive,来代替分类。 + +这种做法的好处就是,把所有任务的范式统一成一个训练的框架,即seq2seq。 + +![](image/image_Kfsn0y8NoB.png) + +比如上图示一个QNLI的数据,它由一个question和一个sentence组成。将它们喂给T5的时候,会进行一些处理,比如会说`qnli question是什么`,`sentence是什么`。然后原来的target是0,现在改成了具体的单词entailment。 + +即解码器被训练来输出需要的单词,而并不是我们所需要的那个类。通过这些简单的demonstration就把这些任务映射成了seq2seq之后,T5模型就可以训练了,不再需要额外的分类层让它重新训练了。 + +这种做法表明了一种趋势。 + +## 1.4 GPT-3 + +- 175B参数的大模型 +- 参数量太大,微调很困难,采用prompts策略,应用到下游任务 + +![](image/image_2L-8nwBYxR.png) + +## 1.5 An Irreversible Trend + +### (1)Model Scaling + +- 更大的PLM往往会带来更好的性能 +- 更好的自然语言理解能力 +- 更好的自然语言生成质量 +- 更好的持续学习新知识的能力 + +![](image/image_r9YHDuWIyh.png) + +### (2)Difficult Tuning + +- 主要方式:Fine-tuning +- 更新所有参数困难 +- 为不同的任务保留单独的实例,占用存储空太大 +- 泛化不良,监督不足 +- 导致在研究中很少使用大规模PLM + +## 1.6 Effective Model Adaptation + +有两种方式高效使用大模型: + +- **任务和数据方面**:通过缩小模型微调和预训练之间的差距,使用**Prompt-learning**来增强少量学习能力 +- **优化方面**:使用**Delta Tuning**来微调具有数十亿参数的模型,并优化一小部分参数。用小参数的优化去驱动大模型 + +![](image/image_JgXU89pK0F.png) + +# 2.Prompt learning + +## 2.1 基本组成与流程介绍 + +### (1)Prompt-learning + +- 使用encoder作为PLMs的基本编码器 +- Fine-tuning为特定任务添加额外的神经网络 +- 微调所有参数 +- pre-training和fine-tuning之间存在差距。**pre-training以mask的方式进行训练,而fine-tuning以QA的方式进行微调,存在差距**。 + +![](image/image_anbir6L4MT.png) + +### (2)Template vs Verbalizer + +- 用 `[MASK]` 位置添加额外的上下文(Template) +- 使用标签标记单词(Verbalizer) +- 弥补pre-training and fine-tuning差距 + +![](image/image_-wg6AO7VYg.png) + +对于一个输入的实例,给它加一句话叫`it was [mask]`,即一个prompt,同时也给它保证成一个和预训练任务一样的形式。比如预训练中的MLM任务,这里也用mask的形式,让模型去预测该mask位置的单词。这里会预测出和预训练中一样的东西,即单词的概率分布。然后根据它子在整个词表上的分布,只去抽取其中想要的词。 + +比如说是一个情感分类任务,那么可能会有一个正类和负类。那么对于正类,就有good或wonderful等这种词来代表正类;而bad或terrible这种词来代表负类。 + +这里额外增加的这个上下文(`it wat [mask]`)称之为**模板(template)**;把标签映射到标签单词的映射器称为**verbalizer**; + +这种做法还有一个好处是,**不再需要考虑各种任务之间的区别**。同样一套数据,根据prompt设置的不同,或者verbalizer选择的不同,那么可以把不同的任务看成是不同的分类。 + +这样就可以把所有的分类,甚至是生成任务都可以通过prompt重新组织成同样一个范 + +### (3)Template :情绪分类 + +#### 使用模板提示 + +首先有一个输入`x = 'I love this moive'`。然后给它包一个prompt,变成` [x] Overall, it was a [z] movie`。这里`[z]`就是要预测的答案。最终经过prompt之后的数据变成了`x'='I love this moive. Overall it was a [z] movie.'`。 + +![](image/image_-QXJpvznck.png) + +#### 预测答案 + +此时模型会输出一个词表上的概率分布,但只选择需要的概率最大的标签单词,假设这里时`fantastic`。 + +![](image/image_74_LcTdOXB.png) + +#### 使用Verbalizer将答案映射到类标签 + +比如认为`fantastic`是一个positive的类。 + +这样就通过prompt-learning完成情感分类的pipeline。 + +![](image/image_IUlbJXwemq.png) + +### (4)Prompt-learning :注意事项 + +预训练模型: + +- Auto-regressive (GPT-1, GPT-2, GPT-3; OPT…) +- Masked Language Modeling (BERT, RoBERTa, DeBERTa) +- Encoder-Decoder (T5, BART) + +模板(Template): + +- Manually Design +- Auto Generation +- Textual or Continuous… + +用言语表达(Verbalizer): + +- Manually Design +- Expanding by external knowledge… + +## 2.2 PTM选取 + +### (1)生成式模型 + +Auto-regressive (GPT-1, GPT-2, GPT-3; OPT…) + +**一般的MASK放在最后,需要最后一个词**,不一定适用于特别长的文本。但是现在几乎超大级别的模型,都是用这种自回归的方式去训练的。这种训练方式非常适用于超大模型。 + +![](image/image_76YcInrFJD.png) + +### (2)MLM:分类模型,语言理解 + +Masked Language Modeling (BERT, RoBERTa, DeBERTa) + +如果要做理解任务或简单的分类任务,可能更好的办法用一个BERT或RoBERTa。 + +**MASK位置在中间,会把前后的上下文attention**。 + +![](image/image_UZjkK6WwJ2.png) + +### (3)Encoder-Decoder:T5 + +Encoder-Decoder (T5, BART) + +然后像T5模型,实际上在训练的时候,它已经有了一些所谓的比较简单的prompt。 + +但没有做的事情是,详细地指明这个prompt可以长什么样。也没有说如果最后生成了那些单词之后,还可不可以做进一步地处理。 + +T5模型有一个好处是比较通用,没有说像自回归模型那样那么不擅长做理解,又不像BERT模型那样不擅长做生成。 + +![](image/image_hkcRZkessT.png) + +## 2.3 Template构造 + +### (1)根据任务特点人为设计 + +考虑任务的特性是什么,比如关系抽取、文本分类、对话等等,我们要考虑任务的特性来构造不同的模板,此时可能需要个人的先验知识。 + +示例,利用人类的先验知识。对于不同的任务,确实可以利用人类的先验知识来设定不同的模板。 + +![](image/image_3KpWblLSm1.png) + +TL;DR:to long, don't reading + +#### **实体关系任务Template** + +- 复制模板中的实体 +- 预测细粒度实体类型 +- 汲取世界知识 + +假设输入是`London is one of the biggest cities in the world.`。假设要加一个模板,可以把`London`复制到模板中去,然后接上`is a [mask]`,来问模型`London`是什么类别。 + +这样对于每个输入,该模板开头的单词都不一样,表示不同的实体。这样来完成实体分类,从而达到抽取世界知识的效果。 + +通过这种做法,在少样本/零样本任务上表现特别好。 + +![](image/image_1f7t7L4gIH.png) + +#### **逻辑增强Template** + +人为定义的规则,加入分类任务中 + +也可以让模板变得非常复杂,这个例子中要抽取`Mark Twain`和`Langdon`的关系。 + +这里设计`prompt`的时候加入了一些人为定制的规则,如果要保证实体之间关系的类别,首先要保证它们实体本身类别的正确性。这样会带来额外一些制约,从而提升最终关系抽取分类的准确度。比如上图中的`x's parent was y`,必须要保证x和y都是person。 + +![](image/image_Qb3pJwD5eI.png) + +### (2)结构化,与规则相结合 + +- 所有提示符的**键值对** +- 将不同的任务组织成结构化的格式 + +提醒模型应该做什么。通过这种提醒,加上训练去微调模型,在模型内部做成一个区分,而且是不同维度上的区分。 + +首先定义一个`[Format]`表示格式是怎样的,然后定义一个`[Task]`表示数据集是怎么的,接着是`[Domain]`表示领域;然后是`[Question]`和`[Passage]`。 + +![](image/image_aex4PK_-wQ.png) + +**多个Template** + +- 为输入实例使用多个不同的提示 +- 降低即时工程成本 +- 稳定任务性能 + +方法 + +- 均匀平均 +- 加权平均 + +![](image/image_NL5XYFmg9s.png) + +### (3)自动生成与搜索优化 + +#### 基于现有单词的梯度搜索提示 + +> AUTOPROMPT: Eliciting Knowledge from Language Models with Automatically Generated Prompts. 2020 + +这里给定输入后,定义了一些触发单词,然后定义一个prompt模板,其中每个单词都是由mask来初始化,通过最大化后验标签的概率来优化这些prompt的嵌入,然后从这些触发单词中找到和优化后的嵌入所对应的单词当成prompt。这会导致最后生成的模板看起来没有什么具体含义(语义不通),但是它就是有效的,甚至比人类定义的prompt更加有效。 + +这带给我们一些启示,通过prompt的目的是触发想要的单词,实际上这并不一定需要人类的直觉来定义。也就是说,**对人类来说是最好的,对模型不一定是最好的**。 + +![](image/image_a4eEsxYk-J.png) + +#### 使用encoder-decoder模型生成prompts + +> LM-BFF: Making Pre-trained Language Models Better Few-shot Learners. 2021 + +利用额外的模型来生成prompt,比如对于一些情感分析类数据直接喂给T5,然后看哪些prompt加上这些数据后得到的准确度最高。选择最高的作为最终的模板。 + +![](image/image_FedizKcbQz.png) + +### (4)连续提示优化 + +- 通过优化连续提示,生成NLU模型 +- P-tuning v1:prompts 输入层(与重新参数化) +- P-tuning v2:prompts 每一层(如前缀微调) + +> P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Tasks + +也可以通过特殊的字符来产生prompt + +![](image/image_nodYY8JaXJ.png) + +## 2.4 Verbalizer构造 + +**Verbalizer就是把标签映射成标签单词的过程。** + +可以把标签定义为一个或多个词,如果是多个词的话, 那么就求这些词概率的(加权)平均值。然后比较类别之间的概率。 + +Verbalizer + +- 映射:answer → 不固定标签 +- Tokens : 预训练语言模型词汇表中的一个或多个Tokens +- Chunks : 由多个符号组成的词块 +- Sentence : 任意长度的句子 + +Construction + +- Hand-crafted +- Auto-generation + +### (1)人工构造Verbalizer + +- 人工设计与人类的先验知识 +- 从一个初始的标签词开始,释义和扩展 +- 从一个初始的标签词开始,使用外部知识并扩展 +- 用多个Tokens分解标签 +- 虚拟Tokens 和优化标签嵌入 + +任务和相应的语言表达方法的例子 + +![](image/image_iC7bUXmhGF.png) + +#### **Knowledgeable Prompting** + +- 标签 → 单词 +- 使用外部知识扩展标签词 + +> Knowledgeable prompt-tuning: Incorporating knowledge into prompt verbalizer for text classification. 2021 + +比如有一个问题:速度与加速度之间的关系是什么? 然后加一个模板,`xx question`。这个`MASK`会预测认为定义的标签单词的概率,比如数学(mathematics)、运动(basketbal)和它们的同义词。 + +接着定义一个verbalizer,先给定标签,比如这里是科学(SCIENCE)。然后用一个知识库去扩充它,接着去掉噪音词,再去选择最终需要的单词。 + +![](image/image_f0Y3OcSiZC.png) + +#### **Virtual Tokens as Label Words** + +- 将 \[MASK] tokens 的隐藏状态投影到嵌入空间并学习原型 +- 学习到的原型构成了语言表达器,并将PLM输出映射到相应的标签。 + +> Prototypical Verbalizer for Prompt-based Few-shot Tuning. 2021 + +除了用有意义的文本来构建之外,还可以用无意义的虚拟单词来表示标签单词。比如对于每个类别对应MASK的隐藏状态进行聚类,让不同的类别学到不同的簇,用这些簇中间的嵌入来表示最终的标签词。 + +![](image/image_R4haGMYzA9.png) + +## 2.5训练新范式 + +训练模型的演变 + +1. 传统: 随机初始化后从零训练 +2. BERT之后: 预训练-微调 +3. T5: 基于文本-文本格式的预训练-微调 +4. GPT: 预训练然后使用prompt\&in-context实现零/少样本学习 + +Prompt-learning 引入了新的学习策略 + +- pre-training,prompting,优化所有参数(中型模型,few-shot设置) +- pre-training,添加soft prompts,冻结模型和优化prompt embeddings (delta tuning perspective) +- pre-training与prompted data,zero-shot推理(Instruction tuning和T0) + +### (1)Pre-trained Prompt Tuning + +- 向输入层加入soft prompts (embeddings) +- **模型规模** +- 与11B PLM条件下的微调结果相当 +- 本质上是一种**参数高效(delta tuning)** 方法 + +![](image/image_xAepdLvMv8.png) + +给预训练注入Prompts + +- 完整数据:fine-tuning和prompt-tuning是可比较的 +- 数据少:只有tuning prompts性能较差 +- vanilla prompt tuning不能在低数据情况下有效推广 +- 在预训练中注入soft prompts,提高prompt tuning的泛化性 + +### (2)多任务预训练和人工prompts + +- 微调一个130B PLM与提示60个任务 +- 大幅提高zero-shot 能力 + +![](image/image_H6vBTLDW4P.png) + +使用人工编写的prompts来训练encoder-decoder模型 + +![](image/image_76VLSiZ6H6.png) + +对未见过的任务进行zero-shot(绿色)。在1300亿的模型上去训练60个任务,为每个任务收集一些prompt,然后可以在未见过的任务上进行推理。 + +![](image/image_4g71gJPx2C.png) + +## 2.6 应用 + +已知的应用: + +- 大多数NLP任务:NLU,生成,信息抽取,QA,翻译,... +- 具有位置相关性的任务可能比较困难,例如序列标记 + +视觉,多模态,生物医药 + +- 可以把输入加一些`soft token`,然后加上人工定义的医学领域的`prompt`,这样哪怕是小模型也可以在生物医学领域表现得特别好。 +- 可以应用到多模态上,本质上是训练图片和文本之间的理解。首先给图片中对象画个框,然后给定颜色,然后在文本中问,比如这个女人被框到了什么颜色里。让模型预测颜色是什么样的,从而让模型建立颜色和文字的理解。 + +![](image/image_uyOSGJnoC-.png) + +# 3.Delta Tuning + +和prompt-learning不同,delta tuning是从另一个角度来高效地微调模型。 思想是**模型绝大部分参数不变,只微调一小部分模型,就能驱动大模型**。 + +![](image/image_mNh2k3SRs-.png) + +**delta tuning**,对于每个任务只优化小部分参数,称之为**delta对象**,它们可能有各种各样的结构。这些delta对象代表解决任务能力的参数化表示。实际上这些参数所占空间很小,那么就没有资源压力。 + +实际上要考虑的地方也有很多,比如**模型的选择、delta对象如何设计**等等。 + +为什么参数高效的微调是有用的? + +- 实际上在过去是不可能实现的,因为过去所有的网络参数都是随机初始化的。因为**有了预训练之后**,有了大模型之后,才能用delta tuning的范式。 +- 因为大模型通过无监督的方式学习了**统一知识**,很多人认为在下游任务的微调中,只是把这个统一知识激发出来。即在下游微调任务中,并没有学习更多的知识,而是激发已经学到的知识。 + +delta tuing中的delta是什么? + +- **Addition-based (增量式)**:新插入模型原来不存在的参数,然后只训练这些额外插入的参数。 +- **Specification-based (指定式)**:指定模型哪些参数可以训练,哪些固定。 +- **Reparameterization-based (重参数化式)**:用低维子空间参数来重参数化原来存在的参数。 + +![](image/image_iwOPocGQYM.png) + +## 3.1 Addition-based (增量式) + +- 为Transformer层增加小的adapter(下图右边的网络模块) +- 实际上是**一个简单的双层神经网络,先缩小再非线性**,再还原:$h \leftarrow f\left(h W_{d}\right) W_{u}+h$(还有残差连接) +- 固定其他参数,只微调这些adapter +- 可训练参数只有整个模型的`0.5%~8%` + +这样**可以达到和全参数模型几乎相同的效果**。 + +![](image/image_slQb4nyeiE.png) + +增量式的方法还有一种,叫做prefix-tuning,它和prompt有些联系。 + +- Addition在线性层,layernorm之前加的, +- refix-tuning在每层的隐藏状态前增加soft token,然后只优化这些soft token。 + +![](image/image_0W34Pah0qQ.png) + +## 3.2 Specification-based (指定式) + +这里介绍一种名为BitFit的方法,它只是去**微调所有偏置(bias)**,也能达到和全参数微调差不多的效果(简单任务)。 + +![](image/image_reaW7pjKvo.png) + +## 3.3 Reparameterization-based (重参数化) + +重参数方法认为**优化过程可以在低维的空间完成**,将120个任务的优化压缩到低维的子空间里。比如在一个五维的空间中训练,然后还原到原来的参数里。此时可以发现在低维空间找到的解,可以在120个任务上表现的很好。 + +![](image/image_-kUn8rG4cH.png) + +**LoRA**认为**要优化的矩阵本质上是低秩的**,虽然实际上并不是低秩的,但可以强行做低秩分解,比如$1000 \times 1000$分解为 $1000 \times 2$和 $2 \times 1000$的,这样可以减少很多计算量。 + +![](image/image_CSEgoXK582.png) + +这些重参数化的方法本质上是有一些联系的,就是说**它们都基于相似的减少,模型的优化可以用很少代价来完成**。可以把它映射到一个低维或低秩的过程,用一个很简单的过程去完成这个模型的优化。 + +> \[1] Intrinsic dimensionality explains the effectiveness of language model tuning, 2020. +> \[2] LoRA: Low-Rank Adaptation of Large Langauge Models, 2021. +> \[3] Exploring low-dimensional intrinsic task subspace via prompt tuning, 2021. + +![](image/image_fCS2DayOnf.png) + +## 3.4 统一tuing + +这种联系可以扩展到更多的方法,最近有人建立了一种统一框架,把这三种方式联系起来。 + +![](image/image_F9GBR7lX1X.png) + +认为它们本质上可能在做同一件事情。 + +![](image/image_2FZ3PVdP1l.png) + +实际上它们都是**固定大模型参数,只微调很小部分的delta对象**。因此可以推导出更加通用的delta tuning变体。 + +![](image/image_N6kZJ2623D.png) + +在100多个NLP任务上进行了实验表明,delta tuning确实效果比较好,比如LoRA(LR)在100多个任务上只微调了0.38%的参数就能达到平均和全参数微调(FT)差不多的效果。 + +![](image/image_Qz_hofI_iT.png) + +然后还可以发现不同的任务适用于不同的结构,那么是否存在一个最优结构呢。 + +比如可以**用自动机器学习的方法来搜索这个结构**,在每个位置设定一个开关,表示使用哪种delta tuning方式。这样就能找到一个比较稀疏的解,能让模型的效果特别好。 + +![](image/image_b7dJNwf1M5.png) + +下图横轴表示参数量的稀疏程度(由多变少),纵轴代表准确率。当参数量变少到万分之一的时候,其他的delta tuning方法都有显著的下降,而通过自动搜索方法得到的解它的效果和全参数微调还是保持相差不大。 + +![](image/image_frf5UO_Sfk.png) + +通过自动搜索的方法用更少的参数去探索一种极限。同时delta tuning还具备非常好的**可迁移性**,这几种delta tuning在不同的任务上得到的图像差不多。 + +![](image/image_rOQMKqxYCb.png) + +## 3.5 总结 + +- **delta tuning在超大规模的模型上非常高效** +- 它的结构随着模型的增加变得越发不重要 + +# 4.OpenPrompt + +## 4.1 OpenPrompt + +![](image/image_NYxpgn7zp3.png) + +Prompt其实可以自定义很多不同的Template/verbalizer,比如一个普通的情感分类任务,模板可能是`it was__`。 + +模板可能不同,mask位置可能不同,verbalizer也可能不同。 + +之前通常将模板写死到代码中,不方便我们尝试不同的模板,也无法灵活地找到mask的位置。 +OpenPrompt工具包的目的是解决上面所说的问题,**定义统一的prompt tuning范式**,使用不同的模板,定义不同的verbalizer,去实现不同的任务。 + +![](image/image_FbnPWg_-BI.png) + +上图是API交互。`PromptDataset`的输出是一个`Tempate`,包裹上输入之后,被`PromptTokenizer`分词成可以输入模型的数据。`PromptModel`把该输入中的soft token转换成`TemplateEmbeddings`,再输入预训练模型(PLM),最后把mask的位置的输出抽出来,送给`Verbalizer`进行预测。 + +除此之外,通过`PromptTrainer`类提供了不同的训练方式。 + +下面简单看一下如何使用OpenPrompt。 + +1. 定义一个任务 +2. 选择预训练模型 +3. 定义一个Template +4. 定义一个Verbalizer +5. 定义一个PromptModel +6. 训练并推理 + +一些Template的例子: + +![](image/image_WqnbN_DY7N.png) + +实施各种快速学习管道 (灰线是暂时没有出现的方法) + +- 修改单独的模块和创建新的方法 +- 将现有方法应用于其他场景 + +![](image/image_44ZRuIYCfM.png) + +## 4.2 OpenPrompt demo + +下面用一个实例来进行演示。 + +[OpenPrompt Demo - Colaboratory (google.com)](https://colab.research.google.com/drive/1bQnMvui8Zb6EwNXWiC3DYKr8AH0IEbQa#scrollTo=j1r0_pLwaqtZ "OpenPrompt Demo - Colaboratory (google.com)") + +#### (1)安装包 + +首先安装需要的包 + +```bash +!pip install transformers --quiet +!pip install datasets==2.0 --quiet +!pip install openprompt --quiet +!pip install torch --quiet + +``` + +#### (2)加载数据集 + +```python +from datasets import load_dataset +raw_dataset = load_dataset('super_glue', 'cb', cache_dir="../datasets/.cache/huggingface_datasets") +raw_dataset['train'][0] + +``` + +```text +{'premise': 'It was a complex language. Not written down but handed down. One might say it was peeled down.', + 'hypothesis': 'the language was peeled down', + 'idx': 0, + 'label': 0} + +``` + +并查看样本。 + +#### (3)加载模型和tokenizer + +下面加载模型和分词器: + +```text +from openprompt.plms import load_plm +plm, tokenizer, model_config, WrapperClass = load_plm("t5", "t5-base") + +``` + +#### (4)构造输入 + +**构建输入**,将原始数据集处理成OpenPrompt可以使用的格式: + +```text +from openprompt.data_utils import InputExample + +dataset = {} +for split in ['train', 'validation', 'test']: + dataset[split] = [] + for data in raw_dataset[split]: + input_example = InputExample(text_a = data['premise'], text_b = data['hypothesis'], label=int(data['label']), guid=data['idx']) + dataset[split].append(input_example) +print(dataset['train'][0]) + +``` + +```text +{ + "guid": 0, + "label": 0, + "meta": {}, + "text_a": "It was a complex language. Not written down but handed down. One might say it was peeled down.", + "text_b": "the language was peeled down", + "tgt_text": null +} + +``` + +可以看到,有一部分叫`text_a`,另一部分输入叫`text_b`。还有刚才提到的`meta`信息。下面 + +**定义模板文本**: + +```text +from openprompt.prompts import ManualTemplate +template_text = '{"placeholder":"text_a"} Deduction: {"placeholder":"text_b"}. Is it correct? {"mask"}.' +mytemplate = ManualTemplate(tokenizer=tokenizer, text=template_text) + +``` + +模板定义如上所示,在mask位置输出我们想要的答案。 + +**使用标记器包装器类对wrapped\_example进行标记** + +为了更好地理解模板包裹了什么,我们看一个例子 + +```text +wrapped_example = mytemplate.wrap_one_example(dataset['train'][0]) +wrapped_example + +``` + +```text +[[{'text': 'It was a complex language. Not written down but handed down. One might say it was peeled down.', + 'loss_ids': 0, + 'shortenable_ids': 1}, + {'text': ' Deduction:', 'loss_ids': 0, 'shortenable_ids': 0}, + {'text': ' the language was peeled down', + 'loss_ids': 0, + 'shortenable_ids': 1}, + {'text': '. Is it correct?', 'loss_ids': 0, 'shortenable_ids': 0}, + {'text': '', 'loss_ids': 1, 'shortenable_ids': 0}, + {'text': '.', 'loss_ids': 0, 'shortenable_ids': 0}], + {'guid': 0, 'label': 0}] + +``` + +`shortenable_ids`表示是否可压缩,`loss_ids`表示是否需要计算损失。 + +接下来处理这样的输出: + +```text +wrapped_t5tokenizer = WrapperClass(max_seq_length=128, decoder_max_length=3, tokenizer=tokenizer,truncate_method="head") +# or +from openprompt.plms import T5TokenizerWrapper +wrapped_t5tokenizer= T5TokenizerWrapper(max_seq_length=128, decoder_max_length=3, tokenizer=tokenizer,truncate_method="head") + +# You can see what a tokenized example looks like by +tokenized_example = wrapped_t5tokenizer.tokenize_one_example(wrapped_example, teacher_forcing=False) +print(tokenized_example) +print(tokenizer.convert_ids_to_tokens(tokenized_example['input_ids'])) +print(tokenizer.convert_ids_to_tokens(tokenized_example['decoder_input_ids'])) + +``` + +```text +{'input_ids': [94, 47, 3, 9, 1561, 1612, 5, 933, 1545, 323, 68, 14014, 323, 5, 555, 429, 497, 34, 47, 158, 400, 26, 323, 5, 374, 8291, 10, 8, 1612, 47, 158, 400, 26, 323, 3, 5, 27, 7, 34, 2024, 58, 32099, 3, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'decoder_input_ids': [0, 32099, 0], 'loss_ids': [0, 1, 0]} +['▁It', '▁was', '▁', 'a', '▁complex', '▁language', '.', '▁Not', '▁written', '▁down', '▁but', '▁handed', '▁down', '.', '▁One', '▁might', '▁say', '▁it', '▁was', '▁pe', 'ele', 'd', '▁down', '.', '▁De', 'duction', ':', '▁the', '▁language', '▁was', '▁pe', 'ele', 'd', '▁down', '▁', '.', '▁I', 's', '▁it', '▁correct', '?', '', '▁', '.', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''] +['', '', ''] + +``` + +这样对整个数据集进行处理: + +```text +model_inputs = {} +for split in ['train', 'validation', 'test']: + model_inputs[split] = [] + for sample in dataset[split]: + tokenized_example = wrapped_t5tokenizer.tokenize_one_example(mytemplate.wrap_one_example(sample), teacher_forcing=False) + model_inputs[split].append(tokenized_example) + +``` + +#### (5)构造dataloader + +dataloader对象是一个可迭代的对象,迭代它将为模型的每次前向传递提供输入张量。 + +下面构建数据加载器: + +```text +from openprompt import PromptDataLoader + +train_dataloader = PromptDataLoader(dataset=dataset["train"], template=mytemplate, tokenizer=tokenizer, + tokenizer_wrapper_class=WrapperClass, max_seq_length=256, decoder_max_length=3, + batch_size=4,shuffle=True, teacher_forcing=False, predict_eos_token=False, + truncate_method="head") + +``` + +#### (6)构建Verbalizer + +```text +from openprompt.prompts import ManualVerbalizer +import torch + +# for example the verbalizer contains multiple label words in each class +myverbalizer = ManualVerbalizer(tokenizer, num_classes=3, + label_words=[["yes"], ["no"], ["maybe"]]) + +print(myverbalizer.label_words_ids) +logits = torch.randn(2,len(tokenizer)) # creating a pseudo output from the plm, and +print(myverbalizer.process_logits(logits)) + +``` + +这里指定了三个标签单词,分别对应三种类别。下面看verbalizer加工后的形状: + +```text +Parameter containing: +tensor([[[4273]], + + [[ 150]], + + [[2087]]]) +tensor([[-2.6867, -0.1306, -2.9124], + [-0.6579, -0.8735, -2.7400]]) + +``` + +#### (7)分类Pipeline + +下面定义一个分类Pipeline。 + +```text +from openprompt import PromptForClassification + +use_cuda = torch.cuda.is_available() +print("GPU enabled? {}".format(use_cuda)) +prompt_model = PromptForClassification(plm=plm,template=mytemplate, verbalizer=myverbalizer, freeze_plm=False) +if use_cuda: + prompt_model= prompt_model.cuda() + +``` + +#### (8)GPU训练 + +把模型移到GPU上。在GPU上进行训练: + +```text +# Now the training is standard +from transformers import AdamW, get_linear_schedule_with_warmup +loss_func = torch.nn.CrossEntropyLoss() +no_decay = ['bias', 'LayerNorm.weight'] +# it's always good practice to set no decay to biase and LayerNorm parameters +optimizer_grouped_parameters = [ + {'params': [p for n, p in prompt_model.named_parameters() if not any(nd in n for nd in no_decay)], 'weight_decay': 0.01}, + {'params': [p for n, p in prompt_model.named_parameters() if any(nd in n for nd in no_decay)], 'weight_decay': 0.0} +] + +optimizer = AdamW(optimizer_grouped_parameters, lr=1e-4) + +for epoch in range(5): + tot_loss = 0 + for step, inputs in enumerate(train_dataloader): + if use_cuda: + inputs = inputs.cuda() + logits = prompt_model(inputs) + labels = inputs['label'] + loss = loss_func(logits, labels) + loss.backward() + tot_loss += loss.item() + optimizer.step() + optimizer.zero_grad() + if step %100 ==1: + print("Epoch {}, average loss: {}".format(epoch, tot_loss/(step+1)), flush=True) + +``` + +```text +Epoch 0, average loss: 0.6918223202228546 +Epoch 1, average loss: 0.21019931323826313 +Epoch 2, average loss: 0.0998007245361805 +Epoch 3, average loss: 0.0021352323819883168 +Epoch 4, average loss: 0.00015113733388716355 + +``` + +#### (9)评估模型 + +最后我们评估一下模型效果: + +```text +validation_dataloader = PromptDataLoader(dataset=dataset["validation"], template=mytemplate, tokenizer=tokenizer, + tokenizer_wrapper_class=WrapperClass, max_seq_length=256, decoder_max_length=3, + batch_size=4,shuffle=False, teacher_forcing=False, predict_eos_token=False, + truncate_method="head") + +allpreds = [] +alllabels = [] +for step, inputs in enumerate(validation_dataloader): + if use_cuda: + inputs = inputs.cuda() + logits = prompt_model(inputs) + labels = inputs['label'] + alllabels.extend(labels.cpu().tolist()) + allpreds.extend(torch.argmax(logits, dim=-1).cpu().tolist()) + +acc = sum([int(i==j) for i,j in zip(allpreds, alllabels)])/len(allpreds) +print(acc) + +``` + +```text +0.9107142857142857 + +``` + +# 5.OpenDelta介绍 + +下面介绍OpenDelta工具,用于delta tuning,它的特点有: + +- 干净:不需要编辑backonePTM的代码。 +- 简单:从全模型tuning迁移到delta-tuning只需要3行代码。 +- 可持续:外部库的进化不需要更新。 +- 可扩展:各种ptm可以共享相同的delta-tuning代码。 +- 灵活:能够应用delta-tuning到(几乎)任何位置。 + +![](image/image_18rpspiBnM.png) + +非常少的修改: + +![](image/image_LiWuhUVOlz.png) + +支持非常多的模型。 + +还是来看一个实例吧。 + +首先安装需要的包。 + +```text +!pip install transformers --quiet +!pip install datasets==2.0 --quiet +!pip install opendelta==0.2.2 --quiet + +``` + +在开头载入需要用到的包: + +```text +from dataclasses import dataclass, field +from typing import Optional, List +from transformers import Seq2SeqTrainingArguments, TrainerCallback +from datasets import load_dataset, load_metric, concatenate_datasets +import transformers +from transformers import ( + AutoConfig, + AutoModelForSeq2SeqLM, + AutoTokenizer, + HfArgumentParser, + MBartTokenizer, + default_data_collator, + set_seed, +) +from datasets import load_dataset +import torch +import numpy as np +import random + +``` + +定义模型的参数: + +```text +@dataclass +class ModelArguments: + """ + Arguments pertaining to which model/config/tokenizer we are going to fine-tune from. + """ + model_name_or_path: str = field( + metadata={"help": "Path to pretrained model or model identifier from huggingface.co/models"} + ) + config_name: Optional[str] = field( + default=None, metadata={"help": "Pretrained config name or path if not the same as model_name"} + ) + tokenizer_name: Optional[str] = field( + default=None, metadata={"help": "Pretrained tokenizer name or path if not the same as model_name"} + ) + cache_dir: Optional[str] = field( + default=None, + metadata={"help": "Where to store the pretrained models downloaded from huggingface.co"}, + ) + use_fast_tokenizer: bool = field( + default=True, + metadata={"help": "Whether to use one of the fast tokenizer (backed by the tokenizers library) or not."}, + ) + model_revision: str = field( + default="main", + metadata={"help": "The specific model version to use (can be a branch name, tag name or commit id)."}, + ) + use_auth_token: bool = field( + default=False, + metadata={ + "help": "Will use the token generated when running `transformers-cli login` (necessary to use this script " + "with private models)." + }, + ) + +model_args = ModelArguments(model_name_or_path="t5-large", ) + +``` + +使用传统的方式加载模型: + +```text +config = AutoConfig.from_pretrained( + model_args.config_name if model_args.config_name else model_args.model_name_or_path, + cache_dir=model_args.cache_dir, + revision=model_args.model_revision, + use_auth_token=True if model_args.use_auth_token else None, +) +config.dropout_rate = 0.0 +tokenizer = AutoTokenizer.from_pretrained( + model_args.tokenizer_name if model_args.tokenizer_name else model_args.model_name_or_path, + cache_dir=model_args.cache_dir, + use_fast=model_args.use_fast_tokenizer, + revision=model_args.model_revision, + use_auth_token=True if model_args.use_auth_token else None, +) +model = AutoModelForSeq2SeqLM.from_pretrained( + model_args.model_name_or_path, + from_tf=bool(".ckpt" in model_args.model_name_or_path), + config=config, + cache_dir=model_args.cache_dir, + revision=model_args.model_revision, + use_auth_token=True if model_args.use_auth_token else None, +) +model.resize_token_embeddings(len(tokenizer)) + +``` + +下面演示一下opendelta提供的可视化功能: + +```text +from opendelta import Visualization +Visualization(model).structure_graph(); + +``` + +![](image/image_-zDA-Ypg2O.png) + +```python +root +├── shared(Embedding),lm_head(Linear) weight:[32100, 1024] +├── encoder (T5Stack) +│ ├── embed_tokens (Embedding) weight:[32100, 1024] +│ ├── block (ModuleList) +│ │ ├── 0 (T5Block) +│ │ │ └── layer (ModuleList) +│ │ │ ├── 0 (T5LayerSelfAttention) +│ │ │ │ ├── SelfAttention (T5Attention) +│ │ │ │ │ ├── q,k,v,o(Linear) weight:[1024, 1024] +│ │ │ │ │ └── relative_attention_bias (Embedding) weight:[32, 16] +│ │ │ │ └── layer_norm (T5LayerNorm) weight:[1024] +│ │ │ └── 1 (T5LayerFF) +│ │ │ ├── DenseReluDense (T5DenseActDense) +│ │ │ │ ├── wi (Linear) weight:[4096, 1024] +│ │ │ │ └── wo (Linear) weight:[1024, 4096] +│ │ │ └── layer_norm (T5LayerNorm) weight:[1024] +│ │ └── 1-23(T5Block) +│ │ └── layer (ModuleList) +│ │ ├── 0 (T5LayerSelfAttention) +│ │ │ ├── SelfAttention (T5Attention) +│ │ │ │ └── q,k,v,o(Linear) weight:[1024, 1024] +│ │ │ └── layer_norm (T5LayerNorm) weight:[1024] +│ │ └── 1 (T5LayerFF) +│ │ ├── DenseReluDense (T5DenseActDense) +│ │ │ ├── wi (Linear) weight:[4096, 1024] +│ │ │ └── wo (Linear) weight:[1024, 4096] +│ │ └── layer_norm (T5LayerNorm) weight:[1024] +│ └── final_layer_norm (T5LayerNorm) weight:[1024] +└── decoder (T5Stack) + ├── embed_tokens (Embedding) weight:[32100, 1024] + ├── block (ModuleList) + │ ├── 0 (T5Block) + │ │ └── layer (ModuleList) + │ │ ├── 0 (T5LayerSelfAttention) + │ │ │ ├── SelfAttention (T5Attention) + │ │ │ │ ├── q,k,v,o(Linear) weight:[1024, 1024] + │ │ │ │ └── relative_attention_bias (Embedding) weight:[32, 16] + │ │ │ └── layer_norm (T5LayerNorm) weight:[1024] + │ │ ├── 1 (T5LayerCrossAttention) + │ │ │ ├── EncDecAttention (T5Attention) + │ │ │ │ └── q,k,v,o(Linear) weight:[1024, 1024] + │ │ │ └── layer_norm (T5LayerNorm) weight:[1024] + │ │ └── 2 (T5LayerFF) + │ │ ├── DenseReluDense (T5DenseActDense) + │ │ │ ├── wi (Linear) weight:[4096, 1024] + │ │ │ └── wo (Linear) weight:[1024, 4096] + │ │ └── layer_norm (T5LayerNorm) weight:[1024] + │ └── 1-23(T5Block) + │ └── layer (ModuleList) + │ ├── 0 (T5LayerSelfAttention) + │ │ ├── SelfAttention (T5Attention) + │ │ │ └── q,k,v,o(Linear) weight:[1024, 1024] + │ │ └── layer_norm (T5LayerNorm) weight:[1024] + │ ├── 1 (T5LayerCrossAttention) + │ │ ├── EncDecAttention (T5Attention) + │ │ │ └── q,k,v,o(Linear) weight:[1024, 1024] + │ │ └── layer_norm (T5LayerNorm) weight:[1024] + │ └── 2 (T5LayerFF) + │ ├── DenseReluDense (T5DenseActDense) + │ │ ├── wi (Linear) weight:[4096, 1024] + │ │ └── wo (Linear) weight:[1024, 4096] + │ └── layer_norm (T5LayerNorm) weight:[1024] + └── final_layer_norm (T5LayerNorm) weight:[1024] + +``` + +下面演示同一个backbone(T5)加上不同delta: + +```text +from opendelta import AutoDeltaConfig, AutoDeltaModel + +delta_model_spelling = AutoDeltaModel.from_finetuned("thunlp/Spelling_Correction_T5_LRAdapter_demo", backbone_model=model) +delta_model_spelling.detach() + +delta_model_topic = AutoDeltaModel.from_finetuned("thunlp/Question_Topic_T5-large_Compacter", backbone_model=model) +delta_model_topic.detach() + +delta_model_fact = AutoDeltaModel.from_finetuned("thunlp/FactQA_T5-large_Adapter", backbone_model=model) +delta_model_fact.detach() + +``` + +下面定义多任务服务函数: + +```text +def multitask_serving(input_text): + # 首先进行拼写改错 + input_ids = tokenizer(input_text, return_tensors="pt").input_ids#.cuda() + delta_model_spelling.attach() + answers_ids =model.generate(input_ids=input_ids, max_length=20, num_beams=4) + input_text = tokenizer.decode(answers_ids[0], skip_special_tokens=True) + print("Correct Spelling: {}".format(input_text)) + delta_model_spelling.detach() + # 然后传入主题分类模型 + delta_model_topic.attach() + input_ids = tokenizer(input_text, return_tensors="pt").input_ids#.cuda() + answers_ids =model.generate(input_ids=input_ids, max_length=20, num_beams=4) + topic = tokenizer.decode(answers_ids[0], skip_special_tokens=True) + delta_model_topic.detach() + print("Question Topic: {}".format(topic)) + # 最后做问答 + delta_model_fact.attach() + input_ids = tokenizer(input_text, return_tensors="pt").input_ids#.cuda() + answers_ids =model.generate(input_ids=input_ids, max_length=20, num_beams=4) + input_text = tokenizer.decode(answers_ids[0], skip_special_tokens=True) + delta_model_fact.detach() + print("Question Answer: {}".format(input_text)) + +``` + +多个任务的切换通过先`attach`再`detach`。 + +这里展示两个例子: + +```text +multitask_serving("When was Beiiing olymp#ic heldd ?") +multitask_serving("What the commmon career of Newton ad eintesin?") + +``` + +```text +Correct Spelling: When was Beijing Olympic held? +Question Topic: The question's topic is sports. +Question Answer: 2008 +Correct Spelling: What was the common career of Newton and Einstein? +Question Topic: The question's topic is science. +Question Answer: Physicists + +``` + +可以看到拼写模型把修正后的输入给了主题模型和问答模型。 + +如果我们想把这个预训练模型回退到没有加delta模型的模型,只要执行`detach`即可: + +```text +delta_model_spelling.detach() +delta_model_topic.detach() +delta_model_fact.detach() + +``` diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_-QXJpvznck.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_-QXJpvznck.png" new file mode 100644 index 0000000..a712a23 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_-QXJpvznck.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_-kUn8rG4cH.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_-kUn8rG4cH.png" new file mode 100644 index 0000000..fc4042a Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_-kUn8rG4cH.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_-wg6AO7VYg.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_-wg6AO7VYg.png" new file mode 100644 index 0000000..c5602d9 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_-wg6AO7VYg.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_-zDA-Ypg2O.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_-zDA-Ypg2O.png" new file mode 100644 index 0000000..8758e6c Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_-zDA-Ypg2O.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_0W34Pah0qQ.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_0W34Pah0qQ.png" new file mode 100644 index 0000000..e00dbea Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_0W34Pah0qQ.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_18rpspiBnM.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_18rpspiBnM.png" new file mode 100644 index 0000000..5ca3735 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_18rpspiBnM.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_1f7t7L4gIH.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_1f7t7L4gIH.png" new file mode 100644 index 0000000..ec1c140 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_1f7t7L4gIH.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_2FZ3PVdP1l.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_2FZ3PVdP1l.png" new file mode 100644 index 0000000..d74cc2a Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_2FZ3PVdP1l.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_2L-8nwBYxR.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_2L-8nwBYxR.png" new file mode 100644 index 0000000..9dc5b06 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_2L-8nwBYxR.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_3KpWblLSm1.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_3KpWblLSm1.png" new file mode 100644 index 0000000..00ec123 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_3KpWblLSm1.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_44ZRuIYCfM.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_44ZRuIYCfM.png" new file mode 100644 index 0000000..ebfe319 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_44ZRuIYCfM.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_4g71gJPx2C.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_4g71gJPx2C.png" new file mode 100644 index 0000000..208b6a5 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_4g71gJPx2C.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_74_LcTdOXB.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_74_LcTdOXB.png" new file mode 100644 index 0000000..5ff248a Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_74_LcTdOXB.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_76VLSiZ6H6.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_76VLSiZ6H6.png" new file mode 100644 index 0000000..44c383f Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_76VLSiZ6H6.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_76YcInrFJD.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_76YcInrFJD.png" new file mode 100644 index 0000000..eb1a3d1 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_76YcInrFJD.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_CSEgoXK582.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_CSEgoXK582.png" new file mode 100644 index 0000000..5e14a02 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_CSEgoXK582.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_F9GBR7lX1X.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_F9GBR7lX1X.png" new file mode 100644 index 0000000..019132e Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_F9GBR7lX1X.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_FbnPWg_-BI.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_FbnPWg_-BI.png" new file mode 100644 index 0000000..c2f5550 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_FbnPWg_-BI.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_FedizKcbQz.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_FedizKcbQz.png" new file mode 100644 index 0000000..cc2a588 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_FedizKcbQz.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_H6vBTLDW4P.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_H6vBTLDW4P.png" new file mode 100644 index 0000000..03dc355 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_H6vBTLDW4P.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_IUlbJXwemq.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_IUlbJXwemq.png" new file mode 100644 index 0000000..7737c18 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_IUlbJXwemq.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_JgXU89pK0F.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_JgXU89pK0F.png" new file mode 100644 index 0000000..39217a4 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_JgXU89pK0F.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_Kfsn0y8NoB.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_Kfsn0y8NoB.png" new file mode 100644 index 0000000..3bf8335 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_Kfsn0y8NoB.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_LiWuhUVOlz.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_LiWuhUVOlz.png" new file mode 100644 index 0000000..44d0af3 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_LiWuhUVOlz.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_N6kZJ2623D.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_N6kZJ2623D.png" new file mode 100644 index 0000000..cc19a52 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_N6kZJ2623D.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_NL5XYFmg9s.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_NL5XYFmg9s.png" new file mode 100644 index 0000000..be66a17 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_NL5XYFmg9s.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_NYxpgn7zp3.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_NYxpgn7zp3.png" new file mode 100644 index 0000000..275d5f9 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_NYxpgn7zp3.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_Qb3pJwD5eI.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_Qb3pJwD5eI.png" new file mode 100644 index 0000000..3cd867f Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_Qb3pJwD5eI.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_Qz_hofI_iT.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_Qz_hofI_iT.png" new file mode 100644 index 0000000..b52ca0e Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_Qz_hofI_iT.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_R4haGMYzA9.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_R4haGMYzA9.png" new file mode 100644 index 0000000..45da434 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_R4haGMYzA9.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_UZjkK6WwJ2.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_UZjkK6WwJ2.png" new file mode 100644 index 0000000..245cb3a Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_UZjkK6WwJ2.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_WqnbN_DY7N.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_WqnbN_DY7N.png" new file mode 100644 index 0000000..f9e9a4c Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_WqnbN_DY7N.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_a4eEsxYk-J.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_a4eEsxYk-J.png" new file mode 100644 index 0000000..dd2dd5e Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_a4eEsxYk-J.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_aex4PK_-wQ.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_aex4PK_-wQ.png" new file mode 100644 index 0000000..fa73dad Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_aex4PK_-wQ.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_anbir6L4MT.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_anbir6L4MT.png" new file mode 100644 index 0000000..5915b1c Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_anbir6L4MT.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_b7dJNwf1M5.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_b7dJNwf1M5.png" new file mode 100644 index 0000000..ebe1749 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_b7dJNwf1M5.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_dcrMxiLpRX.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_dcrMxiLpRX.png" new file mode 100644 index 0000000..697389d Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_dcrMxiLpRX.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_f0Y3OcSiZC.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_f0Y3OcSiZC.png" new file mode 100644 index 0000000..257fe91 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_f0Y3OcSiZC.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_fCS2DayOnf.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_fCS2DayOnf.png" new file mode 100644 index 0000000..b07c429 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_fCS2DayOnf.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_frf5UO_Sfk.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_frf5UO_Sfk.png" new file mode 100644 index 0000000..145df52 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_frf5UO_Sfk.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_hkcRZkessT.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_hkcRZkessT.png" new file mode 100644 index 0000000..a8c224f Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_hkcRZkessT.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_iC7bUXmhGF.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_iC7bUXmhGF.png" new file mode 100644 index 0000000..c53a392 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_iC7bUXmhGF.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_iwOPocGQYM.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_iwOPocGQYM.png" new file mode 100644 index 0000000..ff37795 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_iwOPocGQYM.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_kwTLCEoVcT.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_kwTLCEoVcT.png" new file mode 100644 index 0000000..ef4a2dd Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_kwTLCEoVcT.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_mNh2k3SRs-.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_mNh2k3SRs-.png" new file mode 100644 index 0000000..bae92e0 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_mNh2k3SRs-.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_nodYY8JaXJ.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_nodYY8JaXJ.png" new file mode 100644 index 0000000..49022c9 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_nodYY8JaXJ.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_phkvP3T9qq.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_phkvP3T9qq.png" new file mode 100644 index 0000000..befb219 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_phkvP3T9qq.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_r9YHDuWIyh.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_r9YHDuWIyh.png" new file mode 100644 index 0000000..deba9ea Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_r9YHDuWIyh.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_rOQMKqxYCb.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_rOQMKqxYCb.png" new file mode 100644 index 0000000..0f604bd Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_rOQMKqxYCb.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_reaW7pjKvo.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_reaW7pjKvo.png" new file mode 100644 index 0000000..95a3717 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_reaW7pjKvo.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_slQb4nyeiE.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_slQb4nyeiE.png" new file mode 100644 index 0000000..12cec68 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_slQb4nyeiE.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_uyOSGJnoC-.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_uyOSGJnoC-.png" new file mode 100644 index 0000000..6c194cf Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_uyOSGJnoC-.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_xAepdLvMv8.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_xAepdLvMv8.png" new file mode 100644 index 0000000..cca3502 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_xAepdLvMv8.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_yhS6QGPnZH.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_yhS6QGPnZH.png" new file mode 100644 index 0000000..61aa420 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/4.Prompt Tuning & Delta Tuning/image/image_yhS6QGPnZH.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251.md" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251.md" new file mode 100644 index 0000000..f77c2b0 --- /dev/null +++ "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251.md" @@ -0,0 +1,563 @@ +# 5.高效训练&模型压缩 + +# 1.背景介绍 + +## 1.1 CPU & GPU + +预训练语言模型以每年十倍的速度增大,越大的模型往往表现出更好的性能;但为了训练这些模型耗费也越来越昂贵,训练代码变得更复杂。 + +希望让训练过程变得更加简单,训练变得更高效,并且训练更加廉价。 + +首先要分析GPU内存;其次理解在多张显卡之间的合作模式是怎样的。 + +![](image/image_142NljbVkL.png) + +深度学习中最常见的矩阵乘法和向量加法适合于用GPU来计算。 + +CPU和GPU的合作方法通过CPU发送一些控制信号去控制GPU进行计算。 + +![](image/image_a5BL8if66I.png) + +如果想把模型的向量加法或矩阵乘法放到GPU中计算的话,需要把这些数据从CPU上拷贝到GPU上(`.cuda`)。 + +显卡中有哪些显存的组成。 + +## 1.2 显存组成 + +#### (1)参数 + +为了加速模型的前向传播,需要把模型所有的参数都放到显卡中。 + +![](image/image_L82DMDXVKf.png) + +#### (2)梯度 + +在反向传播过程中,计算得到的梯度也保存到显卡中。 + +![](image/image_rMbDHunpb-.png) + +#### (3)中间结果 + +模型的中间计算结果,比如线性层 $y=Wx$,为了计算反向传播,需要在前向传播时在显卡中保存模型的输入(中间结果)。 + +![](image/image_4GxOk2ZxpK.png) + +#### (4)优化器 + +第四部分,在显存中占大头的一部分,就是优化器,比如`Adam`,需要保存模型的梯度,和相关的历史信息`(m_t,v_t)`。它们的参数量是和梯度等数量级的。 + +![](image/image_dwtkuYMcCT.png) + +这四部分是预训练模型在显卡中主要的四个组成部分。 + +#### (5)示例 + +一个11B参数的预训练语言模型,每个需要用float类型(FP32)来存储 + +$$ +\frac{11 * 10^{9} * 4(F P 32)}{1024^{3}} \approx 40 G B +$$ + +光模型参数就占用了40GB的显存。 + +# 2.模型训练优化方式 + +## 2.1 数据并行 + +### (1)协作通信 + +#### 0)参数服务器 + +1. 有一个参数服务器。 +2. 前向传播 + +- 在每台设备上复制该参数 +- 每个副本处理输入的一部分。 + +1. 反向传播 + +- 每个副本的梯度取平均值。 +- 平均梯度用于更新参数服务器 + +在数据并行过程中,有一个参数服务器,它保持了模型的参数,以及完整的数据。前向传播过程中,参数服务器上的参数会被复制到所有的显卡上,这样每张显卡上都得到了和参数服务器一样的参数。然后把数据分成三份,每张显卡用这部分数据进行前向传播&反向传播,得到各自的梯度,为了让模型学到这份数据的所有知识,需要把这些梯度信息进行聚合。这里用了一个取平均操作,然后让聚合好的参数去更新模型。就能学到这三部分数据合起来完整的知识。 + +参数服务器可以在0号显卡上,从0号显卡把模型的参数复制到1,2,3号显卡。这就像一个广播过程;而从1,2,3号显卡上对模型的梯度进行聚合(或规约),把规约的结果放到服务器0号显卡上。 + +![](image/image_pf8Pu9BEeA.png) + +#### 1)Broadcast + +广播算子做的事情就是**把数据从其中的一张显卡上传到其他所有的显卡上**。可以看到通过广播之后,在原本第二张显卡上的`in`这个向量广播到所有显卡上变成了`out`向量。 + +![](image/image_uWSi1UccIA.png) + +#### 2)Reduce + +规约(Reduce)。规约有很多种种类,可以是**求和、平均、最值**等。会把各张显卡上的数据进行一个规约,然后把规约得到的结果放到一张指定的显卡里面。比如这里把规约的结果放到2号显卡里面。假设规约操作是求和,那么2号显卡最终得到的`out=int0+in1+in2+in3`。 + +![](image/image_G0NAzhkHJo.png) + +#### 3)All Reduce + +All Reduce。比规约多了一个All。在规约的基础上,**把规约得到的结果告诉所有的显卡(All)**。也就是说,最后得到的结果里面,每张显卡上都会得到完全一样的`out=in0+in1+in2+in3`。 + +![](image/image_oRfLBtB-Za.png) + +#### 4)Reduce Scatter + +Reduce Scatter。和All Reduce的相同之处在于,都会把规约得到的结果发送给所有的显卡。不同之处在于,**Reduce Scatter最后每张显卡上只得到了一部分的规约结果**。比如0号显卡就会得到`in0`的前`1/4`的参数+`in1`的前`1/4`参数+`in2`的前`1/4`参数+`in3`的前`1/4`参数。而3号显卡会得到`in0`的最后`1/4`的参数+`in1`的最后`1/4`参数+`in2`的最后`1/4`参数+`in3`的最后`1/4`参数。 + +![](image/image_Lc3O7sN4Fi.png) + +#### 5)All Gather + +收集(All Gather),**拼接每张显卡上的结果**。比如`in0`拼接`in1`拼接`in2`拼接`in3`得到0号显卡的`out`,然后广播到所有显卡上。 + +![](image/image_J5k8pqtYec.png) + +### (2)数据并行 + +可以看到数据并行有两个核心点。 + +1. **通过把数据分成很多份**,让每张显卡计算得到各自梯度之后,为了得到所有数据的知识,需要把这些梯度进行一个规约操作。 +2. 通过使用参数服务器,让规约后的梯度去更新参数服务器上的参数。然后通过广播的操作,让每张显卡上**同步**得到更新之后的参数。 + +### (3)分布式数据并行 + +而分布式参数并行对此进行了优化,**舍弃了专门的参数服务器**,让每张显卡各自去完成参数的更新,保证它们参数更新之后的结果一致。 + +具体来说,初始时,每张显卡上都有一个相同的模型参数,得到了一部分数据。通过前向传播&反向传播得到各自的梯度信息,然后对梯度信息进行一个规约。为了让每张显卡都得到相同的梯度信息,使用All Reduce,它会把规约结果告诉所有的显卡。这样,每一张显卡上都能得到完整的规约之后的梯度,每张显卡都有一样的参数,就可以分别通过模型的优化器进行更新。每轮更新之后,既然参数一样,梯度一样,优化器之前的历史信息一样,那么更新之后,各张显卡上的参数也会保持一致。 + +![](image/image_catk0_mUCQ.png) + +带来的显存上的优化 + +中间结果是一个和`batch`乘以句子长度和模型维度相关的显存占用。在使用数据并存的时候,把一批数据分成了很多份,让每张显卡只处理其中的一部分数据。每张显卡上所处理的`batch`大小就降低到了原来的显卡数量(n)分之一。通过把输入的维度进行了降低,那么模型整体的中间结果量也会进行降低。 + +缺点:数据较少时,参数,梯度,优化器都会保存到显卡上。 + +![](image/image_JzdjyjcS28.png) + +## 2.2模型并行 + +一张显卡上无法存放模型的所有参数,那么就想办法把一个模型分成很多个小的部分。 + +比如针对线性层矩阵乘法的例子,假设有一个`3×2`的矩阵。它乘上一个 `2×1`的向量,那么本质上可以把它的结果分成三部分。 + +这里的 `3×2`的矩阵就是线性层中的参数 `W`,向量就是线性层的输入。可以通过矩阵乘法的性质,把模型的参数横向切成很多份(n),最后得到线性层的结果就是很多个这样小的矩阵乘上线性层的输入,最后把结果进行拼接。 + +通过这样的方式,线性层的参数就可以划分到多张显卡上。同时需要保证多张显卡上模型的输入是一样的。那么就不能使用数据并行的方式对数据进行划分。 + +$$ +\left[\begin{array}{ll}1 & 2 \\ 3 & 4 \\ 5 & 6\end{array}\right]\left[\begin{array}{l}x \\ y\end{array}\right]=\left[\begin{array}{c}1 x+2 y \\ 0 \\ 0\end{array}\right]+\left[\begin{array}{c}0 \\ 3 x+4 y \\ 0\end{array}\right]+\left[\begin{array}{c}0 \\ 0 \\ 5 x+6 y\end{array}\right] +$$ + +$$ +\begin{aligned} \mathbf{y}_{A} & =W_{A \times B} \mathbf{x}_{B} \\ & =\left[W_{\frac{A}{n} \times B}^{(1)} ; W_{\frac{A}{n} \times B}^{(2)} ; \cdots ; W_{\frac{A}{n} \times B}^{(n)}\right] \mathbf{x}_{B} \\ & =\left[W_{\frac{A}{n} \times B}^{(1)} \mathbf{x}_{B} ; W_{\frac{A}{n} \times B}^{(2)} \mathbf{x}_{B} ; \cdots ; W_{\frac{A}{n} \times B}^{(n)} \mathbf{x}_{B}\right]\end{aligned} +$$ + +**需要保证每张显卡上的输入是一样的,是同样一批数据**,**这里对线性层参数进行划分**。每张显卡上得到线性层参数矩阵的一小部分,通过这一小部分参数和数据进行矩阵乘法,就得到了很多个子结果。这里通过All Gather收集算子进行拼接,然后广播给所有的显卡。 + +这样,每张显卡上只需要保存原来的N分之一的模型参数,N是显卡数量。由于只保留了这么一小部分参数,梯度也只需要保留这么多,同时优化器也只需要保持同样级别的参数量。但模型计算的中间结果没有减少,这也是该方法的一个弊端。当batch size很大的时候,仍然会出现显存溢出的问题。 + +![](image/image_ob4xGlT8K8.png) + +## 2.3 ZeRO + +Zero Redundancy优化器是基于**数据并行**建立的一套框架,在数据并行中需要对模型的梯度进行规约。为了保证每轮迭代之后每张显卡上的参数仍然是一致的。就让每张显卡都得到了规约后的参数。然后每张显卡各自进行更新。 + +可以发现每张显卡用的是同样的一批数据,和同样的一批梯度去进行参数更新。那么它们各自去进行参数优化,是不是就带来了计算上的重复和冗余。 + +为了消除这样的冗余,那么**每张显卡只获得一部分的梯度,然后只更新一部分参数**。这样多张显卡通过合作的方式来更新模型的完整参数。 + +![](image/image_mAu-NzbBAY.png) + +### (1)ZeRO-Stage 1 + +具体来说,由于是基于数据并行的架构,因此**每张显卡上保存了完整的模型参数**。有一部分数据,通过前向传播&反向传播得到各自的梯度。之后在规约的时候,不是使用All Reduce的方式,而是使用**Reduce Scatter**让每张显卡得到一部分reduce的结果。这样让**每张显卡上得到的部分梯度去更新对应的部分模型参数,最后通过收集的操作All Gather将每张显卡分工合作之后的结果告诉所有的显卡**。这样,每张显卡上得到了完全一样的参数和一致的结果。 + +![](image/image_HM2dVxDRmH.png) + +### (2)ZeRO-Stage 2 + +在第2阶段中,进行了一个优化。在第1阶段中,需要在反向传播得到所有梯度之后,对梯度进行Reduce Scatter,然后让每张显卡上各得到一部分规约后的梯度`Gradient*`。 原来的梯度就不需要保存在显卡上了。**在第1阶段,在反向传播结束之后,才把这个梯度移除**。那可以在反向传播的过程中先把`Gradient*`算出来,然后把之前一步的`Gradient`删掉。 + +![](image/image_clk_UK5mVJ.png) + +### (3)ZeRO-Stage 3 + +在第3阶段,**对模型的参数进一步划分**。因为每张显卡上只保留了一部分梯度去进行参数更新,参数更新也只更新一部分的模型参数。这样,**实际上每张显卡可以只保存它自己参数更新所负责的那一部分参数**。在FP\&BP的过程中,需要的时候,把模型的参数进行一个All Gather的操作, 用完之后,就可以将参数从显卡中释放。 + +注意:反向传播也需要模型完整的参数 + +![](image/image_pzZz9n9G2c.png) + +### (4)总结 + +比较一下这三个阶段的显存占比: + +![](image/image_3yZSa17FC0.png) + +在第1阶段中,每张显卡只需要处理一部分的模型梯度,优化器降低到了原来的显卡数分之一,同时把中间结果的量也降低到原来的卡数分之一; + +第2阶段中,进一步地把模型的梯度划分提前,把Reduce Scatter提前到了反向传播的过程中,实际上不需要保留完整的梯度。 + +第3阶段中,进一步地划分参数。 + +通过这三部分的优化,显卡上的四大组成部分:参数、梯度、优化器和中间结果都得到了划分,每张显卡只需要保持自己的那部分参数。 + +## 2.4 Pipeline并行 + +与模型的并行方法有类似之处,模型并行的方法通过把线性层分成很多个小的矩阵,然后把这些小的矩阵分到各张显卡上。 + +而对流水线的并行方法,**把模型的不同层分给不同的显卡**。比如有一个三层的Transformer,可以把Transformer的第一层分到第一张显卡上;第二层分到第二张显卡上,等等。 + +进行前向传播的过程中,需要在第一张显卡上完成第一层的模型计算,然后把计算结果告诉第二张显卡,第二章显卡进行计算,再把计算结果传给下一张显卡。 + +可以看到,这样的方法,显存占比都得到了划分,因为每张显卡上只保留了某些层的参数,也只用保留对应的梯度。虽然没有使用数据并行的方法,但模型层数变少了,这样中间结果也得到了减少。 + +但这种方法存在的弊端在于,0号显卡计算的时候,1号和2号显卡实际上处于空闲的状态。 + +![](image/image_EQDpKZAAIf.png) + +## 2.5 优化技术细节 + +### (1)混合精度 + +比如C语言中有`float`类型、`double`类型和`long double`类型。数值表示范围依次增大。 + +`double`类型比`float`类型有更大的表示范围和更高的有效位精度,但是`double`类型的计算会更慢。 + +同理`FP16`和`FP32`是一样的,前者的数值表示范围和有效位数更小,同时计算会更快。 + +在\*\*一般模型的训练中,可能使用`FP32`\*\***作为默认训练参数的表示**。实际上,模型的参数一般不会超过千这个数量级,那么完全可以使用`FP16`。 + +那能否从`FP32`转到`FP16`得到运行速度上的提升呢?其实会面临一个问题,在参数更新的时候,`权重=梯度*学习率`,一般学习率是比较小的:`1e-5`、`1e-3`等。而`FP16`能表示的最小值,是`1e-5`数量级的数,假如梯度乘上学习率低于`FP16`的表示范围,那么参数更新量就会产生丢失(下溢)。 + +那么既然`FP32`能达到出更高的表示范围,**可以把**\*\*`FP16`****的梯度乘上学习率得到的参数更新量表示为****`FP32`\*\*,但模型的参数是更低精度的`FP16`。那无法直接把参数更新量加到模型参数上,**此时需要在优化器上额外保留单精度(****`FP32`****)的一个参数。** + +![](image/image_qtXhWIAwDY.png) + +在一般的模型训练中,模型会有`FP32`的参数和`FP32`的梯度,然后优化器会使用`FP32`的梯度进行参数优化。 + +而在混合精度训练中,为了加速模型的前向传播&反向传播,模型中会使用半精度(`FP16`)的参数,和半精度的梯度,把梯度传到优化器里进行优化器的更新。**同时把优化器的更新量保存为**\*\*`FP32`****类型,把这个****`FP32`****类型通过优化器里临时创建的****`FP32`\*\***参数进行累积,之后转回到FP16的参数来与模型进行计算。** + +### (2)Offloading + +以Adam为例,**优化器的参数量会是模型参数量两倍的关系**,显然它是一个显存占用的大头。能否把它从显卡中移除呢? + +![](image/image_Jjx4WHHwG2.png) + +其实是可以的,**可以把它从显卡上移到CPU上**。 + +这样需要先把模型参数的梯度从显卡中传给CPU,在CPU上进行优化器的优化,将优化的结果传回显卡上。在使用了ZeRO3梯度优化之后,参数划分为显卡数分之一,通过把一张显卡绑定到多张CPU上,就可以让每张CPU上的计算量足够低,能让CPU不成为模型训练的瓶颈。 + +### (3)Overlapping + +通信的计算的重叠。在GPU中的内存操作一般是**异步的**,**可以提前给内存发送一个请求,可以去进行其他的计算,其他计算完成之后,对那个内存请求进行接收**。 + +在模型前向传播过程中,需要把Layer1的参数通过Gather操作,然后对Layer2的参数进行优化。在获得完Layer1参数之后,在Layer1前向传播计算过程中,异步地把Layer2参数的获得进行提前。在Layer1前向传播计算完之后,Layer2的参数也已经获得,那么就可以马上进行Layer2前向传播计算。 + +![](image/image_GHXwbIBQH-.png) + +### (4)Checkpointing + +Checkpointing就是检查点,就像单机游戏中的存档。 + +为了支持模型的反向传播,需要把模型计算的所有中间结果保持在显卡中,是否可以通过存档的方式进行优化。 + +即**不把所有结果都保持到显卡中,而只保持一定的存档点**。 + +![](image/image_73JO_TAoYB.png) + +以Transformer为例,只保留Transformer大层的输入作为检查点,在反向传播过程中,那么如何为大层中的线性层梯度进行计算。此时可以通过**重计算**,就是说通过Transformer每个大层的输入,在反向传播过程中,重新对它进行一个前向的传播。临时得到每个大层里面所有线性层的输入,那么得到了中间结果,就可以进行反向传播。 + +完成了这一层的反向传播之后,就可以把检查点和临时重计算的中间结果从显存中清理掉。这样就不需要保存那么多中间结果。 + +## 2.6 BMTrain——使用介绍 + +本小节介绍BMTrain性能上的提升。 + +![](image/image_kFLejXSqpS.png) + +据说可以使用更少的机器,达到更快的速度。 + +[bmtrain\_demo.ipynb - Colaboratory (google.com)](https://colab.research.google.com/drive/1H-T7PmTjdcgwYUFfMikfxZ4_bMWRKu8h?usp=sharing "bmtrain_demo.ipynb - Colaboratory (google.com)") + +![](image/image_gECDphYAMO.png) + +使用上也简单,替换一些包名前缀。就可以用到前面提到的一些技术。 + +# 3.模型压缩 + +背景就是大模型的规模增长非常快。 + +![](image/image_5k4iHZTQT6.png) + +接下来介绍模型压缩的一些技术,目的是希望把大规模的模型压缩成更小规模。 + +![](image/image_siP0YTrU-5.png) + +## 3.1 知识蒸馏(Knowledge Distillation) + +什么是知识 ? + +这里知识指的是**模型的参数本身**,本质是把模型从输入映射到输出的过程。知识蒸馏就是想把这种映射能力从大模型迁移到小模型上。 + +![](image/image_QWW6CpqEgQ.png) + +soft target比gold labels提供了更多的信息 + +对于输入数据,会有大模型作为Teacher,它会算出当前数据的预测结果,logits。 + +同时,该数据也可以输入给一个小得多的Student模型,该模型对于数据也能给出logits,知识蒸馏想做的事情是让这两个logits尽可能地接近。 + +![](image/image_54CMNTzuvX.png) + +### (1)PKD + +第一篇关于预训练模型的知识蒸馏工作称为PKD,它是面向BERT做的知识蒸馏。 + +> Sun et al. Patient Knowledge Distillation for BERT Model Compression. EMNLP 2019. + +它针**对传统的知识蒸馏进行改进,让student模型可以从teacher模型中间层进行学习**。 + +PKD针对模型很多层都有输出,或者说隐藏状态。它想做的事情是**让student模型的隐藏状态和教师的尽可能接近**。而不是仅拟合最终的输出。 + +![](image/image_KJ_k7h8P6m.png) + +### (2)TinyBERT + +还有一个非常有代表性的工作是,TinyBERT。它进一步地推广了能学习的信号。**从Teacher模型中找到了更多的可用于知识蒸馏的中间表示。** 比如输入的嵌入向量以及Attention矩阵。 + +> Jiao et al. TinyBERT: Distilling BERT for Natural Language Understanding. Findings of EMNLP 2020 + +![](image/image_UzWCaCrojk.png) + +## 3.2 模型剪枝 + +这里剪枝做的事情,比如对于参数矩阵`W`,可能有很多元素非常接近于0。那么是否可以把这些参数丢掉。 + +核心是**去除参数冗余部分**,去除的依据是根据重要性,重要性最直观的依据是看元素绝对值大小,如果非常接近于0,那么就认为它不重要。 + +剪枝分为**结构化剪枝**和**非结构化剪枝**。 + +现在比较有用的是结构化剪枝,它考虑一次性删除矩阵中的一行/一列/一块。这样删掉之后矩阵还是一个比较规整的形状,从而比较利于并行化计算。 + +![](image/image_p8LJXuyNqQ.png) + +权重剪枝效果 + +- 30-40%的权值可以被丢弃而不影响BERT的普适性(剪枝预训练) +- 对下游任务进行微调不会改变其性质(剪枝下游) + +![](image/image_ut10XXv2rI.png) + +注意力剪枝(结构化) + +- 切除一个头 +- 定义注意头的重要性分数 + +$$ +I_{h}=\mathbb{E}_{x \sim X}\left|\operatorname{Att}_{h}(x)^{T} \frac{\partial \mathcal{L}(x)}{\partial \operatorname{Att}_{h}(x)}\right| +$$ + +针对注意力中的冗余。如果把某个注意力head丢掉,观察对与机器翻译和语言理解任务上的影响,从图中可以看到,这种做法不一定会对模型造成负面的影响,甚至很多时候还带来结果的提升。 + +![](image/image_62aJLT5dwL.png) + +在不同的模型上迭代地剪枝头(蓝线) + +![](image/image_r8jqkitIAi.png) + +- 层剪枝(结构化) +- 将dropout从权重扩展到层 +- 训练:随机dropout层 +- 测试:选择任意深度的sub-network + +![](image/image_K28X1zRqnw.png) + +## 3.3 模型量化 + +标准的神经网络数值计算是浮点计算,那么表示的位数相对多一些。观察发现,神经网络其实不需要这么高的精度,所以可以把浮点的表示转换成定精度的表示。 + +![](image/image_lBhev15Xd2.png) + +随着位数的降低,准确率的变化: + +![](image/image_IsehZD-hI9.png) + +## 3.4 其他方法 + +### (1)权重共享 + +ALBERT:两种参数缩减技术 + +- 将大的词表向量分解为两个小矩阵 +- 跨层参数共享 + +> Lan et al. ALBERT: A Lite BERT for Self-supervised Learning of Language Representations. ICLR 2020. + +![](image/image_Bf35rI-n1V.png) + +### (2)低阶近似(Low-rank Approximation) + +$$ +\begin{array}{c}D=U \Sigma V^{\top} \in \mathbb{R}^{m \times n}, \quad m \geq n \quad \Sigma=: \operatorname{diag}\left(\sigma_{1}, \ldots, \sigma_{m}\right) \\ \widehat{D}^{*}=U_{1} \Sigma_{1} V_{1}^{\top}\end{array} +$$ + +难以直接进行低秩近似 + +分解输入矩阵 + +![](image/image_0VE2oICGHb.png) + +### (3)Architecture Search + +Transformer架构是否是完美的? + +- 基于Transformer的神经结构搜索 +- 预定义几个简单模块 +- 对每个架构进行几个小时的训练 + +> So et al. Primer: Searching for Efficient Transformersfor Language Modeling. NeurIPS 2021. + +![](image/image_e5SUgTHPsT.png) + +两种高效的架构 + +![](image/image_eS0UMWoLlc.png) + +# 4.BMCook + +与现有的压缩工具包相比,BMCook支持所有主流的PLM加速方法 + +![](image/image_erWQnqKSLB.png) + +- 用几行代码实现不同的压缩方法 +- 压缩方法可以以任何方式组合到极端加速 + +![](image/image_WRbHsHG_jU.png) + +- BMCook的核心:模型压缩配置文件 +- 用几行代码实现多种方法 + +![](image/image__fGxOdRIoC.png) + +蒸馏配置,支持MSE和CE损耗 + +![](image/image_ngyirMMSz9.png) + +模型剪枝配置,支持非结构化剪枝 + +![](image/image_-A0IJi56J2.png) + +模型量化配置,更换所有线性模块 + +![](image/image_eujzX_gCWl.png) + +# 5.BMInf + +BMInf是OpenBMB发布的第一个工具包。 + +Github repo: [https://github.com/OpenBMB/BMInf](https://github.com/OpenBMB/BMInf "https://github.com/OpenBMB/BMInf") + +主要的目的是能在便宜的GPU,比如GTX 1060上,也能运行起来大模型。 + +消费级显卡运行大模型困难: + +1. 高内存占用; +2. 计算能力; + +## 5.1 深入理解Transformer + +来深入分析模型,看如何优化模型。 + +![](image/image_qqP_n3hqKg.png) + +Transformer模型中主要的就是**线性层**,比如对于CMP-2中90%的参数都是在线性层中。 + +所以先来针对线性层。**在允许一些精度损失的前提下,来优化线性层的运算效率**。 + +> [https://developer.nvidia.com/blog/nvidia-hopper-architecture-in-depth/](https://developer.nvidia.com/blog/nvidia-hopper-architecture-in-depth/ "https://developer.nvidia.com/blog/nvidia-hopper-architecture-in-depth/") + +![](image/image_88bhnjZlVD.png) + +目前常用的是`FP32`,但目前模型比较大,为了降低开销,逐渐在训练过程中引入`FP16`。 + +> `FP16`示例:1.001, -1.001 +> `FP8`示例:1.0, 1.25, 1.5 + +`INT8`:范围更小,但更准确 + +![](image/image_w2FGoBWngA.png) + +为了进一步降低开销,有没有可能使用INT8来表示参数。 + +## 5.2 量化 + +使用整数来模拟浮点矩阵运算。 + +首先**找到矩阵里面最大的那个数,然后缩放到`-127~127`,得到缩放系数。然后把浮点矩阵中所有元素除以该缩放系数**,每个元素值经过四舍五入就能得到新的整数。这样可以把浮点数矩阵拆成缩放系数和一个整数矩阵。 + +就让能让矩阵中值从`FP16`变成了`INT8`。 + +![](image/image_hBmauB6Yt5.png) + +在完成了矩阵量化之后,如果用INT8来模拟矩阵乘法呢? + +针对线性层来说,分别对它的**输入和权重进行量化,就可以得到两个INT8的矩阵和对应的缩放系数**。接着在这两个INT8的矩阵中进行矩阵乘法。这会得到一个整数结果,但该结果INT8是存不下来的,此时会用INT32来存储。同时针对缩放系数进行一个标量惩罚,得到一个新的缩放系数,然后把整数结果乘上这个新缩放系数还原成浮点数。 + +![](image/image_VP0CdPkmvs.png) + +但是该方法直接应用在Transformer上效果不理想。因为Transformer中矩阵太大,使用一个缩放因子有点困难。 + +此需要更加精细的量化方法。**可以将量化的粒度从原来的整个矩阵变成一行或一列,计算单行/列的缩放系数。** 这种方法能在Transformer上达到不错的效果。 + +使用这种方法可以使模型大小优化一半(11G),但还是不能放到GTX 1060(6G)上。 + +![](image/image_Unlu8JySwS.png) + +## 5.3 内存分配 + +借鉴操作系统中**虚拟内存**机制。 + +在进行一个百亿模型推理的时候,实际上**并不会同时用到这11G的参数**,每次只用一部分。比如每次只计算一层,实际上只用到了这一层的参数。那些暂时不用计算的层没必要一直放到GPU上。 + +这种方法在`CUDA6`中被实现了。 + +![](image/image_7_ah3lXjsi.png) + +**如果能在计算一层的同时去加载另一层参**数,那么理论上只需要两层,就可以让整个模型完美地运行起来。比如我们在计算第0层的时候,同时加载第1层。这样第0层计算完之后,就可以释放第0层所占的空间,去加载第1层的参数进行计算,同时加载第2层参数。 + +![](image/image_tpNx52eJws.png) + +但实际操作上遇到了一些问题, + +实际上**传输一层参数的时间远远超过了计算该层参数所用的时间**。如果只放两层参数的话,虽然占用空间小,但花费的时间反而特别长。那是否可以多放几层,来减少加载参数所用的开销。 + +假设**一块GPU上能放n层参数,那么可以固定n-2层在GPU上,多余的2层空间用于调度**。 + +那现在的问题是,哪些层固定? + +![](image/image_3GWEbyidtV.png) + +假如两层需要从CPU加载,左边的方案是固定7,8,9,调度6和10。 右边是固定6,8,10,调度7个9。 + +这两种方法的区别在于,**要加载的层之间的间隔**,左边是间隔了3层,右边是间隔1层。 + +那么左边的方案肯定不会差于右边的,因为我们在加载完第6层之后,中间留下第7、8、9层计算的时间来加载第10层。即留给加载第10层的时间更长。 + +所以要**尽量扩大需要加载的两层之间的间隔**。 + +![](image/image_KXIMvP8wsQ.png) + +## 5.4 使用介绍 + +在实现了上面的技术(BMInf包)之后,终于可以把百亿参数模型放到GTX1060上运行起来。 + +![](image/image_j28CYsA2iP.png) + +那么这么好的工具包怎么使用呢? + +![](image/image_ZB0tdp9F5B.png) diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_-A0IJi56J2.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_-A0IJi56J2.png" new file mode 100644 index 0000000..74e41ca Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_-A0IJi56J2.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_0VE2oICGHb.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_0VE2oICGHb.png" new file mode 100644 index 0000000..791ba50 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_0VE2oICGHb.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_142NljbVkL.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_142NljbVkL.png" new file mode 100644 index 0000000..dc07d21 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_142NljbVkL.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_3GWEbyidtV.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_3GWEbyidtV.png" new file mode 100644 index 0000000..181ef17 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_3GWEbyidtV.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_3yZSa17FC0.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_3yZSa17FC0.png" new file mode 100644 index 0000000..9000e89 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_3yZSa17FC0.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_4GxOk2ZxpK.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_4GxOk2ZxpK.png" new file mode 100644 index 0000000..787f702 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_4GxOk2ZxpK.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_54CMNTzuvX.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_54CMNTzuvX.png" new file mode 100644 index 0000000..49c97e4 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_54CMNTzuvX.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_5k4iHZTQT6.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_5k4iHZTQT6.png" new file mode 100644 index 0000000..e4fd6ba Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_5k4iHZTQT6.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_62aJLT5dwL.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_62aJLT5dwL.png" new file mode 100644 index 0000000..a425e5c Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_62aJLT5dwL.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_73JO_TAoYB.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_73JO_TAoYB.png" new file mode 100644 index 0000000..526b5ee Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_73JO_TAoYB.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_7_ah3lXjsi.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_7_ah3lXjsi.png" new file mode 100644 index 0000000..7cdfa67 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_7_ah3lXjsi.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_88bhnjZlVD.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_88bhnjZlVD.png" new file mode 100644 index 0000000..b60389e Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_88bhnjZlVD.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_Bf35rI-n1V.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_Bf35rI-n1V.png" new file mode 100644 index 0000000..d066c90 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_Bf35rI-n1V.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_EQDpKZAAIf.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_EQDpKZAAIf.png" new file mode 100644 index 0000000..8e49c6a Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_EQDpKZAAIf.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_G0NAzhkHJo.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_G0NAzhkHJo.png" new file mode 100644 index 0000000..612a16c Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_G0NAzhkHJo.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_GHXwbIBQH-.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_GHXwbIBQH-.png" new file mode 100644 index 0000000..c903518 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_GHXwbIBQH-.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_HM2dVxDRmH.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_HM2dVxDRmH.png" new file mode 100644 index 0000000..366aa97 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_HM2dVxDRmH.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_IsehZD-hI9.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_IsehZD-hI9.png" new file mode 100644 index 0000000..a90664e Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_IsehZD-hI9.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_J5k8pqtYec.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_J5k8pqtYec.png" new file mode 100644 index 0000000..fa1c47d Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_J5k8pqtYec.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_Jjx4WHHwG2.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_Jjx4WHHwG2.png" new file mode 100644 index 0000000..6e1d9cd Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_Jjx4WHHwG2.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_JzdjyjcS28.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_JzdjyjcS28.png" new file mode 100644 index 0000000..cc8f2f0 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_JzdjyjcS28.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_K28X1zRqnw.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_K28X1zRqnw.png" new file mode 100644 index 0000000..a450bb6 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_K28X1zRqnw.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_KJ_k7h8P6m.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_KJ_k7h8P6m.png" new file mode 100644 index 0000000..5d74004 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_KJ_k7h8P6m.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_KXIMvP8wsQ.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_KXIMvP8wsQ.png" new file mode 100644 index 0000000..f82fa12 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_KXIMvP8wsQ.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_L82DMDXVKf.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_L82DMDXVKf.png" new file mode 100644 index 0000000..2e67ec2 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_L82DMDXVKf.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_Lc3O7sN4Fi.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_Lc3O7sN4Fi.png" new file mode 100644 index 0000000..afe226d Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_Lc3O7sN4Fi.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_QWW6CpqEgQ.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_QWW6CpqEgQ.png" new file mode 100644 index 0000000..6cc9202 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_QWW6CpqEgQ.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_Unlu8JySwS.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_Unlu8JySwS.png" new file mode 100644 index 0000000..ab9cab6 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_Unlu8JySwS.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_UzWCaCrojk.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_UzWCaCrojk.png" new file mode 100644 index 0000000..ca184f4 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_UzWCaCrojk.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_VP0CdPkmvs.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_VP0CdPkmvs.png" new file mode 100644 index 0000000..71808ec Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_VP0CdPkmvs.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_WRbHsHG_jU.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_WRbHsHG_jU.png" new file mode 100644 index 0000000..baadf2f Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_WRbHsHG_jU.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_ZB0tdp9F5B.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_ZB0tdp9F5B.png" new file mode 100644 index 0000000..2842edb Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_ZB0tdp9F5B.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image__fGxOdRIoC.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image__fGxOdRIoC.png" new file mode 100644 index 0000000..9e50853 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image__fGxOdRIoC.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_a5BL8if66I.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_a5BL8if66I.png" new file mode 100644 index 0000000..c205f7b Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_a5BL8if66I.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_catk0_mUCQ.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_catk0_mUCQ.png" new file mode 100644 index 0000000..31ef7f5 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_catk0_mUCQ.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_clk_UK5mVJ.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_clk_UK5mVJ.png" new file mode 100644 index 0000000..577173c Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_clk_UK5mVJ.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_dwtkuYMcCT.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_dwtkuYMcCT.png" new file mode 100644 index 0000000..7cb949d Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_dwtkuYMcCT.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_e5SUgTHPsT.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_e5SUgTHPsT.png" new file mode 100644 index 0000000..7900196 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_e5SUgTHPsT.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_eS0UMWoLlc.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_eS0UMWoLlc.png" new file mode 100644 index 0000000..259e32e Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_eS0UMWoLlc.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_erWQnqKSLB.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_erWQnqKSLB.png" new file mode 100644 index 0000000..d6f75a7 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_erWQnqKSLB.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_eujzX_gCWl.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_eujzX_gCWl.png" new file mode 100644 index 0000000..a5d906c Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_eujzX_gCWl.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_gECDphYAMO.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_gECDphYAMO.png" new file mode 100644 index 0000000..6f4e120 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_gECDphYAMO.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_hBmauB6Yt5.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_hBmauB6Yt5.png" new file mode 100644 index 0000000..b85dea0 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_hBmauB6Yt5.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_j28CYsA2iP.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_j28CYsA2iP.png" new file mode 100644 index 0000000..067729e Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_j28CYsA2iP.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_kFLejXSqpS.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_kFLejXSqpS.png" new file mode 100644 index 0000000..63f8839 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_kFLejXSqpS.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_lBhev15Xd2.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_lBhev15Xd2.png" new file mode 100644 index 0000000..ba42611 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_lBhev15Xd2.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_mAu-NzbBAY.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_mAu-NzbBAY.png" new file mode 100644 index 0000000..be4a758 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_mAu-NzbBAY.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_ngyirMMSz9.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_ngyirMMSz9.png" new file mode 100644 index 0000000..d11d792 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_ngyirMMSz9.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_oRfLBtB-Za.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_oRfLBtB-Za.png" new file mode 100644 index 0000000..bf5e672 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_oRfLBtB-Za.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_ob4xGlT8K8.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_ob4xGlT8K8.png" new file mode 100644 index 0000000..b8a06a5 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_ob4xGlT8K8.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_p8LJXuyNqQ.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_p8LJXuyNqQ.png" new file mode 100644 index 0000000..d78b9ca Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_p8LJXuyNqQ.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_pf8Pu9BEeA.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_pf8Pu9BEeA.png" new file mode 100644 index 0000000..deadca0 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_pf8Pu9BEeA.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_pzZz9n9G2c.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_pzZz9n9G2c.png" new file mode 100644 index 0000000..b67c8a4 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_pzZz9n9G2c.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_qqP_n3hqKg.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_qqP_n3hqKg.png" new file mode 100644 index 0000000..dad5f28 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_qqP_n3hqKg.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_qtXhWIAwDY.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_qtXhWIAwDY.png" new file mode 100644 index 0000000..6c8005a Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_qtXhWIAwDY.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_r8jqkitIAi.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_r8jqkitIAi.png" new file mode 100644 index 0000000..dd48ff5 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_r8jqkitIAi.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_rMbDHunpb-.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_rMbDHunpb-.png" new file mode 100644 index 0000000..0bd0e7a Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_rMbDHunpb-.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_siP0YTrU-5.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_siP0YTrU-5.png" new file mode 100644 index 0000000..68bfa00 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_siP0YTrU-5.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_tpNx52eJws.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_tpNx52eJws.png" new file mode 100644 index 0000000..44cece2 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_tpNx52eJws.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_uWSi1UccIA.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_uWSi1UccIA.png" new file mode 100644 index 0000000..d8f6e09 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_uWSi1UccIA.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_ut10XXv2rI.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_ut10XXv2rI.png" new file mode 100644 index 0000000..a8d75c6 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_ut10XXv2rI.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_w2FGoBWngA.png" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_w2FGoBWngA.png" new file mode 100644 index 0000000..96e3117 Binary files /dev/null and "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/5.\351\253\230\346\225\210\350\256\255\347\273\203&\346\250\241\345\236\213\345\216\213\347\274\251/image/image_w2FGoBWngA.png" differ diff --git "a/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/6.\346\226\207\346\234\254\347\220\206\350\247\243\345\222\214\347\224\237\346\210\220\345\244\247\346\250\241\345\236\213/6.\346\226\207\346\234\254\347\220\206\350\247\243\345\222\214\347\224\237\346\210\220\345\244\247\346\250\241\345\236\213.md" "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/6.\346\226\207\346\234\254\347\220\206\350\247\243\345\222\214\347\224\237\346\210\220\345\244\247\346\250\241\345\236\213/6.\346\226\207\346\234\254\347\220\206\350\247\243\345\222\214\347\224\237\346\210\220\345\244\247\346\250\241\345\236\213.md" new file mode 100644 index 0000000..d6524db --- /dev/null +++ "b/docs/98.\347\233\270\345\205\263\350\257\276\347\250\213/\346\270\205\345\215\216\345\244\247\346\250\241\345\236\213\345\205\254\345\274\200\350\257\276/6.\346\226\207\346\234\254\347\220\206\350\247\243\345\222\214\347\224\237\346\210\220\345\244\247\346\250\241\345\236\213/6.\346\226\207\346\234\254\347\220\206\350\247\243\345\222\214\347\224\237\346\210\220\345\244\247\346\250\241\345\236\213.md" @@ -0,0 +1,594 @@ +# 6.文本理解和生成大模型 + +# 1.简介 + +## 1.1 NLP的主要应用 + +NLP的主要应用主要分为两类:**自然语言理解(NLU)**和**自然语言生成(NLG)**。 + +- **信息检索**是NLU非常有代表性的应用; +- **文本生成**是NLG一个代表性例子; +- **机器问答**综合了自然语言理解和自然语言生成两个任务。 + +在这三种任务中,大模型都带来了一定的变革。 + +![](image/image_kj2z6nEids.png) + +## 1.2 信息检索 + +信息检索是非常古老、非常经典的任务。在这一方面,大模型可以帮助机器来提供更加智能、更加准确的搜索结果。 + +![](image/image_FqazwCbO7r.png) + +## 1.3 机器问答 + +问机器一些问题,希望机器能提供我们想要的答案。**传统的机器问答方法是基于模板、或者基于知识库的,这样使得它的问答范围受限**。 + +但现在大模型允许机器回答更加复杂的问题,从下面的例子中,列出一些最先进的大模型可以回答的问题。可以看到,即使它背后没有一个知识库去支撑它搜索相关的知识,大模型里面蕴含的知识也足以帮助机器回答上述问题。 + +![](image/image_gspSV1YlTD.png) + +## 1.4文本生成 + +利用大模型可以帮助机器生成更加流畅、自然的文本。 + +![](image/image_M5q0B0YeoC.png) + +# 2.信息检索 + +## 2.1 背景 + +信息以爆炸的形式增加,用户对信息检索的需求也是在急剧增长。 + +可以看到全球的信息用户数量也非常庞大。 + +自动检索:**根据用户的查询,从海量的文本信息中提炼出少量的与用户需求高度相关的文档**,反馈给用户。 + +![](https://img-blog.csdnimg.cn/552a214fc0e744ee93a0b37f9036404a.png) + +信息检索有很多典型的应用,比如搜索引擎、问答系统和智能写作等。 + +## 2.2 IR定义和评价 + +### (1)IR定义 + +首先来看下如何定义信息检索(IR)任务。 + +- 给定一个`query` $q$ +- 给定一个文档库 $D = \{\cdots,d\_i,\cdots \}$ +- IR系统计算相关系数得分$f(q,d_i)$,然后根据该得分进行排序 + +一个典型的IR系统分为两个阶段:检索和重排阶段。 + +- 在检索阶段,针对整个文档库,从中找到相关文档的子集,它**重视的检索速度和相关文档的召回率**; +- 在重排序阶段针对上一步得到的少量文档进行精排,看重的是**性能和效果**。 + +![](image/image_y4x7Thk3EJ.png) + +### (2)IR评价指标 + +IR中常用的三个指标是`MRR@k`、`MAP@k`和`NDCG@k`。后面的`@k`表示在评测中,只要考虑top K个排序的结果。 + +#### MRR (Mean Reciprocal Rank) + +MRR是平均倒数排名,给定一个待评测的查询集合 `Q`,MRR只会考虑哪个查询排名**最靠前的第一个相关文档的位置**。 + +$$ +M R R=\frac{1}{|Q|} \sum_{i=1}^{|Q|} \frac{1}{\operatorname{rank}_{i}} +$$ + +比如说查询集合中一个有三个查询:cat、torus和virus。这三个查询排在首位的相关文档位置,分别是第3位、第2位和第1位。那么对它们取倒数之后就是`1/3`、`1/2`和`1`。对它们求均值之后得到`0.61`,就是MRR评测的结果。 + +$$ +M R R=(1 / 3+1 / 2+1) / 3=0.61 +$$ + +![](image/image_7IsEYThCr8.png) + +#### MAP (Mean Average Precision) + +MAP,**一组查询平均准确率的均值,它会考虑所有相关文档**。这里也举个例子,这个查询集合中一共有两个查询,它们分别有4篇和5篇相关文档。 + +在query1中,这四篇相关文档都被成功地召回了,它们被召回的位置分别是第1位、2位、4位和7位。同样对它们取倒数排名,计算均值之后得到0.83。 + +在query2中,五篇中只成功召回了3篇,位置是1,3和5。那么计算它们的倒数分数,求均值得到0.45。 + +接着对这两个查询的分数相加,再求平均,得到0.64。才是最终MAP的得分。 + +![](image/image_697jvYB7cq.png) + +#### NDCG (Normalized Discounted Cumulative Gain) + +NDCG,**归一化的折损累积增益**,该**指标是商业的搜索引擎/推荐系统中最常用的评价指标**。它会将文档设置成不同的相关等级,相关程度越高,等级越高。 + +它的计算方式为:用待评测的排序列表的DCG分数,除以IDCG的分数。IDCG的分数就是一个理想状态下列表的真实排序方式;DCG的计算公式如下图所示。 + +![](image/image_7MZ2XWU_wQ.png) + +也看一个具体的例子,针对一个query抽回的五篇文档,分别有不同的相关等级 $rel_i $。 + +会计算它的增益和折损后的增益,最后再求和就是DCG的分数。 + +![](image/image_glNFqNar2n.png) + +## 2.3 传统方法 + +### (1)BM25 + +#### BM25 (Best Matching 25) + +给定一个查询,其中包含相应的单词,BM25会计算**该查询与每一篇文档的匹配分数**。 + +![](image/image_jRxYKj8Shy.png) + +#### TF (Term Frequency) + +TF就是**词频**,为查询中每个单词在文档中出现的频率。 + +![](image/image_V1ylxbYdCy.png) + +#### IDF (Inverse Document Frequency) + +而IDF是**逆文档频率**,评估查询单词的稀有程度。如果一个文档在所有文档中都出现,那么它的IDF分数反而很低。 + +![](image/image_bT1PttQvKE.png) + +### (2)缺点 + +那么这种基于词汇匹配的算法存在两方面的问题。 + +首先是**词汇失配**的问题,因为人类会使用不同的单词来表达同一个意思。 + +![](image/image_LgevrcusN-.png) + +其次是**语义失配**问题,可能即使文档和词汇有很高的匹配率,但描述的含义却完全不一样。 + +![](image/image_wt9odGLEqL.png) + +## 2.4 神经网络方法 + +### (1)简介 + +神经网络IR**使用神经网络将用户的查询和文档库的中的文档投射到同一个向量空间,然后计算两者的相关性分数**,从而避免了传统IR中的词汇失配合语义失配的问题。 + +![](image/image_ZiHfNAvkez.png) + +从性能上来说,Neural IR的方法尤其是基于大预训练语言模型的方法,它的检索性能远远超越了传统IR的方法。也可以看到Neural IR的研究热度是逐年增加的。 + +![](image/image_ZSyZofXzUH.png) + +通常会在**重排序阶段**采用左边的**Cross-Encoder的大模型架构**,它会将查询和问答进行词汇级别的拼接,然后进行一个精细地交互式建模,生成一个`查询-文档`的共同表示,然后产生相关性分数。这种建模方式的好处是比较精细,达到的检索性能也较好,但缺点是计算代价比较高。所以一般使用在重排序阶段。 + +而在第一阶段,**检索阶段**,一般采用右边的**Dual-encoder,双塔的架构**,使用大模型对查询和文档分别进行编码,形成两个独立的向量,然后再去计算向量间的相似性。这样可以极大地降低计算的开销。 + +![](image/image_S42nUk58G6.png) + +### (2)Cross-Encoder架构 + +**会先把查询和文档进行拼接,然后一起喂给大模型**。这里以BERT为例,拼接完之后,经过多层transformer的建模之后,把最后一层的CLS token作为`查询-文档`的共同表示。经过一个NLP的投射变成一个标量的分数,可以作为`查询-文档`相关性的分数。 + +在训练该大模型的时候,训练数据的形式是每个查询配一个相关文档,和至少一篇的不相关文档。 + +然后采用常见的Ranking Loss,比如这里的Pairwise hinge loss,为相关文档和查询分配更高的分数。 + +![](image/image_WilKdONj3z.png) + +这里分别展示了以BERT和T5作为bacakbone的重排序结果,可以看到相比传统的IR方法,基于大模型的方法可以达到更出色的重排序效果。并且随着模型参数量的增加,重排序的性能也会持续地增强。 + +> Dai, Zhuyun, et al. SIGIR 2019. Deeper Text Understanding for IR with Contextual Neural Language Modeling. +> Nogueira Rodrigo, et al. EMNLP 2020. Document Ranking with a Pretrained Sequence-to-Sequence Model. + +![](image/image_goivgAubml.png) + +### (3)Dual-Encoder架构 + +这里以DPR为例,它使用两个独立的Encoder分别对查询和文档进行编码,然后用类似softmax这种NLL损失来训练模型。 + +> Karpukhin Vladimir, et al. EMNLP 2020. Dense Passage Retrieval for Open-Domain Question Answering + +![](image/image_w9qE8p1x_-.png) + +Dual-Encoder架构的好处是,因为是**独立编码**,所以可以提前计算缓存整个文档库的编码。然后只需要计算用户的新查询编码,接着使用一些最近邻搜索的工具,比如`faiss`,去找出最相近的`k`个文档。 + +> [https://github.com/facebookresearch/faiss](https://github.com/facebookresearch/faiss "https://github.com/facebookresearch/faiss") + +![](image/image_7EeeVu9a4A.png) + +在检索性能方法,在第一阶段检索时,以BERT、T5作为backbone的效果。在使用1K训练数据的情况下,它的效果已经超过了BM25,同时随着训练数据的增加,大模型的性能也会增加。同样模型的大小增加,效果也越好。 + +> Karpukhin Vladimir, et al. EMNLP 2020. Dense Passage Retrieval for Open-Domain Question Answering. +> Ni, Jianmo, et al. arXiv 2022. Large dual encoders are generalizable retrievers + +![](image/image_nr28FP467r.png) + +## 2.5 前沿热点 + +本小节介绍几种比较常见的基于大模型的Neural IR架构,和IR领域比较前沿的研究热点。 + +### (1)Negative-enhanced Fine-tuning + +首先有相当一部分工作是在研究**如何在微调阶段去挖掘更好的负例**,目前几种常见的训练负例有上图这么几种。 + +- `In-bach negative`:在训练中同一个batch的正例可以作为其他query的一个负例。 +- `Random negative`:随机地从文档中进行采样。 +- `BM25的负例`:先用BM25针对每个query抽回一些top k的文档,然后删除掉相关文档,剩下的就是不相关的。 + +在In-batch空间中,它们的分布是非常不一样的, 因此它最大对大模型检索的性能影响也是比较大的。 + +![](image/image_whMakllS2I.png) + +下面介绍一篇工作,它在训练过程中使用模型本身去挖掘更难的负样本,从而获得更好的性能。 + +#### ANCE (Approximate nearest neighbor Negative Contrastive Learning) + +该方法称为ANCE,它会在模型的训练过程中(图中的绿线)去异步地维护Inferencer的程序,然后每隔k步,去把最新的模型拿过来推理一下,把那些排名靠前的难负样本抽回来,加到下一轮的训练过程中,这样不断地迭代刷新。 + +> Xiong et al. ICLR 2021. Approximate nearest neighbor negative contrastive learning for dense text retrieval. + +![](image/image_ZUGnarhC7d.png) + +#### RocketQA (NAACL 2021) + +还有一类方法,比如RocketQA,它建模**更精细的Cross-Encoder来帮助Dual-Encoder去过滤难负例**,然后加到Dual-Encoder的训练中,这样交叠学习,从而提升Dual-Encoder第一阶段检索的性能。 + +> Qu Yingqi, et al. NAACL 2021. RocketQA: An Optimized Training Approach to Dense Passage Retrieval for Open-Domain Question Answering. + +![](image/image_RtW-RYYhdv.png) + +### (2)IR-oriented Pretraining + +上面是在微调阶段的一个研究热点,第二个研究热点集中在**大规模的预训练阶段**。 + +#### SEED-Encoder (EMNLP 2021) + +SEED-Encoder,它通过在**预训练阶段为Encoder配置一个较弱的Decoder,来促使下面的Encoder对文本形成一个更好的表示**。它主要的调整,第一个在于Encoder和Decoder之间的连接,第二个在于限制Decoder的Span。这些操作的目地在于**让CLS的表示足够强**,这个模型在预训练的时候只能通过CLS token来重建出原文本。CLS表现能力的增强,对IR是非常有帮助的。 + +> Lu Shuqi, et al. EMNLP 2021. Less is More: Pre-train a Strong Text Encoder for Dense Retrieval Using a Weak Decoder. + +![](image/image_5fixWhWrVq.png) + +#### ICT (Inverse Cloze Task) + +ICT,是在预训练的数据上去做一些操作,比如它会针对预训练的文本,随机地抽取文本中任意的一个句子,把这个句子作为我们的查询,剩下的虚线的文本框,作为查询的一个正例。这样就构建出来在微调阶段才能有的数据,接着它再用In-batch negative来配合着进行提前的预训练。 + +> Chang Wei-Cheng, et al. ICLR 2021. Pre-training Tasks for Embedding-based Large-scale Retrieval + +![](image/image_FyAFYCsF9m.png) + +### (3)Few/Zero-Shot IR + +现在越来越多的工作开始关注到Few-shot IR领域,因为在现实生活中,有很多检索场景,都是少样本的场景。这些场景缺乏大规模的监督数据,比如长尾的网页搜索、 涉及隐私的个人检索/企业检索、人工标注昂贵的医学/法律等专业领域的检索。 + +#### Weak supervision generation + +在这些领域,有一部分工作在研究如何用**弱监督的数据去取代监督的数据来训练大模型**。比如下图列了三种不同弱监督数据来源。有文档的标题与文本的正文、网页中的锚文本对、还有的直接用大模型去根据文本生成一个query,这样通过大模型生成数据。 + +![](image/image_pl0YuH2rPs.png) + +但由于刚才提到的弱监督数据是没有经过人工质量检测,不可避免会存在不同程度噪音。因此也涌现了一类工作,去研究如何针对弱监督数据进行去噪学习。比如ReinfoSelect。 + +> Kaitao Zhang, et al. WWW 2020. Selective weak supervision for neural information retrieval. + +![](image/image_wez5YhGUhd.png) + +#### (4)其他 + +还有两个有意思的研究方向, + +- 一个是**对话式IR**,针对用户会同时提多个问题,且后面的问题与前面的问题有关联。 +- 另一个方向是**使用大模型去检索长文本**。因为长文本情况下,模型需要考虑的问题比较多,比如长距离依赖。 + +![](image/image_a_fnQUAUgA.png) + +# 3.QA + +QA分为很多种: + +- 机器阅读理解:阅读特定的文本并回答问题 +- 开放领域QA:搜索并阅读相关文档以回答问题 +- 基于知识的QA:根据知识图谱回答问题 +- 对话式QA:根据对话历史回答问题 + +这里主要介绍前面两种。机器阅读理解是在检索到相关文档后,让机器代替人类去从相关文档中抽取答案的过程。 + +## 3.1 机器阅读理解 + +### (1)RC定义与类型 + +阅读理解的定义:首先会有一篇文章,以及对应的题目,通过理解题目的含义来回答问题。 + +阅读理解的形式有很多种。 + +- 有**完形填空**,通过挖掉句子中某些词,希望模型能正确输出被挖掉的词。 +- 多选: +- 抽取式的阅读理解,它的答案隐藏在文章中,让机器去预测问题的答案实际上是文章中的某个词/短语。 + +从机器阅读理解的数据集类型可以看到它的发展。 + +### (2)Traditional Pipeline + +介绍阅读理解领域一些经典的方法。 + +在大模型出来之前,机器阅读理解经典的框架是这样的。 + +> Seo et al., Bidirectional Attention Flow for Machine Comprehension, In Proceedings of ICLR 2017 + +它是一个四层的结构: + +1. 首先**对文档和问题分别进行编码,得分文档和问题的向量集合**。 +2. 然后**分别处理这些向量集合**,同时包括一些注意力,得分文档和问题的汇聚向量表示。 +3. 接着基于从文档到问题/从问题到文档的**交互得到融合问题和文档的向量** +4. 最后喂给线性层进行**预测**。 + +![](image/image_kIGwLZVKar.png) + +BiDAF就是遵循了上面的框架实现的模型。 + +> Seo et al., Bidirectional Attention Flow for Machine Comprehension, In Proceedings of ICLR 2017 + +![](image/image_it24oL9Cej.png) + +这些设计很复杂,并且迁移性不好。 + +### (3)Big-model-based Methods + +有了大模型之后,**只需要用一个大模型就可以替代上面的前三层**。 + +![](image/image_UIfVVZua_c.png) + +这里给出了BERT刚出来时非常简单的实现问答系统的示例。 + +将问题和上下文的连接提供给BERT。获得问题感知上下文表示,以预测答案的开始/结束 + +直接拼接问题和文档,作为BERT的输入,然后用`[CLS]`进行分类得到最终的答案。 + +![](image/image_ID8c2cu_7R.png) + +大模型的好处除了在于简化阅读理解的Pipeline之外,还有另一个好处是可以**统一不同问答系统的形式**。 + +可以统一成`text-to-text`的形式,比如抽取式QA可以看成给定输入,直接输出答案。 + +> Khashabi et al., UNIFIEDQA: Crossing Format Boundaries with a Single QA System, Findings of EMNLP 2020 + +![](image/image_RX7VpRp8cN.png) + +## 3.2 开放式QA + +开放式QA假设的是**没有给出相关的文章,模型必须自己去寻找相关的文章**。比如从维基百科中去寻找相关文章。开放式QA最终的目标是**建立一个端到端的QA系统**,只需要喂给它问题就能得到答案。 + +开放式QA有两种类型:生成式和检索式。 + +### (1)生成式QA + +生成式的方法就是**用大模型内所存储的知识,直接去回答问题**。 + +> Roberts et al., How Much Knowledge Can You Pack Into the Parameters of a Language Model?, EMNLP 2020 + +![](image/image_yv65azqjiM.png) + +### (2)检索式QA + +第二种是基于检索的方法,通常由两部分组成:`Document retriever`和`Document reader。` + +分别用于检索出相关文章以及从相关文章中找出对应答案。 + +![](image/image_HOArXmLxoG.png) + +### (3)REALM + +在大模型流行起来后一个非常重要的方向是**如何用检索来辅助大模型的预训练过程**。 + +让大模型在下游的机器问答环节中表现得更好。 + +REALM这篇工作它在**模型的预训练过程中加入了一个检索的任务,让大模型把预训练当成一个开放式QA的任务,在预训练的时候,同时训练大模型和知识检索器**。然后在下游的任务中直接用检索器进行检索,从而能够达到更好的表现。 + +![](image/image_GulxkTHCm2.png) + +它具体是如何做的呢?首先在预训练语料库中有一个样本,比如遮盖了pyramidion(金字塔)这样一个词。然后把预训练的过程看作是一个问答的过程, 要去回答这个问题需要在知识库中进行一些检索。把该样本当成一个问题,然后让神经检索器去进行一些检索。再把检索到的相关文章和该问题一起输入到大模型中,希望大模型根据这些文章为找到问题的答案。 + +![](image/image_2tTAZFR0QB.png) + +在下游的微调过程中,就可以用相同的Pipeline,给定一个问题,用前面预训练好的检索器检索相关的文章,然后通过相关的文章来回答问题。 + +![](image/image_sd7hERTcrj.png) + +### (4)WebGPT + +WebGPT比前面介绍的模型更强大,在于它不限定只能在维基百科中寻找答案,而是可以**直接在搜索引擎上去寻找相关的文章,然后回答问题**。 + +- 将文档检索外包给微软必应网络搜索API +- 利用无监督的预训练,通过微调GPT-3来实现高质量的文档合成 +- 创建一个基于文本的网页浏览环境,人类和语言模型都可以与之交互 + +训练前让很多标注人员给定一些问题,让他们用基于文本的检索器去寻找答案。并记录了标注人员每一步的操作。比如可以去搜索,点击每个链接,把有用的句子摘录出来,然后 继续寻找下一个相关的内容。 + +用这些记录的行为去微调GPT-3,希望GPT-3能够模仿人类行为来使用浏览器。然后惊奇的发现,即使给定较少的训练数据,比如几千条,GPT-3就可以很容易地学会怎么去操控浏览器,它每次可以进行检索,记下重要的引用,再通过这些引用生成最终的问题答案。 + +![](image/image_x_Eirw9XGT.png) + +# 4.文本生成 + +文本生成可以**把一些非语言性的表示信息,通过模型以一种人类可以理解的语言表示处理**。 + +非语言性的表示就是常说的数据,比如图片、表格、图等。我们统一把这种生成叫做`date-to-text`生成,实际上广义上还包括`text-to-text`的生成。 + +## 4.1 文本生成任务 + +![](image/image_-GvP3ZdQkq.png) + +1. `Data-To-Text (image, table, graph) ` : 输入可以有很多种形式,比如说图片、表格、图等。 +2. `Dialogue` : 模型针对用户的特定输入,给予一些回答。 +3. `Machine Translation` : 机器翻译,尽可能保留语义和语法 +4. `Poetry Generation` : 诗歌的生成,在生成诗歌的时候,不仅要求它包含某种主题,包含某些关键词,同时还要求它满足一些诗歌的格律。 +5. `Style Transfer` : 文本风格转移,把输入文本的风格转移成所需要的风格。上面是文本风格转移中一些常见的子任务。 +6. `Storytelling` : 故事生成,在给定关键词/故事线下进行故事的生成。上面是一个简单的例子。 + +文本生成任务中还包括总结生成的任务,输入是较长的文档,希望模型能生成较短的关于文档的摘要。 + +## 4.2 神经网络文本生成 + +### (1)语言模型 + +\*\*基于前面`t-1`****词生成第****`t`\*\***个词**。 + +![](image/image_bcXrI_A_aA.png) + +有**条件的语言建模**,不仅基于已经生成的词,还基于其他输入。比如机器翻译。 + +![](image/image_mICC1Cdk22.png) + +### (2)Seq2seq + +Seq2Seq也是一种条件语言模型。 + +在**训练时以teacher forcing的方式进行训练,而测试时基于已生成的单词**。 + +这会带来训练与测试分布的gap。 + +![](image/image_4VD_BwlOnJ.png) + +T5也是一种seq2sqe模型,它基于Transformer实现,将所有的NLP任务统一成`text-to-text`的形式表表示。 + +上图左侧是Encoder部分,右侧是Decoder部分。 + +![](image/image_XYdhiVfAxh.png) + +T5模型在清洗过的数据集上进行训练,**训练时遮盖句子中的部分单词**。在训练时,**希望模型能通过这样的输入预测出被遮盖的部分**。 + +![](image/image_AbA-EtnZkW.png) + +### (3)Autoregressive models + +语言模型分为两大类,其一是自回归生成。 + +**在预测时以过去的输出作为参考来生成下一个单词**。 + +![](image/image_XEH4pylzSJ.png) + +**GPT一系列模型就是自回归生成的典型例子**。 + +它拿到了Transformer中的Decoder部分: + +- GPT1认为**可以通过生成式预训练来提升语言理解能力**; +- GPT-2认为**语言模型是一种无监督的多任务学习者**; +- GPT3认为**语言模型是少样本学习者**。 + +![](image/image_GZ0iWgIIU-.png) + +以GPT-2为例,**它是在无标签的数据上训练的,可以根据下游具体的有标签数据进行微调**。 + +![](image/image_OA1-TdYx_P.png) + +### (4)Non-autoregressive models + +另一类是非自回归生成。 + +在给定source和target的情况下,**编码器会对source进行编码,在解码器生成的过程中,每个解码器之间是没有时序关系的**。可以通过编码器的信息一次性地并行地生成所有的输出单词。 + +![](image/image_dzfDr90lXN.png) + +在给定输入的情况下,输出只与两部分相关。 + +1. 输入会决定目标句子的长度 `m`; +2. 在生成当成单词的时候只与 `z`和 `x`相关, `x`是输入的表示, `z`是计算得到的不同 `x`和不同 `y`之间的权重关系。可以看到`z`中是没有 $y_{t-1}$ 这一项的。所以可以并行地对这些词进行生成。 + +![](image/image_gDJ5dy5cNp.png) + +### (5)Decoding strategy + +#### Greedy Decoding + +Greedy Decoding,在**生成的每步中都会选择计算概率最大的单词作为输出单词**。 + +这种方法的缺点是**很容易生成重复的文本,这样可读性较差**。 + +![](image/image_MSzJ1ZL7Dl.png) + +#### Beam Search + +束搜索是另一种方法,它\*\*在生成时的每步选择最好的`k`个局部序列。最终从这 ​`k`\*\***个序列中选择概率最大的输出**。 + +![](image/image_fvVyz2sLH9.png) + +这两种做法在每步中都会概率最大的那个/些单词,是否有必要选择一个这样概率最大的单词呢? + +实际上是每必要的,那么要怎么做呢? 下面介绍一些基于采用的方法。 + +![](image/image_a053xWPgXY.png) + +#### Sampling-based Decoding + +这些方法按照模型计算出来单词的概率分布,**按照概率随机地从词表中选择生成的单词**,从而增加模型生成的多样性。 + +但也有可能生成无关的概率较小的单词,为了避免大量出现这种无意义的词,可以采取`top-n`和`top-p`两种方法。 + +- `top-n`就是在采样的过程中局限于 `n`个最有可能的单词上进行采样。 +- `top-p`限制采样在若干个单词上进行,这些单词满足怎样的条件呢?概率最大的这些单词概率之和要大于一个阈值 `p`。 +- `sample with temperature` : 在最终的softmax之前,inputs除以温度洗漱 $\tau$ + +![](image/image_N88MOU077W.png) + +![](image/image_ILs9cnbiZB.png) + +## 4.3 受控文本生成 + +### (1)Prompt methods + +首先\*\*通过`prompt`\*\***的形式来控制**,比如图中在 `A knife`前面加上`Horror`来生成恐怖的描述;或者在前面加上`Reviews`来生成关于它的评价。 + +![](image/image_IEp-2FoVbL.png) + +除了可以在文本前面加一个`Prompt`,还可以在模型前加一个`Prefix`。比如增加较小的参数矩阵(Prefix)拼在Transformer前面,**只对Prefix进行训练**。来指导模型完成不同的任务。 + +![](image/image_mcPw3ym6NQ.png) + +### (2)Modifying probability distribution + +另一种是**通过修改概率分布的方法**,这里会再多训练两个模型,一个**生成非歧视语言的模型**,另一个生成**带有严重歧视的语言模型**。 + +在**文本生成时希望生成的语言贴近非歧视语言模型,而原理歧视语言模型**。 + +$$ +\tilde{P}\left(X_{t} \mid \boldsymbol{x}_{ "4.Prompt Tuning & Delta Tuning") + +[5.高效训练&模型压缩](5.高效训练&模型压缩/5.高效训练&模型压缩.md "5.高效训练&模型压缩") + +[6.文本理解和生成大模型](6.文本理解和生成大模型/6.文本理解和生成大模型.md "6.文本理解和生成大模型") diff --git "a/docs/99.\345\217\202\350\200\203\350\265\204\346\226\231/README.md" "b/docs/99.\345\217\202\350\200\203\350\265\204\346\226\231/README.md" new file mode 100644 index 0000000..bd5c51e --- /dev/null +++ "b/docs/99.\345\217\202\350\200\203\350\265\204\346\226\231/README.md" @@ -0,0 +1,9 @@ +# 99.参考资料 + +- [大模型(LLMs) 算法工程师相关的面试题](https://github.com/km1994/LLMs_interview_notes "大模型(LLMs) 算法工程师相关的面试题") +- [epoch次数设置问题](https://mp.weixin.qq.com/s/DBP_eafGeKMEuSIma9Z9Tg "epoch次数设置问题") +- [大模型训练入门实战](https://techdiylife.github.io/big-model-training/deepspeed/LLM-state-of-GPT.html "大模型训练入门实战") +- [大模型训练避坑指南](https://mp.weixin.qq.com/s/s3aPTe11-w_ELL7uZJCI2Q "大模型训练避坑指南") +- [算法工程师笔记](https://mingchao.wang/ "算法工程师笔记") +- [深度学习自然语言处理](https://github.com/DA-southampton/NLP_ability "深度学习自然语言处理") +- [养生的控制人 - 知乎 (zhihu.com)](https://www.zhihu.com/people/yilan-zhong-shan-xiao-29-98 "养生的控制人 - 知乎 (zhihu.com)") diff --git "a/pdf_note/ChatGLM\347\263\273\345\210\227\346\250\241\345\236\213.pdf" "b/docs/pdf_note/ChatGLM\347\263\273\345\210\227\346\250\241\345\236\213.pdf" similarity index 100% rename from "pdf_note/ChatGLM\347\263\273\345\210\227\346\250\241\345\236\213.pdf" rename to "docs/pdf_note/ChatGLM\347\263\273\345\210\227\346\250\241\345\236\213.pdf" diff --git "a/pdf_note/LLM\345\276\256\350\260\203.pdf" "b/docs/pdf_note/LLM\345\276\256\350\260\203.pdf" similarity index 100% rename from "pdf_note/LLM\345\276\256\350\260\203.pdf" rename to "docs/pdf_note/LLM\345\276\256\350\260\203.pdf" diff --git "a/pdf_note/LLaMA\347\263\273\345\210\227\346\250\241\345\236\213.pdf" "b/docs/pdf_note/LLaMA\347\263\273\345\210\227\346\250\241\345\236\213.pdf" similarity index 100% rename from "pdf_note/LLaMA\347\263\273\345\210\227\346\250\241\345\236\213.pdf" rename to "docs/pdf_note/LLaMA\347\263\273\345\210\227\346\250\241\345\236\213.pdf" diff --git a/pdf_note/LangChain.pdf b/docs/pdf_note/LangChain.pdf similarity index 100% rename from pdf_note/LangChain.pdf rename to docs/pdf_note/LangChain.pdf diff --git "a/pdf_note/RAG\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211.pdf" "b/docs/pdf_note/RAG\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211.pdf" similarity index 100% rename from "pdf_note/RAG\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211.pdf" rename to "docs/pdf_note/RAG\357\274\210\346\243\200\347\264\242\345\242\236\345\274\272\347\224\237\346\210\220\357\274\211.pdf" diff --git a/pdf_note/RLHF.pdf b/docs/pdf_note/RLHF.pdf similarity index 100% rename from pdf_note/RLHF.pdf rename to docs/pdf_note/RLHF.pdf diff --git "a/pdf_note/Transformer\346\236\266\346\236\204\347\273\206\350\212\202.pdf" "b/docs/pdf_note/Transformer\346\236\266\346\236\204\347\273\206\350\212\202.pdf" similarity index 100% rename from "pdf_note/Transformer\346\236\266\346\236\204\347\273\206\350\212\202.pdf" rename to "docs/pdf_note/Transformer\346\236\266\346\236\204\347\273\206\350\212\202.pdf" diff --git "a/pdf_note/bert\347\273\206\350\212\202.pdf" "b/docs/pdf_note/bert\347\273\206\350\212\202.pdf" similarity index 100% rename from "pdf_note/bert\347\273\206\350\212\202.pdf" rename to "docs/pdf_note/bert\347\273\206\350\212\202.pdf" diff --git "a/pdf_note/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203.pdf" "b/docs/pdf_note/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203.pdf" similarity index 100% rename from "pdf_note/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203.pdf" rename to "docs/pdf_note/\345\210\206\345\270\203\345\274\217\350\256\255\347\273\203.pdf" diff --git "a/pdf_note/\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211.pdf" "b/docs/pdf_note/\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211.pdf" similarity index 100% rename from "pdf_note/\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211.pdf" rename to "docs/pdf_note/\345\244\247\346\250\241\345\236\213\345\271\273\350\247\211.pdf" diff --git "a/pdf_note/\345\244\247\346\250\241\345\236\213\350\257\204\344\274\260.pdf" "b/docs/pdf_note/\345\244\247\346\250\241\345\236\213\350\257\204\344\274\260.pdf" similarity index 100% rename from "pdf_note/\345\244\247\346\250\241\345\236\213\350\257\204\344\274\260.pdf" rename to "docs/pdf_note/\345\244\247\346\250\241\345\236\213\350\257\204\344\274\260.pdf" diff --git "a/pdf_note/\346\200\235\347\273\264\351\223\276\357\274\210CoT\357\274\211.pdf" "b/docs/pdf_note/\346\200\235\347\273\264\351\223\276\357\274\210CoT\357\274\211.pdf" similarity index 100% rename from "pdf_note/\346\200\235\347\273\264\351\223\276\357\274\210CoT\357\274\211.pdf" rename to "docs/pdf_note/\346\200\235\347\273\264\351\223\276\357\274\210CoT\357\274\211.pdf" diff --git a/index.html b/index.html new file mode 100644 index 0000000..5117996 --- /dev/null +++ b/index.html @@ -0,0 +1,70 @@ + + + + + Document + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +