Skip to content

Commit

Permalink
add ml
Browse files Browse the repository at this point in the history
  • Loading branch information
liqiankun1111 committed Oct 11, 2024
1 parent 7511fa3 commit 3b27049
Show file tree
Hide file tree
Showing 22 changed files with 291 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ LLaMA-Factory
```

workflow.py 的逻辑言简意赅,就是拼凑运行 Trainer的dataset、model、tokenizer、data_collator等参数
1. 对于dataset 有一个load_dataset 和preprocess_dataset 的过程,preprocess_dataset 会根据任务目标不同,处理逻辑不同,也就是将数据转为input_ids 的方式不同。 最终转为trainer 也就是transformer model 可以接受的dataset,包含列 input_ids/attention_task/labels(或其它model.forward 可以支持的参数)。
1. 对于dataset 有一个load_dataset 和preprocess_dataset 的过程,preprocess_dataset 会根据任务目标不同,处理逻辑不同,也就是将数据转为input_ids 的方式不同。 最终转为trainer 也就是transformer model 可以接受的dataset,包含列 input_ids/attention_task/labels(或其它model.forward 可以支持的参数)。 PS: 对于有监督任务,比如包含name=labels 列,至于input 列则名字随意,毕竟input text 总有一个通过tokenizer 转为input_ids 的过程。传入trainer的 dataset 有input_ids 和labels等列即可。
2. Trainer 对训练逻辑已经封的很好了,内部也支持了accelerate 和 deepspeed,只要合适的配置 training_args 即可。

以pt对应的workflow.py 为例
Expand Down

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion _posts/MachineLearning/LLM/2024-08-17-llm_pre_training.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ keywords: llm pretrain
1. 首先就是不断扩大模型和数据规模(Scaling Law)。
2. 一个是越来越强调数据质量的作用,各种数据筛选方法和工具越来越多,保证质量是第一位的
3. 不断增加数学、逻辑、代码这种能够提升大模型理性能力的数据配比比例,包括在预训练阶段(增加预训练数据此类数据比例,且在预训练后面阶段来上采样此类数据,就是说**同样数据多执行几遍,以增加其对模型参数影响的权重**)和Post-Training阶段(增加此类数据占比,Llama3的经过instruct的模型比仅做预训练模型相比,各种尺寸的效果提升都很大)皆是如此。
目前看,在通用数据快被用完情况下,第三个因素会成为之后大模型进步的主导力量,包括使用数学、逻辑、代码合成数据在Post-Training阶段的应用,目前技术也越来越成熟,其质量和数量会是决定未来大模型效果差异的最关键因素。PS:合成数据其实是模型蒸馏的一种变体,合成数据是更大的模型输出数据作为Teacher,小点的模型作为Student从中学习知识,所以其实本质上是一种模型蒸馏。
目前看,在通用数据快被用完情况下,第三个因素会成为之后大模型进步的主导力量,包括使用数学、逻辑、代码合成数据在Post-Training阶段的应用,目前技术也越来越成熟,其质量和数量会是决定未来大模型效果差异的最关键因素。PS:合成数据其实是模型蒸馏的一种变体,合成数据是更大的模型输出数据作为Teacher,小点的模型作为Student从中学习知识,所以其实本质上是一种模型蒸

自研 pretrain 模型的意义又有哪些呢?
1. 各公司仅仅是开源了模型参数,但并没有开源训练框架、训练数据等更核心的内容,其实本质上还是闭源。在这种情况下,每一个 qwen 模型的使用者都无法为下一版 qwen 模型的迭代做出贡献,qwen 团队也仅仅是收获了口碑,甚至因为自己的模型已经开源可以自行部署,买他们服务的客户可能都会变少。因此,在 llm 真正走向全面开源之前(大厂公开训练代码、配比数据,任何人都可以通过提 CR 来帮助大厂优化训练效率、炼丹技巧),掌握 pretrain 的技术能力依然是有意义的;
Expand Down
29 changes: 29 additions & 0 deletions _posts/MachineLearning/LLM/2024-10-10-rerank_finetune.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---

layout: post
title: rerank微调
category: 架构
tags: MachineLearning
keywords: llm emebedding

---

<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=default"></script>

* TOC
{:toc}

## 简介(未完成)


## 为什么用rerank

是使用elasticsearch的retrieval召回的内容相关度有问题,多数情况下score最高的chunk相关度没问题,但是top2-5的相关度就很随机了,这是最影响最终结果的。我们看了elasticsearch的相似度算法,es用的是KNN算法(开始我们以为是暴力搜索),但仔细看了一下,在es8的相似度检索中,用的其实是基于HNSW(分层的最小世界导航算法),HNSW是有能力在几毫秒内从数百万个数据点中找到最近邻的。为了检索的快速,HNSW算法会存在一些随机性,反映在实际召回结果中,最大的影响就是返回结果中top_K并不是我们最想要的,至少这K个文件的排名并不是我们认为的从高分到低分排序的。

因为在搜索的时候存在随机性,这应该就是我们在RAG中第一次召回的结果往往不太满意的原因。但是这也没办法,如果你的索引有数百万甚至千万的级别,那你只能牺牲一些精确度,换回时间。这时候我们可以做的就是增加top_k的大小,比如从原来的10个,增加到30个。然后再使用更精确的算法来做rerank,使用一一计算打分的方式,做好排序。

## 微调

微调数据集格式为[query,正样本集合,负样本集合]。微调在Embeding模型与Reranker模型采用同类型数据集,并将语义相关性任务视为二分类任务,采用BCE作为损失函数。

https://zhuanlan.zhihu.com/p/704562748 未细读
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---

layout: post
title: embedding的原理及实践
title: 推荐系统embedding原理及实践
category: 架构
tags: MachineLearning
keywords: embedding
Expand All @@ -25,9 +25,8 @@ Embedding层是神经网络中的一层,用于将离散的符号(如单词
1. 把item_id当成特征,为什么有效?推荐算法的**传统机器学习时代**:博闻强记。推荐系统记住什么?能够记住的肯定是那些「常见、高频」的模式。到了春节,来了中国人,电商网站给他推饺子,大概率能够购买,到了感恩节,来了美国人,电商网站给他推火鸡,大概率也能购买。为什么?因为<春节,中国人,饺子>的模式、<感恩节、美国人、火鸡>的模式「在训练样本中出现得太多太多了,推荐系统只需要记得住」,下次遇到同样的场景,“照方扒抓药”,就能“药到病除”。如果user侧特征表明这个用户喜欢篮球,那么把“item_id = 某一款经典的耐克篮球鞋”,那两个信号一组合,效果岂不是再明显不过吗?所以把item_id当特征喂入模型,非常有必要,因为它是模型值得记住的。
2. 把item_id先embedding再喂入模型,为什么有效?如果让模型只牢牢记住`<user喜欢篮球,item_id=耐克鞋经典款>`这个pattern就足够了吗?如果耐克新推出了一款篮球鞋,一个只会记忆的模型能够把这款新鞋推出去吗?答案是否定的,因为`<user喜欢篮球,item_id=耐克新款>`由于在样本中出现次数少,根本不在模型的记忆中。而如果这时有了两款耐克鞋的embedding,理论上来讲,新款耐克鞋的item_id embedding应该与经典款耐克鞋embedding有几分相似(表现为向量空间距离近)。因为**基于embedding的模型已经由“精确匹配”进化为“模糊查找”**,模型会认为给“喜欢篮球的用户”推荐新款nike鞋,效果可能比推荐经典款差一些,但也差不多,值得一试。这就是引入item id embedding的意义。

## 基本概念及原理

### 推荐系统范畴
## 基本概念及原理

一种表述:Embedding 是个英文术语,如果非要找一个中文翻译对照的话,我觉得“向量化”(Vectorize)最合适。Embedding 的过程,就是把数据集合映射到向量空间,进而**把数据进行向量化**的过程。Embedding 的目标,就是找到一组合适的向量,来刻画现有的数据集合。
1. 比如让国家作为模型参数,我们该如何用数字化的方式来表示它们呢?毕竟,模型只能消费数值,不能直接消费字符串。一种方法是把字符串转换为连续的整数,然后让模型去消费这些整数。。在理论上,这么做没有任何问题。但从模型的效果出发,整数的表达方式并不合理。为什么这么说呢?我们知道,连续整数之间,是存在比较关系的,比如 1 < 3,6 > 5,等等。但是原始的字符串之间,比如,国家并不存在大小关系,如果强行用 0 表示“中国”、用 1 表示“美国”,逻辑上就会出现“中国”<“美国”的悖论。**仅仅是把字符串转换为数字,转换得到的数值是不能直接喂给模型做训练**
Expand Down Expand Up @@ -62,19 +61,6 @@ Embedding这块,spark MLlib 和 机器学习库 都提供了处理函数。利

在梯度下降这块对embedding weight也有针对性的优化算法,[从梯度下降到FTRL](https://zhuanlan.zhihu.com/p/144562494)FTRL是在广告/推荐领域会用到的优化方法,适用于对高维稀疏模型进行训练,获取稀疏解。

### 大模型范畴

tokenizer的下一步就是将token的one-hot编码转换成更dense的embedding编码。在ELMo(Embeddings from Language Model)之前的模型中,embedding模型很多是单独训练的,而ELMo之后则爆发了直接将embedding层和上面的语言模型层共同训练的浪潮。每个单词会定位这个表中的某一行,而这一行就是这个单词学习到的在嵌入空间的语义。

![](/public/upload/machine/embedding_matrix.jpg)

[没有思考过 Embedding,不足以谈 AI](https://mp.weixin.qq.com/s/7kPxUj2TN2pF9sV06Pd13Q)计算的基础是数,而自然语言是文字,因此很容易想到要做的第一步是让文字数字化,为行文方便,我们将这个过程叫做编码。要设计编码的方法,自然需要思考的问题是:哪些性质是编码规则必须要满足的?
1. 每一个词具有唯一量化值,不同词需要具有不同的量化值
2. 词义相近词需要有"相近"的量化值;词义不相近的词量化值需要尽量“远离”。当性质二得到满足时,同义的句子在序列特征上会更加接近,这将有利于计算机而言更高效地理解共性、区分特性;反之则会给计算机制造非常多的困难。**难以捕捉同质内容之间的共性,就意味着模型需要更多的参数才能描述同等的信息量**,学习的过程显然困难也会更大。OpenAI 的 Jack Rae 在 Standford 的分享 中提到了一个很深刻的理解语言模型的视角:语言模型就是一个压缩器。所有的压缩,大抵都能被概括在以下框架内:提取共性,保留个性,过滤噪声。带着这个视角去看,就更加容易认识到性质二的必要性。不同词所编码的数值,是否基于词义本身的相似性形成高区分度的聚类,会直接影响到语言模型对于输入数据的压缩效率。因为词是离散分布的,而计算模型的输出 —— 除非只使用非常简单的运算并且约束参数的权重 —— 很难恰好落在定义好的量化值中。对于神经网络模型,每一个节点、每一层都必须是连续的,否则便无法计算梯度从而无法应用反向传播算法。**这两个事实放在一起可能会出现的情况是:词的量化值可以全部是整数,但是语言模型的输出不一定**。例如当模型输出 1.5,词表只定义了 1 和 2,这时该如何处理呢?我们会希望 1 和 2 都可以,甚至 3 可能也不会太离谱,因此 1 和 2 所代表的词在词义上最好有某种共性。当相近的词聚集到一起,推断出有效输出的概率就会更高。
3. 词义的多维性。对于每一个词,我们可以表达为一组数,而非一个数;这样一来,就可以在不同的维度上定义远近,词与词之间复杂的关系便能在这一高维的空间中得到表达。

图像可以有embedding,句子和段落也可以有 embedding —— 本质都是通过一组数来表达意义。段落的 embedding 可以作为基于语义搜索的高效索引,AI 绘画技术的背后,有着这两种 embedding 的互动 —— 未来如果有一个大一统的多模态模型,embedding 必然是其中的基石和桥梁 。

## 实践

《深度学习推荐系统实战》为什么深度学习的结构特点不利于稀疏特征向量的处理呢?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ $$

### 编码视角

NLP 神经网络模型的本质就是对输入文本进行编码,常规的做法是首先对句子进行分词,然后将每个词语 (token) 都转化为对应的词向量 (token embeddings),这样文本就转换为一个由词语向量组成的矩阵 $X=(x_1,x_2,...,x_n)$,其中$x_i$就表示第i个词语的词向量。
NLP 神经网络模型的本质就是对输入文本进行编码,常规的做法是首先对句子进行分词,因为模型是无法直接处理文本的,只能处理数字,就跟ASCII码表、Unicode码表一样,计算机在处理文字时也是先将文字转成对应的字码(token),然后为每个字码编写一个对应的数字记录在表中(Tokenizer)。然后将每个数字都转化为对应的词向量 (token embeddings),这样文本就转换为一个由词语向量组成的矩阵 $X=(x_1,x_2,...,x_n)$,其中$x_i$就表示第i个词语的词向量。

以将$x_t$ 编码为 $y_t$ 的视角来理解(结合了上下文词表示)
1. RNN(例如 LSTM)的方案很简单,每一个词语$x_t$对应的编码结果$y_t$通过递归地计算得到:$y_t=f(y_{t-1},xt)$,RNN 本质是一个马尔科夫决策过程,难以学习到全局的结构信息;
Expand Down
63 changes: 63 additions & 0 deletions _posts/MachineLearning/Model/2024-10-11-bert.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---

layout: post
title: bert
category: 架构
tags: MachineLearning
keywords: gcn

---

## 简介(未完成)

* TOC
{:toc}

BERT 是一个用 Transformers 作为特征抽取器的深度双向预训练语言理解模型。通过海量语料预训练,得到序列当前最全面的局部和全局特征表示。

[论文](https://arxiv.org/abs/1810.04805v1)

bert 名称来自 Bidirectional Encoder Representations from Transformers. Unlike recent language representation models, BERT is designed to pre-train deep bidirectional(相对gpt的单向来说,是双向的) representations by jointly conditioning on both left and right context in all layers. As a result, the pre-trained BERT representations can be fine-tuned with just one additional output layer to create state-of-the-art models for a wide range of tasks, such as question answering and language inference, without substantial task-specific architecture modifications. PS:ELMo 是基于rnn,在应用到下游任务时,还需要做一些模型结构的变动。有了一个训练好的bert之后,只需要再加一个额外的层,就可以适配各种任务。


## 模型结构

BERT的基础集成单元是Transformer的Encoder,BERT与Transformer 的编码方式一样。将固定长度的字符串作为输入,数据由下而上传递计算,每一层都用到了self attention,并通过前馈神经网络传递其结果,将其交给下一个编码器。

![](/public/upload/machine/bert_model.jpg)

模型输入

![](/public/upload/machine/bert_input.jpg)

输入的第一个字符为[CLS],在这里字符[CLS]表达的意思很简单 - Classification (分类)。

模型输出

![](/public/upload/machine/bert_output.jpg)

每个位置返回的输出都是一个隐藏层大小的向量(基本版本BERT为768)。以文本分类为例,我们重点关注第一个位置上的输出(第一个位置是分类标识[CLS]) bert 希望它最后的输出代表整个序列的信息。该向量现在可以用作我们选择的分类器的输入,在论文中指出使用单层神经网络作为分类器就可以取得很好的效果。例子中只有垃圾邮件和非垃圾邮件,如果你有更多的label,你只需要增加输出神经元的个数即可,另外把最后的激活函数换成softmax即可。

![](/public/upload/machine/bert_classify.jpg)

## 训练方式

![](/public/upload/machine/bert_masked.jpg)

PS:训练时,自己知道自己mask 了哪个词,所以也是无监督了。

## 应用

BERT的论文为我们介绍了几种BERT可以处理的NLP任务:
1. 短文本相似
![](/public/upload/machine/bert_similarity.jpg)
2. 文本分类
3. QA机器人
4. 语义标注
5. 特征提取 ==> rag 里的emebedding

PS:最后一层的输出 选用[cls] 对应的embedding 或多个emebedding 套个FFNN + softmax,二分类或多分类任务就都可以解决了。

## 其它

WordPiece 分词会切词根, 切词根的目的是,很多词根是复用的,这样能减少此表大小(以3w 左右的词典,不然英文单词不只3w)
Loading

0 comments on commit 3b27049

Please sign in to comment.