Industriel maskinlæring: 10 designprincipper

Industriel maskinlæring: 10 designprincipper

I dag skabes der hver dag nye tjenester, applikationer og andre vigtige programmer, der gør det muligt at skabe utrolige ting: Fra software til at styre en SpaceX-raket til at interagere med en kedel i det næste rum via en smartphone.

Og nogle gange kommer enhver nybegynder programmør, uanset om han er en passioneret startuper eller en almindelig Full Stack eller Data Scientist, før eller siden til den erkendelse, at der er visse regler for programmering og skabelse af software, der i høj grad forenkler livet.

I denne artikel vil jeg kort beskrive 10 principper for, hvordan man programmerer industriel maskinlæring, så det nemt kan integreres i en applikation/tjeneste, baseret på 12-faktor App-metoden. foreslået af Heroku-teamet. Mit initiativ er at øge bevidstheden om denne teknik, som kan hjælpe mange udviklere og datavidenskabsfolk.

Denne artikel er en prolog til en serie artikler om industriel Machine Learning. I dem vil jeg videre fortælle om, hvordan man rent faktisk laver en model og sætter den i produktion, laver en API til den, samt eksempler fra forskellige områder og virksomheder, der har indbygget ML i deres systemer.

Princip 1: Én kodebase

Nogle programmører i de første trin, af dovenskab til at finde ud af det (eller af en eller anden grund af deres egen), glemmer Git. De glemmer enten helt ordet, det vil sige, at de smider filer til hinanden i drevet/smidter bare tekst/sender med duer, eller også tænker de ikke igennem deres arbejdsgang, og forpligter sig hver til deres egen gren, og derefter til mestre.

Dette princip siger: har én kodebase og mange implementeringer.

Git kan bruges både i produktion og i forskning og udvikling (R&D), hvor det ikke bruges så ofte.

For eksempel kan du i R&D-fasen forlade commits med forskellige databehandlingsmetoder og -modeller, for derefter at vælge den bedste og nemt fortsætte med at arbejde videre med den.

For det andet, i produktionen er dette en uerstattelig ting - du bliver nødt til konstant at se på, hvordan din kode ændrer sig og vide, hvilken model der gav de bedste resultater, hvilken kode der virkede i sidste ende, og hvad der skete, der fik den til at holde op med at virke eller begynde at producere forkerte resultater . Det er det, commits er til for!

Du kan også oprette en pakke af dit projekt, placere den for eksempel på Gemfury, og så blot importere funktioner fra den til andre projekter, for ikke at omskrive dem 1000 gange, men mere om det senere.

Princip 2: Klart erklære og isolere afhængigheder

Hvert projekt har forskellige biblioteker, som du importerer udefra for at anvende dem et eller andet sted. Uanset om det er Python-biblioteker eller biblioteker på andre sprog til forskellige formål eller systemværktøjer - din opgave er:

  • Deklarer tydeligt afhængigheder, det vil sige en fil, der vil indeholde alle de biblioteker, værktøjer og deres versioner, der bruges i dit projekt, og som skal installeres (f.eks. i Python kan dette gøres ved hjælp af Pipfile eller requirements.txt. A link, der gør det muligt at forstå: realpython.com/pipenv-guide)
  • Isoler afhængigheder specifikt for dit program under udvikling. Du vil ikke konstant ændre versioner og geninstallere for eksempel Tensorflow?

På denne måde vil udviklere, der vil slutte sig til dit team i fremtiden, hurtigt kunne stifte bekendtskab med de biblioteker og deres versioner, der bruges i dit projekt, og du vil også have mulighed for at administrere de versioner og biblioteker, der er installeret for en bestemt projekt, som vil hjælpe dig med at undgå inkompatibilitet mellem biblioteker eller deres versioner.

Din applikation bør heller ikke stole på systemværktøjer, der kan være installeret på et specifikt OS. Disse værktøjer skal også angives i afhængighedsmanifestet. Dette er nødvendigt for at undgå situationer, hvor versionen af ​​værktøjerne (såvel som deres tilgængelighed) ikke matcher systemværktøjerne i et bestemt OS.

Så selvom curl kan bruges på næsten alle computere, bør du stadig erklære det i afhængigheder, da når du migrerer til en anden platform, er det muligvis ikke der, eller versionen vil ikke være den, du oprindeligt havde brug for.

For eksempel kan din requirements.txt se sådan ud:

# 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

Princip 3: Konfigurationer

Mange har hørt historier om forskellige udviklerfyre, der ved et uheld uploader kode til GitHub til offentlige arkiver med adgangskoder og andre nøgler fra AWS, og vågner op næste dag med en gæld på $6000 eller endda $50000.

