繁体   English   中英

Caffe2:加载ONNX模型,并在多核主机/ docker上进行单线程推理

[英]Caffe2: Load ONNX model, and inference single threaded on multi-core host / docker

当主机有多个内核时,我无法在docker中对模型进行推断。 该模型通过PyTorch 1.0 ONNX导出器导出:

torch.onnx.export(pytorch_net, dummyseq, ONNX_MODEL_PATH)

使用单核启动模型服务器(包装在Flask中)会产生可接受的性能(cpuset将进程固定到特定的docker run --rm -p 8081:8080 --cpus 0.5 --cpuset-cpus 0 my_containerdocker run --rm -p 8081:8080 --cpus 0.5 --cpuset-cpus 0 my_container

回复来自ab -c 1 -n 1000 http://0.0.0.0:8081/predict\\?itemids\\=5,100

Percentage of the requests served within a certain time (ms)
  50%      5
  66%      5
  75%      5
  80%      5
  90%      7
  95%     46
  98%     48
  99%     49

但是将它固定到四个核心可以为同一个ab-call docker run --rm -p 8081:8080 --cpus 0.5 --cpuset-cpus 0,1,2,3 my_container提供完全不同的统计数据docker run --rm -p 8081:8080 --cpus 0.5 --cpuset-cpus 0,1,2,3 my_container

Percentage of the requests served within a certain time (ms)
  50%      9
  66%     12
  75%     14
  80%     18
  90%     62
  95%     66
  98%     69
  99%     69
 100%     77 (longest request)

模型推断是这样完成的,除了这个问题,它似乎按预期工作。 (当然,这在模型导出的完全独立的环境中运行)

from caffe2.python import workspace
from caffe2.python.onnx.backend import Caffe2Backend as c2
from onnx import ModelProto


class Model:
    def __init__(self):
        self.predictor = create_caffe2_predictor(path)

    @staticmethod
    def create_caffe2_predictor(onnx_file_path):
        with open(onnx_file_path, 'rb') as onnx_model:
            onnx_model_proto = ModelProto()
            onnx_model_proto.ParseFromString(onnx_model.read())
            init_net, predict_net = c2.onnx_graph_to_caffe2_net(onnx_model_proto)
            predictor = workspace.Predictor(init_net, predict_net)
        return predictor


    def predict(self, numpy_array):
        return self.predictor.run({'0': numpy_array})

** wrapper flask app which calls Model.predict() on calls to /predict **

OMP_NUM_THREADS=1也存在于容器环境中,这有一些影响,但它不是最终问题。

您在这里看到的基准统计数据是在具有8个超线程的本地计算机上运行的,因此我不应该使我的计算机饱和并影响测试。 这些结果也出现在我的kubernetes环境中,并且我在那里得到了大量的CFS(完全公平调度程序)限制。

我正在kubernetes环境中运行,所以我无法控制主机暴露的CPU数量,并且做某种固定似乎有点hacky。

有没有办法将caffe2模型推理到单个处理器? 我在做一些明显不对的事吗? caffe2.Predictor对象不适合此任务吗?

任何帮助赞赏。

编辑:

我添加了一个我能想到的最简单的可重现的例子,包括一个docker-container和run-script: https//github.com/NegatioN/Caffe2Struggles

这不是问题的直接答案,但如果你的目标是在生产中服务PyTorch模型(现在只有PyTorch模型,就像我的那样),那么简单地使用PyTorch Tracing似乎是更好的选择。

然后,您可以将其直接加载到C ++前端,类似于您通过Caffe2执行的操作,但PyTorch跟踪似乎保持得更好。 从我所看到的,没有速度减速,但配置起来要容易得多。

在单核容器上获得良好性能的一个示例是像以前一样使用OMP_NUM_THREADS=1运行,并按如下方式导出模型:

from torch import jit
### Create a model
model.eval()
traced = jit.trace(model, torch.from_numpy(an_array_with_input_size))
traced.save("traced.pt")

然后只需按照上面的指南在纯C ++中运行模型,或者通过Python接口运行:

from torch import jit
model = jit.load("traced.pt")
output = model(some_input)

我认为这应该有效:

workspace.GlobalInit(["caffe2", "--caffe2_omp_num_threads=1"])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM