Skip to content

Commit d82974e

Browse files
committed
Add sample_optional, and fix pytest for parameters, optional
1 parent f071bc5 commit d82974e

File tree

9 files changed

+151
-21
lines changed

9 files changed

+151
-21
lines changed

.github/workflows/pre-commit_pytest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
runs-on: ubuntu-latest
3838
needs: pre-commit
3939
container:
40-
image: nvcr.io/nvidia/tritonserver:23.03-pyt-python-py3
40+
image: nvcr.io/nvidia/tritonserver:23.08-pyt-python-py3
4141
options:
4242
--shm-size=1g
4343
steps:

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ if __name__ == "__main__":
5555

5656
## Release Notes
5757

58+
- 23.08.30 Support `optional` with model input, `parameters` on config.pbtxt
5859
- 23.06.16 Support tritonclient>=2.34.0
5960
- Loosely modified the requirements related to tritonclient
6061

bin/run_triton_tritony_sample.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
3+
HERE=$(dirname "$(readlink -f $0)")
4+
PARENT_DIR=$(dirname "$HERE")
5+
6+
docker run -it --rm --name triton_tritony \
7+
-p8100:8000 \
8+
-p8101:8001 \
9+
-p8102:8002 \
10+
-v "${PARENT_DIR}"/model_repository:/models:ro \
11+
-e OMP_NUM_THREADS=2 \
12+
-e OPENBLAS_NUM_THREADS=2 \
13+
--shm-size=1g \
14+
nvcr.io/nvidia/tritonserver:23.08-pyt-python-py3 \
15+
tritonserver --model-repository=/models \
16+
--exit-timeout-secs 15 \
17+
--min-supported-compute-capability 7.0 \
18+
--log-verbose 0 # 0-nothing, 1-info, 2-debug, 3-trace

model_repository/sample/1/model.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,11 @@ def initialize(self, args):
1313
pb_utils.triton_string_to_numpy(output_config["data_type"]) for output_config in output_configs
1414
]
1515

