Python、Chaquopy、Android 上由于缺少信号量而使用 tensorflow 时出现 ImportError
Python, Chaquopy, ImportError on Android when using tensorflow due to lack of semaphores
我是 运行 keras,使用 Chaquopy 在 Android 上使用 tensorflow。当我调用 predict()
在我的模型上,出现以下堆栈跟踪异常:
AndroidRuntime: Process: com.example.android.camera2basic, PID: 10113
AndroidRuntime: com.chaquo.python.PyException: ImportError: This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770.
AndroidRuntime: at <python>.multiprocessing.synchronize.<module>(synchronize.py:30)
AndroidRuntime: at <python>.zipimport.load_module(<frozen zipimport>:259)
AndroidRuntime: at <python>.java.chaquopy.import_override(import.pxi:60)
AndroidRuntime: at <python>.multiprocessing.context.Lock(context.py:67)
AndroidRuntime: at <python>.multiprocessing.queues.__init__(queues.py:336)
AndroidRuntime: at <python>.multiprocessing.context.SimpleQueue(context.py:113)
AndroidRuntime: at <python>.multiprocessing.pool.__init__(pool.py:196)
AndroidRuntime: at <python>.multiprocessing.pool.__init__(pool.py:922)
AndroidRuntime: at <python>.tensorflow.python.keras.engine.training_utils.get_copy_pool(training_utils.py:210)
AndroidRuntime: at <python>.tensorflow.python.keras.engine.training_utils.__init__(training_utils.py:242)
AndroidRuntime: at <python>.tensorflow.python.keras.engine.training_utils.create(training_utils.py:335)
AndroidRuntime: at <python>.tensorflow.python.keras.engine.training_v2.run_one_epoch(training_v2.py:171)
AndroidRuntime: at <python>.tensorflow.python.keras.engine.training_v2._model_iteration(training_v2.py:464)
AndroidRuntime: at <python>.tensorflow.python.keras.engine.training_v2.predict(training_v2.py:495)
AndroidRuntime: at <python>.tensorflow.python.keras.engine.training.predict(training.py:1004)
我的理解是Android不支持信号量。
有人对此有任何解决方法吗?
Keras 实际上是在尝试使用一个简单的线程池,但看起来标准库无论如何都会引入一些进程间同步代码。我想这还没有被注意到,因为所有主要平台都支持信号量。
要解决此问题,请在使用 Keras 之前运行以下代码:
import multiprocessing
import threading
def threading_func(name):
def f(self, *args, **kwargs):
return getattr(threading, name)(*args, **kwargs)
f.__name__ = f.__qualname__ = name
return f
ctx = multiprocessing.get_context()
for name in ["Lock", "RLock", "Condition", "Semaphore", "BoundedSemaphore",
"Event", "Barrier"]:
setattr(type(ctx), name, threading_func(name))
setattr(multiprocessing, name, getattr(ctx, name))
请在评论中告诉我这是否有效,因为我可能会将其合并到下一版本的 Chaquopy 中。
我是 运行 keras,使用 Chaquopy 在 Android 上使用 tensorflow。当我调用 predict() 在我的模型上,出现以下堆栈跟踪异常:
AndroidRuntime: Process: com.example.android.camera2basic, PID: 10113
AndroidRuntime: com.chaquo.python.PyException: ImportError: This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770.
AndroidRuntime: at <python>.multiprocessing.synchronize.<module>(synchronize.py:30)
AndroidRuntime: at <python>.zipimport.load_module(<frozen zipimport>:259)
AndroidRuntime: at <python>.java.chaquopy.import_override(import.pxi:60)
AndroidRuntime: at <python>.multiprocessing.context.Lock(context.py:67)
AndroidRuntime: at <python>.multiprocessing.queues.__init__(queues.py:336)
AndroidRuntime: at <python>.multiprocessing.context.SimpleQueue(context.py:113)
AndroidRuntime: at <python>.multiprocessing.pool.__init__(pool.py:196)
AndroidRuntime: at <python>.multiprocessing.pool.__init__(pool.py:922)
AndroidRuntime: at <python>.tensorflow.python.keras.engine.training_utils.get_copy_pool(training_utils.py:210)
AndroidRuntime: at <python>.tensorflow.python.keras.engine.training_utils.__init__(training_utils.py:242)
AndroidRuntime: at <python>.tensorflow.python.keras.engine.training_utils.create(training_utils.py:335)
AndroidRuntime: at <python>.tensorflow.python.keras.engine.training_v2.run_one_epoch(training_v2.py:171)
AndroidRuntime: at <python>.tensorflow.python.keras.engine.training_v2._model_iteration(training_v2.py:464)
AndroidRuntime: at <python>.tensorflow.python.keras.engine.training_v2.predict(training_v2.py:495)
AndroidRuntime: at <python>.tensorflow.python.keras.engine.training.predict(training.py:1004)
我的理解是Android不支持信号量。
有人对此有任何解决方法吗?
Keras 实际上是在尝试使用一个简单的线程池,但看起来标准库无论如何都会引入一些进程间同步代码。我想这还没有被注意到,因为所有主要平台都支持信号量。
要解决此问题,请在使用 Keras 之前运行以下代码:
import multiprocessing
import threading
def threading_func(name):
def f(self, *args, **kwargs):
return getattr(threading, name)(*args, **kwargs)
f.__name__ = f.__qualname__ = name
return f
ctx = multiprocessing.get_context()
for name in ["Lock", "RLock", "Condition", "Semaphore", "BoundedSemaphore",
"Event", "Barrier"]:
setattr(type(ctx), name, threading_func(name))
setattr(multiprocessing, name, getattr(ctx, name))
请在评论中告诉我这是否有效,因为我可能会将其合并到下一版本的 Chaquopy 中。