
No OCR līdz pikseļiem, nezaudējot rezerves ceļu
GeekBye pārstāja lasīt tavus ekrānuzņēmumus ar OCR un sāka sūtīt pašu attēlu redzes modeļiem — un tā ir vieglā daļa. Pamācošā daļa ir optimizācija, kas redzes lietotājiem pilnībā izlaida OCR, klusi salauza rezerves ceļu uz modeļiem bez redzes un bija jāatsauc līdz versijai, kur drošības tīkls darbojas paralēli un neko nemaksā.
Jebkurai lietotnei, kas ļauj tev kaut ko notvert ar ekrānuzņēmumu un pajautāt par to AI, ir īsts ceļa sazarojums. Tu vari palaist OCR — izvilkt tekstu uz ierīces, nosūtīt niecīgu virkni un izmest attēlu. Vai arī tu vari sūtīt pikseļus — piegādāt pašu attēlu un ļaut redzēt spējīgam modelim to izlasīt. OCR ir lēts un mazs, bet akls pret visu, kas nav teksts: izkārtojumu, diagrammu, koda atkāpēm, sarkano viļņoto līniju zem kļūdas. Pikseļi to visu saglabā, bet maksā vairāk baitu un prasa modeli, kas spēj redzēt. GeekBye sāka šā sazarojuma OCR pusē un, cauri v1.8.6 un v1.8.7, pārgāja uz pikseļu pusi. Šī pārslēgšanās ir šī stāsta vieglā daļa. Interesantā daļa ir optimizācija, kas nāca līdzi, salauza rezerves ceļu un bija jāatceļ.
Iepriekš: nolasi tekstu, nomet attēlu
Līdz šai lokai ekrānuzņēmums kļuva par atbildi šādi: tu nospied tveršanas īsceļu, klients palaiž OCR — Apple Vision ietvaru caur Swift VisionOCR bināro failu uz macOS, PowerShell skriptu uz Windows, abus aiz vienas IOcrEngine abstrakcijas — un izvilktais teksts tiek ietīts virknē un nosūtīts aizmugursistēmai kā screenshotText. Pats attēls nekad neatstāja mašīnu. Tas ir efektīvi, un vienkārša teksta sienai tas ir labi. Bet ekrānuzņēmums reti ir tikai teksts. Tas ir darba sludinājums ar divu kolonnu izkārtojumu, programmēšanas uzdevums ar diagrammu, kļūda ar steka izsekojumu, kura atkāpe ir pavediens. OCR saplacina to visu par rindiņu pa rindiņai transkripciju, un modelis atbild uz plānāku jautājumu, nekā tu uzdevi.
Pārslēgšanās: sūti pikseļus (v1.8.6)
v1.8.6 pievienoja otru ceļu. Jauns imageOptimizer.ts, būvēts uz sharp un tāpēc starpplatformu, dara tieši trīs lietas ar neapstrādātu ekrānuzņēmumu:
sharp(pngFilePath).resize({ width: 1920, withoutEnlargement: true }).jpeg({ quality: 80 })
Maini izmēru līdz augstākais 1920px platumam (nekad nepalielini mazāku tvērumu), pārvērtē PNG par JPEG, kvalitāte 80. Izvade ir neapstrādāts base64 ar media tipu, kas tiek nests atsevišķā laukā, un tā aizceļo uz aizmugursistēmu divos jaunos pieprasījuma laukos līdzās vecajam: screenshotImage un screenshotImageMediaType, neatkarīgi no screenshotText. Aizmugursistēma tagad var saņemt attēlu, tekstu vai abus.
Šis optimizācijas solis nav kosmētisks. Neapstrādāts ekrānuzņēmuma PNG ir 3–8 MB; pārmērotais JPEG ir aptuveni 200–500 KB. Tā ir kārta mazāk augšupielādei, un tā arī samazina modeļa rēķinu — redzes modeļi sadala attēlu flīzēs pēc tā izšķirtspējas un iekasē maksu par flīzi, tāpēc platuma ierobežošana līdz 1920 un pārkodēšana tieši samazina gan baitus vadā, gan attēla tokenus, par kuriem tu maksā, bez nozīmīga ekrāna teksta salasāmības zuduma.
Kā lietotne vispār zina, vai modelis spēj redzēt? Aizmugursistēma to paziņo. /api/config atbilde ieguva ai.vision bloku, kas atslēgts pēc plāna, un klients katrā konfigurācijas ielādē kešo vienu Būla vērtību — aiSupportsVision. Kad redze tiek atbalstīta, optimizē attēlu; kad ne, atkāpies uz OCR. Tātad spēja ir aizmugursistēmas fakts, kešots klienta pusē, un katra ekrānuzņēmuma lēmums palaist vai izlaist OCR tiek pieņemts klientā no šā karodziņa. Aizmugursistēmai joprojām pieder tas, kurš modelis patiešām atbild.
Optimizācija, kas bija pārāk gudra
Šeit tas kļūst pamācoši. Redzes ceļa pirmā versija palaida OCR un attēla optimizāciju kopā, paralēli. Tad "perf" komits to savilka par vienu-vai-otru: ja plāns atbalsta redzi, optimizē attēlu un pilnībā izlaid OCR; ja ne, palaid OCR un izlaid attēla darbu. Uz papīra tas ir acīmredzams ieguvums — kāpēc izvilkt tekstu, kas redzes modelim nav vajadzīgs? Izmaiņu žurnāls to pat reklamē: "OCR is skipped when the AI can read the image directly."
Problēma ir jēdzienā rezerves ceļš. Aizmugursistēmai nav viena modeļa; tai ir galvenais un rezerves, un rezerves varētu būt modelis bez redzes. Iztēlojies secību: tava plāna galvenais modelis atbalsta redzi, tāpēc klients lepni izlaiž OCR un nosūta tikai attēlu. Galvenajam pakalpojumu sniedzējam paklūp. Aizmugursistēma atkāpjas uz tikai teksta modeli — kuram tagad tiek pasniegts attēls, ko tas nespēj izlasīt, un nekāda teksta, jo klients tekstu optimizēja prom. Ātrais ceļš klusi bija izdzēsis drošības tīklu. Lieku ātro ceļu var droši atmest; nevar atmest to, ap ko ātrais ceļš bija tikai īsceļš.
Labojums: izšķir pēc rezerves, nevis galvenā
Labojums ir tā daļa, ko vērts nozagt. Tas nebija atgriezties pie pastāvīgas OCR palaišanas — tas atmestu ieguvumu izplatītajam gadījumam. Tas bija padarīt izlaišanu atkarīgu no otra spēju karodziņa: vai rezerves atbalsta redzi? Aizmugursistēmas konfigurācija ieguva fallbackVision bloku; klients kešo aiFallbackSupportsVision blakus pirmajam karodziņam. Tagad lēmumam ir četri zari:
- Gan galvenais, gan rezerves redz → optimizē attēlu, izlaid OCR. Ātrais, izplatītais ceļš.
- Galvenais redz, bet rezerves ir akls → optimizē attēlu un palaid OCR kā apdrošinājumu rezervei.
- Attēla optimizācija met kļūdu → OCR kā stingrs rezerves ceļš.
- Plānam vispār nav redzes → tikai OCR.
Un otrais zars — apdrošināšanas gadījums — ir tur, kur pēdējais gājiens ir svarīgs. OCR palaišana pēc attēla optimizācijas pieliktu tā aizkavi virsū. Tāpēc abi darbojas kopā zem viena Promise.all: attēla optimizācija un OCR pārklājas, un OCR, kas eksistē tikai gadījumam, ja aizmugursistēmai tas ir vajadzīgs, pabeidzas laikā, kad attēls tik un tā tika optimizēts. Drošības tīkls reālā laika ziņā ir bez maksas ikreiz, kad tas netiek izmantots. Tas ir viss triks vienā teikumā: saglabā lēto rezerves ceļu, izšķir to pēc tā, vai tavam rezerves sniedzējam tas patiešām ir vajadzīgs, un palaid to paralēli, lai tas neko nemaksā, līdz brīdim, kad tas tevi izglābj.
Divi mazāki slazdi, ko izlaišana izraisīja
Agresīva atliktā darba izlaišana mēdz izcelt katru vietu, kas klusi pieņēma, ka darbs notiks. Divas parādījās PR pārskatā tajā pašā nedēļā.
Rindas strupceļš. Ekrānuzņēmumu rinda uzskatīja vienumu par "gatavu", kad tam bija OCR teksts. Redzes ekrānuzņēmumi tagad nekad neieguva OCR tekstu — pēc dizaina — tāpēc pilnīguma pārbaude hasIncompleteOCR gaidīja mūžīgi, un rinda iestrēga. Labojums pārdefinē "gatavu" kā ir optimizēts attēls vai ir OCR teksts, kas ir tas, ko konveijers tagad patiešām garantē.
Novecojis spēju karodziņš. aiSupportsVision ir kešots, kas nozīmē, ka tas var novecot tieši nepareizajā virzienā: lietotājs izrakstās vai konfigurācijas ielāde neizdodas, un klients paliek pārliecībā, ka tas joprojām drīkst sūtīt attēlus modelim, kas tos vairs neatbalsta. Karodziņš tagad atiestatās pie izrakstīšanās un pie konfigurācijas ielādes kļūmes — kešotai spējai ir jābūt plānam gadījumam, kad tas, ko tā apraksta, pazūd.
Daži vārdi par skaitļiem
Tāpēc ka godīgums ir šīs sērijas jēga: komitu ziņojumi nes skaitļus — attēla optimizācija "~30ms" pret OCR "~100–150ms," kravas "~200–500 KB vs ~3–8 MB PNG" — un tie ir ticami, bet tie ir paša autora ievietoti novērtējumi, nevis etalona iznākums. Vēsturē nekur nav izmērīta pilna cikla pirms/pēc latentums. Uztver ātruma argumentu kā pamatotu dizaina nolūku, nevis pierādītu rezultātu. Kravas izmēra samazinājums ir vienīgais skaitlis, kam vari uzticēties, jo tas izriet tieši no izmēra maiņas un pārkodēšanas.
Trīs lietas, ko šis laidiens mums iemācīja
- Pikseļu sūtīšana pārspēj teksta lasīšanu — kad modelis spēj redzēt. OCR nomet visu, ko ekrānuzņēmums pauž papildus rakstzīmēm. Redzes modelis nolasa izkārtojumu, diagrammu un atkāpes, un optimizēts JPEG padara to pieņemamu. Bet tā ir likme uz spēju, tāpēc tai ir vajadzīgs rezerves ceļš.
- Ātro ceļu var optimizēt prom, drošības tīklu nekad. OCR izlaišana redzes lietotājiem bija pareiza galvenajam un nepareiza rezervei. Kļūda nebija izlaišana; tā bija izlaišana pēc galvenā spējas, kad svarīga bija rezerves spēja.
- Bezmaksas drošības tīkls ir paralelizēts. Izšķir apdrošināšanas darbu pēc tā, vai tas patiešām ir vajadzīgs, tad palaid to līdzās ātrajam ceļam, lai tas pārklājas. Pareizi izdarīta, graciozā degradācija neko nemaksā līdz dienai, kad tā ir vienīgais iemesls, kāpēc tava funkcija joprojām darbojas.
Iepriekšējai nodaļai v1 stāstā — klikšķcaurlaidīga pārklājuma divi atteices režīmi (v1.8.5); un visai lokai — programmatūras piegādes līdz pilnībai anatomiju.