স্ট্যান্ডার্ড টেনসরফ্লো মডেল সার্ভার তৈরি করা

এই টিউটোরিয়ালটি আপনাকে দেখায় যে কীভাবে টেনসরফ্লো সার্ভিং উপাদানগুলিকে স্ট্যান্ডার্ড টেনসরফ্লো মডেল সার্ভার তৈরি করতে ব্যবহার করতে হয় যা গতিশীলভাবে একটি প্রশিক্ষিত টেনসরফ্লো মডেলের নতুন সংস্করণগুলি আবিষ্কার করে এবং পরিবেশন করে। আপনি যদি শুধুমাত্র আপনার মডেলগুলি পরিবেশন করার জন্য স্ট্যান্ডার্ড সার্ভার ব্যবহার করতে চান, TensorFlow Serving বেসিক টিউটোরিয়াল দেখুন।

এই টিউটোরিয়ালটি হস্তলিখিত চিত্র (MNIST ডেটা) শ্রেণীবিভাগের জন্য TensorFlow টিউটোরিয়ালে প্রবর্তিত সহজ Softmax রিগ্রেশন মডেল ব্যবহার করে। আপনি যদি টেনসরফ্লো বা এমএনআইএসটি কী তা না জানেন তবে এমএল বিগিনার্সের জন্য এমএনআইএসটি টিউটোরিয়ালটি দেখুন।

এই টিউটোরিয়ালের কোড দুটি অংশ নিয়ে গঠিত:

  • একটি পাইথন ফাইল mnist_saved_model.py যা মডেলের একাধিক সংস্করণকে প্রশিক্ষণ ও রপ্তানি করে।

  • একটি C++ ফাইল main.cc যা হল স্ট্যান্ডার্ড টেনসরফ্লো মডেল সার্ভার যা নতুন এক্সপোর্ট করা মডেল আবিষ্কার করে এবং সেগুলি পরিবেশনের জন্য একটি জিআরপিসি পরিষেবা চালায়।

এই টিউটোরিয়ালটি নিম্নলিখিত কাজের মাধ্যমে ধাপে ধাপে রয়েছে:

  1. একটি TensorFlow মডেল প্রশিক্ষণ এবং রপ্তানি করুন।
  2. টেনসরফ্লো সার্ভিং ServerCore সাথে মডেল সংস্করণ পরিচালনা করুন।
  3. SavedModelBundleSourceAdapterConfig ব্যবহার করে ব্যাচিং কনফিগার করুন।
  4. TensorFlow সার্ভিং ServerCore সাথে অনুরোধ পরিবেশন করুন।
  5. চালান এবং পরিষেবা পরীক্ষা.

শুরু করার আগে, প্রথমে ডকার ইনস্টল করুন

ট্রেন এবং রপ্তানি টেনসরফ্লো মডেল

প্রথমত, আপনি যদি এখনও তা না করে থাকেন, তাহলে আপনার স্থানীয় মেশিনে এই সংগ্রহস্থলটি ক্লোন করুন:

git clone https://github.com/tensorflow/serving.git
cd serving

রপ্তানি ডিরেক্টরি সাফ করুন যদি এটি ইতিমধ্যে বিদ্যমান থাকে:

rm -rf /tmp/models

ট্রেন (100টি পুনরাবৃত্তি সহ) এবং মডেলের প্রথম সংস্করণ রপ্তানি করুন:

tools/run_in_docker.sh python tensorflow_serving/example/mnist_saved_model.py \
  --training_iteration=100 --model_version=1 /tmp/mnist

ট্রেন (2000 পুনরাবৃত্তি সহ) এবং মডেলের দ্বিতীয় সংস্করণ রপ্তানি করুন:

tools/run_in_docker.sh python tensorflow_serving/example/mnist_saved_model.py \
  --training_iteration=2000 --model_version=2 /tmp/mnist

আপনি mnist_saved_model.py এ দেখতে পাচ্ছেন, টেনসরফ্লো সার্ভিং বেসিক টিউটোরিয়ালের মতোই প্রশিক্ষণ এবং রপ্তানি করা হয়। প্রদর্শনের উদ্দেশ্যে, আপনি ইচ্ছাকৃতভাবে প্রথম রানের জন্য প্রশিক্ষণের পুনরাবৃত্তিগুলি ডায়াল করছেন এবং এটিকে v1 হিসাবে রপ্তানি করছেন, যখন এটিকে সাধারণত দ্বিতীয় রানের জন্য প্রশিক্ষণ দিচ্ছেন এবং একই প্যারেন্ট ডিরেক্টরিতে v2 হিসাবে রপ্তানি করছেন -- যেমনটি আমরা আশা করি পরবর্তীটি অর্জন করবে আরও নিবিড় প্রশিক্ষণের কারণে শ্রেণীবিভাগের সঠিকতা। আপনার /tmp/mnist ডিরেক্টরিতে চালানো প্রতিটি প্রশিক্ষণের জন্য প্রশিক্ষণের ডেটা দেখতে হবে:

$ ls /tmp/mnist
1  2

সার্ভারকোর

এখন কল্পনা করুন মডেলটির v1 এবং v2 রানটাইমে গতিশীলভাবে তৈরি হয়, যেহেতু নতুন অ্যালগরিদম নিয়ে পরীক্ষা করা হচ্ছে, বা মডেলটিকে একটি নতুন ডেটা সেটের সাথে প্রশিক্ষিত করা হচ্ছে। একটি উত্পাদন পরিবেশে, আপনি এমন একটি সার্ভার তৈরি করতে চাইতে পারেন যা ধীরে ধীরে রোলআউটকে সমর্থন করতে পারে, যেখানে v1 পরিবেশন করার সময় v2 আবিষ্কার, লোড, পরীক্ষা, নিরীক্ষণ বা প্রত্যাবর্তন করা যেতে পারে। বিকল্পভাবে, আপনি v2 আনার আগে v1 ছিঁড়ে ফেলতে চাইতে পারেন। TensorFlow সার্ভিং উভয় বিকল্পকে সমর্থন করে -- যখন একটি ট্রানজিশনের সময় প্রাপ্যতা বজায় রাখার জন্য ভাল, অন্যটি সম্পদের ব্যবহার কমানোর জন্য ভাল (যেমন RAM)।

TensorFlow সার্ভিং Manager ঠিক তাই করে। এটি টেনসরফ্লো মডেলগুলির সম্পূর্ণ জীবনচক্র পরিচালনা করে যার মধ্যে লোড করা, পরিবেশন করা এবং সেগুলি আনলোড করার পাশাপাশি সংস্করণ পরিবর্তন করা। এই টিউটোরিয়ালে, আপনি একটি টেনসরফ্লো সার্ভিং ServerCore উপরে আপনার সার্ভার তৈরি করবেন, যা অভ্যন্তরীণভাবে একটি AspiredVersionsManager মোড়ানো হয়।

int main(int argc, char** argv) {
  ...

  ServerCore::Options options;
  options.model_server_config = model_server_config;
  options.servable_state_monitor_creator = &CreateServableStateMonitor;
  options.custom_model_config_loader = &LoadCustomModelConfig;

  ::google::protobuf::Any source_adapter_config;
  SavedModelBundleSourceAdapterConfig
      saved_model_bundle_source_adapter_config;
  source_adapter_config.PackFrom(saved_model_bundle_source_adapter_config);
  (*(*options.platform_config_map.mutable_platform_configs())
      [kTensorFlowModelPlatform].mutable_source_adapter_config()) =
      source_adapter_config;

  std::unique_ptr<ServerCore> core;
  TF_CHECK_OK(ServerCore::Create(options, &core));
  RunServer(port, std::move(core));

  return 0;
}

ServerCore::Create() একটি ServerCore::Options প্যারামিটার নেয়। এখানে কয়েকটি সাধারণভাবে ব্যবহৃত বিকল্প রয়েছে:

  • ModelServerConfig যা লোড করার জন্য মডেল নির্দিষ্ট করে। মডেলগুলি হয় model_config_list এর মাধ্যমে ঘোষণা করা হয়, যা মডেলগুলির একটি স্ট্যাটিক তালিকা ঘোষণা করে, অথবা custom_model_config এর মাধ্যমে, যা রানটাইমে আপডেট হতে পারে এমন মডেলগুলির একটি তালিকা ঘোষণা করার একটি কাস্টম উপায় সংজ্ঞায়িত করে।
  • PlatformConfigMap যা প্ল্যাটফর্মের নাম (যেমন tensorflow ) থেকে PlatformConfig এ ম্যাপ করে, যা SourceAdapter তৈরি করতে ব্যবহৃত হয়। SourceAdapter StoragePath (যে পথটি একটি মডেল সংস্করণ আবিষ্কৃত হয়) মডেল Loader (স্টোরেজ পাথ থেকে মডেল সংস্করণ লোড করে এবং Manager স্টেট ট্রানজিশন ইন্টারফেস প্রদান করে) অ্যাডাপ্ট করে। যদি PlatformConfigSavedModelBundleSourceAdapterConfig থাকে, তাহলে একটি SavedModelBundleSourceAdapter তৈরি করা হবে, যা আমরা পরে ব্যাখ্যা করব।

SavedModelBundle হল TensorFlow সার্ভিংয়ের একটি মূল উপাদান। এটি একটি প্রদত্ত পথ থেকে লোড করা একটি TensorFlow মডেল উপস্থাপন করে এবং অনুমান চালানোর জন্য TensorFlow হিসাবে একই Session::Run ইন্টারফেস প্রদান করে। SavedModelBundleSourceAdapter Loader<SavedModelBundle> এ স্টোরেজ পাথ অ্যাডাপ্ট করে যাতে Manager দ্বারা মডেলের জীবনকাল পরিচালনা করা যায়। অনুগ্রহ করে মনে রাখবেন SavedModelBundle হল অবনমিত SessionBundle এর উত্তরসূরী। ব্যবহারকারীদের SavedModelBundle ব্যবহার করতে উৎসাহিত করা হচ্ছে কারণ SessionBundle এর জন্য সমর্থন শীঘ্রই সরিয়ে দেওয়া হবে।

এই সবের সাথে, ServerCore অভ্যন্তরীণভাবে নিম্নলিখিতগুলি করে:

  • একটি FileSystemStoragePathSource ইনস্ট্যান্টিয়েট করে যা model_config_list এ ঘোষিত মডেল এক্সপোর্ট পাথ নিরীক্ষণ করে।
  • model_config_list এ ঘোষিত মডেল প্ল্যাটফর্মের সাথে PlatformConfigMap ব্যবহার করে একটি SourceAdapter ইনস্ট্যান্ট করে এবং FileSystemStoragePathSource এর সাথে সংযোগ করে। এইভাবে, যখনই রপ্তানি পথের অধীনে একটি নতুন মডেল সংস্করণ আবিষ্কৃত হয়, SavedModelBundleSourceAdapter এটিকে একটি Loader<SavedModelBundle> এ মানিয়ে নেয়।
  • AspiredVersionsManager নামক Manager একটি সুনির্দিষ্ট বাস্তবায়ন ইনস্ট্যান্টিয়েট করে যা SavedModelBundleSourceAdapter দ্বারা তৈরি এই ধরনের সমস্ত Loader দৃষ্টান্ত পরিচালনা করে। AspiredVersionsManager কে কলগুলি অর্পণ করে ServerCore Manager ইন্টারফেস রপ্তানি করে।

যখনই একটি নতুন সংস্করণ উপলব্ধ হয়, এই AspiredVersionsManager নতুন সংস্করণ লোড করে এবং এর ডিফল্ট আচরণের অধীনে পুরানোটিকে আনলোড করে। আপনি যদি কাস্টমাইজ করা শুরু করতে চান, তাহলে এটি অভ্যন্তরীণভাবে যে উপাদানগুলি তৈরি করে এবং কীভাবে সেগুলি কনফিগার করতে হয় তা বুঝতে আপনাকে উত্সাহিত করা হয়।

এটি উল্লেখ করার মতো যে টেনসরফ্লো সার্ভিং স্ক্র্যাচ থেকে ডিজাইন করা হয়েছে খুব নমনীয় এবং এক্সটেনসিবল। ServerCore এবং AspiredVersionsManager এর মতো জেনেরিক মূল উপাদানগুলির সুবিধা নেওয়ার সময় আপনি সিস্টেমের আচরণ কাস্টমাইজ করতে বিভিন্ন প্লাগইন তৈরি করতে পারেন। উদাহরণস্বরূপ, আপনি একটি ডেটা সোর্স প্লাগইন তৈরি করতে পারেন যা স্থানীয় স্টোরেজের পরিবর্তে ক্লাউড স্টোরেজ নিরীক্ষণ করে, অথবা আপনি একটি সংস্করণ নীতি প্লাগইন তৈরি করতে পারেন যা ভিন্ন উপায়ে সংস্করণ পরিবর্তন করে -- আসলে, আপনি এমন একটি কাস্টম মডেল প্লাগইন তৈরি করতে পারেন যা পরিবেশন করে নন-টেনসরফ্লো মডেল। এই বিষয়গুলি এই টিউটোরিয়ালের সুযোগের বাইরে। যাইহোক, আপনি আরও তথ্যের জন্য কাস্টম উত্স এবং কাস্টম পরিবেশনযোগ্য টিউটোরিয়ালগুলি উল্লেখ করতে পারেন।

ব্যাচিং

