我的学习笔记

土猛的员外

Embedding——从入门到生产使用

搜索功能已经深入到我们的日常生活中,我们常说“Google一下就知道了”,用户已经开始期望几乎每个应用程序和网站都提供某种类型的搜索功能。随着有效搜索变得越来越相关(双关语),寻找新的方法和体系结构来改进搜索结果对于架构师和开发人员来说至关重要。从基础开始,这篇博文将描述Redis中利用深度学习模型创建的向量Embeddings的人工智能搜索功能。

向量Embedding

什么是向量Embedding?简单地说,向量Embedding是可以表示许多类型数据的数字列表。

向量Embedding非常灵活。音频、视频、文本和图像都可以表示为矢量Embedding。这种特性使得向量Embedding成为数据科学家工具箱中的瑞士军刀。

Embedding creation process

从不同类型的数据创建向量Embedding的过程:音频,文本,视频。

为了解释为什么Embedding提供了这样的实用程序,让我们看一下以前处理文本数据(如表格数据中的分类值)的方法。数据科学家有时会使用one-hot编码等方法将分类特征转换为数值。这些编码将为每种类型的类别创建一个列。值为1表示项目属于该列指定的类别。相反,值为0表示项目不属于该类别。

例如,考虑书籍类型:“小说”、“非小说”和“传记”。每一种体裁都可以编码成一个热向量,然而,这样的向量会非常稀疏,因为书籍通常只属于两个体裁。下图显示了这种编码是如何工作的。注意这里0的数量是1的两倍。对于像图书类型这样的类别,随着更多的类型被添加到数据集中,这种稀疏性将会呈指数级恶化。

稀疏性会给ML模型带来挑战。对于每一种新的类型,编码表示的大小都会增长,因此数据集的计算成本会变得很高。

One-hot encoding example

One-hot(独热)编码示例

对于图书类型,或者任何具有相对较少类别的分类数据,我们可以使用简单的one-hot编码,但是,对于整个英语语言呢?对于这种规模的语料库,这种编码方法将变得不切实际。

进入向量Embedding

向量Embedding呈现固定大小的表示,不随数据中观测值的数量而增长。由模型创建的结果向量,通常是384个浮点值,比其他编码方法(如one-hot编码)的表示密度要高得多。这意味着在更少的字节中存在更多的信息,因此在计算上的利用成本更低。正如您稍后将读到的,这些密集表示可以用于多种目的,例如反向图像搜索、聊天机器人、问答和推荐系统。

创建向量Embedding

为了理解向量Embedding是如何创建的,对现代深度学习模型的简要介绍是有帮助的。

机器学习模型不使用非结构化数据。为了使模型能够理解文本或图像,我们必须将它们转换为数字表示。在机器学习之前,这样的表示通常是通过Feature Engineering“手工”创建的。

随着深度学习的出现,复杂数据中的非线性特征交互是由模型学习而不是人工设计的。当一个输入遍历深度学习模型时,该输入数据的新表示将以不同的形状和大小创建。每一层通常关注输入的不同方面。深度学习的这一方面,从输入中“自动”生成特征表示,构成了如何创建向量Embedding的基础。

例如,考虑在ImageNet数据集上训练的著名的ResNet模型。ResNet是一种卷积神经网络(CNN),通常用于与图像相关的任务。在这种情况下,ResNet被训练来预测图像中的对象属于1000个类中的哪一个。

在训练过程中,ResNet将捕获图像中存在的特征信息,通过将图像传递给多个卷积层、池化层和完全连接层。这些图层将捕获边缘、线条和角等特征,并将它们分组到传递给下一个图层的“桶”中。由于CNN的空间不变特性,无论边缘或直线出现在图像的哪个位置,这些特征都将始终映射到相同的桶。这些层将通过模型的层变得越来越小,直到一个由1000个浮点值组成的完全连接的层作为输出。每个值代表1000个类中的1个。该值越高,图像中的对象属于该类的概率就越大。

Diagram of a simple Convolutional Neural Network (CNN)

简单卷积神经网络(CNN)示意图

ResNet和其他类似的图像分类模型回答了这个问题:“这个图像中是什么类型的对象?”然而,这些分类在回答诸如“哪些图像与此图像相似?”之类的prompts时用处不大。对于这个问题,我们需要一起比较图像。尽管没有专门针对这项任务进行训练,ResNet仍然很有用,因为它可以捕获图像的密集表示。

简单地说,CNN和其他类似的模型学习有用的数据表示,以执行图像分类等任务。当输入通过模型的各个层时,可以提取这些表示。被提取的层,也称为潜在空间,通常是靠近模型输出的层。在上图中,这可能是包含768或500个隐藏单位的图层。提取的层或潜在空间提供了一个密集的表示,其中包含有关当前特征的信息,这对于视觉相似性搜索等任务在计算上是可行的。

这是向量Embedding。

存在大量的预训练模型,可以很容易地用于创建向量Embedding。Huggingface Model Hub (https://huggingface.co/models)包含许多模型,可以为不同类型的数据创建Embedding。例如,[all-MiniLM-L6-v2模型](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2)是在线托管和运行的,不需要专业知识或安装。

sentence_transformers这样的包,也来自HuggingFace,为语义相似度搜索、视觉搜索等任务提供了易于使用的模型。要使用这些模型创建Embeddings,只需要几行Python代码:

1
2
3
4
5
6
7
8
9
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')

sentences = [
"That is a very happy Person",
"That is a Happy Dog",
"Today is a sunny day"
]
embeddings = model.encode(sentences)

语义相似度搜索的向量Embedding

语义相似搜索是将文本片段进行比较,以找出包含最相似含义的文本的过程。虽然这对普通人来说似乎很容易,但语言是相当复杂的。将非结构化文本数据提炼成机器学习模型可以理解的格式一直是许多自然语言处理研究人员的研究主题。

向量Embeddings为任何人提供了一种执行语义相似搜索的方法,而不仅仅是NLP研究人员或数据科学家。它们提供了一种有意义的、计算效率高的数字表示,可以通过预先训练的模型“开箱即用”来创建。下面是一个语义相似度的例子,它概述了用上面所示的sentence_transformers库创建的向量Embedding。

让我们看看下面的句子:

  • “That is a happy dog(那是一只快乐的狗)”
  • “That is a very happy person(那是一个非常幸福的人)”
  • “Today is a sunny day(今天是个晴天)”

这些句子中的每一个都可以转换成向量Embedding。下面是一个简化的表示,突出显示了这些示例句子在二维向量空间中相对于彼此的位置。这对于从视觉上衡量我们的Embedding如何有效地表示文本的语义意义非常有用。下文将详细介绍。

A simplified plot of vector embeddings projected into 2 dimensions.

向量Embeddings投影到二维的简化图

假设我们要将这些句子与“那是一个快乐的人”进行比较。首先,我们为查询语句创建向量Embedding。

1
2
3
4
5
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')

# create the vector embedding for the query
query_embedding = model.encode("That is a happy person")

接下来,我们需要比较查询向量Embedding和数据集中的向量Embedding之间的距离。

有很多方法可以计算向量之间的距离。当涉及到语义搜索时,每种方法都有自己的优点和缺点,但我们将在另一篇文章中讨论。下面显示了一些常见的距离度量。

5-1

用于计算向量相似度的距离度量。

在这个例子中,我们将使用余弦相似度来度量两个向量的内积空间之间的距离。

Formula for Cosine Similarity

余弦相似度公式

在Python中,这看起来像

1
2
def cosine_similarity(a, b):
return np.dot(a, b)/(norm(a)*norm(b))

在我们的查询向量和上图中的其他三个向量之间运行这个计算,我们可以确定句子之间的相似程度。

2D plot showing the cosine similarity between the vector embeddings created from our sentences earlier

2D图显示了之前从我们的句子中创建的向量Embeddings之间的余弦相似性

你可能已经猜到,“That is a very happy person(那是一个非常幸福的人)”和“That is a happy person(那是一个幸福的人)”是最相似的句子。这个例子只捕获了向量Embeddings的许多可能用例中的一个:语义相似搜索

下面列出了运行整个示例的Python代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import numpy as np

from numpy.linalg import norm
from sentence_transformers import SentenceTransformer

# Define the model we want to use (it'll download itself)
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')

sentences = [
"That is a very happy person",
"That is a happy dog",
"Today is a sunny day"
]

# vector embeddings created from dataset
embeddings = model.encode(sentences)

# query vector embedding
query_embedding = model.encode("That is a happy person")

# define our distance metric
def cosine_similarity(a, b):
return np.dot(a, b)/(norm(a)*norm(b))

# run semantic similarity search
print("Query: That is a happy person")
for e, s in zip(embeddings, sentences):
print(s, " -> similarity score = ",
cosine_similarity(e, query_embedding))

在安装NumPysentence_transformers之后,运行这个脚本应该会得到以下计算结果

1
2
3
4
5
>>> Query: That is a happy person

>>> That is a very happy person -> similarity score = 0.94291496
>>> That is a happy dog -> similarity score = 0.69457746
>>> Today is a sunny day -> similarity score = 0.25687605

该脚本的结果应该与所选模型在HuggingFace inference API上看到的结果一致。

HuggingFace inference API similarity results

HuggingFace推理API相似度结果

向量Embedding搜索在生产环境中的使用

开发和生产是两个不同的东西,在学习了更多之后,你可能会开始问这样的问题:

  • 我把这些向量存储在哪里?
  • API应该是什么样子?
  • 如何将其与过滤等传统搜索功能结合起来?

幸运的是,开发Redis的好人们决定为你找出这些问题,并将向量相似搜索(VSS)功能构建到现有的reresearch模块中。这基本上把Redis变成了一个低延迟的向量数据库。

Redis as a vector database

Redis是一个矢量数据库

VSS功能是作为reresearch模块的新功能而构建的。它允许开发人员像在Redis散列中存储任何其他字段一样轻松地存储向量。它提供了在大型向量空间中执行低延迟搜索所需的高级索引和搜索功能,通常分布在许多机器上的向量从数万到数亿不等。

Redis现在支持两种类型的向量索引:

  1. Flat
  2. 分级可导航小世界(HNSW)

以及3个距离度量:

  1. LP —— 欧几里得距离
  2. IP —— 内积
  3. cos —— 余弦相似度(如上图所示)

下面是一个使用redis -py在向量被加载到Redis后创建索引的例子。

1
2
3
4
5
6
7
8
9
10
11
12
from redis import Redis
from redis.commands.search.field import VectorField, TagField

def create_flat_index(redis_conn: Redis, number_of_vectors: int, distance_metric: str='COSINE'):

image_field = VectorField("img_vector","FLAT", {
"TYPE": "FLOAT32",
"DIM": 512,
"DISTANCE_METRIC": distance_metric,
"INITIAL_CAP": number_of_vectors,
"BLOCK_SIZE": number_of_vectors})
redis_conn.ft().create_index([image_field])

索引只需要创建一次,当新的哈希值存储在Redis中时,索引会自动重新索引。在将向量加载到Redis中并创建索引之后,就可以为各种基于相似性的搜索任务形成和执行查询。

索引只需要创建一次,当新的哈希值存储在Redis中时,索引会自动重新索引。在将向量加载到Redis中并创建索引之后,就可以为各种基于相似性的搜索任务形成和执行查询。

更好的是,所有现有的reresearch功能,如文本、标签和基于地理的搜索,都可以与VSS功能协同工作。这被称为“混合查询”。对于混合查询,传统的搜索功能可以用作矢量搜索的预过滤器,这可以帮助限制搜索空间。

上面的索引创建函数(create_flat_index)可以很容易地通过添加新字段(如redis-py中的TagFieldTextField)来支持混合查询。

Redis VSS演示

最近,我构建了一个web应用程序来探索这些功能。Fashion Product Finder利用了Redis中新的VSS功能,以及我最喜欢的Redis生态系统的其他部分,如redis-om-python。您可以访问应用程序在这里

注册使用该应用程序后,您将看到如下所示的页面。

Fashion Product Finder application

时尚产品查找应用程序,使用由Redis提供的向量相似度搜索

要通过文本表示查询类似的产品,请找到您喜欢的产品并单击by text。同样,要通过视觉向量搜索查询,请单击产品上的by Image按钮。

可以为产品的性别和类别设置混合搜索属性,以便在执行矢量搜索时,返回的项目将通过这些标记进行过滤。下面是选择右下角黑色手表时的视觉向量搜索示例。

Fashion Product Finder search results

通过图片查询类似手表后的搜索结果为黑色G-Shock手表。

这个演示是一种探索Redis VSS功能的有趣方式,然而,这并不是应用程序中使用的Redis生态系统的唯一组件。事实上,Redis是这个应用程序使用的唯一数据库,用RedisJSON存储产品元数据,用RediSearch存储矢量数据。

您可以查看整个代码库在这里。如果你觉得有用,请点赞和分享!

有关Redis和reresearch模块中VSS的更多信息,您可以查看以下资源:

参考文档


目前正在接受试用中!!!

请将您的称谓、公司名称和使用场景,发邮件到yuanwai@mengjia.net。

也可以直接加微信:lxdhdgss 咨询

更多详情,可查看文章:TorchV Bot开始对外试用了!


最新内容,关注“土猛的员外”公众号

不开玩笑——在家部署1800亿参数的Falcon大模型

0

Falcon的发布机构TII官网

前几天Falcon-180B大模型发布,在Hugging Face的所有LLM(大语言模型)里面排名第一,应该也是迄今为止参数量最大的开源预训练模型了。就性能来说,我看很多国外的专家都在给他背书,说仅次于GPT-4,和PaLM2相当,也就是说性能已经超过了大部分常用的ChatGPT3.5(GPT-3.5)了。开始我是不相信的,但是马上一想,这是TII(阿联酋阿布扎比技术创新研究所)发布的,我信了,因为他们是一群有“钞”能力的人。

很快,我们吕总就开始问我了,搞不搞。我一想到1800亿参数,那还不得上百张A100啊,不可能的,直接拒绝了。但是意识到可以自己武断了,于是再去好好查看了他们的网站,果然是我唐突了。官方说推理的话,400GB的显存就可以了,也就是6张A100-80GB就可以了(实际需要大概8张A100),大概也就是84万元(实际需要112万元)人民币(不考虑其他设备成本的话)。

好吧,这个“也就”用的有点飘,我感觉到了。

说实话180B的大模型,目前还没有太多中文benchmark出来,所以,我还是很想去尝试一下,看看效果的。

于是,我找到了一篇文章:《Falcon 180B: Can It Run on Your Computer?》,可能大多数人不一定能打开原文,那么可以看我下面的一些转述。

注:本文中180B中的B代表billion,也就是十亿,所以180B=1800亿。

2023年5月,阿布扎比技术创新研究所(TII)已经发布了两种预训练大语言模型:Falcon-7b和Falcon-40b,以及它们的聊天版本(Chat)。这两个模型表现出了非常好的性能,并曾经在OpenLLM排行榜上排名第一。

TII发布的第三个大模型就是Falcon-180B,一个1800亿个参数模型。它比Llama2-70b多2.5x参数,比Falcon-40b多4.5x参数。

关于Falcon-180B的一些基本情况(1)

  • 预训练3.5万亿tokens(2)
  • 使用Apache 2.0 license分发
  • 容量大小为360GB
  • 在OpenLLM排行榜(3)上排名第一(截至2023年9月11日)

img

OpenLLM排行榜截图(2023年9月11日)

还有一个聊天(Chat)版本。这些模型可以在Hugging Face中心找到:

Falcon-180B是完全免费和最先进的。但它也是一个巨大的模型

那么,它能在你的电脑上运行吗?

除非你的计算机已经准备好进行非常密集的计算,否则它无法开箱即用地运行Falcon180B。您将需要升级您的计算机并使用该模型的量化版本。

接下来,我们来看看如何在消费类硬件上运行Falcon-180B。我们将看到,在家用计算机上运行一个1800亿个参数的模型是可行的。我还讨论了几种有助于减少硬件需求的技术。

在电脑上加载Falcon180B所需的条件

您需要知道的第一件事是,Falcon180B有1800亿个参数,存储形式为bfloat16。一个bfloat16参数在内存中占2个字节。

当你加载一个模型时,标准Pytorch管道是这样工作的:

  1. 创建一个空模型:180B个参数* 2字节= 360 GB
  2. 在内存中加载其权重:180B个参数* 2字节= 360 GB
  3. 在步骤1创建的空模型中加载步骤2加载的权重
  4. 将步骤3得到的模型移动到设备上进行推理,例如GPU

步骤1和步骤2消耗内存。总的来说,您需要720 GB的可用内存。这可以是CPU RAM,但为了快速推理,您可能希望使用GPU,例如,9块A100(80GB)VRAM刚好是720GB,但实际上最好是12块A100。

无论是CPU RAM还是VRAM,这都是很大的内存。幸运的是,目前其实有一些方法可以“曲线”完成。

在HuggingFace,Falcon-180B使用安全防护器格式(safetensors format)分发。与标准Pytorch格式相比,这种格式有几个优点。它(几乎)没有复制(注:不需要有一个巨大或等量内存区域来做中间缓存),所以模型直接加载到第1步创建的空模型中。它节省了很多内存。

关于safetensors

safetensors 节省内存,而且它也使模型更安全运行,因为没有任意代码可以存储在这种格式。Safetensors模型的加载速度也快得多。当您从Hugging Face下载模型时,请使用此格式而不是“.bin”格式,以便更快、更安全、更节省内存。

尽管看起来我们跳过了第2步,但仍然会有一些内存开销。TII在Hugging Face的模型介绍上写着400GB的内存可以工作。这仍然很大,但比使用标准Pytorch格式少了220gb。

我们需要一个400 GB的设备,例如,5个A100(80G)的GPU VRAM,但这个结果离“消费级”家用电脑配置还很远。

在多个存储设备上分布式Falcon180B

你可能没有一个400 GB的内存设备,但如果你把以下所有设备的内存组合起来,你的电脑可能有超过400 GB的内存:

  • GPU VRAM:如果你有NVIDIA RTX 3090或4090,那已经是24GB了。
  • CPU RAM:大多数现代计算机至少有12GB的CPU内存,CPU的扩展也非常便宜。
  • 硬盘(或SSD):SSD一般都可以有几个TB存储空间,而且是可以用SWAP做虚拟内存的。请注意,如果您计划使用SSD(固态硬盘)运行LLM,那么它将比原来的机械硬盘驱动器速度快得多,但是仅仅是高铁比汽车快的意思,和飞机、火箭差距依然很大。

为了利用可用的设备,我们可以拆分Falcon-180B,以便它按照以下优先顺序使用设备的最大可用内存:GPU, CPU RAM和SSD。

这很容易通过Accelerate上的device_map架构来实现。

Device_map将模型的整个层放在您拥有的不同设备上。

img

device_map架构示意图

如果您想查看device_map使用的一些示例,请参考这篇文章

Device_map对于解决CUDA内存不足问题来说确实是一种很好的方法,但如果你打算在消费级硬件上使用Falcon180B,那还远远不够理想。即使是拥有24 GB VRAM的GPU(比如RTX 4090)和32 GB CPU RAM的高端配置,它也依然还需要动用几百GB的硬盘空间。

这里有两个原因:

  • 硬盘驱动器/SSD总体来说比GPU VRAM、CPU RAM慢得多。从硬盘装载和运行Falcon180B需要很长时间。
  • 消费类硬盘和固态硬盘不是为这种密集计算使用设计和测试的。如果模型的许多部分被装载到硬盘驱动器上,系统将不得不在推理期间多次访问和读取模型的大量分割部分。这是长时间的大量读取操作。如果您连续数天进行推理,例如生成一些合成数据集,这可能会损坏您的硬盘,或者至少会显著降低其预期寿命。

为了避免过度使用硬盘,我们最好的方式就是去除硬盘方案,那么剩下来的解决方案实在不多了:

  • 增加一个GPU:大多数高端主板可以容纳两个RTX 3090/4090。它会给你48 GB的VRAM。
  • 扩展CPU RAM:大多数主板有4个插槽可用于CPU RAM套件。4x128GB CPU内存的套件有出售,但不容易找到,而且仍然很贵。 注意:您的操作系统可以支持的CPU RAM总量也有限制。Windows 10是2tb。如果你使用的是一个老版操作系统,你应该在购买更多的内存之前看看它的文档
  • 量化版Falcon180B和扩展CPU RAM

Falcon180B的量化版是减少内存消耗的最佳方案之一。

使用量化版Falcon180B减少RAM尺寸

现在的常见做法是将非常大的语言模型量化到较低的精度。GPTQ(4)和bitsandbytes nf4(5)是将LLM量化到4位精度的两种常用方法。

Falcon180B在使用bfloat16的情况下,我们看到它的尺寸是360 GB。

一旦量化到NF4精度,它只需要90GB(1800亿个参数* 0.5字节)。我们可以用100GB内存(90GB +一些内存开销)加载NF4的Falcon-180B。

如果你有24 GB的VRAM,你“只”需要75 GB的CPU RAM。这仍然是很多,但比加载原始模型便宜得多,并且在推理期间不会需要和硬盘上的模型层做交换。注意:您仍然需要100 GB的可用硬盘空间来存储模型

你甚至不需要GPU。使用128 GB的CPU RAM,您可以仅使用CPU进行推理。

量化本身是非常昂贵的。值得庆幸的是,我们已经可以在网上找到量化的版本。TheBloke:https://huggingface.co/TheBloke 发布了使用GPTQ制作的4位版本:

注:也有3位模型可作为模型的“分支”。按照4位型号卡的说明来获取它们

虽然模型的精度降低了,但根据Hugging Face的实验,模型的性能仍然相似这一点太棒了!!!)。

GPTQ模型的推理速度很快,您可以使用LoRA适配器对它们进行微调,可以在这里查看如何微调使用GPTQ量化的Llama 2(6)

虽然可以对GPTQ模型进行微调,但我不推荐这样做。使用QLoRA进行微调具有类似的内存消耗,但由于使用nf4进行了更好的量化,因此产生了更好的模型,如QLoRA论文(7)所示。

最后

总而言之,您需要量化版本(4-bit Falcon180B)和100GB内存才能在高配置的家用计算机上运行Falcon-180B。

对于快速推理微调,你需要使用到GPU。RTX 4090(或RTX 3090 24GB,更实惠,但速度更慢)将足以加载量化模型的1/4。如果你的电脑机箱有足够的空间,你甚至可以放两张RTX卡。

如果你想在一个只有CPU的配置上运行Falcon-180b,也就是说,没有任何GPU,那你只把放弃微调的想法,它会慢到你怀疑人生,嗯,推理也同样会很慢。如果要在纯CPU的机器上运行,那llama.cpp(C++重写的llama)是个不错的选择。我们只能期待Falcon180B也有这样的版本,那在存内存的环境下运行Falcon180B才有可能。

我目前家里电脑的配置是RTX 4090(24GB) + 32GB内存,如果再买一块64GB的内存,好像就可以跑起来了哈哈。64GB的内存大概1400元,虽然有些舍不得,但感觉有点心动。

引用:

1.Falcon-180B模型介绍:https://huggingface.co/tiiuae/falcon-180B

2.RefinedWeb:https://huggingface.co/datasets/tiiuae/falcon-refinedweb

3.OpenLLM排行榜:https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard

4.GPTQ:https://arxiv.org/abs/2210.17323

5.bitsandbytes nf4:https://arxiv.org/abs/2305.14314

6.微调使用GPTQ量化的Llama 2:https://kaitchup.substack.com/p/quantize-and-fine-tune-llms-with?source=post_page-----c3f3fb1611a9--------------------------------

7.QLoRA论文:https://arxiv.org/abs/2305.14314


目前正在接受试用中!!!

请将您的称谓、公司名称和使用场景,发邮件到yuanwai@mengjia.net。

也可以直接加微信:lxdhdgss 咨询

更多详情,可查看文章:TorchV Bot开始对外试用了!


最新内容,关注“土猛的员外”公众号

使用frp轻松搞定ssh家里的服务器

起因

前些天听我邻居介绍了ngrok可以做内网穿透,这样就可以把我家里的那台带了RTX4090的PC用起来。于是我折腾了一通,发现ngrok配置是简单的,但用它自己的server来做转发,网络太慢了,于是就放弃了。昨晚在Github搜索ngrok的替代品时,发现有人整理了一个非常完整的tunneling工具列表frp赫然列在第一位。

list

图1:tunneling工具列表(部分)

frp的优势

相比于ngrok,这次的frp更符合我的需求。frp的一些特性优势:

  • 自定义服务端:可以使用自己的云服务器做服务端,速度有保障(确实很快);
  • 类型支持丰富:包括http/https/ssh/ssh2/dns/socket/ftp/xtcp等类型;
  • 文档出色:有中文文档,如果你有高级需求,那文档还是很重要的。

也许ngrok也有这些功能,但我没有耐心继续找下去了,frp更符合我。

frp安装

frp安装其实比较简单。

在介绍安装之前,先介绍一下我的PC配置,你们可以按自己的情况下载和安装:

  • 本地服务器:i7/RTX4090/32G/2TB,Ubuntu Server 22.04.3 LTS,对应的就是你自己家里的电脑;
  • 云服务器:阿里云,轻应用服务器(612元/年,买了一年多了),CentOS,3M带宽。

因为都是linux系统,所以我下载的是frp_0.51.3_linux_amd64.tar.gz,大家可以在这里下载

如果是公众号文章,会无法直接点击跳转,您可以点击左下角的“阅读原文”,原文是我的blog,那里的链接可以直接点击。

我们可以把这个文件分别传到本地服务器和云服务器,然后用tar -xvf frp_0.51.3_linux_amd64.tar.gz把文件解开,我们可以发现里面的文件如下:

frp_folder

图2:frp目录下的文件
  • frpc:对应的是你家里的电脑;
  • frps:对应的是云服务器,公网上的;
  • xxxx.ini:这是配置文件,你要做的主要配置仅仅在frpc.inifrps.ini这两个文件里面。

其实解压好之后,安装其实就算完成了,对于存放的目录其实没太多要求。

frp配置

配置可能是这里面最复杂的了,但是总体上也非常简单,只要你照着我下面的步骤做。

【服务器端】

先来看服务端,在我这里就是那台有公网IP的阿里云服务器。

进入到frp的目录,输入以下命令打开frps.ini:

1
sudo vim frps.ini

在这里,我们以配置ssh为例,你可以先看一下官方文档

guanf

图3:frps的服务端和客户端配置

教程已经非常清楚了,我无需再详细解读,这里我贴一下我的配置,以便大家可以对照看看如何修改。

1
2
3
[common]
bind_port = 7000
vhost_http_port = 8080

这里如果大家只是配置ssh的话,只需要上面的bind_port = 7000,注意=两边的空格。下面的vhost_http_port是为了放开家里服务器的web服务的。

然后用命令:

1
sudo ./frps -c ./frps.ini

启动服务端的服务。

注意:一般是先启动服务端(也就是公网上的),再启动本地的。

【注册成系统服务】

目前的命令在我们的终端关闭之后就会结束,所以如果你要持续运行,可以将它注册成系统服务。官方也提供了很详细的文档,使用systemd,很简单,在服务端和本地端都可以用,我就不再赘述了。

【本地配置】

好,接下来我们来配置本地这一端,也就是你家里的PC。

本地端的配置是在你自己的电脑上(怕大家弄错了,多啰嗦一下),修改的是frpc.ini,对,结尾是c,不是s

官方的配置说明已经在图3展示了,你也可以直接进入官方文档进行查看。

我贴一下我的frpc.ini配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[common]
server_addr = 121.xxx.xx.175
server_port = 7000

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000


[web]
type = http
local_port = 80
custom_domains = www.luxxxxxxxxxxxxxong.com

我不仅仅是ssh,还配置了一个web。

隐去一些具体信息。

然后,启动你的本地PC上的服务:

1
sudo ./frpc -c ./frpc.ini

好了,你试试看。在其他电脑上用下面的命令试试ssh:

1
ssh -oPort=6000 username@x.x.x.x

x.x.x.x是你的公网服务器IP地址。

【无法访问的原因】

如果你的测试过程有问题,那一多半的可能是你的云服务器对外端口未开放。你配置里面涉及的端口,如6000/7000/8080,都需要在阿里云服务器上开通。

一般在“控制台”–>“轻量应用服务器/ECS云服务器”–>“防火墙/安全组规则”。

端口

图4:云服务器的出入站规则

结束

OK,我想你应该和我一样可以开心地跑起来了,速度还可以!

如果你有具体的问题,可以邮件咨询我:lxdhzzj@gmail.com

下面是我的ssh附图:

ssh6000


目前正在接受试用中!!!

请将您的称谓、公司名称和使用场景,发邮件到yuanwai@mengjia.net。

也可以直接加微信:lxdhdgss 咨询

更多详情,可查看文章:TorchV Bot开始对外试用了!


最新内容,关注“土猛的员外”公众号

关于LLM(大语言模型)的一些声音

这篇文章是最近听到的一些播客(如《此话当真》),以及之前读到的一些文章,当然还有自己在公司产品中的一些实践中产生的想法归纳。

这波LLM,巨头和创业者/小公司其实处在同一起跑线,但是小公司/创业者真的没必要去做LLM,还是应该聚焦在基于AI的应用上,需要去做错位竞争。

主要原因有二:

  • 这次LLM是在第一时间给市场看到了最好的产品——ChatGPT,其他竞争对手和OpenAI都还存在代差。一些国内外的Benchmark大家看看就得了,只要他们声称自己的新模型超过GPT-3.5,接近GPT-4.0,那在全领域来比较多半还差距很大,所以不要全信。
  • 后面大模型的竞争首先会成为卡的竞争,也就是钱。对于大部分企业来说,无法获得如此多的资金,而且去All in一个可能还是未知数的方向。大可在基于LLM的应用上多发力,比如没有什么垂直大模型,只有垂直应用。

数据还是壁垒吗?

那必须是!

但开放数据已经变得不值一提了,大家都可以获取,哪怕所谓的垂直LLM,如果你的训练数据是可以公开获取的,那壁垒也不高。比如司法LLM、医药LLM等行业。

什么样的数据才是壁垒?

那些不属于你所有,但与你共生的数据才是最重要的数据。比如你帮客户建立AI服务,中间产生的很多数据,你可以触碰和分析,但是不能做它途使用的数据。这部分数据以后应该是最多的,而且符合数据安全的相关条例。我们现在产品中的数据也属于这一类。

这部分数据,在企业应用中大多数是:1.内部协同数据;2.企业的客户使用数据。在个人层面,这部分数据更多是设备端数据。

LLM在未来的一种变形是做的事情更专注、更小型化,比如可以装载在设备上,做边缘计算,这些LLM可以帮助人们的生活更加简单。

RAG vs Fine-tuning

Fine-tuning(微调)是用一定量的数据集对LLM进行局部参数的调整,以期望LLM更加理解我们的业务逻辑,有更好的zero-shot能力。

RAG(检索增强生成)的做法是把企业内部的文档数据先进行embedding,借助检索先获得大致的知识范围答案,再结合prompt给到LLM,让LLM生成最终的答案。

说实话两种方式都不简单,但是Fine-tuning 的成本似乎更大一些。所以目前有一种趋势就是更倾向RAG方式,毕竟对于客户本身来说,操作空间会更大,他们可以通过管理文档来调整最终的检索和问答能力。所以目前有一些预测已经旗帜鲜明地认为fine-tuning的需求一定会下降。

传统程序员怎么办?

首先我觉得没有什么可以惊慌的,如果你原来的工作就很有价值,以后依然会很有价值。

AI算法工程师很重要,但是没有重要到离谱的程度,甚至现在很多招聘其实对AI算法工程师的热度是在下降的(Q3与Q2相比)。因为大厂拿到牌照了,加上Llama2、ChatGLM2等开源商用授权的发布,让很多公司稍稍从恐慌中心里有底了一些。

做过基于LLM产品的人现在大概都知道了,一个产品/平台,最终组成部分,80%是产品工程,20%是创新技术(国内的话,创新技术有10%其实已经很优秀)。所以,对于传统程序员和产品经理,一方面拥抱AI,另外一方面真正要支棱起一个AI应用,更大的工程量还是要靠你们。

对于AI应用的需求

在和B端客户交流中发现,65%的需求都是信息的检索、汇总和再生成,其实更像上面提到的RAG。

另外第二大需求(约占20%)是流程自动化、决策辅助,BI等需求上AI驱动的应用升级。

文生图和代码生成的需求在B端其实很低,和我们之前预期的差距很大。

很多大客户对于结果的可靠性要求非常高,很多项目都已经进入POC阶段了,因为达不到想要的可靠性(哪怕是再降低一些)而被否决。

甚至有些客户后面直接就想通了,我要的就是一个更好的搜索而已,但是LLM好像做不到。到最后,大家都冷静下来了,客户知道自己要的是一个解决方案,解决他业务中的痛点,而不是一个大模型。

客户一般都知道或者用过最好的(ChatGPT),所以他们的需求会天马行空,然后接触到国内基于LLM的产品之后,感觉落差巨大。

运营兜底

但是基于LLM的产品也不是就没救了,别这么悲观。现在碰到的问题是:我们把LLM神化了,感觉什么都可以通过LLM一劳永逸的解决了,但实际真不是这样的。

我们回想过往所有产品,精准度都是很高的,我们怎么做到的呢?运营啊!加人力成本啊!

到目前为止,要有非常好的精准度,依然必须要有运营兜底。基于生成式的LLM在幻想方面是个黑盒,不要说我们,OpenAI也没办法完全控制。

运营介入的方法简单说有三类:

1.prompt优化,当然不排斥针对某些行业和客户的“穷举”优化;

2.反馈迭代:获得使用中用户的反馈,进行微调,或者补充知识;

3.BERT前置:对于一些需要非常谨慎的服务内容,还是需要用预训练语料去完成,只要覆盖了需要这些高精度需求,其他的可以用GPT托底。

AI产品经理的核心素质

国内LLM的能力其实大家都差不多,所以对于基于LLM的业务最后拼的就是运营和反馈机制建立。

  • 运营:就是我上面一节说的这个意思,我们原来小知在行业里面占据领先地位也是这个做法;

  • 反馈:必须是建立一种可以持续获得反馈的机制。Midjourney生成四张图,每次让人选择一张(一般情况下会认为是更符合客户需求的),这种方式就是一种非常好的反馈机制。

所以,作为AI产品经理,最最重要的就是这两件事

  • 认清现实:知道我们完全靠机器是不太可能做好所有的事情的,然后如何用运营来弥补这种缺失,达到最好的交付效果;
  • 反馈飞轮:如何在交互上做出一个良好的反馈机制,让“模型-应用-反馈-优化”这个飞轮可以更加快速运转起来。

如果没有这两方面的考虑,都不能称之为一个合格的AI产品经理。

再说说运营能力,也可以作为一种标准服务提供给企业,或者运营也可以是一种AI浪潮下的企业员工培训,让企业员工如何适应AI产品来提高生产力。

避免过早优化

整体来说,中文LLM的能力还非常差,很多时候都体会不到真正LLM的“魔力”。

但是我对于中文LLM的发展还是非常乐观的,所以我们在做基于LLM产品的时候,可以考虑一年之后我们可以拿到一个类似GPT4差不多水平的LLM。

言外之意,即使在现在,业务优先,AI在后

应用与LLM的切割,做好架构,先做好自己的应用,做到随时切换各个不同的LLM。

或者,我们现在做业务,也可以不要一个猛子扎进去,可以有意与LLM有一个边界。

PLUS:现在做的三款产品

一、2019年就开始做的AI助手产品,在颐和园、长隆、良渚、普陀山等140多家景区有应用,原来是纯BERT的,现在加了GPT兜底;

二、基于RAG的产品,在行政服务中心、招商等部门都有一定的应用;

三、文博行业产品,在客户端,给原来纯用声音听的功能做了可视化升级,在后台用大模型做了内容的快速处理与合成,比传统内容制作效率提升很多。非直接生成,那质量非常不可控。

好了,就写到这里!


目前正在接受试用中!!!

请将您的称谓、公司名称和使用场景,发邮件到yuanwai@mengjia.net。

也可以直接加微信:lxdhdgss 咨询

更多详情,可查看文章:TorchV Bot开始对外试用了!


最新内容,关注“土猛的员外”公众号

Transformer架构的整体指南

介绍

Transformer模型于2017年发明,并首次在开创性论文“Attention is All You Need”(Vaswani等人,2017)中提出,它对深度学习做出了革命性的贡献,可以说是对整个计算机科学的贡献。作为一个神经机器翻译的工具,它已经被证明是深远的,扩展了它的适用性,超越了自然语言处理(NLP),巩固了它作为一个通用的、通用的神经网络架构的地位。

在这个全面的指南中,我们将剖析Transformer模型的核心,深入探索从其注意机制到编码器-解码器( encoder-decoder)结构的每个关键组件。我们不会停留在基础层面,我们将遍历利用transformer功能的大型语言模型,深入研究它们独特的设计属性和功能。进一步扩大视野,我们将探索transformer模型在NLP之外的应用,并探讨这一有影响力的架构当前的挑战和潜在的未来方向。此外,还将为那些有兴趣进一步探索的人提供一个精心策划的开源实现列表和补充资源。

transformer

图0:我们将在本文中深入探讨的Transformer体系结构。改编自(Vaswani et al. 2017)。

Transformers出现之前的神经网络

Transformer神经体系结构的设计者对寻找一种可以用于序列到序列建模的体系结构很感兴趣。这并不是说没有现有的序列建模体系结构,只是它们有很多缺点。还有哪些类型的神经网络可以用于序列建模?它们的缺点是什么?让我们在激励Transformers的过程中寻找这些问题的答案。

多层感知器(MLP)

让我们从多层感知器(MLP)开始,这是一种经典的神经网络方法。MLP本身并不是超级强大,但你会发现它们几乎集成在任何其他架构中(令人惊讶的是,甚至在transformer中)。MLP基本上是一个线性层序列或完全连接的层。

2mlps

图1:多层感知器(MLP)。

在AI社区找到各种模式的最佳架构之前,MLP长期以来一直用于建模不同类型的数据,但有一点是肯定的,它们不适合序列建模。由于它们的前馈设计,它们不能保持序列中信息的顺序。当数据的顺序丢失时,序列数据就失去了意义。因此,MLP不能保持信息的顺序使其不适合序列建模。此外,MLP需要许多参数,这是神经网络可能具有的另一个不希望的属性。

卷积神经网络

卷积神经网络(CNN 或ConvNets)是一类神经网络架构,以处理图像和其他模式(如文本和视频)而闻名。

3convnets

图2:用于文本理解的卷积神经网络(X。Zhang and LeCun 2015)。

迄今为止,卷积神经网络在小尺度和大尺度视觉识别方面取得了成功,但在序列建模方面并不十分成功。由于它们的局部性(计算被捆绑在输入数据的局部部分),它们很容易并行化(对GPU很好),它们需要许多层来处理长期依赖关系。与固定长度的图像相反,大多数顺序数据具有可变长度,这是ConvNets或MLP都无法处理的。

循环神经网络

与MLP或ConvNets不同,递归神经网络(RNN)的设计考虑了序列。RNN在其设计中具有反馈回路,这是其模拟序列数据能力的关键因素。RNN的另一个令人满意的特性是它们可以处理可变长度的数据。

RNN的连接方式存在一些基本问题。首先,由于它们的顺序设计,它们可能对长期序列不稳定。

img

图3:循环神经网络(RNN)。

循环网络有很多变体。其中一个著名的版本是长短期记忆(LSTM)。LSTM可以处理长期序列。它们有一个细胞状态(下图中的水平直线)和门,它们都平滑信息流。

img

图4:长短期记忆(LSTM)

LSTM的另一个稍微有效的版本是门循环单元(GRUs)。LSTM对于基本的序列建模问题非常有效,但它们的应用范围仍然有限。正如我们之前所说,它们不能被平行化,也就是说它们不能被缩放。此外,即使它们能够保持信息的顺序,它们也无法推断出它们正在处理的数据的全局上下文。背景很重要。以机器翻译为例(这个任务基本上给了我们transformer),被翻译的句子的上下文和顺序一样重要。

我们所做的基本上就是激励Transformers。到目前为止,我们已经看到,先前的神经网络要么不适合序列建模,要么不可并行化,要么不稳定,要么受上下文长度的限制,这些都是序列神经结构的主要特征。

现在我们有了正确的背景知识,让我们深入了解transformer架构。

Transformer架构

