PDF는 읽기 순서가 없다: 두 단(column) 구조의 논문을 줄 단위로 재구성하는 방법
요약
PDF는 단락, 열, 읽기 순서가 아닌 위치 지정된 글리프의 목록일 뿐이며, 두 단 구조 논문에서 텍스트 추출 시 내용이 뒤섞이는 문제가 발생합니다. 이 문제를 해결하기 위해 바운딩 박스를 이용해 페이지를 여러 개의 열로 인식하고, 각 열 내 스팬을 y좌표 및 x좌표 순으로 재정렬하는 기하학적 접근 방식을 제시했습니다.
핵심 포인트
- PDF는 읽기 순서가 없으며, 글리프의 위치 목록일 뿐이다.
- 두 단 구조 논문은 좌우 열이 나란히 추출되어 텍스트가 뒤섞인다.
- 해결책은 기하학적 접근으로, 바운딩 박스를 이용해 페이지를 열로 분할해야 한다.
- 재정렬된 텍스트에 대해 단락 감지 및 제목 휴리스틱스 적용이 필요하다.
한 사용자의 RAG 파이프라인이 ML 논문에 대한 질문에 답변을 시작했는데, 그 답변들이 관련 없는 두 섹션을 뒤섞어 붙인 형태였습니다. 저는 출처를 확인했습니다: 전형적인 두 단(two-column) 구조의 학회 논문이었습니다. 추출된 Markdown은 마치 누군가 모든 다른 줄들을 섞어 놓은 것처럼 보였는데, 실제로 그랬습니다. 문장 중간에 열(column)을 번갈아 가며 배치했기 때문입니다.
그때까지 제가 완전히 이해하지 못했던 것은 다음과 같습니다: PDF는 단락(paragraph), 열(column), 그리고 읽기 순서가 없습니다. 그것은 위치가 지정된 글리프(glyph)들의 목록일 뿐입니다. 추출 순서는 콘텐츠 스트림에 텍스트 연산자(text operators)를 작성한 생산자가 어떤 순서로 기록했는지에 달려 있습니다. 그리고 수많은 도구들이 전체 페이지 너비에 걸쳐 기준선 y-좌표(baseline y-coordinate)별로 정렬된 스팬(span)들을 방출합니다. 두 단 구조의 경우, 이는 왼쪽 열의 37번째 줄과 오른쪽 열의 37번째 줄이 나란히 나오는 것을 의미합니다.
해결책은 더 좋은 파서 라이브러리가 아니라 기하학적 접근 방식이었습니다:
- 모든 바운딩 박스(bounding box)와 함께 텍스트 스팬을 수집합니다.
- 페이지마다 지속적으로 존재하는 수직 여백(vertical gutter), 즉 어떤 스팬도 놓이지 않는 x-범위를 찾습니다. 페이지의 약 80%를 차지하는 것을 발견했다면? 해당 페이지를 두 개의 열로 간주합니다.
- 각 열 영역 내의 스팬들을 y좌표, 그리고 x좌표 순으로 정렬한 다음; 전체 너비를 차지하는 스팬들(제목, 양쪽 열을 아우르는 초록 등)은 열이 시작되기 전에 다시 배치합니다.
- 그 후에야 비로소 정상적이고 순서가 지정된 텍스트에 대해 단락 감지 및 제목 휴리스틱스(heading heuristics)를 실행합니다.
저는 스스로에게 정직하기 위해 작은 벤치마크를 만들었습니다: 두 단 논문 30개, 그 답변이 특정 열에 존재하는 질문 100개. 수정 전에는 검색 결과가 10번 중 약 4번 잘못된 청크(chunk)를 가져왔습니다—모든 단어는 존재했지만, 마치 색종이 조각처럼 뒤섞여 있었습니다. 수정을 거친 후에는 10번 중 1번에 가까워졌고, 남아있는 실패 사례들은 대부분 가로 방향으로 회전된 표들인데, 이는 별개의 문제입니다.
같은 교훈은 각주(footnotes), 사이드바(sidebars), 그리고 인용구(pull quotes)에도 적용됩니다. 만약 추출된 텍스트가 의미가 통하지 않는 유창한 영어라면, 내용이 아니라 순서에 문제가 있다고 의심해야 합니다.
저는 결국 레이아웃 인지 재정렬 기능을 제가 운영하는 PDF-to-Markdown API(https://x402.freeq.one/tools/pdf_to_markdown.html)에 패키징했습니다. 주된 이유는 저의 자체 데이터 수집 작업(ingestion jobs)이 벡터 스토어에 쓰레기 같은 데이터를 계속 흘려보내는 것을 막기 위해서입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기