1P by GN⁺ | ★ favorite | 댓글 1개
  • nlm-ingestor는 llmsherpa API가 연결해 쓰는 서비스 코드로, RAG에 맞춘 PDF·HTML·Text·DOCX·PPTX 등 문서 파서를 제공함
  • PDF 파서는 nlmatics 수정판 Tika에서 얻은 텍스트 좌표, 그래픽, 폰트 데이터를 사용하며, 스캔 페이지가 있으면 apply_ocr 옵션으로 OCR을 자동 적용할 수 있음
  • PDF 처리 기능에는 섹션·하위 섹션 수준, 문단 병합, 섹션-문단 연결, 표, 중첩 목록, 페이지 간 콘텐츠 결합, 반복 헤더·푸터 제거, 워터마크 제거, OCR 바운딩 박스가 포함됨
  • 모델 기반 비전 파서와 비교해 규칙 기반 파서는 PDF 페이지 이미지를 만들 필요가 없어 100배 빠르다고 설명하며, OCR이 아닌 텍스트 레이어 PDF와 수백 페이지 문서에서 더 실용적이라고 봄
  • 개발용 서버는 Docker 또는 직접 실행으로 띄울 수 있고, 운영 환경에서는 nginx나 클라우드 게이트웨이 같은 보안 게이트웨이 뒤에서 실행하는 구성이 권장됨

nlm-ingestor가 제공하는 문서 파서

  • nlm-ingestorllmsherpa API가 연결할 수 있는 서비스 코드 저장소임
  • RAG(retrieval augmented generation)에 맞춘 커스텀 파서를 여러 파일 형식에 제공함
    • PDF

    • HTML

    • Text

      • DOCX, PPTX, Apache Tika가 지원하는 기타 형식

PDF 파서의 동작 방식과 기능

  • PDF 파서는 규칙 기반이며, nlmatics 수정판 nlm-tika에서 얻은 텍스트 좌표, 그래픽, 폰트 데이터를 사용함
  • PDF 텍스트 레이어를 기반으로 동작하며, apply_ocr 옵션을 통해 PDF에 스캔 페이지가 있으면 OCR을 자동 적용할 수 있음
  • OCR 기능은 내부적으로 tesseract를 사용하는 nlmatics 수정판 Tika에 기반함
  • PDF 파서를 직접 실험할 수 있는 노트북으로 pdf_visual_ingestor_step_by_step이 제공됨
  • PDF 파서 기능은 다음과 같음
    • 섹션과 하위 섹션 및 각 레벨 식별
    • 여러 줄을 합쳐 문단 구성
    • 섹션과 문단 사이의 연결 생성
    • 표와 표가 발견된 섹션 식별
    • 목록과 중첩 목록 처리
    • 페이지를 넘나드는 콘텐츠 결합
    • 반복되는 헤더와 푸터 제거
    • 워터마크 제거
    • OCR 결과에 대한 바운딩 박스 제공

HTML·Text·Office 문서 처리

  • HTML 파서는 RAG 성능을 높이기 위해 더 품질 좋은 청크를 만들도록 레이아웃 인식 블록을 생성함
  • Text 파서는 시각 정보, 폰트 정보, 바운딩 박스 없이 텍스트만 보고 목록, 표, 헤더 등을 추정함
  • DOCX, PPTX 및 Apache Tika가 지원하는 다른 형식은 Tika의 HTML 출력을 사용한 뒤 HTML 파서로 처리함

실행과 API 사용

  • 직접 실행 절차는 Java 설치, Tika 서버 실행, nlm-ingestor 설치, ingestor 실행으로 구성됨
    • Tika 서버 실행: java -jar <path_to_nlm_ingestor>/jars/tika-server-standard-nlm-modified-2.9.2_v2.jar
    • 설치: pip install nlm-ingestor
    • 실행: python -m nlm_ingestor.ingestion_daemon
  • 공개 GitHub Container Registry에 Docker 이미지가 제공됨
    • 이미지 받기: docker pull ghcr.io/nlmatics/nlm-ingestor:latest
    • 실행 예: docker run -p 5010:5001 ghcr.io/nlmatics/nlm-ingestor:latest-<version>
  • 서버 실행 후 llmsherpa API 라이브러리로 청크를 받아 LLM 프로젝트에 사용할 수 있음
  • llmsherpa_url 예시는 http://localhost:5010/api/parseDocument?renderFormat=all
    • OCR 적용: &applyOcr=yes
    • 헤더 레벨 할당에 다른 알고리듬을 쓰는 새 indent 파서 사용: &useNewIndentParser=yes
  • 개발용 서버로는 사용할 수 있지만, 운영 환경에서는 nginx나 클라우드 게이트웨이 같은 보안 게이트웨이 뒤에서 실행하는 구성이 권장됨
  • llmsherpa 파서로 서버를 테스트하는 샘플 코드는 test_llmsherpa_api 노트북에 있음

