Kuidas TensorFlow mudeleid tootmiseks TF TF-i abil kasutada

Sissejuhatus

Masinõppe mudelite kasutuselevõtmine tootmises on muutunud populaarseks ja korduvaks teemaks. Paljud ettevõtted ja raamistikud pakuvad erinevaid lahendusi, mille eesmärk on selle probleemiga tegeleda.

Selle mure lahendamiseks andis Google välja TensorFlow (TF) Servingi, pakkudes lootust lahendada ML-mudelite tootmise juurutamise probleem.

See tükk pakub praktilist õpet eelõppe saanud konvolutsioonilise semantilise segmenteerimisvõrgu teenindamiseks. Selle artikli lõpuks saate TF-i teenust kasutada TF-is koolitatud Deep CNN-i juurutamiseks ja taotluste esitamiseks. Samuti esitan ülevaate TF-esitamise peamistest plokkidest ning arutan selle API-sid ja kuidas see kõik töötab.

Üks asi, mida kohe märkate, on see, et TF-mudeli reaalseks teenindamiseks on vaja väga vähe koodi. Kui soovite tutvuda juhendajaga ja käivitada näite oma arvutis, järgige seda nagu praegu. Kuid kui soovite teada ainult TensorFlow teenindamise kohta, võite keskenduda kahele esimesele jaotisele.

See tükk rõhutab osa tööst, mida me siin Daitan Groupis teeme.

TensorFlow teenindavad raamatukogud - ülevaade

Võtame veidi aega, et mõista, kuidas TF Serving ML-i mudelite teenindamise kogu olelustsükli jooksul toime tuleb. Siin käsitleme (kõrgel tasemel) kõiki TF Servingi peamisi ehitusplokke. Selle jaotise eesmärk on anda pehme tutvustus TF-i teenindavate API-de jaoks. Põhjaliku ülevaate saamiseks külastage TF Teenuste dokumentatsiooni lehte.

TensorFlow Serving koosneb mõnest abstraktsioonist. Need abstraktsioonid rakendavad API-sid erinevate ülesannete jaoks. Kõige olulisemad neist on Servable, Loader, Source ja Manager. Vaatame üle, kuidas nad suhelda saavad.

Lühidalt - esitamise elutsükkel algab siis, kui TF Serving tuvastab mudeli kettal. Lähtekomponent hoolitseb selle eest. See vastutab uute laaditavate mudelite tuvastamise eest. Praktikas hoiab see failisüsteemil silma peal, et tuvastada uue mudeli versiooni saabumine kettale. Uue versiooni nägemisel luuakse selle mudeli konkreetse versiooni jaoks laadur.

Kokkuvõtlikult võib öelda, et laadur teab mudeli kohta peaaegu kõike. See sisaldab seda, kuidas seda laadida ja kuidas hinnata mudeli vajalikke ressursse, näiteks taotletud RAM ja GPU mälu. Laaduril on mudelile osuti kettal koos kõigi selle laadimiseks vajalike metaandmetega. Kuid siin on saak: laaduril pole veel lubatud mudelit laadida.

Pärast laaduri loomist saadab allikas selle haldurile aspired versionina.

Pärast mudeli eeldatava versiooni saamist jätkab haldur esitamisprotsessi. Siin on kaks võimalust. Üks on see, et esimene mudeli versioon lükatakse juurutamiseks. Selles olukorras hoolitseb haldur vajalike ressursside olemasolu eest. Kui need on olemas, annab haldur laadurile loa mudeli laadimiseks.

Teine on see, et lükkame ümber olemasoleva mudeli uue versiooni. Sel juhul peab haldur enne kaugemale minemist konsulteerima versioonipoliitika pistikprogrammiga. Versioonipoliitika määratleb, kuidas uue mudeli versiooni laadimine toimub.

Täpsemalt, mudeli uue versiooni laadimisel saame valida (1) saadavuse või (2) ressursside säilitamise vahel. Esimesel juhul oleme huvitatud sellest, et meie süsteem oleks sissetulevate klientide taotluste jaoks alati saadaval. Me teame, et haldur lubab laaduril uue graafiku uute kaaludega realiseerida.

Sel hetkel on meil korraga laaditud kaks mudeli versiooni. Kuid haldur laadib vanema versiooni maha alles pärast laadimise lõppu ja mudelite vahel on turvaline vahetada.

Teisest küljest, kui soovime ressursse kokku hoida, kuna meil pole lisapuhvrit (uue versiooni jaoks), võime ressursse säilitada. Väga raskete mudelite jaoks võib olla kasulik mälu säästmise vastu väike puudus saadavusest.

Lõpus, kui klient nõuab mudeli käepidet, tagastab haldur käepideme serverisse.

Selle ülevaate abil võime sukelduda reaalse maailma rakendusse. Järgmistes jaotistes kirjeldame, kuidas TF Servingut kasutades teenida konvolutsioonilist närvivõrku (CNN).

Teenindamise mudeli eksportimine

Esimene samm TensorFlow-i sisseehitatud ML-mudeli teenindamiseks on veenduda, et see on õiges vormingus. Selleks pakub TensorFlow klassi SavedModel.

SavedModel on universaalne serialiseerimisvorming TensorFlow mudelitele. Kui olete TF-iga tuttav, olete tõenäoliselt kasutanud mudeli muutujate säilitamiseks TensorFlow Saverit.

TensorFlow Saver pakub funktsioone mudeli kontrollpunktide failide salvestamiseks / taastamiseks kettalt / kettalt. Tegelikult pakendab SavedModel TensorFlow Saver ja see on mõeldud TF-mudelite esitamiseks tavaliseks viisiks.

Objektil SavedModel on mõned toredad funktsioonid.

Esiteks võimaldab see salvestada ühele SavedModeli objektile rohkem kui ühe metagraafiku. Teisisõnu, see võimaldab meil erinevate ülesannete jaoks erinevaid graafikuid.

Näiteks oletame, et olete just lõpetanud oma mudeli koolitamise. Enamikul juhtudel ei vaja graafik järelduste tegemiseks mõnda treeningupõhist toimingut. Need opid võivad sisaldada optimeerija muutujaid, õppimiskiiruse ajastamise tenoreid, täiendavaid eeltöötluse oppe jne.

Lisaks võiksite mobiili juurutamiseks esitada graafi kvanteeritud versiooni.

Selles kontekstis võimaldab SavedModel salvestada erinevate konfiguratsioonidega graafikuid. Meie näites oleks kolm erinevat graafikut koos vastavate siltidega, nagu „koolitus”, „järeldus” ja „mobiil”. Samuti jagaksid need kolm graafikut sama muutujate komplekti - see rõhutab mälu tõhusust.

Mitte nii kaua aega tagasi, kui tahtsime TF-mudeleid mobiilseadmetele juurutada, pidime teadma sisend- ja väljundtensorite nimesid mudelisöötmiseks ja andmete saamiseks. See nõuab programmeerijatelt sunnitud otsima vajalikku tenorit graafiku kõigi tenoride seast. Kui tenoreid õigesti ei nimetata, võib ülesanne olla väga tüütu.

Asjade lihtsustamiseks pakub SavedModel tuge SignatureDefsile. Kokkuvõtlikult määratlevad SignatureDefs arvutuse allkirja, mida toetab TensorFlow. See määrab arvutusliku graafiku jaoks õiged sisend- ja väljund tenorid. Lihtsamalt öeldes saate nende allkirjade abil täpsustada sisendi ja väljundi jaoks täpsed sõlmed.

Sisseehitatud teenindavate API-de kasutamiseks vajab TF-esitamine mudeleid, mis sisaldavad ühte või mitut SignatureDefs.

Selliste allkirjade loomiseks peame esitama sisendite, väljundite ja soovitud meetodi nime definitsioonid. Sisendid ja väljundid tähistavad stringi ja TensorInfo objektide kaardistamise (selle viimase kohta rohkem). Siin määratleme vaike tenorid graafikule andmete edastamiseks ja vastuvõtmiseks. Parameeter method_name on suunatud ühele TF kõrgetasemelist teenuseliidest.

Praegu on teenindavaid API-sid kolm: klassifitseerimine, ennustamine ja regressioon. Iga allkirja määratlus vastab konkreetsele RPC API-le. Classified RPC API jaoks kasutatakse Classification SegnatureDef. Predict SegnatureDef on ette nähtud RPC API ennustamiseks ja edasi.

Klassifikaatori allkirja jaoks peab olema sisendtensor (andmete vastuvõtmiseks) ja vähemalt üks kahest võimalikust väljundtensorist: klassid ja / või hinded. Regression SignatureDef nõuab sisendiks täpselt ühte tenorit ja väljundiks teist. Lõpuks võimaldab allkiri Ennustada võimaldab dünaamilist arvu sisend- ja väljund tenoreid.

Lisaks toetab SavedModel varade ladustamist juhtudel, kui opside lähtestamine sõltub välistest failidest. Samuti on sellel mehhanismid seadmete kustutamiseks enne SavedModeli loomist.