Transformer是一种神经网络架构,可以处理文本、音频、视频和图像等顺序数据(作为图像补丁的序列)。Transformer不使用任何循环层或卷积层。它的基础层叫做Attention(注意力)。它还包含其他基本层,如全连接层、规范化层[主要是LayerNorm](Ba, Kiros, and Hinton 2016)、Embedding层和位置编码层。在下一节中,我们将看到这些层的作用。

6transformer

图5:Transformer体系结构。改编自(Vaswani et al. 2017)。

正如我们在开头提到的,transformer最初是为机器翻译引入的,这是一项需要处理两个序列(输入和输出都是序列)的任务。因此,transformer模型有两个部分:处理输入的encoder和生成输出的解码器。关于encoder、解码器和其他层的更多信息将在下面讨论。

Encoder(编码器)

编码器是transformer结构的主要模块之一,位于输入序列的输入端。编码器将输入序列转换为压缩表示。在原始的transformer架构中,encoder重复了6次(这取决于架构的整体尺寸,可以更改)。每个encoder块有3个主要层,即多头注意(MHA),层规范和mlp(或根据论文的前馈)。

多头注意和mlp在transformer论文中被称为子层。子层之间有层归一化,层之间有dropout和残差连接(各层的正确流程见图)。

如前所述,encoder层数为6层。encoder层的数量越多,模型就越大,模型就越有可能捕获输入序列的全局上下文,从而产生更好的任务泛化。

Decoder(解码器)

解码器几乎与encoder相同,除了在encoder的输出上操作额外的多头注意。解码器的目标是将encoder输出与目标序列融合,并进行预测(或预测下一个token)。

在解码器中占用目标序列的注意力被屏蔽,以防止当前(正在处理的)token关注目标序列中的后续tokens。如果解码器可以访问完整的目标序列,这基本上是作弊,并且可能导致模型不能泛化到训练数据之外。

解码器通常也与encoder重复相同的次数。在原transformer中,解码器块的数量也是6块。

Attention(注意力)

注意力到底是什么?

注意力是transformer结构的基本要素。从本质上讲,注意是一种机制,它可以让神经网络更多地关注输入数据中包含有意义信息的部分,而较少关注输入的其余部分。

早在transformer架构引入之前,注意力机制就被用于各种任务中。注意力的概念最早出现在神经机器翻译(NMT)方法中,该方法使用注意力来寻找输入句子中最相关信息集中的[位置集](Bahdanau, Cho, and Bengio 2014)。因为他们基于注意力的NMT可以联合或同时对齐和翻译,所以它比以前的方法表现得更好。如下图所示,该网络能够在翻译的句子中找到正确的单词顺序,这是之前的神经机器翻译方法难以实现的壮举。

7attention

图6:神经机器学习翻译中的源句和目标句对齐(Bahdanau, Cho, and Bengio 2014)。x轴和y轴分别表示源句和翻译句。每个像素表示源(输入)token与其对应的目标token的关注权重。对角线上的注意表示单词按相应的顺序排列(例如:对->L ‘ accord sur la)。注意可以找出正确的词序(例如:European Economic Area ->区域(欧洲)。

上面的图片是怎么回事?你能发现什么吗?在翻译的句子中,只要在目的语中有意义,单词的顺序就会被颠倒。因此,在翻译一个句子时,注意不仅可以赋予模型正确翻译句子的能力,而且还可以根据目标语言的上下文按照正确的顺序进行翻译。简而言之,在将一种语言翻译成另一种语言时,注意力可以识别和保存语境。

另一个使用注意力的早期工作是在神经图像字幕中发现的(Xu et al. 2015)。在这项工作中,作者使用卷积神经网络进行特征提取,并使用带有注意力机制的rnn来生成与输入图像最一致的标题。下图(取自论文)显示了模型大致关注的地方。

8attention-cap

图7:用神经字幕模型生成字幕。白色区域显示了模型在生成标题“一个女人在公园里扔飞盘”时聚焦的位置。图片来自Xu et al. 2015)。

在全局层面上,在图像字幕模型中集成注意机制有助于模型在生成字幕时关注输入图像中有意义的部分。

9attention-cap2

图8:模型可以在生成标题时关注关键对象。图片取自Xu et al. 2015)。

我们上面使用的两个例子都证明了注意力的有效性。注意力确实是一种神奇的机制,它允许神经网络专注于包含有意义信息的部分输入数据,而较少关注其余输入数据。

现在我们了解了注意力,让我们看看transformer体系结构中注意力函数的输入:查询、键和值。

注意力功能:Query, Key, Value(查询、键、值)

直观地说,注意力实际上是“关注输入数据中最重要的部分”。从技术上讲,注意力测量两个向量之间的“相似度”,并返回“加权相似度分数”。一个标准的注意力函数有三个主要输入:查询、键和值向量。在分解注意力函数之前,让我们试着理解键、值和查询的含义。

查询、键和值是搜索引擎和数据库系统中常用的术语。为了理解这些术语,让我们举一个简单的例子:1假设你正在搜索ArXiv上基于注意力的论文。理想情况下,您将在搜索框中输入查询。在内部,ArXiv可以通过一组预定义的键来组织论文。在ArXiv给出你所要求的论文之前,它会将你的查询与那些预定义的密钥集进行比较,并返回与查询和密钥对应最匹配的论文。Values仅指数据库中的所有论文。作为免责声明,我们使用这个示例来理解查询、键和值在搜索和数据库系统上下文中的含义。这并不是试图展示ArXiv系统是如何工作的。

img

图9:ArXiv论文搜索系统中的查询、键和值示例。

对查询、键和值有了这样直观的理解之后,让我们转向注意力函数的数学表示。

11

由上式可知,Q、K、V分别为查询矩阵、键矩阵、值矩阵。我们计算查询和键的点积,并将乘积除以一个比例因子dk的平方根。比例因子用于避免QK^T^的大值会导致小梯度的情况。然后,我们用softmax将点积归一化为概率分布(这基本上给了我们加权和),并通过将其与值相乘,我们得到加权值。

img

图10:点积注意力的图形表示。图改编自(Vaswani, 2017)

上面描述的注意力被称为缩放点积注意力,一种改进的点积注意力(Luong, Pham, and Manning 2015)。还有其他类型的注意力,如添加性注意力(Bahdanau, Cho, and Bengio 2014),基于内容的注意力(Graves, Wayne, and Danihelka 2014),基于位置的注意力(Bahdanau, Cho, and Bengio 2014)和一般注意力(Luong, Pham,and Manning 2015)。每一种注意力类型都可以应用于全局(整个输入数据),因此是全局注意力,也可以应用于局部(输入数据的子部分),因此是局部注意力。

你可能听说过transformer是平行的,你可能想知道它是从哪里来的。变压器并联源于注意函数。如果查询、键和值都是矩阵,则可以在两个主要的矩阵乘法中执行注意力,因此不涉及循环或任何循环操作。gpu的计算注意力更快。对于更大的模型(数以十亿计的参数)和大量的训练数据(数以十亿/万亿计的tokens),注意力可能是昂贵的,因为每个token都要参加其他tokens,这需要二次时间复杂度

注意

如果查询、键和值来自同一来源,则应用于它们的关注称为自关注。如果它们来自不同的来源,我们说***交叉注意。

多头注意力

我们在上面描述的是一个单一的注意层。在实践中,只有一个注意层通常不会得到好的结果。相反,人们倾向于并行计算多个注意层,并将结果串联起来。简而言之,这就是多头注意力。多头注意力基本上是在线性投影的QKV向量上计算的多个独立注意力。在下面的多头注意图中,将连接的注意值线性投影到模型维度。

img

图11:多头注意力。图改编自(Vaswani, 2017)

