Skip to content

Commit 35578f7

Browse files
krishung5oandreeva-nv
authored andcommitted
Add test for Python BLS model loading API (#5980)
* Add test for Python BLS model loading API * Fix up
1 parent 23e7d78 commit 35578f7

File tree

3 files changed

+254
-0
lines changed

3 files changed

+254
-0
lines changed

qa/L0_backend_python/bls/test.sh

+92
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,98 @@ else
227227
RET=1
228228
fi
229229

230+
# Test model loading API with BLS
231+
rm -fr ./models
232+
mkdir -p models/bls_model_loading/1/
233+
cp ../../python_models/bls_model_loading/model.py models/bls_model_loading/1/
234+
cp ../../python_models/bls_model_loading/config.pbtxt models/bls_model_loading/
235+
cp -fr ${DATADIR}/qa_model_repository/onnx_int32_int32_int32 models/.
236+
# Make only version 2, 3 is valid version directory
237+
rm -rf models/onnx_int32_int32_int32/1
238+
239+
SERVER_LOG="./bls_model_loading_server.log"
240+
SERVER_ARGS="--model-repository=`pwd`/models --backend-directory=${BACKEND_DIR} --model-control-mode=explicit --log-verbose=1"
241+
242+
run_server
243+
if [ "$SERVER_PID" == "0" ]; then
244+
echo -e "\n***\n*** Failed to start $SERVER\n***"
245+
cat $SERVER_LOG
246+
exit 1
247+
fi
248+
249+
export MODEL_NAME='bls_model_loading'
250+
251+
set +e
252+
code=`curl -s -w %{http_code} -X POST localhost:8000/v2/repository/models/${MODEL_NAME}/load`
253+
set -e
254+
if [ "$code" == "400" ]; then
255+
echo -e "\n***\n*** Failed to load model '${MODEL_NAME}'\n***"
256+
RET=1
257+
fi
258+
259+
set +e
260+
261+
python3 $CLIENT_PY >> $CLIENT_LOG 2>&1
262+
if [ $? -ne 0 ]; then
263+
echo -e "\n***\n*** 'bls_model_loading' test FAILED. \n***"
264+
cat $CLIENT_LOG
265+
RET=1
266+
else
267+
check_test_results $TEST_RESULT_FILE $EXPECTED_NUM_TESTS
268+
if [ $? -ne 0 ]; then
269+
cat $CLIENT_LOG
270+
echo -e "\n***\n*** Test Result Verification Failed\n***"
271+
RET=1
272+
fi
273+
fi
274+
275+
set -e
276+
277+
kill $SERVER_PID
278+
wait $SERVER_PID
279+
280+
# Test model loading API with BLS warmup
281+
(cd models/bls_model_loading && \
282+
echo "model_warmup [{" >> config.pbtxt && \
283+
echo " name : \"regular sample\"" >> config.pbtxt && \
284+
echo " batch_size: 1" >> config.pbtxt && \
285+
echo " inputs {" >> config.pbtxt && \
286+
echo " key: \"INPUT0\"" >> config.pbtxt && \
287+
echo " value: {" >> config.pbtxt && \
288+
echo " data_type: TYPE_FP32" >> config.pbtxt && \
289+
echo " dims: 4" >> config.pbtxt && \
290+
echo " zero_data: false" >> config.pbtxt && \
291+
echo " }" >> config.pbtxt && \
292+
echo " }" >> config.pbtxt && \
293+
echo " inputs {" >> config.pbtxt && \
294+
echo " key: \"INPUT1\"" >> config.pbtxt && \
295+
echo " value: {" >> config.pbtxt && \
296+
echo " data_type: TYPE_FP32" >> config.pbtxt && \
297+
echo " dims: 4" >> config.pbtxt && \
298+
echo " zero_data: false" >> config.pbtxt && \
299+
echo " }" >> config.pbtxt && \
300+
echo " }" >> config.pbtxt && \
301+
echo "}]" >> config.pbtxt )
302+
303+
SERVER_LOG="./bls_model_loading_server_warmup.log"
304+
run_server
305+
if [ "$SERVER_PID" == "0" ]; then
306+
echo -e "\n***\n*** Failed to start $SERVER\n***"
307+
cat $SERVER_LOG
308+
exit 1
309+
fi
310+
311+
set +e
312+
code=`curl -s -w %{http_code} -X POST localhost:8000/v2/repository/models/${MODEL_NAME}/load`
313+
set -e
314+
if [ "$code" == "400" ]; then
315+
echo -e "\n***\n*** Failed to load model '${MODEL_NAME}'\n***"
316+
RET=1
317+
fi
318+
319+
kill $SERVER_PID
320+
wait $SERVER_PID
321+
230322
if [ $RET -eq 1 ]; then
231323
cat $CLIENT_LOG
232324
cat $SERVER_LOG
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Copyright 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
#
3+
# Redistribution and use in source and binary forms, with or without
4+
# modification, are permitted provided that the following conditions
5+
# are met:
6+
# * Redistributions of source code must retain the above copyright
7+
# notice, this list of conditions and the following disclaimer.
8+
# * Redistributions in binary form must reproduce the above copyright
9+
# notice, this list of conditions and the following disclaimer in the
10+
# documentation and/or other materials provided with the distribution.
11+
# * Neither the name of NVIDIA CORPORATION nor the names of its
12+
# contributors may be used to endorse or promote products derived
13+
# from this software without specific prior written permission.
14+
#
15+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
16+
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18+
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23+
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
27+
name: "bls_model_loading"
28+
backend: "python"
29+
30+
output [
31+
{
32+
name: "OUTPUT0"
33+
data_type: TYPE_BOOL
34+
dims: [ 1 ]
35+
}
36+
]
37+
38+
instance_group [
39+
{
40+
count: 3
41+
kind: KIND_CPU
42+
}
43+
]
+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Copyright 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
#
3+
# Redistribution and use in source and binary forms, with or without
4+
# modification, are permitted provided that the following conditions
5+
# are met:
6+
# * Redistributions of source code must retain the above copyright
7+
# notice, this list of conditions and the following disclaimer.
8+
# * Redistributions in binary form must reproduce the above copyright
9+
# notice, this list of conditions and the following disclaimer in the
10+
# documentation and/or other materials provided with the distribution.
11+
# * Neither the name of NVIDIA CORPORATION nor the names of its
12+
# contributors may be used to endorse or promote products derived
13+
# from this software without specific prior written permission.
14+
#
15+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
16+
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18+
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23+
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
27+
import numpy as np
28+
import unittest
29+
import triton_python_backend_utils as pb_utils
30+
31+
32+
class PBBLSModelLoadingTest(unittest.TestCase):
33+
34+
def setUp(self):
35+
self.model_name = "onnx_int32_int32_int32"
36+
37+
def tearDown(self):
38+
pb_utils.unload_model(self.model_name)
39+
40+
def test_load_unload_model(self):
41+
self.assertFalse(pb_utils.is_model_ready(model_name=self.model_name))
42+
pb_utils.load_model(model_name=self.model_name)
43+
self.assertTrue(pb_utils.is_model_ready(self.model_name))
44+
pb_utils.unload_model(self.model_name)
45+
self.assertFalse(pb_utils.is_model_ready(self.model_name))
46+
47+
def test_load_with_config_override(self):
48+
self.assertFalse(pb_utils.is_model_ready(self.model_name))
49+
pb_utils.load_model(self.model_name)
50+
self.assertTrue(pb_utils.is_model_ready(self.model_name))
51+
52+
# Send the config with the wrong format
53+
wrong_config = "\"parameters\": {\"config\": {{\"backend\":\"onnxruntime\", \"version_policy\":{\"specific\":{\"versions\":[2]}}}}}"
54+
with self.assertRaises(pb_utils.TritonModelException):
55+
pb_utils.load_model(model_name=self.model_name, config=wrong_config)
56+
# The model should not be changed after a failed load model request
57+
for version in ["2", "3"]:
58+
self.assertTrue(pb_utils.is_model_ready(model_name=self.model_name, model_version=version))
59+
60+
# Send the config with the correct format
61+
config = "{\"backend\":\"onnxruntime\", \"version_policy\":{\"specific\":{\"versions\":[2]}}}"
62+
pb_utils.load_model(self.model_name, config=config)
63+
# The model should be changed after a successful load model request
64+
self.assertTrue(pb_utils.is_model_ready(self.model_name, "2"))
65+
self.assertFalse(pb_utils.is_model_ready(self.model_name, "3"))
66+
67+
def test_load_with_file_override(self):
68+
self.assertFalse(pb_utils.is_model_ready(self.model_name))
69+
pb_utils.load_model(self.model_name)
70+
self.assertTrue(pb_utils.is_model_ready(self.model_name))
71+
72+
override_name = "override_model"
73+
config = "{\"backend\":\"onnxruntime\"}"
74+
with open('models/onnx_int32_int32_int32/3/model.onnx', 'rb') as file:
75+
data = file.read()
76+
files = {"file:1/model.onnx": data}
77+
78+
# Request to load the model with override file, should fail without
79+
# providing override config.
80+
with self.assertRaises(pb_utils.TritonModelException):
81+
pb_utils.load_model(self.model_name, "", files)
82+
83+
# Request to load the model with override file and config in a different name
84+
pb_utils.load_model(model_name=override_name, config=config, files=files)
85+
# Sanity check that the model with original name is unchanged
86+
self.assertFalse(pb_utils.is_model_ready(self.model_name, "1"))
87+
self.assertTrue(pb_utils.is_model_ready(self.model_name, "3"))
88+
89+
# Check the override model readiness
90+
self.assertTrue(pb_utils.is_model_ready(override_name, "1"))
91+
self.assertFalse(pb_utils.is_model_ready(override_name, "3"))
92+
93+
# Request to load the model with override file and config in original name
94+
pb_utils.load_model(self.model_name, config, files)
95+
# Check that the model with original name is changed
96+
self.assertTrue(pb_utils.is_model_ready(self.model_name, "1"))
97+
self.assertFalse(pb_utils.is_model_ready(self.model_name, "3"))
98+
99+
# Sanity check readiness of the different named model
100+
self.assertTrue(pb_utils.is_model_ready(override_name, "1"))
101+
self.assertFalse(pb_utils.is_model_ready(override_name, "3"))
102+
103+
104+
class TritonPythonModel:
105+
106+
def initialize(self, args):
107+
# Run the unittest during initialization
108+
test = unittest.main('model', exit=False)
109+
self.result = test.result.wasSuccessful()
110+
111+
def execute(self, requests):
112+
responses = []
113+
for _ in requests:
114+
responses.append(
115+
pb_utils.InferenceResponse([
116+
pb_utils.Tensor('OUTPUT0',
117+
np.array([self.result], dtype=np.float16))
118+
]))
119+
return responses

0 commit comments

Comments
 (0)