Industriel maskinlæring: 10 designprincipper

Selvfølgelig er disse tilfælde ekstreme, men meget vigtige. Hvis du gemmer dine legitimationsoplysninger eller andre data, der er nødvendige for konfiguration inde i koden, laver du en fejl, og jeg tror, ​​der ikke er behov for at forklare hvorfor.

Et alternativ til dette er at gemme konfigurationer i miljøvariabler. Du kan læse mere om miljøvariabler her.

Eksempler på data, der typisk er lagret i miljøvariabler:

  • Domænenavne
  • API URL'er/URI'er
  • Offentlige og private nøgler
  • Kontaktpersoner (mail, telefoner osv.)

På denne måde behøver du ikke konstant at ændre koden, hvis dine konfigurationsvariabler ændrer sig. Dette vil hjælpe med at spare dig tid, kræfter og penge.

For eksempel, hvis du bruger Kaggle API til at udføre tests (for eksempel download softwaren og kør modellen igennem den for at teste, når du kører, at modellen fungerer godt), så skal private nøgler fra Kaggle, såsom KAGGLE_USERNAME og KAGGLE_KEY, være gemt i miljøvariabler.

Princip 4: Tredjepartstjenester

Ideen her er at skabe programmet på en sådan måde, at der ikke er nogen forskel mellem lokale og tredjepartsressourcer med hensyn til kode. For eksempel kan du forbinde både lokale MySQL og tredjeparts. Det samme gælder for forskellige API'er såsom Google Maps eller Twitter API.

For at deaktivere en tredjepartstjeneste eller forbinde en anden, skal du bare ændre nøglerne i konfigurationen i miljøvariablerne, som jeg talte om i afsnittet ovenfor.

Så for eksempel, i stedet for at angive stien til filer med datasæt inde i koden hver gang, er det bedre at bruge pathlib-biblioteket og erklære stien til datasættene i config.py, så uanset hvilken service du bruger (f. for eksempel CircleCI), var programmet i stand til at finde ud af stien til datasættene under hensyntagen til strukturen af ​​det nye filsystem i den nye tjeneste.

Princip 5. Byg, frigive, køretid

Mange mennesker i Data Science finder det nyttigt at forbedre deres softwareskrivningsfærdigheder. Hvis vi vil have vores program til at gå ned så sjældent som muligt og arbejde uden fejl så længe som muligt, er vi nødt til at opdele processen med at frigive en ny version i 3 trin:

  1. etape forsamlinger. Du transformerer din bare code med individuelle ressourcer til en såkaldt pakke, der indeholder al den nødvendige kode og data. Denne pakke kaldes en samling.
  2. etape frigivelse — her forbinder vi vores config til assembly, uden hvilken vi ikke ville være i stand til at frigive vores program. Nu er dette en fuldstændig klar til lancering.
  3. Dernæst kommer scenen opfyldelse. Her frigiver vi applikationen ved at køre de nødvendige processer fra vores udgivelse.

Et sådant system til at frigive nye versioner af en model eller hele pipelinen giver dig mulighed for at adskille roller mellem administratorer og udviklere, giver dig mulighed for at spore versioner og forhindrer uønskede stop af programmet.

Til udgivelsesopgaven er der lavet mange forskellige tjenester, hvor du kan skrive processer til at køre dig selv i en .yml-fil (f.eks. i CircleCI er dette config.yml for at understøtte selve processen). Wheely er fantastisk til at skabe pakker til projekter.

Du kan oprette pakker med forskellige versioner af din maskinlæringsmodel og derefter pakke dem og henvise til de nødvendige pakker og deres versioner for at bruge de funktioner, du skrev derfra. Dette vil hjælpe dig med at oprette en API til din model, og din pakke kan f.eks. hostes på Gemfury.

Princip 6. Kør din model som en eller flere processer

Desuden bør processer ikke have delte data. Det vil sige, at processer skal eksistere separat, og alle former for data skal eksistere separat, for eksempel på tredjepartstjenester som MySQL eller andre, alt efter hvad du har brug for.

Det vil sige, det er bestemt ikke værd at gemme data inde i procesfilsystemet, ellers kan dette føre til sletning af disse data under næste udgivelse/ændring af konfigurationer eller overførsel af systemet, som programmet kører på.

Men der er en undtagelse: For maskinlæringsprojekter kan du gemme en cache af biblioteker for ikke at geninstallere dem, hver gang du starter en ny version, hvis der ikke er foretaget yderligere biblioteker eller ændringer i deres versioner. På denne måde vil du reducere den tid, det tager at lancere din model i industrien.