16-
parameters = self.model_config["parameters"]
17-
1816
def execute(self, requests):
1917
responses = [None for _ in requests]
2018
for idx, request in enumerate(requests):
2119
current_add_value = int(json.loads(request.parameters()).get("add", 0))
22-
in_tensor = [item.as_numpy() + current_add_value for item in request.inputs()]
20+
in_tensor = [item.as_numpy() + current_add_value for item in request.inputs() if item.name() == "model_in"]
2321
out_tensor = [
2422
pb_utils.Tensor(output_name, x.astype(output_dtype))
2523
for x, output_name, output_dtype in zip(in_tensor, self.output_name_list, self.output_dtype_list)

model_repository/sample/config.pbtxt

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,6 @@ name: "sample"
22
backend: "python"
33
max_batch_size: 0
44

5-
parameters [
6-
{
7-
key: "add",
8-
value: { string_value: "0" }
9-
}
10-
]
11-
125
input [
136
{
147
name: "model_in"
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import json
2+
3+
import triton_python_backend_utils as pb_utils
4+
5+
6+
class TritonPythonModel:
7+
def initialize(self, args):
8+
self.model_config = model_config = json.loads(args["model_config"])
9+
output_configs = model_config["output"]
10+
11+
self.output_name_list = [output_config["name"] for output_config in output_configs]
12+
self.output_dtype_list = [
13+
pb_utils.triton_string_to_numpy(output_config["data_type"]) for output_config in output_configs
14+
]
15+
16+
def execute(self, requests):
17+
responses = [None for _ in requests]
18+
for idx, request in enumerate(requests):
19+
current_add_value = int(json.loads(request.parameters()).get("add", 0))
20+
optional_in_tensor = pb_utils.get_input_tensor_by_name(request, "optional_model_sub")
21+
if optional_in_tensor:
22+
optional_in_tensor = optional_in_tensor.as_numpy()
23+
else:
24+
optional_in_tensor = 0
25+
26+
in_tensor = [
27+
item.as_numpy() + current_add_value - optional_in_tensor
28+
for item in request.inputs()
29+
if item.name() == "model_in"
30+
]
31+
out_tensor = [
32+
pb_utils.Tensor(output_name, x.astype(output_dtype))
33+
for x, output_name, output_dtype in zip(in_tensor, self.output_name_list, self.output_dtype_list)
34+
]
35+
inference_response = pb_utils.InferenceResponse(output_tensors=out_tensor)
36+
responses[idx] = inference_response
37+
return responses
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: "sample_optional"
2+
backend: "python"
3+
max_batch_size: 0
4+
5+
parameters [
6+
{
7+
key: "add",
8+
value: { string_value: "0" }
9+
}
10+
]
11+
12+
input [
13+
{
14+
name: "model_in"
15+
data_type: TYPE_FP32
16+
dims: [ -1 ]
17+
},
18+
{
19+
name: "optional_model_sub"
20+
data_type: TYPE_FP32
21+
optional: true
22+
dims: [ -1 ]
23+
}
24+
]
25+
26+
output [
27+
{
28+
name: "model_out"
29+
data_type: TYPE_FP32
30+
dims: [ -1 ]
31+
}
32+
]
33+
34+
instance_group [{ kind: KIND_CPU, count: 1 }]
35+
36+
model_warmup {
37+
name: "RandomSampleInput"
38+
batch_size: 1
39+
inputs [{
40+
key: "model_in"
41+
value: {
42+
data_type: TYPE_FP32
43+
dims: [ 10 ]
44+
random_data: true
45+
}
46+
}, {
47+
key: "model_in"
48+
value: {
49+
data_type: TYPE_FP32
50+
dims: [ 10 ]
51+
zero_data: true
52+
}
53+
}]
54+
}

tests/test_model_call.py

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,47 +5,72 @@
55

66
from tritony import InferenceClient
77

8-
MODEL_NAME = os.environ.get("MODEL_NAME", "sample")
98
TRITON_HOST = os.environ.get("TRITON_HOST", "localhost")
109
TRITON_HTTP = os.environ.get("TRITON_HTTP", "8000")
1110
TRITON_GRPC = os.environ.get("TRITON_GRPC", "8001")
1211

1312

13+
EPSILON = 1e-8
14+
15+
1416
@pytest.fixture(params=[("http", TRITON_HTTP), ("grpc", TRITON_GRPC)])
1517
def protocol_and_port(request):
1618
return request.param
1719

1820

19-
def get_client(protocol, port):
21+
def get_client(protocol, port, model_name):
2022
print(f"Testing {protocol}", flush=True)
21-
return InferenceClient.create_with(MODEL_NAME, f"{TRITON_HOST}:{port}", protocol=protocol)
23+
return InferenceClient.create_with(model_name, f"{TRITON_HOST}:{port}", protocol=protocol)
2224

2325

2426
def test_swithcing(protocol_and_port):
25-
client = get_client(*protocol_and_port)
27+
client = get_client(*protocol_and_port, model_name="sample")
2628

2729
sample = np.random.rand(1, 100).astype(np.float32)
2830
result = client(sample)
2931
assert {np.isclose(result, sample).all()}
3032

3133
sample_batched = np.random.rand(100, 100).astype(np.float32)
3234
client(sample_batched, model_name="sample_autobatching")
33-
assert {np.isclose(result, sample).all()}
35+
assert np.isclose(result, sample).all()
3436

3537

3638
def test_with_input_name(protocol_and_port):
37-
client = get_client(*protocol_and_port)
39+
client = get_client(*protocol_and_port, model_name="sample")
3840

3941
sample = np.random.rand(100, 100).astype(np.float32)
4042
result = client({client.default_model_spec.model_input[0].name: sample})
41-
assert {np.isclose(result, sample).all()}
43+
assert np.isclose(result, sample).all()
4244

4345

4446
def test_with_parameters(protocol_and_port):
45-
client = get_client(*protocol_and_port)
47+
client = get_client(*protocol_and_port, model_name="sample")
4648

4749
sample = np.random.rand(1, 100).astype(np.float32)
4850
ADD_VALUE = 1
4951
result = client({client.default_model_spec.model_input[0].name: sample}, parameters={"add": f"{ADD_VALUE}"})
5052

51-
assert {np.isclose(result[0], sample[0] + ADD_VALUE).all()}
53+
assert np.isclose(result[0], sample[0] + ADD_VALUE).all()
54+
55+
56+
def test_with_optional(protocol_and_port):
57+
client = get_client(*protocol_and_port, model_name="sample_optional")
58+
59+
sample = np.random.rand(1, 100).astype(np.float32)
60+
61+
result = client({client.default_model_spec.model_input[0].name: sample})
62+
assert np.isclose(result[0], sample[0], rtol=EPSILON).all()
63+
64+
OPTIONAL_SUB_VALUE = np.zeros_like(sample) + 3
65+
result = client(
66+
{
67+
client.default_model_spec.model_input[0].name: sample,
68+
"optional_model_sub": OPTIONAL_SUB_VALUE,
69+
}
70+
)
71+
assert np.isclose(result[0], sample[0] - OPTIONAL_SUB_VALUE, rtol=EPSILON).all()
72+
73+
74+
if __name__ == "__main__":
75+
test_with_parameters(("grpc", "8101"))
76+
test_with_optional(("grpc", "8101"))

tritony/tools.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,11 @@ async def request_async(protocol: TritonProtocol, model_input: Dict, triton_clie
115115
loop = asyncio.get_running_loop()
116116

117117
if "parameters" in grpc_get_inference_request.__code__.co_varnames:
118-
model_input["parameters"] = None
118+
# check tritonclient[all]>=2.34.0, NGC 23.04
119+
model_input["parameters"] = model_input.get("parameters", None)
120+
else:
121+
logger.warning("tritonclient[all]<2.34.0, NGC 21.04")
122+
model_input.pop("parameters")
119123
request = grpc_get_inference_request(
120124
**model_input,
121125
priority=0,

0 commit comments

Comments
 (0)