GenQ¶
在我们的论文BEIR: 一个用于零样本评估信息检索模型的异构基准中,我们提出了一种在没有标注训练数据的情况下,为语料库适配非对称语义搜索模型的方法。
背景¶
在非对称语义搜索中,用户提供一个(简短的)查询,例如一些关键词或一个问题。然后我们希望检索一个较长的文本段落来提供答案。
例如:
查询: Python是什么?
要检索的段落: Python是一种解释型、高级且通用的编程语言。Python的设计哲学强调代码的可读性,并显著使用空白字符。其语言结构和面向对象的方法旨在帮助程序员为小型和大型项目编写清晰、逻辑的代码。
我们展示了如果拥有足够的训练数据(查询和相关的段落),如何训练这样的模型:训练MS MARCO数据集
在本教程中,我们展示了如何在没有训练数据的情况下训练这样的模型,也就是说,如果你没有成千上万的标注查询和相关段落对。
概述¶
我们使用合成查询生成来实现我们的目标。我们从文档集合中的段落开始,并为这些段落创建用户可能询问/搜索的查询。
例如,我们有以下文本段落:
Python是一种解释型、高级且通用的编程语言。Python的设计哲学强调代码的可读性,并显著使用空白字符。其语言结构和面向对象的方法旨在帮助程序员为小型和大型项目编写清晰、逻辑的代码。
我们将这个段落通过一个专门训练的T5模型传递,该模型为我们生成可能的查询。对于上述段落,它可能会生成这些查询:
Python是什么?
Python的定义是什么?
哪种语言使用空白字符?
然后我们使用这些生成的查询来创建我们的训练集:
(Python是什么?, Python是一种解释型...)
(Python的定义是什么?, Python是一种解释型...)
(哪种语言使用空白字符?, Python是一种解释型...)
并用它来训练我们的SentenceTransformer双编码器。
查询生成¶
在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是一种解释型、高级且通用的编程语言。Python的设计哲学强调代码的可读性,并显著使用空白字符。其语言结构和面向对象的方法旨在帮助程序员为小型和大型项目编写清晰、逻辑的代码。"
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("段落:")
print(para)
print("\n生成的查询:")
for i in range(len(outputs)):
query = tokenizer.decode(outputs[i], skip_special_tokens=True)
print(f"{i + 1}: {query}")
在上面的代码中,我们使用了Top-p (nucleus) sampling,它将从一组可能的词中随机选择一个词。因此,每次模型都会生成不同的查询。
双编码器训练¶
使用生成的查询,我们可以使用MultipleNegativesRankingLoss来训练一个双编码器。
完整示例¶
我们训练一个语义搜索模型来搜索关于编程文章和技术的维基百科文章。
我们使用以下维基百科文章的文本段落: 汇编语言, C, C#, C++, Go, Java, JavaScript, Keras, Laravel, MATLAB, Matplotlib, MongoDB, MySQL, 自然语言工具包, NumPy, pandas (软件), 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双编码器。这将产生一个模型,随后我们可以用它来进行语义搜索(针对给定的维基百科文章)。
3_programming_semantic_search.py - 展示了如何使用训练好的模型进行语义搜索。