正如transformer架构的设计者所解释的那样,并行计算多个关注点允许模型“共同关注来自不同位置的不同表示子空间的信息”。*(Vaswani et al. 2017)。关于多头注意力的一个令人惊讶的事情是,它不会增加总体计算成本,因为每个头像的维度是头像数量的十分之一(i。E、底座transformer的磁头是整体模型尺寸的8倍(即512倍)。因此,如果模型(文中dmodel)的维数为512,则多头注意中的头像数为8,则每个头像为512/8=64。

在ConvNets中,多头注意力可以被视为深度可分离卷积(Chollet 2017)。深度可分离卷积是一种特殊类型的卷积,它将输入张量分成多个通道,在每个通道上独立操作,连接各个输出,并将结果提供给点卷积(1x1卷积相当于线性投影)。

MLPs

MLPs或多层感知器2是encoder和解码器中的两个子层之一。Transformer中的MLPs由两个线性层组成,中间有ReLU激活,它们独立且相同地应用于每个位置。

img

图12:transformer中的多层感知器(MLP)。

Embeddings和位置编码层

transformer架构包含两个Embedding层:一个在encoder处用于处理输入或源序列,另一个在解码器处用于处理目标或输出序列。这些Embedding层将输入或输出tokens转换为固定大小的密集向量,本质上是将序列中的每个token映射到特定的密集向量。利用Embeddings是语言建模的标准实践,因为它们提供了语义深度。有了这些嵌入的token向量,那些具有相似语义的向量倾向于在同一方向上对齐3

基本transformer中的Embeddings尺寸为512(这是整个模型的尺寸)。作为旁注,transformer架构在整个网络中保持相同的尺寸,基本模型为512。这就是之前所说的dmodel模型。

位置编码在Transformer模型中的encoder和解码器的初始阶段都是不可或缺的组件。它们用于保持序列中tokens的顺序。有人可能会质疑这些位置Embeddings的必要性。这源于注意力机制固有的排列不变性,因此修改tokens的顺序不会改变输出加权值4。因此,注意机制本身缺乏对token顺序的意识。由于transformer架构不包含任何其他递归方法,因此引入位置编码以使模型具有序列中tokens的位置感知。实质上,如果没有位置编码,Transformer确实会表现出排列不变性。然而,这样的设计对于序列顺序具有重要意义的任务来说是不够的,就像大多数NLP任务一样。

为了在序列中编码位置信息,transformer的设计者使用了不同频率的正弦函数。他们还尝试了习得的位置Embeddings,但结果并没有什么不同。

残留连接,层规范化,和Dropout

残差连接是神经网络设计的核心,也是现代深度学习中流行的成分之一。自从深度残差网络在计算机视觉中证明了可观的性能(He et al. 2016)以来,残差连接已被用于几乎大多数神经网络,不仅用于视觉,还用于其他模式。事实上,现在几乎不可能看到一个不使用剩余连接的神经网络模型。残差连接缓解了梯度不稳定问题,有助于模型更快收敛。

transformer的作者之一Ashish Vaswani曾经说过,“在其他信息中,剩余连接将位置信息传递到更高层。”看看下面的图片!

img

图13:剩余连接将信号传递到更高层,从而改善了transformer模型的训练。第一幅图像的平滑对角线(带有残差)显示了残差连接的有效性。图片由Ashish Vaswani在CS224N拍摄。

层归一化(Ba, Kiros, and Hinton 2016)也是现代神经网络中最常用的归一化技术之一。层归一化通过用层均值和方差对层的激活进行归一化,显著减少了训练时间。与批归一化(Ioffe and Szegedy 2015)不同,批归一化是用在小批上计算的均值和方差对每一层进行归一化,而层归一化只是用每个激活的均值和方差对每一层进行归一化。层规范化在训练和测试阶段保持相似的行为,不像批规范化在这两个阶段表现出不同的行为。

有两种方法可以在transformer体系结构中实现层规范化。第一种方法称为后层规范化(Post- ln),其中层规范化放置在残馀块之间(或在每个子层之后(多头注意和mlp),但在加法之后)。第二种选择称为预层规范化(Pre- ln),其中层规范化放置在剩余块内的每个子层之前。标准transformer架构使用Post-LN,但在训练原始transformer的更新代码库5中,发现它是Pre-LN。纸张和代码之间的不匹配使得很难追溯到初始transformer中层规范化的实际位置,但从提交历史来看,似乎后来使用了Pre-LN。作者本可以更新这篇论文,但他们可能并不介意,因为没有人知道这篇论文会成为神经网络设计领域有影响力的参考论文之一。

img

图14:层后归一化(Post- ln)和层前归一化(Pre- ln)

因此,层归一化应该在哪里并不明确,这是一个积极的研究问题。最近一项关于Pre-LN和Post-LN影响的研究(Xiong et al. 2020)表明,在多头注意力和mlp之前进行层归一化(Pre-LN)可以提高训练效果,并且比在多头注意力和mlp之后进行层归一化收敛得快得多。该研究还声称,使用Pre-LN,你不需要聪明地选择学习率调度器,因为Pre-LN有更好的初始化。前ln和后ln都不是完美的。最近的另一项研究引入了ResDual(Xie et al. 2023),通过引入层归一化的附加残差连接,基本上缓解了ln前和ln后的问题。

应该在哪里放置图层规范化仍然是一个问题,但这应该不是一个问题。正如许多人注意到的那样,transformer似乎是一种通用架构。在语言建模、视觉识别和多模态学习方面,原始的香草transformer(有一些调整,如yes LN)仍然是大多数新颖作品的背后,并且有数百万的作品声称可以改进transformer。因此,我们的目标应该是保持这种架构的普遍性。我们将在文章末尾的高效Transformers中看到更多这方面的内容。

在我们结束本节之前,让我们讨论一下transformer架构中的dropout(Srivastava et al. 2014)。层规范化可以作为一种副作用的正则化器,但您仍然需要其他形式的网络正则化来处理过拟合。Dropout应用于每个子层的输出(在加法和归一化之前)。它还适用于encoder和解码器堆栈中的Embeddings和位置编码之和。有关训练transformer中使用的其他正则化技术和其他训练细节,请查看论文以获取更多信息。

线性和Softmax图层

解码器后的线性层获取解码激活并将其投影到词汇表的大小。这个线性层基本上会产生对数。softmax层将获取这些逻辑并将它们转换为下一个令牌概率。下一个预测的token基本上是softmax输出的argmax。

可视化的关注

注意力可以从输入序列中捕获整体上下文,这通常会提高模型的性能。通过将注意力可视化,我们可以看到输入序列的哪些部分对模型的输出有显著影响。这有助于我们更好地理解Transformer神经网络的内部工作原理。

img

图15:使用ExBert可视化注意力。

上图描绘了GPT-2第8^th^层的注意力头(Radford et al. 2019)。从图中可以清楚地看出,即使在transformer的早期层中,大多数tokens也是相互关联的。

随着时间的推移,许多可视化注意力的工具已经发展起来,以帮助深度学习社区理解transformer模型内部的情况。其中最著名的工具是BertViz(Vig 2019) 6。我们用来进行上述可视化的ExBert也是一个优秀而简单的工具,用于可视化大多数基于transformer的模型(如GPT-2和BERT)的注意力(Devlin et al. 2019)。

注意力的利弊

注意机制导致了序列建模和其他可以作为序列框架的模式的重大转变。与其他序列网络(如循环网络和1D卷积)相比,注意力网络具有许多优势。下面简要讨论这些问题:

  • 长期依赖:传统的循环神经网络(rnn),包括长短期记忆(LSTM)和门控循环单元(GRU)等变体,容易出现长期依赖的问题,即模型保留信息的能力随着时间的推移而减弱。注意机制允许模型直接访问输入序列中的任何点,从而保留整个上下文,从而帮助缓解了这个问题。
  • 并行化:与需要顺序计算的rnn不同,基于注意力的模型,如transformer架构,可以并行处理输入序列中的所有tokens。这使得它们的计算效率更高,并且可以更好地与当前的硬件加速器配合使用。
  • 可解释性:注意提供一定程度的可解释性,因为它突出了模型认为对产生特定输出最重要的输入部分。“注意图”可以帮助我们理解模型在“思考”什么。
  • 全局上下文:在卷积神经网络(cnn)中,接受野通常是局部的,取决于核大小,可能导致更广泛的上下文丢失。然而,需要注意的是,每个输出token都可以考虑输入序列中每个token的信息,从而保留全局上下文。
  • 提高性能:基于注意力的模型,特别是那些利用transformer架构的模型,在许多NLP任务中取得了最先进的性能,优于RNN和CNN同行。他们还推动了计算机视觉、语音识别、机器人、多模式学习等其他模式的发展……

在下面的图中,我们总结了基于注意力的模型与其他深度神经网络架构的特性。

img

图16:注意力与其他循环网络架构的对比。变压器几乎具有神经网络的所有优良特性。卷积神经网络类似于transformer,但需要很多层才能实现远程依赖。

尽管它们提供了许多优势,但就像生活中的其他事情一样,注意力机制也面临着相当大的挑战。例如,在几种类型的注意力中,内存消耗和计算成本都可以随序列长度呈二次增长。已经提出了各种策略,例如稀疏注意力或局部注意力,以缓解这些问题,但其中大多数在实践中很少使用(Tay等人,2020)。

虽然Transformers在训练过程中提供了并行化的优势,但推理过程的本质可能仍然需要顺序方法,这取决于特定的任务。由于它们的自回归性质,Transformers每次产生一个token输出,继续这个迭代过程,直到完全产生所需的输出序列。

此外,虽然注意力提供了一定程度的可解释性,但它远非完美。尽管它提供了对模型功能的一些见解,但完全基于注意力图来完全破译复杂的模型,至少可以说,是一项艰巨的任务,如果不是几乎不可能的话。

大型语言转换模型

大语言模型的演变

大型语言模型(大语言模型)已经彻底改变了人类与机器学习系统的互动。自然语言接口,如ChatGPTBard,由健壮的大语言模型提供支持。这些模型为实时执行自然语言下游任务或通过zero-shot学习铺平了道路。在过去,这样的任务需要收集下游或特定任务的数据集。

在这些大语言模型的核心,它基本上是一个transformer模型,我们看到这里和那里有一点调整。在本节中,我们将深入研究大型语言模型的压缩演化。此外,我们将探索垂直大语言模型的发展,专门为特定应用设计和微调。

变压器基本模型有65M个参数,但从那以后,语言模型变得越来越大(以数十亿计),因此被称为大型语言模型。下面是流行的大型语言模型的快速概述。

img

图17:流行的大语言模型概述。对于编码器-解码器模型,层是堆叠的编码器/解码器或两者的数量,宽度是模型的维度,头是多头注意中注意层的数量,参数是参数的数量。注意,GPT-2测试中出现正面的次数并不确切。

大多数大型语言模型(大语言模型)的训练过程遵循大致相似的模式。在最初的预训练阶段,大语言模型会接触到大量经过整理的文本数据,这些数据来自书籍、文章、代码片段和网站等各种各样的材料。这个庞大的数据集对于模型获得对世界的全面理解至关重要,使它们能够创建丰富的表示并生成与上下文相关的响应。公众对大语言模型在各个领域的表现抱有很高的期望。为了满足这些期望,预训练数据必须包含广泛的主题和学科([J]。Yang et al. 2023

大语言模型的实际训练以无监督的方式进行,特别关注自我监督学习(SSL)。这种方法消除了对标记数据的需求,考虑到几乎不可能对整个在线内容进行标记,这是一个至关重要的特性。

img

图18:大型语言模型的典型训练工作流。大语言模型通常在大型未标记数据集上进行训练。之后,它们可以通过prompt工程直接使用,也可以在专门任务中进一步微调。

然而,基于未标记数据的训练模型需要巧妙地实现训练目标,因为没有可参考的基础真理。因此,大多数大语言模型使用下一个令牌预测(NTP)作为常见的训练目标。本质上,大语言模型被教导准确地预测序列中的下一个token,逐渐增强他们的理解和生成能力。另一个常用的训练目标是掩码语言建模(MLM)。蒙面语言模型被训练来预测序列中的蒙面token。BERT推广了这一目标(Devlin et al. 2019)。

在预训练阶段之后,模型可以通过zero-shot学习或少射击学习等技术来生成文本。在zero-shot学习中,提示模型执行任务(或回答给定的问题),而不需要演示如何完成任务。在几次学习中,在要求模型执行任务之前,会给模型一些如何完成任务的演示。zero-shot学习和Few-shot学习是情境学习是指大语言模型使用语义先验知识生成连贯文本的能力(Jerry Wei等人,2023),而不需要任何参数更新(akyrek等人,2023)。提示大型语言模型(也称为prompt工程)本身是一个相对较新的领域,还有其他prompt工程技术,如思维链(CoT)(Jason Wei, Nye, and Liang 2022)。

情境学习倾向于擅长那些被认为简单的任务,但不擅长那些无法在prompts中轻易描述的任务。复杂的任务需要的不仅仅是巧妙的prompts。用Karpathy的话来说,“达到顶级性能(在复杂任务上)将包括微调,特别是在具有明确定义的具体任务的应用程序中,可以收集大量数据并在其上“实践”。7。因此,为了让大语言模型在数学、医学、科学领域(如化学)等专业任务上获得良好的表现,人们通常会在下游数据集上对大语言模型进行微调。我们将在垂直大语言模型一节中看到这方面的例子。

既然我们已经简要介绍了大型语言模型(Large Language Models, llm),现在是时候研究一些最流行的大语言模型了,特别关注它们的设计选择:它们是作为编码器、解码器,还是采用编码器-解码器的组合架构。

Encoder, Decoder, Encoder-decoder大语言模型

标准的transformer模型有编码器-解码器,这与它要执行的任务有关,这是机器翻译,你必须处理输入句子和目标翻译。自transformer以来,AI研究界针对不同的任务提出了不同的架构变体。根据不同的任务,一些transformer模型保持编码器-解码器结构,一些只使用解码器或只使用encoder。让我们从后者开始。

仅仅Encoder的LLMs

只有编码器的大语言模型使用标准transformer模型的encoder部分。只有编码器的大语言模型通常用于NLP判别任务,如文本分类和情感分析。

BERT(Devlin et al. 2019)是最流行的纯编码语言模型之一。BERT是最早的工作之一,它表明您可以在大型未标记文本数据集上预训练transformer(encoder),并通过附加的任务特定头部在各种下游任务上微调相同的架构。BERT的预训练目标是掩模语言建模(MLM)和下一句预测(NSP)8。通过屏蔽语言建模,我们屏蔽了给定百分比(论文中提到的15%)的输入tokens,目标是预测被屏蔽的tokens。在下一个句子预测中,对于组成输入序列的两个句子对,目标是随机预测两个句子的顺序是否正确。

img

图19:BERT中的掩码语言建模(MLM)。在图中所示的句子示例中,训练BERT的目标是预测被屏蔽词“network”。在下一个句子预测目标中,工作流程大致相同,但我们不是预测被屏蔽的tokens,而是预测由SEPtoken分隔的两个句子对是否顺序正确。

BERT是一项真正革命性的技术,它在无所不在的NLP下游任务上改进了SOTA。它也启发了其他用于NLP预训练的高效双向架构,如RoBERTa(Y。Liu et al. 2019](https://deeprevision.github.io/posts/001-transformer/#ref-liu2019roberta))代表鲁棒优化的BERT方法。RoBERTa介绍的主要设计选择之一是不使用下一个句子预测目标。

仅仅Decoder的LLMs

纯解码器大语言模型基于标准transformer的解码器部分。在transformer架构中,解码器与encoder非常相似,只是解码器中的自关注被屏蔽,以防止模型在生成当前token时查看后续tokens。

解码器大语言模型使用下一个token预测目标进行训练9。因此,它们一次只能生成一个token或自回归。总的来说,解码器模型用于生成任务。

最流行的解码器模型是GPT(生成预训练变压器)模型家族,最著名的是GPT-3(Brown等人。2020)和GPT-4(OpenAI 2023)。GPT-3和GPT-4是早期GPT模型的直接放大(Radford et al. 2018)。与任何其他大型语言模型一样,GPT模型是在大量未标记数据(数十亿到数万亿个tokens)上进行训练的。由于大规模的预训练和合适的训练目标,GPT模型开发了令人印象深刻的上下文学习能力,它们可以执行一系列NLP下游任务,而无需梯度更新或特定于任务的微调(Brown等人。2020)。事实上,GPT模型只需在zero-shot或Few-shot设置中提示模型,就可以执行文本分类、摘要、问题回答等任务10。这种卓越的情境学习能力通常被称为大型语言模型的“涌现能力”(Jason Wei等人,2022)。

GPT模型并不是唯一基于解码器的模型。事实上,大多数著名的大语言模型都是解码器。例如PaLM(Chowdhery等人。2022)、BLOOM(Le Scao等人。2022)、Chinchilla(Hoffmann等人。2022)、Llama(Touvron等人。2023)等等。

Encoder-Decoder LLMs

编码器-解码器大语言模型看起来像标准transformer。它们通常用于需要处理两个序列的任务中。(输入和目标都是序列)如机器翻译。与我们所见过的其他模型风格相比,编码器-解码器风格并没有被广泛使用。这类最著名的模型是T5(rafael et al. 2019)、BART(Lewis et al. 2019)、UL2(Tay et al. 2022)、FlanT5(Chung et al. 2022)、mT5(Xue et . 2021)等…

编码器-解码器风格也用于多模态学习,最著名的是视觉语言预训练(VLP)。工作原理类似SimVLM([Z]。Wang等。2021](https://deeprevision.github.io/posts/001-transformer/#ref-wang2021simvlm))和pal -X([X。Chen等人2023)使用encoder来学习图像和文本的联合表示,使用解码器来生成输出。

Vertical(垂直) LLMs

我们上面概述的大多数大语言模型通常被称为基础或前沿大语言模型。基础模型通常在具有自我监督的大量数据上进行训练,并且可以对其进行微调,以适应广泛的下游任务(Bommasani et al. 2022)。

垂直大语言模型是一类适用于特定应用的大语言模型。基础大语言模型可以推广到情感分析等简单任务,但它们在复杂任务或需要领域专业知识的任务上表现不佳。例如,基础LLM不太可能在医学问答任务中表现良好,因为它没有医学专业知识。更多的例子:基础LLM不太可能在法律问题回答任务中表现良好,因为它没有法律专业知识。在金融、物理、化学等其他领域也是如此……垂直大语言模型就是为了解决这个问题而设计的。他们在一个特定的领域受过训练,他们可以很好地完成需要该领域专业知识的任务。基础模型的目标是成为通才,但大多数时候,我们关心的是能把一件事做得很好的模型。

最近的垂直大语言模型的例子包括MedPaLM(Singhal et al. 2022)和Med-PaLM 2, ClinicalGPT(G。Wang等。2023), FinGPT([H.]Yang, Liu, and Wang 2023), bloomberg pt (Wu et al. 2023), Galactica(Taylor et al. 2022), Minerva(Lewkowycz et al. 2022)等。

img

图20:大语言模型拓扑。改编自[J]Yang et al. 2023

超越NLP的Transformers:视觉和其他模式

Transformer被引入到自然语言处理(NLP)领域,更准确地说,是用于神经机器翻译。在大多数NLP任务中,Transformers的表现很快就超过了先前的神经网络,并迅速扩展到其他模式。在本节中,我们将简要讨论Transformers在视觉识别和其他模式中的出现。

视觉识别是最早受到Transformers显著影响的模式之一。在很长一段时间里,卷积神经网络是视觉识别领域的最新技术。因此,问为什么研究人员关心卷积神经网络的替代品是一个关键问题。卷积神经网络的主要缺点是其空间归纳偏差11

transformer在图像处理中的最早应用之一是image transformer (Parmar et al. 2018),它将图像生成作为一个自回归问题,类似于文本生成。Image Transformer是一个应用于一系列像素的标准transformer,经过训练可以自回归地生成这些像素,直到创建完整的图像。这是一个很棒的想法,但事实证明,图像通常具有很大的分辨率,因此,对256x256的图像应用自关注是不可行的。有几部作品试图将transformer应用于图像域,但第一批成功的作品之一是视觉变压器(Dosovitskiy等人,2021),它将transformerencoder应用于一系列图像补丁。利用图像拼接思想克服了自关注的计算复杂性,标志着变换向计算机视觉领域的扩展迈出了重要的一步。

正如我们之前看到的,NLP中Transformers成功的巨大贡献是对大量未标记数据的无监督预训练。Vision transformer的成功也归功于数以百万计的训练图像,JFT-300M(C。Sun et al. 2017),尽管后来的MAE(He et al. 2021)和(Steiner et al. 2021)在经典的计算机视觉基准(如ImageNet)上取得了相当不错的性能。MAE是一种编码器-解码器自监督模型,它遵循BERT预训练的目标,预测随机掩码补丁,而BERT则探索巧妙的增强和正则化来训练ViT。ViT已被用作许多有影响力的论文的主干,如CLIP(Radford et al. 2021), DALLE•2(Ramesh et al. 2022),Stable Diffusion(Rombach et al. 2022),以及其他最近在视觉语言模型方面的研究。除了ViT支持视觉和语言的联合建模之外,它还被卷积神经网络增强,以在计算机视觉下游任务中获得这两个世界。ConvNets和Vision Transformer拓扑的著名作品有DETR(Carion et al. 2020)、PatchConvNet(Touvron et al. 2021)、MobileViT(Mehta and Rastegari 2022)等。

当涉及到人机交互时,视觉和语言是最重要的两种形式,所以大多数结合Transformers的作品都是在语言、视觉或视觉语言学习中进行的,这并不奇怪。也就是说,Transformers已用于其他模式,如强化学习(L。Chen et al. 2021](https://deeprevision.github.io/posts/001-transformer/#ref-chen2021decision))、机器人技术(Brohan et al. 2022)、机器猫(Bousmalis et al. 2023)和语音识别(Radford et al. 2022)。最后,像Gato(Reed et al. 2022)和ImageBind(Girdhar et al. 2023)这样的作品在几乎所有模式的建模方面都走得更远。

Transformer已经确立了自己作为通用架构的地位,最近跨不同模式的工作证明了这一点,但仍然存在挑战。

Transformer:当前的挑战和未来的方向

高效Transformers

Transformer在语言、视觉、机器人和强化学习等各种模式上都表现出了显著的性能。Transformer神经网络体系结构具有一系列特征,使其成为适合这些领域的体系结构:它具有表现力,与当前的优化技术配合得很好,并且可以并行化。从这些特点来看,我们可以说transformer是一种高效的架构。然而,由于transformer自注意的二次时间和内存复杂度,其效率带来了巨大的计算成本。transformer的计算需求限制了其可扩展性及其在智能手机和微控制器等低预算设备中的应用。

在开发和部署机器学习系统时,模型效率是一个重要的考虑因素,因为模型在推理过程中的表现会影响用户体验(Dehghani et al. 2022)。已经有无数的transformer模型声称可以提高transformer架构的效率(内存占用和计算成本)(这些模型通常被称为“xformers”),但这些模型通常倾向于针对一个特定的基准或设备。大多数声称可以降低自关注的二次时间和内存复杂度的新型*** **模型都比普通transformer慢得多,在实践中很少使用,也不具备原始transformer的通用性(Tay et al. 2020)。

正如(Tay et al. 2020)在“高效Transformers”的调查中很好地指出的那样,理想的变形金刚应该减少自我关注的二次时间复杂度,但应该保持普遍性,并在所有任务和模式中表现良好。它也不应该为了内存而牺牲速度,不应该是硬设计的,应该保持优雅和简单。*更多信息,我建议您阅读[高效Transformers]的调查报告(https://arxiv.org/abs/2009.06732)。

img 图21:高效Transformers的分类。图片来自Tay et al. 2020)。

几乎所有改进的transformer模型都计算了注意力的近似值,以降低成本。与这些方法相反,实际上有一种注意力可以精确地计算出标准注意力值,但速度更快。这种方法就是FlashAttention(Dao et al. 2022),我们将在高层次上讨论它。

FlashAttention是快速和内存效率的算法,计算准确的注意力。FlashAttention比标准attention快2-4倍。它通过使用两种主要技术实现了计算效率的巨大提高:平铺和重新计算。平铺发生在向前传递中,涉及将注意力(K键和V值)的大矩阵分成块。FlashAttention不是在整个矩阵上计算注意力,而是在块上计算注意力,并将结果块连接起来,从而节省了大量内存。重新计算发生在向后传递,它基本上意味着重新计算注意力矩阵,而不是向前存储它。FlashAttention的想法归结为提高内存,而不是减少计算,因为现代gpu具有高理论FLOPs(Floaping Point Operations,意味着你想要最大化),但有限的内存12(means在内存中的任何节省都可以提高训练速度)。HBM(高带宽内存)通常很大,但它并不比片上SRAM(静态随机存取内存)快,因此,对块(K和V)的计算发生在SRAM中(因为它更快),但所有完整矩阵都存储在HBM中(因为它很大)。这种高层次的解释可能过于简单化,因为FlashAttention是在GPU层面实现的(使用CUDA软件),这实际上是IO感知的原因,但希望这能解释这个快速算法中发生的事情。

下图显示了GPU, FlashAttention算法的内存层次结构,以及GPT-2注意与FlashAttention的每个中间步骤所花费的时间(毫秒)。理想情况下,我们希望大量的计算由矩阵乘法(matmul)操作来完成,但令人惊讶的是,dropout、softmax和mask(i)。(例如,GPT-2是解码器模型)最终会占用GPT-2的整个运行时间,因为它们是在完整矩阵上计算的。Matmuls比那些其他操作花费更少的运行时间,因为gpu的设计正是为了快速处理矩阵乘法(它们具有非常高的理论FLOPs,最大化FLOPs的使用并不会减少运行时间)。通过使用平铺和重新计算技术,FlashAttention的计算时间明显低于标准注意,如下图所示。

img

图22:GPT-2注意与FlashAttention的内存层次、FlashAttention算法和运行时。

FlashAttention集成在PyTorch 2.0,Hugging FaceTransformers,微软的DeepSpeed, MosaicML作曲家库和许多其他库中。您可以在论文中了解更多FlashAttention,或观看核心作者的此视频发布博客。在撰写本节时,FlashAttention2(Dao 2023)也发布了,它甚至比FlashAttention版本1要快几个数量级。FlashAttention2通过并行化序列长度维度而不是批大小和注意头的数量来提高并行性,并拆分Q(查询)矩阵而不是K和v。这篇博文(https://crfm.stanford.edu/2023/07/17/flash2.html)很好地解释了FlashAttention2给张量表带来了什么。

具有有效长上下文的Transformers

处理长上下文长度是Transformer大型模型研究的主要活跃领域之一。由于注意力的二次时间和记忆复杂性的直接后果,transformer不能处理长上下文窗口。研究扩展transformer架构上下文窗口的技术是一件很重要的事情,因为上下文窗口决定了在推理期间transformer内存中可以容纳的信息量。像长对话、总结长文档和执行长期计划这样的任务可能需要支持长上下文窗口的模型。Chen et al. 2023

已经有很多关于上下文窗口和扩展它们的文章,例如S.Sun etal.2021,但我想强调最近的一篇论文,该论文围绕长上下文提出了显著的发现。最近的语言模型(基于transformer)可以接受较长的上下文,但不清楚长上下文是否真的有帮助。如图[N]所示。F. Liu et al. 2023,语言模型的性能随着输入上下文长度的增加而下降。因此,即使对于具有扩展上下文长度的模型,它们的性能对于更长的输入上下文仍然会下降。此外,该工作还发现,当相关信息被放置在输入上下文的开头或结尾时,语言模型表现良好,而当相关信息被放置在中间时,语言模型显著下降,这表明语言模型是u形推理器。

上面强调的研究结果很有吸引力,并提供了广泛的含义,可以适用于微调数据集的设计和上下文学习,但重要的是要注意,如果“transformer模型如何在长上下文窗口上执行”是一个活跃的研究领域,那么这些都不是既定的理解。我们希望未来的transformer模型能够在长输入序列上运行,同时无论放置的相关信息如何,都能表现良好。这实际上是大型语言模型的圣杯。

img 图23:当相关信息位于输入上下文的开头或结尾时,语言模型(基于transformer)往往表现良好(左图),而对于较长的上下文(右图),它们的性能会下降。图表取自[N]。刘峰等。2023

Multimodal Transformer

神经网络设计的一个主要目标是构建一个单一的通用模型,该模型可以有效地处理多个模态,而无需特定于模态的编码器或预处理。实际上,transformer模型已经被广泛应用于各种领域,包括文本、图像、机器人和语音。然而,创造一种真正通用的transformer的目标仍然是一个挑战,这种变压器在所有模式下都能同样有效地工作,而不需要进行特定的调整。这一挑战来自数据类型和transformer模型本身的固有差异和复杂性,它们经常需要特定于模式的修改。

例如,处理文本、图像和语音的过程由于其各自的特征而具有独特的考虑。Transformers在数据可以被框架为一系列tokens的场景中表现出色,然而,将特定模态转置到这样一个序列的方法在不同的模态之间显着不同。因此,挑战在于设计一种能够以相当的效率统一地从所有数据类型中提取有价值的见解的单一体系结构。

这种架构的实现将标志着多模态学习领域的巨大进步,为可以在不同类型的数据之间无缝转换的模型铺平了道路,并有可能开启多模态表示学习的新探索途径。

目前几乎所有的多模态学习技术都是为每个模态使用单独的标记器和encoder,其中大多数也是为视觉语言学习而设计的。本节不会深入讨论当前基于Transformers的多模式方法的细节,但我们为有兴趣深入研究的人提供了示例:Flamingo(视觉语言)(Alayrac等人,2022), Gato(Reed等人,2022), ImageBind(Girdhar等人,2023), OFA(P。Wang et al. 2022), Unified-IO(Lu et al. 2022), Meta-Transformer([Y。Zhang et al. 2023)等。

请注意

几乎所有的transformer挑战都源于其极端的计算和内存要求。像FlashAttention这样真正高效的Transformers可能会缓解这些挑战。

Transformer的开源实现

最初的transformer模型是在Tensor2Tensor库中实现的13,但最近已经弃用了。Tensor2Tensor的继承者是基于JAX的Trax 14

有许多transformer模型体系结构的开源实现。让我们简要讨论一下最流行的三种实现。HuggingFace Transformer库(Wolf etal . 2020)可以说是最流行的Transformers实现之一。该库简化了NLP(和视觉)下游任务的推理管道,并可用于训练或微调基于变压器的模型。HuggingFace Transformer库易于使用,它很干净,并且有一个庞大的开发人员和贡献者社区。Andrej Karpathy的minGPTnanoGPT也是开源和研究社区中流行的实现。此外,x-transformers提供了各种transformer模型的简明和实验实现,通常来自新的研究论文。

最后,你不太可能需要从头开始实现transformer模型或它的一部分,因为现代深度学习框架,如PyTorchKeras和JAX(Via flex)提供了可以轻松导入的层的实现,就像导入卷积或线性层一样。

补充的资源

本文对现有的围绕transformer神经网络体系结构理解的知识库做出了贡献。因此,不强调一些关于transformer体系结构的宝贵资源是疏忽的,我们将在下面简要地提供:

  • 注释的Transformer:这是最好的和实用的资源之一。它提供了transformer体系结构的逐行实现和完全可用的代码。原始版本由Sasha Rush撰写,最新版本由Austin Huang和他的同事撰写。

  • Andrej Karpathy的《让我们从头开始构建GPT》:这可以说是关于transformer实现的最佳资源,最值得注意的是GPT(生成预训练transformer)。Karpathy从零开始构建和训练整个GPT,并在此过程中为每一步提供了一个像样的解释。这里有一个讲座视频附带的代码库(nanoGPT)

  • 斯坦福CS25:Transformers联合V2旨在研究Transformers是如何工作的,以及它们如何应用于从NLP, CV,生物学到机器人等不同领域。本课程包含来自研究人员的精彩演讲。课程最新版本的入门课程深入研究了transformer架构,由Karpathy教授,他对神经网络的复杂性有着深刻的理解。

  • Transformers的形式化算法提供了各种transformer架构的数学概述和形式化算法。

  • Transformer分类法提供了transformer模型的优秀文献综述,自标准transformer开始以来的架构变化,后预培训技术和3种培训技术。

  • The Illustrated Transformer是一篇出色的博客文章,它将transformer模型分解并直观地解释了每个部分。

  • Lilian Weng的Transformer和注意力系列博客也提供了对transformer和注意力机制的深刻理解。一个值得注意的例子是Transformer家族版(there也是这个博客的第二版)和[注意?(https://lilianweng.github.io/posts/2018-06-24-attention/)。

  • 关注是你所需要的视频由Yannic Kilcher讲解论文,解释所有相关概念和相关作品。

  • Transformer模型:介绍和目录也是另一个值得一提的资源。它提供了一个不错的流行transformer型号目录。

结论

Transformer神经网络体系结构在深度学习和计算机科学领域的重要性不容忽视。最初为神经机器翻译引入的transformer模型已经发展成为一种通用的通用架构,展示了超越自然语言处理的令人印象深刻的性能。

在本文中,我们深入研究了transformer的核心机制及其基本组件——它的encoder和解码器结构、注意机制、多头注意、mlp、Embedding、位置编码层等等。我们已经探讨了自我关注的几个好处,以及潜在的缺点。此外,通过研究注意力的可视化,我们对Transformers如何聚焦于输入序列的不同部分以产生输出有了更深入的了解。

Transformers是最近风靡全球的大型语言模型(大语言模型)的核心。我们已经看到了大语言模型及其不同设计风格的演变,以及Transformers在NLP之外的应用。我们还讨论了他们当前面临的挑战,包括对更高效模型的需求和对上下文窗口的有效使用。这些挑战为未来的研究和改进提供了令人兴奋的机会。

随着深度学习领域的不断发展,transformer架构仍然是现代机器学习系统的基础构建块。transformer架构有许多变化,但无论Transformers的未来如何,有一件事是肯定的-注意力是你所需要的。保持好奇,不断学习,时刻关注!

参考文献

Akyürek, Ekin, Dale Schuurmans, Jacob Andreas, Tengyu Ma, and Denny Zhou. 2023. “What Learning Algorithm Is in-Context Learning? Investigations with Linear Models.” arXiv Preprint arXiv:2211.15661.

Alayrac, Jean-Baptiste, Jeff Donahue, Pauline Luc, Antoine Miech, Iain Barr, Yana Hasson, Karel Lenc, et al. 2022. “Flamingo: A Visual Language Model for Few-Shot Learning.” arXiv Preprint arXiv:2204.14198.

Ba, Jimmy Lei, Jamie Ryan Kiros, and Geoffrey E Hinton. 2016. “Layer Normalization.” arXiv Preprint arXiv:1607.06450.

Bahdanau, Dzmitry, Kyunghyun Cho, and Yoshua Bengio. 2014. “Neural Machine Translation by Jointly Learning to Align and Translate.” arXiv Preprint arXiv:1409.0473.

Bommasani, Rishi, Drew A Hudson, Ehsan Adeli, Russ Altman, Simran Arora, Sydney von Arx, Michael S Bernstein, et al. 2022. “On the Opportunities and Risks of Foundation Models.” arXiv Preprint arXiv:2108.07258.

Bousmalis, Konstantinos, Giulia Vezzani, Dushyant Rao, Coline Devin, Alex X Lee, Maria Bauza, Todor Davchev, et al. 2023. “RoboCat: A Self-Improving Foundation Agent for Robotic Manipulation.” arXiv Preprint arXiv:2306.11706.

Brohan, Anthony, Noah Brown, Justice Carbajal, Yevgen Chebotar, Joseph Dabis, Chelsea Finn, Keerthana Gopalakrishnan, et al. 2022. “RT-1: Robotics Transformer for Real-World Control at Scale.” arXiv Preprint arXiv:2212.06817.

Brown, Tom B, Benjamin Mann, Nick Ryder, Melanie Subbiah, Jared Kaplan, Prafulla Dhariwal, Arvind Neelakantan, et al. 2020. “Language Models Are Few-Shot Learners.” arXiv Preprint arXiv:2005.14165.

Carion, Nicolas, Francisco Massa, Gabriel Synnaeve, Nicolas Usunier, Alexander Kirillov, and Sergey Zagoruyko. 2020. “End-to-End Object Detection with Transformers.” arXiv Preprint arXiv:2005.12872.

Chen, Lili, Kevin Lu, Aravind Rajeswaran, Kimin Lee, Aditya Grover, Michael Laskin, Pieter Abbeel, Aravind Srinivas, and Igor Mordatch. 2021. “Decision Transformer: Reinforcement Learning via Sequence Modeling.” arXiv Preprint arXiv:2106.01345.

Chen, Shouyuan, Sherman Wong, Liangjian Chen, and Yuandong Tian. 2023. “Extending Context Window of Large Language Models via Positional Interpolation.” arXiv Preprint arXiv:2306.15595.

Chen, Xi, Josip Djolonga, Piotr Padlewski, Basil Mustafa, Soravit Changpinyo, Jialin Wu, Carlos Riquelme Ruiz, et al. 2023. “PaLI-x: On Scaling up a Multilingual Vision and Language Model.” arXiv Preprint arXiv:2305.18565.

Chollet, François. 2017. “Xception: Deep Learning with Depthwise Separable Convolutions.” arXiv Preprint arXiv:1610.02357.

Chowdhery, Aakanksha, Sharan Narang, Jacob Devlin, Bosma Maarten, Mishra Gaurav, Roberts Adam, Barham Paul, et al. 2022. “PaLM: Scaling Language Modeling with Pathways.” arXiv Preprint arXiv:2204.02311.

Chung, Hyung Won, Le Hou, Shayne Longpre, Barret Zoph, Yi Tay, William Fedus, Yunxuan Li, et al. 2022. “Scaling Instruction-Finetuned Language Models.” arXiv Preprint arXiv:2210.11416.

Dao, Tri. 2023. “FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning.” arXiv Preprint arXiv:2307.08691.

Dao, Tri, Daniel Y. Fu, Stefano Ermon, Atri Rudra, and Christopher Ré. 2022. “FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness.” arXiv Preprint arXiv:2205.14135.

Dehghani, Mostafa, Anurag Arnab, Lucas Beyer, Ashish Vaswani, and Yi Tay. 2022. “The Efficiency Misnomer.” arXiv Preprint arXiv:2110.12894.

Devlin, Jacob, Ming-Wei Chang, Kenton Lee, and Kristina Toutanova. 2019. “BERT: Pre-Training of Deep Bidirectional Transformers for Language Understanding.” In Proceedings of the 2019 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies, Volume 1 (Long and Short Papers), 4171–86.

Dosovitskiy, Alexey, Lucas Beyer, Alexander Kolesnikov, Dirk Weissenborn, Xiaohua Zhai, Thomas Unterthiner, Mostafa Dehghani, et al. 2021. “An Image Is Worth 16x16 Words: Transformers for Image Recognition at Scale.” In International Conference on Learning Representations.

Girdhar, Rohit, Alaaeldin El-Nouby, Zhuang Liu, Mannat Singh, Kalyan Vasudev Alwala, Armand Joulin, and Ishan Misra. 2023. “ImageBind: One Embedding Space to Bind Them All.” arXiv Preprint arXiv:2305.05665.

Graves, Alex, Greg Wayne, and Ivo Danihelka. 2014. “Neural Turing Machines.” arXiv Preprint arXiv:1410.5401.

He, Kaiming, Xinlei Chen, Saining Xie, Yanghao Li, Piotr Dollár, and Ross Girshick. 2021. “Masked Autoencoders Are Scalable Vision Learners.” arXiv Preprint arXiv:2111.06377.

He, Kaiming, Xiangyu Zhang, Shaoqing Ren, and Jian Sun. 2016. “Deep Residual Learning for Image Recognition.” In Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition, 770–78.

Hoffmann, Jordan, Sebastian Borgeaud, Arthur Mensch, Elena Buchatskaya, Trevor Cai, Eliza Rutherford, Diego de Las Casas, et al. 2022. “Training Compute-Optimal Large Language Models.” arXiv Preprint arXiv:2203.15556.

Ioffe, Sergey, and Christian Szegedy. 2015. “Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift.” In International Conference on Machine Learning, 448–56.

Le Scao, Teven, Angela Fan, Christopher Akiki, Pavlick Ellie, Ilić Suzana, Hesslow Daniel, Castagné Roman, et al. 2022. “BLOOM: A 176B-Parameter Open-Access Multilingual Language Model.” arXiv Preprint arXiv:2211.05100.

Lewis, Mike, Yinhan Liu, Naman Goyal, Marjan Ghazvininejad, Abdelrahman Mohamed, Omer Levy, Veselin Stoyanov, and Luke Zettlemoyer. 2019. “BART: Denoising Sequence-to-Sequence Pre-Training for Natural Language Generation, Translation, and Comprehension.” arXiv Preprint arXiv:1910.13461.

Lewkowycz, Aitor, Anders Andreassen, David Dohan, Ethan Dyer, Henryk Michalewski, Vinay Ramasesh, Ambrose Slone, et al. 2022. “Solving Quantitative Reasoning Problems with Language Models.” arXiv Preprint arXiv:2206.14858.

Liu, Nelson F., Kevin Lin, John Hewitt, Ashwin Paranjape, Michele Bevilacqua, Fabio Petroni, and Percy Liang. 2023. “Lost in the Middle: How Language Models Use Long Contexts.” arXiv Preprint arXiv:2307.03172.

Liu, Yinhan, Myle Ott, Naman Goyal, Jingfei Du, Mandar Joshi, Danqi Chen, Omer Levy, Mike Lewis, Luke Zettlemoyer, and Veselin Stoyanov. 2019. “RoBERTa: A Robustly Optimized BERT Pretraining Approach.” arXiv Preprint arXiv:1907.11692.

Lu, Jiasen, Christopher Clark, Rowan Zellers, Roozbeh Mottaghi, and Aniruddha Kembhavi. 2022. “Unified-IO: A Unified Model for Vision, Language, and Multi-Modal Tasks.” arXiv Preprint arXiv:2206.08916.

Luong, Minh-Thang, Hieu Pham, and Christopher D Manning. 2015. “Effective Approaches to Attention-Based Neural Machine Translation.” arXiv Preprint arXiv:1508.04025.

Mehta, Sachin, and Mohammad Rastegari. 2022. “MobileViT: Light-Weight, General-Purpose, and Mobile-Friendly Vision Transformer.” arXiv Preprint arXiv:2110.02178.

OpenAI. 2023. “GPT-4 Technical Report.” arXiv Preprint arXiv:2303.08774.

Parmar, Niki, Ashish Vaswani, Jakob Uszkoreit, Łukasz Kaiser, Noam Shazeer, Alexander Ku, and Dustin Tran. 2018. “Image Transformer.” In Proceedings of the 35th International Conference on Machine Learning, 4055–64.

Radford, Alec, Jong Wook Kim, Chris Hallacy, Aditya Ramesh, Gabriel Goh, Sandhini Agarwal, Girish Sastry, et al. 2021. “Learning Transferable Visual Models from Natural Language Supervision.” In International Conference on Machine Learning, 8748–63.

Radford, Alec, Jong Wook Kim, Tao Xu, Greg Brockman, Christine McLeavey, and Ilya Sutskever. 2022. “Robust Speech Recognition via Large-Scale Weak Supervision.” arXiv Preprint arXiv:2212.04356.

Radford, Alec, Karthik Narasimhan, Tim Salimans, and Ilya Sutskever. 2018. “Improving Language Understanding by Generative Pre-Training.”

Radford, Alec, Jeffrey Wu, Rewon Child, David Luan, Dario Amodei, and Ilya Sutskever. 2019. “Language Models Are Unsupervised Multitask Learners.” OpenAI Blog 1 (8).

Raffel, Colin, Noam Shazeer, Adam Roberts, Katherine Lee, Sharan Narang, Michael Matena, Yanqi Zhou, Wei Li, and Peter J Liu. 2019. “Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer.” arXiv Preprint arXiv:1910.10683.

Ramesh, Aditya, Prafulla Dhariwal, Alex Nichol, Casey Chu, and Mark Chen. 2022. “Hierarchical Text-Conditional Image Generation with CLIP Latents.” arXiv Preprint arXiv:2204.06125.

Reed, Scott, Konrad Zolna, Emilio Parisotto, Sergio Gomez Colmenarejo, Alexander Novikov, Gabriel Barth-Maron, Mai Gimenez, et al. 2022. “A Generalist Agent.” arXiv Preprint arXiv:2205.06175.

Rombach, Robin, Andreas Blattmann, Dominik Lorenz, Patrick Esser, and Björn Ommer. 2022. “High-Resolution Image Synthesis with Latent Diffusion Models.” In Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition, 10684–95.

Singhal, Karan, Shekoofeh Azizi, Tao Tu, S Sara Mahdavi, Jason Wei, Hyung Won Chung, Nathan Scales, et al. 2022. “Large Language Models Encode Clinical Knowledge.” arXiv Preprint arXiv:2212.13138.

Srivastava, Nitish, Geoffrey Hinton, Alex Krizhevsky, Ilya Sutskever, and Ruslan Salakhutdinov. 2014. “Dropout: A Simple Way to Prevent Neural Networks from Overfitting.” Journal of Machine Learning Research 15 (56): 1929–58.

Steiner, Andreas, Alexander Kolesnikov, Xiaohua Zhai, Ross Wightman, Jakob Uszkoreit, and Lucas Beyer. 2021. “How to Train Your ViT? Data, Augmentation, and Regularization in Vision Transformers.” arXiv Preprint arXiv:2106.10270.

Sun, Chen, Abhinav Shrivastava, Saurabh Singh, and Abhinav Gupta. 2017. “Revisiting Unreasonable Effectiveness of Data in Deep Learning Era.” In Proceedings of the IEEE International Conference on Computer Vision, 843–52.

Sun, Simeng, Kalpesh Krishna, Andrew Mattarella-Micke, and Mohit Iyyer. 2021. “Do Long-Range Language Models Actually Use Long-Range Context?” In Proceedings of the 2021 Conference on Empirical Methods in Natural Language Processing (EMNLP), 807–22. Online; Punta Cana, Dominican Republic: Association for Computational Linguistics. https://doi.org/10.18653/v1/2021.emnlp-main.62.

Tay, Yi, Mostafa Dehghani, Dara Bahri, and Donald Metzler. 2020. “Efficient Transformers: A Survey.” arXiv Preprint arXiv:2009.06732.

Tay, Yi, Mostafa Dehghani, Vinh Q Tran, Xavier Garcia, Jason Wei, Xuezhi Wang, Hyung Won Chung, et al. 2022. “UL2: Unifying Language Learning Paradigms.” arXiv Preprint arXiv:2205.05131.

Taylor, Ross, Marcin Kardas, Guillem Cucurull, Thomas Scialom, Anthony Hartshorn, Elvis Saravia, Andrew Poulton, Viktor Kerkez, and Robert Stojnic. 2022. “Galactica: A Large Language Model for Science.” arXiv Preprint arXiv:2211.09085.

Touvron, Hugo, Matthieu Cord, Alaaeldin El-Nouby, Piotr Bojanowski, Armand Joulin, Gabriel Synnaeve, and Hervé Jégou. 2021. “Augmenting Convolutional Networks with Attention-Based Aggregation.” arXiv Preprint arXiv:2112.13692.

Touvron, Hugo, Thibaut Lavril, Gautier Izacard, Xavier Martinet, Marie-Anne Lachaux, Timothée Lacroix, Baptiste Rozière, et al. 2023. “LLaMA: Open and Efficient Foundation Language Models.” arXiv Preprint arXiv:2302.13971.

Vaswani, Ashish, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N Gomez, Lukasz Kaiser, and Illia Polosukhin. 2017. “Attention Is All You Need.” arXiv Preprint arXiv:1706.03762.

Vig, Jesse. 2019. “A Multiscale Visualization of Attention in the Transformer Model.” In Proceedings of the 57th Annual Meeting of the Association for Computational Linguistics: System Demonstrations, 37–42.

Wang, Guangyu, Guoxing Yang, Zongxin Du, Longjun Fan, and Xiaohu Li. 2023. “ClinicalGPT: Large Language Models Finetuned with Diverse Medical Data and Comprehensive Evaluation.” arXiv Preprint arXiv:2306.09968.

Wang, Peng, An Yang, Rui Men, Junyang Lin, Shuai Bai, Zhikang Li, Jianxin Ma, Chang Zhou, Jingren Zhou, and Hongxia Yang. 2022. “OFA: Unifying Architectures, Tasks, and Modalities Through a Simple Sequence-to-Sequence Learning Framework.” In Proceedings of the 39th International Conference on Machine Learning, 23318–40. PMLR.

Wang, Zirui, Jiahui Yu, Adams Wei Yu, Zihang Dai, Yulia Tsvetkov, and Yuan Cao. 2021. “SimVLM: Simple Visual Language Model Pretraining with Weak Supervision.” arXiv Preprint arXiv:2108.10904.

Wei, Jason, Max Nye, and Percy Liang. 2022. “Chain-of-Thought Prompting Elicits Reasoning in Large Language Models.” arXiv Preprint arXiv:2201.11903.

Wei, Jason, Yi Tay, Rishi Bommasani, Colin Raffel, Barret Zoph, Sebastian Borgeaud, Dani Yogatama, et al. 2022. “Emergent Abilities of Large Language Models.” arXiv Preprint arXiv:2206.07682.

Wei, Jerry, Jason Wei, Yi Tay, Dustin Tran, Albert Webson, Yifeng Lu, Xinyun Chen, et al. 2023. “Larger Language Models Do in-Context Learning Differently.” arXiv Preprint arXiv:2303.03846.

Wolf, Thomas, Lysandre Debut, Victor Sanh, Julien Chaumond, Clement Delangue, Anthony Moi, Pierric Cistac, et al. 2020. “Transformers: State-of-the-Art Natural Language Processing.” In Proceedings of the 2020 Conference on Empirical Methods in Natural Language Processing: System Demonstrations, 38–45. Online: Association for Computational Linguistics. https://doi.org/10.18653/v1/2020.emnlp-demos.6.

Wu, Shijie, Ozan Irsoy, Steven Lu, Vadim Dabravolski, Mark Dredze, Sebastian Gehrmann, Prabhanjan Kambadur, David Rosenberg, and Gideon Mann. 2023. “BloombergGPT: A Large Language Model for Finance.” arXiv Preprint arXiv:2303.17564.

Xie, Shufang, Huishuai Zhang, Junliang Guo, Xu Tan, Jiang Bian, Hany Hassan Awadalla, Arul Menezes, Tao Qin, and Rui Yan. 2023. “ResiDual: Transformer with Dual Residual Connections.” arXiv Preprint arXiv:2304.14802.

Xiong, Ruibin, Yunchang Yang, Di He, Kai Zheng, Shuxin Zheng, Chen Xing, Huishuai Zhang, Yanyan Lan, Liwei Wang, and Tie-Yan Liu. 2020. “On Layer Normalization in the Transformer Architecture.” In International Conference on Machine Learning, 10524–33.

Xu, Kelvin, Jimmy Ba, Ryan Kiros, Kyunghyun Cho, Aaron Courville, Ruslan Salakhutdinov, Richard S Zemel, and Yoshua Bengio. 2015. “Show, Attend and Tell: Neural Image Caption Generation with Visual Attention.” In International Conference on Machine Learning, 2048–57.

Xue, Linting, Noah Constant, Adam Roberts, Mihir Kale, Rami Al-Rfou, Aditya Siddhant, Aditya Barua, and Colin Raffel. 2021. “mT5: A Massively Multilingual Pre-Trained Text-to-Text Transformer.” In Proceedings of the 2021 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies, 483–98.

Yang, Hongyang, Xiao-Yang Liu, and Christina Dan Wang. 2023. “FinGPT: Open-Source Financial Large Language Models.” arXiv Preprint arXiv:2306.06031.

Yang, Jingfeng, Hongye Jin, Ruixiang Tang, Xiaotian Han, Qizhang Feng, Haoming Jiang, Bing Yin, and Xia Hu. 2023. “Harnessing the Power of LLMs in Practice: A Survey on ChatGPT and Beyond.” arXiv Preprint arXiv:2304.13712.

Zhang, Xiang, and Yann LeCun. 2015. “Text Understanding from Scratch.” arXiv Preprint arXiv:1502.01710.

Zhang, Yiyuan, Kaixiong Gong, Kaipeng Zhang, Hongsheng Li, Yu Qiao, Wanli Ouyang, and Xiangyu Yue. 2023. “Meta-Transformer: A Unified Framework for Multimodal Learning.” arXiv Preprint arXiv:2307.10802.

Footnotes

  1. Example adapted from Deep Learning with Python by Francois Chollet↩︎
  2. In the transformer paper, MLPs are what referred to as feed-forward networks(FFNs). I find the terminology of FFNs confusing sometime. MLPs are feed-forward networks but not the other way around.↩︎
  3. If you want to see how embeddings look like and how words with same semantic meaning tend to be closer to each other, you can play with Embedding Projector↩︎
  4. The core operation in attention is the dot product between query and keys, which, being a summation operation, is permutation invariant↩︎
  5. Hat tip to Sebastian Raschka for sharing this in his newsletter↩︎
  6. BertViz be accessed at https://github.com/jessevig/bertviz[↩︎](https://deeprevision.github.io/posts/001-transformer/#fnref6)
  7. Karpathy said that in a Twitter thread. Available here: https://twitter.com/karpathy/status/1655994367033884672?s=20[↩︎](https://deeprevision.github.io/posts/001-transformer/#fnref7)
  8. Next sentence prediction in BERT and next token prediction in standard transformer are different. The idea is roughly similar, but the former is usually for discriminative modelling while the later is for auto-regressive generative modelling↩︎
  9. Next token prediction in decoder LLMs is different to next sentence prediction in BERT. The former operates on token level while the later operates on sentence level↩︎
  10. It’s fair to say that GPT-3 popularized prompt engineering.↩︎
  11. The inductive biases in ConvNets are the results of their translation invariance. Convolution itself is translation equivariance(changing the position of pixels changes the output) but pooling which is often used after convolution is translation invariant(changing the position of pixels doesn’t change the output) and this make the overall ConvNets translation invariant architecture↩︎
  12. GPU main memory is called HBM which stands for High Bandwidth Memory↩︎
  13. Available at https://github.com/tensorflow/tensor2tensor[↩︎](https://deeprevision.github.io/posts/001-transformer/#fnref13)
  14. Available at https://github.com/google/trax[↩︎](https://deeprevision.github.io/posts/001-transformer/#fnref14)

原文:The Transformer Blueprint: A Holistic Guide to the Transformer Neural Network Architecture


目前正在接受试用中!!!

请将您的称谓、公司名称和使用场景,发邮件到yuanwai@mengjia.net。

也可以直接加微信:lxdhdgss 咨询

更多详情,可查看文章:TorchV Bot开始对外试用了!


最新内容,关注“土猛的员外”公众号

如何使用LLM与任何pdf和图像文件聊天

介绍

如此多有价值的信息被困在PDF和图像文件中。幸运的是,我们拥有强大的大脑,能够处理这些文件以找到特定的信息,这实际上很棒。

但是,我们当中有多少人在内心深处不希望有一个工具可以回答关于给定文档的任何问题?

这就是本文的全部目的。我将逐步解释如何构建一个可以与任何pdf和图像文件聊天的系统。

项目的一般工作流程

对正在构建的系统的主要组件有一个清晰的理解总是好的。让我们开始吧。

截屏2023-09-09 23.47.50

整个聊天系统的端到端工作流程
  • 首先,用户提交待处理的文档,文档可以是PDF格式,也可以是图像格式。
  • 第二个模块用于检测文件的格式,以便应用相关的内容提取功能。
  • 然后使用Data Splitter模块将文档的内容分割成多个块。
  • 这些块最终使用Chunk Transformer转换成Embeddings,然后将它们存储在矢量存储中。
  • 在流程结束时,用户的查询用于查找包含该查询答案的相关块,并将结果作为JSON返回给用户。

1. 检测文档类型

对于每个输入文档,将根据其类型(无论是PDF还是image)应用特定的处理。

这可以通过辅助函数detect_document_type 与内置Python模块中的guess 函数相结合来实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def detect_document_type(document_path):

guess_file = guess(document_path)
file_type = ""
image_types = ['jpg', 'jpeg', 'png', 'gif']

if(guess_file.extension.lower() == "pdf"):
file_type = "pdf"

elif(guess_file.extension.lower() in image_types):
file_type = "image"

else:
file_type = "unkown"

return file_type

现在我们可以在两种类型的文档上测试这个函数:

  • transformer_paper.pdf是Transformers研究论文来自Arxiv
  • zoumana_article_information.png是图像文档,包含有关我在Medium上覆盖的主要主题的信息。
1
2
3
4
5
research_paper_path = "./data/transformer_paper.pdf"
article_information_path = "./data/zoumana_article_information.png"

print(f"Research Paper Type: {detect_document_type(research_paper_path)}")
print(f"Article Information Document Type: {detect_document_type(article_information_path)}")

输出:

img

成功检测到的文件类型(图片按作者)

这两种文件类型都被detect_document_type函数成功检测到。

2. 根据文档类型提取内容

langchain库提供了不同的模块来提取给定类型文档的内容。

  • UnstructuredImageLoader提取图像内容。
  • UnstructuredFileLoader提取任何pdf和Txt文件的内容。

我们可以将这些模块与上面的detect_document_type 函数结合起来实现文本提取逻辑。

这些模块可用于在extract_file_content函数中实现端到端的文本提取逻辑。

让我们看看他们的行动吧!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from langchain.document_loaders.image import UnstructuredImageLoader
from langchain.document_loaders import UnstructuredFileLoader

def extract_file_content(file_path):

file_type = detect_document_type(file_path)

if(file_type == "pdf"):
loader = UnstructuredFileLoader(file_path)

elif(file_type == "image"):
loader = UnstructuredImageLoader(file_path)

documents = loader.load()
documents_content = '\n'.join(doc.page_content for doc in documents)

return documents_content

现在,让我们打印每个文件内容的前400个字符。

1
2
3
4
5
6
7
8
research_paper_content = extract_file_content(research_paper_path)
article_information_content = extract_file_content(article_information_path)

nb_characters = 400

print(f"First {nb_characters} Characters of the Paper: \n{research_paper_content[:nb_characters]} ...")
print("---"*5)
print(f"First {nb_characters} Characters of Article Information Document :\n {research_paper_content[:nb_characters]} ...")

输出:

上述文件的前400个字符如下:

  • 研究论文内容以Provided proper attribution is provided开始,以Jacod Uszkoreit* Google research usz@google.com结束。
  • 图像文档的内容以This document provides a quick summary开始,并以Data Science section covers basic to advance concepts结束。

img

《Transformers》论文和文章信息文档的前400个字符

3. Chat实现

输入文档被分割成块,然后在实现问答逻辑之前为每个块创建Embedding。

a. 文档组块

块表示较大文本的较小部分。这个过程对于确保一段内容以尽可能少的噪音表示,使其具有语义相关性至关重要。

可以应用多种分块策略。

例如,我们有NLTKTextSplitterSpacyTextSplitter,、RecursiveCharacterTextSplitterCharacterTextSplitter等等。

每一种策略都有其优缺点。

本文的主要重点是CharacterTextSplitter,它基于\n\n从输入文档中创建块,并通过其字符数测量每个块的长度(length_function)。

1
2
3
4
5
6
text_splitter = CharacterTextSplitter(        
separator = "\n\n",
chunk_size = 1000,
chunk_overlap = 200,
length_function = len,
)

chunk_size告诉我们希望每个块中最多有1000个字符,较小的值将产生更多的块,而较大的值将产生更少的块。

需要注意的是,选择chunk_size的方式会影响整体结果。因此,一个好的方法是尝试不同的值,并选择更适合自己用例的值。

此外,chunk_overlap意味着我们希望在连续块之间最多有200个重叠字符。

例如,假设我们有一个包含文本Chat with your documents using LLMs的文档,并希望使用Chunk Size = 10Chunk overlap = 5来应用分块。

这个过程如下图所示:

img

文档分块说明

我们可以看到,对于35个字符(包括空格)的输入文档,我们最终得到了总共7个块。

但是,我们为什么要首先使用这些重叠呢?

包括这些重叠, CharacterTextSplitter确保在块之间维护底层上下文,这在处理长段文档时特别有用。

chunk_size类似,chunk_overlap没有固定值。需要测试不同的值,以选择效果更好的值。

现在,让我们看看它们在我们的场景中的应用:

1
2
3
4
5
research_paper_chunks = text_splitter.split_text(research_paper_content)
article_information_chunks = text_splitter.split_text(article_information_content)

print(f"# Chunks in Research Paper: {len(research_paper_chunks)}")
print(f"# Chunks in Article Document: {len(article_information_chunks)}")

输出:

img

每个文档中的块数

对于像研究论文这样的大型文档,我们有更多的块(51),而一页的文章文档只有2个。

b. 创建块的Embeddings

我们可以使用OpenAIEmbeddings模块,它默认使用text-embedding-ada-002 模型来创建块的Embedding。

而不是使用text-embedding-ada-002可以使用不同的模型(例如:gpt-3.5-turbo-0301),通过改变以下参数:

  • model = “ gpt-3.5-turbo-0301
  • deployment = “<DEPLOYMENT-NAME>“,对应于模型部署期间给出的名称。默认值也是text- embeddings -ada-002

为了简单起见,我们将在本教程中坚持使用默认参数的值。但在此之前,我们需要获得OpenAI凭据,下面的文章提供了所有步骤。

1
2
3
4
5
from langchain.embeddings.openai import OpenAIEmbeddings
import os

os.environ["OPENAI_API_KEY"] = "<YOUR_KEY>"
embeddings = OpenAIEmbeddings()

c. 创建文档搜索

为了获得给定查询的答案,我们需要创建一个向量存储,用于查找与该查询最接近的匹配块。

这样的矢量存储可以使用FAISS模块中的from_texts函数来创建,该函数有两个主要参数:text_splitterEmbeddings,这两个参数都是前面定义的。

1
2
3
4
5
from langchain.vectorstores import FAISS

def get_doc_search(text_splitter):

return FAISS.from_texts(text_splitter, embeddings)

通过在研究论文块上运行get_doc_search,我们可以看到结果是vectorstores。如果我们使用article_information_chunks,结果将是相同的。

1
2
doc_search_paper = get_doc_search(research_paper_chunks)
print(doc_search_paper)

输出:

img

研究论文的矢量存储

d. 开始和你的文件聊天

祝贺你走了这么远!

chat_with_file函数用于通过组合上述所有函数以及similarity_search函数来实现聊天的端到端逻辑。

最后一个函数接受两个形参:

  • 我们想要聊天的文件,还有
  • 用户提供的查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from langchain.llms import OpenAI
from langchain.chains.question_answering import load_qa_chain
chain = load_qa_chain(OpenAI(), chain_type = "map_rerank",
return_intermediate_steps=True)

def chat_with_file(file_path, query):

file_content = extract_file_content(file_path)
text_splitter = text_splitter.split_text(file_content)

document_search = get_doc_search(text_splitter)
documents = document_search.similarity_search(query)

results = chain({
"input_documents":documents,
"question": query
},
return_only_outputs=True)
answers = results['intermediate_steps'][0]

return answers

让我们退一步来正确理解上面代码块中发生的事情。

  • load_qa_chain提供了一个接口,用于在一组文档上执行问答。在这个特定的情况下,我们使用默认的OpenAI GPT-3大型语言模型。
  • chain_typemap_rerank。通过这样做,load_qa_chain函数根据链给出的置信度分数返回答案。还有其他的chain_type可以使用,比如map_reducestuffrefine等等。每个人都有自己的优点和缺点。
  • 通过设置return_intermediate_steps=True,我们可以访问元数据,如上述置信度评分。

它的输出是一个包含两个键的字典:查询的答案和信心得分

我们终于可以和我们的文件聊天了,从图像文档开始:

  • 与图像文档聊天

为了与图像文档进行对话,我们提供了文档的路径,以及我们希望模型回答的问题。

1
2
3
4
5
6
7
8
query = "What is the document about"

results = chat_with_file(article_information_path, query)

answer = results["answer"]
confidence_score = results["score"]

print(f"Answer: {answer}\n\nConfidence Score: {confidence_score}")

输出:

img

对图片文档查询的结果

该模型对其响应有100%的信心。通过查看下面原始文档的第一段,我们可以看到模型响应确实是正确的。

img

原文章图片文档前两段

最有趣的部分之一是,它提供了文档中涵盖的主要主题的简要摘要(统计、模型评估指标、SQL查询等)。

  • 与PDF文件聊天

PDF文件的处理过程与上一节中的过程类似。

1
2
3
4
5
6
7
8
query = "Why is the self-attention approach used in this document?"

results = chat_with_file(research_paper_path, query)

answer = results["answer"]
confidence_score = results["score"]

print(f"Answer: {answer}\n\nConfidence Score: {confidence_score}")

输出:

我们再一次从模型中得到了100%的置信度。这个问题的答案看起来非常正确!

img

查询PDF文件的结果

在这两种情况下,该模型都能在几秒钟内做出类似人类的反应。让一个人完成同样的过程需要几分钟,甚至几个小时,这取决于文档的长度。

本文的Github地址

原文:How to Chat With Any PDFs and Image Files Using Large Language Models — With Code


目前正在接受试用中!!!

请将您的称谓、公司名称和使用场景,发邮件到yuanwai@mengjia.net。

也可以直接加微信:lxdhdgss 咨询

更多详情,可查看文章:TorchV Bot开始对外试用了!


最新内容,关注“土猛的员外”公众号

Midjourney中标点符号的使用指南

这篇文章研究的是标点符号在prompt中的作用。

Midjourney的prompt可以包含标点符号。我们经常使用它们来制作prompt,而不需要太多思考。毕竟,这是官方的Midjourney用户指南声明:

使用逗号,括号和连字符来帮助组织你的想法,但请记住,MidjourneyBot不会可靠地解释它们。

对于许多用户来说,“不能可靠地解释它们”意味着“不用麻烦了”。然而,标点符号对你的prompt几乎没有影响,这是真的吗?如果他们这样做了怎么办?如果它们有微妙的影响,你可以利用它们来调整你的prompt?

到目前为止我们对标点符号的了解

在我们研究标点符号是否重要之前,让我们来看看Midjourney机器人可以可靠理解的五个主要标点符号:

  1. 双连字符--用于--ar 3:2
  2. 双冒号::用于multiprompt(可以表示::两边字符的权重)和输入weights
  3. 花括号{}表示排列prompt
  4. 反斜杠\用于转义排列中的逗号。例如,/imagine prompt:a photo of {a bird\, cat, a dog\, fish}将创建两个prompts:/imagine prompt:a photo of a bird\, cat/imagine prompt:a photo of a dog, fish
  5. 空格实际上就是分隔单词或tokens的字符

另外两个标点符号是正斜杠 / 和冒号: ——但它们是在命令中使用,而不是在prompt中。

根据Midjourney常见问题解答,上述标点符号列表之外的所有其他标点符号都是“有趣的噪音”。

“有趣的噪音”表明某些事情显然正在发生,即使还没有设计出实验来揭示它。在对prompt进行故障排除时,有必要尝试一下有趣的噪音,因为它可能是打开你想要的东西的钥匙。

Midjourney的编程不支持理解逗号或连字符,但建议在prompts中使用它们,因为人类会使用它们,而且它们在数据集中可能具有很强的相关性。

到目前为止,我们已经讨论了我们所知道的标点符号。现在,让我们来看看这个“有趣的噪音”。

以下是我们将探讨的4个问题:

  1. 如果我们用标点符号超载prompt符会怎样?
  2. 何时使用连字符,何时不使用?
  3. 如果我们用不同的标点符号来区分概念或想法有关系吗?
  4. 机器人能理解由标点符号组成的表情符号吗?

方法

  • 至少重新提示3次
  • 小心使用 /shorten
  • 使用CLIP标记器
  • 使用MidjourneyV5.2进行测试

每个prompt将被重新提示至少三次,以确保一致性和可重复性。结果预计会受到随机化的影响,但目标是在再次提示后找到类似的东西或效果。

/shorten用于测试标点符号对prompt的影响。它用于检测由标点符号引起的单词“相对影响值”的变化。相对影响力的值表示token(或单词)对生成的输出是否具有更大的影响力或影响。

不幸的是, /shorten仍然是一项正在进行的工作,需要更可靠地精确定位生成图像所需的单词。例如,一些重要的单词被 /缩短划掉(划掉),但需要生成所需的图像。

但是,我们仍然可以使用它来验证prompt是否发生了变化,因为单词的相对影响值可能由于标点符号而发生了变化。

CLIP Tokenizer用于确定标点符号是否影响在prompt符中创建的tokens的数量。

Midjourney机器人会在读取prompt时将单词分解成称为“tokens”的片段。然后将tokens与训练数据进行比较以生成图像。

tokens的数量通常等于或超过单词的数量。更多的tokens并不总是好的,因为Midjourney V5.2中的prompt符最多只能容纳大约。60个tokens。

好的,让我们从现在开始寻找新的东西。

(1) 如果我们用标点符号超载prompt符会怎样?

感叹号用于表达强烈的情感。星号*符号强调消息传递应用程序中的单词或短语。如果我们把它们都塞进一个prompt中呢?对形象有影响吗?

Prompt 1 — /imagine prompt: a dog and a cat

Prompt 2 — /imagine prompt: a dog and a !!!!!**cat**!!!!

Prompt 3 — /imagine prompt: a cat and a !!!!!**dog**!!!!

Prompt 1 在没有标点符号时,为图像的外观建立基线。它创建了5个tokens。生成的图像描绘了一只没有表情或情感的狗和一只猫。

  • /shorten 分析只是忽略了猫作为重要关键字,这是令人沮丧的。
  • 为了演示标点符号的效果,我修改了prompt符,以包括短语“一张照片”-生成的图像与没有短语的图像相同(未显示图像)。据报道,狗的相对影响值为1,猫的相对影响值为0.6。

Prompt 2 用感叹号和星号填充了prompt。它生成了10个tokens,是prompt1的两倍!动物们现在表现出兴奋的迹象。令人惊讶的是,虽然“猫”这个词被标点符号包围,但狗比猫更兴奋。但摇了几下之后,这只猫也表现出兴奋的迹象。

  • 因为在prompt中没有使用其他词语来描述情感,很明显,标点符号改变了受试者的行为举止
  • 情绪的表现是随机的。偶尔,网格中的大多数图像都描绘了情感。其他时候,每个网格只有一个图像具有情感表达。

Prompt 3和Prompt 2是一样的,除了猫的位置和狗的位置互换了。因为Prompt 2中的狗狗同样兴奋,所以很难说位置的改变是否会让狗狗更开心。Prompt 3生成10个tokens,与Prompt 2相同。

  • 看到 /shorten如何识别感叹号(!!!!!cat)作为重要的tokens而忽略星号是很有趣的。Cat现在的相对值(0.46)低于没有标点符号的prompt符。

img

img

(上) /imagine prompt: a dog and a cat (下) /imagine prompt: a *dog and a !!!!!**cat**!!!!*

img

img

img

/shorten 分析结果. (上) /imagine prompt: a dog and a cat (中) /imagine prompt: a photo of a dog and a cat (下) /imagine prompt: *a photo of a dog and a !!!!!**cat**!!!!*

目前还不清楚我们是否可以针对一个主题,并在其周围使用多个标点符号来让主题“做某事”。

将prompt改为使用更少的感叹号对动物的表达几乎没有影响(图片未显示)。例如:/imagine prompt:a dog and a !cat!

不管周围有没有标点符号,狗狗们都很兴奋。(我还想在第一个图像网格中突出显示图4的6腿猫!)

img

img

(上) /imagine prompt: *a dog and a !!!!!**cat**!!!!* (下) /imagine prompt: *a cat and a !!!!!**dog**!!!!*

另一件需要注意的事情是,在单词周围加上星号将使它在Discord中斜体化。例如,/imagine prompt:dog将斜体/强调dog这个词。然而,不管有没有星号,都没有任何特殊效果。

摘要:标点符号会影响prompt中单词的相对影响力,产生的tokens数量,甚至受试者的行为举止。

(2) 什么时候用连字符,什么时候不用?

连字符是我最喜欢的连接单词的方便工具之一,它可以增加单词之间的联系和影响力。“影响力”指的是这些词在生成的图像中被表达或出现的能力。

Prompt 4 — /imagine prompt: a photo of an **elephant-like** **monster**

Prompt 5 — /imagine prompt: a photo of an **elephant like monster**

假设我们正在寻找具有某些怪物特征的大象,prompt 4的“elephant-like”链接短语比prompt5的结果更好。

根据“/shorten”分析的结果,“monster” token在prompt4中的影响较小,使主题看起来更像大象。

当prompt5中“monster” token的相对影响值增加时,我们得到一个具有大象特征的怪物。

prompt 4生成8个tokens,而prompt 5生成7个。

img

img

(上) /imagine prompt: a photo of an elephant-like monster (下) /imagine prompt: a photo of an elephant like monster

img

img

/shorten分析结果. (上) /imagine prompt: a photo of an elephant-like monster (下) /imagine prompt: a photo of an elephant like monster

什么时候使用连字符

Midjourney中的许多颜色使用连字符。在Midjourney V5 alpha中记录的一种公认的遗留颜色是带有连字符的“olive-green”。

Prompt 6 — /imagine prompt: a photo of a box **olive green**

Prompt 7 — /imagine prompt: a photo of a box **olive-green**

Prompt 8 — /imagine prompt: a photo of a box**, olive-green**

prompt8产生了最好的结果,假设我们正在寻找一个与橄榄无关的绿色盒子。它用逗号把盒子的概念和颜色分开。

prompt6有问题。如果没有连字符,机器人就会生成带有橄榄色和绿色方框的图像。如果这是你要找的,去掉连字符。

prompt7与prompt8非常相似。然而,它偶尔会生成一些绿色盒子和橄榄的图像。如果这就是你所需要的,那么就不需要加逗号了。

prompts6到8分别产生了7、8和9个tokens。标点符号增加了tokens的数量。

img

img

img

(上) /imagine prompt: a photo of a box olive green (中) /imagine prompt: a photo of a box olive-green (下) /imagine prompt: a photo of a box, olive-green

总结:连字符是用来连接单词,以增加他们的联想和影响力。它影响prompt中单词的相对重要性和生成的tokens的数量。

在对prompt进行故障处理时,请考虑添加或删除连字符,并判断生成的结果是否符合要求。

(3) 如果我们用不同的标点符号来区分概念或想法有关系吗?

Midjourney唯一的“官方”概念分隔符是双冒号::。这意味着机器人必须独立考虑概念或想法,而不是将它们结合起来。

双冒号在多提示符中被广泛使用。如果你是多提示和多提示的新手,看看这些故事:Midjourney:多提示的温和指南Midjourney滑块方法:如何通过多提示微调图像

还有其他很少讨论的概念分隔符。为了简单起见,我们将集中讨论逗号和管道符号。(注意:我将在本文中使用管道符号作为“标点符号”,尽管thesaurus.com说它不是。)

`/shorten据说与多提示符不兼容,但我发现它对短的多提示符有些作用。

Prompt 9 — /imagine prompt: a photo of a **honey bee**

Prompt 10 — /imagine prompt: a photo of a **honey, bee**

Prompt 11 — /imagine prompt: a photo of a **honey | bee**

Prompt 12 — /imagine prompt: a photo of a **honey:: bee::**

假设我们只是在寻找蜜蜂(不是蜂蜜),prompt9(没有标点符号)显然是赢家,表明蜜蜂在努力工作。

令人惊讶的是,逗号(prompt10)巧妙地将单词honey和bee分开。网格中至少有一张图像描绘了蜂巢上的蜜蜂。

  • 我曾经认为逗号对概念分离没有任何影响,但这是不正确的。它确实有微妙的影响。这个新信息使我想知道是否应该删除或添加逗号以排除将来的prompts。

双冒号(prompt12)将蜂蜜和蜜蜂的概念分开。它在合成中生成了蜜蜂和蜂蜜/蜂巢的独立图像。分离的概念是显而易见的。(注意:末尾的最后一个双冒号是可选的,但这是我喜欢的编写多提示符的风格。)

Pipe是一个发现,它证明了它可以分离概念,尽管比双冒号更弱、更模糊。

/shorten分析结果表明,标点符号改变了tokens的相对影响值。它支持这样一种看法,即逗号会微妙地影响概念分离,因为其影响值与没有逗号的prompt相似。

如前所述,生成的tokens数量随着使用标点符号的增加而增加。

从整体上看,标点符号的“概念分离强度”由高到低依次为:逗号(最弱)→管道→双冒号(最强)

img

img

(上) /imagine prompt: a photo of a honey bee (下) /imagine prompt: a photo of a honey, bee

img

img

(上) /imagine prompt: a photo of a honey | bee (下) /imagine prompt: a photo of a honey:: bee::

img

img

/shorten分析结果 (上) /imagine prompt: a photo of a honey bee (下) /imagine prompt: a photo of a honey, bee

img

img

/shorten 分析结果. (上) /imagine prompt: a photo of a honey | bee (下) /imagine prompt: a photo of a honey:: bee::

再次确认

考虑到Midjourney中概念分离的重要性,我将调查扩展到另一个主题上——海狮。

Prompt 13 — /imagine prompt: a photo of a **sea lion**

Prompt 14 — /imagine prompt: a photo of a **sea, lion**

Prompt 15 — /imagine prompt: a photo of a **sea | lion**

Prompt 16 — /imagine prompt: a photo of a **sea:: lion::**

实验结果与以往的蜜蜂实验结果一致。除了 / shorten的结果更难以解释。目前还不清楚为什么逗号会对相对影响值产生如此重大的影响。

img

img

(上) /imagine prompt: a photo of a sea lion (下) /imagine prompt: a photo of a sea, lion

img

img

(上) /imagine prompt: a photo of a sea | lion (下) /imagine prompt: a photo of a sea:: lion::

img

img

Results of /shorten analysis. (Top/Left) /imagine prompt: a photo of a sea lion (Bottom/Right) /imagine prompt: a photo of a sea, lion

img

img

/shorten分析结果. (Top/Left) /imagine prompt: a photo of a sea | lion (Bottom/Right) /imagine prompt: a photo of a sea:: lion::

我还测试了使用连字符和加号+的效果。这里没有显示生成的图像,因为没有什么特别的期望。

不出所料,连字符很好地连接了这些想法。加号对概念分离的影响可以忽略不计,但改变了/shorten 分析中的相对影响值。

摘要:最强的概念分隔符是一个双冒号,后跟一个管道和一个逗号。逗号在分隔prompt中的概念方面有微妙的作用。该管道可能具有用于分离概念的新应用程序,作为多提示符的替代方案。尚不清楚该管道是否受控制多提示符的相同规则的约束。

img

img

/shorten 分析结果. (Top/Left) /imagine prompt: a photo of a sea-lion (Bottom/ Right) /imagine prompt: a photo of a sea + lion

(4) 机器人能理解由标点符号组成的表情符号吗?

最后,让我们看看机器人是否能理解一些完全由标点符号(没有单词)组成的表情符号。

Prompt 17 — /imagine prompt: {:-), :-(, ;-), :-/, :-O, X-(}

以下是经过测试的简单表情符号列表:

:-)
:-(
;-)
:-/
:-O
X-(

你猜怎么着?机器人只能理解 :-( 悲伤的表情符号。其他的表情符号都不起作用。

嘿,Midjourney机器人,你现在不开心吗?是因为我们给你太多工作要做吗?

Images of sad people.

/imagine prompt: :-(

原文:Midjourney: The Ultimate Guide to Punctuation


目前正在接受试用中!!!

请将您的称谓、公司名称和使用场景,发邮件到yuanwai@mengjia.net。

也可以直接加微信:lxdhdgss 咨询

更多详情,可查看文章:TorchV Bot开始对外试用了!


最新内容,关注“土猛的员外”公众号

为什么是奥本海默,成为“之父”需要哪些能力

obhm

上周去看了诺兰的《奥本海默》,说真的,要深刻了解这个片子,没有一些辅助的资料还是很难的,特别是当时的背景和时局发展,后半段对奥本海默的审批,以及各种闪现的配角(诺贝尔奖得主)。当然,本篇不想过多解读审判这条主线,更多想说说研发原子弹的庞大工程——曼哈顿计划的主持人为什么是奥本海默,他有什么过人之处,以及我们可以学到什么。

为了把这个问题讨论清楚,我们还是分四个章节来讲,分别是:

  • 曼哈顿计划的历史背景——先把整体的情况捋一下;
  • 为什么是奥本海默——选他的原因,以及他如何成功;
  • 我们学到了什么——对于创新型产品研发的启示;
  • 说说第二主角格罗夫斯——管理的艺术。

一、曼哈顿计划背景

为了让大家可以对整体的背景有一些了解,这一章节会先简要介绍背景和数据。

起因

原子弹工程的起因是1939年德国科学家哈恩和斯特拉斯曼发表了铀原子核裂变的论文,很短时间内,世界各国科学家在自己的实验室复现了该实验,并且发现可以实现链式反应,极其微量的铀235就可以释放出巨大能力。由于当时英法已经对德宣战,二战的大规模战争开始,于是这马上引起了科学界的警觉,匈牙利赴美的科学家齐拉得·莱奥呼吁大家警惕这种全新的科技会被用于战争。果不其然,德国任命量子力学奠基人之一海森堡开始了原子弹研究。

2

电影剧照:爱因斯坦和奥本海默

在美国这边,爱因斯坦(不用介绍了)和西伯格(“钚之父”,诺贝尔化学奖)给当时美国总统罗斯福写了一封倡议研发原子弹的信,希望总统下令全力研制核武器——德国人已经在海森堡的主持下率先开始了工作,如果这种超级炸弹掌握在泯灭人性的纳粹手里,那将是谁也不敢想象的一种结局。而后万尼瓦尔·布什(著名科学家、香农的导师,互联网、鼠标、图形界面等一系列产物的原始提出者)作为总负责人发起了原子弹制造计划。军方派出的总指挥是格罗夫斯准将(Leslie R. Groves),当时他刚建造好五角大楼,在曼哈顿项目中属于万尼瓦尔的下属。此人的能力非常强悍,而且难得可贵的是他积极满足项目的各种需求,但几乎不干预后来科学家们的具体工作,设置包括一些人事任命。

奥本海默加入

最初参与该项目的科学家是与奥本海默同在加州大学伯克利分校任职的欧内斯特·劳伦斯(回旋加速器发明人、诺贝尔物理学奖获得者)和芝加哥大学的阿瑟·康普顿(“康普顿效应”发现者,诺贝尔物理学奖获得者),但他们极力向格罗夫斯推荐更加才智卓越的奥本海默。奥本海默在参加曼哈顿计划之前就已经有多年的左翼活动,而且妻子、情人、弟弟全是美国共产党,这也是后来他最大的麻烦。但是格罗夫斯的厉害之处是守住安全底线的前提下,不问出身,只看是否可以为计划带来决定性贡献。于是奥本海默成为了整个曼哈顿计划的首席科学家,任职洛斯·阿拉莫斯实验室(曼哈顿计划总部)的主任,负责整个研发工作。

诺贝尔奖得主集中营

整个研发过程集聚了大量人员,巅峰时达到50余万,且其中大量科学家,诺贝尔奖(很多是之后获得)得主近百人,特别是洛斯阿拉莫斯实验室,也被称为“诺贝尔奖获得者集中营”。

除了上面提到的,还有玻尔(和爱因斯坦齐名)、费米(中子物理学之父,诺贝尔物理学奖,建成第一座原子反应堆)、查德威克(发现中子、诺贝尔物理学奖得主)、阿尔瓦雷茨(诺贝尔物理学奖得主)、费曼(物理学家、数学家,诺贝尔物理学奖获得者)、尤金·维格纳(诺贝尔物理学奖得主)、爱德华·泰勒(氢弹之父)、冯·诺依曼(计算机之父)等。

feimi

芝加哥大学费米团队建造出世界上第一个核反应堆

曼哈顿工程可能是人类历史上首个三位一体工程,既科学、军事和工业三位一体。而且可能也是在科技时代最大最复杂的工程之一。

为什么是奥本海默,他为什么可以成功

介绍了大致背景,上面的阵容应该已经空前强大了。那么,为什么,没有诺贝尔奖的奥本海默会被选为研发原子弹的总负责人呢?(事后诸葛亮般的总结

先来看看当时推荐他的欧内斯特·劳伦斯是怎么评价他的:

“曼哈顿工程”是一个要凝聚全世界最顶尖大脑的“超级工程”,但越是一流的科学家,就越是有些“恃才傲物”,必须要有一个既懂科学又懂管理的人才来把这批人管理起来,有效运转,最快达成目标。

既懂科学又懂管理,是劳伦斯的主要观点,这里其实跟重要的是“懂科学”,因为参与曼哈顿计划的都是一些什么人,大家在上面已经看到了。但是通过《奥本海默传》等书籍可以看出,之所以科学家们推举他,还有很多其他重要的原因,反而学术能力只是一种底线,而不是真正的原因。

那么我们来看看到底是哪些原因促成了他,并且领导整个项目顺利完成。

学术能力

奥本海默本身就是天才,在剑桥卡文迪许实验室学习过,当时的主任是大名鼎鼎的卢瑟福(弟子中有29名诺贝尔奖得主),后又在哥廷根大学(当时世界上最顶级学府)获得博士,师从量子力学奠基人之一的马克思玻恩。在理论天文学、核物理、光谱学和量子场论(包括量子电动力学)等方面都做出了优秀成果,而且预测了“黑洞”的存在。所以他在学术能力是可以和这些参与者一起共事的,甚至在当时,他在学术上比一些参与者还要更领先(因为一些参与者获得诺贝尔奖是在曼哈顿计划之后)。

lusehu

物理神话卢瑟福,一众大神的老师

讲故事能力

他有超强的讲故事能力。

他来到加州大学伯克利分校之后,在课堂总能把深奥的天文学、物理学知识通过让人印象深刻的故事讲述出来,所以他的学生众多,且非常受欢迎。这一点在领导曼哈顿工程时尤为重要,他在不同地点和不同时间,至少与3000人进行过工作沟通。没有这种深入浅出的讲故事和刻画的能力,很难让大家明白并统一意识。相信也是基于这一点,让当时很多科学家觉得奥本海默有一种“看见”的能力,并可以通过交流让大家共同“看见”,这是推荐他来当总负责人的原因之一。

“看见”的能力

在电影里面还提到了他经常睡不着,因为脑子停不下来,一直在播放各种运算的画面。这一点特质也非常重要,甚至我觉得在这个项目中是最重要的。因为要完成这样一个工程,他需要首先在脑子里有一个完整的蓝图,他首先要“看见”最终的样子。

然后脑子里有一张庞大繁杂的思维导图,上面动态地描绘着发展的情况:从总目标,到一级、二级、三级…目标是什么,每个环节的功能和时间节点,现在进展到哪里,哪里可能是难点…。首先要自己“看见”,才能让大家一起看见(虽然当时不能让大家一起看见,因为需要保密,50万人里面只有12人知道全盘计划)。

siweidaotu

“看见”是管理的基础,如果无法“看见”,那根本无法从全局视野推动事情的进展。其实同在曼哈顿计划的很多杰出人才在这方面也是对奥本海默非常佩服的,可以看看和他不太对付的“氢弹之父”泰勒是怎么说的:

“我不知道奥本海默是怎样做到这一切的,但是没有他的话,这项工程不知道什么时候能成功。”

系统工程

3

电影剧照:奥本海默在洛斯阿拉莫斯

曼哈顿工程的复杂度,哪怕放到现在,依然可以排在世界上五大最复杂的工程之列:
整个工程分布在16个地区进行,其中最重要是4个:

  • 费米和康普顿领导的芝加哥大学第一个原子核反应堆;
  • 在田纳西的核反应材料工厂,代号“橡树岭”,提炼铀235,8.2万人;
  • 西伯格的汉福德钚提炼工厂,6万人;
  • 奥本海默的洛斯阿拉莫斯实验室,总指挥部和组装原子弹。

Y12

橡树岭Y-12工程

在这么广大的区域,在如此多人员参与的情况下,虽然有军方的各种保障,但是管理难度依然非常大。所以在管理过程中,奥本海默运用了运筹学、控制论、信息理论、基础数学和计算机科学等学科的经验,以寻找最优解为目标出发,对组织、技术、行为和方法进行了科学的综合应用。这也在后来催生了“系统工程”学科的诞生。

语言能力

奥本海默除了学术能力,还有一些非常特殊的能力。比如他熟练掌握八门语言,包括梵语。在原子弹试爆成功之后,他用常读的印度梵文诗《摩诃婆罗多经》中的《福者之歌》选段说了一段:

“漫天奇光异彩,有如圣灵逞威。
只有一千个太阳,才能与其争辉。
……
我是死神,是世界的毁灭者。”

yuanzidan

第一颗原子弹试爆

面对多国科学家组成的大团队,拥有多国语言能力同样也是一项重要特质。

我们可以学到什么

曼哈顿工程可以算得上一个高科技产品研发项目,我们把焦点放会到自己手上的事情,也会发现如果我们作为一个owner去做一件创新的事情,同样需要这些品质,才能有效地把事情做好。

通过上面的描述,我认为要带领一个创新产品的研发,需要有以下几种能力:

  • 有扎实的技术和产品能力:这是基础能力,技术和产品,最低限度是要精通一样吧。有了这个能力,才能和共同参与的成员进行沟通,才能有整体的思考基础;
  • 有“看见”的能力:这是非常核心的能力,对于要去创造的产品,你心中必须要有一个蓝图,而且是非常清晰的,不能朦朦胧胧,这样你才能清晰知道团队的方向在哪里,还需要往前走多少路程。“看见”之后,你必须分解达成需要做的事务,一般可以分成多级事务,每个事务都会有目标、动作、组成人员和其能力,以及过程进度。这样才能搭建组织,寻找能力匹配的人员,分配工作,检查工作完成度和质量。这里需要去学习一些系统工程的方法,让自己在管理上更加科学。当然,你也可以在电脑上用XMind、Focus等软件进行管理;
  • 讲故事的能力:其实是一种非常优秀的沟通能力,而且可以将复杂的业务逻辑非常清晰、生态地同步给同伴,重点是让别人可以理解。只有将“蓝图”与团队同事分享,让他们共同看见,才能形成合力完成目标,也就是上下同欲者胜。

当然,如果你是在主导一个面向市场的产品,你可能还需要一些额外的但也同样重要的能力:

  • 需要懂PMF:PMF(Product-Market-Fit)要研究的是产品价值和市场需求是否匹配的问题,这是成功的产品必须要有的条件。这就需要你也有市场能力,有一些客户人脉,能和客户去交流MVP(最小可用品)的价值,并对市场反馈非常敏感。诚然,找到PMF是非常难的,有时候还需要一些运气,但你必须要有这种意识,并了解实现它的一些方法;
  • 产品推广能力:一个研发中的产品,很多时候都是需要在它完成前就进行推广的。这同样需要讲故事的能力,你不需要把所有特性都一一讲出来,有时候需要将它的一两个点拿出来放大。对于会讲故事的人,这并不难,因为我看见过几个讲故事很厉害的人,有时候即使他们完全没参与产品的研发过程,一样可以快速提炼价值点,并打动客户。

好吧,也许你会认为这样的人几乎很难找,是的,但这正是你的竞争力所在啊。被冠以“之父”的人,必须是要有这些能力的,而且要有“主人翁”心态,哪怕你明明知道产品最终是属于公司的,哈哈。

最后,说说管理

你也许会想,那我不会技术和产品,是不是就已经没有这个机会了。那也不是的,你看看格罗夫斯,他确实是个很厉害的人。他的能力在于知人善任,哪怕知道奥本海默有共产主义倾向。而且在奥本海默的一些用人上,他虽然不太乐意,但是依然不干涉。整部影片,从组件核心团队,到推进,到完成结果,处处可以看到他优秀的管理能力(马特达蒙饰演的效果是,一本正经的时候反而有一点幽默)。

geluosifu

格罗夫斯的另一个具体贡献是在保障上,在资源上让奥本海默无后顾之忧。这真的太重要了,别认为这些事情是奥本海默自己应该去争取,我觉得这些事情如果是奥本海默需要耗尽心机去想办法搞定的,那项目不可能顺利推进。原因无非有二:一,权限不够,虽然奥本海默已经K-6最高等级,但是仅限于研发团队,对于军方人员、大量劳动力、经费和国土资源依然没有办法调动;二、一个人需要耗费大量精力在思考项目推进的情况下,是不太可能有更多精力去思考人和人之间、信念之间的“斗争”的。

最后就是格罗夫斯很知道自己该站的位置,不会去干涉具体工具,不会想着要在原子弹工程上留下自己的印记,比如需要加点什么特性,应该长什么样子等等。这一点我也是这个态度,如果我在这个位置,除非负责人需要征求我的意见,不然我不会去强加我的思想,因为很多时候产品是一种创意,不太可能在“民主”投票中产生。

sitelaos

钢铁侠饰演的刘易斯·施特劳斯

格罗夫斯和奥本海默一样,都是优秀的管理者,而且都是业务管理者,他们的特点是善于目标管理,在用人上更看重人的优点。作为区别,电影后期的施特劳斯(小罗伯特唐尼饰演)更像是行政管理,他们更在意的是意识形态、文化,重点在发现人的缺点或者危险。

所以,如果把曼哈顿工程比作一部电影,那么格罗夫斯就是总监制,奥本海默是导演,上面的万尼瓦尔·布什就是制片人。没有技术和产品背景,你依然可以成为格罗夫斯。

好了,就写到这里!


目前正在接受试用中!!!

请将您的称谓、公司名称和使用场景,发邮件到yuanwai@mengjia.net。

也可以直接加微信:lxdhdgss 咨询

更多详情,可查看文章:TorchV Bot开始对外试用了!


最新内容,关注“土猛的员外”公众号

用AI(大模型)重构推荐系统

AI助手的崛起

人工智能正在改变我们与在线应用程序互动的方式。目前,我们使用搜索引擎、新闻源和精心设计的菜单来导航,这些菜单引导我们找到所需的信息或服务。然而,我相信目前人工智能的创新使一种新型的推荐引擎成为可能:人工智能助手。随着Chat-GPTBard的出现,我们已经看到了这方面的证据。但是,让我们考虑一个示例来进一步说明这一点。想象一下,你正在伦敦度假,你想和一些朋友在格林威治公园野餐。在你决定日期之前,你可能会通过谷歌搜索或直接找到你喜欢的天气预报服务。接下来,您将浏览他们的站点并检查所选日期范围内的天气预报,根据最有利的天气选择一天和时间。

img

格林威治公园

如果你直接问不是更简单吗?“哪天去格林威治公园野餐最好?”

不需要搜索谷歌,不需要选择你的日子。如果它与语音助手相连,你可能甚至不需要输入任何东西,你只需要从你信任的人工智能天气助手那里得到一个建议,告诉你安排旅行的最佳日期。

在本文中,我将演示如何使用从Open AILangchain ‘s SQL Database ChainOpen Weather Map API调用的函数来实现这一点。

请注意下面的动图,展示了我在实际中开发的原型

The first shows the response to “What’s the best day to have a picnic in Greenwich park?”(第一个是对“在格林威治公园野餐最好的一天是哪天?”)

img

这是一个温和的例子,说明了什么是可能的。让我们尝试一些更复杂的方法。如果我们去冰岛旅游,想看北极光呢?我们可能会问:“When am I most likely to see the Northern Lights in Reykjavik?(我什么时候最有可能在雷克雅未克看到北极光?)”

如果您对此印象深刻,请继续阅读,我将解释它是如何工作的。

(简化的)应用架构

img

首先,我想通过提供我认为将为这些人工智能助手提供动力的架构类型的广泛而直接的概述来建立背景。

他们将使用大型语言模型 (LLM)函数调用、API请求和对结构化数据集的自动查询来向用户提供个性化的响应。

随着生态系统的成熟,这个也会成熟,但我相信一般的方法将保持不变——只是增加一些额外的功能。

这是我用来构建AI天气助手原型的通用架构,所以让我们深入了解一些技术细节,以获得更好的理解。

函数调用

在llm出现之前,解析文本需要使用Regex——它非常严格,限制了我们使用自然语言所能做的事情。

现在有了llm和函数调用,我们可以更灵活地操作自然语言。让我们检查一下函数调用本身,以理解为什么它如此强大。

在我们的AI天气助手示例中,应用程序的用户希望确定访问特定地点的最佳日期,可能是为了参加活动。

因此,我们需要三个关键的信息:地标/目的地、它的坐标(纬度、经度)和未来一段时间的天气预报。

一旦知道了地标/目的地,后两者就很简单了。但是,前者是从用户提供的自由格式文本输入派生出来的。

由于拼写错误、大小写不一致和语法错误,或者目的地可能只能通过上下文推断,因此从自由文本中确定目的地是具有挑战性的。

然而,这正是函数调用被证明是无价的地方。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from geopy.geocoders import Nominatim
import pandas as pd
import requests
import uuid

# gets latitude and longitude
def get_lat_long(location):
geolocator = Nominatim(user_agent="my_application_" + str(uuid.uuid4()))
location = geolocator.geocode(location)
return (location.latitude, location.longitude)

# gets weather data for the enxt five days - returns a dataframe
def get_weather(location_response, location):
api_key = YOUR_OPEN_WEATHER_MAP_API_KEY # Replace with your API key from Open Weather Map
base_url = "https://api.openweathermap.org/data/2.5/forecast"
params = {
'lat': location_response[0], # latitude
'lon': location_response[1], # longitude
'appid': api_key,
'units': 'metric' # change 'metric' to 'imperial' for Fahrenheit
}
response = requests.get(base_url, params=params)
weather_data = response.json()
df = pd.json_normalize(weather_data['list']).drop(columns='weather')
df['location'] = location

return df

我们首先定义检索天气数据的函数。我们有两个独立的函数。

第一个方法接受位置作为非特定输入,并返回纬度和经度。

第二个方法接受纬度、经度和位置,并通过调用Open weather Map API返回一个包含该位置未来五天天气数据的数据框。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import openai
import pandas as pd
import json

def parse_location(query):

# OpenAI function calling

function_call = [
{
"name": "get_lat_long",
"description": "Takes the location as an argument. Returns a tuple (latiude, longitude)",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": '''Do not answer the question. Only respond with the location, or the location of the landmark/tourist attraction mentioned.
Location must be in the form City name, state code (only for the US) and country code divided by comma.
Please use ISO 3166 country codes.'''
}
},
"required": ["location"]
}
}
]

# Open AI API Call
openai.api_key = YOUR_OPEN_AI_API_KEY # Replace this with your openAI API key

message = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "system", "content": query}],
functions = function_call,
function_call = 'auto',
temperature=0
)

arguments = message["choices"][0]["message"]["function_call"]["arguments"]
arguments_dict = json.loads(arguments)
location = arguments_dict['location']

print(f"LOCATION!: {location}")

return location

接下来,我们设计函数调用。这里我们感兴趣的函数是我们之前定义的get_lat_long函数,它以location作为参数。我们在函数调用字典中的name键中建立它。

真正的“神奇”发生在parameters键下,我们通过其属性定义参数。

该描述尤其重要,因为它使我们能够利用大型语言模型的预测属性来帮助从查询中识别位置。

例如,如果用户询问:“参观埃菲尔铁塔的最佳日期是哪天?”,我们将收到以下回复:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<OpenAIObject chat.completion id=chatcmpl-7byJmyUNMNeYIIQhrBQ295u4JqM4C at 0x1f654544680> JSON: {
"id": "chatcmpl-7byJmyUNMNeYIIQhrBQ295u4JqM4C",
"object": "chat.completion",
"created": 1689284354,
"model": "gpt-4-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "{\n \"location\": \"Paris, FR\"\n}"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 124,
"completion_tokens": 12,
"total_tokens": 136
}
}
}
],
"usage": {
"prompt_tokens": 132,
"completion_tokens": 19,
"total_tokens": 151
}
}

我们可以看到函数调用返回了Paris, Fr作为我们的位置。这里的诀窍是,我们利用模型的强大功能,直接从查询中推断出埃菲尔铁塔的位置。

在这个关键时刻,我应该提出一个警告:虽然这个技巧到目前为止表现良好,但llm不是数据库查找,它们可能会产生幻觉并推断出错误的位置。

为了提高健壮性,可以加入一个步骤,将位置与数据库交叉引用。虽然我没有对错误率做过任何数学计算,但大多数时候,这个模型都是正确的,特别是如果你使用GPT-4以后的版本。

一旦确定了位置,我们就可以继续获取纬度和经度,最终从Open weather Map返回用户指定位置的结构化天气数据。

Langchain SQL数据库链

创新的第二部分是朗链的SQL数据库链。调用API之后,我们就有了一些结构化的天气数据。

我们可以利用Langchain的SQL数据库链来自动查询。下面是相应的代码片段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from sqlalchemy import create_engine
import openai
import pandas as pd
from langchain import OpenAI, SQLDatabase, SQLDatabaseChain

# load data in memeory to sql lite database
def load_data(df):
engine = create_engine('sqlite:///:memory:')

# Write the data to the SQLite database
df.to_sql('weather', engine, if_exists='replace', index=False)

# Check if the data was loaded correctly
df_loaded = pd.read_sql('SELECT * FROM weather', engine)
db = SQLDatabase(engine)
return db

# run langchain sql database chain
def run_query(query, db):
openai_token = YOUR_OPENAI_KEY
llm = OpenAI(temperature=0, verbose=True, openai_api_key=openai_token)
db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True, use_query_checker=True)
response = db_chain.run(query)
return response

Note: 我对SQL数据库链使用的一个小提示工程技巧是要求模型解释它的选择,我发现这样做会产生更好的响应。这只需使用f字符串即可完成。

1
2
3
query = "What's the best day to visit the Eiffel Tower for the best view of the city?"
query_1 = f"{query} Return an explanation alongside your response, and a description of the relevant weather conditions"

SQL数据库链将自然语言请求转换为SQL查询,并在结构化天气数据上执行该查询。

让我们回想一下雷克雅未克的例子。SQL数据库链生成的SQL查询是这样的:

img

SQL数据库链能够进行一些分析推理。它可以接受用户提交的请求并基于它生成SQL查询。

通过检查SQL查询,我们可以辨别模型用来生成响应的逻辑。看看你是否相信它与反应一致。

人工智能天气助手原型可供你自己玩。你需要一个OpenAI API密钥来让它工作并批准使用GPT-4,不幸的是,该模型不能与GPT-3.5一起工作。

总结

我相信专业的人工智能助手将在众多服务行业中变得越来越普遍。

采用这些更无缝的人工智能替代方案的公司可能会从一些采用传统菜单或基于搜索的选项的公司那里抢夺市场份额。

我可以想象这样一个未来,我们与人工智能助手互动,帮助我们预订机票、安排住宿、计划约会、组织我们的财务生活——这个清单是无止境的。然而,仍有许多问题需要解决。

  • 延迟相当高,特别是考虑到我们已经习惯了即时请求和接收信息。

  • 用户体验设计是另一个将被证明是关键区别的领域。目前,许多人工智能应用程序感觉很麻烦,但用户体验将得到改善,并将成为用户采用背后的关键驱动力之一。

  • 一致性很难实现。大多数情况下,模型会返回相同的结果,但偶尔也会给出不同的建议。对于期望一定程度的确定性的用户来说,这可能是一个问题。

  • 调用多个api的成本限制了高价值用例的商业可行性。

原文:Reimagining the Recommendation Engine


目前正在接受试用中!!!

请将您的称谓、公司名称和使用场景,发邮件到yuanwai@mengjia.net。

也可以直接加微信:lxdhdgss 咨询

更多详情,可查看文章:TorchV Bot开始对外试用了!


最新内容,关注“土猛的员外”公众号

使用AI(大模型)进行文档自动化处理

手工文档处理

随着所有人工智能创新的发生,人们很容易忘记,人们的工作的许多方面仍然是手工和繁琐的。这种单调的工作很大程度上源于重复的文档处理。在一家银行工作期间,我的一位前股东(风险经理)被大量手工文档处理任务淹没。她会花时间浏览冗长的基金招股说明书,以识别招股说明书中的关键信息,并将其转换为Excel电子表格(用于记录保存和下游分析)。

我预计许多读者将遇到类似的工作负载。因此,在本文中,我将介绍一种使用大型语言模型和检索管道自动化此类工作负载的简单方法。为了给您提供一个现实的用例,我用Morgan Stanley Funds UK的基金招股说明书来演示这一点,这是一份164页的公开文件,提供了他们一些基金的信息。这与风险经理可能会看到的招股说明书类型类似。我们将从招股说明书中提取并记录以下信息:

  • FCA产品参考编号: 6位数字,用于识别基金。
  • 基金名称: 基金名称。
  • 投资目标: 基金的目标,例如在10年内增加投资。
  • 投资政策: 基金经理制定的投资规则。
  • 投资策略: 基金经理的投资“哲学”。
  • ESG: 如果基金正在追求ESG战略。

看看下面的演示,让你更好地理解我们将做什么。

img

演示从基金招股说明书中提取信息的管道

我之所以选择这个例子,是因为我知道它与许多银行业人士息息相关。然而,这种方法可以很容易地转移到具有类似工作量的其他领域,包括保险、法律、测量、医学等。

库和先决条件

使这个例子为您工作所需的主要库是OpenAIHaystackPandashugs Face中的句子变形器。对于OpenAI,你需要注册一个API密钥——如果你还没有,你可以遵循这个教程

How to Build

在继续之前,看一下这个显示流程的高级架构图。下一节将解释图表上的每个过程。

2

Step 1 — 查询

这里的查询只是来自用户(或我们的示例中的风险管理人员)的请求。经理可能会问这样的问题:“我需要就全球可持续发展基金(Global Sustainability Fund)做报告。

Step 2 — 预处理

我们正在处理一份大型招股说明书(168页文本),需要对其进行预处理并存储以供下游使用。预处理分为两个阶段:

  1. 读入并重新格式化:我们需要把我们的招股说明书分成更小的块或句子,我们称之为文档。我们可以利用Haystack中的“开箱即用”函数来实现这一点。只需指出[convert_files_to_docs] (https://docs.haystack.deepset.ai/reference/utils-api convert_files_to_docs:文本=模块预处理- convert_files_to_docs, python: ~:文本=模块预处理- convert_files_to_docs, python)招股说明书的存储位置和初始化函数(预处理)(https://docs.haystack.deepset.ai/reference/preprocessor-api::文本=模块预处理,预处理,python: ~:文本=模块预处理,预处理,python)对象与我们文档拆分要求,我们可以轻松地将招股说明书重新格式化为更小、更易于管理的块。
  2. 转换和存储:模型实际上并不解释单词;他们解读数字。因此,我们利用句子嵌入模型将我们的句子转换为密集向量(即,保留句子语义结构的数值表示)。我们利用了一个来自hug Face句子转换器库的预训练的句子嵌入模型all-mpnet-base-v2来做到这一点。一旦我们有了嵌入,我们需要用FAISS对它们进行索引。我们还将文档和相关元数据以文本格式存储在SQL Lite数据库中。Haystack提供了一个API [FAISSDocumentStore](https://docs.haystack.deepset.ai/reference/document-store-api#faissdocumentstore:~:text=Module faiss-,FAISSDocumentStore,- python),使我们能够索引嵌入并将文档存储在磁盘上,以便稍后检索(我们将在下一节讨论检索)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from haystack.nodes import PreProcessor
from haystack.utils import convert_files_to_docs
from haystack.document_stores import FAISSDocumentStore
from sqlalchemy import create_engine
from haystack.nodes import EmbeddingRetriever

# pre-process docs
def preprocess_docs(doc_dir):
all_docs = convert_files_to_docs(dir_path=doc_dir)
preprocessor = PreProcessor(
clean_empty_lines=True,
clean_whitespace=True,
clean_header_footer=False,
split_by="word",
split_respect_sentence_boundary=True,
split_overlap=30,
split_length=100
)
docs = preprocessor.process(all_docs)
print(f"n_files_input: {len(all_docs)}\nn_docs_output: {len(docs)}")
return docs

# create FAISS and store
def vector_stores(docs):
engine = create_engine('sqlite:///C:/Users/johna/anaconda3/envs/longfunctioncall_env/long_functioncall/database/database.db') # change to your local directory
try:
# Attempt to drop the table
engine.execute("DROP TABLE document")
except Exception as e:
# Catch any exceptions, likely due to the table not existing
print(f"Exception occurred while trying to drop the table: {e}")

document_store = FAISSDocumentStore(sql_url='sqlite:///C:/Users/johna/anaconda3/envs/longfunctioncall_env/long_functioncall/database/database.db', faiss_index_factory_str="Flat", embedding_dim=768) # change to your local directory
document_store.write_documents(docs)

return document_store

def generate_embeddings(document_store):
retriever = EmbeddingRetriever(
document_store=document_store,
embedding_model="sentence-transformers/all-mpnet-base-v2"
)
document_store.update_embeddings(retriever)
return retriever

接下来的两个步骤定义我们的管道,它由两个节点组成:一个检索器和一个定制的OpenAI函数调用节点。

Step 3 — Retriever

检索节点利用FAISS在文档的句子嵌入和表示用户查询的句子嵌入之间执行相似性搜索(回想一下,我们用FAISS对句子嵌入进行了索引)。根据相似度评分,检索节点返回与我们的查询相似度最高的前k个文档。从本质上讲,检索使我们能够有效地从冗长的基金文档中搜索和隔离相关部分。如果您尝试处理整个168页的文档,您会发现您将很快超过任何大型语言模型的最大上下文长度(在撰写本文时)。

*注意:研究 *表明,大型语言模型,即使是那些具有显式长上下文窗口的语言模型,在没有检索的情况下对这些文档进行操作时,其性能也会下降

Step 4 — OpenAI函数调用

对于那些不熟悉函数调用的人,您可以将其视为使用OpenAI的大型语言模型构建非结构化文本数据的一种方式。有一些非结构化文本作为输入,函数调用返回结构化JSON输出。阅读我的关于函数的文章,深入了解细节。函数调用将从检索器返回的k个最相关的文档作为输入。在函数调用中,我们将希望从招股说明书中提取的关键信息定义为提示符。

我们必须足够精确地使用这里的提示来引导大型语言模型提取正确的信息。该函数调用由OpenAI的gpt -3.5 turbo驱动,可以根据我们的提示,利用其推理能力识别并记录关键信息。

最后,函数调用返回一个JSON,其中包含我们要求它提取的键细节,记录为参数。从这里开始,将这些写入DataFrame非常简单。

注意:函数调用不能作为Haystack中的节点使用,因此必须通过创建自定义组件来创建该节点。下面的脚本向您展示了如何实现这一点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import openai
from haystack.nodes.base import BaseComponent
from typing import List
import json

class OpenAIFunctionCall(BaseComponent):
outgoing_edges = 1
def __init__(self, API_KEY):
self.API_KEY = API_KEY

def run(self, documents: List[str]):

try:
document_content_list = [doc.content for doc in documents]
print("documents extracted")
document_content = " ".join(document_content_list)
except Exception as e:
print("Error extracting content:", e)
return
functions = [
{
"name": "update_dataframe",
"description": "write the fund details to a dataframe",
"parameters": {
"type": "object",
"properties": {
"Product_reference_num": {
"type": "string",
"description": "The FCA product reference number which will be six or seven digits"
},
"investment_objective": {
"type": "string",
"description": "You should return the investment objective of the fund. This is likely to be something like this: The Fund aims to grow your investment over t – t + delta t years"
},
"investment_policy": {
"type": "string",
"description": "Return a summary of the fund's investment policy, no more than two sentences."
},
"investment_strategy": {
"type": "string",
"description": "Return a summary of the fund's investment strategy, no more than two sentences."
},
"ESG": {
"type": "string",
"description": "Return either True, or False. True if the fund is an ESG fund, False otherwise."
},
"fund_name": {
"type": "string",
"description": "Return the name of the fund"
},
},
},
"required": ["Product_reference_num",
"investment_objective",
"investment_policy",
"investment_strategy",
"ESG",
"fund_name"]
}
]

openai.api_key = self.API_KEY
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo-0613",
messages=[{"role": "system", "content": document_content}],
functions=functions,
function_call="auto", # auto is default, but we'll be explicit
)

function_call_args = json.loads(response["choices"][0]["message"]["function_call"]["arguments"])

return function_call_args, "output_1"

def run_batch(self, documents: List[str]):
# You can either process multiple documents in a batch here or simply loop over the run method
results = []
for document_content in document_content:
result, _ = self.run(document_content)
results.append(result)
return results, "output_1"

一旦定义了自定义函数调用,将其与管道中的检索器结合在一起就很简单了。

1
2
3
4
5
6
7
8
from haystack import Pipeline
from function_call import OpenAIFunctionCall

def create_pipeline(retriever, API_KEY):
p = Pipeline()
p.add_node(component=retriever, name="retriever", inputs=["Query"])
p.add_node(component=OpenAIFunctionCall(API_KEY), name="OpenAIFunctionCall", inputs=["retriever"])
return p

这个Github库可供您探索;有一个笔记本和一个带有Streamlit前端的原型版本。

结论

这种方法非常有效;然而,本演示是为本基金招股说明书设计的。在实际的业务用例中,每个招股说明书可能使用不同的术语或应用不同的标准。尽管大型语言模型在这种情况下往往是健壮的,但我怀疑您将不得不以更复杂的方式设计流程来处理细微差别。我所展示的是,将函数调用与检索相结合可以提供大量自动化可能性,这些可能性相对容易实现。

原文:Automate Tedious Document Processing


目前正在接受试用中!!!

请将您的称谓、公司名称和使用场景,发邮件到yuanwai@mengjia.net。

也可以直接加微信:lxdhdgss 咨询

更多详情,可查看文章:TorchV Bot开始对外试用了!


最新内容,关注“土猛的员外”公众号