Skip to content

Commit

Permalink
Decoupling path dependence in notebooks (#84)
Browse files Browse the repository at this point in the history
* Cleanup parameters in Notebooks

* Add image requisition from URL utils

* Decoupling path dependence in notebooks

* Temporarily ignore PyTorch Nightly in CI

* Add some notes
  • Loading branch information
zhiqwang authored Mar 29, 2021
1 parent 3087993 commit 2aaee95
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 137 deletions.
20 changes: 10 additions & 10 deletions .github/workflows/ci_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ jobs:
matrix:
python-version: [3.7]
os: [ubuntu-latest]
torch: [1.7.1+cpu, 1.8.0+cpu, nightly]
torch: [1.7.1+cpu, 1.8.1+cpu] # nightly
include:
- torch: 1.7.1+cpu
pip_address: torch==1.7.1+cpu torchvision==0.8.2+cpu -f https://download.pytorch.org/whl/torch_stable.html
unittest_type: --cov=test --cov-report=xml
- torch: 1.8.0+cpu
pip_address: torch==1.8.0+cpu torchvision==0.9.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
- torch: 1.8.1+cpu
pip_address: torch==1.8.1+cpu torchvision==0.9.1+cpu -f https://download.pytorch.org/whl/torch_stable.html
unittest_type: --cov=test --cov-report=xml
- torch: nightly
pip_address: --pre torch torchvision -f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html
unittest_type: test
# - torch: nightly
# pip_address: --pre torch torchvision -f https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html
# unittest_type: test

steps:
- name: Clone repository
Expand Down Expand Up @@ -65,7 +65,7 @@ jobs:
PYTORCH_TEST_WITH_SLOW=1 pytest ${{ matrix.unittest_type }}
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
if: matrix.torch == '1.8.0+cpu'
if: matrix.torch == '1.8.1+cpu'
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.xml
Expand All @@ -75,7 +75,7 @@ jobs:
fail_ci_if_error: true
verbose: true
- name: Build TorchVision Cpp ${{ matrix.torch }}
if: matrix.torch == '1.8.0+cpu'
if: matrix.torch == '1.8.1+cpu'
run: |
export TORCH_PATH=$(dirname $(python -c "import torch; print(torch.__file__)"))
cd ..
Expand All @@ -87,11 +87,11 @@ jobs:
make -j4
sudo make install
- name: Export torchscript model
if: matrix.torch == '1.8.0+cpu'
if: matrix.torch == '1.8.1+cpu'
run: |
python -m test.tracing.trace_model
- name: Test libtorch tracing
if: matrix.torch == '1.8.0+cpu'
if: matrix.torch == '1.8.1+cpu'
run: |
export TORCH_PATH=$(dirname $(python -c "import torch; print(torch.__file__)"))
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TORCH_PATH/lib/
Expand Down
138 changes: 84 additions & 54 deletions notebooks/export-onnx-inference-onnxruntime.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"\n",
"from yolort.models import yolov5s\n",
"\n",
"from yolort.utils.image_utils import read_image"
"from yolort.utils import get_image_from_url, read_image_to_tensor"
]
},
{
Expand All @@ -26,9 +26,9 @@
"import os\n",
"\n",
"os.environ[\"CUDA_DEVICE_ORDER\"]=\"PCI_BUS_ID\"\n",
"os.environ[\"CUDA_VISIBLE_DEVICES\"]=\"5\"\n",
"os.environ[\"CUDA_VISIBLE_DEVICES\"]=\"0\"\n",
"\n",
"device = torch.device('cuda')"
"device = torch.device('cpu')"
]
},
{
Expand All @@ -44,7 +44,7 @@
"metadata": {},
"outputs": [],
"source": [
"model = yolov5s(upstream_version='v4.0', export_friendly=True, pretrained=True, score_thresh=0.45)\n",
"model = yolov5s(export_friendly=True, pretrained=True, score_thresh=0.45)\n",
"\n",
"model = model.eval()\n",
"model = model.to(device)"
Expand All @@ -63,12 +63,12 @@
"metadata": {},
"outputs": [],
"source": [
"img_one = cv2.imread('test/assets/bus.jpg')\n",
"img_one = read_image(img_one, is_half=False)\n",
"img_one = get_image_from_url(\"https://gitee.com/zhiqwang/yolov5-rt-stack/raw/master/test/assets/bus.jpg\")\n",
"img_one = read_image_to_tensor(img_one, is_half=False)\n",
"img_one = img_one.to(device)\n",
"\n",
"img_two = cv2.imread('test/assets/zidane.jpg')\n",
"img_two = read_image(img_two, is_half=False)\n",
"img_two = get_image_from_url(\"https://gitee.com/zhiqwang/yolov5-rt-stack/raw/master/test/assets/bus.jpg\")\n",
"img_two = read_image_to_tensor(img_two, is_half=False)\n",
"img_two = img_two.to(device)\n",
"\n",
"images = [img_one, img_two]"
Expand All @@ -78,7 +78,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Inference in `pytorch` backend"
"### Inference on PyTorch backend"
]
},
{
Expand All @@ -100,8 +100,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 16 ms, sys: 0 ns, total: 16 ms\n",
"Wall time: 16.8 ms\n"
"CPU times: user 3.72 s, sys: 132 ms, total: 3.86 s\n",
"Wall time: 109 ms\n"
]
}
],
Expand All @@ -119,10 +119,10 @@
{
"data": {
"text/plain": [
"tensor([[ 52.1687, 384.9377, 235.4150, 899.1040],\n",
" [223.6789, 406.9857, 346.8747, 862.1425],\n",
" [677.8205, 390.5674, 811.9033, 871.8314],\n",
" [ 9.4887, 227.6140, 799.6432, 766.6011]], device='cuda:0')"
"tensor([[ 52.1603, 384.9539, 235.4333, 899.1226],\n",
" [223.7285, 407.0463, 346.9296, 862.0854],\n",
" [ 8.5867, 227.5113, 805.2753, 765.3226],\n",
" [675.7438, 394.1103, 811.3925, 869.5128]])"
]
},
"execution_count": 7,
Expand All @@ -142,7 +142,7 @@
{
"data": {
"text/plain": [
"tensor([0.8995, 0.8665, 0.8193, 0.8094], device='cuda:0')"
"tensor([0.8993, 0.8671, 0.8034, 0.8005])"
]
},
"execution_count": 8,
Expand All @@ -162,7 +162,7 @@
{
"data": {
"text/plain": [
"tensor([0, 0, 0, 5], device='cuda:0')"
"tensor([0, 0, 5, 0])"
]
},
"execution_count": 9,
Expand All @@ -178,35 +178,35 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Export to `ONNX` model"
"## Export the model to ONNX"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"from torchvision.ops._register_onnx_ops import _onnx_opset_version"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Starting ONNX export with onnx 1.8.1, onnxruntime 1.6.0...\n"
"We are using opset version: 11\n"
]
}
],
"source": [
"# TorchScript export\n",
"print(f'Starting ONNX export with onnx {onnx.__version__}, onnxruntime {onnxruntime.__version__}...')\n",
"export_onnx_name = 'checkpoints/yolov5/yolov5s.onnx'"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"from torchvision.ops._register_onnx_ops import _onnx_opset_version"
"export_onnx_name = 'yolov5s.onnx' # path of the exported ONNX models\n",
"\n",
"print(f'We are using opset version: {_onnx_opset_version}')"
]
},
{
Expand All @@ -224,17 +224,17 @@
" 'Automatically generated names will be applied to each dynamic axes of input {}'.format(key))\n",
"/usr/local/lib/python3.6/dist-packages/torch/nn/functional.py:3123: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n",
" dtype=torch.float32)).float())) for i in range(dim)]\n",
"/mnt/yolov5-rt-stack/yolort/models/anchor_utils.py:31: TracerWarning: torch.as_tensor results are registered as constants in the trace. You can safely ignore this warning if you use this function to create tensors out of constant variables that would be the same every time you call this function. In any other case, this might cause the trace to be incorrect.\n",
"/data/wangzq/yolov5-rt-stack/yolort/models/anchor_utils.py:31: TracerWarning: torch.as_tensor results are registered as constants in the trace. You can safely ignore this warning if you use this function to create tensors out of constant variables that would be the same every time you call this function. In any other case, this might cause the trace to be incorrect.\n",
" stride = torch.as_tensor([stride], dtype=dtype, device=device)\n",
"/mnt/yolov5-rt-stack/yolort/models/anchor_utils.py:50: TracerWarning: torch.as_tensor results are registered as constants in the trace. You can safely ignore this warning if you use this function to create tensors out of constant variables that would be the same every time you call this function. In any other case, this might cause the trace to be incorrect.\n",
"/data/wangzq/yolov5-rt-stack/yolort/models/anchor_utils.py:50: TracerWarning: torch.as_tensor results are registered as constants in the trace. You can safely ignore this warning if you use this function to create tensors out of constant variables that would be the same every time you call this function. In any other case, this might cause the trace to be incorrect.\n",
" anchor_grid = torch.as_tensor(anchor_grid, dtype=dtype, device=device)\n",
"/mnt/yolov5-rt-stack/yolort/models/anchor_utils.py:77: TracerWarning: torch.tensor results are registered as constants in the trace. You can safely ignore this warning if you use this function to create tensors out of constant variables that would be the same every time you call this function. In any other case, this might cause the trace to be incorrect.\n",
"/data/wangzq/yolov5-rt-stack/yolort/models/anchor_utils.py:77: TracerWarning: torch.tensor results are registered as constants in the trace. You can safely ignore this warning if you use this function to create tensors out of constant variables that would be the same every time you call this function. In any other case, this might cause the trace to be incorrect.\n",
" shifts = shifts - torch.tensor(0.5, dtype=shifts.dtype, device=device)\n",
"/mnt/yolov5-rt-stack/yolort/models/box_head.py:363: TracerWarning: Converting a tensor to a Python index might cause the trace to be incorrect. We can't record the data flow of Python values, so this value will be treated as a constant in the future. This means that the trace might not generalize to other inputs!\n",
"/data/wangzq/yolov5-rt-stack/yolort/models/box_head.py:363: TracerWarning: Converting a tensor to a Python index might cause the trace to be incorrect. We can't record the data flow of Python values, so this value will be treated as a constant in the future. This means that the trace might not generalize to other inputs!\n",
" for idx in range(batch_size): # image idx, image inference\n",
"/mnt/yolov5-rt-stack/yolort/models/transform.py:287: TracerWarning: torch.tensor results are registered as constants in the trace. You can safely ignore this warning if you use this function to create tensors out of constant variables that would be the same every time you call this function. In any other case, this might cause the trace to be incorrect.\n",
"/data/wangzq/yolov5-rt-stack/yolort/models/transform.py:287: TracerWarning: torch.tensor results are registered as constants in the trace. You can safely ignore this warning if you use this function to create tensors out of constant variables that would be the same every time you call this function. In any other case, this might cause the trace to be incorrect.\n",
" for s, s_orig in zip(new_size, original_size)\n",
"/mnt/yolov5-rt-stack/yolort/models/transform.py:287: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n",
"/data/wangzq/yolov5-rt-stack/yolort/models/transform.py:287: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n",
" for s, s_orig in zip(new_size, original_size)\n",
"/usr/local/lib/python3.6/dist-packages/torch/onnx/symbolic_opset9.py:2378: UserWarning: Exporting aten::index operator of advanced indexing in opset 11 is achieved by combination of multiple ONNX operators, including Reshape, Transpose, Concat, and Gather. If indices include negative values, the exported graph will produce incorrect results.\n",
" \"If indices include negative values, the exported graph will produce incorrect results.\")\n",
Expand All @@ -261,17 +261,19 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Simplifier exported `ONNX` model"
"## Simplify the exported ONNX model (Optional)\n",
"\n",
"*ONNX* is great, but sometimes too complicated. And thanks to @daquexian for providing a powerful tool named [`onnxsim`](https://github.com/daquexian/onnx-simplifier/) to eliminate some redundant operators.\n",
"\n",
"First of all, let's install `onnx-simplifier` with following script."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Don't forget to install `onnx-simplifier`\n",
"\n",
"```bash\n",
"!pip -U install onnx-simplifier\n",
"```shell\n",
"pip install -U onnx-simplifier\n",
"```"
]
},
Expand All @@ -284,7 +286,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Starting simplifing with onnxsim 0.3.2\n"
"Starting simplifing with onnxsim 0.3.3\n"
]
}
],
Expand All @@ -301,7 +303,7 @@
"metadata": {},
"outputs": [],
"source": [
"onnx_simp_name = 'checkpoints/yolov5/yolov5s.simp.onnx'"
"onnx_simp_name = 'yolov5s.simp.onnx' # path of the simplified ONNX models"
]
},
{
Expand Down Expand Up @@ -330,13 +332,41 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Inference on `ONNXRuntime` Backend"
"## Inference on ONNXRuntime Backend\n",
"\n",
"Now, We begin to verify whether the inference results are consistent with PyTorch's, similarly, install `onnxruntime` first."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```shell\n",
"pip install -U onnxruntime\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Starting with onnx 1.8.1, onnxruntime 1.7.0...\n"
]
}
],
"source": [
"print(f'Starting with onnx {onnx.__version__}, onnxruntime {onnxruntime.__version__}...')"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"images, _ = torch.jit._flatten(images)\n",
Expand All @@ -345,7 +375,7 @@
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -358,7 +388,7 @@
},
{
"cell_type": "code",
"execution_count": 18,
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -368,7 +398,7 @@
},
{
"cell_type": "code",
"execution_count": 19,
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -378,7 +408,7 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -389,15 +419,15 @@
},
{
"cell_type": "code",
"execution_count": 21,
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 2.33 s, sys: 0 ns, total: 2.33 s\n",
"Wall time: 77.9 ms\n"
"CPU times: user 2.3 s, sys: 0 ns, total: 2.3 s\n",
"Wall time: 62.3 ms\n"
]
}
],
Expand All @@ -410,7 +440,7 @@
},
{
"cell_type": "code",
"execution_count": 22,
"execution_count": 23,
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -458,4 +488,4 @@
},
"nbformat": 4,
"nbformat_minor": 4
}
}
Loading

0 comments on commit 2aaee95

Please sign in to comment.