규칙 기반 파서를 선택한 이유

  • nlmatics 팀은 4년 동안 Tom Liu와 Yi Zhang이 개발한 YOLO 기반 비전 파서를 포함해 여러 선택지를 평가한 뒤 규칙 기반 파서를 선택함
  • 규칙 기반 파서는 어떤 비전 파서보다 상당히 빠르며, 저장소 설명은 이를 100배 빠름으로 표현함
    • 비전 파서는 텍스트 레이어가 있는 PDF라도 모든 페이지 이미지를 만들어야 함
    • 비전 파서는 텍스트 레이어가 없는 OCR PDF나 폼 데이터로 구성된 작은 PDF에는 더 나은 선택지일 수 있음
    • 수백 페이지에 걸친 큰 텍스트 레이어 PDF에는 규칙 기반 파서가 더 실용적이라고 봄
  • PDF OCR 기능을 쓰지 않는다면 특수 하드웨어가 필요 없음
    • 저장소 설명은 2000년대 초반 하드웨어에서도 실행할 수 있다고 밝힘
  • 비전 파서를 포함한 모든 파서는 오류가 생길 수 있으며, 모델 기반 파서의 오류 수정 방식은 만족스럽지 않았다고 설명함
    • 학습 세트에 예시를 더 추가하면 이전 학습의 정확도가 떨어지고 기존에 동작하던 코드가 불확실해질 수 있음
    • 모델 기반 파서 문제를 규칙 기반 아이디어로 고치면 다시 많은 규칙을 작성하게 됨

nlmatics 수정판 Tika

  • nlmatics 수정판 Tika는 2.4.1-nlm 브랜치에 있음
  • 편의를 위해 컴파일된 jar 파일이 저장소의 jars/ 폴더에 포함됨
  • 일부 PDF는 Java 서버에서 오류가 날 수 있으며, 이 경우 해당 코드를 수정하고 jar 파일을 다시 컴파일해야 함
  • 수정된 파일은 PDF 텍스트 요소마다 폰트와 좌표를 추가하고 워터마크를 제거함
    • PDF2XHTML.java
    • AbstractPDF2XHTML.java
  • GraphicsStreamProcessor.java 변경은 표 탐지에 도움이 될 수 있는 선과 사각형을 추가하기 위한 것임
  • 변경의 영향은 pdf_visual_ingestor_step_by_step 노트북 앞부분에서 확인할 수 있음
  • 향후 작업 아이디어는 다음과 같음
    • pdfbox 위에 자체 래퍼를 작성해 Tika 변경 의존성을 제거
    • 최신 Tika 버전으로 업그레이드
    • 반환되는 HTML 형식을 더 CSS 친화적으로 정리

댓글과 토론

