如何让自己的Python快100倍?spaCy和Cython实现…
2018-07-18 01:15:56来源:博客园 阅读 ()
所以我在这里有点作弊,因为我们会谈论 Python,但也谈论一些 Cython 的神奇作用。但是,你知道吗?Cython 是 Python 的超集,所以不要让它吓跑你!
你现在的 Python 程序已经是 Cython 程序。
有几种情况下你可能需要加速,例如:
- 你正在使用 Python 开发一个 NLP 的生产模块;
- 你正在使用 Python 计算分析大型 NLP 数据集;
- 你正在为深度学习框架,如 PyTorch /TensorFlow,预处理大型训练集,或者你的深度学习批处理加载器中的处理逻辑过于繁重,这会降低训练速度。
让我们用一个简单的例子来分析这个问题。假设我们有一大堆矩形,并将它们存储进一个 Python 对象列表,例如 Rectangle 类的实例。我们的模块的主要工作是迭代这个列表,以便计算有多少矩形的面积大于特定的阈值。
我们的 Python 模块非常简单,如下所示:
我们在这里使用了原生 C 指针数组,但你也可以选择其他选项,特别是 C ++ 结构,如向量、对、队列等。在这个片段中,我还使用了 cymem 的便利的 Pool()内存管理对象,以避免必须手动释放分配的 C 数组。当 Pool 由 Python 当做垃圾回收时,它会自动释放我们使用它分配的内存。
在 Jupyter 的第一次测试
使用 %load_ext Cython 将 Cython 插件加载到 Jupyter notebook 中。
现在,你可以使用黑魔术命令 %% cython 编写像 Python 代码一样的 Cython 代码。
如果在执行 Cython 单元时遇到编译错误,请务必检查 Jupyter 终端输出以查看完整的信息。
大多数情况下,在 %% cython 编译为 C ++(例如,如果你使用 spaCy Cython API)或者 import numpy(如果编译器不支持 NumPy)之后,你会丢失 - + 标记。
- Python 函数,用常用的关键字 def 定义。它们可作为输入和输出的 Python 对象。也可以在内部同时使用 Python 和 C / C ++ 对象,并可以调用 Cython 和 Python 函数。
- 用 cdef 关键字定义的 Cython 函数。它们可以作为输入,在内部使用并输出 Python 和 C / C ++对象。这些函数不能从 Python 空间访问(即 Python 解释器和其他可导入 Cython 模块的纯 Python 模块),但可以由其他 Cython 模块导入。
- 用 cpdef 关键字定义的 Cython 函数就像 cdef 定义的 Cython 函数一样,但它们也提供了一个 Python封装器,因此可以从 Python 空间(以 Python 对象作为输入和输出)以及其他 Cython 模块(以 C / C ++ 或 Python 对象作为输入)中调用它们。
它可以通过 spaCy 任意处及任意对象访问(请参阅上图),例如 nlp.vocab.strings、doc.vocab.strings 或 span.doc.vocab.string。
当某个模块需要对某些 token 执行快速处理时,仅使用 C 级别的 64 位哈希码而不是字符串。调用 StringStore 查找表将返回与哈希码相关联的 Python unicode 字符串。
6我在左边写了一个脚本,它生成用于 spaCy 解析的 10 份文档的列表,每个文档大约 170k 字。我们也可以生成每个文档 10 个单词的 170k 份文档(比如对话数据集),但创建速度较慢,因此我们坚持使用 10 份文档。
我们想要在这个数据集上执行一些 NLP 任务。例如,我们想要统计数据集中单词「run」作为名词的次数(即用 spaCy 标记为「NN」词性)。
一个简单明了的 Python 循环就可以做到:
但它也很慢!在我的笔记本电脑上,这段代码需要大约 1.4 秒才能得到结果。如果我们有一百万份文件,则需要一天以上才能给出结果。
我们可以使用多线程,但在 Python 中通常不是很好的解决方案,因为你必须处理 GIL。另外,请注意,Cython 也可以使用多线程!而且这实际上可能是 Cython 最棒的部分,因为 GIL 被释放,我们可以全速运行。Cython 基本上直接调用 OpenMP。
代码有点长,因为我们必须在调用 Cython 函数之前在 main_nlp_fast 中声明并填充 C 结构。(如果你在代码中多次使用低级结构,使用 C 结构包装的 Cython 扩展类型来设计我们的 Python 代码是比每次填充 C 结构更优雅的选择。这就是大多数 spaCy 的结构,它是一种结合了快速,低内存以及与外部 Python 库和函数接口的简便性的非常优雅的方法。)
但它也快很多!在我的 Jupyter Notebook 中,这个 Cython 代码的运行时间大约为 20 毫秒,比我们的纯 Python 循环快大约 80 倍。
进群:125240963 即可获取数十套PDF哦!
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- python3基础之“术语表(2)” 2019-08-13
- python3 之 字符串编码小结(Unicode、utf-8、gbk、gb2312等 2019-08-13
- Python3安装impala 2019-08-13
- 小白如何入门 Python 爬虫? 2019-08-13
- python_字符串方法 2019-08-13
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash