Vaizdais gausius agento ciklus išlaikome atmintyje
Gamyboje agento ciklas ištuštėjo atmintį, pasiekęs 952 MB, kai iškirpinėjo produktus iš šešių katalogo nuskaitymų ir žiūrėjo į savo iškirpimus. Nebuvo vienos nutekėjimo priežasties – buvo trys. Kiekvienas kvietimas modeliui iš naujo siuntė visus ciklo vaizdus pilname dydyje; biblioteka, kurią naudojame modeliui kviesti, laikė kiekvieną užklausą gyvą iki ciklo pabaigos; o agento sistemos sekimas (tracing) išlaikė kiekvieno kvietimo įvestis, įskaitant vaizdus, visam ciklui. Visas tris ištaisėme: vaizdai dabar sumažinami prieš siunčiant, o kiekvieno kvietimo vaizdai atleidžiami, kai tik kvietimas baigiamas.
Kaip agentas mato vaizdus
Kai kuriate Mythex, agentas dirba jūsų projekto debesies smėlio dėžėje. Jis gali žiūrėti į vaizdus – ekrano nuotrauką, kurią prisegate, maketą, failą projekte arba vaizdą, kurį pats ką tik sukūrė – siųsdamas juos modeliui kartu su pokalbiu.
Ciklas – tai viskas, ką agentas daro atsakydamas į vieną jūsų žinutę. Ciklo metu agentas modeliui kviečiamas daug kartų: mąsto, paleidžia įrankį, žiūri į rezultatą, vėl mąsto. Kiekvienas kvietimas siunčia pokalbį iki šiol, o tame yra ciklo vaizdai, užkoduoti kaip tekstas (base64, todėl jie apie trečdalį didesni).
Ciklas, kuris sugedo, darė kažką pagrįsto. Jis paėmė šešis katalogo nuskaitymus, po maždaug 2,4 MB kiekvienas, iškirpo atskirus produktus ir vėl skaitė savo iškirpimus, kad patikrintų. Tai daug modelio kvietimų, kiekvienas su keliais dideliais vaizdais.
1 priežastis: kiekvienas kvietimas siuntė pilno dydžio vaizdus iš naujo
Kiekvienas modelio kvietimas perkūrė savo užklausos turinį su visais ciklo vaizdais pilname dydyje – apie 20 MB base64 kiekvienam kvietimui. Turinys sukuriamas kaip viena eilutė agento atmintyje, todėl kiekvienas kvietimas paskirstydavo dar apie 20 MB.
Siųsti pilnu dydžiu iš tikrųjų nieko nedavė. Modelis pats sumažina vaizdus iki maždaug 1300 pikselių ilgosios pusės, todėl papildomi pikseliai kainuoja tik atmintį ir įkėlimo laiką.
Sprendimas: vieną kartą sumažinti, siųsti mažus
- Vaizdai didesni nei 400 KB prieš siunčiant konvertuojami į JPEG, kurio ilgoji pusė ne didesnė nei 1568 pikseliai. Mažesni vaizdai siunčiami tokie, kokie yra.
- Konvertavimui naudojamas ImageMagick, kuris yra kiekvienoje Mythex smėlio dėžėje, ir jis veikia kartą kiekvienam failui. Ciklas, kuris rodo tuos pačius nuskaitymus kiekvieno kvietimo metu, naudoja jau sumažintą kopiją. Ta talpykla raktuojama pagal failo kelią, dydį ir keitimo laiką, todėl redaguotas failas konvertuojamas iš naujo, ir ji turi savo dydžio ribą, kad pati netaptų tuo, kas užpildo atmintį.
- Vaizdams vienu modelio kvietimu skirtas biudžetas sumažėja nuo 16 MB iki 6 MB.
Tie patys šeši nuskaitymai dabar kainuoja 4,4 MB kiekvienam kvietimui vietoj 19,7 MB.
2 priežastis: modelio klientas niekada nepaleido užklausos
Kiekvienos užklausos dydis buvo tik dalis problemos. Atmintis taip pat augo iš kvietimo į kvietimą. Mūsų testavimo aplinkoje tokio paties tipo ciklas laikė 369 MB gyvos atminties net po pilno šiukšlių surinkimo – taško, kai viskas, ką nebegalima pasiekti, jau atlaisvinama. Krūvos (heap) analizė visą augimą rodė bibliotekos dalyje, kuri koduoja užklausų turinį.
Priežastis buvo nutraukimo klausytojas. Kai paspaudžiate Stabdyti, ciklo nutraukimo signalas suveikia, ir visos užklausos, klausančios to signalo, atšaukiamos. Mes perdavėme vieną bendrą ciklo signalą kiekvienai užklausai. Kliento biblioteka prideda „abort“ klausytoją prie bet kurio signalo, kuris jai perduodamas – ir niekada jo nepašalina.
Todėl kiekviena ciklo užklausa liko pasiekiama iš ciklo signalo tiek, kiek ciklas tęsėsi: klausytojas, kuris laikė užklausos valdiklį, kuris laikė pačią užklausą, kuri laikė visą užklausos turinį su vaizdais.
Sprendimas: vienas signalas kiekvienai užklausai
Dabar kiekviena užklausa gauna savo signalą. Jis susiejamas su ciklo signalu tik tol, kol užklausa vykdoma – srautinio atsakymo atveju, kol perskaitytas paskutinis gabalas – ir iškart po to atsiejamas. Stabdymas vis dar pasiekia bet kurią vykdomą užklausą, bet ciklo signale vienu metu būna tik vienas klausytojas.
Testai apima visas tris dalis:
- Po 12 kvietimų ciklo signale nelieka klausytojų. Prieš pataisymą jų buvo 12.
- Per 15 užklausų po 8 MB atmintis lieka stabili. Anksčiau ji augo 128 MB.
- Paspaudus Stabdyti, užklausa vis dar nutraukiama viduryje srauto.
3 priežastis: sekimas išlaikė kiekvieno kvietimo įvestis
Krūvos nuotrauka parodė trečią laikytoją: apie 6 MB kiekvienam modelio kvietimui. Tai kilo iš agento sistemos įvykių srautinio perdavimo. Ji įrašo kiekvieną modelio kvietimą ciklo viduje kaip ciklo vaikinį elementą, įskaitant įvestis, iki ciklo pabaigos. Kiekvienas kiekvieno kvietimo prisegtas vaizdas liko atmintyje kartu su juo.
Sprendimas: ištuštinti vaizdus, kai kvietimas grąžina rezultatą
Vaizdai niekada nėra saugomi pokalbio išsaugotoje būsenoje; jie prisegami tik prie žinučių, sukurtų konkrečiam modelio kvietimui. Todėl, kai kvietimas grąžina rezultatą, saugu ištuštinti vaizdų duomenis tose žinutėse. Sekimas išsaugo tekstinį kvietimo įrašą; pikseliai išnyksta.
Vienas dalykas buvo svarbus: vaizdus reikia ištuštinti vietoje. Sekimo įrankis gali pasiekti tuos pačius vaizdų duomenis per daugiau nei vieną nuorodą žinutėje, todėl, jei pakeistume juos nauju, tuščiu sąrašu, originalas – pikseliai ir viskas – liktų pasiekiamas. Išsaugota pokalbio būsena niekada nekeičiama.
Testas paleidžia agento grafą su tuo pačiu įvykių srautinimu, kiekviename kvietime pateikdamas 4 MB vaizdą. Be pataisymo atmintis per 16 kvietimų išaugo 77 MB. Su pataisymu atmintis lieka stabili.
Ką iš to išmokome
- Atminties problemos gali būti sluoksniuotos. Trys atskiros priežastys kiekviena laikė vaizdus per ilgai, ir visos trys turėjo būti pašalintos, kad ciklas tilptų į atmintį.
- Viskas, ką perduodate bibliotekai, gali būti laikoma. Signalas ir sekimas išgyveno kvietimus, kuriems buvo perduoti. Kai atmintis auga kiekvienam kvietimui, žiūrėkite, kokius ilgai gyvuojančius objektus kvietimas paliečia.
- Nesiųskite to, ką kita pusė vis tiek išmes. Pikseliai, kuriuos modelis vis tiek atmestų, kainavo mums atmintį kiekviename kvietime.
- Testuokite atmintį tiesiogiai. Kiekvienas pataisymas buvo pateiktas su testu, kuris matuoja krūvos augimą ar klausytojų skaičių, todėl regresija pasireiškia kaip skaičius, o ne kaip avarija.
Tai antra atminties istorija, susijusi su agentu per trumpą laiką; pirmoji buvo progreso etiketė, kuri į eilę įdėjo 41 000 kartų. Jei norite daugiau sužinoti, kas yra agentas ir kaip jis veikia, žr. mūsų vadovą apie AI agentus ir pokalbio dokumentaciją.