Kuvapainotteiset agenttivuorot muistin rajoissa
Tuotannossa agenttivuoro loppui muistista 952 megatavussa, kun se leikkasi tuotteita kuudesta tuoteluettelon skannauksesta ja tarkisti leikkaukset katselemalla niitä. Vuotoja ei ollut yksi vaan kolme. Jokainen mallikutsu lähetti vuoron kuvat uudelleen täydessä koossa; kirjasto, jolla kutsumme mallia, piti jokaisen pyynnön elossa vuoron loppuun asti; ja agenttikehyksen jäljitys säilytti jokaisen kutsun syötteet, kuvat mukaan lukien, koko vuoron ajan. Korjasimme kaikki kolme: kuvat pienennetään ennen lähettämistä, ja kunkin kutsun kuvat vapautetaan heti, kun kutsu on valmis.
Miten agentti näkee kuvat
Kun rakennat Mythexillä, agentti toimii projektisi pilvihiekkalaatikossa. Se voi katsella kuvia — liittämäsi kuvakaappauksen, mockupin, projektin tiedoston tai kuvan, jonka se on itse juuri tuottanut — lähettämällä ne mallille keskustelun mukana.
Vuoro on kaikki, minkä agentti tekee yhden viestisi perusteella. Vuoron aikana agentti kutsuu mallia monta kertaa: se miettii, ajaa työkalun, katsoo tuloksen ja miettii uudelleen. Jokainen kutsu lähettää keskustelun tähän asti, ja siihen kuuluvat vuoron kuvat koodattuna tekstiksi (base64, joka tekee niistä noin kolmanneksen isompia).
Vuoro, joka kaatui, teki järkevää työtä. Se otti kuudesta tuoteluettelon skannauksesta, noin 2,4 MB kukin, yksittäisiä tuotteita ja luki leikkauksia takaisin tarkistaakseen ne. Se oli paljon mallikutsuja, joista jokainen kantoi useita suuria kuvia.
Syy 1: jokainen kutsu lähetti täyskokoiset kuvat uudelleen
Jokainen mallikutsu rakensi pyyntörungon uudelleen vuoron kuvat täyskokoisina — noin 20 MB base64-muodossa per kutsu. Runko rakennetaan yhtenä merkkijonona agentin muistiin, joten jokainen kutsu varasi noin 20 MB lisää.
Täysikokoisesta lähettämisestä ei ollut edes hyötyä. Malli pienentää kuvat itse noin 1 300 pikselin pitkälle sivulle, joten ylimääräiset pikselit kuluttivat vain muistia ja latausaikaa.
Korjaus: pienennä kerran, lähetä pieni
- Yli 400 KB kuvat muunnetaan JPEG-muotoon, jonka pitkä sivu on enintään 1 568 pikseliä, ennen lähettämistä. Pienemmät kuvat lähetetään sellaisinaan.
- Muunnos tehdään ImageMagickilla, joka on jokaisessa Mythex-hiekkalaatikossa, ja se ajetaan kerran per tiedosto. Vuoro, joka näyttää samat skannaukset joka kutsulla, käyttää uudelleen pienennettyä kopiota. Välimuisti perustuu tiedoston polkuun, kokoon ja muokkausaikaan, joten muokattu tiedosto muunnetaan uudelleen, ja sillä on oma kokorajansa, ettei siitäkään tule muistin täyttäjää.
- Kuvabudjetti yhdessä mallikutsussa laskee 16 MB:stä 6 MB:iin.
Sama kuuden skannauksen joukko maksaa nyt 4,4 MB per kutsu 19,7 MB:n sijaan.
Syy 2: mallin asiakas ei koskaan vapauttanut pyyntöä
Pyynnön koko oli vain osa ongelmaa. Muisti myös kasvoi kutsu kutsulta. Testiympäristössämme sama vuorotyyppi piti hallussaan 369 MB elävää muistia, vaikka suoritettiin täysi roskienkeruu — kohta, jossa kaikki tavoittamattomissa oleva on vapautettu. Kekomittaus osoitti, että kaikki kasvu oli siinä mallin asiakaskirjaston osassa, joka koodaa pyyntörunkoja.
Syynä oli keskeytyskuuntelija. Kun painat Pysäytä, vuoron keskeytyssignaali laukeaa, ja jokainen sitä kuunteleva pyyntö perutaan. Välitimme yhden koko vuoron kattavan signaalin jokaiselle pyynnölle. Asiakaskirjasto lisää signaaliin „abort”-kuuntelijan eikä koskaan poista sitä.
Joten jokainen vuoron pyyntö pysyi tavoitettavana vuoron signaalin kautta niin kauan kuin vuoro kesti: kuuntelija, joka piti hallussaan pyynnön ohjaimen, joka piti hallussaan pyyntöä, joka piti hallussaan koko pyyntörunkoa kuvineen.
Korjaus: yksi signaali per pyyntö
Jokaisella pyynnöllä on nyt oma signaalinsa. Se linkitetään vuoron signaaliin vain sen ajon ajaksi — suoratoistetulle vastaukselle siihen asti, kunnes viimeinen pala on luettu — ja irrotetaan heti sen jälkeen. Pysäytä tavoittaa edelleen käynnissä olevan pyynnön, mutta vuoron signaalilla on kerrallaan vain yksi kuuntelija.
Testit kattavat kaikki kolme osaa:
- Kahdentoista kutsun jälkeen vuoron signaalilla ei ole kuuntelijoita jäljellä. Ennen korjausta niitä oli 12.
- Viidentoista 8 MB:n pyynnön jälkeen muisti pysyy tasaisena. Ennen se kasvoi 128 MB.
- Pysäytä keskeyttää edelleen pyynnön kesken suoratoiston.
Syy 3: jäljitys säilytti jokaisen kutsun syötteet
Keko-otos paljasti kolmannen pitäjän: noin 6 MB per mallikutsu. Tämä tuli agenttikehyksen tapahtumavirrasta. Se tallentaa jokaisen vuoron mallikutsun vuoron lapsena, syötteet mukaan lukien, kunnes vuoro päättyy. Jokainen kutsuun liitetty kuva pysyi muistissa sen mukana.
Korjaus: tyhjennä kuvat, kun kutsu palautuu
Kuvia liitetään vain tiettyyn mallikutsuun rakennettuihin viesteihin. Niitä ei koskaan tallenneta keskustelun tallennettuun tilaan. Kun kutsu palautuu, kuvadatan voi siis turvallisesti tyhjentää noista viesteistä. Jäljitys säilyttää tekstitietueen kutsusta, pikselit katoavat.
Yksi yksityiskohta oli tärkeä: kuvat täytyy tyhjentää paikallaan. Jäljittäjä voi tavoittaa saman kuvadatan useamman viittauksen kautta viestissä, joten uuden tyhjän listan asettaminen jättäisi alkuperäisen — pikselit mukana — tavoitettavaksi. Tallennettua keskustelutilaa ei muuteta lainkaan.
Testi ajaa agentin graafin samalla tapahtumavirralla, jokaisella kutsulla 4 MB:n kuva. Ilman korjausta muisti kasvoi 77 MB 16 kutsun aikana. Korjauksen kanssa muisti pysyy tasaisena.
Mitä opimme
- Muistiongelmat voivat tulla kerroksittain. Kolme erillistä syytä piti kuvia liian kauan, ja kaikki kolme piti korjata, ennen kuin vuoro pysyi muistin rajoissa.
- Kaikki, mitä annat kirjastolle, voidaan säilyttää. Signaali ja jäljitys elivät kauemmin kuin kutsut, joille ne annettiin. Kun muisti kasvaa kutsu kerrallaan, katso, mihin pitkäikäisiin olioihin kutsu koskee.
- Älä lähetä sitä, minkä vastapuoli heittää pois. Pikselit, jotka malli joka tapauksessa hylkäisi, veivät muistia joka kutsulla.
- Testaa muisti suoraan. Jokainen korjaus tuli testin kanssa, joka mittaa keon kasvua tai kuuntelijamäärää, joten regressio näkyy lukuna eikä kaatumisena.
Tämä on toinen agentin muistitarina lyhyen ajan sisällä; ensimmäinen oli edistymisnäyttö, joka lähetettiin uudelleen 41 000 kertaa. Jos haluat tietää, mitä agentti on ja miten se toimii, katso oppaamme tekoälyagenteista ja chatin dokumentaatio.