Kā izvietot TensorFlow modeļus ražošanā, izmantojot TF Serving

Ievads

Mašīnmācīšanās (ML) modeļu ieviešana ražošanā ir kļuvusi par populāru, atkārtotu tēmu. Daudzi uzņēmumi un struktūras piedāvā dažādus risinājumus, kuru mērķis ir risināt šo problēmu.

Lai novērstu šīs bažas, Google izlaida TensorFlow (TF) Serving, cerot atrisināt ML modeļu izvietošanas ražošanā problēmu.

Šis raksts piedāvā praktisku apmācību par iepriekš apmācīta konvolucionālās semantiskās segmentācijas tīkla apkalpošanu. Šī raksta beigās jūs varēsiet izmantot TF Serving, lai izvietotu un iesniegtu pieprasījumus Deep CNN, kas apmācīts TF. Es arī iepazīstināšu ar TF apkalpošanas galveno bloku pārskatu un apspriedīšu tā API un kā tas viss darbojas.

Viena lieta, ko pamanīsit uzreiz, ir tā, ka, lai faktiski kalpotu TF modelim, ir nepieciešams ļoti maz koda. Ja vēlaties iet kopā ar apmācību un palaist piemēru savā datorā, izpildiet to, kā tas ir. Bet, ja vēlaties uzzināt tikai par TensorFlow apkalpošanu, varat koncentrēties uz pirmajām divām sadaļām.

Šis raksts uzsver dažus darbus, ko mēs darām šeit, Daitan Group.

TensorFlow apkalpojošās bibliotēkas - pārskats

Pavadīsim kādu laiku, lai saprastu, kā TF Serving veic pilnu ML modeļu dzīves ciklu. Šeit mēs aplūkosim (augstā līmenī) katru no galvenajiem TF Serving veidojošajiem blokiem. Šīs sadaļas mērķis ir sniegt vienkāršu ievadu TF apkalpošanas API. Lai iegūtu padziļinātu pārskatu, lūdzu, dodieties uz TF apkalpošanas dokumentācijas lapu.

TensorFlow apkalpošana sastāv no dažām abstrakcijām. Šīs abstrakcijas ievieš API dažādiem uzdevumiem. Vissvarīgākie ir Servable, Loader, Source un Manager. Apskatīsim, kā viņi mijiedarbojas.

Īsāk sakot, kalpošanas dzīves cikls sākas, kad TF Serving identificē modeli diskā. Avota komponents par to rūpējas. Tā ir atbildīga par jaunu ielādējamo modeļu noteikšanu. Praksē tā seko līdzi failu sistēmai, lai identificētu, kad diskā nonāk jauna modeļa versija. Kad tā redz jaunu versiju, tā turpina, izveidojot iekrāvēju šai konkrētajai modeļa versijai.

Kopumā Loader zina gandrīz visu par modeli. Tas ietver to, kā to ielādēt un kā novērtēt modeļa nepieciešamos resursus, piemēram, pieprasīto RAM un GPU atmiņu. Krāvējam diskā ir norāde uz modeli, kā arī visi tā ielādēšanai nepieciešamie metadati. Bet šeit ir nozveja: iekrāvējam pagaidām nav atļauts ielādēt modeli.

Pēc Loader izveides avots to nosūta pārvaldniekam kā vēlamo versiju.

Saņemot modeļa Aspired versiju, vadītājs turpina apkalpošanas procesu. Šeit ir divas iespējas. Viens ir tas, ka pirmā modeļa versija tiek virzīta izvietošanai. Šajā situācijā vadītājs pārliecinās, vai ir pieejami nepieciešamie resursi. Kad tie ir, pārvaldnieks dod Loader atļauju ielādēt modeli.

Otrais ir tas, ka mēs virzām jaunu esošā modeļa versiju. Šajā gadījumā pārvaldniekam ir jākonsultējas ar versiju politikas spraudni, pirms iet tālāk. Versiju politika nosaka, kā notiek jaunas modeļa versijas ielādes process.

