Blog

Pad memorije skriven u oznaci napretka

Jedne večeri krajem septembra AI agent u radnom prostoru jednog korisnika srušio se zbog greške out-of-memory usred izvršavanja. Očigledni osumnjičeni, previše pod-agenata koji rade istovremeno ili kontekst koji je previše narastao, bili su pogrešni. Pravi uzrok bila je oznaka statusa: dok je model streamovao veliku shell komandu po nekoliko karaktera, mi smo na svaki dio ponovo slali cijelu dosad napisanu komandu kao oznaku napretka. Jedna komanda od 124 KB pretvorila se u oko 41.000 događaja i otprilike 690 MB stringova u redu čekanja.

Kako agent šalje svoj rad

Kada gradite na Mythexu, agent radi unutar privatnog cloud sandboxa vašeg projekta. Dok model piše, njegov izlaz se streamuje nazad u vaš pregledač: tekst se pojavljuje riječ po riječ, a kada pokrene alat, na primjer shell komandu koja piše fajl, vidite oznaku za to kako se uživo ažurira, pa znate šta radi.

Model streamuje u malim dijelovima. Sa modelom koji smo koristili, ti dijelovi su često bili dugi samo tri karaktera.

Prve hipoteze bile su pogrešne

Srušenje je izgledalo kao problem skaliranja, pa smo tu i počeli.

  • Paralelni pod-agenti? Izvršavanje je koristilo samo dva, svaki s oko 1,5 MB stanja. Nedovoljno.
  • Zadržani tragovi? Naše praćenje držalo je stablo izvršavanja u memoriji, ali ono nije bilo blizu veličine heapa u trenutku pada.

Obje priče bile su uvjerljive i obje su bile jeftine za vjerovanje. Nijedna nije reprodukovala pad. Lekcija koju stalno ponovo učimo: hipoteza nije uzrok dok ne reprodukuje grešku.

Reprodukcija za pravo

Napravili smo privremeni sandbox sa istim limitima memorije kao produkcija i lažni model koji je streamovao veliki fajl u realističnim dijelovima od tri karaktera. Takođe smo usporili čitača na drugom kraju socketa, kao pravu mrežu.

To je uspjelo. Heap je rastao i proces je umro s istom greškom.

Mehanizam je bio jednostavan kada smo mogli da ga gledamo. Dok je model pisao veliku komandu, u ovom slučaju heredoc koji je upisao fajl od 124 KB, naš kod za streaming ažurirao je oznaku alata na svakom dijelu. Oznaka nije bila novih tri karaktera; bila je cijela dosad napisana komanda. Tako su događaji rasli: 3 karaktera, zatim 6, zatim 9, … sve do 124 KB, otprilike 41.000 puta. Socket ih nije mogao slati brzo koliko su nastajali, pa su se nagomilali u njegovom baferu za pisanje kao stringovi, oko 690 MB.

Popravka

  • Ograničite oznaku. Oznaka statusa treba samo da kaže šta se dešava. Sada je ograničena na 200 karaktera, a učestalost ponovnog skeniranja djelimične komande je ograničena.
  • Zaustavite kvadratno nadovezivanje. Spajanje streamovanih dijelova ponovljenim nadovezivanjem stringova je O(n²) za velike izlaze. Prešli smo na pristup zasnovan na chunkovima koji dodaje u linearnom vremenu.

Zatim smo potražili bilo šta drugo što bi moglo rasti bez ograničenja pod naletom izlaza, i ograničili to:

  • Izlaz naredbi uživo prikazan u chatu se grupiše i čuva se samo posljednjih 8.000 karaktera.
  • Pojedinačne linije događaja su ograničene na 4 MB.
  • Bafer za ponovno puštanje koji pregledač koristi da se sustigne nakon ponovnog povezivanja ograničen je na 8 MB po projektu.
  • Stari checkpointi se čiste dok izvršavanje turn-a napreduje, zadržavajući najnovije stanje i sidra koja su potrebna ranijim turn-ovima.

Testiranje naleta iskreno

Dvije stvari su ovo učinile težim za testiranje nego što treba:

  1. Pravi modeli ne sarađuju. Zamolite model da ispiše ogroman fajl i obično će odbiti, sažeti ili napisati razumnije. Da biste testirali nalete, treba vam skriptovani model koji radi tačno ono što mu kažete, kroz pravi kod agenta.
  2. Skripte moraju da se ponašaju kao modeli. Naš prvi skriptovani model koristio je isti ID odgovora pri svakom odgovoru, pa je okvir agenta svaki odgovor tretirao kao zamjenu prethodnog i prekidao turn-ove prerano. Izgledalo je kao bug osvježavanja UI-ja. Nije bio. Bio je to test harness koji nas je lagao. Takođe smo morali da u skripti provedemo stvarni limit konteksta modela, inače su brojevi memorije bili nerealni.

Šta smo iz toga izvukli

  • Streaming UI-ji umnožavaju male greške. Sve što šaljete „po dijelu“ šalje se desetine hiljada puta. Šaljite delte ili ograničite teret.
  • Ograničite svaki bafer koji prelazi spori spoj. Socketi, logovi za ponovno puštanje i checkpointi svi trebaju plafon.
  • Reprodukujte prije popravke. Prva dva objašnjenja zvučala su tačno i bila su pogrešna.

Ako ste nedavno u Mythex chatu vidjeli vrlo dug fajl koji se pojavio bez zastoja agenta, ovo je dio razloga.

Mythex · Pricing · Izradite bilo šta uz AI · Šabloni za web stranice i aplikacije · Mythex u poređenju · Rječnik izrade aplikacija uz AI · Besplatni alati za izradu aplikacija uz AI · English

English አማርኛ العربية Български বাংলা Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)