3P by GN⁺ 3일전 | ★ favorite | 댓글 1개
  • PDF 파일에서 텍스트 추출은 예상보다 훨씬 어렵고, PDF는 본질적으로 그래픽 기반 파일 포맷
  • PDF 안의 글리프 위치 정보만 존재하고 의미론적 신호는 거의 없어 텍스트의 식별과 재구성이 까다로운 상황임
  • 검색 엔진에서는 HTML 형태의 깔끔한 입력을 요구하지만, 기존 오픈소스 도구들은 제목이나 문단 등 구조적 정보 추출에 한계가 있음
  • 머신러닝 기반 비전 방식이 가장 정확하지만, 리소스와 성능 문제로 대규모 적용에 어려움이 있음
  • 주요 개선책으로는 폰트 크기와 통계 기반의 제목·문단 식별 알고리듬을 도입해 추출 정확성을 높임

PDF에서 텍스트 추출의 도전

  • 최신 검색 엔진은 PDF 파일 포맷을 인덱싱하는 기능을 갖추게 되었음
  • PDF에서 정보 추출은 쉽지 않은 문제로, PDF가 원래 텍스트 포맷이 아닌 그래픽 포맷임에 기인함
  • 실제 텍스트 대신 글리프가 좌표에 배치된 형태라서, 회전, 겹침, 순서 뒤섞임, 의미 정보 결여 등이 발생함
  • 우리가 보통 생각하는 텍스트로서의 정보가 파일 내에는 직접 존재하지 않음
  • PDF 뷰어에서 ctrl+f로 텍스트 검색이 가능하다는 것은 사실 놀라운 일임

검색 엔진의 요구와 기본 접근법의 한계

  • 검색 엔진이 가장 선호하는 입력은 깨끗한 HTML 형식
  • 최신 머신러닝 기반 컴퓨터 비전 모델이 가장 좋은 성능을 보이지만,
    • 대용량(수백 GB) PDF 파일을 GPU 없이 한 서버에서 처리하는 것은 비효율적
  • 다행히 이 분야가 완전히 미지의 영역은 아니어서,
    • PDFBox의 PDFTextStripper 클래스를 활용해 출발점으로 사용 가능함
    • 하지만 제목 등 의미론적 구조 파악이 거의 되지 않음—문자열만 추출됨

제목 식별 알고리듬

제목 식별의 기본 원리

  • 보통 제목은 세미볼드 혹은 더 굵직한 글씨가 고립되어 있음을 활용할 수 있음
    • 굵게 처리되지 않은 제목도 흔해, 이 방법만으론 한계가 있음
  • 많은 경우, 폰트 크기가 제목을 구분하는 기준이 됨
    • 그러나 폰트 크기는 문서마다 전혀 다르고, 글로벌 임계치 사용이 불가능

폰트 크기 통계 활용

  • 각 페이지에는 대체로 지배적인 폰트 크기(본문) 가 존재함
  • 1페이지(표지)는 서술적 내용 및 저자 정보가 있어 폰트 크기 분포가 다름
  • 페이지별 폰트 크기 분포가 다르므로, 문서 전체가 아니라 페이지 단위 통계 활용이 효과적임
  • 각 페이지의 중앙값 폰트 크기에 20% 가량 상향을 적용해 제목을 꽤 정확히 식별 가능함

여러 줄 제목의 병합 문제

  • 스타일적 이유로 제목이 여러 줄로 나뉘기도 함
    • 제목 병합 시점 판단은 간단하지 않으며, 두 줄 이상의 제목이나 저자명, 별도의 강조 텍스트가 혼재할 수 있음
  • 병합 규칙:
    • 동일한 폰트 크기와 굵기를 갖는 연속 줄을 합치는 것이 꽤 잘 동작
    • 하지만 예외 상황 많이 존재—무분별한 병합은 엉뚱한 결과를 초래할 수 있음

문단 식별 개선

  • PDFTextStripper는 줄 간격 및 들여쓰기에 기반해 문단을 식별함
    • 라인별 구분 임계치를 고정 값으로 사용하므로, 문서마다 다른 줄 간격 적용에는 한계가 있음
    • 특히 논문 초안/사전출판본에서는 1.5~2배 줄 간격도 흔함
  • 임계값이 너무 크면, 제목이 본문에 포함되는 오류가 발생함

통계 기반 문단 구분

  • 폰트 크기처럼, 라인 간격에 대해서도 통계처리를 적용
    • 줄 사이 거리의 중간값(중앙값)을 활용해, 어떤 줄 간격이든 견고한 문단 구분이 가능함

결론

  • PDF에서 텍스트를 추출하는 것은 근본적으로 완벽하지 못할 수밖에 없음
    • PDF 포맷 자체가 그 용도에 맞게 설계되지 않았기 때문임
  • 실제 구현에서는 타협이 필수이고, “충분히 괜찮은” 정도의 결과를 얻는 전략이 중요함
  • 검색 엔진은 제목, 요약, 주요 구조적 단서 등 의미 있는 신호 추출에 집중함이 효율적임

참고 샘플 텍스트

  • Can Education be Standardized? Evidence from Kenya (2022) - Working Paper
    : Guthrie Gray-Lobe, Anthony Keats, Michael Kremer, Isaac Mbiti, Owen W. Ozier
  • The theory of ideas and Plato’s philosophy of mathematics (2019)
    : Dembiński, B.
  • The role of phronesis in Knowledge-Based Economy (2024)
    : Anna Ceglarska, Cymbranowicz Katarzyna
Hacker News 의견
  • 인생에서 뭔가 새롭고 흥미롭다고 생각하다가, 예전에 여러 달 또는 몇 년간 전문가가 되었던 기억이 희미하게 떠오르는 경험을 해본 적 있음. 심지어 아주 멋진 일들을 했던 순간조차 머릿속에서 다 사라진 것 같아 다시 처음부터 시작하는 느낌을 받게 됨. 6~7년 전쯤 PDF와 OCR로 굉장한 무언가를 했었다는 막연한 기억이 있음. 구글에 검색해보니 “tesseract”라는 이름이 익숙하게 들림

    • 2006년경 초창기 해킹이 가능한 e-reader인 iRex에서 다중 칼럼 과학 논문의 텍스트를 복사할 수 없는 문제에 짜증이 남. 당시 pdf 뷰어에 poppler가 사용되어서, 다중 칼럼 문서에서 읽기 순서를 추론하도록 poppler를 수정함. 이를 위해 tesseract의 저자인 Thomas Breuel의 OCR 알고리즘을 참고함. 이것은 일종의 휴리스틱 해킹이었고 접근성 API와 잘 맞지 않았음. 멀티칼럼 선택 기능이 도입되었으나 유지보수자 설득에 어려움을 겪었음. 어쨌든 이렇게 kpdf에 멀티칼럼 선택 기능이 생김. 최근에는 이런 용도엔 tesseract를 직접 쓰는 게 훨씬 합리적이라는 생각임

    • PDF라는 포맷 때문에 낭비된 인류 수십 년의 시간을 되돌릴 수 없음. 이 미친 현상은 언제 끝날지 궁금함

    • Tesseract가 한동안 최고의 오픈소스 OCR이었음. 하지만 요즘은 정확도와 GPU 가속 면에서 docTR이 더 우수하다고 생각함. docTR은 다양한 텍스트 감지 및 인식 모델을 조합할 수 있는 파이프라인 구조임. PyTorch나 TensorFlow에서 학습 및 튜닝도 가능해 특정 도메인에 훨씬 잘 맞는 성능을 끌어낼 수 있음

    • 인생이란 이런 것임. 프로젝트를 끝낼 때마다 “이제 나는 이 분야의 전문가가 되었음. 하지만 아마도 다시는 이걸 안 하겠지”라고 생각하게 됨. 왜냐하면 다음에는 완전히 새로운 주제를 다시 처음부터 시작하게 되기 때문임

    • 얼마 전 누군가 C++에 대해 질문했을 때 “진지하게 일한 적 없음”이라고 말했었음. 그러다가 약 20년 전에 Borland C++로 만든 프라이빗 인스턴트 메신저의 클라이언트 코드를 썼고, 수천 명이 사용했었다는 걸 뒤늦게 기억함. 이런 일이 종종 일어남

    • 네 머릿속을 다 알 순 없지만, 아마 정말로 tesseract였던 것 같음. 나도 비슷한 경험이 있는데, 내 경우는 12년 전쯤임

    • HQ가 유행할 때 tesseract로 자동 HQ 퀴즈 풀이기를 만든 적 있음. 앱의 질문 화면을 스크린샷으로 찍고 작은 API로 전송한 뒤, 구글에서 질문 문구를 검색해 각 답변이 나타난 횟수를 집계해서 확률별로 랭킹하는 식이었음. 정확하진 않고 단순한 방식이었지만 만드는 재미는 컸음

    • 바람에 잎이 날아가면 그냥 다른 잎을 찾는 불개미와 다를 바 없는 현상임

    • 7~8년 전 20대 때였던 일이라 아직도 기억이 생생함. 혹시 나이 차이가 좀 있는 것인지 궁금함. 아니면 건강 검진도 해보는 것 추천임

  • 브라우저 개발자 도구(‘요소 검사’)처럼 PDF의 컨텐츠 스트림—텍스트를 둘러싸는 BT…ET, 폰트와 좌표를 지정하는 각종 오퍼레이터 등—을 소스 수준으로 “보고”, 렌더링 결과와 나란히 비교·분석할 수 있는 툴이 있었으면 좋겠다는 바람이 있음. 현재 비전 모델이 PDF를 “보듯이” 처리하여 텍스트를 읽는 흐름과는 다르지만, 진짜로 PDF 내부에 무슨 정보가 포함되어 있는지 깊이 이해하고 싶다는 욕구임. 일부 툴이 있긴 하지만 오브젝트 단위까지만 보여주고, 컨텐츠 스트림 내부까지 파고들진 않음. 예시 PDF의 실제 스트림 소스와 렌더링 결과를 HTML처럼 나란히 비교·분석하면서 어떤 부분이 어떤 식으로 표현되는지 확인할 수 있는 환경을 원함

    • Mozilla의 PDF.js를 사용해 PDF를 DOM으로 렌더링하면 거의 비슷한 체험을 할 수 있을 것으로 생각함. 예컨대 Tj나 TJ와 같은 연산자가 각각 <span>이나 그들의 집합으로 변환됨. 아마 원본 문서에 충실할 필요가 있어서 그런 듯함

    • cpdf 툴을 사용해보길 권함(직접 만듦). cpdf의 -output-json 및 -output-json-parse-content-streams 옵션으로 PDF를 JSON으로 변환해 각종 실험이 가능함. 역으로 JSON에서 PDF로 되돌리는 것도 가능함. 다만 실시간 상호작용은 제공하지 않음

    • 무료 또는 오픈소스 툴을 찾고 있는 것 같지만, 예전 Acrobat Pro를 쓸 때 거의 비슷한 기능을 제공했었음. 다만 페이지를 검사하기보단 콘텐츠 트리를 순회하는 방식이었고, 오브젝트/스트림까지만 보여주면서 개별 명령까지 내려가진 않았음

    • “비전 모델로 PDF를 ‘사람처럼 본다’와 ‘실제로 PDF에 어떤 데이터가 들었는지 안다’의 결합체를 우리가 Tensorlake에서 만들고 있음(내가 거기 다님). 단순히 텍스트만 읽는 게 아니라, 표, 이미지, 수식, 손글씨 등도 진짜 이해해서 마크다운/JSON으로 데이터 추출할 수 있게 해 AI, LLM 등의 앱에 적용 가능함” https://tensorlake.ai

    • 완전히 원하는 수준은 아니지만, PDF 내부의 각종 드로잉 연산을 ‘라이브’로 보여주는 인스펙터를 제공하는 노트북이 있으니 참고해볼 것을 추천함 https://observablehq.com/@player1537/pdf-utilities

  • 수년간 Apple에서 이 문제에 집중함. 핵심은 “전부 기하학”이라는 점을 받아들이고, 단어 간격과 글자 간격을 군집분석해서 차별화하는 알고리즘임. 대부분의 PDF에선 효과적이지만 가까이 보면 종류가 너무 다양해 일부는 실망스러움. 요즘 다시 하면, OCR은 완전히 빼고 기하 정보 기반으로 접근하지만 머신러닝을 접목시킬 생각임. 미리 아는 텍스트로 PDF를 만들고 기계학습에 활용하면 학습 데이터 구축도 자동화 가능임. (WWDC 2009 Bertrand Serlet의 발표 영상 있음)

  • ‘PDF to Text’라는 하나의 문제가 아니라, 실제론 3가지 범주로 나눌 수 있다고 봄: (1) 신뢰할만한 OCR(검색, 벡터 DB 입력 등 용도), (2) 구조화된 데이터 추출(특정 값만 뽑기), (3) 문서 전체 파이프라인 자동화(예: 모기지 자동화). Marginalia는 (1)이 목적이고, 요즘 Gemini Flash 등 덕에 OCR이 저가화·범용화됨. 그러나 (2)와 (3)은 더 까다롭고, 완전 자동화에는 여전히 데이터셋 구축, 파이프라인 설계, 불확실성 탐지와 수동 개입, 파인튜닝 등 많은 인간의 노력이 필요함. 미래는 이 방향임. (LLM 문서 처리 회사 운영 중임) https://extend.ai

    • (4)로 다양한 형태 문서에서의 신뢰할 만한 OCR 및 의미 추출, 즉 접근성을 위한 솔루션도 필요하다고 봄. 이게 어려운 이유는, 일반 워크플로우와 달리 사용자 문서 종류 예측불가, 표, 헤더/푸터/주석/수식 등 텍스트 외 요소도 추출해야 함, 오류 최소화 요구되어 필요 이상으로 OCR 사용 금지, 내장 텍스트와 렌더링 내용이 불일치 가능(숨겨진 텍스트나 비정형 조합 등), 로컬 앱 위주로 구동되서 서버 활용 어려움, 임프린터 용도의 문서에 대한 Form 지원 필요 등 복합적인 난제가 산적함. 현재 완전하게 이 모든 점을 해결한 솔루션은 존재하지 않음

    • VLM을 이용해서 OCR 파이프라인을 간소화했다고 하지만, 실제 복잡한 문서에선 굉장히 어렵다는 경고임. 단순 이미지 라벨에는 뛰어나고, 아주 단순한 문서에는 쓸 만하지만, 표·헤더·정리 요약 등이 들어간 문서에서 심하게 환각(hallucinate) 현상이 나타남. 따라서 실제로는 거의 쓸 수 없는 수준임

    • Markdown으로 변환하는 와중에 헤더 탐지 등 다양한 이슈를 경험하고 있음. 요즘 OCR은 훌륭하지만, 문서 전체 구조를 유지하는 게 훨씬 더 어려움. LLM을 여러 번 통과시켜 구조를 추출하고, 페이지별로 컨텍스트를 집어넣는 방식으로 그나마 괜찮은 결과를 얻고 있음

  • 더 나은 해결책은 PDF 내부에 편집 가능한 소스 문서를 첨부하는 것임. LibreOffice로 간단하게 할 수 있음. 일반적으로 공간도 많이 차지하지 않고, 텍스트 의미를 명확히 알 수 있음. 기존 PDF 리더로도 문제없이 사용할 수 있음

    • 기존 PDF에서 텍스트 추출이 문제일 때, PDF 제작 방식에 대한 조언이 진정으로 어떤 도움이 될지 의문임. 언제쯤 이런 해결법이 본격적으로 효과가 나타날지 궁금함

    • 맞는 말이지만, 소스 문서와 렌더링 PDF의 내용이 전혀 다를 수 있는 위험이 생김

    • 맞는 의견이지만, PDF를 만든 사람과 PDF를 소비하는 사람의 이해관계가 일치해야만 유효함. 전자증거개시(e-Discovery) 분야에선, 상대방 변호사가 자료를 쓰기 어렵게 일부러 PDF로 변환해 제출하는 관행이 흔함. 그 결과, 자원이 부족한 공공변호인은 자료 처리에 더 많은 시간이 걸려 실질적 불이익을 받게 됨. 이를 방지하려면 각종 데이터는 표준 기계판독 포맷으로 강제 제출하도록 법제화해야 한다고 생각함

    • 만약 소스 문서에 접근할 수 있다면, PDF 내부에 첨부하는 게 매우 좋음. 그렇지만 대부분의 경우엔 그런 통제권이 없음

    • 진짜 문제 대부분은 레거시 PDF임. 우리 회사에도 수천 개 쌓여 있고, 일부는 엉망인 스캔본임. Adobe OCR이 내장된 것도 있지만 대다수는 아예 없음

  • 아래에 있는 PDF는 실제로는 .txt 파일임. 확장자를 .pdf로 바꿔서 PDF 뷰어로 열 수 있고, 텍스트 에디터로 직접 수정해 화면에 보일 내용, 폰트, 폰트 크기, 행간, 한 페이지 당 글자수, 행수, 종이 크기 등 다양한 부분을 컨트롤 할 수 있음. (직접 PDF 텍스트 예시 포함)

    • PDF엔 이진(binary) 스트림 내장도 가능함. PDF는 텍스트가 아니라, 레이아웃과 그래픽을 위해 만들어진 포맷임. 예시처럼 각 줄이 한 번에 나타날 수도 있지만, 실제론 글자마다, 단어마다 또는 심지어 무순서로도 표현할 수 있음

    • PDF란 “Portable Document Format”의 약자임. 7-bit ASCII 파일로서 인코딩되어 있어 다양한 기기나 OS 환경에서 높은 이식성을 자랑함. (참고: Adobe 공식 문서 링크)

    • 이 예시는 PDF의 ‘Hello World’임. 최근 PDF들은 대부분 객체(obj)를 deflate로 압축하고, 그 객체들을 스트림 내부에 그룹화시켜 더 복잡해짐. 그래서 단순 텍스트로 "6 0 Obj"를 검색하면서 분석하기가 매우 어려워짐

  • PDF에서 텍스트, 특히 구조화된 텍스트를 뽑는 것은 결코 쉬운 일이 아님. HTML 테이블은 대체로 그나마 간단하게 추출할 수 있는데, PDF는 렌더링된 좌표 기반으로만 표처럼 보일 뿐 실제론 텍스트와 그래픽이 흩어진 채로 들어있음. 나 역시 Poppler PDF utils로 PDF를 HTML로 바꾼 뒤, 테이블 헤더를 찾고, 각 값의 x좌표를 기준으로 열을 파악해 행별 데이터를 추출하는 방법으로 사용하고 있음. 보기에는 투박하지만 정렬된 txt로 하는 것보단 신뢰할 수 있는 결과임

    • 웹페이지와 BeautifulSoup처럼 PDF에서 데이터를 추출하지 못하는 게 불만이라서 그런 인터페이스를 가진 라이브러리를 직접 만듦. ('page.find' 형식 예시) PDF별로 케이스가 지옥처럼 다양해서, 추출 노하우와 괴랄한 PDF 예시들을 모아서 라이브러리로 만들고 있음 https://jsoma.github.io/natural-pdf/ , https://badpdfs.com/

    • 언젠가 PDF에서 표 데이터를 내 데이터 처리 소프트웨어로 뽑아내고 싶음. C++ 앱에 연동할 수 있으면서 무료이거나 아주 저렴한 라이브러리를 아는 분 제보 바람

    • (국가기관처럼) 출력 가능한 텍스트와 실제 추출되는 텍스트가 전혀 다른 문서들이 있음. 이런 케이스가 종종 있음

    • PDF는 본질적으로 마크업/XML 포맷임. 같은 PDF도 정말 수많은 방식으로 만들 수 있음. 그래픽 툴에서 내보내면 그래픽과 텍스트가 혼합된 PDF, 워드프로세서에서 내보내면 텍스트 중심 PDF 등 다차원적인 결과가 나옴. 제작 앱이 정보를 어떻게 처리하느냐가 PDF 출력 방식에 큰 영향을 줌. 오프더셸프 유틸리티로는 cisdem 등 다양한 제품군이 어느 정도 구조화 데이터를 뽑는 데 쓸 만함. 하지만 작업별로 적합한 도구가 필요함

  • 내가 좋아하는 사례 중 하나는, 이 논문 PDF임(링크 첨부). 첫 페이지에 전형적인 2단 텍스트와 중앙 헤더, 양 칼럼 사이에 끼어드는 텍스트, 줄 길이와 들여쓰기를 바꾸는 요소까지 다양함. 페이지 헤더도 홀/짝수에 따라 다르고, 섹션 헤더 규칙도 제각각임. 단락도 항상 들여쓰지 않고 줄 간격에 변동이 있음. 다양한 문제의 총집합임

    • MacOS의 CoreGraphics API는 PDF의 텍스트를 페이지 단위로, 딕셔너리에 encoding된 순서 그대로 제공함. 95% 경우엔 이 방식으로 꽤 잘 동작했고, PDFKit과 Preview에서도 수년간 큰 문제가 없었음. 2단 텍스트도 보통 원래 워드프로세서의 버퍼 순서와 일치하게 PDF에 들어갔으므로 내용 흐름이 올바름. 단, 헤더/푸터 등은 내부 앱마다 완전히 다르게 처리돼서 예측 불가임
  • 직접 간단한 PDF 파서를 만들어봤을 때, 포맷의 방식에 깜짝 놀란 적 있음. 그래서 오히려 왜 이 포맷이 텍스트 중심 용도로 많이 쓰이는지 늘 의아하게 생각함. 예를 들어 인보이스라면, 디지털 시스템이 데이터 추출은 쉽고, 사람에게는 포매팅 처리된 방식이 적합해야 함. 그래서 기술계가 더 나은 포맷으로 점진적 마이그레이션 했으면 하는 바람이 있음

    • 예전엔 XML+XSLT가 이런 역할에 거의 근접했었는데, 불행히도 브라우저들이 이제는 로컬 XML 파일용으로 더 이상 지원하지 않음. 원격 서버를 통한 XML만 지원함
  • PDF에서 ‘유용한 정보’ 추출이 바로 Tensorlake의 업무임(https://tensorlake.ai). PDF는 텍스트뿐만 아니라 표, 이미지, 수식, 손글씨, 취소선 등 다양한 정보를 담고 있기에, 개발자로서 우리는 텍스트를 “읽기”만이 아니라 “이해”할 수 있어야 함. (직원임을 밝힘)