Konkrētāk, ielādējot jaunu modeļa versiju, mēs varam izvēlēties saglabāt (1) pieejamību vai (2) resursus. Pirmajā gadījumā mēs esam ieinteresēti pārliecināties, ka mūsu sistēma vienmēr ir pieejama ienākošo klientu pieprasījumiem. Mēs zinām, ka pārvaldnieks ļauj iekrāvējam precizēt jauno diagrammu ar jaunajiem svariem.

Šajā brīdī mums ir vienlaikus ielādētas divas modeļu versijas. Bet vadītājs vecāko versiju izkrauj tikai pēc tam, kad ir pabeigta ielāde, un ir droši pārslēgties starp modeļiem.

No otras puses, ja mēs vēlamies ietaupīt resursus, neizmantojot papildu buferi (jaunajai versijai), mēs varam izvēlēties saglabāt resursus. Ļoti smagiem modeļiem varētu būt noderīgi, ja būtu maz vietas pieejamībā, apmaiņā pret atmiņas taupīšanu.

Beigās, kad klients pieprasa modeļa rokturi, pārvaldnieks atgriež rokturi Servable.

Izmantojot šo pārskatu, mēs esam gatavi ienirt reālajā lietojumprogrammā. Nākamajās sadaļās mēs aprakstām, kā apkalpot konvolucionālo neironu tīklu (CNN), izmantojot TF apkalpošanu.

Ekspluatācijas modeļa eksportēšana

Pirmais solis, lai apkalpotu TensorFlow iebūvēto ML modeli, ir pārliecināties, ka tas ir pareizajā formātā. Lai to izdarītu, TensorFlow nodrošina klasi SavedModel.

SavedModel ir universāls sērijas formāts TensorFlow modeļiem. Ja esat pazīstams ar TF, jūs, iespējams, izmantojāt TensorFlow Saver, lai saglabātu modeļa mainīgos.

TensorFlow Saver nodrošina funkcijas modeļa kontrolpunktu failu saglabāšanai / atjaunošanai uz / no diska. Faktiski, SavedModel iesaiņo TensorFlow Saver, un tas ir paredzēts kā standarta veids, kā eksportēt TF modeļus apkalpošanai.

SavedModel objektam ir dažas jaukas funkcijas.

Pirmkārt, tas ļauj jums saglabāt vairāk nekā vienu meta-grafiku vienā SavedModel objektā. Citiem vārdiem sakot, tas ļauj mums izveidot dažādus grafikus dažādiem uzdevumiem.

Piemēram, pieņemsim, ka esat tikko pabeidzis sava modeļa apmācību. Vairumā gadījumu, lai veiktu secinājumu, jūsu diagrammā nav nepieciešamas dažas apmācībai specifiskas darbības. Šīs opcijas var ietvert optimizētāja mainīgos, mācību ātruma plānošanas tenorus, papildu pirmapstrādes opcijas utt.

Turklāt mobilajām ierīcēm jūs varētu vēlēties rādīt kvantētu diagrammas versiju.

Šajā kontekstā programma SavedModel ļauj saglabāt diagrammas ar dažādām konfigurācijām. Mūsu piemērā mums būtu trīs dažādi grafiki ar atbilstošiem tagiem, piemēram, “apmācība”, “secinājums” un “mobilais”. Arī visiem šiem trim grafikiem būtu kopīgs mainīgo lielumu kopums, kas uzsver atmiņas efektivitāti.

Ne tik sen, kad mēs vēlējāmies izvietot TF modeļus mobilajās ierīcēs, mums bija jāzina ievades un izvades tenzoru nosaukumi, lai barotu un iegūtu datus no / uz modeli. Šī vajadzība lika programmētājiem meklēt vajadzīgo tenoru starp visiem diagrammas tenoriem. Ja tenori nebūtu pareizi nosaukti, uzdevums varētu būt ļoti garlaicīgs.

