我即将参与NLP相关项目,我需要使用各种库。一些是在Java中,另一些是在C / C ++中(对于需要更高速度的任务),最后一些是在Python中。我正在考虑使用Python作为“粘合剂”,并为每个我想要做的依赖于不同语言的任务创建包装类。为了做到这一点,例如,包装类将执行java程序并使用管道与它通信。 我的问题是:
您认为这对cpu要求高且重复性高的任务有用吗?或管道通信增加的开销是否过重?
您建议使用其他(最好是简单的)架构吗?
答案 0 :(得分:5)
我只是建议不要这样做。
不要在C / C ++中实现“for speed”。性能优势不可能与您期望的一样高;例如与使用“最佳实践”设计和性能技术在Java中实现相比。
不要尝试将许多语言粘合在一起。您正在为自己设置许多可移植性问题,调试困难和可靠性问题;例如由于C / C ++错误导致JVM崩溃。此外,语言之间的桥接存在性能开销,并且可能存在意外的瓶颈。 (例如,您可能会发现由于线程问题,您的C / C ++必须运行单线程,因此您无法在典型的多核系统上获得Java多线程的好处。)
相反,我建议您查找允许您使用一种语言实现整个应用程序的库。如果不可能,请将其设计为不同的语言组件是不同的可执行文件/进程,通过某种RPC,消息传递或其他方式进行通信。
答案 1 :(得分:1)
您是否在通过管道/套接字进行通信时遇到问题与任务的CPU密集程度无关,而是您需要在进程之间发送信息以及需要发送多少数据的频率。设置线程进行通信几乎没有处理开销。
您可以使用Python(SWIG,ctypesgen,Boost.Python)自动包装C / C ++代码,因此您自己编写的唯一粘合剂就是在谈论到Java。
你也可以这样做 - 用Jython在JVM中运行Python代码,这样Python和Java代码就在一起,然后从那里与C / C ++对话。
答案 2 :(得分:1)
你应该看看Apache UIMA。它专为此而设计。来自项目网站:
Frameworks运行组件,可用于Java和C ++。 Java Framework支持运行Java和非Java组件(使用C ++框架)。 C ++框架除了支持用C / C ++编写的注释器外,还支持Perl,Python和TCL注释器。
UIMA可以管理管道和注释器,并且可以按比例构建。
答案 3 :(得分:0)
答案 4 :(得分:0)
1)您认为这对cpu要求高且重复性高的任务有用吗?或者管道通信增加的开销是否过重?
取决于你的任务。如果这是一个典型的NLP应用程序,你在内存中加载了一个大型模型,并且你只传递相对较小的数据(字符串,标签序列/解析树),它可能会起作用。然而,管道通信很难做到,因为你必须解决很多缓冲和同步问题。 Python是一种非常好的粘合语言,但它并不能解决所有问题。
2)你会建议其他(最好是简单的)架构吗?
制作NLP组件服务并通过REST接口连接它们。有现成的工具可以做到这一点,例如: CLAM。 Pyro和SPIRO使Java和Python之间的通信更加直接,并且可能比HTTP / REST(但是YMMV)更容易使用。
用C / C ++编写的部分也可以使用Cython与CPython集成。不要在C或C ++中开始实现,因为你认为它们会更快;您也可以先在Python中实现它们,然后看看您是否可以使用NumPy和/或Cython获得所需的性能。