Industriell maskinlæring: 10 designprinsipper

Industriell maskinlæring: 10 designprinsipper

Nå for tiden skapes det hver dag nye tjenester, applikasjoner og andre viktige programmer som gjør det mulig å lage utrolige ting: fra programvare for å kontrollere en SpaceX-rakett til å samhandle med en vannkoker i neste rom via en smarttelefon.

Og noen ganger innser enhver nybegynner programmerer, enten han er en lidenskapelig startuper eller en vanlig Full Stack eller Data Scientist, før eller siden at det er visse regler for programmering og å lage programvare som i stor grad forenkler livet.

I denne artikkelen vil jeg kort beskrive 10 prinsipper for hvordan man programmerer industriell maskinlæring slik at den enkelt kan integreres i en applikasjon/tjeneste, basert på 12-faktor App-metodikken. foreslått av Heroku-teamet. Mitt initiativ er å øke bevisstheten om denne teknikken, som kan hjelpe mange utviklere og datavitenskapsfolk.

Denne artikkelen er en prolog til en serie artikler om industriell maskinlæring. I dem vil jeg videre snakke om hvordan man faktisk kan lage en modell og lansere den i produksjon, lage en API for den, samt eksempler fra ulike områder og selskaper som har innebygget ML i systemene sine.

Prinsipp 1: En kodebase

Noen programmerere i de første stadiene, av latskap til å finne ut av det (eller av en eller annen grunn av sine egne), glemmer Git. Enten glemmer de ordet helt, det vil si at de kaster filer til hverandre i stasjonen/sender bare tekst/sender med duer, eller så tenker de ikke gjennom arbeidsflyten sin, og forplikter seg til hver sin gren, og deretter til herre.

Dette prinsippet sier: har én kodebase og mange distribusjoner.

Git kan brukes både i produksjon og i forskning og utvikling (FoU), hvor det ikke brukes så ofte.

For eksempel, i FoU-fasen kan du forlate commits med forskjellige databehandlingsmetoder og modeller, for deretter å velge den beste og enkelt fortsette å jobbe med den videre.

For det andre, i produksjon er dette en uerstattelig ting - du må hele tiden se på hvordan koden endres og vite hvilken modell som ga de beste resultatene, hvilken kode som fungerte til slutt og hva som skjedde som fikk den til å slutte å virke eller begynne å produsere feil resultater . Det er det forpliktelser er til for!

Du kan også lage en pakke av prosjektet ditt, plassere det for eksempel på Gemfury, og så ganske enkelt importere funksjoner fra det for andre prosjekter, for ikke å omskrive dem 1000 ganger, men mer om det senere.

Prinsipp 2: Klargjør og isoler avhengigheter

Hvert prosjekt har forskjellige biblioteker som du importerer utenfra for å bruke dem et sted. Enten det er Python-biblioteker, eller biblioteker på andre språk for ulike formål, eller systemverktøy - oppgaven din er:

  • Deklarer tydelig avhengigheter, det vil si en fil som vil inneholde alle bibliotekene, verktøyene og deres versjoner som brukes i prosjektet ditt og som må installeres (for eksempel i Python kan dette gjøres ved å bruke Pipfile eller requirements.txt. A lenke som gjør det mulig å forstå: realpython.com/pipenv-guide)
  • Isoler avhengigheter spesifikt for programmet ditt under utvikling. Du vil ikke hele tiden endre versjoner og installere for eksempel Tensorflow på nytt?

På denne måten vil utviklere som vil slutte seg til teamet ditt i fremtiden raskt kunne bli kjent med bibliotekene og deres versjoner som brukes i prosjektet ditt, og du vil også ha muligheten til å administrere versjonene og bibliotekene selv installert for en spesifikk prosjekt, som vil hjelpe deg å unngå inkompatibilitet mellom biblioteker eller deres versjoner.

Applikasjonen din bør heller ikke stole på systemverktøy som kan være installert på et spesifikt operativsystem. Disse verktøyene må også deklareres i avhengighetsmanifestet. Dette er nødvendig for å unngå situasjoner der versjonen av verktøyene (så vel som deres tilgjengelighet) ikke samsvarer med systemverktøyene til et bestemt operativsystem.

Dermed, selv om curl kan brukes på nesten alle datamaskiner, bør du fortsatt erklære den i avhengigheter, siden når du migrerer til en annen plattform, kan den ikke være der, eller versjonen vil ikke være den du opprinnelig trengte.

For eksempel kan requirements.txt se slik ut:

# Model Building Requirements
numpy>=1.18.1,<1.19.0
pandas>=0.25.3,<0.26.0
scikit-learn>=0.22.1,<0.23.0
joblib>=0.14.1,<0.15.0

# testing requirements
pytest>=5.3.2,<6.0.0

# packaging
setuptools>=41.4.0,<42.0.0
wheel>=0.33.6,<0.34.0

