यह दस्तावेज़ बताता है कि एक नए प्रकार के सर्वेबल के साथ TensorFlow सर्विंग को कैसे बढ़ाया जाए। सबसे प्रमुख सर्व करने योग्य प्रकार SavedModelBundle
है, लेकिन यह आपके मॉडल के साथ आने वाले डेटा की सेवा के लिए अन्य प्रकार के सर्वेबल्स को परिभाषित करने के लिए उपयोगी हो सकता है। उदाहरणों में शामिल हैं: एक शब्दावली लुकअप तालिका, सुविधा परिवर्तन तर्क। कोई भी C++ क्लास सर्व करने योग्य हो सकती है, उदाहरण के लिए int
, std::map<string, int>
या आपके बाइनरी में परिभाषित कोई भी क्लास - आइए हम इसे YourServable
कहते हैं।
YourServable
के लिए Loader
और SourceAdapter
को परिभाषित करना
YourServable
प्रबंधित और परोसने के लिए TensorFlow सर्विंग को सक्षम करने के लिए, आपको दो चीजों को परिभाषित करने की आवश्यकता है:
एक
Loader
वर्ग जोYourServable
के एक उदाहरण को लोड करता है, उस तक पहुंच प्रदान करता है और अनलोड करता है।एक
SourceAdapter
जो कुछ अंतर्निहित डेटा प्रारूप जैसे फ़ाइल-सिस्टम पथ से लोडर को इंस्टेंटिएट करता है।SourceAdapter
के विकल्प के रूप में, आप एक संपूर्णSource
लिख सकते हैं। हालाँकि, चूंकिSourceAdapter
दृष्टिकोण अधिक सामान्य और अधिक मॉड्यूलर है, इसलिए हम यहां इस पर ध्यान केंद्रित करते हैं।
Loader
एब्स्ट्रैक्शन को core/loader.h
में परिभाषित किया गया है। इसके लिए आपको अपने प्रकार के सर्व करने योग्य को लोड करने, एक्सेस करने और अनलोड करने के तरीकों को परिभाषित करने की आवश्यकता है। जिस डेटा से सर्व करने योग्य लोड किया गया है वह कहीं से भी आ सकता है, लेकिन इसका स्टोरेज-सिस्टम पथ से आना आम बात है। आइए मान लें कि यह YourServable
का मामला है। आइए आगे मान लें कि आपके पास पहले से ही एक Source<StoragePath>
है जिससे आप खुश हैं (यदि नहीं, तो कस्टम सोर्स दस्तावेज़ देखें)।
आपके Loader
के अलावा, आपको एक SourceAdapter
परिभाषित करने की आवश्यकता होगी जो किसी दिए गए स्टोरेज पथ से Loader
को तुरंत चालू करता है। अधिकांश सरल उपयोग-मामले SimpleLoaderSourceAdapter
वर्ग ( core/simple_loader.h
में) के साथ दो वस्तुओं को संक्षिप्त रूप से निर्दिष्ट कर सकते हैं। उन्नत उपयोग-मामले निम्न-स्तरीय एपीआई का उपयोग करके Loader
और SourceAdapter
कक्षाओं को अलग-अलग निर्दिष्ट करने का विकल्प चुन सकते हैं, उदाहरण के लिए यदि SourceAdapter
कुछ स्थिति बनाए रखने की आवश्यकता है, और/या यदि स्थिति को Loader
उदाहरणों के बीच साझा करने की आवश्यकता है।
एक सरल हैशमैप सर्वेबल का एक संदर्भ कार्यान्वयन है जो servables/hashmap/hashmap_source_adapter.cc
में SimpleLoaderSourceAdapter
उपयोग करता है। आपको HashmapSourceAdapter
की एक प्रति बनाना और फिर अपनी आवश्यकताओं के अनुरूप इसे संशोधित करना सुविधाजनक लग सकता है।
HashmapSourceAdapter
के कार्यान्वयन के दो भाग हैं:
LoadHashmapFromFile()
में किसी फ़ाइल से हैशमैप लोड करने का तर्क।एक
SourceAdapter
को परिभाषित करने के लिएSimpleLoaderSourceAdapter
का उपयोग जोLoadHashmapFromFile()
के आधार पर हैशमैप लोडर उत्सर्जित करता है। नएSourceAdapter
HashmapSourceAdapterConfig
प्रकार के कॉन्फ़िगरेशन प्रोटोकॉल संदेश से इंस्टेंट किया जा सकता है। वर्तमान में, कॉन्फ़िगरेशन संदेश में केवल फ़ाइल प्रारूप शामिल है, और संदर्भ कार्यान्वयन के उद्देश्य के लिए केवल एक सरल प्रारूप समर्थित है।डिस्ट्रक्टर में
Detach()
पर कॉल नोट करें। राज्य को तोड़ने और अन्य थ्रेड्स में निर्माता लैम्ब्डा के किसी भी चल रहे आह्वान के बीच दौड़ से बचने के लिए यह कॉल आवश्यक है। (भले ही इस सरल स्रोत एडॉप्टर में कोई स्थिति नहीं है, फिर भी बेस क्लास यह लागू करता है कि Detach() को कॉल किया जाता है।)
YourServable
ऑब्जेक्ट को प्रबंधक में लोड करने की व्यवस्था करना
यहां बताया गया है कि YourServable
लोडर के लिए अपने नए SourceAdapter
स्टोरेज पथों के मूल स्रोत और एक प्रबंधक से कैसे जोड़ा जाए (खराब त्रुटि प्रबंधन के साथ; वास्तविक कोड अधिक सावधान रहना चाहिए):
सबसे पहले, एक प्रबंधक बनाएं:
std::unique_ptr<AspiredVersionsManager> manager = ...;
फिर, एक YourServable
स्रोत एडाप्टर बनाएं और इसे प्रबंधक में प्लग करें:
auto your_adapter = new YourServableSourceAdapter(...);
ConnectSourceToTarget(your_adapter, manager.get());
अंत में, एक सरल पथ स्रोत बनाएं और इसे अपने एडाप्टर में प्लग करें:
std::unique_ptr<FileSystemStoragePathSource> path_source;
// Here are some FileSystemStoragePathSource config settings that ought to get
// it working, but for details please see its documentation.
FileSystemStoragePathSourceConfig config;
// We just have a single servable stream. Call it "default".
config.set_servable_name("default");
config.set_base_path(FLAGS::base_path /* base path for our servable files */);
config.set_file_system_poll_wait_seconds(1);
TF_CHECK_OK(FileSystemStoragePathSource::Create(config, &path_source));
ConnectSourceToTarget(path_source.get(), your_adapter.get());
लोड की गई YourServable
ऑब्जेक्ट तक पहुंच
यहां बताया गया है कि लोड किए गए YourServable
का हैंडल कैसे प्राप्त करें और उसका उपयोग कैसे करें:
auto handle_request = serving::ServableRequest::Latest("default");
ServableHandle<YourServable*> servable;
Status status = manager->GetServableHandle(handle_request, &servable);
if (!status.ok()) {
LOG(INFO) << "Zero versions of 'default' servable have been loaded so far";
return;
}
// Use the servable.
(*servable)->SomeYourServableMethod();
उन्नत: स्थिति साझा करने के लिए एकाधिक सर्व करने योग्य उदाहरणों की व्यवस्था करना
सोर्स एडेप्टर उस स्थिति को रख सकते हैं जिसे कई उत्सर्जित सर्वेबल्स के बीच साझा किया जाता है। उदाहरण के लिए:
एक साझा थ्रेड पूल या अन्य संसाधन जिसका उपयोग एकाधिक सर्वेबल्स करते हैं।
एक साझा रीड-ओनली डेटा संरचना जिसका उपयोग कई सर्व करने योग्य उदाहरण में डेटा संरचना की नकल करने के समय और स्थान के ओवरहेड से बचने के लिए करते हैं।
साझा स्थिति जिसका आरंभीकरण समय और आकार नगण्य है (उदाहरण के लिए थ्रेड पूल) को सोर्स एडाप्टर द्वारा उत्सुकता से बनाया जा सकता है, जो फिर प्रत्येक उत्सर्जित सर्व करने योग्य लोडर में एक पॉइंटर को एम्बेड करता है। महंगे या बड़े साझा राज्य का निर्माण पहले लागू लोडर::लोड() कॉल के लिए स्थगित किया जाना चाहिए, अर्थात प्रबंधक द्वारा शासित। सममित रूप से, महंगी/बड़ी साझा स्थिति का उपयोग करके अंतिम सर्व करने योग्य लोडर::अनलोड() कॉल को इसे तोड़ देना चाहिए।