Skip to content

Commit c5491d3

Browse files
authored
Use np.object_ when serializing BYTES type (triton-inference-server#38)
* Fix docstring * Fix trailing zero issue for Python backend * Revert
1 parent c840588 commit c5491d3

File tree

2 files changed

+43
-41
lines changed

2 files changed

+43
-41
lines changed

src/resources/startup.py

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -53,29 +53,33 @@
5353

5454
def serialize_byte_tensor(input_tensor):
5555
"""
56-
Serializes a bytes tensor into a flat numpy array of length prepend bytes.
57-
Can pass bytes tensor as numpy array of bytes with dtype of np.bytes_,
58-
numpy strings with dtype of np.str_ or python strings with dtype of np.object.
59-
Parameters
60-
----------
61-
input_tensor : np.array
62-
The bytes tensor to serialize.
63-
Returns
64-
-------
65-
serialized_bytes_tensor : np.array
66-
The 1-D numpy array of type uint8 containing the serialized bytes in 'C' order.
67-
Raises
68-
------
69-
InferenceServerException
70-
If unable to serialize the given tensor.
71-
"""
56+
Serializes a bytes tensor into a flat numpy array of length prepended
57+
bytes. The numpy array should use dtype of np.object_. For np.bytes_,
58+
numpy will remove trailing zeros at the end of byte sequence and because
59+
of this it should be avoided.
60+
61+
Parameters
62+
----------
63+
input_tensor : np.array
64+
The bytes tensor to serialize.
65+
66+
Returns
67+
-------
68+
serialized_bytes_tensor : np.array
69+
The 1-D numpy array of type uint8 containing the serialized bytes in 'C' order.
70+
71+
Raises
72+
------
73+
InferenceServerException
74+
If unable to serialize the given tensor.
75+
"""
7276

7377
if input_tensor.size == 0:
7478
return np.empty([0])
7579

76-
# If the input is a tensor of string/bytes objects, then must flatten those
77-
# into a 1-dimensional array containing the 4-byte byte size followed by
78-
# the actual element bytes. All elements are concatenated together in "C"
80+
# If the input is a tensor of string/bytes objects, then must flatten those into
81+
# a 1-dimensional array containing the 4-byte byte size followed by the
82+
# actual element bytes. All elements are concatenated together in "C"
7983
# order.
8084
if (input_tensor.dtype == np.object) or (input_tensor.dtype.type
8185
== np.bytes_):
@@ -84,18 +88,15 @@ def serialize_byte_tensor(input_tensor):
8488
# If directly passing bytes to BYTES type,
8589
# don't convert it to str as Python will encode the
8690
# bytes which may distort the meaning
87-
if obj.dtype.type == np.bytes_:
88-
if type(obj.item()) == bytes:
89-
s = obj.item()
90-
else:
91-
s = bytes(obj)
91+
if type(obj.item()) == bytes:
92+
s = obj.item()
9293
else:
93-
s = str(obj).encode('utf-8')
94+
s = bytes(obj)
9495
flattened += struct.pack("<I", len(s))
9596
flattened += s
96-
flattened_array = np.asarray(flattened)
97+
flattened_array = np.asarray(flattened, dtype=np.object_)
9798
if not flattened_array.flags['C_CONTIGUOUS']:
98-
flattened_array = np.ascontiguousarray(flattened_array)
99+
flattened_array = np.ascontiguousarray(flattened_array, dtype=np.object_)
99100
return flattened_array
100101
else:
101102
raise TritonModelException(
@@ -128,7 +129,7 @@ def deserialize_bytes_tensor(encoded_tensor):
128129
sb = struct.unpack_from("<{}s".format(l), val_buf, offset)[0]
129130
offset += l
130131
strs.append(sb)
131-
return (np.array(strs, dtype=bytes))
132+
return (np.array(strs, dtype=np.object_))
132133

133134

134135
def parse_startup_arguments():
@@ -149,7 +150,6 @@ def parse_startup_arguments():
149150
class PythonHost(PythonInterpreterServicer):
150151
"""This class handles inference request for python script.
151152
"""
152-
153153
def __init__(self, module_path, *args, **kwargs):
154154
super(PythonInterpreterServicer, self).__init__(*args, **kwargs)
155155

@@ -305,13 +305,18 @@ def Execute(self, request, context):
305305
# We need to serialize TYPE_STRING
306306
if output_np_array.dtype == np.object or output_np_array.dtype.type is np.bytes_:
307307
output_np_array = serialize_byte_tensor(output_np_array)
308-
309-
tensor = Tensor(name=output_tensor.name(),
310-
dtype=tpb_utils.numpy_to_triton_type(
311-
output_np_array.dtype.type),
312-
dims=output_shape,
313-
raw_data=output_np_array.tobytes())
314-
308+
raw_data = output_np_array.item() if output_np_array.size > 0 else b''
309+
tensor = Tensor(name=output_tensor.name(),
310+
dtype=tpb_utils.numpy_to_triton_type(
311+
output_np_array.dtype.type),
312+
dims=output_shape,
313+
raw_data=raw_data)
314+
else:
315+
tensor = Tensor(name=output_tensor.name(),
316+
dtype=tpb_utils.numpy_to_triton_type(
317+
output_np_array.dtype.type),
318+
dims=output_shape,
319+
raw_data=output_np_array.tobytes())
315320
response_tensors.append(tensor)
316321
exec_responses.append(InferenceResponse(outputs=response_tensors))
317322
execute_response = ExecuteResponse(responses=exec_responses)

src/resources/triton_python_backend_utils.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
# TRITONSERVER_TYPE_FP64
5353
12: np.float64,
5454
# TRITONSERVER_TYPE_STRING
55-
13: np.bytes_
55+
13: np.object_
5656
}
5757

5858
TRITON_STRING_TO_NUMPY = {
@@ -68,7 +68,7 @@
6868
'TYPE_FP16': np.float16,
6969
'TYPE_FP32': np.float32,
7070
'TYPE_FP64': np.float64,
71-
'TYPE_STRING': np.bytes_
71+
'TYPE_STRING': np.object_
7272
}
7373

7474
NUMPY_TO_TRITON_TYPE = {v: k for k, v in TRITON_TO_NUMPY_TYPE.items()}
@@ -346,9 +346,6 @@ def triton_to_numpy_type(data_type):
346346

347347

348348
def numpy_to_triton_type(data_type):
349-
if data_type == np.object_:
350-
return 'TYPE_STRING'
351-
352349
return NUMPY_TO_TRITON_TYPE[data_type]
353350

354351

0 commit comments

Comments
 (0)