Vaatame nüüd, kuidas seda praktikas teha.

Keskkonna seadistamine

Enne kui alustame, kloonige see TensorFlow DeepLab-v3 rakendus Githubist.

DeepLab on Google'i parim semantiline segmenteerimine ConvNet. Põhimõtteliselt võtab võrk pildi sisendina ja väljastab maskitaolise pildi, mis eraldab teatud objektid taustast.

Seda versiooni koolitati Pascal VOC segmenteerimise andmekogumis. Seega saab see segmentida ja ära tunda kuni 20 klassi. Kui soovite semantilise segmenteerimise ja DeepLab-v3 kohta rohkem teada saada, siis vaadake lähemalt sukeldumist sügavatesse konvolutsioonsetesse semantilistesse segmenteerimisvõrkudesse ja Deeplab_V3.

Kõik teenindamisega seotud failid asuvad: ./deeplab_v3/serving/. Seal leiate kaks olulist faili: deeplab_saved_model.py ja deeplab_client.ipynb

Enne kaugemale minekut laadige kindlasti alla eelkoolitatud Deeplab-v3 mudel. Minge ülaltoodud GitHubi hoidlasse, klõpsake lingil kontrollpunktid ja laadige alla kaust nimega 16645 /.

Lõpuks peaks teil olema kaust nimega tboard_logs /, mille sees oleks kaust 16645 /.

Nüüd peame looma kaks Pythoni virtuaalset keskkonda. Üks Python 3 ja teine ​​Python 2 jaoks. Iga env jaoks installige kindlasti vajalikud sõltuvused. Leiate need failide serve_requirements.txt ja client_requirements.txt failidest.

Vajame kahte Pythoni env, kuna meie mudel DeepLab-v3 töötati välja Python 3 all. TensorFlow Serving Python API avaldatakse siiski ainult Python 2 jaoks. Seetõttu kasutame mudeli eksportimiseks ja TF-i esitamise käitamiseks Python 3 env . Kliendikoodi käitamiseks TF Serving python API abil kasutame PIP paketti (saadaval ainult Python 2 jaoks).

Pange tähele, et saate Python 2 env-st loobuda, kasutades teenuseliidese API-sid bazelist. Üksikasjalikuma teabe saamiseks lugege TF teenust Installatsioon.

Selle sammu lõpetamisega alustame kõige olulisemast.

Kuidas seda teha

SavedModeli kasutamiseks pakub TensorFlow hõlpsasti kasutatavat kõrgetasemelist utiliidi SavedModelBuilder. Klass SavedModelBuilder pakub funktsioone mitme metagraafiku, nendega seotud muutujate ja varade salvestamiseks.

Vaatame lähemalt näidet, kuidas eksportida sügava segmenteerimisega CNN-i mudelit esitamiseks.

Nagu eespool mainitud, kasutame mudeli eksportimiseks klassi SavedModelBuilder. See genereerib protokolli puhverfaili SavedModel koos mudeli muutujate ja varadega (vajadusel).

Tehke kood lahti.

SavedModelBuilder võtab vastu (sisendina) kataloogi, kuhu mudeli andmed salvestada. Muutuja export_path on siin ekspordi_path_baasi ja mudeli_versiooni liitmine. Selle tulemusel salvestatakse erinevad mudeli versioonid eraldi kataloogidesse kausta export_path_base.

Ütleme nii, et meil on tootmisel meie mudeli algversioon, kuid tahame juurutada selle uue versiooni. Oleme parandanud oma mudeli täpsust ja soovime seda uut versiooni pakkuda oma klientidele.

Sama graafiku erineva versiooni eksportimiseks saame lihtsalt määrata FLAGS.model_version kõrgema täisarvu. Seejärel luuakse kausta export_path_base teine ​​kaust (milles on meie mudeli uus versioon).

Nüüd peame täpsustama oma mudeli sisend- ja väljund tenorid. Selleks kasutame SignatureDefs. Allkirjad määravad, millist tüüpi mudeleid me eksportida tahame. See pakub kaardistamist stringidest (loogilised Tensori nimed) TensorInfo objektideni. Idee on see, et tegelikele tenorinimedele sisendile / väljundile viitamise asemel saavad kliendid viidata allkirjade määratletud loogilistele nimedele.

Semantilise segmenteerimise CNN-i teenindamiseks loome ennustatava allkirja. Pange tähele, et funktsioon build_signature_def () võtab sisend- ja väljundtensorite ning soovitud API kaardistamise.

