Machine Learning og DataOps: Sådan får du styr på versionskontrol

Mangel på versionering er den grundlæggende årsag til en masse teknisk gæld, kompleksitet og fiaskoer, når det kommer til machine learning systems, skriver Luca Palmieri.
Brødtekst

Ved data science-meetups deles ofte en tilbagevendende rædselshistorie: projekter, hvor kode og data blev sendt rundt mellem holdkammerater (og klienter) ved hjælp af e-mails med vedhæftede zip-filer.

Hvis du nogensinde har arbejdet på en PowerPoint-præsentation inden Google Slides-æraen, ved du hvad jeg taler om. Den mest almindelige kilde til problemer i disse situationer er versioning: at vide, hvordan hver zip-fil er relateret til de andre, for at forstå, hvad der er ændret af hvem og, endnu vigtigere, hvilken version af projektet du skal arbejde på.

Disse rædshistorier nævner normalt den mest avancerede versionskonvention, der er kendt for den menneskelige race - manuel filsporing: project_v1.zipproject_v2.zipproject_v2_bis.zip, etc.

Vi kan helt sikkert gøre det bedre end det.

Især hvis du har investeret store pengebeløb i at starte et Data Science-projekt eller opbygge et Machine Learning-team. Det er du nødt til. 

Som det ofte er tilfældet, har andre mennesker været der før os, og de har fundet smarte løsninger på vores problemer: softwareudviklere. De er måske gået lidt af mode i dag (de laver ikke den der AI-ting, som alle taler om!), men de måtte finde en måde at samarbejde effektivt på softwareprojekter et par årtier før Data Scientist endda blev betragtet som en legitim jobtitel.

Det var ikke let, men softwareudviklingssamfundet vedtog til sidst versionskontrol-software som den foretrukne måde at styre og koordinere teambidrag til et softwareprojekt. Det mest berømte værktøj i denne verden er bestemt git, fjernt efterfulgt af mercurial.

Versionkontrol?

Hovedideen er ganske simpel: Hver gang nogen vil bidrage til projektet med nogle ændringer, bundter de dem sammen i et commit, og dette bidrag tilføjes i slutningen af projektets historik. Hvert commit er et atomisk bidrag, og historikken er intet andet end en sekvens af commits - det giver os mulighed for at observere projektets status på ethvert tidspunkt: fra den første prototype til den seneste produktionsændring er det simpelthen et spørgsmål om at vælge, hvilket commit man vil se på.

Verden bliver lidt mere rodet med branches og merge conflicts, men det har mere at gøre med brug af "distributed" versionkontrolsoftware så vel som holddynamikker.

Hvad der betyder noget for os er, at vi kan stille spørgsmål som:

  • Hvornår var fejl X introduceret?
  • Hvem var den sidste, der ændrede en linje i Y?
  • Hvordan så linje Y ud før ændringen?
  • Hvad for noget kode var i produktion to måneder før denne [katastrofiske begivenhed] skete?

Og det er muligt, fordi vi har en enkel kilde af sandhed for kode - vores versionkontrols-historik.

Applikationskode er ikke god nok

Antag, at du bygger et websted - en blog, for at være mere specifik.

Du har designet din applikation ved hjælp af den nyeste JavaScript-framework, og den kører problemfrit på din maskine, når du tester den ud på localhost. Men det er ikke nok til at gøre den synlig og tilgængelig for verden!

Du bliver nødt til at skaffe dig en server, der er vært for webstedet, du bliver nødt til at registrere et domæne med en DNS-service, og oftest er du også nødt til at komme op med en slags database, som din applikation vil tale med.

Hvordan sikrer du dig, at alle disse dele fungerer sammen og kører problemfrit?

Du har måske glemt at fryse dine afhængigheder i JavaScript-applikationen: Når du installerer dem på serveren får du nyere versioner af et par pakker, der indeholder en fejl, der ødelægger din blog. Skidt!

Du bruger muligvis en smart MacBook Pro som din arbejdshestmaskine, men din server vil sandsynligvis køre en form for Linux - en anden kilde til problemer. Skidt!

Din database kommunikerer muligvis fint med din applikation, når du kører dem begge på localhost, men du har glemt at indstille de korrekte tilladelser til at få serverne, der hoster dem, til at kommunikere med hinanden - nu kan din live blog ikke nå sin database og alle indlæg / kommentarsektioner er tomme. Skidt!

worksonmymachine
Illustration: Palmieri

Der er et tilbagevendende mønster: al vores kode lever i et versionskontrol repository, og vi har sørget for, at det fungerer (unit test, acceptance test osv.), Men der er et helt univers omkring en applikation i produktionen, der ikke er taget højde for og som med stor sandsynlighed kan forårsage funktionsfejl i vores softwareprojekt. Dette univers er ikke fanget i vores versionskontrolsystem.
Hvordan løser vi det?

Du versionerer alt.

Hvordan gør du det? Du starter med at skrive miljø, konfiguration, infrastruktur og processer som kode. Der er en række værktøjer til at gøre dette muligt, lige fra Docker-containere til reproducerbare miljøer til Terraform-moduler til reproducerbar infrastruktur, samt værktøjer til continuous deployment. Alt sammen for at sikre, at applikationen i det versionskontrollerede repository bliver ordentligt implementeret i de rigtige miljøer (produktion, udvikling osv.). Processer skal også opbevares som kode.

Det spørgsmål, du har brug for at stille jer selv, som denne artikel antyder, er:

Can I recreate a specific version of the complete software system — with infrastructure, data, software, and configuration — by running one command that gets a specific revision from my version-control system?

Hvis du ikke kan, versionerer du ikke alt. Hvis du ikke versionerer alt, kan du ikke konsekvent gengive din applikation.

Det har vidtrækkende konsekvenser, og jeg ville vove at sige, at det er den grundlæggende årsag til en masse teknisk gæld, kompleksitet og fiaskoer, når det kommer til machine learning-systemer.

Hvor er machine learning så specielt?

Data er den vigtigste forskel mellem et machine learning-projekt og et traditionelt softwareprojekt: selvom alt andet forbliver stabilt, vil en ændring i dine modellers træningsdata gøre en enorm forskel. Og data er på grund af deres størrelse og art meget vanskelige at indsamle i versionskontrolsystemer som git.

Vi kan få yderligere indsigt ved at se på, hvordan et machine learning-projekt fungerer.

Vi kan normalt identificere to forskellige faser:

  • Prototyping  - forskellige opsætninger (algoritmer, hyperparametre, datakilder, databehandling) testes indtil den mest lovende løsning identificeres for at løse det aktuelle forretningsproblem;
  • Produktion - ML-modellen implementeres sammen med alt det relevante maskineri, der kræves for at få den til at fungere (API, ETL pipelines, etc.)

At træne en model, medmindre du har at gøre med en eller anden online-læringsmodel, sker normalt, før en model bliver sat i brug i den sene prototypefase. Det er en artefakt genereret fra kombinationen af ​​et vist antal datakilder og koden, der bruges til at behandle og lære af dem.

Prototypefasen har således direkte indflydelse på, hvad der sker i produktionsfasen - at kunne reproducere et træningsforløb bliver yderst relevant, når en af ​​modellerne er sat i produktion og noget går galt.

For at sikre reproducerbarhed af træningskørsel skal vi holde styr på:

  • Dataplan eller data historik - hvor kommer dette datasæt fra (Er det resultatet af en database-forespørgsel? Er der et originalt rå datasæt? Er det resultatet af script, der køres oven på et andet datasæt?);
  • Eksperimentopsætning - hvor kører vi vores træning? Er miljøet reproducerbart? Kan vi tilknytte de data, der er blevet brugt til den resulterende model, vi har trænet?
  • Friskhed - er vi sikre på, at vi hver gang vi ændrer et trin i vores data-pipeline, har genberegnet alle nu uaktuelle datasæt, inden vi kører endnu en træningssession for en model?
  • Logning - hvordan holder vi styr på resultaterne?

Alt dette er nødvendigt, hvis du vil være i stand til at gå tilbage og kigge på hvert lille skridt du tog for at fremstille den serieopbyggede model for at kunne udpege, hvad der gik galt, hvor - for at kunne debugge den! (Eller for at revidere den, hvis du arbejder i en branche, der kræver det)

Hvis alt er fanget i versionskontrol, kan alle de ting, vi har nævnt indtil videre, opnås - reproducerbarhed for machine learning-systemer bliver mulig.

Hvordan fikser vi det?

Vi har brug for datavidenskabsmænd og maskinlæringsspecialister for at forstå, at software ligger i hjertet af de systemer, vi arbejder med, og vi er nødt til at vedtage al den bedste praksis, der er udviklet over tid for at tackle det. Vi har helt sikkert arvet alle problemerne, så vi bør også samle de gode ting op!

Der er meget arbejde, der skal gøres for at replikere til Machine Learning-systemer, hvad DevOps har gjort for softwareudvikling.

En ting er sikkert: Det er tid til at rulle ærmerne op.

Dette er en opdateret version af en ældre artikel, oversat med forfatterens tilladelse. Læs mere på forfatterens blog.

Se blandt andet denne meget fine liste over DataOps-boganbefalinger.