PDF RAG 파싱, 표만 나오면 답이 깨지는 이유

PDF RAG 파싱

결론부터 말씀드리면, 표가 든 PDF에서 RAG 답변이 틀어지는 원인은 대부분 파싱 단계에 있습니다. 텍스트 추출 라이브러리가 PDF 안의 글자를 화면에 보이는 순서가 아니라 문서 내부에 저장된 좌표 순서대로 읽어오기 때문에, 표의 행과 열이 뒤섞인 채로 임베딩되는 것입니다. PDF RAG 파싱을 할 때 표 추출과 레이아웃 순서를 얼마나 보존하느냐가 답변 품질을 가르는 핵심 변수입니다.

표가 많은 PDF를 그대로 넣으면 답이 흔들리는 이유

PyPDF, pdfminer 계열 라이브러리는 PDF 콘텐츠 스트림에 기록된 텍스트 객체 순서대로 문자열을 뽑아냅니다. 이 순서는 사람이 눈으로 읽는 순서와 다를 때가 많습니다. 특히 표는 셀마다 위치가 절대좌표로 지정되어 있어서, 왼쪽 열을 먼저 읽고 오른쪽 열을 나중에 읽는 식으로 뒤섞여 추출되는 경우가 흔합니다.

이렇게 뒤섞인 텍스트가 청킹(chunking) 단계로 넘어가면 문제가 커집니다. 표 중간에서 청크가 잘리면 헤더 행(항목명)과 데이터 행이 서로 다른 청크에 들어가버립니다. 검색 단계에서 데이터 행만 담긴 청크가 뽑히면, LLM은 그 숫자가 어떤 항목의 값인지 알 방법이 없어 엉뚱한 답을 만들어냅니다. 위키백과 PDF 문서에도 설명되어 있듯이 PDF는 애초에 ‘보이는 대로 그리기 위한’ 페이지 기술 형식이라, 표라는 논리 구조 자체를 파일 안에 저장하지 않습니다. 겉보기엔 표지만 파서 입장에서는 그냥 흩어진 텍스트 조각의 모음인 셈입니다.

레이아웃 보존 파싱, 기존 방식과 뭐가 다른가요

레이아웃 보존 파싱은 텍스트를 뽑기 전에 문서 이미지를 먼저 분석합니다. 레이아웃 감지 모델이 페이지를 스캔해서 제목, 본문 단락, 표, 머리글·바닥글 영역을 박스로 나누고, 사람이 읽는 순서대로 영역을 정렬합니다. 표로 인식된 영역은 별도의 표 구조 인식 모델로 넘겨서 행과 열 관계를 다시 계산합니다.

PDF 문서에서 표 데이터를 추출하는 파싱 과정

IBM 리서치가 공개한 Docling이 대표적입니다. Docling은 레이아웃 감지 모델과 함께 TableFormer라는 표 구조 인식 모델을 내부적으로 사용해서, 병합된 셀이나 다단 헤더가 있는 표도 격자 구조로 복원한 뒤 마크다운 파이프 테이블이나 HTML로 내보냅니다. 이 구조는 Docling 기술 보고서에 처리 파이프라인이 자세히 설명되어 있습니다. 결과적으로 청킹 시점에 표 하나가 통째로 한 청크 안에 들어갈 확률이 높아지고, 행과 열의 대응 관계도 텍스트로 남아 LLM이 참조하기 쉬워집니다.

Docling으로 표 구조 살려서 마크다운 뽑아보기

간단한 사용 예시로 어떻게 다른지 확인해 볼 수 있습니다. 아래 코드는 PDF 한 장을 변환해 마크다운으로 출력하는 최소 예시입니다.

from docling.document_converter import DocumentConverter

converter = DocumentConverter()
result = converter.convert("quarterly_report.pdf")

print(result.document.export_to_markdown())

이 코드를 표가 포함된 보고서 PDF에 실행하면, 텍스트만 늘어놓는 대신 아래와 같은 형태의 결과를 얻을 수 있습니다.

## 분기별 매출 현황

| 항목   | 1분기 | 2분기 |
| ------ | ----- | ----- |
| 매출   | 120   | 135   |
| 영업이익 | 18    | 21    |

일반 텍스트 추출기로 같은 페이지를 뽑으면 “매출 항목 1분기 2분기 120 영업이익 135 18 21″처럼 항목명과 숫자의 대응이 끊긴 채로 나오는 경우가 많습니다. 표 형태 그대로 마크다운 파이프 테이블로 남아 있으면, 청크 안에서 헤더와 값이 함께 붙어 있으니 검색 결과로 뽑혔을 때도 의미가 살아 있습니다.

PDF RAG 파싱 도구별 표 추출 방식 비교

RAG 파이프라인에서 구조화된 문서 데이터를 처리하는 AI 시스템

같은 목적이라도 도구마다 레이아웃을 다루는 방식과 표 추출 결과물 형태가 다릅니다. RAG 파이프라인에 붙이기 전에 이 차이를 확인해 두는 편이 좋습니다.

도구 레이아웃 처리 방식 표 추출 결과 비고
Docling 레이아웃 감지 + TableFormer 구조 인식 마크다운/HTML 표 오픈소스, 로컬 실행, 첫 실행 시 모델 다운로드 필요
unstructured (hi_res) 레이아웃 모델로 요소 분류 Table 요소의 text_as_html 속성 오픈소스, GPU 없이도 동작하나 속도는 느림
PyMuPDF4LLM 페이지 내 표 탐지(find_tables) 결합 마크다운 파이프 테이블 설치가 가볍고 빠르지만 복잡한 병합 셀엔 약함
LlamaParse 클라우드 레이아웃 파싱 서비스 마크다운 표 페이지당 과금되는 유료 API, 별도 인프라 불필요

표에서 보듯 로컬에서 무료로 쓰고 싶다면 Docling이나 unstructured 쪽이 자연스러운 선택이고, 인프라를 두기 어려운 상황이면 LlamaParse 같은 서비스형 옵션도 검토할 만합니다.

레이아웃을 살려도 표가 깨지는 경우와 다음 단계

레이아웃 보존 파싱이 만능은 아닙니다. 스캔본처럼 이미지로만 존재하는 PDF는 OCR을 함께 돌려야 하는데, 표 선이 흐릿하거나 회전되어 있으면 구조 인식 모델도 셀 경계를 잘못 잡습니다. 셀이 여러 줄로 병합된 재무제표나 중첩 헤더가 있는 표는 여전히 사람이 결과를 한 번 검수해야 안전합니다.

속도와 자원 문제도 있습니다. 레이아웃 모델과 표 구조 모델을 함께 돌리는 만큼, 페이지 수가 많은 문서는 일반 텍스트 추출 대비 처리 시간이 눈에 띄게 늘어납니다. 실시간으로 업로드된 PDF를 바로 답변에 써야 하는 서비스라면 이 지연 시간을 감안해서 비동기 처리 구조로 설계하는 편이 낫습니다.

지금 운영 중인 RAG 파이프라인에서 표가 섞인 PDF로 답변이 자주 틀린다면, 우선 문제되는 문서 몇 개를 Docling이나 unstructured로 다시 파싱해 마크다운 표가 온전히 나오는지부터 확인해 보시길 권합니다. 그 다음 청킹 로직을 표 단위로 쪼개지 않도록 조정하면, 같은 임베딩 모델과 같은 LLM을 쓰더라도 답변 정확도가 눈에 띄게 달라집니다.

LLM 테스트 작성법, 매번 다른 출력도 검증할 수 있습니다

Leave a Comment