有个视频解析项目做了好几年,一台GPU服务器上需要同时跑多种算法。既有跑在GPU上的,也有跑在CPU上的;包括人脸、物体检测等多种算法。深度学习刚开始火的时候,这个项目就存在了,混合了多种框架,cuda也更新了好几个版本,多数深度学习模型开始采用python2,现在逐渐过渡到python3。最近遇到一个问题,AI模型相关算法需要用python3代码执行,其他部分CPU上跑的算法又需要在python2里跑,我这人又懒懒的,本来计划把CPU上跑的部分代码也编译成支持python3的函数动态库,折腾了两把嫌麻烦,加上之前好几个算法都是python2的,同时维护起来存在一定困难。想了个绝招,就干脆让需要python3的AI模型的代码跑在另外一个进程里用python3算了,之间通过有名管道通信,普通文件传递结果。示例:
app.py
fdr = os.open('model.fifo', os.O_RDWR)
fdw = os.open('app.fifo', os.O_RDWR)
try:
pid = os.fork()
if pid == 0:
print("this is child process")
cmd = "python3 model.py"
os.system(cmd)
else:
while True:
ret, frame = cap.read()
if not ret or frame.empty():
break
cv2.imwrite('tmp.jpg', frame)
os.write(fdw, b"wake")
os.read(fdr, 4)
with open('tmp.json', 'rb') as f:
resultjson = json.load(f)
exit_stat = os.waitpid(pid, 0)
print("waited child process's PID = %d" % (exit_stat[0]))
except OSError, e:
pass
os.close(fdw)
os.close(fdr)
model.py
fdr = os.open('app.fifo', os.O_RDWR)
fdw = os.open('model.fifo', os.O_RDWR)
while True
msg = os.read(fdr, 4).decode('ascii')
if msg == "exit":
break
img = cv2.imread('tmp.jpg', 1)
result = model.predict(img)
resultjson = ...some process with result...
with open('tmp.json', 'wb') as f:
f.write((json.dumps(resultjson, cls=NumpyEncoder)).encode("utf-8"))
os.write(fdw, b"wake")
os.close(fdw)
os.close(fdr)
这样的一个坏处就是会导致每次解析视频帧都得做一次进程切换,但是它短时间内解决了各种算法/框架/语言版本兼容性等问题。