FasterRCNN Resnet50 JIT Trace

username: HussainHaris
cooked: <p>Hi,</p>
<p>I’m trying to trace FasterRCNN to use in Pytorch Mobile on iOS.</p>
<p>I simply trace as shown below:</p>
<pre><code class="lang-auto">model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
model.eval()

input_tensor = torch.rand(1,3,224,224)
script_model = torch.jit.trace(model, input_tensor)
script_model.save("models/fRCNN_resnet50.pt")
</code></pre>
<p>I receive a “Only tensors or tuples of tensors can be output from traced functions (getOutput at …/torch/csrc/jit/tracer.cpp:209)” error as shown below</p>
<pre><code class="lang-auto">RuntimeError: Only tensors or tuples of tensors can be output from traced functions (getOutput at ../torch/csrc/jit/tracer.cpp:209)
frame #0: c10::Error::Error(c10::SourceLocation, std::__1::basic_string&lt;char, std::__1::char_traits&lt;char&gt;, std::__1::allocator&lt;char&gt; &gt; const&amp;) + 135 (0x128cc29e7 in libc10.dylib)
frame #1: torch::jit::tracer::TracingState::getOutput(c10::IValue const&amp;) + 1785 (0x120164069 in libtorch.dylib)
frame #2: torch::jit::tracer::exit(std::__1::vector&lt;c10::IValue, std::__1::allocator&lt;c10::IValue&gt; &gt; const&amp;) + 232 (0x120167108 in libtorch.dylib)
frame #3: torch::jit::tracer::createGraphByTracing(pybind11::function const&amp;, torch::jit::tracer::TypedStack, pybind11::function const&amp;, bool, torch::jit::script::Module*) + 916 (0x11c957914 in libtorch_python.dylib)
frame #4: void pybind11::cpp_function::initialize&lt;torch::jit::script::initJitScriptBindings(_object*)::$_16, void, torch::jit::script::Module&amp;, std::__1::basic_string&lt;char, std::__1::char_traits&lt;char&gt;, std::__1::allocator&lt;char&gt; &gt; const&amp;, pybind11::function, pybind11::tuple, pybind11::function, bool, pybind11::name, pybind11::is_method, pybind11::sibling&gt;(torch::jit::script::initJitScriptBindings(_object*)::$_16&amp;&amp;, void (*)(torch::jit::script::Module&amp;, std::__1::basic_string&lt;char, std::__1::char_traits&lt;char&gt;, std::__1::allocator&lt;char&gt; &gt; const&amp;, pybind11::function, pybind11::tuple, pybind11::function, bool), pybind11::name const&amp;, pybind11::is_method const&amp;, pybind11::sibling const&amp;)::'lambda'(pybind11::detail::function_call&amp;)::__invoke(pybind11::detail::function_call&amp;) + 197 (0x11c993185 in libtorch_python.dylib)
frame #5: pybind11::cpp_function::dispatcher(_object*, _object*, _object*) + 3324 (0x11c4cd92c in libtorch_python.dylib)
frame #6: _PyCFunction_FastCallDict + 183 (0x10e3d0167 in Python)
frame #7: call_function + 184 (0x10e452d28 in Python)
frame #8: _PyEval_EvalFrameDefault + 27511 (0x10e44f597 in Python)
frame #9: _PyEval_EvalCodeWithName + 2447 (0x10e45388f in Python)
frame #10: fast_function + 545 (0x10e454141 in Python)
frame #11: call_function + 401 (0x10e452e01 in Python)
frame #12: _PyEval_EvalFrameDefault + 27511 (0x10e44f597 in Python)
frame #13: _PyEval_EvalCodeWithName + 2447 (0x10e45388f in Python)
frame #14: fast_function + 545 (0x10e454141 in Python)
frame #15: call_function + 401 (0x10e452e01 in Python)
frame #16: _PyEval_EvalFrameDefault + 27511 (0x10e44f597 in Python)
frame #17: _PyEval_EvalCodeWithName + 2447 (0x10e45388f in Python)
frame #18: PyEval_EvalCode + 100 (0x10e448954 in Python)
frame #19: builtin_exec + 548 (0x10e445fe4 in Python)
frame #20: _PyCFunction_FastCallDict + 491 (0x10e3d029b in Python)
frame #21: call_function + 439 (0x10e452e27 in Python)
frame #22: _PyEval_EvalFrameDefault + 27511 (0x10e44f597 in Python)
frame #23: gen_send_ex + 183 (0x10e3a7fe7 in Python)
frame #24: _PyEval_EvalFrameDefault + 11552 (0x10e44b740 in Python)
frame #25: gen_send_ex + 183 (0x10e3a7fe7 in Python)
frame #26: _PyEval_EvalFrameDefault + 11552 (0x10e44b740 in Python)
frame #27: gen_send_ex + 183 (0x10e3a7fe7 in Python)
frame #28: _PyCFunction_FastCallDict + 560 (0x10e3d02e0 in Python)
frame #29: call_function + 439 (0x10e452e27 in Python)
frame #30: _PyEval_EvalFrameDefault + 27511 (0x10e44f597 in Python)
frame #31: fast_function + 381 (0x10e45409d in Python)
frame #32: call_function + 401 (0x10e452e01 in Python)
frame #33: _PyEval_EvalFrameDefault + 27511 (0x10e44f597 in Python)
frame #34: fast_function + 381 (0x10e45409d in Python)
frame #35: call_function + 401 (0x10e452e01 in Python)
frame #36: _PyEval_EvalFrameDefault + 27511 (0x10e44f597 in Python)
frame #37: _PyEval_EvalCodeWithName + 2447 (0x10e45388f in Python)
frame #38: _PyFunction_FastCallDict + 763 (0x10e45445b in Python)
frame #39: _PyObject_FastCallDict + 247 (0x10e3873e7 in Python)
frame #40: _PyObject_Call_Prepend + 149 (0x10e387505 in Python)
frame #41: PyObject_Call + 96 (0x10e387220 in Python)
frame #42: _PyEval_EvalFrameDefault + 28250 (0x10e44f87a in Python)
frame #43: _PyEval_EvalCodeWithName + 2447 (0x10e45388f in Python)
frame #44: fast_function + 545 (0x10e454141 in Python)
frame #45: call_function + 401 (0x10e452e01 in Python)
frame #46: _PyEval_EvalFrameDefault + 27670 (0x10e44f636 in Python)
frame #47: gen_send_ex + 183 (0x10e3a7fe7 in Python)
frame #48: builtin_next + 92 (0x10e446bcc in Python)
frame #49: _PyCFunction_FastCallDict + 491 (0x10e3d029b in Python)
frame #50: call_function + 439 (0x10e452e27 in Python)
frame #51: _PyEval_EvalFrameDefault + 27511 (0x10e44f597 in Python)
frame #52: _PyEval_EvalCodeWithName + 2447 (0x10e45388f in Python)
frame #53: fast_function + 545 (0x10e454141 in Python)
frame #54: call_function + 401 (0x10e452e01 in Python)
frame #55: _PyEval_EvalFrameDefault + 27511 (0x10e44f597 in Python)
frame #56: gen_send_ex + 183 (0x10e3a7fe7 in Python)
frame #57: builtin_next + 92 (0x10e446bcc in Python)
frame #58: _PyCFunction_FastCallDict + 491 (0x10e3d029b in Python)
frame #59: call_function + 439 (0x10e452e27 in Python)
frame #60: _PyEval_EvalFrameDefault + 27511 (0x10e44f597 in Python)
frame #61: _PyEval_EvalCodeWithName + 2447 (0x10e45388f in Python)
frame #62: fast_function + 545 (0x10e454141 in Python)
frame #63: call_function + 401 (0x10e452e01 in Python)
</code></pre>
<p>Could someone explain to me how to properly trace or script a pretrained object detection model such as this one? I don’t know which steps I might be missing if any!</p>

