Press "Enter" to skip to content

使用Transformers中的对比搜索生成人类水平的文本 🤗


使用Transformers中的对比搜索生成人类水平的文本 🤗 四海 第1张

1. 简介:

自然语言生成(即文本生成)是自然语言处理(NLP)中的核心任务之一。在本博客中,我们介绍了当前最先进的解码方法对比搜索(Contrastive Search),用于神经文本生成。对比搜索最初在“A Contrastive Framework for Neural Text Generation”[1]([论文][官方实现])中提出,该论文发表于NeurIPS 2022。此外,在随后的研究“Contrastive Search Is What You Need For Neural Text Generation”[2]([论文][官方实现])中,作者进一步证明了对比搜索可以使用现成的语言模型在16种语言中生成人类水平的文本。

[备注] 对于不熟悉文本生成的用户,请参考此博文了解更多细节。


对比搜索现在可以在🤗 transformers上使用,包括PyTorch和TensorFlow。您可以使用您选择的框架在此Colab笔记本上与本博客中显示的示例进行交互。我们还建立了这个很棒的演示,直接比较对比搜索与其他流行的解码方法(例如束搜索、top-k采样[3]和nucleus采样[4])。


3. 环境安装:

在运行以下部分的实验之前,请安装最新版本的transformers

pip install torch
pip install "transformers==4.24.0"

4. 存在的解码方法问题:

解码方法可以分为两类:(i)确定性方法和(ii)随机性方法。让我们讨论一下两者!

4.1. 确定性方法:

确定性方法,如贪婪搜索和束搜索,通过选择语言模型测量的概率最高的文本延续来生成文本。然而,正如以前的研究[3] [4]广泛讨论的那样,确定性方法经常导致模型退化的问题,即生成的文本不自然且包含不希望的重复。

下面,让我们看一个使用GPT-2模型进行贪婪搜索生成的文本示例。

from transformers import AutoTokenizer, GPT2LMHeadModel

tokenizer = AutoTokenizer.from_pretrained('gpt2-large')
input_ids = tokenizer('DeepMind Company is', return_tensors='pt').input_ids
model = GPT2LMHeadModel.from_pretrained('gpt2-large')

output = model.generate(input_ids, max_length=128)
print("Output:\n" + 100 * '-')
print(tokenizer.decode(output[0], skip_special_tokens=True))
print("" + 100 * '-')

模型输出:

Output:
----------------------------------------------------------------------------------------------------
DeepMind公司是一家领先的人工智能研究公司,专注于深度学习和基于深度
学习的系统。

该公司的研究重点是开发基于深度学习的系统
可以从大量数据中学习,并可以用于解决现实世界的问题。

DeepMind的研究还被英国政府用于开发新技术
英国的国家医疗服务。

DeepMind的研究还被英国政府用于开发新技术
英国的国家医疗服务。

DeepMind的研究还被英国政府用于开发新技术
----------------------------------------------------------------------------------------------------

[备注] 从贪婪搜索生成的结果中,我们可以看到明显的重复模式。

4.2. 随机性方法:

为了解决确定性方法带来的问题,随机性方法在解码过程中引入随机性来生成文本。两种广泛使用的随机性方法是(i)top-k采样[3]和(ii)nucleus采样(也称为top-p采样)[4]。

下面,我们以使用GPT-2模型进行核心采样(p=0.95)生成文本的示例进行说明。

import torch
from transformers import AutoTokenizer, GPT2LMHeadModel

tokenizer = AutoTokenizer.from_pretrained('gpt2-large')
input_ids = tokenizer('DeepMind是一家', return_tensors='pt').input_ids
model = GPT2LMHeadModel.from_pretrained('gpt2-large')

torch.manual_seed(0.)
output = model.generate(input_ids, do_sample=True, max_length=128, top_p=0.95, top_k=0)
print("输出结果:\n" + 100 * '-')
print(tokenizer.decode(output[0], skip_special_tokens=True))
print("" + 100 * '-')

模型输出:

输出结果:
----------------------------------------------------------------------------------------------------
DeepMind是一家AI研究、开发和交付安全、基础设施、机器学习、通信等领域的领先提供商。