# fetching datasets
kaggle>=1.5.6,<1.6.0

Prinsipp 3: Konfigurasjoner

Mange har hørt historier om forskjellige utviklere som ved et uhell laster opp kode til GitHub til offentlige depoter med passord og andre nøkler fra AWS, og våkner neste dag med en gjeld på $6000 50000, eller til og med $XNUMX XNUMX.

Industriell maskinlæring: 10 designprinsipper

Selvfølgelig er disse tilfellene ekstreme, men svært betydningsfulle. Hvis du lagrer legitimasjonen din eller andre data som trengs for konfigurasjon inne i koden, gjør du en feil, og jeg tror det ikke er nødvendig å forklare hvorfor.

Et alternativ til dette er å lagre konfigurasjoner i miljøvariabler. Du kan lese mer om miljøvariabler her.

Eksempler på data som vanligvis lagres i miljøvariabler:

  • Domenenavn
  • API URL-er/URI-er
  • Offentlige og private nøkler
  • Kontakter (e-post, telefoner osv.)

På denne måten trenger du ikke hele tiden å endre koden hvis konfigurasjonsvariablene dine endres. Dette vil hjelpe deg med å spare tid, krefter og penger.

Hvis du for eksempel bruker Kaggle API til å utføre tester (for eksempel laste ned programvaren og kjøre modellen gjennom den for å teste når du kjører at modellen fungerer bra), bør private nøkler fra Kaggle, som KAGGLE_USERNAME og KAGGLE_KEY, være lagret i miljøvariabler.

Prinsipp 4: Tredjepartstjenester

Tanken her er å lage programmet på en slik måte at det ikke er noen forskjell mellom lokale og tredjeparts ressurser når det gjelder kode. For eksempel kan du koble til både lokale MySQL og tredjeparts. Det samme gjelder ulike APIer som Google Maps eller Twitter API.

For å deaktivere en tredjepartstjeneste eller koble til en annen, trenger du bare å endre nøklene i konfigurasjonen i miljøvariablene, som jeg snakket om i avsnittet ovenfor.

Så, for eksempel, i stedet for å spesifisere banen til filer med datasett inne i koden hver gang, er det bedre å bruke pathlib-biblioteket og deklarere banen til datasettene i config.py, slik at uansett hvilken tjeneste du bruker (f. for eksempel CircleCI), var programmet i stand til å finne ut stien til datasettene under hensyntagen til strukturen til det nye filsystemet i den nye tjenesten.

Prinsipp 5. Bygg, slipp, kjøretid

Mange personer i Data Science synes det er nyttig å forbedre sine ferdigheter i programvareskriving. Hvis vi vil at programmet vårt skal krasje så sjelden som mulig og fungere uten feil så lenge som mulig, må vi dele prosessen med å gi ut en ny versjon i 3 trinn:

  1. Scene forsamlinger. Du transformerer din bare kode med individuelle ressurser til en såkalt pakke som inneholder all nødvendig kode og data. Denne pakken kalles en sammenstilling.
  2. Scene utgivelse — her kobler vi konfigurasjonen vår til sammenstillingen, uten den ville vi ikke kunne frigi programmet vårt. Nå er dette en helt klar til lansering.
  3. Neste kommer scenen oppfyllelse. Her slipper vi applikasjonen ved å kjøre de nødvendige prosessene fra vår utgivelse.

Et slikt system for utgivelse av nye versjoner av en modell eller hele pipelinen lar deg skille roller mellom administratorer og utviklere, lar deg spore versjoner og forhindrer uønskede stopp av programmet.

For utgivelsesoppgaven er det laget mange forskjellige tjenester der du kan skrive prosesser for å kjøre deg selv i en .yml-fil (for eksempel i CircleCI er dette config.yml for å støtte selve prosessen). Wheely er flink til å lage pakker for prosjekter.

Du kan lage pakker med forskjellige versjoner av maskinlæringsmodellen din, og deretter pakke dem og referere til de nødvendige pakkene og deres versjoner for å bruke funksjonene du skrev derfra. Dette vil hjelpe deg med å lage et API for modellen din, og pakken din kan for eksempel hostes på Gemfury.

Prinsipp 6. Kjør modellen som én eller flere prosesser

Dessuten skal ikke prosesser ha delt data. Det vil si at prosesser må eksistere separat, og alle typer data må eksistere separat, for eksempel på tredjepartstjenester som MySQL eller andre, avhengig av hva du trenger.

Det vil si at det definitivt ikke er verdt å lagre data inne i prosessfilsystemet, ellers kan dette føre til sletting av disse dataene under neste utgivelse/endring av konfigurasjoner eller overføring av systemet som programmet kjører på.

Men det er et unntak: for maskinlæringsprosjekter kan du lagre en buffer med biblioteker for ikke å installere dem på nytt hver gang du starter en ny versjon, hvis ingen ekstra biblioteker eller endringer er gjort i versjonene deres. På denne måten vil du redusere tiden det tar å lansere modellen din i industrien.

For å kjøre modellen som flere prosesser kan du lage en .yml-fil der du spesifiserer de nødvendige prosessene og deres rekkefølge.

Prinsipp 7: Resirkulerbarhet

Prosessene som kjører i modellapplikasjonen din skal være enkle å starte og stoppe. Dermed vil dette tillate deg å raskt distribuere kodeendringer, konfigurasjonsendringer, raskt og fleksibelt skalere, og forhindre mulige sammenbrudd av fungerende versjon.

Det vil si at prosessen din med modellen bør:

  • Minimer oppstartstiden. Ideelt sett bør oppstartstiden (fra det øyeblikket oppstartskommandoen ble gitt til det øyeblikket prosessen starter) ikke være mer enn noen få sekunder. Bibliotekbufring, beskrevet ovenfor, er en teknikk for å redusere oppstartstiden.
  • Avslutt riktig. Det vil si at lytting på tjenesteporten faktisk er suspendert, og nye forespørsler sendt til denne porten vil ikke bli behandlet. Her må du enten sette opp god kommunikasjon med DevOps-ingeniører, eller forstå hvordan det fungerer selv (helst, selvfølgelig, sistnevnte, men kommunikasjon bør alltid opprettholdes, i ethvert prosjekt!)

Prinsipp 8: Kontinuerlig distribusjon/integrasjon

Mange selskaper bruker et skille mellom applikasjonsutviklings- og distribusjonsteamene (gjør applikasjonen tilgjengelig for sluttbrukere). Dette kan i stor grad bremse programvareutvikling og fremgang i forbedringen. Det ødelegger også DevOps-kulturen, der utvikling og integrasjon grovt sett er kombinert.

Derfor sier dette prinsippet at utviklingsmiljøet ditt skal være så nært produksjonsmiljøet som mulig.

Dette vil tillate:

  1. Reduser utgivelsestiden med titalls ganger
  2. Reduser antall feil på grunn av kodeinkompatibilitet.
  3. Dette reduserer også arbeidsbelastningen på ansatte, siden utviklere og personer som distribuerer applikasjonen nå er ett team.

Verktøy som lar deg jobbe med dette er CircleCI, Travis CI, GitLab CI og andre.

Du kan raskt gjøre tillegg til modellen, oppdatere den og starte den umiddelbart, samtidig som det vil være enkelt, ved feil, å gå veldig raskt tilbake til den fungerende versjonen, slik at sluttbrukeren ikke en gang legger merke til det. Dette kan gjøres spesielt enkelt og raskt hvis du har gode tester.

Minimer forskjeller!!!

Prinsipp 9. Loggene dine

Logger (eller "Logger") er hendelser, vanligvis registrert i tekstformat, som skjer i applikasjonen (hendelsesstrøm). Et enkelt eksempel: "2020-02-02 - systemnivå - prosessnavn." De er designet slik at utvikleren bokstavelig talt kan se hva som skjer når programmet kjører. Han ser fremdriften i prosesser og forstår om det er slik utvikleren selv har tenkt.

Dette prinsippet sier at du ikke skal lagre loggene dine i filsystemet ditt - du bør bare "outputte" dem til skjermen, for eksempel gjør dette på systemets standardutgang. Og på denne måten vil det være mulig å overvåke flyten i terminalen under utbygging.

Betyr dette at det ikke er behov for å lagre logger i det hele tatt? Selvfølgelig ikke. Applikasjonen din skal bare ikke gjøre dette - overlat det til tredjepartstjenester. Applikasjonen din kan bare videresende logger til en bestemt fil eller terminal for sanntidsvisning, eller videresende den til et generell datalagringssystem (som Hadoop). Selve applikasjonen din skal ikke lagre eller samhandle med logger.

Prinsipp 10. Test!

For industriell maskinlæring er denne fasen ekstremt viktig, siden du må forstå at modellen fungerer riktig og produserer det du ønsket.

Tester kan lages ved hjelp av pytest, og testes med et lite datasett hvis du har en regresjons-/klassifiseringsoppgave.

Ikke glem å sette det samme kimen til dyplæringsmodeller slik at de ikke hele tiden gir forskjellige resultater.

Dette var en kort beskrivelse av de 10 prinsippene, og det er selvfølgelig vanskelig å bruke dem uten å prøve og se hvordan de fungerer, så denne artikkelen er bare en prolog til en serie interessante artikler der jeg vil avsløre hvordan man lager industrielle maskinlæringsmodeller, hvordan de integreres i systemer, og hvordan disse prinsippene kan gjøre livet enklere for oss alle.

Jeg vil også prøve å bruke kule prinsipper som hvem som helst kan legge igjen i kommentarfeltet hvis de ønsker det.

Kilde: www.habr.com

Legg til en kommentar