For at køre modellen som flere processer kan du oprette en .yml-fil, hvor du angiver de nødvendige processer og deres rækkefølge.

Princip 7: Genanvendelighed

De processer, der kører i din modelapplikation, skal være nemme at starte og stoppe. Således vil dette give dig mulighed for hurtigt at implementere kodeændringer, konfigurationsændringer, hurtigt og fleksibelt skalere og forhindre mulige nedbrud af den fungerende version.

Det vil sige, din proces med modellen skal:

  • Minimer opstartstiden. Ideelt set bør opstartstiden (fra det øjeblik startkommandoen blev udstedt til det øjeblik, processen træder i funktion) ikke være mere end et par sekunder. Bibliotekscache, beskrevet ovenfor, er en teknik til at reducere opstartstiden.
  • Slut rigtigt. Det vil sige, at lytning på serviceporten faktisk er suspenderet, og nye anmodninger sendt til denne port vil ikke blive behandlet. Her skal du enten oprette en god kommunikation med DevOps-ingeniører eller selv forstå, hvordan det fungerer (helst selvfølgelig sidstnævnte, men kommunikationen skal altid vedligeholdes, i ethvert projekt!)

Princip 8: Kontinuerlig implementering/integration

Mange virksomheder bruger en adskillelse mellem applikationsudviklings- og implementeringsteams (gør applikationen tilgængelig for slutbrugere). Dette kan i høj grad bremse softwareudvikling og fremskridt med at forbedre den. Det ødelægger også DevOps-kulturen, hvor udvikling og integration groft sagt er kombineret.

Derfor siger dette princip, at dit udviklingsmiljø skal være så tæt som muligt på dit produktionsmiljø.

Dette vil tillade:

  1. Reducer udgivelsestiden med titusinder
  2. Reducer antallet af fejl på grund af kodeinkompatibilitet.
  3. Dette reducerer også arbejdsbyrden på personalet, da udviklere og folk, der implementerer applikationen, nu er ét team.

Værktøjer, der giver dig mulighed for at arbejde med dette, er CircleCI, Travis CI, GitLab CI og andre.

Du kan hurtigt lave tilføjelser til modellen, opdatere den og starte den med det samme, samtidig med at det vil være nemt, i tilfælde af fejl, meget hurtigt at vende tilbage til den fungerende version, så slutbrugeren ikke engang bemærker det. Dette kan gøres særligt nemt og hurtigt, hvis du har gode tests.

Minimer forskelle!!!

Princip 9. Dine logfiler

Logfiler (eller "logfiler") er hændelser, normalt registreret i tekstformat, der forekommer i applikationen (hændelsesstrøm). Et simpelt eksempel: "2020-02-02 - systemniveau - procesnavn." De er designet, så udvikleren bogstaveligt talt kan se, hvad der sker, når programmet kører. Han ser forløbet af processer og forstår, om det er, som udvikleren selv har tænkt sig.

Dette princip siger, at du ikke skal gemme dine logs inde i dit filsystem - du skal bare "outputte" dem til skærmen, for eksempel gøre dette på systemets standard output. Og på den måde bliver det muligt at overvåge flowet i terminalen under udviklingen.

Betyder det, at der overhovedet ikke er behov for at gemme logfiler? Selvfølgelig ikke. Din applikation burde bare ikke gøre dette - overlad det til tredjepartstjenester. Din applikation kan kun videresende logfiler til en specifik fil eller terminal til visning i realtid eller videresende den til et generelt datalagringssystem (såsom Hadoop). Selve din applikation bør ikke gemme eller interagere med logfiler.

Princip 10. Test!

For industriel maskinlæring er denne fase ekstremt vigtig, da du skal forstå, at modellen fungerer korrekt og producerer det, du ønskede.

Test kan oprettes ved hjælp af pytest, og testes ved hjælp af et lille datasæt, hvis du har en regressions-/klassificeringsopgave.

Glem ikke at sætte det samme kimen til deep learning-modeller, så de ikke konstant producerer forskellige resultater.

Dette var en kort beskrivelse af de 10 principper, og det er selvfølgelig svært at bruge dem uden at prøve og se, hvordan de virker, så denne artikel er blot en prolog til en række interessante artikler, hvor jeg vil afsløre, hvordan man skaber industrielle maskinlæringsmodeller, hvordan man integrerer dem i systemer, og hvordan disse principper kan gøre livet lettere for os alle.

Jeg vil også prøve at bruge seje principper, som alle kan skrive i kommentarerne, hvis de ønsker det.

Kilde: www.habr.com

Tilføj en kommentar