홈으로 돌아가기

무료 GPU에서의 MLOps: PDF 아카이브 처리

이 기사는 CV 기반 수의학 스크리닝과 러시아 제국 스타일 이미지 생성 두 실전 프로젝트를 다룹니다. 주요 초점은 제한된 자원 작업 기술 솔루션: ZeroGPU, PyMuPDF, 밝기 분산 필터링 및 강제 메모리 관리.

예산 없는 MLOps: 9 GB 혁명 전 잡지 처리 방법
Advertisement 728x90

엣지에서의 MLOps: 무료 GPU로 9GB의 혁명 이전 신문 아카이브 처리하기

긴밀한 제약 속에서 ML 솔루션을 개발하는 일은 단순한 학문적 실험이 아니라, 많은 엔지니어들의 일상적인 현실입니다. 이번 글에서는 하나의 스택 위에 구축된 두 가지 프로젝트의 기술적 구현 과정을 자세히 살펴봅니다: 수의 진료 선별을 위한 AI-Vet-Scanner과 제국풍 비주얼 생성을 위한 LoRA 모델입니다. 두 프로젝트 모두 유료 인프라 리소스를 전혀 사용하지 않고, 오직 Hugging Face Spaces의 무료 할당량과 T4 GPU 및 16GB RAM을 갖춘 클라우드 기반 Jupyter 환경만을 활용해 개발되었습니다.

ZeroGPU 아키텍처: 서버리스 추론

AI-Vet-Scanner은 소의 다중 클래스 이미지 분류 문제를 해결합니다. 가장 중요한 요구 사항은 최종 사용자에게 발생하는 모든 비용을 제로로 만드는 것입니다. 이를 달성하기 위해 우리는 전통적인 전용 GPU 기반 배포 방식을 포기하고, 대신 Hugging Face Spaces의 ZeroGPU 메커니즘을 활용했습니다: 모델은 단 한 번의 요청 처리 시점에만 메모리에 로드되고 이후 완전히 언로드됩니다. 이러한 작업은 다음과 같은 방법으로 이루어집니다:

  • transformersaccelerate를 사용하여 모델의 지연 로딩을 적용;
  • 추론 후 모델을 강제로 언로드(model.cpu(); del model);
  • torch.inference_mode()를 통해 중간 텐서 캐싱을 비활성화;
  • GPU가 사용 불가능할 경우 CPU 전용 백업 옵션 제공.

이러한 접근법은 피크 부하 상황에서도 장애에 대한 내성을 보장합니다—메모리에 고착될 수 있는 상태가 존재하지 않습니다. 따라서 수동 인스턴스 관리 없이도 추론이 무료로 그리고 확장 가능하게 유지됩니다.

Google AdInline article slot

9.24GB PDF 아카이브 처리: OOM과 디스크 공간 문제 극복

두 번째 프로젝트인 SDXL LoRA용 데이터셋 준비 과정에서는 근본적인 도전 과제가 있었습니다: ‘Vestnik Mody’(1885–1917) 저널의 9.24GB 스캔 아카이브는 20GB 디스크 공간과 16GB RAM 안에는 도저히 전체를 로드할 수 없었습니다. pdf2image + Poppler와 같은 표준 도구들은 모든 페이지를 RAM에 버퍼링하면서 즉시 OOM을 발생시킵니다.

우리는 이를 PyMuPDF(fitz) 기반의 최적화된 파이프라인으로 대체했습니다. 이 도구의 주요 장점은 다음과 같습니다:

  • 문서 전체를 메모리에 로드하지 않음;
  • 한 번에 정확히 한 페이지만 렌더링;
  • 압축 렌더링 지원(matrix=fitz.Matrix(2, 2)와 같이 2배 확대 시에도 RAM 내 중간 확장을 하지 않음);
  • PDF 레이어와 메타데이터에 대한 기본 지원.

분산 기반 필터링: 감지기가 아닌 수학

300여 페이지의 PDF 중 70%는 텍스트 열입니다. YOLO을 사용해 조각품을 감지하도록 학습시키는 것은 실용적이지 않습니다: 어노테이션이 너무 적고 오버헤드가 크기 때문입니다. 대신 우리는 OpenCV를 이용한 간단한 휴리스틱 필터를 적용했습니다:

Google AdInline article slot
import cv2
import numpy as np

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

밝기의 표준편차는 시각적 복잡성의 신뢰할 수 있는 지표로 작용합니다: 텍스트 페이지는 σ ≈ 15–30을 보이는 반면, 조각품과 삽화는 σ ≥ 50–90을 나타냅니다. 이 방법은 관련 샘플을 잃지 않으면서 처리 데이터 양을 73%나 줄였습니다.

메모리 관리: GC를 파이프라인의 일부로

필터링과 1024×1024(LANCZOS) 크기로 리사이징을 마친 후에는 강제 정리 작업을 수행합니다:

  • del cv_img, gray;
  • gc.collect();
  • torch.cuda.empty_cache()(CUDA 가속을 사용하는 경우);
  • JPEG 파일을 품질 92로 저장(PIL.Image.save(..., quality=92))하여 세부 묘사의 눈에 띄는 손실 없이 파일 크기를 최소화합니다.

이러한 절차는 임시 파일의 축적을 방지하고 긴 처리 사이클 동안 메모리 누수를 예방합니다. 만약 이러한 단계를 거치지 않는다면 20GB 디스크 공간은 약 12시간 만에 꽉 차게 될 것입니다.

Google AdInline article slot

무엇이 중요한가

  • ZeroGPU는 Hugging Face의 특정 기능이 아니라, 모델을 영구적으로 호스팅하는 대신 필요 시 동적으로 로드/언로드하는 패턴입니다.
  • PyMuPDF는 다중 페이지 PDF를 처리할 때 pdf2image보다 4.2배 더 빠르며, RAM 사용량도 87%나 적습니다.
  • 밝기 분산은 역사적 아카이브에서 삽화를 필터링하는 데 유효하고 빠른 지표이며, 학습이 필요 없고 CPU에서 실행됩니다.
  • 리소스 제한이 엄격한 경우에는 강제 gc.collect()empty_cache()를 모든 처리 단계에 포함해야 합니다.
  • 렌더링, 필터링, 리사이징, 저장 등 모든 작업은 중간 배열을 버퍼링하지 않고 엄격한 순서대로 수행되어야 합니다.

현재 단계에서 자동조종장치는 T4 GPU에서 시간당 약 1,400페이지를 처리하고 있습니다. 추출이 완료되면 ZIP 아카이브는 SDXL LoRA 학습 파이프라인에 입력되어 500회 이상의 에포크 동안 미세 조정을 진행할 예정입니다. 목표 프롬프트는 현대적 객체와 역사적 스타일을 의미적으로 결합하는 것으로, 예를 들어 “1890년대 조각품 스타일의 사이버 모노클”과 같은 표현입니다. 여기서 기술적 도전 과제는 생성 자체가 아니라 데이터셋의 순도와 대표성을 보장하는 것입니다. 특히 작은 타깃 클래스 볼륨을 다룰 때는 바로 이 단계가 최종 모델의 품질을 결정짓는 핵심 요소입니다.

이러한 프로젝트의 엔지니어링적 가치는 성능이 항상 예산에 의존하는 것이 아니라, 도구 선택의 정교함과 제약 조건에 대한 깊은 이해에 달려 있다는 점을 보여줍니다. ‘DIY’ MLOps는 타협이 아니라, 매번 gc.collect()를 호출하고 fitz.Matrix()의 한 줄을 작성할 때마다 측정 가능한 영향을 미치는 하나의 학문입니다.

— Editorial Team

Advertisement 728x90

다음 읽기