AI'en inde i dit fotobibliotek, og hvorfor vi har flyttet den over på vores egne GPU'er

AI'en inde i dit fotobibliotek, og hvorfor vi har flyttet den over på vores egne GPU'er

Når du søger i dit fotobibliotek efter “hund i sneen”, og det rigtige billede dukker op, har noget allerede læst det foto for dig. Ingen har tagget det. En machine learning-model kiggede på pixlerne, afgjorde, hvad der var i billedet, og gemte den forståelse, så du kunne finde det igen senere. Vi flyttede for nylig det arbejde fra CPU’er over på vores egne GPU’er (graphics processing units, grafikprocessorer). Dette indlæg forklarer, hvad AI’en faktisk gør, og hvorfor hardwaren under den betyder noget.

Modellerne, der gør dette muligt, er ikke vores egne. De kommer fra open source-projektet Immich, som PixelUnion er bygget på. Det, der er vores, er, hvor de kører: på hardware, vi selv ejer og driver, på europæisk jord, ikke i en tredjeparts AI-sky. Modellerne læser dine fotos, og for os betyder det noget, at de gør det i vores egne racks og intet andet sted.

Der er én skelnen, som er værd at gøre, før vi går videre, for det er den, der betyder mest for dit privatliv. At bruge en model er ikke det samme som at træne en. Træning er den dyre engangsproces, hvor en model lærer af millioner af eksempelbilleder, og den udføres af modellens ophavsfolk længe før, den når til os. Det, vi gør, er inferens: vi tager en færdig, allerede trænet model og sender dit foto igennem den én gang for at få et resultat, ligesom du sender et dokument gennem en scanner. Dine fotos bruges aldrig til at lære modellerne noget som helst. De tilføjes ikke til et træningssæt, de forbedrer ikke en fælles model, og intet fra dem forlader os for at gøre en fremtidig version klogere. Modellen kigger på dit foto, giver sit svar og glemmer det igen.


Tre opgaver, ét fælles trick: at gøre pixels søgbare

Immich kører sin AI i en separat tjeneste, containeren immich-machine-learning, dokumenteret i projektets machine learning-README. Den udfører tre opgaver, og hver løser et forskelligt problem:

  • Smart søgning forvandler et foto til noget, du kan søge i med almindeligt sprog, ved hjælp af en CLIP-model.
  • Ansigtsgenkendelse finder ansigter og finder ud af, hvilke der tilhører den samme person, ved hjælp af en modelpakke som buffalo_l.
  • OCR læser tekst, der optræder i dine fotos, ved hjælp af en PP-OCRv5-model.

Det er værd at være præcis her, for “tre modeller” er en forenkling. To af disse opgaver er faktisk et par modeller, der arbejder i rækkefølge, og hver opgave kan udskiftes med en anden model. Ansigtsgenkendelse kører en detektionsmodel efterfulgt af en genkendelsesmodel, og buffalo_l er en bundt, der indeholder begge. Immich leverer også alternativer som antelopev2, buffalo_m og buffalo_s. OCR fungerer på samme måde, én model til at finde tekst og en anden til at læse den. Og CLIP i sig selv er et par encodere, én til billeder og én til tekst, med mange udskiftelige varianter. Der findes slet ingen separat objektdetektionsmodel: at genkende, at et foto indeholder en hund eller en strand, håndteres af CLIP, ikke af en dedikeret tagging-model.

Det, der betyder noget for at forstå dem, er, at alle tre opgaver deler ét underliggende trick. Så lad os forstå det trick først. Derefter giver forskellene mening.

Ansigtsgenkendelse i to trin: detektion og genkendelse


CLIP: at søge efter betydning, ikke efter tags

Gammel fotosøgning byggede på filnavne og manuelle tags. Hvis du ikke havde skrevet “strand” i en billedtekst, fandt en søgning på “strand” ingenting. CLIP, en model oprindeligt udgivet af OpenAI (artikel her), fjerner den begrænsning. Den kigger på det faktiske indhold i et billede.

Her er den del, folk snubler over, forklaret enkelt. CLIP gemmer ikke en liste af ord for hvert foto. Den konverterer hvert foto til en vektor: en lang liste af tal, et par hundrede af dem, der tilsammen beskriver billedets betydning. Et billede af en husky i frisk sne og et billede af en anden hund i sne ender med lignende lister af tal, fordi de betyder noget lignende. Den liste kaldes en embedding.

Hvad vektorsøgning faktisk er

Så snart hvert foto i dit bibliotek er en vektor, gemmer vi alle disse vektorer i en database. Søgningen fungerer sådan her:

  1. Du skriver “hund i sneen”.
  2. Den samme model forvandler dine ord til en vektor, i det samme talsystem som fotoene.
  3. Databasen sammenligner din søgevektor med de gemte fotovektorer og måler, hvor tæt hver ligger.
  4. De nærmeste match kommer først tilbage.

“Tæt” er her matematik. Hver vektor er et punkt i rummet, og systemet måler afstanden mellem din forespørgsel og hvert foto. I den enkleste form er det brute force: tjek afstanden til hvert eneste foto, sortér efter det nærmeste. Der er ingen tag-matching og ingen søgeordsopslag nogen steder i den proces. Et foto uden billedtekst, uden filnavn og uden beskrivelse dukker alligevel op, fordi dets betydning bor i tallene.

Hvordan vektorsøgning finder de fotos, der ligger tættest på din søgning

Den brute force-sammenligning er den ærlige version, og for et normalt bibliotek fungerer den fint. Den navngiver også omkostningen. At sammenligne én forespørgsel med millioner af vektorer, én ad gangen, bliver langsomt. I stor skala skifter man til smartere indekser, approximate nearest neighbor-søgning, som springer de fleste sammenligninger over og alligevel finder de rigtige match. Hvilken tilgang du har brug for, afhænger af bibliotekets størrelse, men princippet er det samme: lav alt om til vektorer, og find derefter de nærmeste.

Én ting mere, der betyder noget i Europa. Standard-CLIP-modellen håndterer engelsk godt og andre sprog dårligt. Der findes flersprogede varianter, og Immich lader dig udskifte dem, som projektets guide til modelvalg beskriver. Afvejningen er reel: de bedre flersprogede modeller er større og har brug for mere hukommelse for at køre. Det hukommelsespres er en af grundene til, at valget af hardware begynder at betyde noget, og det kommer vi til.


buffalo_l: at finde den samme person på tværs af dine fotos

Ansigtsgenkendelse i Immich bruger buffalo_l, en modelpakke fra InsightFace-projektet, hostet til Immich på Hugging Face. Den kører i to trin, og begge er værd at forstå, for man antager ofte, at den gør noget, den ikke gør.

Trin et er detektion. Modellen scanner billedet og finder ud af, hvor ansigterne er. Tænk på fokusfirkanten, et kamera tegner omkring et ansigt, bortset fra at modellen gør det bagefter, på hvert foto. Resultatet er et sæt kasser: her er et ansigt, her er et til.

Trin to er genkendelse. For hvert fundet ansigt producerer modellen en vektor, samme idé som CLIP, men indstillet til ansigter. Du kan se den som et numerisk fingeraftryk af det ansigt. To fotos af den samme person, i forskelligt lys og fra forskellige vinkler, giver vektorer, der ligger tæt på hinanden. To forskellige personer ligger langt fra hinanden.

Det er hele mekanismen bag “personer” i dit bibliotek. Vi slår ikke dit ansigt op mod nogen ekstern database, og der hænger intet navn på noget, før du selv vælger at mærke en person. Modellen måler geometrien i et ansigt og laver den om til tal og grupperer så de tal, der ligger tæt. Immichs egen guide til ansigtsklynger beskriver, hvordan den gruppering kan finjusteres. Fingeraftrykkene bliver i vores system, på vores hardware. De er aldrig produktet.


PP-OCRv5: at læse teksten inde i dine billeder

Den nyeste af de tre er OCR, optisk tegngenkendelse, tilføjet i Immich version 2.2. Den bruger PP-OCRv5, en model fra Baidus PaddleOCR-projekt. OCR er det, der lader dig søge efter ord, der optræder inde i et foto: et gadeskilt, en butiksfacade, et whiteboard, etiketten på en flaske.

Også dette fungerer i to trin, og opdelingen afspejler ansigtsgenkendelse.

Først registrerer den tekst. Modellen finder de områder af billedet, der indeholder skrift, og tegner kasser omkring dem, på samme måde som ansigtsmodellen indrammer ansigter. Et foto af en gade kan have tekst fem steder: et skilt, en nummerplade, en plakat, et menukort, en bus. Hver bliver til en kasse.

Derefter læser den. For hver kasse finder en anden model ud af, hvilke tegn der faktisk står der, og laver dem om til rigtig, maskinlæsbar tekst. Den tekst går ind i søgeindekset, så du senere kan søge efter “pizzeria” og finde fotoet af restaurantfacaden, selvom du aldrig skrev en billedtekst.

Afvejningen er sådan en typisk Marc-detalje, der er værd at nævne: OCR er god til klar trykt tekst i understøttede skriftsystemer og meget svagere ved håndskrift eller stærkt stiliserede skrifttyper. Immich understøtter officielt engelsk, kinesisk og japansk, mens sprog med latinsk skrift generelt fungerer med noget lavere nøjagtighed, som drøftet i projektets tråd om OCR-sprog. Det er en virkelig nyttig funktion, ikke en magisk en.


Hvorfor alt dette kører så meget bedre på en GPU

Hver model ovenfor udfører under overfladen den samme slags regnestykke: enorme mængder af små multiplikationer og additioner, arrangeret som matrixmatematik. At lave et foto om til en vektor er millioner af disse operationer. Det ene faktum forklarer hele hardwarehistorien.

En CPU har et lille antal meget dygtige kerner, en håndfuld til et par dusin. Hver kerne er fleksibel og hurtig og arbejder sig gennem opgaver stort set i rækkefølge. Det design er fremragende til det varierede, forgrenede arbejde, en server udfører hele dagen. Det passer dårligt til at lave den samme simple multiplikation et par millioner gange i træk.

En GPU er det modsatte. Den har tusindvis af enklere kerner, bygget til at køre den samme operation på tværs af enorme mængder af tal på én gang, parallelt. Grafikkort blev designet til at skygge millioner af pixels samtidig, og det viser sig, at machine learning-inferens er samme slags problem: den samme matematik, gentaget på tværs af mange data. Så i stedet for at et fotos millioner af operationer siver bølge for bølge gennem nogle få CPU-kerner, fordeler de sig sammen på tusindvis af GPU-kerner.

En CPU med få store kerner over for en GPU med mange små kerner

Resultatet er ikke en lille forbedring, det er en anden størrelsesorden af hastighed for netop denne arbejdsbyrde. Immich tilbyder præcis dette i sin dokumentation om hardwareacceleration, som lader machine learning-tjenesten køre på CUDA, ROCm eller OpenVINO i stedet for CPU’en. Rapporter fra fællesskabet giver en fornemmelse af skalaen. På CPU er smart søgning konsekvent den langsomste af machine learning-opgaverne, og brugere beskriver den som flaskehalsen ved indeksering af et stort bibliotek. På beskeden GPU-hardware dokumenterer en beretning embedding af omkring 300.000 fotos på under én nat. Det er eksterne tal fra andres opsætninger, ikke vores egne, men retningen er konsekvent overalt: GPU’en rydder efterslæbet på en brøkdel af tiden.

Kortene, vi valgte til dette, er ældre grafikkort til forbrugere, ikke nye datacenter-acceleratorer. Det er et bevidst valg, og det kommer med afvejninger, der er værd at nævne. Et sådant kort har stadig tusindvis af parallelle kerner og nok indbygget hukommelse til at rumme disse modeller komfortabelt, og det er alt, hvad denne arbejdsbyrde har brug for. Modellerne er ikke store efter nutidens standarder. CLIP er den tungeste af de tre, mens ansigts- og OCR-modellerne er forholdsvis lette. At genbruge dygtig ældre hardware holder godt silicium i drift i stedet for at sætte det på en hylde, og det holder hele pipelinen på udstyr, vi ejer fuldt ud.

