0

执行 @ray.remote 函数时,会引发以下异常,即使我提供了函数定义中设置的所有参数:

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ray/signature.py in extend_args(function_signature, args, kwargs)
    208                     raise Exception("No value was provided for the argument "
    209                                     "'{}' for the function '{}'.".format(
--> 210                                         keyword_name, function_name))
    211 
    212     no_positionals = len(arg_is_positionals) == 0 or not arg_is_positionals[-1]

Exception: No value was provided for the argument 'phones' for the function 'compile_file'.

编辑:我的远程函数定义和远程调用的最小示例如下:

import ray
ray.init(num_cpus=4, num_gpus=1, include_webui=False) #initialize ray with 4 CPUs

@ray.remote
def compile_file(self, rgx_patts, phones): # method for my Case class

    self._phones = self.phonelist(rgx_patts, phones)

def compile_all(inputDirectory='C/TODOS', phones = ['10002000']):  
   d = {}
   file_lst = pdfLister(inputDirectory, termin)
   for i, file in enumerate(file_lst):
      doc = Case(file)
      doc.compile_file.remote(rgx_patts, phones) # exception thrown here
      d[i] = doc
   case_dic = {k: ray.get(dic_id) for k, dic_id in d.items()}
   return case_dic

编辑:下面的完整例外

   ---------------------------------------------------------------------------
   Exception                             Traceback (most recent call last)
   <timed exec> in <module>()

   ~/compile_files.py in compile_all(pckle, inputDirectory,   pickle_op_file, termin, rgx_patts, ceav_phones)
    111                             prm._rgx_patts, prm._ceav_phones)
    114             d[i] = doc
    115         ceav_dic = {k: ray.get(dic_id) for k, dic_id in d.items()}

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ray/remote_function.py in remote(self, *args, **kwargs)
    103     def remote(self, *args, **kwargs):
    104         """This runs immediately when a remote function is called."""
--> 105         return self._submit(args=args, kwargs=kwargs)
    106 
    107     def _submit(self,

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ray/remote_function.py in _submit(self, args, kwargs, num_return_vals, num_cpus, num_gpus, resources)
    118         kwargs = {} if kwargs is None else kwargs
    119         args = ray.signature.extend_args(self._function_signature, args,
--> 120                                          kwargs)
    121 
    122         if num_return_vals is None:

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ray/signature.py in extend_args(function_signature, args, kwargs)
    208                     raise Exception("No value was provided for the argument "
    209                                     "'{}' for the function '{}'.".format(
--> 210                                         keyword_name, function_name))
    211 
    212     no_positionals = len(arg_is_positionals) == 0 or not arg_is_positionals[-1]

   Exception: No value was provided for the argument 'ceav_phones' for the function 'compile_file'.
4

2 回答 2

3

在您的示例中,compile_file似乎是类的方法,但未提供类定义。

我建议将所有内容都移到compile_file函数中,使其成为一个独立的函数,例如,

import ray

ray.init(num_cpus=4, num_gpus=1)

class Case(object):
    def __init__(self, file):
        pass

    def compile_file(self):
        pass

@ray.remote
def compile_file_helper(file):
    case = Case(file)
    case.compile_file()

value_ids = []
for file in ['file1', 'file2', 'file3']:
    value_ids.append(compile_file_helper.remote(file))

values = ray.get(value_ids)

另一种选择是让Case班级成为演员。例如,

# This assumes you've already called "import ray" and "ray.init()".

@ray.remote
class Case(object):
    def __init__(self, file):
        pass

    def compile_file(self):
        pass

# Create one actor per file (more generally, you could create a pool
# of actors and have each actor compile multiple files).
value_ids = []
for file in ['file1', 'file2', 'file3']:
    case = Case.remote(file)
    value_ids.append(case.compile_file.remote())

values = ray.get(value_ids)

在这个例子中,我们只对每个actor调用一个方法,但是,这种方法只有在你要为每个actor调用多个方法时才有意义。

于 2019-01-21T08:15:13.493 回答
1

异常的原因是您的远程函数需要三个参数:self、rgx_patts 和phones,因为它是这样声明的:

@ray.remote
def compile_file(self, rgx_patts, phones): 

请注意,您在调用中只向它传递了两个参数:

doc.compile_file.remote(rgx_patts, phones)

第一个参数被解释为 self,第二个参数被解释为 rgx_patts,并且没有为电话传递参数,因此出现异常。一种可能的解决方法是将对象(在您的示例中为文档)作为您的第一个参数传递,这样调用将变为:

doc.compile_file.remote(doc, rgx_patts, phones)

这看起来有点不靠谱,但我认为它应该可以工作——事实上它在类似的情况下对我有用,尽管我无法针对你的情况对其进行测试,因为你的代码示例不是自包含的。如果您使用此解决方案,并且doc是同一时间,您可能只想使用ray.put()序列化doc一次,而不是每次调用该方法。为此,您可以doc_id = ray.put(doc)(仅执行一次)然后在上面的代码中替换为(doc是序列化的对象 id )。doc_iddoc_iddoc

请注意,另一种解决方案是将您的类转换为Actor,如果您的类具有需要在调用方法之间存储在内存中的“状态”,这似乎是合适的。

于 2018-10-20T07:13:23.513 回答