username: driazati
cooked: <p>The MaskRCNN based models don’t support tracing due to the error you saw, but thanks to <a href="https://github.com/pytorch/vision/pull/1407" rel="nofollow noopener">this PR</a> you can use <code>torch.jit.script</code> to compile the whole network.</p>
<p>You’ll need to get the most current version of torchvision by <a href="https://github.com/pytorch/vision#installation" rel="nofollow noopener">building it from source</a>, then you can do</p>
<pre><code class="lang-python">model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
model.eval()
script_model = torch.jit.script(model)
</code></pre>

username: HussainHaris
cooked: <aside class="quote no-group" data-username="driazati" data-post="2" data-topic="62337">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/driazati/48/15393_2.png" class="avatar"> driazati:</div>
<blockquote>
<p>building it from source</p>
</blockquote>
</aside>
<p>Hi! I know some time has passed between now and when this was response was written. Would recompiling from source still be the solution for this? Will try tonight! Thanks</p>

username: driazati
cooked: <p>We had a release recently, so it should work so long as you’re using the latest versions of PyTorch and torchvision.</p>
<pre><code class="lang-auto"># Clear out old versions
pip uninstall torch
pip uninstall torch
pip uninstall torchvision

# Install the most recent versions
pip install torch torchvision
</code></pre>