Der er en reel omkostning på den anden side af regnskabet, og at lade som om andet ville være uærligt. En GPU trækker mere strøm under belastning end en inaktiv CPU, og at drive sin egen hardware betyder, at vi bærer vedligeholdelsen, driverne og elektriciteten. Vi mener, det er den rigtige afvejning. Pr. behandlet foto udfører GPU’en arbejdet med langt bedre effektivitet, og det betyder, at den AI, der læser dine minder, kører på maskiner, vi kontrollerer, under europæisk lov, i stedet for at blive sendt til en andens sky for at blive behandlet.

Indtil videre kører vi Immichs standardmodeller, de samme, som enhver Immich-bruger får ud af boksen. Grunden til, at dette hardwaretrin rækker ud over hastighed, er råderum. Større modeller har generelt brug for mere regnekraft og mere hukommelse for at køre i et brugbart tempo, præcis hvad en CPU ikke kunne levere. Med vores egne GPU’er på plads bliver det at køre en større CLIP-variant for skarpere søgning, eller en tungere ansigtsmodel for bedre klyngedannelse, en praktisk mulighed i stedet for en umulighed. Vi giver ingen løfter om bestemte modeller her. Pointen er, at dette trin åbner døren, og bedre resultater for vores kunder er grunden til at gå igennem den.

Der er en hage ved at skifte til en større model, og det er bedst at være ærlig om den. En anden model producerer andre vektorer. De tal, én CLIP-model tildeler et foto, betyder intet for en anden CLIP-model, så du kan ikke blande gammelt og nyt. Hvis vi nogensinde skifter til en større model, ville vi være nødt til at genberegne embeddings for hvert foto i hver brugers bibliotek fra bunden, på vores egne GPU’er. For en stor brugerbase er det en enorm mængde regnearbejde, og det er præcis den slags opgave, der er håbløs på CPU’er og blot en stor opgave på GPU’er. Dette trin bringer os tættere på at være klar til det, men vi er der ikke endnu. Når vi er, er det et blogindlæg værd i sig selv.


Hvorfor vi gør det selv

Ingen af disse modeller er eksotiske, og ingen af dem er hemmelige. Sådan er det at bygge på open source: du kan læse præcis, hvad CLIP, buffalo_l og PP-OCRv5 gør, og det kan vi også. Den beslutning, der faktisk former dit privatliv, er ikke, hvilken model der kører, men hvor den kører, og hvem der driver den.

Vi kører dem på vores egne GPU’er, i vores eget miljø, på europæisk jord. Dine fotos læses af maskiner, vi er ansvarlige for, og de vektorer og fingeraftryk, der kommer ud af den proces, bliver hos os og sælges aldrig. Det er den del, Big Tech ikke vil tilbyde dig, for for dem er læsningen af dine fotos forretningsmodellen, ikke en funktion.

For at være klar om, hvor vi er: dette er et første skridt, ikke det færdige billede. Machine learning-modellerne kører nu på vores egne GPU’er, men ikke hele vores platform kører endnu på hardware, vi ejer. Vi bygger selvdrevet infrastruktur op stykke for stykke, og AI’en, der læser dine fotos, var et bevidst sted at begynde, fordi det er den mest følsomme del. Vi fortæller dig hellere præcis, hvad der kører hvor i dag, end at antyde, at vi er længere, end vi er. Forvent, at vi uddyber dette i fremtidige indlæg, efterhånden som mere af stakken flytter over på vores egen hardware.

Hvis du vil have et fotobibliotek med en søgning, der er så dygtig, uden at overlade de underliggende data til et firma, der tjener penge på dem, er det præcis det, vi bygger.

Se, hvad vi tilbyder →


En note om billederne: infografikkerne i dette indlæg er genereret med AI. Vi mener, at de fortjener deres plads, fordi de gør disse idéer nemmere at forestille sig.