Hacker News 의견들
  • 과학 논문을 다룬다면 GROBID도 추가할 만함: https://github.com/kermitt2/grobid
    paperetl(https://github.com/neuml/paperetl)과 함께 쓰고 있음

  • 좋은 프로젝트임. 문서 파싱에는 성숙도와 지원 형식이 넓어서 오랫동안 Tika를 써왔고, XHTML 출력이 RAG용 문서 청킹에 도움이 됨
    예시는 https://neuml.hashnode.dev/build-rag-pipelines-with-txtaihttps://neuml.hashnode.dev/extract-text-from-documents가 있음
    참고로 txtai(https://github.com/neuml/txtai)의 주 작성자임

    • 주제에서 조금 벗어나지만, Tika가 다른 PDF 파싱 라이브러리와 비교해 어떤지 궁금함
      pdfminer.six(unstructured가 쓰는 것)는 레이아웃 감지가 꽤 기본적이라 다단 텍스트 파싱에 실패해서 실망스러웠고, MuPDF는 완벽하게 처리했음
      지금은 MuPDF + AWS Textract(주로 표)를 섞어 쓰고 있는데, 다른 사람들이 뭘 쓰는지 알고 싶음
  • 꽤 도움이 될 것 같음. 내가 일하는 회사에는 PDF를 읽고 의미적 차이를 비교하는 PDF 비교 도구 “PDFC”가 있음: https://www.inetsoftware.de/products/pdf-content-comparer
    PDF 형식이 워낙 복잡해서 파싱이 상당히 골치 아플 수 있음. 우리는 이미 이런 기능 대부분을 지원하지만, 엣지 케이스가 늘 많아서 추가적인 접근 방식이 도움이 될 수 있음

  • Tesseract OCR 폴백은 좋아 보임
    이제 RAG용 파일 로더가 langchain, LLMindex, unstructured 등 많이 있는데, 이걸 선호할 이유가 있는지 궁금함. 예를 들면 벤치마크 점수가 앞선다든가 하는 근거가 있는지

    • 이 도구는 Apple Silicon에서 빌드되지 않고 ARM Docker 이미지도 없어서 직접 써보지는 못했음
      다만 PDF 파싱 용도로 그런 RAG 도구들을 써봤는데 출력 품질이 꽤 낮았음. LLM이 문제를 어느 정도 우회하니 RAG로는 그럭저럭 동작하지만, 제대로 된 참조가 붙은 더 높은 품질의 답변을 원하면 규칙 기반 파서를 직접 쓰는 게 제일 낫다고 봄. 결국 나도 그렇게 했고, 다만 Tika가 아니라 MuPDF 기반이었음
      이 도구의 작성자들도 비슷한 생각이었을 수 있음
    • 마지막으로 Langchain을 써봤을 때는, 인정하건대 약 6개월 전이지만, PDF와 HTML 파일에서 콘텐츠 추출하는 구현이 매우 기본적이었음
      RAG 프로토타입을 돌리기에는 충분했지만 신뢰할 만한 것을 만들기에는 부족했음. 이 프로젝트는 훨씬 더 실전에서 검증된 구현처럼 보임
  • 훌륭한 작업이고 매우 흥미로움. 하지만 GitHub에 가보면 “This organization has no public members”라고 나오고, 당신들이 누구인지 전혀 모르겠으며 공개되지 않은 채 이 안에 또 무엇이 포함될 수 있는지도 알 수 없음
    전반적으로 “이름 없는 숨은 그룹이 $CORP 보안 사이트에 올린 것”과 전통적인 소개·신뢰 구축 방식 사이에, 시간이 지나며 식별과 신뢰를 쌓을 수 있는 중간 지점이 필요하다고 봄

  • LLM/RAG 프로젝트에서 최적의 청크를 얻으려면 이 서버를 llmsherpa LayoutPDFReader와 함께 쓰면 됨: https://github.com/nlmatics/llmsherpa
    저장소의 예제와 노트북을 보면 됨

  • 예시 입력·출력 쌍이 어딘가에 있는지 궁금함

  • 이걸로 PDF 몇백 개를 파싱해봤는데 결과가 꽤 괜찮았음. Julia로 개발됐다면 적어도 10배는 더 빨랐을 것 같음

  • 이것이 Azure Document Intelligence와 어떻게 다른지, 아니면 사실상 같은 것인지 궁금함

    • 같은 일을 하는 것은 아님. 대부분의 클라우드 파서는 비전 모델을 쓰기 때문에 훨씬 느리고 비싸며, 좋은 청크를 추출하려면 그 위에 코드를 더 작성해야 함
      이 서버와 llmsherpa 라이브러리(https://github.com/nlmatics/llmsherpa)를 함께 쓰면 LLM/RAG 프로젝트에 맞는 레이아웃 친화적인 청크를 얻을 수 있음
    • 여기에는 OCR이나 AI가 들어가지 않음. 표준 폴백을 제외하면 그렇다는 뜻임
      이 라이브러리와 fitz/pymupdf 같은 도구는 PDF에서 텍스트를 직접 추출하고, 파싱과 구조화 규칙을 적용할 수 있게 해줌. 최신 PDF 대부분은 OCR 없이 텍스트 추출이 가능함
      당연히 훨씬 저렴하지만 동적인 레이아웃 전반으로는 잘 확장되지 않으므로, 보통 표준 구조에 맞춰 설정할 수 있을 때 쓰게 됨. 그래도 과학 논문 같은 것에는 규칙 기반 텍스트 추출이 꽤 동적으로 잘 동작한다고 봤음
    • 마지막으로 써봤을 때 Azure Document Intelligence는 분할 지점을 고르는 데 그리 똑똑하지 않았음. 이쪽은 더 나은 휴리스틱을 구현한 것처럼 보임
    • 나도 궁금함. ADI는 신뢰할 만하지만 잘못 만들어진 PDF에서는 엣지 케이스 문제가 있음
      다만 Tesseract OCR이 잠재적 한계일까 걱정됨. 실수를 너무 많이 하는 걸 봤음
  • 예제가 있는지 궁금함. 저장소에는 PDF 파일이 하나도 없어 보임

    • 예제는 llmsherpa 프로젝트에서 볼 수 있음: https://github.com/nlmatics/llmsherpa
      이 nlm-ingestor 프로젝트는 llmsherpa와 함께 동작하는 백엔드를 제공함. llmsherpa 라이브러리는 LLM/RAG 프로젝트용으로 좋은 청크를 추출하는 데 매우 편리함