如果你想使用Azure OpenAI的ada-002模型为文档生成嵌入,那么你应该向该API发送最多8192个tokens。如果一个文档的tokens超过8K,为了处理它,我们应该按照我的调查结果执行特定的步骤。
- 准备文档文本,清理、标准化、去除停用词,以便能够按照Azure OpenAI ada-002的计数方式计算tokens。
- 通过空格(” “)分割文档文本,将其标记化为单词。
- 如果文档的tokens超过8K,则将其分割成最多8K tokens的多个子文档。
- 将这些8K的子文档传递给Azure OpenAI ada-002端点,并为每个子文档获取嵌入。
- 将这些浮点嵌入(通过追加)组合成一个单一向量,以表示原始文档。
- 然后,为了能够根据问题找到相似的文档,问题向量和文档向量应具有相同的长度,因此我们显然需要对被分割并重新嵌入到单一向量的文档进行降维处理。
例如,如果一个文档(10K Tokens)被分割成两个子文档(8K和2K),每个子文档的嵌入将有1536个维度,因此完整文档将有1536 x 2 = 3072。未超过8K tokens的问题将有1536个维度,因此无法与所有文档进行比较。
那么,有没有办法将这些3072维的文档正确地降维回1536维呢?
根据我的研究,这可以通过PCA来实现,我在C#中找到了以下示例,但这里的数据是[][]而不是[]:
double[][] data = new double[][]{// ... 这里放入你的组合嵌入向量};// 创建一个新的主成分分析var pca = new PrincipalComponentAnalysis(){Method = PrincipalComponentMethod.Center,Whiten = false};// 学习PCA模型pca.Learn(data);// 将数据转换为降维空间double[][] reducedData = pca.Transform(data, 3); // 降维到3维
有什么想法吗?
回答:
找到了答案,解决这个问题有多种方法:
首先,将文档分成块(重要的是文档分块的方式,我们可以按句子、按符号或按固定数量的tokens来分割文档),如果我们使用基于所用模型的特定tokens数量,例如将文档分割成256-Tokens、512-Tokens或1K-Tokens,这对ADA-002的性能有好处。然后使用选定的模型(例如ADA-002)嵌入每个块,并收集文档的所有嵌入块。在大多数情况下,块之间的tokens重叠可以提高解决方案的质量。
降维可以通过多种方式实现:
一种好的方法是,在文档的所有块都被嵌入后,我们可以对每个维度在块之间的平均值进行计算。如果ADA-002的一个块有1532个维度,那么我们将有多个1532维的块。计算每个维度的平均值,我们将再次得到相同维度的向量。这种方法快速且易于实现。
第二种方法是,在文档的所有块都被嵌入后,我们可以组合文档的嵌入。如果ADA-002的一个块有1532个维度,那么我们将有1532 x 嵌入数量的维度。然后我们可以使用PCA将维度降回原始形状。
刚刚测试了将文档分割成固定数量的tokens,设置为1K,tokens重叠为100,并采用平均值作为降维方法,似乎效果很好。