GenQ
在我们的论文 BEIR: Information Retrieval Models 零样本评估的异构基准 中,我们提出了一种方法,用于调整模型以进行 非对称语义搜索,而无需使用没有标记训练数据的语料库。
背景
在 非对称语义搜索 中,用户提供一个(简短的)查询,例如一些关键词或一个问题。然后我们想要检索一个更长的文本段落,该段落提供答案。
例如
query: What is Python?
passage to retrieve: Python is an interpreted, high-level and general-purpose programming language. Python's design philosophy emphasizes code readability with its notable use of significant whitespace. Its language constructs and object-oriented approach aim to help programmers write clear, logical code for small and large-scale projects.
我们展示了如果有足够的训练数据(查询 & 相关段落)可用,如何训练此类模型:训练 MS MARCO 数据集
在本教程中,我们将展示在没有训练数据可用的情况下如何训练此类模型,即,如果您没有数千个标记的查询 & 相关段落对。
概述
我们使用合成查询生成来实现我们的目标。我们从文档集合中的段落开始,并为这些可能的查询创建用户可能询问/可能搜索的内容。
例如,我们有以下文本段落
Python is an interpreted, high-level and general-purpose programming language. Python's design philosophy emphasizes code readability with its notable use of significant whitespace. Its language constructs and object-oriented approach aim to help programmers write clear, logical code for small and large-scale projects.
我们将此段落传递给经过专门训练的 T5 模型,该模型为我们生成可能的查询。对于上面的段落,它可能会生成这些查询
什么是 python
definition python
什么语言使用空格
然后我们使用这些生成的查询来创建我们的训练集
(What is python, Python is an interpreted...)
(definition python, Python is an interpreted...)
(what language uses whitespaces, Python is an interpreted...)
并使用它训练我们的 SentenceTransformer bi-encoder。
查询生成
在 BeIR 中,我们提供了可用于查询生成的不同模型。在本例中,我们使用由 docTTTTTquery 训练的 T5 模型
from transformers import T5Tokenizer, T5ForConditionalGeneration
import torch
tokenizer = T5Tokenizer.from_pretrained("BeIR/query-gen-msmarco-t5-large-v1")
model = T5ForConditionalGeneration.from_pretrained("BeIR/query-gen-msmarco-t5-large-v1")
model.eval()
para = "Python is an interpreted, high-level and general-purpose programming language. Python's design philosophy emphasizes code readability with its notable use of significant whitespace. Its language constructs and object-oriented approach aim to help programmers write clear, logical code for small and large-scale projects."
input_ids = tokenizer.encode(para, return_tensors="pt")
with torch.no_grad():
outputs = model.generate(
input_ids=input_ids,
max_length=64,
do_sample=True,
top_p=0.95,
num_return_sequences=3,
)
print("Paragraph:")
print(para)
print("\nGenerated Queries:")
for i in range(len(outputs)):
query = tokenizer.decode(outputs[i], skip_special_tokens=True)
print(f"{i + 1}: {query}")
在上面的代码中,我们使用 Top-p(nucleus)采样,它将从可能的单词集合中随机选择一个单词。因此,模型每次将生成不同的查询。
Bi-Encoder 训练
使用生成的查询,我们可以然后使用 MultipleNegativesRankingLoss 训练 bi-encoder。
完整示例
我们训练一个语义搜索模型,以搜索关于编程文章和技术的 Wikipedia 文章。
我们使用以下 Wikipedia 文章中的文本段落:Assembly language, C , C# , C++, Go , Java , JavaScript, Keras, Laravel, MATLAB, Matplotlib, MongoDB, MySQL, Natural Language Toolkit, NumPy, pandas (software), Perl, PHP, PostgreSQL, Python , PyTorch, R , React, Rust , Scala , scikit-learn, SciPy, Swift , TensorFlow, Vue.js
在
1_programming_query_generation.py - 我们为这些文章的所有段落生成查询
2_programming_train_bi-encoder.py - 我们使用这些生成的查询训练 SentenceTransformer bi-encoder。这产生了一个模型,我们可以将其用于语义搜索(对于给定的 Wikipedia 文章)。
3_programming_semantic_search.py - 展示了如何将训练好的模型用于语义搜索。