Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion qa/L0_pytorch_python_runtime/test.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
# Copyright 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# Copyright 2023-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
Expand Down Expand Up @@ -122,6 +122,24 @@ else
fi
done

# Regression guard: core auto-complete must not fill in
# default_model_filename for a model using the Python-based runtime.
# If it does, 'neuralnet' is selected as TorchScript and torch.jit.load()
# fails on its weights file with a "constants.pkl not found" error.
grep "Loading 'neuralnet' as TorchScript" $SERVER_LOG
if [ $? -eq 0 ]; then
echo -e "\n***\n*** 'neuralnet' took the TorchScript load path: core autofilled default_model_filename for a runtime \"model.py\" model. \n***"
RET=1
fi

if ! NEURALNET_DEFAULT_FILENAME=$(curl -sf localhost:8000/v2/models/neuralnet/config | python3 -c "import json,sys; c=json.load(sys.stdin); assert c.get('name')=='neuralnet', c; print(c.get('default_model_filename', ''))"); then
echo -e "\n***\n*** Failed to retrieve or parse the configuration for 'neuralnet'. \n***"
RET=1
elif [ "$NEURALNET_DEFAULT_FILENAME" != "" ]; then
echo -e "\n***\n*** Expected empty default_model_filename for 'neuralnet', got \"$NEURALNET_DEFAULT_FILENAME\". \n***"
RET=1
fi

# Infer TorchScript model
CLIENT_LOG="./infer.torchscript.log"
python $IMAGE_CLIENT -m "resnet50_libtorch" -s INCEPTION -c 1 -b 2 "$IMAGE_DIR/vulture.jpeg" > $CLIENT_LOG 2>&1
Expand Down
47 changes: 45 additions & 2 deletions qa/L0_pytorch_python_runtime/unit_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3

# Copyright 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# Copyright 2023-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
Expand All @@ -26,15 +26,22 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os
import shutil
import sys
import tempfile
import unittest

import torch

# satisfy Python runtime import requirements
sys.modules["triton_python_backend_utils"] = unittest.mock.MagicMock()
# import modules from Python runtime to be tested
from py_runtime import _gather_torch_tensors, _scatter_torch_tensors
from py_runtime import ( # noqa: E402
_gather_torch_tensors,
_get_model_path,
_scatter_torch_tensors,
)


class PyTorchPythonBackendRuntimeUnittest(unittest.TestCase):
Expand Down Expand Up @@ -150,5 +157,41 @@ def test_scatter_torch_tensors(self):
self.assertTrue(torch.equal(tensor, expected_tensor))


class PyTorchPythonRuntimeModelPathTest(unittest.TestCase):
"""For a Python-class model, 'model.py' must be selected over a
sibling weights file 'model.pt' unless the user explicitly requests the
weights file via default_model_filename."""

def setUp(self):
self._model_dir = tempfile.mkdtemp()
pb_utils = sys.modules["triton_python_backend_utils"]
pb_utils.get_model_dir.return_value = self._model_dir

def tearDown(self):
shutil.rmtree(self._model_dir)

def _touch(self, filename):
path = os.path.join(self._model_dir, filename)
open(path, "w").close()
return path

def test_model_py_preferred_over_sibling_weights(self):
expected = self._touch("model.py")
self._touch("model.pt")
config = {"default_model_filename": ""}
self.assertEqual(_get_model_path(config), expected)

def test_explicit_default_model_filename_wins(self):
self._touch("model.py")
expected = self._touch("model.pt")
config = {"default_model_filename": "model.pt"}
self.assertEqual(_get_model_path(config), expected)

def test_torchscript_only_model(self):
expected = self._touch("model.pt")
config = {"default_model_filename": ""}
self.assertEqual(_get_model_path(config), expected)


if __name__ == "__main__":
unittest.main()
Loading