username: HussainHaris
cooked: <aside class="quote no-group" data-username="driazati" data-post="2" data-topic="62337">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/driazati/48/15393_2.png" class="avatar"> driazati:</div>
<blockquote>
<pre><code class="lang-auto">script_model = torch.jit.script(model)
</code></pre>
</blockquote>
</aside>
<p>Okay, I was able to successfuly script the model as a pt file. I proceeded to place this pt file in an iOS project via pytorch mobile bridging headers. I also changed the settings to accept an 800x800 input image since the model specifies that.</p>
<p>However when I try to run predict/inference on Swift/iOS I get the following error.</p>
<pre><code class="lang-auto">2020-01-29 12:43:32.086469-0500 torchMobile[11047:2729940] 
Unknown builtin op: torchvision::_new_empty_tensor_op.
Could not find any similar ops to torchvision::_new_empty_tensor_op. This op may not exist or may not be currently supported in TorchScript.
:
at /Users/hxh85ki/Desktop/Projects/thdEnv/lib/python3.6/site-packages/torchvision/ops/new_empty_tensor.py:16:11
        output (Tensor)
    """
    return torch.ops.torchvision._new_empty_tensor_op(x, shape)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ &lt;--- HERE
Serialized at code/__torch__/torchvision/ops/new_empty_tensor.py:4:7
def _new_empty_tensor(x: Tensor,
    shape: List[int]) -&gt; Tensor:
  _0 = ops.torchvision._new_empty_tensor_op(x, shape)
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ &lt;--- HERE
  return _0
'_new_empty_tensor' is being compiled since it was called from 'interpolate'
Serialized at code/__torch__/torchvision/ops/misc.py:25:2
    align_corners: Optional[bool]=None) -&gt; Tensor:
  _1 = __torch__.torchvision.ops.misc._output_size
  _2 = __torch__.torchvision.ops.new_empty_tensor._new_empty_tensor
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ &lt;--- HERE
  _3 = uninitialized(Tensor)
  if torch.gt(torch.numel(input), 0):
'interpolate' is being compiled since it was called from 'GeneralizedRCNNTransform.resize'
Serialized at code/__torch__/torchvision/models/detection/transform.py:79:4
    target: Optional[Dict[str, Tensor]]) -&gt; Tuple[Tensor, Optional[Dict[str, Tensor]]]:
    _18 = __torch__.torchvision.models.detection.transform.resize_boxes
    _19 = __torch__.torchvision.ops.misc.interpolate
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ &lt;--- HERE
    _20 = __torch__.torchvision.models.detection.transform.resize_keypoints
    _21 = uninitialized(Tuple[Tensor, Optional[Dict[str, Tensor]]])
'GeneralizedRCNNTransform.resize' is being compiled since it was called from 'GeneralizedRCNNTransform.forward'
at /Users/hxh85ki/Desktop/Projects/thdEnv/lib/python3.6/site-packages/torchvision/models/detection/transform.py:47:34
                                 "of shape [C, H, W], got {}".format(image.shape))
            image = self.normalize(image)
            image, target_index = self.resize(image, target_index)
                                  ~~~~~~~~~~~ &lt;--- HERE
            images[i] = image
            if targets is not None and target_index is not None:
Serialized at code/__torch__/torchvision/models/detection/transform.py:29:33
        pass
      image0 = (self).normalize(image, )
      _2 = (self).resize(image0, target_index, )
                                 ~~~~~~~~~~~~ &lt;--- HERE
      image1, target_index0, = _2
      _3 = torch._set_item(images0, i, image1)
Fatal error: Can't find the model file!: file /Users/hxh85ki/thd-visual-ai/pytorchMobile/torchMobile/torchMobile/ViewController.swift, line 110
2020-01-29 12:43:32.088293-0500 torchMobile[11047:2729940] Fatal error: Can't find the model file!: file /Users/hxh85ki/thd-visual-ai/pytorchMobile/torchMobile/torchMobile/ViewController.swift, line 110
</code></pre>
<p>My model file is definitely in the project and I’m able to successfully able to run any normal image classification models on iOS. But this is my first attempt with Object Detection using Faster RCNN. Where am I going wrong? Any help would be appreciated. If necessary I could also take it to the mobile thread.</p>
<p>From my understanding, if I can trace/script a pt file for mobile, pytorch mobile should be able to run it? This is a vanilla Faster RCNN Resnet50 fpn.</p>
<p>Thanks, Haris</p>

username: David_Reiss
cooked: <p>We don’t currently build and ship torchvision or torchaudio for mobile.  We’re looking into it.</p>

username: xta0
cooked: <p><a class="mention" href="/u/hussainharis">@HussainHaris</a> David is right, the torchvision c++ APIs are not supported on mobile yet.  If your local pytorch version is 1.4.0, you can use the python API below to examine the ops used by your model</p>
<pre><code class="lang-auto">torch.jit.export_opnames(traced_script_module)
</code></pre>

username: ekilic
cooked: <p><a class="mention" href="/u/david_reiss">@David_Reiss</a> I try to load faster rcnn model with nightly libtorch on Win10. But it failed. Is it support win10?</p>

username: HussainHaris
cooked: <p>Thanks, how is shipping torchvision models for object detection or segmentation such as this FasterRCNN different from say shipping a resnet50 on mobile? Isn’t resnet50 and other CV models torchvision models? Just so I can understand better!</p>

username: David_Reiss
cooked: <p>Detection models use special ops that are not part of the PyTorch core.  Some segmentation architectures (like U-Net) work fine without those ops.  We are looking into supporting them.</p>
<p>Win10 is supported.</p>

username: mrpropellers
cooked: <p>I’ve also run into this same issue using the pre-trained Faster RCNN model from pytorch, saved using</p>
<pre><code class="lang-auto">model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
model.eval()
script_module = torch.jit.script(model)
script_module.save("../models/frcnn_torchscript.pt")
</code></pre>
<p>Module.load using the Java wrappers in Android Studio gives:</p>
<pre><code class="lang-auto">Unknown builtin op: torchvision::_new_empty_tensor_op.
    Could not find any similar ops to torchvision::_new_empty_tensor_op. This op may not exist or may not be currently supported in TorchScript.
</code></pre>
<p>Is this something I could fix by compiling the latest Pytorch Android from source?</p>

username: HussainHaris
cooked: <p>As David stated,  F-RCNN is a detection model using special ops not part of the Pytorch Core and is therefore not directly scriptable for mobile deployment unfortunately</p>

username: mrpropellers
cooked: <p>Ok thanks <a class="mention" href="/u/hussainharis">@HussainHaris</a>. Do you have any insight on what <a href="https://github.com/pytorch/vision/pull/1407/files#diff-9b4079a8972dd58b35089da703a0a35f" rel="nofollow noopener">this change</a> did and what I could do to build it into the android libraries?  It seems like there <em>is</em> a torchvision package available now (<a href="https://github.com/pytorch/android-demo-app/blob/master/PyTorchDemoApp/app/build.gradle#L39" rel="nofollow noopener">used in this example I was following</a>) which uses at least some of the vision ops, so maybe there is a way for me to hack the missing ops in and unblock myself for a while?</p>

username: HussainHaris
cooked: <aside class="quote no-group" data-username="mrpropellers" data-post="13" data-topic="62337">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/mrpropellers/48/21514_2.png" class="avatar"> mrpropellers:</div>
<blockquote>
<p>this change</p>
</blockquote>
</aside>
<p>I didn’t see this actually, maybe <a class="mention" href="/u/david_reiss">@David_Reiss</a> could shed some light on these changes for MaskRCNN scriptability?</p>
<p>Please let me know <a class="mention" href="/u/mrpropellers">@mrpropellers</a> of any updates with this attempt. Currently I’m trying to add MaskRCNN Resnet50 via <a href="https://medium.com/tensorflow/mlir-a-new-intermediate-representation-and-compiler-framework-beba999ed18d" rel="noopener nofollow ugc">MLRI/Tensorflow Lite’s experimental convertor</a>.</p>

username: mikey_t
cooked: <p>Hi <a class="mention" href="/u/hussainharis">@HussainHaris</a> . It has been a while since this issue was active, so I’m wondering if you’ve had any more success with this in more recent versions of torch and torchvision. I’m trying to do the same thing as you, where I save a trace of a faster rcnn model, and the problem appears to be that those ops functions are not available for tracing.</p>
<p>Are there any ways to do this now that the packages have been updated.<br>
Thank you</p>