Skip to content

Padding for variable-length inputs in batching session.  #530

@penguin138

Description

@penguin138

Hi, I encountered a problem when using serving with RNNs that accept variable-length input. When passing batch of inputs of variable length to RNN I perform zero padding and save original sequence lengths, so that input tensor has fixed dimensions. When using serving with batching I am unable to do that, because apparently batching session does not perform padding (even optional) for batch of incoming requests. So when I send requests with inputs of different length server crashes when concatenating inputs in MergeInputTensors method of BatchingSession. This happens because Concat assumes that all tensors have identical dim sizes for all dims except zero ( it simply uses tensors[0].shape with zero dim size set to sum of zero dim sizes of all tensors), but it's not true for non-padded inputs to RNN.
Here's full output:

...2017-07-21 11:27:52.365101: I tensorflow_serving/model_servers/main.cc:151] Building single TensorFlow model file config:  model_name: default model_base_path: /tinkoff/tfserving_ckpts/ model_version_policy: 0
2017-07-21 11:27:52.365333: I tensorflow_serving/model_servers/server_core.cc:375] Adding/updating models.
2017-07-21 11:27:52.365354: I tensorflow_serving/model_servers/server_core.cc:421]  (Re-)adding model: default
2017-07-21 11:27:52.465527: I tensorflow_serving/core/basic_manager.cc:698] Successfully reserved resources to load servable {name: default version: 1}
2017-07-21 11:27:52.465547: I tensorflow_serving/core/loader_harness.cc:66] Approving load for servable version {name: default version: 1}
2017-07-21 11:27:52.465555: I tensorflow_serving/core/loader_harness.cc:74] Loading servable version {name: default version: 1}
2017-07-21 11:27:52.465570: I external/org_tensorflow/tensorflow/contrib/session_bundle/bundle_shim.cc:360] Attempting to load native SavedModelBundle in bundle-shim from: /tinkoff/tfserving_ckpts/1
2017-07-21 11:27:52.465578: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:236] Loading SavedModel from: /tinkoff/tfserving_ckpts/1
2017-07-21 11:27:52.508828: W external/org_tensorflow/tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE4.1 instructions, but these are available on your machine and could speed up CPU computations.
2017-07-21 11:27:52.508850: W external/org_tensorflow/tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE4.2 instructions, but these are available on your machine and could speed up CPU computations.
2017-07-21 11:27:52.508856: W external/org_tensorflow/tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use AVX instructions, but these are available on your machine and could speed up CPU computations.
2017-07-21 11:27:52.508860: W external/org_tensorflow/tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use AVX2 instructions, but these are available on your machine and could speed up CPU computations.
2017-07-21 11:27:52.508864: W external/org_tensorflow/tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use FMA instructions, but these are available on your machine and could speed up CPU computations.
2017-07-21 11:27:52.610637: I external/org_tensorflow/tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:893] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2017-07-21 11:27:52.610983: I external/org_tensorflow/tensorflow/core/common_runtime/gpu/gpu_device.cc:940] Found device 0 with properties: 
name: GeForce GTX 1080
major: 6 minor: 1 memoryClockRate (GHz) 1.936
pciBusID 0000:01:00.0
Total memory: 7.92GiB
Free memory: 7.79GiB
2017-07-21 11:27:52.610995: I external/org_tensorflow/tensorflow/core/common_runtime/gpu/gpu_device.cc:961] DMA: 0 
2017-07-21 11:27:52.611000: I external/org_tensorflow/tensorflow/core/common_runtime/gpu/gpu_device.cc:971] 0:   Y 
2017-07-21 11:27:52.611008: I external/org_tensorflow/tensorflow/core/common_runtime/gpu/gpu_device.cc:1030] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX 1080, pci bus id: 0000:01:00.0)
2017-07-21 11:27:52.687469: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:155] Restoring SavedModel bundle.
2017-07-21 11:27:52.689909: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:190] Running LegacyInitOp on SavedModel bundle.

2017-07-21 11:27:52.693255: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:284] Loading SavedModel: success. Took 227671 microseconds.
2017-07-21 11:27:52.693280: I tensorflow_serving/servables/tensorflow/saved_model_bundle_factory.cc:93] Wrapping session to perform batch processing
2017-07-21 11:27:52.693312: I tensorflow_serving/servables/tensorflow/bundle_factory_util.cc:153] Wrapping session to perform batch processing
2017-07-21 11:27:52.693365: I tensorflow_serving/core/loader_harness.cc:86] Successfully loaded servable version {name: default version: 1}
2017-07-21 11:27:52.695139: I tensorflow_serving/model_servers/main.cc:294] Running ModelServer at 0.0.0.0:8002 ...
2017-07-21 11:38:04.433970: F external/org_tensorflow/tensorflow/core/framework/tensor_util.cc:78] Check failed: offset + from_data.size() <= to_data.size() (348248 vs. 268256)
Aborted (core dumped)