“AI不是新闻”

更糟糕的是,研究人员希望传达给世界媒体的信息是,这不是真正的研究,而是一种从他人的无知中获利的快速致富计划。

“问题是,我们知道人们不会有意识地评估其他人的信息的价值。他们知道他们会得到与他们自己相同的信息。”

一个例子?给出今天的细节
----------------------------------------------------------------------------------------------------

[备注] 尽管核心采样可以生成没有重复的文本,但生成文本的语义连贯性并不好。例如,生成的短语“AI不是新闻”与给定的前缀“DeepMind是一家”不连贯。

我们注意到,这个语义不一致的问题可以通过降低温度来部分解决。然而,降低温度会使核心采样更接近贪婪搜索,这可以看作是贪婪搜索和核心采样之间的权衡。一般来说,很难找到一个与提示和模型无关的温度,既避免了贪婪搜索的缺陷,又避免了核心采样的缺陷。


在本节中,我们详细介绍一种新的解码方法对比搜索

5.1. 解码目标:

给定前缀文本 x < t x_{< t} x < t ​ ,输出标记 x t x_{t} x t ​ 的选择遵循

使用Transformers中的对比搜索生成人类水平的文本 🤗 四海 第2张

其中 V ( k ) V^{(k)} V ( k ) 是语言模型概率分布 p θ ( v ∣ x < t ) p_{\theta}(v|x_{< t}) p θ ​ ( v ∣ x < t ​ ) 的前 k 个预测集合。第一项,即模型置信度,是语言模型预测的候选项 v v v 的概率。第二项,即退化惩罚,测量了 v v v 相对于先前上下文 x < t x_{< t} x < t ​ 的区分度。函数 s ( ⋅ , ⋅ ) s(\cdot, \cdot) s ( ⋅ , ⋅ ) 计算标记表示之间的余弦相似度。具体来说,退化惩罚定义为 v v v 的标记表示 h v h_{v} h v ​ 与上下文 x < t x_{< t} x < t ​ 中所有标记的表示之间的最大余弦相似度。这里,候选表示 h v h_{v} h v ​ 是由语言模型根据 x < t x_{< t} x < t ​ 和 v v v 的连接进行计算的。直观地说,v v v 的退化惩罚越大,表示它在上下文中(表示空间中)与上下文更相似,因此更有可能导致模型退化的问题。超参数 α \alpha α 调节着这两个组成部分的重要性。当 α = 0 \alpha=0 α = 0 时,对比搜索退化为普通的贪婪搜索。

[备注] 在生成输出时,对比搜索共同考虑了(i)语言模型预测的概率,以保持生成文本与前缀文本的语义连贯性;和(ii)相对于先前上下文的相似性,以避免模型退化。

下面,我们使用与第4.1节和4.2节相同的前缀文本(即“DeepMind公司是”),并使用对比搜索(k = 4和α = 0.6)生成文本。为了充分展示对比搜索的优越能力,我们让语言模型生成一个文档,其中包含512个标记。

from transformers import GPT2Tokenizer, GPT2LMHeadModel

model_name = 'gpt2-large'
tokenizer = GPT2Tokenizer.from_pretrained(model_name)
model = GPT2LMHeadModel.from_pretrained(model_name, pad_token_id=tokenizer.eos_token_id)
model.eval()

# 准备前缀
prefix_text = r'DeepMind公司是'
input_ids = tokenizer(prefix_text, return_tensors='pt').input_ids

# 使用对比搜索生成结果
output = model.generate(input_ids, penalty_alpha=0.6, top_k=4, max_length=512)
print("输出结果:\n" + 100 * '-')
print(tokenizer.decode(output[0], skip_special_tokens=True))
print("" + 100 * '-')

参数说明如下:

  • --top_k:对比搜索中的超参数k。
  • --penalty_alpha:对比搜索中的超参数α。

模型输出:

输出结果:
----------------------------------------------------------------------------------------------------
DeepMind公司是人工智能(AI)领域的领导者。我们与谷歌、Facebook、亚马逊和微软等公司合作多年,开发能够改善人们生活的产品。今天,我们很高兴地宣布,DeepMind的AlphaGo程序在围棋比赛中战胜了职业围棋选手,成为首个击败职业围棋选手的程序。

这一胜利证明了深度学习的强大能力,也证明了我们的研究团队在过去五年中一直处于人工智能研究的前沿。AlphaGo是迄今为止最先进的围棋程序之一,其性能是实现人类级别人工智能目标的重要一步。

DeepMind的围棋研究始于2010年,当时我们开始使用全球顶级围棋选手的数百万场比赛训练神经网络进行围棋对局。此后,我们不断改进算法,增加了越来越多的强化学习层次,以提高其对模式的识别能力和基于模式的决策能力。在过去的一年半里,我们在围棋比赛中取得了重大进展,连胜13场,进入世界排名前四名。

DeepMind的联合创始人兼首席技术官Andy Ng表示:“这是十年辛勤工作的成果。我们为实现这一里程碑感到非常高兴,并期待继续开发能够应用于各种领域、改善人们生活的人工智能。”

除了在围棋比赛中的胜利,DeepMind还开发了一套可以学习玩多种不同游戏(包括扑克、围棋和国际象棋)的人工智能系统。这套名为Tarsier的人工智能系统是与卡内基梅隆大学和加州大学伯克利分校合作开发的,用于教授计算机视觉和机器学习,能够识别图像中的物体并理解自然语言中的语音。Tarsier已经接受了围棋等多项游戏的训练。
----------------------------------------------------------------------------------------------------

[备注] 我们可以看到生成的文本质量异常高。整个文档在语法流畅和语义连贯方面表现出色。与此同时,生成的文本也很好地保持了事实的正确性。例如,在第一段中,它将“AlphaGo”描述为“首个击败职业围棋选手的程序”。

为了更好地理解对比搜索的工作原理,我们提供了贪婪搜索(第4.1节)和对比搜索之间的可视化比较。具体而言,我们分别可视化了贪婪搜索和对比搜索生成的文本的标记相似性矩阵。两个标记之间的相似性定义为它们的标记表示之间的余弦相似度(即最后一个Transformer层的隐藏状态)。下图显示了贪婪搜索(顶部)和对比搜索(底部)的结果。

使用Transformers中的对比搜索生成人类水平的文本 🤗 四海 第3张 使用Transformers中的对比搜索生成人类水平的文本 🤗 四海 第4张

[备注] 从贪婪搜索的结果可以看出,非对角线条目中存在高相似度分数,清晰地表明了贪婪搜索生成的重复内容。相反,在对比搜索的结果中,高相似度分数主要出现在对角线条目中,验证了成功解决的退化问题。通过在解码过程中引入退化惩罚(见第5.1节),实现了对比搜索的这一良好特性。


6. 更多生成的示例:

在本部分,我们提供更多生成的示例以比较不同的解码方法。

6.1. 示例一 – GPT-2:

在这部分中,我们使用GPT-2根据原始OpenAI博客中发布GPT-2的前缀文本生成文本。

在一个令人震惊的发现中,科学家们发现了一群生活在安第斯山脉中的偏远、以前未被开发的山谷中的独角兽。更令研究人员惊讶的是,这些独角兽竟然说着完美的英语。

加载语言模型并准备前缀文本:

import torch
from transformers import AutoTokenizer, GPT2LMHeadModel

tokenizer = AutoTokenizer.from_pretrained('gpt2-large')
model = GPT2LMHeadModel.from_pretrained('gpt2-large')

prefix_text = r"在一个令人震惊的发现中,科学家们发现了一群生活在安第斯山脉中的偏远、以前未被开发的山谷中的独角兽。更令研究人员惊讶的是,这些独角兽竟然说着完美的英语。"
input_ids = tokenizer(prefix_text, return_tensors='pt').input_ids

代码: [点击展开]

output = model.generate(input_ids, max_length=512)
print("输出:\n" + 100 * '-')
print(tokenizer.decode(output[0], skip_special_tokens=True))
print("" + 100 * '-')

模型输出: [点击展开]

输出:
----------------------------------------------------------------------------------------------------
在一个令人震惊的发现中,科学家们发现了一群生活在安第斯山脉中的偏远、以前
未被开发的山谷中的独角兽。更令研究人员惊讶的是,这些独角兽竟然说着完美的英语。

该研究由加利福尼亚大学圣塔克鲁兹分校的David R. Williams博士领导,他们在秘鲁的安第斯山脉中发现了这些独角兽。该地区以其独特的地质而闻名,并且是许多稀有动物物种的家园。

研究人员在秘鲁的安第斯山脉中发现了这些独角兽。

Williams说:“我们惊讶地发现这些独角兽能够彼此交流。”“我们还惊讶地发现它们能够用英语交流。”

研究人员认为这些独角兽是古老的印加人的后裔,他们生活在大约2000年前的这个地区。

Williams说:“印加人是第一个将安第斯山脉作为逃避安第斯山脉严酷气候的避难所的人。”“他们也是第一个将安第斯山脉作为狩猎和采集食物的地方的人。”

研究人员认为这些独角兽是古老的印加人的后裔,他们生活在大约2000年前的这个地区。

Williams说:“印加人是第一个将安第斯山脉作为逃避安第斯山脉严酷气候的避难所的人。”“他们也是第一个将安第斯山脉作为狩猎和采集食物的地方的人。”

研究人员认为这些独角兽是古老的印加人的后裔,他们生活在大约2000年前的这个地区。

Williams说:“印加人是第一个将安第斯山脉作为逃避安第斯山脉严酷气候的避难所的人。”“他们也是第一个将安第斯山脉作为狩猎和采集食物的地方的人。”

研究人员认为这些独角兽是古老的印加人的后裔,他们生活在大约2000年前的这个地区。

Williams说:“印加人是第一个将安第斯山脉作为逃避安第斯山脉严酷气候的避难所的人。”“他们也是第一个将安第斯山脉作为狩猎和采集食物的地方的人。”

研究人员认为这些独角兽是古老的印加人的后裔,他们生活在大约2000年前的这个地区。

Williams说:“印加人是第一个将安第斯山脉作为逃避安第斯山脉严酷气候的避难所的人。”“他们也是第一个将安第斯山脉作为狩猎和采集食物的地方的人。”

研究人员认为这些独角兽是古老的印加人的后裔,他们生活在大约2000年前的这个地区。
----------------------------------------------------------------------------------------------------
6.1.2. 使用核心采样生成文本:

代码:[点击展开]

torch.manual_seed(0.)
output = model.generate(input_ids, do_sample=True, max_length=512, top_p=0.95, top_k=0)
print("输出:\n" + 100 * '-')
print(tokenizer.decode(output[0], skip_special_tokens=True))
print("" + 100 * '-')

模型输出:[点击展开]

输出:
----------------------------------------------------------------------------------------------------
在一个令人震惊的发现中,科学家们发现了一群生活在安第斯山脉一个偏远、以前未被探索的山谷中的独角兽。更令研究人员感到惊讶的是,这些独角兽竟然说一口流利的英语。这项研究于2016年3月发表在《动物学杂志》上。

像独角兽这样的多配偶哺乳动物在科学界一直鲜为人知。领导这项研究的牛津大学教授古斯塔沃·贾科塔表示,他们已经有记录显示,这些动物在俄罗斯的东西伯利亚远至东方西伯利亚,但在戈壁沙漠中只见过几次。

这些毛色苍白而有光泽的微小动物生活在人类的存在之下,几乎不太可能成为任何虐待的受害者。然而,在偏远地区的人类和动物中,有一些证据表明这种情况可能存在,这可能与共存于皮肤上的“黑痣”有相似之处。

人们认为独角兽可能是内心的存在,它们根据当前环境有不同的气味,或者只是掉落下来,有很多关于它们如何生存的传说。专家们推测,飞蛾和其他动物可能是叶吉迪·伊西斯(Yezidi Isis)和查尔昂(Charon)的残余,它们字面上既是“巨鸟”一词,也是希腊语中表示声音的词。据说伊西斯和查尔昂教导他们的后代以呼唤他人的方式使用声音。

科学家们认为这可能是古老的民间传说,已经幸存下来,不再归因于真实存在的实体。
----------------------------------------------------------------------------------------------------
6.1.3. 使用对比搜索生成文本:

代码:

output = model.generate(input_ids, max_length=512, penalty_alpha=0.6, top_k=4)
print("输出:\n" + 100 * '-')
print(tokenizer.decode(output[0], skip_special_tokens=True))
print("" + 100 * '-')

模型输出:

输出:
----------------------------------------------------------------------------------------------------
在一个令人震惊的发现中,科学家们发现了一群生活在安第斯山脉一个偏远、以前未被探索的山谷中的独角兽。更令研究人员感到惊讶的是,这些独角兽竟然说一口流利的英语。

据英国广播公司报道,布里斯托尔大学的戴维·麦凯博士带领的一个科学家团队在对该地区进行调查期间,花费了两年时间寻找这群独角兽。

"这是一个非常罕见的发现,"麦凯告诉英国广播公司。"喜马拉雅山脉有一些,但这是我们首次在如此偏远的地区发现一只独角兽。"

团队对于在一个以偷猎闻名的地区发现一群生活在那里的独角兽感到惊讶,许多动物因其角而被偷猎,这些角在传统中医中用于治疗从风湿病到癌症的各种疾病。

"我们知道该地区富含犀牛角,但我们不知道有多少个,它们在那里做什么,"麦凯说。"这是一个高偷猎压力区域,我们想要弄清楚发生了什么。"

为了做到这一点,团队使用GPS项圈追踪动物在山上和周围地区的移动。然后将GPS数据与当地村民收集到的信息进行比较,这些信息包括它们在哪里进食、晚上在做什么以及它们每天在山上度过多少时间。

在分析数据后,团队确定这群独角兽至少由三个物种组成,包括一只雄性和两只雌性。其中一只雌性是雄性的母亲,另外两只是她的女儿。所有三只独角兽的角颜色相同,这被认为是动物王国中纯洁的标志。

尽管这一发现令人兴奋,但科学家们并不是第一次发现一种会说英语的动物。去年,科学家们发现了一种可以被人类听到的豪猪物种,并因其与人类交流的能力而被称为"豪猪人"。
----------------------------------------------------------------------------------------------------

6.2. 示例二 – OPT:

在这部分中,我们使用了Meta最近发布的OPT模型[5],通过从著名的ResNet论文[6]的摘要中提取前两个句子来生成文本。

更深的神经网络更难训练。我们提出了一种残差学习框架,以便训练比先前使用的网络更深的网络变得更容易。

加载语言模型并准备前缀文本:

import torch
from transformers import AutoTokenizer, OPTForCausalLM
model_name = r'facebook/opt-1.3b'
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = OPTForCausalLM.from_pretrained(model_name)

prefix_text = r"更深的神经网络更难训练。我们提出了一种残差学习框架,以便训练比先前使用的网络更深的网络变得更容易。"
input_ids = tokenizer(prefix_text, return_tensors='pt').input_ids
6.2.1. 使用贪婪搜索生成文本:

代码:[展开]

output = model.generate(input_ids, max_length=256)
print("输出结果:\n" + 100 * '-')
print(tokenizer.decode(output[0], skip_special_tokens=True))
print("" + 100 * '-')

模型输出:[展开]

输出结果:
----------------------------------------------------------------------------------------------------
更深的神经网络更难训练。我们提出了一种残差学习框架,以便训练比先前使用的网络更深的网络变得更容易。我们展示了残差学习框架可以用于训练比先前使用的网络更难训练的深度神经网络。我们还展示了残差学习框架可以用于训练比先前使用的网络更难训练的深度神经网络。

该论文提出了一种基于残差概念的深度神经网络残差学习框架。残差是在训练过程中未使用的网络的残差。通过获取在训练过程中使用的网络的残差并减去在训练过程中未使用的网络的残差,计算出这些残差。然后使用这些残差来训练网络。通过获取在训练过程中使用的网络的残差并减去在训练过程中未使用的网络的残差,计算出这些残差。然后使用这些残差来训练网络。通过获取在训练过程中使用的网络的残差并减去在训练过程中未使用的网络的残差,计算出这些残差。
----------------------------------------------------------------------------------------------------
6.2.2. 使用核心抽样生成文本:

代码:[展开]

torch.manual_seed(0.)
output = model.generate(input_ids, do_sample=True, max_length=256, top_p=0.95, top_k=0)
print("输出结果:\n" + 100 * '-')
print(tokenizer.decode(output[0], skip_special_tokens=True))
print("" + 100 * '-')

模型输出:[展开]

输出结果:
----------------------------------------------------------------------------------------------------
更深的神经网络更难训练。我们提出了一种残差学习框架,以便训练比先前使用的网络更深的网络变得更容易。该理论关注学习的几个方面,包括学习的复制和非复制方面的动力学。该框架强调了通过熵进行学习。新的随机算法使得能够通过残差学习训练网络,以便深度网络能够像传统的网络一样可靠且高效地部署。
----------------------------------------------------------------------------------------------------
6.2.3. 使用对比搜索生成文本:

代码:

output = model.generate(input_ids, max_length=256, penalty_alpha=0.6, top_k=6)
print("输出结果:\n" + 100 * '-')
print(tokenizer.decode(output[0], skip_special_tokens=True))
print("" + 100 * '-')

模型输出:

输出结果:
----------------------------------------------------------------------------------------------------
更深的神经网络更难训练。我们提出了一种残差学习框架,以便训练比先前使用的网络更深的网络变得更容易。

在本文中,我们提出了一种基于模型的残差学习(MBRL)框架,该框架基于在维度稀疏的数据上训练的神经网络(例如1、2、3等)。选择网络参数,使得收敛的概率较高,即迭代次数足够多,以最小化残差的方差。这是通过在一组维度稀疏的训练数据上训练网络,然后在训练完成后丢弃非参数化部分的数据来实现的。

我们展示了MBRL在深度强化学习(RL)和深度卷积神经网络(CNNs)方面的性能优于其他方法至少2倍。此外,我们展示了与CNN相比,MBRL在二维(2D)和三维(3D)情况下的性能更好。
----------------------------------------------------------------------------------------------------

7. 资源:

有关对比搜索的更多细节,请参阅我们的论文和代码:

  • 神经文本生成的对比框架:(1) 论文和 (2) 官方实现。
  • 对比搜索是神经文本生成所需的
    1. 论文和 (2) 官方实现。

8. 引用:

@inproceedings{su2022a,
   title={神经文本生成的对比框架},
   author={苏一萱 and 兰天 and 王艳 and Dani Yogatama and 孔令鹏 and Nigel Collier},
   booktitle={神经信息处理系统进展},
   editor={Alice H. Oh and Alekh Agarwal and Danielle Belgrave and Kyunghyun Cho},
   year={2022},
   url={https://openreview.net/forum?id=V88BafmH9Pj}
}

@article{su2022contrastiveiswhatyouneed,
  title={对比搜索是神经文本生成所需的},
  author={苏一萱 and Nigel Collier},
  journal={arXiv预印本 arXiv:2210.14140},
  year={2022}
}

参考文献:

[1] Su等人, 2022 “A Contrastive Framework for Neural Text Generation” , NeurIPS 2022

[2] Su和Collier, 2022 “Contrastive Search Is What You Need For Neural Text Generation” , Arxiv 2022

[3] Fan等人, 2018 “Hierarchical Neural Story Generation” , ACL 2018

[4] Holtzman等人, 2020 “The Curious Case of Neural Text Degeneration” , ICLR 2020

[5] Zhang等人, 2022 “OPT: Open Pre-trained Transformer Language Models” , Arxiv 2022

[6] He等人, 2016 “Deep Residual Learning for Image Recognition” , CVPR 2016


– 作者:苏一萱和兰天


致谢:

我们要感谢Joao Gante (@joaogante)、Patrick von Platen (@patrickvonplaten)和Sylvain Gugger (@sgugger)在将本博文中提到的对比搜索添加到transformers库中的过程中给予的帮助和指导。

Leave a Reply

Your email address will not be published. Required fields are marked *