助力 Python 老司机都开火箭了!Cython 实现百倍加速 NLP (助力油和液压油一样吗)

文章编号:41195 资讯动态 2024-12-03 加速CythonPythonNLP

老司机都开火箭了!Cython 助力 Python NLP 实现百倍加速

SpaceX 猎鹰重型发射器,版权归

在去年我们发布了用 Python 实现的 基于神经网络的相互引用解析包(Neural coreFerence resolution package) 之后,在社区中获得了惊人数量的反馈,许多人开始将该解析包用到各种各样的应用中,有一些应用场景甚至已经超出了我们原本设计的对话框用例(Dialog use-case)。

后来我们发现,虽然这个解析包对于对话框消息而言,解析速度完全够用,但如果要解析更大篇幅的文章就显得太慢了。

因此我决定要深入探索解决方案,并最终开发出了 NeuralCoref v3.0 。这个版本比之前(每秒解析几千字)的要快出百倍,同时还保证了相同的准确性,当然,它依然易于使用,也符合 Python 库的生态环境。

在本篇文章中,我想向大家分享我在开发 NeuralCoref v3.0 过程中学到的一些经验,尤其将涉及:

我的标题其实有点作弊,因为我实际上要谈论的是 Python,同时也要介绍一些 Cython 的特性。不过你知道吗?Cython 属于 Python 的超集,所以不要让它吓跑了!

以下给出了一些可能需要采用这种加速策略的场景:

百倍加速第一步:代码剖析

老司机都开火箭了!Cython 助力 Python NLP 实现百倍加速

你需要知道的第一件事情是,你的大部分代码在纯 Python 环境下可能都运行良好,但是其中存在一些瓶颈函数(Bottlenecks functions),一旦你能给予它们更多的「关照」,你的程序将获得几个数量级的提速。

所以你应该从剖析自己的 Python 代码开始,找出那些低效模块。其中一种方法就是使用:

你很可能会发现低效的原因是因为一些循环控制,或者你使用神经网络时引入了过多的 Numpy 数组操作(我不会花费时间在这里介绍 Numpy,这个问题已经有 太多文章 进行了讨论)。

那么我们该如何来加速循环呢?

在 Pyhthon 中加入 Cython 加速循环计算

老司机都开火箭了!Cython 助力 Python NLP 实现百倍加速

让我们通过一个简单的例子来解决这个问题。假设有一堆矩形,我们将它们存储成一个由 Python 对象(例如对象实例)构成的列表。我们的模块的主要功能是对该列表进行迭代运算,从而统计出有多少个矩形的面积是大于所设定阈值的。

我们的 Python 模块非常简单:

其中 check_rectangles 函数就是我们程序的瓶颈!它对一个很长的 Python 对象列表进行迭代,而这一过程会相当缓慢,因为 Python 解释器在每次迭代中都需要做很多工作(查找类中的方法、参数的打包和解包、调用 Python API 等等)。

Cython 语言是 Python 的一个超集,它包含有两种类型的对象:

定义这种循环最直接的一种方法就是,定义一个包含有计算过程中我们所需要用到的所有对象的结构体。具体而言,在本例中就是矩形的长度和宽度。

然后我们可以将矩形对象列表存储到 C 的结构数组中,再将数组传递给 check_rectangles 函数。这个函数现在将接收一个 C 数组作为输入,此外我们还使用关键字取代了(注意:也可以用于定义 Cython C 对象)将函数定义为一个 Cython 函数。

这里是 Cython 版本的模块程序:

这里我们使用了原生的 C 数组指针,不过你还有其它选择,特别是 C++ 中诸如向量、二元组、队列这样的结构体 。在这段程序中,我还使用了一个来自提供的内存管理对象,它可以避免手动释放所申请的 C 数组内存空间。当不再需要使用 Pool 中的对象时,它将自动释放该对象所占用的内存空间。

有很多办法来测试、编译和发布 Cython 代码。Cython 甚至可以像 Python 一样 直接用于 Jupyter Notebook 中。

通过 pip install cython 命令安装 Cython。

老司机都开火箭了!Cython 助力 Python NLP 实现百倍加速

使用 %load_ext Cython 指令在 Jupyter notebook 中加载 Cython 扩展。

然后通过指令,我们就可以像 Python 一样在 Jupyter notebook 中使用 Cython。

如果在执行 Cython 代码的时候遇到了编译错误,请检查 Jupyter 终端的完整输出信息。

大多数情况下可能都是因为在之后遗漏了标签(比如当你使用 spaCy Cython 接口时)。如果编译器报出了关于 Numpy 的错误,那就是遗漏了 import numpy

正如我在一开始就提到的,请好好阅读 这份 Jupyter notebook 和这篇文章,它包含了我们在 Jupyter 中讨论到的所有示例。

Cython 代码的文件后缀是,这些文件将被 Cython 编译器编译成 C 或 C++ 文件,再进一步地被 C 编译器编译成字节码文件。最终 Python 解释器将能够调用这些字节码文件。

你也可以使用将一个 .pyx 文件直接加载到 Python 程序中:

你也可以将自己的 Cython 代码作为 Python 包构建,然后像正常的 Python 包一样将其导入或者发布,更多细节请参考 这里 。不过这种做法需要花费更多的时间,特别是你需要让 Cython 包能够在所有的平台上运行。如果你需要一个参考样例,不妨看看 spaCy 的安装脚本 。

在我们开始优化自然语言处理任务之前,还是先快速介绍一下、和这三个关键字。它们是你开始学会使用 Cython 之前需要掌握的最主要的知识。

你可以在 Cython 程序中使用三种类型的函数:

关键字的另一个用途就是,在代码中表明某一个对象是 Cython C/C++ 对象。所以除非你在代码中使用声明对象,否则这些对象都会被解释器当做 Python 对象(这会导致访问速度变慢)。

使用 Cython 和 spaCy 加速自然语言处理

这一切看起来都很好,但是......我们到现在都还没开始涉及优化自然语言处理任务!没有字符串操作,没有 unicode 编码,也没有我们在自然语言处理中所使用的妙招。

此外 Cython 的官方文档甚至 建议不要使用 C 语言类型的字符串:

那么当我们在操作字符串时,要如何在 Cython 中设计一个更加高效的循环呢?

spaCy 处理该问题的做法就非常地明智。

将所有的字符串转换为 64 位哈希码

spaCy 中所有的 unicode 字符串(一个标记的文本、它的小写形式文本、它的引理形式、POS 标记标签、解析树依赖标签、命名实体标签等等)都被存储在一个称为 Stringstore 的数据结构中,它通过一个 64 位哈希码 进行索引,例如 C 类型的。

老司机都开火箭了!Cython 助力 Python NLP 实现百倍加速

StringStore 对象实现了 Python unicode 字符串与 64 位哈希码之前的查找映射。

它可以从 spaCy 的任何地方和任意对象进行访问,例如 npl.vocab.strings doc.vocab.strings 或者 span.doc.vocab.string

当某一个模块需要在某些标记(tokens)上获得更快的处理速度时,你可以使用 C 语言类型的 64 位哈希码代替字符串来实现。调用 StringStore 查找表将返回与该哈希码相关联的 Python unicode 字符串。

但是 spaCy 能做的可不仅仅只有这些,它还允许我们访问文档和词汇表完全填充的 C 语言类型结构,我们可以在 Cython 循环中使用这些结构,而不必去构建自己的结构。

与 spaCy 文档有关的主要数据结构是 Doc 对象,该对象拥有经过处理的字符串的标记序列(“words”)以及 C 语言类型对象中的所有标注,称为,它是一个 TokenC 的结构数组。

TokenC 结构包含了我们需要的关于每个标记的所有信息。这种信息被存储成 64 位哈希码,它可以与我们刚刚所见到的 unicode 字符串进行重新关联。

如果想要准确地了解这些漂亮的 C 结构中的内容,可以查看新建的 spaCy 的 Cython API 文档 。

接下来看一个简单的自然语言处理的例子。

假设现在有一个文本文档的数据集需要分析。

我写了一个脚本用于创建一个包含有 10 份文档的列表,每份文档都大概含有 17 万个单词,采用 spaCy 进行分析。当然我们也可以对 17 万份文档(每份文档包含 10 个单词)进行分析,但是这样做会导致创建的过程非常慢,所以我们还是选择了 10 份文档。

我们想要在这个数据集上展开某些自然语言处理任务。例如,我们可以统计数据集中单词「run」作为名词出现的次数(例如,被 spaCy 标记为「NN」词性标签)。

采用 Python 循环来实现上述分析过程非常简单和直观:

但是这个版本的代码运行起来非常慢!这段代码在我的笔记本上需要运行 1.4 秒才能获得答案。如果我们的数据集中包含有数以百万计的文档,为了获得答案,我们也许需要花费超过一天的时间。

我们也许能够采用多线程来实现加速,但是在 Python 中这种做法并不是那么明智 ,因为你还需要处理 全局解释器锁(GIL) 。另外请注意,Cython 也可以 使用多线程 !Cython 在后台可以直接调用 OpenMP。不过我没有时间在这里讨论并行性,所以请查看 此链接 以了解更多详情。

现在让我们尝试使用 spaCy 和 Cython 来加速 Python 代码。

首先需要考虑好数据结构,我们需要一个 C 类型的数组来存储数据,需要指针来指向每个文档的 TokenC 数组。我们还需要将测试字符(「run」和「NN」)转成 64 位哈希码。

当所有需要处理的数据都变成了 C 类型对象,我们就可以以纯 C 语言的速度对数据集进行迭代。