So I've put together a fix similar to PadOp from Tensorflow that performs padding for all dimensions of all input tensors. I would be happy to contribute if you need it, but I need some guidance on how to proceed with:

  • making it optional for specific dimensions of specific tensors( might need to make changes to classes that use Batching session)
  • maybe getting rid of ugly switches (right now code is similar to Tensorflow PadOp)
  • proper testing of this thing

Also, right now it works only with types that support memcpy (as returned by DataTypeCanUseMemcpy), but considering that Concat only works with tensor data types that support memcpy and DT_STRING, I only need to get it to work with DT_STRING. Right now when I try to use DT_STRING tensors it gives me compilation error somewhere deep in Eigen:

In file included from external/eigen_archive/unsupported/Eigen/CXX11/../../../Eigen/Core:371:0,
                 from external/eigen_archive/unsupported/Eigen/CXX11/Tensor:14,
                 from external/org_tensorflow/third_party/eigen3/unsupported/Eigen/CXX11/Tensor:1,
                 from external/org_tensorflow/tensorflow/core/framework/tensor.h:19,
                 from external/org_tensorflow/tensorflow/core/public/session.h:24,
                 from ./tensorflow_serving/batching/batching_session.h:32,
                 from tensorflow_serving/batching/batching_session.cc:16:
external/eigen_archive/unsupported/Eigen/CXX11/../../../Eigen/src/Core/MathFunctions.h: In instantiation of 'static NewType Eigen::internal::cast_impl<OldType, NewType>::run(const OldType&) [with OldType = int; NewType = std::__cxx11::basic_string<char>]':
external/eigen_archive/unsupported/Eigen/CXX11/../../../Eigen/src/Core/MathFunctions.h:402:42:   required from 'NewType Eigen::internal::cast(const OldType&) [with OldType = int; NewType = std::__cxx11::basic_string<char>]'
external/eigen_archive/unsupported/Eigen/CXX11/../../../Eigen/src/Core/functors/UnaryFunctors.h:155:120:   required from 'const NewType Eigen::internal::scalar_cast_op<Scalar, NewType>::operator()(const Scalar&) const [with Scalar = int; NewType = std::__cxx11::basic_string<char>]'
external/eigen_archive/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h:776:129:   required from 'const Eigen::TensorPaddingOp<const PaddingDimensions, const Derived> Eigen::TensorBase<Derived, 0>::pad(const PaddingDimensions&) const [with PaddingDimensions = std::array<std::pair<int, int>, 1ul>; Derived = Eigen::TensorMap<Eigen::Tensor<std::__cxx11::basic_string<char>, 1, 1, long int>, 16, Eigen::MakePointer>]'
tensorflow_serving/batching/batching_session.cc:145:38:   required from 'tensorflow::Tensor tensorflow::serving::PadTensor<DT, T, num_dims>::operator()(tensorflow::Tensor, Eigen::array<std::pair<int, int>, num_dims>, float) [with tensorflow::DataType DT = (tensorflow::DataType)7; T = std::__cxx11::basic_string<char>; int num_dims = 1; Eigen::array<std::pair<int, int>, num_dims> = std::array<std::pair<int, int>, 1ul>]'
tensorflow_serving/batching/batching_session.cc:176:43:   required from 'tensorflow::Tensor tensorflow::serving::pad_tensor_of_specific_type(std::__cxx11::string, tensorflow::Tensor, std::map<std::__cxx11::basic_string<char>, std::vector<int> >) [with tensorflow::DataType DT = (tensorflow::DataType)7; T = std::__cxx11::basic_string<char>; std::__cxx11::string = std::__cxx11::basic_string<char>]'
tensorflow_serving/batching/batching_session.cc:547:113:   required from here
external/eigen_archive/unsupported/Eigen/CXX11/../../../Eigen/src/Core/MathFunctions.h:392:34: error: no matching function for call to 'std::__cxx11::basic_string<char>::basic_string(const int&)'
     return static_cast<NewType>(x);
                                  ^
In file included from /usr/include/c++/5/string:52:0,
                 from /usr/include/c++/5/stdexcept:39,
                 from /usr/include/c++/5/array:38,
                 from /usr/include/c++/5/tuple:39,
                 from /usr/include/c++/5/functional:55,
                 from ./tensorflow_serving/batching/batching_session.h:23,
                 from tensorflow_serving/batching/batching_session.cc:16:
/usr/include/c++/5/bits/basic_string.h:534:9: note: candidate: template<class _InputIterator, class> std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(_InputIterator, _InputIterator, const _Alloc&)
         basic_string(_InputIterator __beg, _InputIterator __end,
         ^
/usr/include/c++/5/bits/basic_string.h:534:9: note:   template argument deduction/substitution failed:
In file included from external/eigen_archive/unsupported/Eigen/CXX11/../../../Eigen/Core:371:0,
                 from external/eigen_archive/unsupported/Eigen/CXX11/Tensor:14,
                 from external/org_tensorflow/third_party/eigen3/unsupported/Eigen/CXX11/Tensor:1,
                 from external/org_tensorflow/tensorflow/core/framework/tensor.h:19,
                 from external/org_tensorflow/tensorflow/core/public/session.h:24,
                 from ./tensorflow_serving/batching/batching_session.h:32,
                 from tensorflow_serving/batching/batching_session.cc:16:
external/eigen_archive/unsupported/Eigen/CXX11/../../../Eigen/src/Core/MathFunctions.h:392:34: note:   candidate expects 3 arguments, 1 provided
     return static_cast<NewType>(x);
                                  ^
In file included from /usr/include/c++/5/string:52:0,
                 from /usr/include/c++/5/stdexcept:39,
                 from /usr/include/c++/5/array:38,
                 from /usr/include/c++/5/tuple:39,
                 from /usr/include/c++/5/functional:55,
                 from ./tensorflow_serving/batching/batching_session.h:23,
                 from tensorflow_serving/batching/batching_session.cc:16:
/usr/include/c++/5/bits/basic_string.h:511:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&&, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       basic_string(basic_string&& __str, const _Alloc& __a)
       ^
/usr/include/c++/5/bits/basic_string.h:511:7: note:   candidate expects 2 arguments, 1 provided
/usr/include/c++/5/bits/basic_string.h:507:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       basic_string(const basic_string& __str, const _Alloc& __a)
       ^
/usr/include/c++/5/bits/basic_string.h:507:7: note:   candidate expects 2 arguments, 1 provided
/usr/include/c++/5/bits/basic_string.h:503:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::initializer_list<_Tp>, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc())
       ^
/usr/include/c++/5/bits/basic_string.h:503:7: note:   no known conversion for argument 1 from 'const int' to 'std::initializer_list<char>'
/usr/include/c++/5/bits/basic_string.h:476:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       basic_string(basic_string&& __str) noexcept
       ^
/usr/include/c++/5/bits/basic_string.h:476:7: note:   no known conversion for argument 1 from 'const int' to 'std::__cxx11::basic_string<char>&&'
/usr/include/c++/5/bits/basic_string.h:464:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type, _CharT, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type = long unsigned int]
       basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc())
       ^
/usr/include/c++/5/bits/basic_string.h:464:7: note:   candidate expects 3 arguments, 1 provided
/usr/include/c++/5/bits/basic_string.h:454:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>] <near match>
       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
       ^
/usr/include/c++/5/bits/basic_string.h:454:7: note:   conversion of argument 1 would be ill-formed:
In file included from external/eigen_archive/unsupported/Eigen/CXX11/../../../Eigen/Core:371:0,
                 from external/eigen_archive/unsupported/Eigen/CXX11/Tensor:14,
                 from external/org_tensorflow/third_party/eigen3/unsupported/Eigen/CXX11/Tensor:1,
                 from external/org_tensorflow/tensorflow/core/framework/tensor.h:19,
                 from external/org_tensorflow/tensorflow/core/public/session.h:24,
                 from ./tensorflow_serving/batching/batching_session.h:32,
                 from tensorflow_serving/batching/batching_session.cc:16:
external/eigen_archive/unsupported/Eigen/CXX11/../../../Eigen/src/Core/MathFunctions.h:392:34: error: invalid conversion from 'int' to 'const char*' [-fpermissive]
     return static_cast<NewType>(x);
                                  ^
In file included from /usr/include/c++/5/string:52:0,
                 from /usr/include/c++/5/stdexcept:39,
                 from /usr/include/c++/5/array:38,
                 from /usr/include/c++/5/tuple:39,
                 from /usr/include/c++/5/functional:55,
                 from ./tensorflow_serving/batching/batching_session.h:23,
                 from tensorflow_serving/batching/batching_session.cc:16:
/usr/include/c++/5/bits/basic_string.h:444:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type = long unsigned int]
       basic_string(const _CharT* __s, size_type __n,
       ^
/usr/include/c++/5/bits/basic_string.h:444:7: note:   candidate expects 3 arguments, 1 provided
/usr/include/c++/5/bits/basic_string.h:426:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&, std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type, std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type = long unsigned int]
       basic_string(const basic_string& __str, size_type __pos,
       ^
/usr/include/c++/5/bits/basic_string.h:426:7: note:   candidate expects 4 arguments, 1 provided
/usr/include/c++/5/bits/basic_string.h:410:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&, std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type, std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::size_type = long unsigned int]
       basic_string(const basic_string& __str, size_type __pos,
       ^
/usr/include/c++/5/bits/basic_string.h:410:7: note:   candidate expects 3 arguments, 1 provided
/usr/include/c++/5/bits/basic_string.h:398:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       basic_string(const basic_string& __str)
       ^
/usr/include/c++/5/bits/basic_string.h:398:7: note:   no known conversion for argument 1 from 'const int' to 'const std::__cxx11::basic_string<char>&'
/usr/include/c++/5/bits/basic_string.h:390:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       basic_string(const _Alloc& __a)
       ^
/usr/include/c++/5/bits/basic_string.h:390:7: note:   no known conversion for argument 1 from 'const int' to 'const std::allocator<char>&'
/usr/include/c++/5/bits/basic_string.h:379:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string() [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       basic_string()
       ^
/usr/include/c++/5/bits/basic_string.h:379:7: note:   candidate expects 0 arguments, 1 provided

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions