10.6.4 CI/CD 파이프라인 연동을 위한 데이터셋 직렬화 포맷(JSONL, Parquet) 최적화
엔터프라이즈 환경에서 시간의 흐름에 따라 수만에서 수십만 건의 거대한 스케일(Scale)로 불어난 골든 데이터셋(Golden Dataset)의 레코드들을 깃(Git) 저장소나 S3에 우겨넣어 관리할 때, 이를 순진하게 단일 통짜 JSON 파일(예: [{"id": 1}, {"id": 2}, ...])이나 거대한 단일 엑셀 CSV 파일 구조로 무식하게 직렬화(Serialization)하여 덤프(Dump) 저장하는 것은 CI/CD 자동화 파이프라인의 성능과 메모리를 치명적으로 갉아먹는 최악의 데이터 엔지니어링 안티 패턴(Anti-Pattern)이다.
통합된 단일 JSON 파일 구조의 치명적인 단점은, 테스트 파이프라인 워커(Worker) 노드가 그 안의 1,045번째 레코드 테스트 데이터 단 한 건만을 파싱(Parsing)하여 읽어내려 할 때도 배열 블록의 구문적 완결성을 검증하기 위해 수백 MB에 달하는 전체 JSON 파일을 서버의 메인 메모리(RAM)에 한꺼번에 몽땅 풀 로딩(Full Loading)해야 한다는 점이다. 이는 도커 격리 컨테이너 환경에서 잦은 OOM(Out of Memory) 프로세스 킬(Kill) 에러를 유발하는 1순위 주범이다. 더불어 CSV 포맷의 경우, 골든 데이터셋의 꽃이라 할 수 있는 RAG 문서 컨텍스트 배열 속성이나 다중 턴(Multi-turn) 대화 기록 같은 ’중첩되고 복잡한(Nested & Complex) JSON 배열 구조’의 데이터를 영속성 있게 담아내기에는 1차원적인 콤마(,) 구분자 방식이 기술적으로 너무나 부적합하고 파싱 에러를 남발한다.
따라서 깃 배포 빌드 시간과 테스트 실행 속도(Velocity) 타깃을 극대화하고 리소스를 최적화하기 위해, 오라클의 연료가 되는 골든 데이터셋은 파일 크기가 무한히 늘어나더라도 성능 저하가 없는 스트리밍(Streaming) I/O 읽기와 분산 병렬 처리(Parallel Processing) 아키텍처에 완벽하게 최적화된 엔터프라이즈 직렬화 파일 포맷으로 영구 관리되어야만 한다.
1. 경량 CI/CD 파이프라인 분산 처리를 위한 JSONL(JSON Lines) 스트리밍 포맷
가장 기본적으로 채택해야 하는 현대적인 표준은 JSONL(JSON Lines) 포맷이다. 이는 배열의 대괄호 [ ]로 전체를 감싸지 않고, 텍스트 파일의 ‘엔터키 한 줄(New Line \n)’ 단위가 각각 물리적으로 완벽히 독립적이고 구문이 완료된 유효한 단일 JSON 객체(Object) 해시맵으로 구성된 매우 우아한 스트리밍 텍스트 포맷이다.
// jsonl 포맷의 엣지 케이스 데이터셋
{"test_id": "T001", "intent": "refund", "prompt": "어제 산 거 환불해 줘", "expected_oracle": "refuse", "context_array": ["policy_doc_1"]}
{"test_id": "T002", "intent": "booking", "prompt": "내일 오후 예약할게", "expected_oracle": "approve", "context_array": ["schedule_db_4"]}
// ... (아무리 많은 라인이 추가되어도 파일 전체 구조가 깨지지 않음)
이 느슨하지만 강력한 포맷의 가장 압도적인 엔지니어링 장점은, 파일의 전체 바이트(Byte) 크기가 10GB에 달하더라도, 수십 개의 쿠버네티스 워커(Worker) 파드(Pod) 노드들이 전체 파일을 메모리에 로드할 필요 없이 각자 할당받은 오프셋(Offset) 구간부터 파일 디스크립터(File Descriptor) 스트리밍 방식으로 텍스트를 한 줄씩만 가볍게 읽어 들여 즉각 통신하고 오라클 채점을 병렬(Parallel)로 시작할 수 있다는 점이다. 또한 Git 형상 관리 툴 트리에서 코드 충돌(Merge Conflict)이 발생했을 때도 콤마 에러 없이 에러가 난 라인만 깔끔하게 짚어내고 병합하기 쉬워, 대부분의 경량 애자일 CI/CD 구조에서 오라클 골든 데이터의 디폴트 표준 규격으로 채택된다.
2. 대규모(Large-Scale) RAG 분산 테스트를 위한 Parquet(파케이) 컬럼 압축 최적화
조직이 성장함에 따라 데이터셋의 규모가 수만 건을 넘어 수백만 건 단위의 풀 맵 스트레스 테스트 셋(Full-map Stress Test Set)으로 팽창하고, 이 데이터 페이로드가 단순 텍스트를 넘어 멀티모달(이미지 픽셀 어레이, 음성 메타데이터 바이너리)이나 10,000토큰이 넘어가는 거대하고 뚱뚱한 RAG 컨텍스트 텍스트 스냅샷 원문 전체를 셀 안에 무겁게 포함하여 전체 파일 볼륨이 기가바이트(GB) 단위로 커질 경우, 무식한 텍스트 기반인 JSONL I/O 스캔 속도조차도 저장소 네트워크 대역폭(Bandwidth) 병목을 일으킬 수 있다. 이때 아키텍트는 아파치 파케이(Apache Parquet)와 같은 고도의 컬럼리스트 지향형(Columnar) 바이너리 엔진 압축 포맷으로 데이터를 직렬화 영구 백업(Serialization)하는 전략으로 스위치(Switch)해야 한다.
Parquet 아키텍처의 압도적인 런타임 이점은 CI/CD 파이프라인에서 앞서 언급한 ’조건부 카테고리 부분 릴리즈 테스트(Partial Testing)’를 수행할 때 그 찬란한 빛을 발한다.
예를 들어, 워커 노드가 이번 CI 빌드를 타면서 SQL 렌더링을 통해 “전체 100만 건 중, 도메인 카테고리 컬럼이 ’금융 결제’인 데이터만 딱 50개 샘플링으로 가져와서 빠르게 추론 테스트해라“라는 명령을 수행한다고 가정해 보자. JSONL 포맷의 경우 조건에 맞는 데이터를 찾기 위해 10GB 파일을 앞에서부터 첫 줄부터 무식하게 쭉 읽어가며 키 값을 비교해야(Full Table Scan) 한다.
반면 바이너리 포맷인 Parquet은 메타데이터(Metadata)와 함께 컬럼(Column) 단위로 데이터가 블록 단위 나뉘어 저장되고 관리되므로, 검색 조건과 전혀 무관하고 용량만 더럽게 많이 차지하는 ’거대한 RAG 스냅샷 프리텍스트 컬럼’이나 ’이미지 텐서 컬럼’은 메모리에 아예 올리지도 않고(디스크 I/O 절약), 오직 가벼운 문자열인 ‘도메인 카테고리 컬럼’ 딕셔너리만 초고속으로 메모리에 스캔 매핑(Mapping)하여 인덱스(Index)를 찾은 뒤, 조건에 완벽히 들어맞는 논리적 로우(Row) 블록만 핀셋으로 떼어 물리적으로 가져오는 **푸시다운(Predicate Pushdown) 프로젝션(Projection)**이라는 마법 같은 쿼리 최적화 기능을 완벽하게 지원한다.
이러한 눈에 보이지 않는 백엔드 직렬화 포맷 아키텍처 데이터 최적화는, 겉으로 드러나는 화려한 LLM의 성능 향상과는 거리가 멀어 보일 수 있다. 하지만 거시적으로 보면 천문학적인 API 워크로드 클라우드 비용 절감(API 호출 연산 및 병목 대기 시간 단축)과 파이프라인 빌드 속도 향상(수백 개의 테스트 쿠버네티스 컨테이너 팜으로의 완벽한 분산 병렬 처리)이라는 구식 소프트웨어 공학의 난제 두 가지를 동시에 우아하게 해결하여, 가장 민첩하고 폭력적인 속도의 애자일(Agile)한 AI 마이크로 서비스 개발을 안전하게 가능케 하는 엔터프라이즈 CI/CD 인프라스트럭처의 보이지 않는 핵심 심장 엔진이다.