在GPT和类似的大语言模型中,文本被切割成称为"tokens"的小单位进行处理。一个token可以是一个字符,也可以是一个单词,这取决于分词策略。GPT模型有一个最大token限制,表示模型能够处理的最大输入长度。这个限制是由模型的架构和超参数决定的,它是为了平衡模型的计算复杂性和资源消耗而设定的。
Token 限制包括了输入和输出,也就是你在一次对话中提交给 ChatGPT 的内容和 ChatGPT 输出的内容不能超过模型规定的 Token 数量。比如 ChatGTP 3.5 的 Token 限制是 4096,ChatGPT 4 的 Token 限制是 8192。以后可能会支持的Token 数更高, 但我们比较复杂的问题时, 往往很轻易就能超过这个上限。
ChatGPT阅读理解和逻辑能力是比较好的, ChatGPT刚出来我就想过, 如果我输入一本书的内容给他会怎么样?把整个项目的源码全部给他,让他根据需求改代码会怎么样?把一个技术文档给他, 让他根据需求写代码会怎么样。。。
后来发现是不现实的, 会有token限制。其实还有很多场景需要解决这个token限制,也就是长文本问题。
下面就从几个思路看看怎么解决超长文本限制的问题。
压缩法
在处理token限制之前, 先明白 tokens 咋回事
先看看OpenAI官方的介绍:
什么是代币以及如何计算它们?
https://help.openai.com/en/articles/4936856-what-are-tokens-and-how-to-count-them
OpenAI 官方的 Tokenizer 可以用于计算内容的token数。
https://platform.openai.com/tokenizer
在官方的 Tokenizer网站输入中文"我爱你"和英文"i love you"对比一下
tokens 不是指 prompt 字符串的长度,token指的是一段话中可能被分出来的词汇。比如:i love you,就是三个token,分别为 「i」「love」「you」。
不同语言token计算不一样,比如中文的「我爱你」其实是算 5 个 token,因为它会先把内容转成 unicode。
简单来说就是tokens是文本的一部分,不一定和单词对应,它们的数量取决于文本的长度和语言。tokens的数量影响了API的请求和计费。
语言转换压缩法
根据上边的对token的了解, 我们可以这样操作, 先把中文转换为英文, 再去发送请求。这样就能减少的token的大小, 达到某个程度上解决超长文本限制的问题。
当然,缺点也是很多的,语言的转换可能会丢失原有语义,机翻的话效果没那么好, 使用GPT进行翻译又而外增加了token消耗,得不偿失。在某个场景或许是用得上的,可以作为一种技术储备。
摘要压缩法
还有一个压缩思路, 就是通过一些技术手段或者直接用GPT提炼压缩成短文本,比如删除冗余信息,提取关键信息,使用缩略语等。这种方法可以保留文本的核心内容,但是可能会丢失一些细节信息和语义信息。
应用场景:如果我们想要用GPT来阅读一篇论文,我们可以先用一些摘要技术或者关键词提取技术将论文压缩成一个短摘要或者一个关键词列表,然后用GPT生成一个对论文的理解或者评价。然后进行索引,方便搜寻。对论文的某一段有疑问,在根据摘要的索引找到对应的文章句子进行发送给GPT提问, 这样就能用于辅助阅读一篇长论文了。
额外话:之前看到一个关于压缩很有趣的观点, 有兴趣可以去阅读下。
压缩即泛化,泛化即智能
https://zhuanlan.zhihu.com/p/615554635
ChatGPT是网上所有文本模糊的图片
https://baijiahao.baidu.com/s?id=1757454901451803072&wfr=spider&for=pc
切分法
如果我们向朋友发送一个5G的文件, 而软件最大限制是1GB, 那怎么发呢?可以用压缩分卷的形式拆成5个1GB的文件,分5次发送就可以解决。
同理如果发送要发送的文本太大, 我们可以将长文本切分成若干个短文本,然后分别输入模型,最后将输出结果拼接起来。这种方法简单易实现,但是可能会损失文本之间的上下文信息和连贯性。例如,如果我们想要用GPT来写一篇博客文章,我们可以将文章切分成若干个段落或者小节,然后分别用GPT生成每个段落或者小节的内容,最后将它们拼接起来形成完整的文章。但是这样做可能会导致文章缺乏整体的逻辑和结构。
切分法缺点显而易见,就是可能会丢失上下文的关联。适合上下文关联不强的场景。
比如翻译一本英文小说的场景, 按句切按页切会丢失上下文的关联, 造成逻辑和结构问题。
切分如果切得恰当,比如按一章节进行切分, 可以减少丢失上下文的关联导致的逻辑性问题。
Embedding
什么是Embedding?
Embedding是一种将输入文本(单词、句子等)转换为连续向量表示的过程。在GPT模型中,也使用了词向量的技术,将文本中的每个单词映射到一个连续的向量空间,这个向量空间可以捕捉到单词之间的语义和语法关系。
举个例子,考虑以下输入文本:"I love to play soccer."
- 词语嵌入(Word Embedding):首先,每个单词("I", "love", "to", "play", "soccer")被映射到模型的嵌入空间,其中每个单词对应一个向量表示。例如,"love"可能被映射为一个包含多个浮点数值的向量,如[0.2, 0.8, -0.4, ...]。
- 位置嵌入(Position Embedding):为了捕捉输入文本中单词的顺序和位置信息,位置嵌入将每个单词的位置编码为一个向量。例如,第一个单词"I"的位置嵌入向量可能是[0.1, -0.3, 0.5, ...],第二个单词"love"的位置嵌入向量可能是[-0.2, 0.4, -0.1, ...],以此类推。
什么是向量数据?
使用OpenAI的Embedding接口将输入文本(如句子或段落)中的每个单词或符号转换为连续的向量表示。这些向量被称为嵌入向量,它们捕捉了单词在语义和上下文方面的信息。
让我们通过一个具体的例子来说明GPT的嵌入向量数据:
考虑以下输入文本:"The cat is sitting on the mat."
对于这个文本,GPT模型中的嵌入层将为其中的每个单词生成一个嵌入向量。假设每个嵌入向量的维度为100,那么每个单词将被表示为一个100维的向量。
例如,对于单词 "cat",它的嵌入向量可能是一个长度为100的向量,如 [0.2, -0.1, 0.5, ...]。同样地,其他单词(如 "sitting"、"mat")也会有相应的嵌入向量。
这些嵌入向量的生成是通过GPT模型在大规模文本语料上进行预训练得到的。在预训练过程中,模型学习到了单词之间的上下文关系和语义信息。因此,嵌入向量在向量空间中的相对位置可以反映单词之间的语义相似性。
例如,对于类似的单词 "cat" 和 "dog",它们的嵌入向量在向量空间中可能会比较接近,因为它们在语义上相关。相反,与它们不相关的单词(如 "car")的嵌入向量可能会与它们较远。
这样,通过使用GPT的嵌入向量,我们可以将输入文本中的离散单词转换为连续的向量表示,从而为模型提供了一种更好地理解和处理自然语言数据的方式。这些向量可以用于各种下游任务,如文本分类、情感分析、文本生成等。
什么是向量数据库?
向量数据库是一种专门用于存储和查询向量数据的数据库系统。它们提供高效的向量操作和相似性搜索功能。
Embedding 可以以多种格式存储,其中 JSON 是一种常见的格式之一。
向量数据库(Vector Database)是一种专门用于存储和检索向量数据的数据库系统。它们提供高效的向量索引和查询功能,允许用户根据向量之间的相似性进行快速搜索和分析。
使用向量数据库的主要原因是向量数据的特殊性质。传统的数据库通常适用于标量或结构化数据,而对于高维向量数据(如嵌入向量、图像特征向量、音频特征向量等),传统数据库的查询和索引方法往往效率较低。向量数据库通过使用专门的索引结构和查询算法,能够高效地处理向量数据,提供更快的查询速度和更好的检索准确性。
向量数据库的优势包括:
- 高效的相似度搜索:向量数据库可以根据向量之间的相似度,快速找到最相似的向量。这在许多应用场景中非常有用,如图像搜索、推荐系统、聚类分析等。
- 扩展性:向量数据库通常能够处理大规模的向量数据集,并具备良好的水平扩展性,可以在需要时轻松添加更多的存储和计算资源。
- 灵活的查询功能:向量数据库提供了各种灵活的查询功能,可以支持范围查询、K近邻查询、相似度匹配等多种查询类型。
一些常见的向量数据库包括:
- PostgreSQL:PostgreSQL是另一个常见的关系型数据库,它提供了更丰富的数据类型和功能。
- Faiss:Facebook AI Research 开源的向量索引库,提供了高效的相似度搜索和向量聚类功能。
- Milvus:一个开源的向量数据库引擎,支持高性能的相似度搜索和向量存储。
- Annoy:一个快速的C++库,用于在大规模数据集上进行近似最近邻搜索。
- Elasticsearch:一个流行的分布式搜索和分析引擎,可以通过插件支持向量数据的索引和查询。
这只是一小部分向量数据库的例子,还有其他许多向量数据库可用,具体选择取决于应用需求和性能要求。
使用嵌入(Embedding)来解决长文本限制问题是一种常见的方法。嵌入是将文本或实体表示为低维稠密向量的技术,可以将高维的文本表示转化为固定长度的向量,从而克服原始文本长度的限制。以下是一些具体的操作方式和示例场景:
- 文本嵌入模型:使用预训练的文本嵌入模型(如Word2Vec、GloVe、BERT等)可以将单词或短语转换为向量表示。这样,长文本可以通过将其分解为单词或短语,并将它们的嵌入向量进行平均或拼接,得到整个文本的嵌入表示。这种方式可以用于各种场景,例如情感分析、文本分类、文本相似度计算等。
示例场景:在一个知识库中,每篇文章都有较长的文本描述。可以使用预训练的文本嵌入模型,将每个文章的文本描述转换为固定长度的嵌入向量。然后,可以计算用户查询与知识库中文章的相似度,基于相似度进行匹配和推荐相关文章。
- 序列嵌入模型:对于长文本序列,如文章、评论或对话,可以使用序列嵌入模型(如LSTM、Transformer等)来获取整个序列的嵌入表示。这种方式会考虑序列中的上下文信息,并生成一个固定长度的向量表示整个序列。这对于文本生成、机器翻译、对话建模等任务非常有用。
示例场景:在一个问答系统中,用户输入一个较长的问题,需要将其转换为向量表示并与知识库中的答案进行匹配。可以使用序列嵌入模型,将问题和答案分别转换为嵌入向量,然后计算它们之间的相似度,以找到最相关的答案。
- 文本摘要:对于长文本,可以使用文本摘要模型(如Seq2Seq模型)生成一个简洁的摘要,将长文本压缩为固定长度的摘要向量。这对于新闻摘要、文档摘要等任务非常有用。
示例场景:在一个新闻聚合应用中,用户可以浏览大量的新闻文章。为了提供更好的用户体验,可以使用文本摘要模型将每篇新闻文章压缩为简洁的摘要向量,以便用户快速浏览并选择感兴趣的文章。
这些是一些使用嵌入来解决长文本限制问题的操作方式和示例场景。具体的选择取决于应用需求和数据特点。嵌入技术可以帮助我们从长文本中提取有用的信息并转换为固定长度的向量表示,从而应对长文本带来的挑战。
模型微调
OpenAI 的微调(fine-tuning)是指在预训练的语言模型基础上,使用特定的数据集对模型进行进一步的训练,以适应特定的任务或领域。微调可以使模型更好地理解和生成与特定任务相关的文本。
要解决长文本输入限制的问题,可以使用 OpenAI 的微调技术来对语言模型进行适应。以下是使用微调技术解决长文本输入限制的一般步骤:
- 数据集准备:准备一个与所需任务相关的数据集,其中包含长文本示例。这可以是一个包含长文本样本的文本数据集,或者是一个特定任务的标注数据集,例如长文本分类或生成任务。
- 模型选择:选择一个适合任务的预训练语言模型作为基础模型。OpenAI 提供了各种预训练模型,如GPT-3、GPT-2等。根据任务需求和计算资源,选择一个合适的模型。
- 微调模型:使用准备好的数据集对预训练模型进行微调。微调的过程包括加载预训练模型的权重,将任务相关的数据输入模型,并通过反向传播优化模型参数。微调的目标是使模型适应特定任务,并提高模型在长文本输入上的性能。
- 超参数调整:微调过程中,可能需要进行一些超参数的调整,如学习率、批次大小和训练轮数。这些超参数的选择可以通过实验和验证集上的性能评估来进行调整。
- 测试和评估:在微调完成后,对模型进行测试和评估。使用一组测试集或实际应用场景的数据,评估模型在长文本输入上的性能和效果。
通过微调技术,可以使预训练模型更好地理解和处理长文本输入。预训练模型具有对语言的广泛理解能力,而微调可以帮助模型针对特定任务或领域进行优化,以解决长文本输入限制的问题。
总结
总之,在GPT这样的预训练语言模型中,长文本输入是一个普遍存在且有待解决的问题。根据不同的场景和任务,可以采用不同的思路和方案来解决这个问题,比如切分,压缩,向量化,模型微调等,也可以综合起来运用。这些方案各有优缺点,需要根据实际情况进行选择和优化。
评论 (0)