老司机都开火箭了!Cython助力PythonNLP实现百倍加速雷峰网

如何才能够使用Python设计出一个高效率的模块,

如何利用好spaCy的内置数据结构,从而设计出超高效的自然语言处理函数。

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

小提示:你当前所编写的Python项目已经算是一个Cython项目了。

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

你正在使用Python给自然语言处理任务开发一个应用级模块

你正在使用Python分析一个自然语言处理任务的大型数据集

你正在为诸如PyTorch/TensoFlow这些深度学习框架预处理大型训练集,或者你的深度学习模型采用了处理逻辑复杂的批量加载器(Batchloader),它严重拖慢了你的训练速度

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

importcProfile

importpstats

importmy_slow_module

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

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

我们的Python模块非常简单:

fromrandomimportrandom

classRectangle:

def__init__(self,w,h):

self.w=w

self.h=h

defarea(self):

returnself.w*self.h

defcheck_rectangles(rectangles,threshold):

n_out=0

forrectangleinrectangles:

ifrectangle.area()>threshold:

n_out+=1

returnn_out

defmain():

n_rectangles=10000000

rectangles=list(Rectangle(random(),random())foriinrange(n_rectangles))

n_out=check_rectangles(rectangles,threshold=0.25)

print(n_out)

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

这时候该有请Cython出场帮助我们加速循环操作了。

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

Python对象就是我们在常规Python中使用到的那些对象,诸如数值、字符串、列表和类实例等等

CythonC对象就是那些C和C++对象,诸如双精度、整型、浮点数、结构和向量,它们能够由Cython在超级高效的低级语言代码中进行编译

该循环只要采用Cython进行复现就能获得更高的执行速度,不过在Cython中我们只能够操作CythonC对象。

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

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

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

fromcymem.cymemcimportPool

cdefstructRectangle:

floatw

floath

cdefintcheck_rectangles(Rectangle*rectangles,intn_rectangles,floatthreshold):

cdefintn_out=0

#Carrayscontainnosizeinformation=>weneedtogiveitexplicitly

forrectangleinrectangles[:n_rectangles]:

ifrectangle[i].w*rectangle[i].h>threshold:

cdef:

intn_rectangles=10000000

floatthreshold=0.25

Poolmem=Pool()

Rectangle*rectangles=mem.alloc(n_rectangles,sizeof(Rectangle))

foriinrange(n_rectangles):

rectangles[i].w=random()

rectangles[i].h=random()

n_out=check_rectangles(rectangles,n_rectangles,threshold)

通过pipinstallcython命令安装Cython。

使用%load_extCython指令在Jupyternotebook中加载Cython扩展。

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

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

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

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

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

>>>importpyximport;pyximport.install()

>>>importmy_cython_module

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

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

Python函数由def关键字定义,它的输入和输出都是Python对象。在函数内可以使用Python和C/C++对象,并且能够调用Cython和Python函数。

Cython函数由cdef关键字进行定义,它可以作为输入对象,在函数内部也可以操作或者输出Python和C/C++对象。这些函数不能从Python环境中访问(即Python解释器和其它可以导入Cython模块的纯Python模块),但是可以由其它Cython模块进行导入。

通过关键字cpdef定义的Cython函数与cdef定义的Cython函数很相似,但是cpdef定义的函数同时还提供了Python装饰器,所以它们能够在Python环境中被直接调用(函数采用Python对象作为输入与输出),此外也支持在Cython模块中被调用(函数采用C/C++或者Python对象作为输入)。

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

通常来说:除非你明确地知道自己正在做什么,不然就该避免使用C类型字符串,而应该使用Python的字符串对象。

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

spaCy引起了我们的注意力。

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

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

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

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

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

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

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

importurllib.request

importspacy

text=response.read()

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

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

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

defslow_loop(doc_list,word,tag):

fordocindoc_list:

fortokindoc:

iftok.lower_==wordandtok.tag_==tag:

defmain_nlp_slow(doc_list):

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

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

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

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

%%cython-+

fromspacy.tokens.doccimportDoc

fromspacy.typedefscimporthash_t

fromspacy.structscimportTokenC

cdefstructDocElement:

TokenC*c

intlength

cdefintfast_loop(DocElement*docs,intn_docs,hash_tword,hash_ttag):

fordocindocs[:n_docs]:

forcindoc.c[:doc.length]:

ifc.lex.lower==wordandc.tag==tag:

defmain_nlp_fast(doc_list):

cdefinti,n_out,n_docs=len(doc_list)

cdefPoolmem=Pool()

cdefDocElement*docs=mem.alloc(n_docs,sizeof(DocElement))

cdefDocdoc

fori,docinenumerate(doc_list):#Populateourdatabasestructure

docs[i].c=doc.c

docs[i].length=(doc).length

n_out=fast_loop(docs,n_docs,word_hash,tag_hash)

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

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

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

THE END
1.python之开发笔记pyecharts - A Python Echarts Plotting Library built with love. Document --javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown #导包 from pyecharts.charts import Line from pyecharts.options import TitleOpts,LegendOpts,ToolboxOpts,VisualMapOpts ...http://www.kler.cn/a/412211.html
2.用python画漂亮的航天火箭python航天00:00/00:00 用python画漂亮的航天火箭 楚姣贤说发布于:上海市2022.09.27 09:26 分享到 用python画漂亮的航天火箭https://learning.sohu.com/a/588285685_120145551
3.用Python解释SpaceX如何进行火箭回收对我而言有两种可能:1、我非常幸运,2、SpaceX在其实际系统上运行了非常相似的优化。这是一个非常有趣的东西,希望能为进入火箭回收后面的魔法打开一扇窗户。在开始编写代码之前,可能最好先解释一下轨迹优化的理论(但如果您愿意,也可以直接跳转至代码)。 https://www.360doc.cn/article/18334519_988378871.html
4.抗日奇侠2全集观看抗日奇侠第二部免费实况网当前视点!点火,他们为火箭飞天发令——记西昌卫星发射中心西昌发射场“01”指挥员团队 2023-04-25 【环球热闻】校园美育新实践:“校服可以更美哒”设计大赛收官,优秀作品将走进校园 2023-04-25 我爱涨停钟(永赢基金) 2023-04-25 日本举行国会补选 执政党自民党“4胜1负” 2023-04-25 10只主板新股首...http://m.cqtimes.cn/news/redian/20230427/218076.html
5.cmp.lhkjq.com/storify/2826170.html火箭军李玉超之子 动漫美女被狂揉下部?羞羞网站 蘑菇视频国产免费软件小说 2023年国精产品一区二区 桃色成人国产AV在线电影 美国式桥矿第一集 二炮司令李玉超泄密事件 Free?护士变态 免费又硬又爽又粗大片 张津瑜记者卫生间1080 国产精品无码久久久 美女被爆?羞羞网站视频 91精品国产麻豆国产...http://cmp.lhkjq.com/storify/2826170.html
1.用python画机甲mob64ca12eee07b的技术博客用python画机甲 用Python 绘制机甲的完整指南 绘制机甲是一项很有趣的任务,尤其是对于刚入门的小白朋友。通过 Python,我们可以利用一些强大的库来完成这一任务。本文将详细介绍如何使用 Python 来绘制一个机甲,并带你逐步了解每一步的工作。 整体流程 在开始之前,我们需要明确整个绘制流程。以下是完成此任务的步骤:...https://blog.51cto.com/u_16213425/12691198
2.OpenRocket——一款功能强大易于上手的模型火箭模拟器相信每个过年玩钻天猴的小伙伴在小时候都有个造火箭的梦想,今天给大家推荐一个开源火箭设计工具OpenRocket。这款免费且功能全面的模型火箭模拟器,为爱好者们提供了一个从设计到模拟的完整平台,让梦想在虚拟世界中先行翱翔。 一、软件介绍 OpenRocket允许用户通过丰富的内置组件进行火箭设计。无论是选择合适的发动机、调整...https://blog.csdn.net/fitAllEnv/article/details/144164603
3.编程代码绘制火箭的奇妙之旅火箭发射scratch代码在许多人的眼中,火箭是探索太空、征服宇宙的象征,而编程代码则是现代科技的基石,它们共同构成了我们这个时代的科技奇迹,将这两者结合在一起,我们可以用编程代码来绘制火箭,这不仅是一种技术挑战,更是一种艺术创作。 编程语言的选择 要绘制火箭,首先需要选择一种合适的编程语言,Python因其简洁易懂的语法和强大的功能...http://www.skypure.com.cn/post/552.html
4.www.juntengtech.cn/newxr45691322/47220827.htm火箭少女的开襟乳液狂飙 18.65MB 80%好评382人 调查 制服下裸全着航空6 八重神子给旅行者喂乳液视频 77.37MB 12%好评312人 2022仙踪林婚纱摄影工作室 亚洲逼院 十大污黄app 74.59MB 50%好评702人 爱情岛1号线2线3线 99久久国产精品免费热99 多田有花人妻秘书汗电影 34.40MB 22%好评172...http://www.juntengtech.cn/newxr45691322/47220827.htm
5.h.miaoji007.com/newxr84265537.shtml火箭少女和平精英 38.57MB 82%好评777人 嫩草一二三线路 久久亚洲精品日韩高清 荔枝视频黄 24.63MB 28%好评783人 FOhup精XXX老太 张律渝和吕总落地窗下的奇遇 巨茎人妖出精汇汇HD 84.45MB 11%好评69人 国精产品一区二区三区糖心下载 少妇愉情理仑片高潮 zzzz色wwww 94.57MB 33%好评22人...https://h.miaoji007.com/newxr84265537.shtml
6.www.jxmzxx.com{$woaini}>www.jxmzxx.com{$woaini}为了成为内马尔的正牌女友, 布鲁娜签署了多么奇葩的协议? 为了成为内马尔的正牌女友,布鲁娜签署了多么奇葩的协议?虽然布鲁娜比安卡迪是内马尔的女朋友,但她只有内马尔的部分使用权,原因是他们之间签署了一份十分奇葩的恋爱协议,协议允许内马尔和其他女人调情甚至发生关系,但对内马尔有三条约束,分别是不能找应召女郎,不能...http://www.jxmzxx.com/appnews/668449.html
7.quan.zjsuedu.com/yyys/59000716.htm火箭少女操逼 美女100%露奶头无遮无掩 欧美经典多交性爱高清多p 86.96MB 993好评 蛋蛋爆了表情表情包gif动图 爽爽淫人网 替夫还债 28.51MB 211好评 会员试看60 teensⅩXHD 92手机看片 25.52MB 930好评 亚洲午夜精品久久久久久成年 啪啪高潮软件 精品久久精品久久人妻 94.26MB 803好评 下...http://quan.zjsuedu.com/yyys/59000716.htm
8.wy.chaobiaomao.com/mmmj/275724.shtml火箭少女吃坤吧 60.51MB 09%好评4804人) 男女?羞羞视频网站免费 看亚洲美女色色 久草大香蕉手机在线 99.72MB 62%好评02人) 胖女人一级片 干少妇逼 老少配xxxxx欧美 68.91MB 81%好评036人) 久久久久亚洲AV成人人小说 下载中国的三级片 小毛驴在线影院 35.20MB 63%好评797人) 就要草人...http://wy.chaobiaomao.com/mmmj/275724.shtml
9.www.zjmj.cn/ttkll11火箭军司令员李玉超被 351.59MB 441好评 男人把j捅进美女的p里全过程无遮挡 國内中年壮熊洗澡自慰网站 自拍偷拍激情小说 426.71MB 262好评 虐乳AV 暴操狂插黑丝制服老师熟女老师大肥屁股 骚逼扣逼乳交 312.77MB 549好评 出差被上司连续我失去理智在线播放 https://www.zjmj.cn/ttkll11_26/71970.html
10.web.yjsuoj.com/nodenews/830013.shtml撞 火箭少女 边做饭边被躁我和邻居的 91精品乱码一区二区三区 韩国地线观看一二三四区 《法国空乘电影完整版在线观看视频免费》 扒开她的黑森林让我添动态图 偷尝禁果H1V1幸运的山熊 44447777亚洲 日小穴内射到爆免费视频 品色堂永远的免费论坛 敌伦交换第11部分白洁 你怎么这么耐C啊秦菲雨 极品国模于...http://web.yjsuoj.com/nodenews/830013.shtml
11.练习导入Python库和火箭发射数据Python复制 launch_data = pd.read_excel('RocketLaunchDataCompleted.xlsx') launch_data.head() 开始浏览数据 最后,我们可使用.columns函数调用来查看数据中的所有列。 这会向我们显示数据具有的属性。 你将看到一些常见属性,例如过去计划发射的火箭的名称、计划发射日期、实际是否已发射等等。 请查看这些列,并试...https://docs.microsoft.com/zh-cn/learn/modules/collect-manipulate-data-python-nasa/4-import-data/
12.火箭的控制原理——TVC与钱学森弹道火箭的控制 TVC姿态控制 假设我们的喷嘴是矢量喷口,则我们可以用δz和δy表达喷管的偏角。则δ?和δω分别表达俯仰和偏航的等效角。对应的?和ω对应俯仰角和偏航角,那么我们可以得到: δz=cosωxtδ?+sinωxtδωδy=?sinωxtδ?+cosωxtδω...https://blog.minloha.cn/posts/11152241a306b22024081544.html
13.程序员炫酷溜娃!用代码画地球日月的动态轨道模型来源|Python作业辅导员 无言相守45亿年,太阳、地球和月球这三个好基友究竟是怎样的关系呢?从孩提时代我就一直在想,要是能有一个可以直观演示太阳、地球和月球运行轨迹的模型就好了。今天,我终于实现了小时候的梦想:用WxGL画出了太阳、地球和月球的动态轨道模型。配上简单的解说,小朋友也可以秒懂四季更迭、日蚀月蚀...https://cloud.tencent.com/developer/article/2282228