SignatureDef nõuab järgmiste andmete täpsustamist: sisendid, väljundid ja meetodi nimi. Pange tähele, et sisenditele ootame kolme väärtust - pilti ja veel kahte tenorit, mis täpsustavad selle mõõtmeid (kõrgus ja laius). Väljundite jaoks määratlesime ainult ühe tulemuse - segmenteerimisväljundi maski.

Pange tähele, et stringid „pilt”, „kõrgus”, „laius” ja „segmentimine_kaart” ei ole tenorid. Selle asemel on need loogilised nimed, mis viitavad tegelikele tenoritele input_tensor, image_height_tensor ja image_width_tensor. Seega võivad need olla suvalised unikaalsed stringid.

Samuti puudutavad SignatureDefs kaardistused TensorInfo protobufi objekte, mitte tegelikke tenoreid. TensorInfo objektide loomiseks kasutame utiliidi funktsiooni: tf.saved_model.utils.build_tensor_info (tensor).

See on kõik. Nüüd kutsume funktsiooni add_meta_graph_and_variables () üles ehitama protokolli puhverobjekti SavedModel. Siis käivitame salvestamismeetodi ja see säilitab meie mudeli hetketõmmise kettale, mis sisaldab mudeli muutujaid ja varasid.

Nüüd saame mudeli eksportimiseks käivitada deeplab_saved_model.py.

Kui kõik läks hästi, näete kausta ./serving/versions/1. Pange tähele, et 1 tähistab mudeli praegust versiooni. Iga versiooni alamkataloogi sees näete järgmisi faile:

  • salvestatud_mudel.pb või salvestatud_mudel.pbtxt. See on serialiseeritud fail SavedModel. See sisaldab mudeli ühte või mitut graafimääratlust, samuti allkirjade määratlusi.
  • Muutujad. See kaust sisaldab graafikute seerialiseeritud muutujaid.

Nüüd oleme valmis oma mudeliserveri käivitama. Selleks käivitage:

$ tensorflow_model_server --port = 9000 --modell_name = deeplab --model_base_path = 

Model_base_path viitab sinna, kuhu eksporditud mudel salvestati. Samuti ei täpsusta me tee versiooni kausta. Mudeli versiooni juhtimist haldab TF Serving.

Klienditaotluste genereerimine

Kliendikood on väga lihtne. Vaadake seda aadressil deeplab_client.ipynb.

Esiteks loeme pildi, mille tahame serverisse saata, ja teisendame selle õigesse vormingusse.

Järgmisena loome gRPC tüve. Tüvi võimaldab meil helistada kaugserveri meetoditele. Selleks lähtestame mooduli ennustus_teenuse_pb2 klassi beeta_create_PredictionService_stub klassi. Sel hetkel hoiab tükk vajalikku loogikat kaugprotseduuride (serverist) helistamiseks, justkui need oleksid kohalikud.

Nüüd peame looma ja seadistama päringuobjekti. Kuna meie server juurutab TensorFlow Predict API-d, peame sõeluma ennustamistaotluse. Ennustamistaotluse väljastamiseks esmalt vahendame klassi PredictRequest mooduli ennustus_pb2. Samuti peame täpsustama parameetrid model_spec.name ja model_spec.signature_name. Nimiparameeter on argument 'mudel_nimi', mille määratlesime serveri käivitamisel. Ja signatuuri_nimi viitab loogilisele nimele, mis on määratud rutiini add_meta_graph () parameetrile Signal_def_map ().

Järgmisena peame sisestama sisendandmed, nagu on määratletud serveri allkirjas. Pidage meeles, et serveris määratlesime ennustatava API, mis eeldab nii pilti kui ka kaht skalaari (pildi kõrgus ja laius). Sisendandmete sisestamiseks päringuobjekti pakub TensorFlow utiliiti tf.make_tensor_proto (). See meetod loob TensorProto objekti numpy / Python objektist. Saame seda kasutada pildi ja selle mõõtmete lisamiseks päringuobjektile.

Paistab, et oleme valmis serverile helistama. Selleks kutsume meetodit Ennusta () (tüve kasutades) ja edastame argumendina päringuobjekti.

Ühtset vastust tagastavate päringute korral toetab gRPC nii sünkroonseid kui ka asünkroonseid kõnesid. Seega, kui soovite päringu menetlemise ajal mõnda tööd teha, võiksime ennustada () asemel helistada Predict.future ().

Nüüd saame tulemusi hankida ja neist rõõmu tunda.

Loodetavasti teile see artikkel meeldis. Täname, et lugesite!

Kui soovite rohkem, vaadake: