38.1 Helyi gép, távoli CPU és managed notebook

Adatkezelési határ: felhős vagy menedzselt notebook kiválasztása előtt ellenőrizd az adatok területi elhelyezését, a hozzáféréseket, a futtatási naplók megőrzését és a költségkorlátot; a távoli erőforrás használata önmagában nem teszi reprodukálhatóvá a munkát.

38.1.1 Cél és konkrét helyzet

A feladat ugyanaz a két Northstar-munkamenet, de eltérő erőforrásigénnyel. A kimenet nem két modell, hanem egy futtatásihely-térkép: honnan indul a kód, hol lakik az adat, hol fut a processz, és mi az ellenőrzés, amely igazolja, hogy a megfelelő gépen a megfelelő környezet dolgozott.

A) Fejlesztői kísérlet. Bemenet a lab orders.csv (2400 rendelés) és order_items.csv (4796 tétel), együttesen néhány megabájt. Megfigyelési egység a rendelés, illetve a belőle épített feature-sor. Cél: a Predikciós szerződés és hibateszt alfejezetben tanult predikciós szerződéssel logisztikus baseline és hibatábla. Induló becslés: a dekompresszált DataFrame 2400 × 16 módon is százezer cella alatt marad, a RAM-igény 100 MB alatt van; bármelyik modern laptop elég.

B) Nagy batch előállítás. Ugyanaz a séma, de 8 000 000 rendelés és 16 000 000 tétel, 20 GiB tömörített Parquet-ban. Cél: a teljes batch predikciója 2 órán belül, a predict_proba oszlop épsége mellett. Induló becslés a RAM-ra: 8 numerikus oszlop dominál, a dekompresszált tábla 4-5 GB; a feltöltési idő viszont veszélyes, ezért előbb számoljunk, mielőtt bármit mozgatunk.

38.1.2 Három futtatási hely és a fizikai határ

A laptop a tanulási főút gépe. Előnye, hogy a teljes környezet a mi felügyeletünk alatt áll, és a kis Northstar-adat hálózat nélkül is feldolgozható. Határa a RAM, a CPU-magok száma és a feltöltési sávszélesség.

A remote VM (távoli virtuális gép, SSH-val elérhető CPU-s szerver) ugyanazt a uv + Jupyter munkamenetet futtatja, mint a laptop, de az adat közelében. Ha a Parquet fájl már az adott régió object storage-ában (objektumtárolójában) van, a processz odaköltözik, és csak a kód utazik.

A managed notebook (menedzselt notebook: például AWS SageMaker, GCP Vertex AI Workbench, Azure ML vagy Databricks kategóriájába eső szolgáltatás) a notebook-szerver, a kernel és a storage üzemeltetését csomagban adja. Cserébe a konkrét menüút, ár és korlát szolgáltatónként változik; ezek aktuális részletét a sources.md kulcsaiból kiindulva, dátumozott dokumentációval kell ellenőrizni. Itt a kategóriaszintű döntési keretet tanuljuk, nem konzolkattintásokat.

A döntés magja a kód és az adat eltérő mozgatási költsége. A hálózati átviteli idő közelítő képlete:

tmove=sbytesbeff,t_{\text{move}} = \frac{s_{\text{bytes}}}{b_{\text{eff}}},

ahol sbytess_{\text{bytes}} a mozgatott bájtok száma (B), beffb_{\text{eff}} a két végpont közötti ténylegesen elérhető átviteli sebesség (B/s), és tmovet_{\text{move}} a becsült idő (s). Két gép között a lassabb irány számít: otthoni feltöltésnél jellemzően az upload, a managed notebook és a VM belső hálózatán a storage felőli letöltés.

Kézi kontroll a 20 GiB feltöltésére, beff=10MB/sb_{\text{eff}} = 10\ \text{MB/s} mellett:

20⋅230B=21474836480B,21474836480107≈2147s≈35,8perc.20 \cdot 2^{30}\ \text{B} = 21\,474\,836\,480\ \text{B}, \qquad \frac{21\,474\,836\,480}{10^7} \approx 2147\ \text{s} \approx 35{,}8\ \text{perc}.

Ugyanennyi idő alatt 10 MB forráskód és lock fájl 0,1 másodperc alatt másolható. Ezért mondjuk: a kódot költöztesd az adathoz, ne az adatot a kódhoz.

A másik fizikai határ a RAM. A Nagyobb mint RAM: előbb adatfolyam alfejezetben tanult szabály itt is érvényes: a tömörített Parquet mérete nem memóriaigény. A becslés oszloponként:

Rmem≈∑cnrows⋅wc,R_{\text{mem}} \approx \sum_c n_{\text{rows}} \cdot w_c,

ahol nrowsn_{\text{rows}} a sorok száma (darab), wcw_c a cc oszlop reprezentációs szélessége bájt/sor egységben, RmemR_{\text{mem}} pedig a dekompresszált reprezentáció becsült bájtmennyisége. A 8 millió soros batchre: tíz float64 oszlop 10⋅8⋅8000000=64010 \cdot 8 \cdot 8\,000\,000 = 640 MB, két int64 oszlop 128 MB, három string/kategória oszlop átlagosan 120 B/sorral 2,88 GB; ez nyersen 3,65 GB, pandas overheaddel és a transzformációk köztes másolataival 4,5-5,5 GB. Egy 8 GB-os managed notebook épp hogy elférhet, de a szűkösség hibakeresést nehezít; a 16-32 GB-os VM a biztonságosabb választás.

Három további réteg egészíti ki a döntést, ahogy a R-környezet és statisztikai munkafolyamat alfejezetben az R-környezetnél is rétegekre bontottunk:

38.1.3 Teljes minimális példa: két térkép, kézi ellenőrzéssel

Az alábbi munkamenet nem futtatott kimenet, a parancsok szintaktikailag jelölt, szemléltető lépések. A munkakönyvtár minden blokk előtt adott.

A feladat — helyi laptop. A lab gyökere ~/projects/northstar, Linux/macOS bash. A környezet feloldása és az ellenőrzés:

# ~/projects/northstar, Linux/macOS bash
uv sync --locked
uv run python quickcheck.py

A --locked kapcsoló a uv.lock és a pyproject.toml egyezését őrzi; a quickcheck.py a mellékelt adatszerződést ellenőrzi: orders.csv 2400 sor, order_items.csv 4796 sor, a manifest hash-értékei egyeznek. A processz fizikai helyét a következő Python-ellenőrzés rögzíti:

import getpass, platform, socket, sys
print({
    "host": socket.gethostname(),
    "user": getpass.getuser(),
    "platform": platform.platform(),
    "python": sys.executable,
})

Elméletileg várt, szemléltető kimenet: {"host": "dev-laptop", "user": "alma", "platform": "macOS-14.5-arm64", "python": "/Users/alma/projects/northstar/.venv/bin/python"}. A python útvonal mutatja, hogy a kernel tényleg a projekt .venv-jéből indult, nem a rendszer Pythonjából.

B feladat — távoli VM, az adat mellett. Az adat s3://northstar-batch/orders_8m.parquet formában az object storage-ban van, a VM ugyanabban a régióban fut. A kódot másoljuk, az adatot nem:

# ~/projects/northstar, Linux/macOS bash; a VM neve vm.internal
scp -r src pyproject.toml uv.lock remote-user@vm.internal:/srv/projects/northstar/
ssh remote-user@vm.internal
# a távoli munkamenetben, /srv/projects/northstar, Linux bash
uv sync --locked
sha256sum /srv/projects/northstar/src/northstar/predict.py

A tömörített Parquet hash-ét nem a VM-re másolás után ellenőrizzük — a fájl nem mozdult. A storage oldalán a manifest vagy az etag (a szolgáltató által adott objektum-ellenőrző jegy) rögzíti az eredetet; a VM a bucketből olvas, és a feldolgozás elején a sorok számával ellenőrzi az olvasás teljességét:

# szemléltető kód, nem futtatott kimenet
import pandas as pd
df = pd.read_parquet("orders_8m.parquet", columns=["order_id", "distance_km", "basket_minor"])
assert df["order_id"].nunique() == 8_000_000  # az adatszerződés szerinti egyedi kulcs

A managed notebook ugyanezt a logikát kapná: a projektet gitből klónozzuk, a kernelt a projekt uv-környezetéből regisztráljuk, az adatot a szolgáltató storage-ából olvassuk, a hitelesítő adatot a platform kulcstárolójából kérjük. A döntési lap ugyanaz, mint a VM-nél; csak a notebook-szerver üzemeltetése másik kézben van.

38.1.4 Eredmény értelmezése és kézi kontroll

A térkép akkor helyes, ha három kérdésre egyértelmű a válasz:

  1. Hol van az adat? A 20 GiB-os batch a bucketben marad; a fejlesztői CSV a laptopon.
  2. Hol fut a processz? A batch a VM-en, az adattal azonos régióban; a fejlesztői kísérlet a laptopon.
  3. Mi bizonyítja, hogy a megfelelő környezet futott? A sys.executable, a uv sync --locked sikere, a manifest hash és a feldolgozás eleji sor-/kulcsszám.

A hash-ellenőrzés toleranciája szigorú bitazonosság: egyetlen eltérő bájt is bukást jelent. A modellpredikciónál viszont a VIII. ellenőrző pont: átadható modellprojekt alfejezetben bevezetett szabály él: a lebegőpontos oszlopok egyezését relatív és abszolút tűréssel is ellenőrizzük, mert a seed azonos lehet, de a platformok közötti bitazonosság nem automatikus. Így a futtatásihely-választás nem csempész be rejtett kísérleti tényezőt: a split manifest, a seed és a küszöb a Küszöb, kalibráció és ritka esemény tanulsága szerint a futás előtt rögzített.

38.1.5 Feladatok

1. Értelmezés. A B feladat 8 000 000 rendeléssel és 20 GiB tömörített Parquet-val fut. A becsült dekompresszált tábla 4,5-5,5 GB. Melyik környezet indokolt, és mi az a fizikai körülmény, amelynél a döntés megfordulna?

2. Megvalósítás. Készíts telepítési és adatmozgatási térképet a B feladathoz. Tüntesd fel: mi mozog, mi marad, hol fut a processz, és mi az ellenőrző invariant. Kategóriaszintű, szolgáltatóspecifikus konzolút nélkül.

3. Hibadiagnózis. A csapat egy managed notebook platformon fejlesztett, ahol a notebook fut. Később valaki a laptopra klónozza a repót, és uv sync --locked parancsot ad: a hiba szerint uv.lock nem létezik. Hogyan lehet, hogy a notebook a platformon mégis futott? Mi hiányzott a reprodukálhatósági láncból?

4. Megváltozott feltétel. Az adat 80 GiB tömörítettre nőtt, a feltöltési sebesség 100 Mbps, a batch-keret továbbra is 2 óra. Számold újra a mozgatási időt, és dönts: adatmozgatás vagy az adat melletti feldolgozás? Nevezd meg a korlátot.

38.1.6 Megoldások és indoklás

1. megoldás. A 32 GB RAM-os távoli VM az elsődleges jelölt, mert a kód mozgatása olcsó, az adat viszont a storage-ban maradhat. A döntés akkor fordul meg, ha a dekompresszált munkahalmaz meghaladja a VM RAM-ját, vagy ha a bucket elérése lassabb, mint a munkakönyvtár lemezén tartott példány. Az ellenőrző invariant: a feldolgozott sorok száma 8_000_000, az egyedi rendeléskulcsok száma szintén 8_000_000, és a predikciós oszlop hossza mindkettővel egyezik.

2. megoldás. A térkép:

Elem Hely / mozgás Döntés
src, pyproject.toml, uv.lock laptop → VM mozog, scp vagy git
orders_8m.parquet object storage → VM olvasó nem mozog, a bucketben marad
VM processz ugyanaz a régió, mint a bucket itt fut a batch
manifest.json, split, modell VM → storage, verziózva visszamennek artifactként

A processz telepítése a VM-en uv sync --locked; az olvasás előtt a manifest/etag és a sorszám ellenőrzése zárja a láncot. A döntési lap minden lépésére igaz: az adat és a processz fizikai határa kimondva szerepel.

3. megoldás. A managed notebook nem feltétlenül a projekt uv.lock-jából építette a kernelt: a platform saját, előre összeállított image-e csomagokat garantált, és a notebook a szerveren, a csapat tárolójában futott. Attól, hogy a notebook outputot adott, a környezet még nem volt a projekt lockjával rögzítve. A hiányzó láncszem a verziózott uv.lock magában a repóban, és a kernel sys.executable-ellenőrzése. Ez pontosan a Globális és lokális magyarázat tanulsága átfordítva: az eszköz megléte nem bizonyíték; a lock, az image és a manifest együttese az.

4. megoldás. A 80 GiB =80⋅230=85899345920= 80 \cdot 2^{30} = 85\,899\,345\,920 B. A 100 Mbps feltöltés =12,5⋅106= 12{,}5 \cdot 10^6 B/s, így

8589934592012,5⋅106≈6872s≈1,91óra.\frac{85\,899\,345\,920}{12{,}5 \cdot 10^6} \approx 6872\ \text{s} \approx 1{,}91\ \text{óra}.

Ez önmagában majdnem felemészti a 2 órás keretet, és a dekompresszált becslés 4×4 \times aránnyal 320 GB, ami a 32 GB-os VM RAM-ját is meghaladja. A döntés tehát: nem mozgatjuk az adatot; a feldolgozás az adat mellett, partíciónkénti olvasással vagy lusta végrehajtással történik (Nagyobb mint RAM: előbb adatfolyam streaming, Dask task graph és partíció task graph). A szűk keresztmetszet itt a hálózat és a dekompresszált munkahalmaz, nem a CPU.

38.1.7 Gyakori tévedés és ellenpélda

A leggyakoribb tévedés: „a menedzselt notebook szolgáltatás gondoskodik a reprodukálhatóságról.” Ellenpélda: a csapat a platformon fejleszt, a notebook minden cellája lefut. Hat hónappal később a platform frissíti a kernel image-ét, és a pandas verzió megváltozik. A Kiválasztás és módosítás Copy-on-Write mellett alfejezetben tanult Copy-on-Write viselkedés más figyelmeztetést ad, egy láncolt értékadás kimenete akár meg is változhat, de a notebook outputja nem őrzi a kernel verzióját. Ha nincs uv.lock és manifest, senki nem tudja rekonstruálni, melyik környezet produkálta a régi számokat. A szolgáltatás a futás kényelmét adja; a reprodukálhatóság a projekt lockjának, image-ének és adathash-ének tulajdonsága.

38.1.8 Önellenőrzés

38.1.9 Rövid összefoglaló

A futtatási hely kiválasztása követelmény-alapú döntés, nem platform-preferencia. A kis Northstar fejlesztés a helyi laptop uv/Jupyter környezetében él; a nagy batch esetén a kód megy az adathoz. A 20 GiB feltöltése 10 MB/s mellett körülbelül 36 perc, míg a forráskód másodpercek alatt másolható. A managed notebook a kernel és a notebook-szerver üzemeltetését adja, de a reprodukálhatóságot a projekt lock, az image és a manifest biztosítja. A hitelesítő adatok rövid életűek, és nem kerülnek notebookba. Következő alkalmazás: a CPU, GPU és elosztott rendszer közötti döntés CPU, GPU és elosztott rendszer közötti döntés ugyanezzel a kerettel.