Lai atvieglotu lietas, SavedModel piedāvā atbalstu SignatureDefs. Kopumā SignatureDefs definē TensorFlow atbalstītā aprēķina parakstu. Tas nosaka pareizu ievades un izvades tenzoru skaitļošanas grafikam. Vienkārši sakot, ar šiem parakstiem jūs varat precīzi norādīt mezglus, kurus izmantot ievadei un izvadei.

Lai izmantotu iebūvētās apkalpošanas API, TF Serving modeļos ir jāiekļauj viens vai vairāki SignatureDefs.

Lai izveidotu šādus parakstus, mums jānodrošina ievades, izvades un vēlamās metodes nosaukuma definīcijas. Ieejas un izejas veido kartēšanu no virknes TensorInfo objektus (vairāk par šo pēdējo). Šeit mēs definējam noklusējuma tenzorus datu barošanai un saņemšanai no grafika un no tā. METHOD_NAME parametrs ir vērsta viens no TF augsta līmeņa apkalpo API.

Pašlaik ir trīs apkalpojošās API: klasifikācija, prognozēšana un regresija. Katra paraksta definīcija atbilst noteiktai RPC API. Classification SegnatureDef tiek izmantots klasificēšanas RPC API. Predict SegnatureDef tiek izmantots prognožu RPC API un tālāk.

Klasifikācijas parakstam jābūt ievades tenoram (lai saņemtu datus) un vismaz vienam no diviem iespējamiem izvades tenzoriem: klasēm un / vai rādītājiem. Regresijas SignatureDef ievadei ir vajadzīgs tieši viens tenzors, bet izejai - cits. Visbeidzot, Parakstīt paraksts ļauj dinamiski ievadīt un izvest tenzorus.

Turklāt SavedModel atbalsta aktīvu glabāšanu gadījumos, kad opu inicializēšana ir atkarīga no ārējiem failiem. Turklāt tam ir mehānismi ierīču notīrīšanai pirms SavedModel izveides.

Tagad redzēsim, kā mēs to varam izdarīt praksē.

Vides uzstādīšana

Pirms sākam, klonējiet šo TensorFlow DeepLab-v3 ieviešanu no Github.

DeepLab ir Google labākā semantiskā segmentācija ConvNet. Būtībā tīkls uzņem attēlu kā ievadi un izvada maskai līdzīgu attēlu, kas atsevišķus objektus atdala no fona.

Šī versija tika apmācīta Pascal VOC segmentācijas datu kopā. Tādējādi tas var segmentēt un atpazīt līdz 20 klasēm. Ja vēlaties uzzināt vairāk par semantisko segmentēšanu un DeepLab-v3, ieskatieties sadaļā Diving into Deep Convolutional Semantic Segmentation Networks un Deeplab_V3.

Visi faili, kas saistīti ar apkalpošanu, atrodas: ./deeplab_v3/serving/. Tur jūs atradīsit divus svarīgus failus: deeplab_saved_model.py un deeplab_client.ipynb

Pirms doties tālāk, noteikti lejupielādējiet iepriekš apmācītu Deeplab-v3 modeli. Dodieties uz iepriekšminēto GitHub repozitoriju, noklikšķiniet uz saites kontrolpunkti un lejupielādējiet mapi ar nosaukumu 16645 / .

Galu galā, jums ir jābūt mapi ar nosaukumu tboard_logs / ar 16645 / mapi ievietots tajā iekšā.

Tagad mums ir jāizveido divas virtuālās Python vides. Viens - Python 3 un otrs - Python 2. Katram env noteikti instalējiet nepieciešamās atkarības. Tos var atrast failos serving_requirements.txt un client_requirements.txt.

Mums ir nepieciešami divi Python envs, jo mūsu modelis DeepLab-v3 tika izstrādāts zem Python 3. Tomēr TensorFlow Serving Python API ir publicēts tikai Python 2. Tāpēc, lai eksportētu modeli un palaistu TF apkalpošanu, mēs izmantojam Python 3 env . Lai palaistu klienta kodu, izmantojot TF Serving python API, mēs izmantojam PIP pakotni (pieejama tikai Python 2).

Ņemiet vērā, ka varat atteikties no Python 2 env, izmantojot bazel servēšanas API. Plašāku informāciju skatiet TF apkalpošanas instalācijā.

Kad šis solis ir pabeigts, sāksim ar to, kas patiešām ir svarīgs.

Kā to izdarīt

Lai izmantotu SavedModel, TensorFlow nodrošina viegli lietojamu augsta līmeņa utilītu klasi, ko sauc par SavedModelBuilder. SavedModelBuilder klase nodrošina funkcijas, lai saglabātu vairākus meta grafikus, saistītos mainīgos un aktīvus.

Apskatīsim piemēru, kā eksportēt Deep Segmentation CNN modeli rādīšanai.

Kā minēts iepriekš, modeļa eksportēšanai mēs izmantojam klasi SavedModelBuilder. Tas ģenerēs SavedModel protokola bufera failu kopā ar modeļa mainīgajiem un aktīviem (ja nepieciešams).

Izdalīsim kodu.

SavedModelBuilder saņem (kā ievadi) direktoriju, kur saglabāt modeļa datus. Šeit mainīgais export_path ir export_path_base un model_version savienojums . Rezultātā dažādas modeļa versijas tiks saglabātas atsevišķos direktorijos mapē export_path_base .

Pieņemsim, ka mūsu ražošanā ir mūsu modeļa bāzes versija, taču mēs vēlamies izvietot jaunu tās versiju. Mēs esam uzlabojuši modeļa precizitāti un vēlamies piedāvāt šo jauno versiju saviem klientiem.

Lai eksportētu citu tā paša diagrammas versiju, mēs varam vienkārši iestatīt FLAGS.model_version uz lielāku vesela skaitļa vērtību. Tad mapē export_path_base tiks izveidota cita mape (turot mūsu modeļa jauno versiju) .

Tagad mums jānorāda mūsu modeļa ievades un izvades tenzori. Lai to izdarītu, mēs izmantojam SignatureDefs. Paraksti nosaka, kāda veida modeli mēs vēlamies eksportēt. Tas nodrošina kartēšanu no virknēm (loģiskiem tenzora nosaukumiem) līdz TensorInfo objektiem. Ideja ir tāda, ka klienti var atsaukties uz parakstu definētajiem loģiskajiem nosaukumiem, nevis atsaukties uz faktiskajiem tenzoru nosaukumiem ievadei / izejai.

Lai apkalpotu semantisko segmentu CNN, mēs izveidosim Paredzēt parakstu . Ņemiet vērā, ka funkcija build_signature_def () veic ieejas un izejas tenzoru kartēšanu, kā arī vēlamo API.

SignatureDef nepieciešams norādīt: ievades, izvades un metodes nosaukumu. Ņemiet vērā, ka mēs sagaidām trīs ievades vērtības - attēlu un vēl divus tenorus, kas norāda tā izmērus (augstumu un platumu). Par rezultātiem , mēs definēts tikai viens iznākums - to segmentācija izejas masku.

Ņemiet vērā, ka virknes “attēls”, “augstums”, “platums” un “segmentācijas_karte” nav tensori. Tā vietā tie ir loģiski nosaukumi, kas attiecas uz faktiskajiem tenzoriem input_tensor , image_height_tensor un image_width_tensor . Tādējādi tie var būt jebkura unikāla virkne, kas jums patīk.

Arī kartējumi SignatureDefs attiecas uz TensorInfo protobuf objektiem, nevis uz faktiskajiem tenzoriem. Lai izveidotu TensorInfo objektus, mēs izmantojam utilītas funkciju: tf.saved_model.utils.build_tensor_info (tensor) .

Tas ir viss. Tagad mēs izsaucam funkciju add_meta_graph_and_variables (), lai izveidotu protokola bufera objektu SavedModel. Pēc tam mēs palaižam metodi save (), un tā saglabās mūsu modeļa momentuzņēmumu diskā, kurā būs modeļa mainīgie un aktīvi.

Tagad mēs varam palaist deeplab_saved_model.py, lai eksportētu savu modeli.

Ja viss noritēja labi, jūs redzēsiet mapi ./serving/versions/1 . Ņemiet vērā, ka “1” apzīmē modeļa pašreizējo versiju. Katras versijas apakšdirektorijā jūs redzēsiet šādus failus:

  • saved_model.pb vai saved_model.pbtxt. Šis ir sērijveida fails SavedModel. Tas ietver vienu vai vairākas modeļa diagrammas definīcijas, kā arī parakstu definīcijas.
  • Mainīgie. Šajā mapē ir grafiku sērijveida mainīgie.

Tagad mēs esam gatavi palaist mūsu modeļa serveri. Lai to izdarītu, palaidiet:

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

Model_base_path attiecas uz vietu, kur eksportēti modelis tika saglabāts. Tāpat mēs ceļā nenorādām versiju mapi. Modeļa versiju vadību pārvalda TF Serving.

Klientu pieprasījumu ģenerēšana

Klienta kods ir ļoti vienkāršs. Apskatiet to vietnē: deeplab_client.ipynb.

Pirmkārt, mēs izlasījām attēlu, kuru vēlamies nosūtīt uz serveri, un pārvēršam to pareizajā formātā.

Tālāk mēs izveidojam gRPC spraudni. Šoks ļauj mums izsaukt attālā servera metodes. Lai to izdarītu, mēs instanticējam moduļa prediction_service_pb2 beta_create_PredictionService_stub klasi . Šajā brīdī stumbrs satur nepieciešamo loģiku, lai izsauktu attālās procedūras (no servera), it kā tās būtu lokālas.

Tagad mums ir jāizveido un jāiestata pieprasījuma objekts. Tā kā mūsu serveris ievieš TensorFlow Predict API, mums ir parsēt Predict pieprasījumu. Lai izsniegtu pieprasījumu Prognozēt, vispirms mēs modulī PrognozētRequest izdomājam klasi PredictRequest . Mums arī jānorāda modeļa_spec.nosaukums un modeļa_spec.paraksts_nosaukums parametri. Nosaukums param ir "MODEL_NAME" arguments, ka mēs definēts, kad mēs uzsākām serveri. Un signature_name attiecas uz loģisku nosaukumu piešķirts uz signature_def_map () parametrs add_meta_graph () rutīnas.

Tālāk mums jāievada ievaddati, kā noteikts servera parakstā. Atcerieties, ka serverī mēs definējām Predict API, lai sagaidītu attēlu, kā arī divus skalārus (attēla augstumu un platumu). Lai ievadītu ievades datus pieprasījuma objektā, TensorFlow nodrošina utilītu tf.make_tensor_proto () . Šī metode izveido objektu TensorProto no numpy / Python objekta. Mēs to varam izmantot, lai attēlu un tā izmērus ievadītu pieprasījuma objektā.

Izskatās, ka esam gatavi izsaukt serveri. Lai to izdarītu, mēs izsaucam metodi Predict () (izmantojot stub) un nododam pieprasījuma objektu kā argumentu.

Pieprasījumiem, kas atbild uz vienu atbildi, gRPC atbalsta gan sinhronos, gan asinhronos zvanus. Tādējādi, ja vēlaties veikt kādu darbu pieprasījuma apstrādes laikā, Predict () vietā mēs varētu izsaukt Predict.future () .

Tagad mēs varam atnest un izbaudīt rezultātus.

Ceru, ka jums patika šis raksts. Paldies, ka lasījāt!

Ja vēlaties vairāk, pārbaudiet:

Kā apmācīt savu FaceID ConvNet, izmantojot TensorFlow Eager izpildi

Faces ir visur - sākot no fotogrāfijas un video par sociālo mediju mājas lapām, lai patērētāju drošības lietojumiem, piemēram, ... medium.freecodecamp.org Iegremdēšanās dziļa convolutional Semantiskā segmentācija tīkli un Deeplab_V3

Dziļi konvolucionālie neironu tīkli (DCNN) ir guvuši ievērojamus panākumus dažādās Computer Vision lietojumprogrammās ... medium.freecodecamp.org