解除 GPT 知识限制打造无限对话机器人:Embeddings 原理基础

LLMs(语言模型)只能利用训练所用数据集来回答问题,这也意味着对于 ChatGPT 而言,它只能回答关于 2021 年 9 月之前的信息。而利用 Embedding 你可以做到让 GPT 回答:

  • 2021 年 9 月以后的新闻
  • 公司内部的非公开文档(如果你信任 OpenAI 的商用服务)
  • 过往对话记录(以实现无限 token 的对话机器人)

本文将通过使用 Embedding 搜索来让 GPT 能够回答与杭州亚运会相关的问题,并最终实现能无视 token 限制无限对话的 AI 助手。

提供上下文

LLMs 有两种途径学习知识:

  • 通过模型权重学习(比如通过训练集对模型进行 Fine-tuning)
  • 通过模型输入(比如插入上下文信息到输入消息中)

OpenAI 推荐在信息中插入上下文信息作为为模型输入新知识的方式,而不是使用 Fine-tuning。这或许有出于成本的考虑,但更重要的是 Fine-tuning 无法保证作用于参数权重的训练结果能体现到具体的每一次对话上。即 Fine-tuning 不太适合用来让 LLMs 回忆某一个具体事例,而更多用于让其适应特定形式和风格的任务。

打个比方:Fine-tuning 调整模型权重的过程就像是让能处理各种不同通用任务的大学生接受特定岗位的培训。而插入搜索的结果则是让在处理具体任务时给出针对性的几条参考信息,能让人很容易应用到当前的事例中。

搜索相比于 Fine-tuning 有一个缺点是:插入的信息作为对话的一部分,也会受限于模型的对话最大文本量限制。

模型 最大文本量
gpt-3.5-turbo 4,096 tokens
gpt-4 8,192 tokens
gpt-4-32k 32,768 tokens

也就是说我们做不到把整本红楼梦原著插入对话当中,并向 GPT 提问书中内容,因为 GPT 的对话 token 容量根本无法支持输入这么多信息。

因此我们应该向 GPT 提供尽可能相关的部分有限信息。

嵌入搜索

我们可以在庞大的数据集中搜索最相关的内容来作为对话的上下文,这里有几种不同的方法:

  • 关键词搜索
  • 图搜索
  • 嵌入搜索

在为 LLMs 提供对话上下文信息时常用到的就是最后一种嵌入搜索,也就是我们常说的 Embeddings。它相比于仅依赖关键词的搜索的优势有很多。

比如嵌入搜索可以处理不同语言的内容,不同语言表达同一种意思的文本在嵌入空间的语义维度上更接近。比如搜索 "I like to eat apples." 就更容易匹配到 "我喜欢吃苹果" 而不是同样出现 "Apple" 单词且同为英文的句子 "I bought some stocks of Apple Inc."。

vbnet 复制代码
Query: I like to eat apples.
[1.00000] I like to eat apples.
[0.87726] 我喜欢吃苹果
[0.82987] I bought some stocks of Apple Inc.

运用 Embeddings 还可以处理一些并不能直接匹配文本的情况,比如下面查询的语句中并没有直接出现苹果公司股票相关字眼,但由于逻辑上的关联性而被认为与其高度相关。

vbnet 复制代码
Query: I tend to favor value investing and usually invest in some tech giants.
[0.84487] I bought some stocks of Apple Inc.
[0.78884] I like to eat apples.
[0.72575] 我喜欢吃苹果

需要注意的是不能将 "嵌入" 理解成 "将上下文信息嵌入 到对话当中",这里的 "嵌入" 应该指的是:将使用自然语言描述的问题文本,嵌入到高维度的向量空间中,以实现程式化的分析。下面将详细解释 Embeddings 的概念。

嵌入的概念

当我们谈到 "嵌入(Embedding)" 时,一个简单的数学领域的例子是将一个向量嵌入到一个更高维的空间中。

假设我们有一个二维平面上的点A,它的坐标是 (2, 3)。我们想要将这个点嵌入到一个三维空间中,可以将其表示为 (2, 3, 0)。这样,我们就在三维空间中嵌入了二维点 A。

在这个例子中,原始的二维点 A 被嵌入到一个更高维的空间中,使得我们可以在新的空间中利用额外的维度来表示更多的信息。这种嵌入可以帮助我们更好地理解和处理数据。类似地,嵌入可以应用于其他领域,如自然语言处理中的词嵌入,将单词嵌入到一个高维向量空间中,以便进行语义分析和文本处理。

在词嵌入中,向量空间的几何意义可以提供对词汇关系的一些直观理解。

向量空间中的距离可以表示单词之间的相似性。如果两个单词的向量在空间中距离较近,那么它们在语义上可能具有较高的相似性。例如,在训练良好的词嵌入模型中,"king" 和 "queen" 这两个单词的向量在空间中的距离可能比较接近,因为它们在语义上具有相似的含义。

向量空间中的方向可以表示语义关系。例如,我们可以通过计算两个单词向量的差异向量来捕捉它们之间的关系。例如,使用 "king" 向量减去 "man" 向量,再加上 "woman" 向量,可能会得到一个接近于 "queen" 向量的结果。这说明了在向量空间中,"king" 和 "queen" 之间的关系可能与 "man" 和 "woman" 之间的关系相似。

向量空间中的线性组合也可以表示语义关系。通过将两个单词向量相加或相减,我们可以生成新的向量,表示两个单词之间的合成或对比关系。例如,使用 "Paris" 向量减去 "France" 向量,再加上 "Italy" 向量,可能会得到一个接近于 "Rome" 向量的结果。

<math xmlns="http://www.w3.org/1998/Math/MathML"> k i n g ⃗ − m a n ⃗ + w o m a n ⃗ ≈ q u e e n ⃗ \vec{king} - \vec{man} + \vec{woman} \approx \vec{queen} </math>king −man +woman ≈queen

Embedding API

OpenAI 提供了 text-embedding-ada-002 模型用来实现 Embedding,也就是说将文本转换成向量:

typescript 复制代码
import { OpenAI } from 'openai';

const api = new OpenAI({});

const response = await api.embeddings.create({
  model: 'text-embedding-ada-002',
  input: '我喜欢吃苹果',
});

这里打印 response.data[0].embedding 可以得到一个包含 1536 个浮点数的数组,这就是我们之后用于分析和搜索的 Embeddings 向量。注意这里向量的维度是固定的,任意长度的文本输入都会得到相同长度的数组。

向量查询

根据向量查询相似度的方法非常简单,类似使用勾股定理就可以求解两个二维向量的距离,我们可以很轻松地求解任意两个向量之间的距离。这里我使用 ChatGPT 生成了一段代码实现:

Q: 使用 TypeScript 实现一个计算两个任意维度向量之间距离的函数
A: 下面是一个使用 TypeScript 实现计算两个任意维度向量之间距离的函数的示例:

typescript 复制代码
function calculateDistance(vector1: number[], vector2: number[]): number {
  if (vector1.length !== vector2.length) {
    throw new Error('Vectors must have the same number of dimensions');
  }

  const squaredDistances = vector1.map((coord, index) => {
    const diff = coord - vector2[index];
    return diff * diff;
  });

  const sumOfSquaredDistances = squaredDistances.reduce(
    (accumulator, current) => accumulator + current,
    0
  );

  return Math.sqrt(sumOfSquaredDistances);
}

// 示例使用
const vector1 = [1, 2, 3];
const vector2 = [4, 5, 6];
const distance = calculateDistance(vector1, vector2);
console.log(distance);

在上述示例中,calculateDistance 函数接受两个参数 vector1vector2,它们分别代表两个向量。函数首先检查两个向量的维度是否相同,如果不同则抛出错误。然后,函数计算每个坐标的差值的平方,并将所有平方差值相加。最后,函数返回平方和的平方根,即向量之间的距离。

请注意,该示例假设向量的维度是相同的,并且向量的坐标是数字类型。如果需要处理其他类型或者更复杂的向量操作,可能需要进行适当的修改。

下一篇文章我们会用 Node.js 实现能回答有关杭州亚运会的问题的问答程序。

参考链接

相关推荐
岁月宁静2 小时前
用 Node.js 封装豆包语音识别AI模型接口:双向实时流式传输音频和文本
前端·人工智能·node.js
徐sir(徐慧阳)2 小时前
搭建属于自己的网站HEXO静态页(二)发布网站到gihub
服务器·node.js·github·hexo
雪中何以赠君别3 小时前
【框架】CLI 工具笔记
javascript·node.js
量子位4 小时前
OpenAI IPO计划第一步曝光,奥特曼骚操作看傻华尔街
openai
新智元5 小时前
马斯克「世界模拟器」首曝,1 天蒸馏人类 500 年驾驶经验!擎天柱同脑进化
人工智能·openai
新智元5 小时前
LeCun 怒揭机器人最大骗局,坦白 Llama 与我无瓜!
人工智能·openai
专注VB编程开发20年5 小时前
JSA变成类似vba环境给第三方软件集成IDE功能,脚本功能
ide·microsoft·node.js·vba·wps·vb6·jsa
刘永胜是我7 小时前
解决Volta环境下npm全局包卸载失败:一次深入排查之旅
前端·node.js
机器之心7 小时前
三百年几何猜想被推翻,数学家首次发现「穿不过去」的多面体
人工智能·openai
Achieve前端实验室8 小时前
【每日一面】手写防抖函数
前端·面试·node.js