আরেকটি সাধারণ সার্ভার বৈশিষ্ট্য যা আমরা উৎপাদন পরিবেশে চাই তা হল ব্যাচিং। মেশিন লার্নিং ইনফারেন্স করতে ব্যবহৃত আধুনিক হার্ডওয়্যার এক্সিলারেটর (জিপিইউ, ইত্যাদি) সাধারণত যখন অনুমান অনুরোধগুলি বড় ব্যাচে চালানো হয় তখন সর্বোত্তম গণনা দক্ষতা অর্জন করে।

SavedModelBundleSourceAdapter তৈরি করার সময় সঠিক SessionBundleConfig প্রদান করে ব্যাচিং চালু করা যেতে পারে। এই ক্ষেত্রে আমরা BatchingParameters বেশ ডিফল্ট মান সহ সেট করি। কাস্টম টাইমআউট, ব্যাচ_সাইজ, ইত্যাদি মান সেট করে ব্যাচিং সূক্ষ্ম-টিউন করা যেতে পারে। বিস্তারিত জানার জন্য, অনুগ্রহ করে BatchingParameters দেখুন।

SessionBundleConfig session_bundle_config;
// Batching config
if (enable_batching) {
  BatchingParameters* batching_parameters =
      session_bundle_config.mutable_batching_parameters();
  batching_parameters->mutable_thread_pool_name()->set_value(
      "model_server_batch_threads");
}
*saved_model_bundle_source_adapter_config.mutable_legacy_config() =
    session_bundle_config;

সম্পূর্ণ ব্যাচে পৌঁছানোর পরে, অনুমান অনুরোধগুলি অভ্যন্তরীণভাবে একটি একক বড় অনুরোধে (টেনসর) একত্রিত করা হয় এবং tensorflow::Session::Run() চালু করা হয় (যেখান থেকে GPU-তে প্রকৃত দক্ষতা লাভ হয়)।

ম্যানেজারের সাথে পরিবেশন করুন

উপরে উল্লিখিত হিসাবে, টেনসরফ্লো সার্ভিং Manager একটি সাধারণ উপাদান হিসাবে ডিজাইন করা হয়েছে যা অবাধ মেশিন লার্নিং সিস্টেম দ্বারা তৈরি মডেলগুলির লোডিং, পরিবেশন, আনলোডিং এবং সংস্করণ পরিবর্তন পরিচালনা করতে পারে। এর APIগুলি নিম্নলিখিত মূল ধারণাগুলিকে ঘিরে তৈরি করা হয়েছে:

  • পরিবেশনযোগ্য : পরিবেশনযোগ্য যে কোনও অস্বচ্ছ বস্তু যা ক্লায়েন্টের অনুরোধগুলি পরিবেশন করতে ব্যবহার করা যেতে পারে। একটি সার্ভেবলের আকার এবং গ্রানুলারিটি নমনীয়, যেমন একটি একক পরিবেশনযোগ্য একটি লুকআপ টেবিলের একক শার্ড থেকে একটি একক মেশিন-শিক্ষিত মডেল থেকে একাধিক মডেল পর্যন্ত কিছু অন্তর্ভুক্ত করতে পারে। একটি servable যে কোনো ধরনের এবং ইন্টারফেস হতে পারে.

  • পরিবেশনযোগ্য সংস্করণ : পরিবেশনযোগ্যগুলি সংস্করণযুক্ত এবং টেনসরফ্লো সার্ভিং Manager একটি পরিবেশনের এক বা একাধিক সংস্করণ পরিচালনা করতে পারে। সংস্করণকরণ একটি পরিবেশনযোগ্য সংস্করণের একাধিক সংস্করণকে একযোগে লোড করার অনুমতি দেয়, ধীরে ধীরে রোলআউট এবং পরীক্ষা-নিরীক্ষা সমর্থন করে।

  • পরিবেশনযোগ্য স্ট্রীম : একটি পরিবেশনযোগ্য স্ট্রিম হল একটি পরিবেশনযোগ্য সংস্করণের ক্রম, যার সংখ্যা বৃদ্ধি পাচ্ছে।

  • মডেল : একটি মেশিন-শিক্ষিত মডেল এক বা একাধিক পরিবেশনযোগ্য দ্বারা প্রতিনিধিত্ব করা হয়। servables উদাহরণ হল:

    • TensorFlow সেশন বা তাদের চারপাশে মোড়ানো, যেমন SavedModelBundle
    • অন্যান্য ধরণের মেশিন-লার্নড মডেল।
    • শব্দভান্ডার সন্ধান টেবিল।
    • এম্বেডিং লুকআপ টেবিল।

    একটি যৌগিক মডেলকে একাধিক স্বাধীন পরিবেশনযোগ্য হিসাবে বা একক যৌগিক পরিবেশনযোগ্য হিসাবে উপস্থাপন করা যেতে পারে। একটি পরিবেশনযোগ্য একটি মডেলের একটি ভগ্নাংশের সাথেও মিলিত হতে পারে, উদাহরণস্বরূপ অনেকগুলি Manager দৃষ্টান্ত জুড়ে একটি বড় লুকআপ টেবিলের সাথে।

এই টিউটোরিয়ালের প্রেক্ষাপটে এগুলি রাখতে:

  • TensorFlow মডেলগুলিকে এক ধরনের পরিবেশনযোগ্য - SavedModelBundle দ্বারা উপস্থাপন করা হয়। SavedModelBundle অভ্যন্তরীণভাবে একটি tensorflow:Session সেশনে কোন গ্রাফটি লোড করা হয় এবং কীভাবে অনুমানের জন্য এটি চালাতে হয় সে সম্পর্কে কিছু মেটাডেটা যুক্ত করা হয়।

  • একটি ফাইল-সিস্টেম ডিরেক্টরি রয়েছে যেখানে টেনসরফ্লো এক্সপোর্টের একটি স্ট্রীম রয়েছে, প্রতিটির নিজস্ব সাবডিরেক্টরিতে রয়েছে যার নাম একটি সংস্করণ নম্বর। বাইরের ডিরেক্টরিটিকে টেনসরফ্লো মডেলের জন্য পরিবেশনযোগ্য স্ট্রিমের ক্রমিক উপস্থাপনা হিসাবে বিবেচনা করা যেতে পারে। প্রতিটি রপ্তানি লোড করা যেতে পারে এমন একটি servables এর সাথে মিলে যায়।

  • AspiredVersionsManager রপ্তানি স্ট্রীম নিরীক্ষণ করে, এবং সমস্ত SavedModelBundle servables এর জীবনচক্র গতিশীলভাবে পরিচালনা করে।

TensorflowPredictImpl::Predict তারপর শুধু:

  • ম্যানেজারের কাছ থেকে SavedModelBundle অনুরোধ (সার্ভারকোরের মাধ্যমে)।
  • PredictRequest এ যৌক্তিক টেনসরের নামগুলিকে বাস্তব টেনসরের নামের সাথে মানচিত্র করতে এবং টেনসরের সাথে মানগুলি আবদ্ধ করতে generic signatures ব্যবহার করে।
  • অনুমান চালায়।

পরীক্ষা করুন এবং সার্ভার চালান

নিরীক্ষণ করা ফোল্ডারে এক্সপোর্টের প্রথম সংস্করণটি অনুলিপি করুন:

mkdir /tmp/monitored
cp -r /tmp/mnist/1 /tmp/monitored

তারপর সার্ভার শুরু করুন:

docker run -p 8500:8500 \
  --mount type=bind,source=/tmp/monitored,target=/models/mnist \
  -t --entrypoint=tensorflow_model_server tensorflow/serving --enable_batching \
  --port=8500 --model_name=mnist --model_base_path=/models/mnist &

সার্ভারটি প্রতি এক সেকেন্ডে লগ বার্তা নির্গত করবে যা বলে "সার্ভারযোগ্যের জন্য উচ্চাকাঙ্ক্ষী সংস্করণ ...", যার অর্থ এটি রপ্তানি খুঁজে পেয়েছে এবং এর অব্যাহত অস্তিত্ব ট্র্যাক করছে৷

--concurrency=10 দিয়ে ক্লায়েন্ট চালাই। এটি সার্ভারে একযোগে অনুরোধ পাঠাবে এবং এইভাবে আপনার ব্যাচিং লজিককে ট্রিগার করবে।

tools/run_in_docker.sh python tensorflow_serving/example/mnist_client.py \
  --num_tests=1000 --server=127.0.0.1:8500 --concurrency=10

যার ফলে আউটপুট দেখায়:

...
Inference error rate: 13.1%

তারপরে আমরা রপ্তানির দ্বিতীয় সংস্করণটি পর্যবেক্ষণ করা ফোল্ডারে অনুলিপি করি এবং পরীক্ষাটি পুনরায় চালাই:

cp -r /tmp/mnist/2 /tmp/monitored
tools/run_in_docker.sh python tensorflow_serving/example/mnist_client.py \
  --num_tests=1000 --server=127.0.0.1:8500 --concurrency=10

যার ফলে আউটপুট দেখায়:

...
Inference error rate: 9.5%

এটি নিশ্চিত করে যে আপনার সার্ভার স্বয়ংক্রিয়ভাবে নতুন সংস্করণ আবিষ্কার করে এবং পরিবেশনের জন্য এটি ব্যবহার করে!