关于传递String数据类型前面需要加个len的情况,这个过程是在构造数据和解析数据的时候使用,好像也可以不使用
python的客户端在收发的时候都会加上len(解析的时候也会解析len),这个在python客户端库中添加了
def serialize_byte_tensor(input_tensor):
"""
Serializes a bytes tensor into a flat numpy array of length prepended
bytes. The numpy array should use dtype of np.object_. For np.bytes_,
numpy will remove trailing zeros at the end of byte sequence and because
of this it should be avoided.
Parameters
----------
input_tensor : np.array
The bytes tensor to serialize.
Returns
-------
serialized_bytes_tensor : np.array
The 1-D numpy array of type uint8 containing the serialized bytes in row-major form.
Raises
------
InferenceServerException
If unable to serialize the given tensor.
"""
if input_tensor.size == 0:
return np.empty([0], dtype=np.object_)
# If the input is a tensor of string/bytes objects, then must flatten those into
# a 1-dimensional array containing the 4-byte byte size followed by the
# actual element bytes. All elements are concatenated together in row-major
# order.
if (input_tensor.dtype != np.object_) and (input_tensor.dtype.type !=
np.bytes_):
raise_error("cannot serialize bytes tensor: invalid datatype")
flattened_ls = []
# 'C' order is row-major.
for obj in np.nditer(input_tensor, flags=["refs_ok"], order='C'):
# If directly passing bytes to BYTES type,
# don't convert it to str as Python will encode the
# bytes which may distort the meaning
if input_tensor.dtype == np.object_:
if type(obj.item()) == bytes:
s = obj.item()
else:
s = str(obj.item()).encode('utf-8')
else:
s = obj.item()
flattened_ls.append(struct.pack("<I", len(s)))
flattened_ls.append(s)
flattened = b''.join(flattened_ls)
flattened_array = np.asarray(flattened, dtype=np.object_)
if not flattened_array.flags['C_CONTIGUOUS']:
flattened_array = np.ascontiguousarray(flattened_array,
dtype=np.object_)
return flattened_array
C++也有相应的
Error
InferInput::AppendFromString(const std::vector<std::string>& input)
{
// Serialize the strings into a "raw" buffer. The first 4-bytes are
// the length of the string length. Next are the actual string
// characters. There is *not* a null-terminator on the string.
str_bufs_.emplace_back();
std::string& sbuf = str_bufs_.back();
for (const auto& str : input) {
uint32_t len = str.size();
sbuf.append(reinterpret_cast<const char*>(&len), sizeof(uint32_t));
sbuf.append(str);
}
return AppendRaw(reinterpret_cast<const uint8_t*>(&sbuf[0]), sbuf.size());
}