मानक टेन्सरफ्लो मॉडलसर्वर का निर्माण

यह ट्यूटोरियल आपको दिखाता है कि मानक TensorFlow मॉडल सर्वर बनाने के लिए TensorFlow सर्विंग घटकों का उपयोग कैसे करें जो गतिशील रूप से प्रशिक्षित TensorFlow मॉडल के नए संस्करणों की खोज और सेवा करता है। यदि आप अपने मॉडलों की सेवा के लिए मानक सर्वर का उपयोग करना चाहते हैं, तो TensorFlow सर्विंग बेसिक ट्यूटोरियल देखें।

यह ट्यूटोरियल हस्तलिखित छवि (एमएनआईएसटी डेटा) वर्गीकरण के लिए टेन्सरफ्लो ट्यूटोरियल में पेश किए गए सरल सॉफ्टमैक्स रिग्रेशन मॉडल का उपयोग करता है। यदि आप नहीं जानते कि TensorFlow या MNIST क्या है, तो ML शुरुआती ट्यूटोरियल के लिए MNIST देखें।

इस ट्यूटोरियल के कोड में दो भाग हैं:

  • एक पायथन फ़ाइल mnist_saven_model.py जो मॉडल के कई संस्करणों को प्रशिक्षित और निर्यात करती है।

  • एक C++ फ़ाइल main.cc जो मानक TensorFlow मॉडलसर्वर है जो नए निर्यातित मॉडल की खोज करती है और उनकी सेवा के लिए एक gRPC सेवा चलाती है।

यह ट्यूटोरियल निम्नलिखित कार्यों को पूरा करता है:

  1. TensorFlow मॉडल को प्रशिक्षित करें और निर्यात करें।
  2. TensorFlow सर्विंग ServerCore के साथ मॉडल संस्करण प्रबंधित करें।
  3. SavedModelBundleSourceAdapterConfig का उपयोग करके बैचिंग कॉन्फ़िगर करें।
  4. TensorFlow सर्विंग ServerCore के साथ अनुरोध प्रस्तुत करें।
  5. सेवा चलाएँ और परीक्षण करें.

आरंभ करने से पहले, पहले डॉकर इंस्टॉल करें

TensorFlow मॉडल को प्रशिक्षित करें और निर्यात करें

सबसे पहले, यदि आपने अभी तक ऐसा नहीं किया है, तो इस रिपॉजिटरी को अपनी स्थानीय मशीन पर क्लोन करें:

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 में देख सकते हैं, प्रशिक्षण और निर्यात उसी तरह किया जाता है जैसे कि TensorFlow सर्विंग बेसिक ट्यूटोरियल में किया जाता है। प्रदर्शन उद्देश्यों के लिए, आप जानबूझकर पहले रन के लिए प्रशिक्षण पुनरावृत्तियों को डायल कर रहे हैं और इसे v1 के रूप में निर्यात कर रहे हैं, जबकि दूसरे रन के लिए इसे सामान्य रूप से प्रशिक्षित कर रहे हैं और इसे उसी मूल निर्देशिका में v2 के रूप में निर्यात कर रहे हैं - जैसा कि हम बाद वाले से प्राप्त करने की उम्मीद करते हैं अधिक गहन प्रशिक्षण के कारण बेहतर वर्गीकरण सटीकता। आपको अपनी /tmp/mnist निर्देशिका में चलाए गए प्रत्येक प्रशिक्षण के लिए प्रशिक्षण डेटा देखना चाहिए:

$ ls /tmp/mnist
1  2

सर्वरकोर

अब कल्पना करें कि मॉडल के v1 और v2 रनटाइम पर गतिशील रूप से उत्पन्न होते हैं, क्योंकि नए एल्गोरिदम का प्रयोग किया जा रहा है, या जब मॉडल को नए डेटा सेट के साथ प्रशिक्षित किया जाता है। उत्पादन परिवेश में, आप एक ऐसा सर्वर बनाना चाह सकते हैं जो क्रमिक रोलआउट का समर्थन कर सके, जिसमें v1 की सेवा करते समय v2 को खोजा, लोड किया जा सकता है, प्रयोग किया जा सकता है, मॉनिटर किया जा सकता है या वापस लाया जा सकता है। वैकल्पिक रूप से, आप v2 लाने से पहले v1 को फाड़ना चाह सकते हैं। TensorFlow सर्विंग दोनों विकल्पों का समर्थन करती है - जबकि एक संक्रमण के दौरान उपलब्धता बनाए रखने के लिए अच्छा है, दूसरा संसाधन उपयोग (जैसे RAM) को कम करने के लिए अच्छा है।

TensorFlow सर्विंग Manager बिल्कुल यही करता है। यह TensorFlow मॉडल के पूर्ण जीवनचक्र को संभालता है जिसमें उन्हें लोड करना, सर्व करना और अनलोड करना और साथ ही संस्करण परिवर्तन भी शामिल है। इस ट्यूटोरियल में, आप अपने सर्वर को TensorFlow सर्विंग 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 को राज्य संक्रमण इंटरफेस प्रदान करता है)। यदि PlatformConfig में SavedModelBundleSourceAdapterConfig शामिल है, तो एक 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 उदाहरणों का प्रबंधन करता है। ServerCore AspiredVersionsManager को कॉल सौंपकर Manager इंटरफ़ेस निर्यात करता है।

जब भी कोई नया संस्करण उपलब्ध होता है, तो यह AspiredVersionsManager नया संस्करण लोड करता है, और अपने डिफ़ॉल्ट व्यवहार के तहत पुराने को अनलोड करता है। यदि आप अनुकूलन शुरू करना चाहते हैं, तो आपको उन घटकों को समझने के लिए प्रोत्साहित किया जाता है जो यह आंतरिक रूप से बनाता है, और उन्हें कैसे कॉन्फ़िगर करें।

उल्लेखनीय है कि TensorFlow सर्विंग को शुरुआत से ही बहुत लचीला और विस्तार योग्य बनाने के लिए डिज़ाइन किया गया है। आप 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() को लागू किया जाता है (जहां से जीपीयू पर वास्तविक दक्षता लाभ होता है)।

प्रबंधक के साथ सेवा करें

जैसा कि ऊपर बताया गया है, TensorFlow सर्विंग Manager एक सामान्य घटक के रूप में डिज़ाइन किया गया है जो मनमाने ढंग से मशीन लर्निंग सिस्टम द्वारा उत्पन्न मॉडलों की लोडिंग, सर्विंग, अनलोडिंग और संस्करण संक्रमण को संभाल सकता है। इसके एपीआई निम्नलिखित प्रमुख अवधारणाओं के आसपास बनाए गए हैं:

  • सर्व करने योग्य : सर्व करने योग्य कोई भी अपारदर्शी वस्तु है जिसका उपयोग क्लाइंट के अनुरोधों को पूरा करने के लिए किया जा सकता है। एक सर्व करने योग्य का आकार और ग्रैन्युलैरिटी लचीली होती है, जैसे कि एक एकल सर्व करने योग्य में लुकअप टेबल के एक टुकड़े से लेकर एक मशीन से सीखे गए मॉडल से लेकर मॉडलों के टुपल तक कुछ भी शामिल हो सकता है। एक सर्व करने योग्य किसी भी प्रकार और इंटरफ़ेस का हो सकता है।

  • सर्व करने योग्य संस्करण : सर्व करने योग्य संस्करण होते हैं और TensorFlow सर्विंग Manager एक सर्व करने योग्य के एक या अधिक संस्करणों का प्रबंधन कर सकता है। वर्जनिंग क्रमिक रोलआउट और प्रयोग का समर्थन करते हुए, सर्व करने योग्य के एक से अधिक संस्करण को एक साथ लोड करने की अनुमति देता है।

  • सर्व करने योग्य स्ट्रीम : एक सर्व करने योग्य स्ट्रीम बढ़ती संस्करण संख्या के साथ, एक सर्व करने योग्य के संस्करणों का अनुक्रम है।

  • मॉडल : मशीन से सीखा गया मॉडल एक या अधिक सर्वेबल्स द्वारा दर्शाया जाता है। सर्वबल के उदाहरण हैं:

    • TensorFlow सत्र या उनके चारों ओर रैपर, जैसे SavedModelBundle
    • अन्य प्रकार के मशीन से सीखे गए मॉडल।
    • शब्दावली लुकअप टेबल.
    • लुकअप टेबल एम्बेड करना.

    एक समग्र मॉडल को कई स्वतंत्र सर्वबलों के रूप में, या एकल मिश्रित सर्वयोग्य के रूप में दर्शाया जा सकता है। एक सर्व करने योग्य मॉडल के एक अंश के अनुरूप भी हो सकता है, उदाहरण के लिए कई Manager उदाहरणों में विभाजित एक बड़ी लुकअप तालिका के साथ।

इन सभी को इस ट्यूटोरियल के संदर्भ में रखने के लिए:

  • TensorFlow मॉडल को एक प्रकार के सर्वेबल - SavedModelBundle द्वारा दर्शाया जाता है। SavedModelBundle में आंतरिक रूप से एक tensorflow:Session कुछ मेटाडेटा के साथ जोड़ा जाता है कि सत्र में कौन सा ग्राफ़ लोड किया गया है और अनुमान के लिए इसे कैसे चलाया जाए।

  • एक फ़ाइल-सिस्टम निर्देशिका है जिसमें TensorFlow निर्यात की एक स्ट्रीम शामिल है, प्रत्येक की अपनी उपनिर्देशिका है जिसका नाम एक संस्करण संख्या है। बाहरी निर्देशिका को परोसे जा रहे TensorFlow मॉडल के लिए सर्व करने योग्य स्ट्रीम के क्रमबद्ध प्रतिनिधित्व के रूप में सोचा जा सकता है। प्रत्येक निर्यात एक सर्वेबल्स से मेल खाता है जिसे लोड किया जा सकता है।

  • AspiredVersionsManager निर्यात स्ट्रीम की निगरानी करता है, और सभी SavedModelBundle सर्वेबल्स के जीवनचक्र को गतिशील रूप से प्रबंधित करता है।

TensorflowPredictImpl::Predict तो बस:

  • प्रबंधक से (ServerCore के माध्यम से) 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%

यह पुष्टि करता है कि आपका सर्वर स्वचालित रूप से नए संस्करण की खोज करता है और सेवा के लिए इसका उपयोग करता है!