Zpět na domů

MLOps na bezplatných GPU: zpracování archivů PDF

Článek rozebírá dva praktické projekty: veterinární screening na základě CV a generování obrázků ve stylu Ruské říše. Hlavní fokus — technická řešení pro práci s omezenými zdroji: ZeroGPU, PyMuPDF, filtrování podle disperze jasu a vynucená správa paměti.

MLOps bez rozpočtu: jak jsme zpracovali 9 GB předrevolučních časopisů
Advertisement 728x90

MLOps na hraně možností: jak zpracovat 9 GB archivů předrevoluční tisku na bezplatných GPU

AI-Vet-Scanner řeší problém multiklasifikační klasifikace obrázků domácích zvířat. Klíčový požadavek je nulové náklady pro konečného uživatele. Proto jsme se vzdali tradičního nasazení na stálém GPU. Místo toho jsme použili mechanismus ZeroGPU v Hugging Face Spaces: model se načte do paměti pouze na dobu zpracování jednoho dotazu a poté je kompletně uvolněn. Toto je dosaženo prostřednictvím:

  • Použití transformers + accelerate s lazy loadingem modelů;
  • Povinného vyložení modelu (model.cpu(); del model) po inferenci;
  • Vypnutí cachování meziproduktů tensorů prostřednictvím torch.inference_mode();
  • Rezervace fallbacku pouze na CPU v případě nedostupnosti GPU.

Tento přístup zaručuje odolnost proti selháním i při špičkových zátěžích — není žádné stav, který by mohl „uvíznout“ v paměti. Inferenční proces zůstává bezplatný a škálovatelný bez ručního řízení instancí.

Zpracování 9,24 GB PDF archivu: boj s OOM a disky

Druhý projekt — příprava datasetu pro SDXL LoRA — narazil na zásadní problém: 9,24 GB skenů časopisu „Vestnik Mody“ (1885–1917) nelze celé načíst do 20 GB úložného prostoru a 16 GB RAM. Standardní nástroje jako pdf2image + Poppler okamžitě vyvolají OOM kvůli buferizaci všech stran v RAM.

Google AdInline article slot

Nahradili jsme je optimalizovaným pipeline na bázi PyMuPDF (fitz). Jeho klíčové výhody:

  • Není nutné načítat dokument celý do paměti;
  • Renderování striktně po jedné straně;
  • Podpora komprimovaného renderování (například matrix=fitz.Matrix(2, 2) pro 2× zvětšení bez mezistupňového zvětšování v RAM);
  • Nativní podpora PDF vrstev a metadata.

Filtrace podle disperze: matematika místo detektoru

Ze 300+ stran PDF je 70% textových kolonek. Učit YOLO pro detekci gravur je neopodstatněné: příliš málo anotací, vysoký overhead. Použili jsme rychlý heuristický filtr na základě OpenCV:

def is_image_page(cv_img, min_variance=45):
    gray = cv2.cvtColor(cv_img, cv2.COLOR_RGB2GRAY)
    return gray.std() > min_variance

Standardní odchylka jasu slouží jako spolehlivý indikátor vizuální složitosti: textové stránky mají σ ≈ 15–30, gravury a ilustrace – σ ≥ 50–90. Tento přístup snížil objem zpracovávaných dat o 73% bez ztráty relevantních vzorků.

Google AdInline article slot

Správa paměti: GC jako součást pipeline

Po filtraci a resizování na 1024×1024 (LANCZOS) provádíme povinné vyčištění:

  • del cv_img, gray;
  • gc.collect();
  • torch.cuda.empty_cache() (pro případy, kdy se používá CUDA-zrychlení);
  • Ukládání JPEG s kvalitou 92 (PIL.Image.save(..., quality=92)), aby se minimalizovala velikost bez znatelné ztráty detailů.

Toto zabraňuje hromadění dočasných souborů a úniků paměti při dlouhých cyklech zpracování. Bez tohoto kroku by se 20 GB disku zaplnilo za ~12 hodin.

Co je důležité

  • ZeroGPU není funkce Hugging Face, ale vzor: dynamické načítání/vyložení modelů v momentě dotazu, nikoli trvalé hostování.
  • PyMuPDF je 4,2× rychlejší než pdf2image při zpracování vícestránkových PDF a spotřebuje o 87% méně RAM.
  • Disperze jasu je validní a rychlý znak pro filtraci ilustrací v historických archivech; nevyžaduje učení a funguje na CPU.
  • Povinné gc.collect() a empty_cache() by měly být součástí každého kroku zpracování, pokud jsou limity zdrojů přísné.
  • Všechny operace (render, filtr, resize, save) se provádějí ve striktním pořadí bez buferizace meziproduktů.

V současné fázi autopilot zpracovává ~1400 stran za hodinu na T4 GPU. Po dokončení extrakce bude ZIP archiv předán do tréninkového pipeline SDXL LoRA s fine-tuningem na 500 epoch. Cílový prompt zahrnuje semantičeské smíchání moderních objektů a historických stylů — například „kybernetický monokl ve stylu gravury z 1890. let“. Technická složitost zde není v generaci, ale v zajištění čistoty a reprezentativnosti datasetu. Právě tento krok určuje kvalitu finálního modelu — zejména při malých objemech cílových klasů.

Google AdInline article slot

Inženýrská hodnota takových projektů spočívá v demonstrování, že výkon nezávisí vždy na rozpočtu, ale na přesnosti výběru nástrojů a hloubce porozumění limitacím. MLOps „na kolena“ není kompromis, ale disciplína, kde každý volání gc.collect() a každá řádka v fitz.Matrix() má měřitelný efekt.

— Editorial Team

Advertisement 728x90

Číst dál