Cython中使用Ray报@ray.remote装饰器需作用于函数/类错误如何解决
报错根因
报错由两个问题共同触发:
setup.py中重复调用了两次setup(),第二次调用会完全覆盖第一次的Cython编译配置,导致cythonize的编译逻辑根本没有生效,最终用默认参数编译Cython代码。- Cython默认编译参数下,
def定义的函数会被生成为cyfunction类型而非Python原生的function类型,@ray.remote装饰器做入参类型校验时,识别不了该类型,就会抛出类型错误。
修复步骤
- 修正
setup.py配置,删除重复的setup调用,添加必要的Cython编译指令:
from distutils.core import setup from Cython.Build import cythonize import numpy setup( ext_modules=cythonize( "ray_cython.pyx", language_level=3, # 和你本地使用的Python大版本保持一致,用Python2就填2 compiler_directives={"binding": True} # 核心配置:让Cython编译生成符合Python类型检查规则的函数包装对象 ), include_dirs=[numpy.get_include()] ) # 编译命令保持不变:python setup.py build_ext --inplace
- 修改
ray_cython.pyx的代码,不要直接在函数上叠加@ray.remote装饰器,改为先定义普通函数,再显式调用ray.remote()做包装(该写法兼容所有Ray版本,不会触发装饰器加载时的类型校验问题):
from numpy import linalg as LA import time import ray cimport numpy as np np.import_array() DTYPE = np.int ctypedef np.int_t DTYPE_t # 先定义普通def函数,注意不要用cdef/cpdef定义需要被Ray调度的函数,这类C原生函数无法被Ray序列化 def myfunction(): # 填入你自己的业务逻辑 pass # 显式包装为Ray远程函数 myfunction = ray.remote(myfunction)
注意事项
- 被Ray调度的函数必须用
def定义,不能用cdef/cpdef,后者是C层级函数,不支持Python序列化,无法被Ray分发到工作节点执行。 - 远程函数的参数、返回值都必须是可被pickle序列化的Python对象,不要直接传Cython定义的cdef类实例、C指针这类非Python对象。
内容的提问来源于stack exchange,提问作者Eciel
相关产品推荐
相关产品推荐

