How to import actor that contains inherited class from other module?

System model

  • Python : 3.8.8
  • Ray : 1.9.1
  • IDE : Jupyter Notebook
  • OS : Windows 10, 64bit

I am currently trying to start an actor that contains inherited class.
My problem situation can be divided into three categories.

First of all, there is an inheritance class in one file.

It works well!

#main.ipynb
import ray

ray.init()

class para(object):
    def __init__(self):
        self.para = 1
        
@ray.remote
class Person(para):
    def __init__(self):
        super().__init__()
    
    def heritage(self):
        return self.para 
    
people = Person.remote()
ray.get(people.heritage.remote())    

Second, When importing a class without an inherited class from another file,

It works well!

#a.ipynb
import ray
import numpy as np

@ray.remote
class Person(object):
    def __init__(self):
        self.name = np.random.choice(['Jon', 'Suasan', 'Frank', 'Anne', 'Ashley', 'Bill'])
    
    def say_hello(self):
        return f"Hi, I'm {self.name}"
#main.ipynb
import import_ipynb
import ray
from a import Person

ray.init()
people = Person.remote()
ray.get(people.say_hello.remote())

Finally, An error occurs when importing a class that contains an inherited class from another file.

#a.ipynb
import ray
import numpy as np

class para(object):
    def __init__(self):
        self.para = 1

@ray.remote
class Person(para):
    def __init__(self):
        super().__init__()
    
    def heritage(self):
        return self.para 
#main.ipynb
import import_ipynb
import ray
from a import Person

ray.init()
people = Person.remote()
ray.get(people.heritage.remote())

Below is the error message.

 pid=34368) 2022-01-10 19:45:06,467	ERROR worker.py:431 -- Exception raised in creation task: The actor died because of an error raised in its creation task, ray::Person.__init__() (pid=34368, ip=127.0.0.1)
 pid=34368)   File "python\ray\_raylet.pyx", line 625, in ray._raylet.execute_task
 pid=34368)   File "python\ray\_raylet.pyx", line 629, in ray._raylet.execute_task
 pid=34368)   File "python\ray\_raylet.pyx", line 578, in ray._raylet.execute_task.function_executor
 pid=34368)   File "C:\Users\ksshin\anaconda3\lib\site-packages\ray\_private\function_manager.py", line 609, in actor_method_executor
 pid=34368)     return method(__ray_actor, *args, **kwargs)
 pid=34368)   File "C:\Users\ksshin\anaconda3\lib\site-packages\ray\_private\function_manager.py", line 512, in temporary_actor_method
 pid=34368)     raise RuntimeError(
 pid=34368) RuntimeError: The actor with name Person failed to import on the worker. This may be because needed library dependencies are not installed in the worker environment:
 pid=34368) aryActor
 pid=34368) ray::Person.__init__() (pid=34368, ip=127.0.0.1)
 pid=34368)   File "C:\Users\ksshin\anaconda3\lib\site-packages\ray\_private\function_manager.py", line 564, in _load_actor_class_from_gcs
 pid=34368)     actor_class = pickle.loads(pickled_class)
 pid=34368) ModuleNotFoundError: No module named 'a'
---------------------------------------------------------------------------
RayActorError                             Traceback (most recent call last)
<ipython-input-2-91fa4fbb45a9> in <module>
      1 people = Person.remote()
----> 2 ray.get(people.heritage.remote())

~\anaconda3\lib\site-packages\ray\_private\client_mode_hook.py in wrapper(*args, **kwargs)
    103             if func.__name__ != "init" or is_client_mode_enabled_by_default:
    104                 return getattr(ray, func.__name__)(*args, **kwargs)
--> 105         return func(*args, **kwargs)
    106 
    107     return wrapper

~\anaconda3\lib\site-packages\ray\worker.py in get(object_refs, timeout)
   1713                     raise value.as_instanceof_cause()
   1714                 else:
-> 1715                     raise value
   1716 
   1717         if is_individual_id:

RayActorError: The actor died because of an error raised in its creation task, ray::Person.__init__() (pid=34368, ip=127.0.0.1)
  File "python\ray\_raylet.pyx", line 625, in ray._raylet.execute_task
  File "python\ray\_raylet.pyx", line 629, in ray._raylet.execute_task
  File "python\ray\_raylet.pyx", line 578, in ray._raylet.execute_task.function_executor
  File "C:\Users\ksshin\anaconda3\lib\site-packages\ray\_private\function_manager.py", line 609, in actor_method_executor
    return method(__ray_actor, *args, **kwargs)
  File "C:\Users\ksshin\anaconda3\lib\site-packages\ray\_private\function_manager.py", line 512, in temporary_actor_method
    raise RuntimeError(
RuntimeError: The actor with name Person failed to import on the worker. This may be because needed library dependencies are not installed in the worker environment:

ray::Person.__init__() (pid=34368, ip=127.0.0.1)
  File "C:\Users\ksshin\anaconda3\lib\site-packages\ray\_private\function_manager.py", line 564, in _load_actor_class_from_gcs
    actor_class = pickle.loads(pickled_class)
ModuleNotFoundError: No module named 'a'

I guess there is an error in the process of importing the module, and I searched as much as possible about the ray issue, but could not find a solution.
I would really appreciate it if you could tell me how to solve it.

Hi @mincheolseong, thanks for the very detailed issue/reproduction! When running the final snippet, with the a.ipynb saved in an a.py module and running main.ipynb in an IPython notebook, it works for me:

In [1]: import ray
   ...: from a import Person
   ...:
   ...: ray.init()
   ...: people = Person.remote()
   ...: ray.get(people.heritage.remote())

2022-01-10 19:50:45,244 INFO services.py:1384 -- View the Ray dashboard at http://127.0.0.1:8265
Out[1]: 1

This is with Ray 1.9.1, Python 3.7.10, and on Ubuntu, so there’s a chance this is a Windows-specific issue.

Thanks for your kind reply.
As you mentioned, I found a problem with importing .ipynb and it works fine with .py.
I hope that one day I will be able to use ray comfortably with Jupyter notebooks.