这里展示了这个例子被转换成 Cython 和 spaCy 的实现:

代码有点长,因为我们必须在调用 Cython 函数之前在 main_nlp_fast 中声明和填充 C 结构。

这串代码虽然变长了,但是运行效率却更高!在我的 Jupyter notebook上,这串 Cython 代码只运行了大概 20 毫秒,比之前的纯 Python 循环快了大概 80 倍。

使用 Jupyter notebook 单元编写模块的速度很可观,它可以与其它 Python 模块和函数自然地连接:在 20 毫秒内扫描大约 170 万个单词,这意味着我们每秒能够处理高达 8 千万个单词。

对使用 Cython 进行自然语言处理加速的介绍到此为止,希望大家能喜欢它。

关于 Cython 还有很多其它的东西可以介绍,但是已经超出了这篇文章的初衷(这篇文章只是作为简介)。从现在开始,最好的资料也许是这份综述性的 Cython 教程 和介绍 spaCy 自然语言处理的 Cython 页面 。

如果你还想要获得更多类似的内容,请记得给我们点赞哟!

Via 100 Times Faster Natural Language PROcessing in Python ,雷锋网 AI 研习社编译整理

版权文章,未经授权禁止转载。详情见 转载须知 。

老司机都开火箭了!Cython 助力 Python NLP 实现百倍加速

全局中部横幅
深圳市前程网络科技服务中心,南山西丽电脑上门维修组装升级

深圳市前程网络科技服务中心,南山西丽电脑上门维修组装升级、网络IT维护运维外包、数据恢复、计算机配件、联想lenovo,戴尔DELL,华硕ASUS,华为HUAWEI,小米MI,苹果APPLE,惠普HP,宏基ACER等品牌代理销售,网络设备,打印复印机出租,硒鼓加粉,监控摄像头,共享网管,智能WIFI覆盖,网站建设,小程序开发,电信宽带,电脑及配件回收等

最新热门电视剧分集剧情介绍

剧情百科网是专业的电视剧分集剧情介绍网站,提供最新热门电视剧及分集剧情介绍,热门电影剧情介绍及演员表资料等.看剧情,就来剧情百科!

大鱼吃小鱼小游戏,大鱼吃小鱼小游戏大全,4399大鱼吃小鱼小游戏全集,4399小游戏

4399大鱼吃小鱼小游戏大全收录了国内外大鱼吃小鱼类小游戏、大鱼吃小鱼2中文版、大鱼吃小鱼单机游戏、大鱼吃小鱼无敌版、大鱼吃小鱼下载。好玩就拉朋友们一起来玩吧!

商洛之窗

商洛之窗是商洛日报社主办的综合性新闻网站。突现商洛特色,追求本土一流权威媒体品质,突出新闻性、娱乐性、资料性,重点覆盖商洛网民。

散热风扇,三匠电脑用鼓风机,三匠支架风扇,三匠鼓风机

广东健策电子有限公司专业代理三匠散热风扇,三匠鼓风机,微型电脑鼓风机,支架风扇

中医

轻壹是专注中医健康养生的知识分享平台,收集大数据中医健康养生大数据,中医养生视频,中医电子书,中医视频课程,穴位视频功效应用解读,中医药材方剂;传播贴切生活的健康养生知识,针灸、艾灸、推拿、等中医小知识等;提升大众基础健康理念。

首页

深圳市披克科技有限公司是一家以打造门禁管理系统的整体安全解决方案为愿景的科技创新企业。公司产品线丰富,涵盖了非接触式IC卡的各个应用领域,包括智能访客系统、手机门禁系统、智慧停车系统、电梯管理系统、车辆出入管理系统、车位引导及反向寻车、智能车牌识别等,

首页

安徽庆卓网络科技有限公司

孝感市欣宁净化科技有限公司

孝感市欣宁净化科技有限公司创建于2008年,是一家专业从事洁净室及相关授控环境系统工程设计、咨询、施工及激光打标加工,并经营空调设备及五金水暖材料为一体的专业化企业。本公司以孝感市为公司总部

长沙居居侠自装口碑平台,家装业主自装就找居居侠,0佣金找装修师傅

居居侠APP是隶属于湖南居居时代数字科技有限公司一家以信息智能动态交付技术为核心的口碑自装交付平台公司以工匠服务驱动研发,攻克家装行业最难以解决的施工批量交付难题,同时打通F2C家装全案供应链,结合公司智能可视化预算系统以及DIY选款系统,并通过12年互联网技术沉淀,砍掉90%订单运营成本,为业主打造设计、施工、材料一体化的超高信价比的新型自装模式。

首页

寿光市彤泰防水材料有限公司,创建于2003年,是一个集防水材料研制、开发、生产销售、设计施工于一体的专业化新型防水材料生产企业。

全局底部横幅