블로그로 돌아가기
Tech Insight2026년 11월 13일165

docling 사용법 2026 — PDF·DOCX를 RAG용 마크다운으로, 한국어 OCR 설정과 HWP 현실

docling 사용법 — PDF·DOCX·PPTX를 RAG용 마크다운으로 바꾸는 최소 코드와 한국어 OCR 설정을 공식 문서로 직접 대조했습니다. 기본값이 OCR을 조용히 건너뛰는 조건, 표가 한 열로 뭉칠 때 바꿀 옵션, HWP·HWPX 미지원(이슈 #3602)까지 정리했습니다.

docling 사용법은 한 문장으로 정리된다 — PDF·DOCX·PPTX·이미지를 넣으면 레이아웃과 표 구조를 살린 마크다운이나 JSON으로 꺼내 주는 파이썬 라이브러리이고, 사내 문서로 RAG를 만들 때 검색 품질을 결정하는 첫 단계가 바로 이 변환이다. IBM이 공개한 오픈소스이며 pip install docling 한 줄로 설치하고 DocumentConverter().convert(경로).document.export_to_markdown() 세 줄로 첫 결과를 받는다. 다만 실무에서 막히는 지점은 대부분 그 세 줄 밖에 있다 — 기본 설정이 OCR을 건너뛰는 조건, 표를 병합해 버리는 옵션, 그리고 한국 문서의 절반을 차지하는 HWP·HWPX가 지원 목록에 없다는 사실이다. 아래 내용은 2026년 11월 13일 공식 문서와 GitHub 저장소를 직접 대조해 정리했다. 버전이 올라가면 옵션 이름이 바뀌는 제품이므로, 쓰기 전에 설치된 버전의 문서를 한 번 더 확인하는 편이 빠르다.

docling 사용법 — 설치부터 첫 변환까지

공식 설치 문서가 권하는 명령은 두 가지다.

pip install docling
# 또는
uv add docling

macOS·Linux·Windows를 지원하고 x86_64와 arm64 모두 올라간다. 여기서 두 가지 함정이 문서에 명시돼 있다.

첫째, Intel 맥이라면 파이썬 버전을 내려야 한다. 문서는 "PyTorch 2.2.2는 파이썬 3.12 이하를 요구한다"고 적고, 3.13 이상을 쓰지 말라고 못 박는다. 최신 PyTorch(2.6.0+)가 Intel 맥용 휠을 더 이상 제공하지 않기 때문이다. 이 경우는 pip install "docling[mac_intel]" 또는 버전을 직접 고정하는 경로를 안내한다.

둘째, cv2 오류는 설치 방식 때문이다. docling 패키지는 docling-slim[standard]를 설치하고 여기에는 RapidOCR이 항상 포함된다. 그런데 extras를 직접 골라 설치하면 OpenCV가 빠질 수 있고, 그러면 PDF 변환이 ModuleNotFoundError: No module named 'cv2'로 죽는다. 문서가 직접 적어 둔 증상이다.

GPU 없는 리눅스 서버에 올릴 때는 CPU 전용 인덱스를 지정하는 쪽이 설치 용량을 크게 줄인다.

pip install docling --extra-index-url https://download.pytorch.org/whl/cpu

첫 변환은 이게 전부다.

from docling.document_converter import DocumentConverter

source = "https://arxiv.org/pdf/2408.09869"   # 파일 경로 또는 URL
converter = DocumentConverter()
doc = converter.convert(source).document

print(doc.export_to_markdown())

배치로 수백 건을 돌릴 때는 변환 결과를 다 쓴 뒤 result.input.release()를 호출하라고 문서가 안내한다. 입력 백엔드를 붙잡고 있으면 메모리가 계속 쌓인다. CLI도 같은 일을 한다.

docling https://arxiv.org/pdf/2206.01062
docling convert --from pdf --to dclx --ocr-engine rapidocr --ocr-lang en document.pdf

어떤 포맷이 들어가고, 무엇이 안 들어가나

지원 입력 포맷은 생각보다 넓다. 공식 목록을 그대로 옮기면 PDF, DOCX·XLSX·PPTX, 레거시 DOC·XLS·PPT, RTF, ODT·ODS·ODP, EPUB, Apple iWork(Pages·Numbers·Keynote), 마크다운, AsciiDoc, LaTeX, HTML·XHTML·MHTML, CSV, 이미지(PNG·JPEG·TIFF·BMP·WEBP), 오디오(WAV·MP3·M4A·AAC·OGG·FLAC), 비디오(MP4·AVI·MOV·MKV·WEBM), WebVTT, BoxNote, 이메일(.eml·.msg), AFP, iCalendar, 그리고 USPTO·JATS·XBRL 같은 스키마 전용 XML까지다.

주의할 것은 일부가 추가 의존성을 전제한다는 점이다.

포맷 묶음전제 조건현장에서 걸리는 지점
DOC · XLS · PPT · RTFLibreOffice 설치컨테이너 이미지가 커진다. 레거시 파일이 섞인 아카이브를 돌릴 때만 넣는다
Pages · Numbers · Keynoteformat-iwork extra기본 설치에 없다
오디오·비디오audio 또는 asr extra, 비디오는 ffmpeg비디오는 오디오 트랙만 떼어 전사한다
XBRLxbrl extraiXBRL(.htm·.html·.xhtml)도 같은 extra
EBCDICEbcdicBackendOptions 지정메인프레임 덤프용

그리고 한국에서 가장 먼저 확인해야 할 항목이 있다. HWP와 HWPX는 지원 목록에 없다. 문서 사이트와 GitHub 저장소의 포맷 목록 양쪽을 확인했고 어디에도 없다. 저장소에는 「Add HWP/HWPX input backend with layout provenance」(이슈 #3602)가 2026년 6월 14일에 열려 있지만, 지금까지 라벨·담당자·마일스톤이 붙지 않았고 저장소에 병합된 PR도 없다. 본문에는 "Docling에 아직 이들을 위한 InputFormat이 없다"고 적혀 있고, 작성자가 7월에 네이티브 HWPX 백엔드와 바이너리 HWP 경로를 둘로 나눈 계획을 남겼으나 메인테이너 답글은 달리지 않았다. 11월에 다른 사용자가 테스트 파일을 제공하겠다고 적은 것이 마지막 움직임이다.

즉 현재 시점에서 HWP는 docling에 그냥 넣을 수 없다. 이걸 모르고 사내 문서 전체를 큐에 밀어 넣으면 한글 문서만 조용히 실패한다.

마크다운이냐 JSON이냐 — RAG에 무엇을 넣을까

출력은 하나가 아니다. 공식 출력 목록은 HTML, 마크다운, JSON, DocLang XML, 평문 텍스트, DocTags, WebVTT, DocLang 아카이브(dclx), Chunks(JSONL), LaTeX다. 선택 기준은 세 가지로 갈린다.

  • 마크다운 — 사람이 읽고 검수할 수 있다. 중간 산출물을 눈으로 확인하는 단계에서 가장 쓸모 있다. export_to_markdown()이 그대로 문자열을 돌려준다.
  • JSON — 문서가 "Docling Document의 무손실 직렬화"라고 적는다. 좌표·계층·출처를 유지해야 하는 파이프라인은 이쪽이다. 마크다운으로 내리면 그 정보가 사라진다.
  • Chunks(JSONL) — 문서가 명시적으로 "RAG 파이프라인용 청크 출력"이라고 적어 둔 형식이고, --chunks-type · --chunks-max-tokens · --chunks-tokenizer로 조정한다.

청킹을 코드로 하려면 docling.chunking의 청커를 쓴다. HybridChunker · LineBasedTokenChunker · HierarchicalChunker가 있고, 공통 인터페이스는 chunk(dl_doc)와 contextualize(chunk)다. HybridChunker의 기본값 중 repeat_table_header=True가 실무에서 특히 중요하다 — 긴 표가 여러 청크로 쪼개질 때 머리행을 각 청크에 다시 붙여 준다. 이게 없으면 "2023년 열이 무엇을 의미하는지" 모르는 숫자 덩어리가 벡터 DB에 들어간다. merge_peers도 기본 True이고, omit_header_on_overflow는 기본 False다.

한 가지 분명히 할 것이 있다. 공식 청킹 문서는 마크다운으로 내려 직접 청킹하는 방식과 네이티브 청커를 쓰는 방식 두 가지를 모두 소개하고, 어느 쪽이 더 낫다고 말하지 않는다. 그러니 "docling은 네이티브 청커를 권한다"는 식으로 읽지 말고, 우리 검색 품질로 판단하는 편이 맞다.

한국어 OCR 설정 — 기본값은 OCR 없이 지나간다

여기가 가장 많이 틀리는 자리다. 기본 선택기(OcrAutoOptions)는 Tesseract를 절대 고르지 않는다. 그리고 고를 수 있는 엔진이 하나도 설치돼 있지 않으면 No OCR engine found. Please review the install details.를 로그에 남기고 OCR 없이 변환을 끝낸다. 예외가 나지 않는다. 스캔 PDF를 넣고 빈 마크다운을 받은 뒤 "docling이 한글을 못 읽는다"고 결론 내리는 경로가 정확히 이것이다.

엔진은 EasyOCR · Nemotron OCR · Tesseract · Tesseract CLI · OcrMac · RapidOCR · OnnxTR, 그리고 원격 KServe v2까지 있다. 지정은 ocr_options로 한다.

from docling.datamodel.pipeline_options import PdfPipelineOptions

pipeline_options = PdfPipelineOptions()
pipeline_options.do_ocr = True
pipeline_options.ocr_options = TesseractOcrOptions()

언어는 엔진이 달라도 같은 필드 하나로 받는다 — OcrOptions.lang이다. 값은 엔진 고유 코드(deu · ch)를 쓰거나, iso: 접두어를 붙여 BCP-47 태그(iso:de · iso:en-US)를 쓴다. 빈 리스트를 주면 엔진이 알아서 고른다.

한국어는 문서에 이렇게 적혀 있다.

  • RapidOCR: iso:ko가 PP-OCR의 korean 토큰으로 매핑된다. 기본 설치에 RapidOCR이 포함되므로 추가 설치 없이 가장 먼저 시도할 경로다.
  • Nemotron OCR: 학습된 5개 언어에 iso:ko가 포함되고, 이 값을 주면 다국어 모델이 선택된다. 다만 리눅스 x86_64 · 파이썬 3.12 · CUDA 13.x를 요구한다.
  • Tesseract: 한국어 코드(kor)는 문서에 명시돼 있지 않다. 일반 규칙으로 "Tesseract의 어휘는 ISO 639-2/T라서 대부분의 iso: 태그가 그대로 매핑된다"고만 적는다.

Tesseract를 쓸 때 걸리는 함정이 하나 더 있다. 기본 언어가 eng · spa · fra · deu 네 개이고, 이 중 하나라도 설치돼 있지 않으면 변환이 실패한다. 한국어 팩만 깔고 영어 외 세 개를 빼면 거기서 멈춘다. 엔진이 실제로 어떤 언어를 받는지는 supported_ocr_languages()로 확인한다.

마지막으로 옵션 이름이 바뀐 자리를 짚어 둔다. 전 페이지를 OCR로 읽히는 설정은 지금 mode=OcrMode.FULL_PAGE(CLI는 --ocr-mode full_page)다. 과거 이름으로 알려진 force_full_page_ocr는 현재 문서 어디에도 없다. 오래된 예제를 복사하면 조용히 무시되거나 깨진다.

ocr_options = TesseractCliOcrOptions(mode=OcrMode.FULL_PAGE)
pipeline_options.ocr_options = ocr_options

문서는 전면 OCR이 "하이브리드 검출보다 느릴 때가 많다"고 적고, 레이아웃 추출이 불안정하거나 스캔 페이지가 섞였을 때 쓰라고 안내한다. 텍스트 레이어가 깨진 PDF만 골라 OCR로 돌리고 싶으면 replace_broken_text_layer가 따로 있다 — 기본은 꺼져 있다.

표와 레이아웃을 살리는 옵션

RAG에서 표는 가장 비싼 자산이고 가장 쉽게 망가진다. docling은 표 구조 인식 결과를 PDF 셀에 되돌려 매핑하는 것이 기본이고, 이 동작을 끌 수 있다.

from docling.datamodel.pipeline_options import PdfPipelineOptions, TableFormerMode

pipeline_options = PdfPipelineOptions(do_table_structure=True)
pipeline_options.table_structure_options.do_cell_matching = False
pipeline_options.table_structure_options.mode = TableFormerMode.ACCURATE

문서가 적어 둔 판단 기준이 명확하다 — "추출된 표에서 여러 열이 하나로 잘못 병합되는 현상"이 보이면 do_cell_matching = False로 두고 표 구조 모델이 예측한 텍스트 셀을 쓰라는 것이다. 한글 문서의 복잡한 병합 셀에서 자주 만나는 증상이다.

TableFormerMode는 docling 1.16.0부터 선택할 수 있고, FAST는 빠르지만 덜 정확하며 기본값은 ACCURATE다. 수천 페이지를 한 번에 돌리면서 처리 시간이 문제라면 FAST로 내리는 선택지가 있지만, 표가 결과물의 핵심이면 기본값을 그대로 두는 편이 낫다. 읽기 순서를 괘선으로 판단하는 동작(use_reading_order_separators)도 기본으로 켜져 있다.

한국 문서의 현실 — HWP는 먼저 변환한다

위에서 확인한 대로 HWP·HWPX는 지원 포맷이 아니다. 그래서 사내 문서 RAG의 실제 파이프라인은 두 단계가 된다.

  1. HWP·HWPX → PDF 또는 DOCX 변환 (별도 경로로 처리)
  2. 변환된 파일을 docling에 넣어 마크다운·JSON·청크로 추출

1번을 어떻게 처리하는지가 한국 프로젝트의 난이도를 결정한다. 한글파일을 Claude로 다루는 구체적인 방법은 클로드로 한글파일(HWP) 변환·작성·자동화하는 법에 따로 정리해 뒀고, 도구 연결 쪽은 HWP-MCP로 Claude에 한글파일 읽기 붙이기를 보면 된다. 중요한 것은 변환 단계에서 표와 서식이 얼마나 살아남는지를 먼저 측정하고 나서 docling 단계를 설계하는 순서다. 1번에서 표가 깨지면 2번의 TableFormerMode.ACCURATE는 아무 의미가 없다.

파싱이 끝나면 평가와 관측이 남는다

파싱은 RAG 구축의 첫 단계일 뿐이고, 여기서 끝내면 "검색이 잘 되는지"를 아무도 모르는 상태로 운영에 들어간다. 순서는 이렇게 이어진다.

단계하는 일참고
파싱문서 → 마크다운·JSON·청크이 글
검색 품질 측정청크가 답을 담고 있는지 수치로RAG 평가 지표 — RAGAS로 재는 법
운영 관측실제 질문·응답·비용 추적LLM 모니터링 도구 비교
인수·운영 경계어디까지 우리가 고치고 어디부터 넘기나RAG 챗봇 인수·운영 경계 가이드

특히 파싱 품질과 검색 품질을 따로 재야 한다는 점이 자주 생략된다. 마크다운이 깔끔해 보여도 청킹 경계가 표 중간을 자르면 검색은 실패한다. 반대로 파싱이 거칠어도 청크마다 맥락이 붙어 있으면 답은 나온다. 그래서 파싱 단계를 바꿀 때마다 같은 질문 세트로 다시 재는 루프가 필요하다.

그래서 어디까지 자동화할 수 있나

docling으로 자동화되는 부분은 포맷 변환과 구조 추출이다. 자동화되지 않는 부분이 둘 남는다. 하나는 HWP처럼 지원 목록 밖에 있는 포맷의 전처리 경로이고, 다른 하나는 "어떤 문서를 넣을지" 고르는 일이다. 사내 문서 저장소를 통째로 넣으면 만료된 규정과 현행 규정이 같은 가중치로 검색된다 — 이건 파서가 풀 수 없는 문제다.

트리숲에서 사내 문서 RAG를 구축할 때도 이 두 가지가 실제 작업량의 절반 이상을 차지한다. 파싱 파이프라인은 하루면 세우지만, 문서 선별 기준과 갱신 주기를 정하는 일은 담당 부서와 같이 앉아야 끝난다. 그 작업과 구축 범위는 자연어 처리·LLM 구축 서비스에 정리돼 있고, 팀이 어떤 방식으로 개발하는지는 AI-Native 개발 방식을 보면 된다. 구축이 끝난 뒤 그 상태가 계속 도는 쪽은 ax.trina.app이 맡는다 — 문서가 바뀔 때마다 사람이 다시 돌리는 구조로 두면 반년 뒤에 아무도 안 돌린다.

Q: docling 사용법에서 가장 먼저 확인할 것은 무엇인가요?

OCR 엔진이 실제로 선택됐는지입니다. 기본 선택기는 Tesseract를 고르지 않고, 고를 수 있는 엔진이 없으면 No OCR engine found.를 로그에 남긴 뒤 OCR 없이 변환을 끝냅니다. 예외가 발생하지 않으므로 스캔 PDF가 빈 결과로 나와도 성공으로 보입니다. 기본 설치에 포함된 RapidOCR을 iso:ko로 지정해 한 번 돌려 보고, 결과 문자열 길이를 확인하는 것이 가장 빠른 점검입니다.

Q: docling이 HWP·HWPX를 지원하나요?

2026년 11월 13일 기준으로 지원하지 않습니다. 공식 지원 포맷 목록(문서 사이트·GitHub 양쪽)에 HWP와 HWPX가 없습니다. 저장소에 「Add HWP/HWPX input backend with layout provenance」(이슈 #3602)가 2026년 6월부터 열려 있지만 병합된 PR이나 마일스톤은 없습니다. 따라서 HWP는 PDF나 DOCX로 먼저 변환한 뒤 docling에 넣는 2단계 구성이 현재의 유일한 경로입니다.

Q: RAG에는 마크다운과 JSON 중 무엇을 넣어야 하나요?

둘 다 정답이 될 수 있어서 공식 문서도 한쪽을 권하지 않습니다. 사람이 중간 결과를 검수하는 단계라면 마크다운이 편하고, 좌표·계층·출처를 유지해야 하면 JSON(무손실 직렬화)입니다. RAG 전용으로는 Chunks(JSONL) 출력이 따로 있고 --chunks-max-tokens로 길이를 조정합니다. 표가 많은 문서라면 HybridChunker의 repeat_table_header=True(기본값)로 머리행이 각 청크에 붙는지 확인하세요.

Q: 표가 여러 열로 뭉쳐 나옵니다. 어떤 옵션을 봐야 하나요?

table_structure_options.do_cell_matching입니다. 기본값은 인식된 구조를 PDF 셀에 되돌려 매핑하는 방식인데, 공식 문서는 여러 열이 하나로 잘못 병합되는 경우 이 값을 False로 두고 표 구조 모델이 예측한 텍스트 셀을 쓰라고 안내합니다. 함께 TableFormerMode.ACCURATE(기본값)인지 확인하고, 처리 속도 때문에 FAST로 내려 둔 적이 없는지 점검하세요.

Q: 스캔 PDF 전체를 OCR로 읽히려면 어떻게 하나요?

mode=OcrMode.FULL_PAGE를 OCR 옵션에 지정합니다(CLI는 --ocr-mode full_page). 과거 예제에 자주 보이는 force_full_page_ocr는 현행 문서에 없는 이름이라 그대로 복사하면 동작하지 않습니다. 전면 OCR은 하이브리드 검출보다 느리므로, 텍스트 레이어가 깨진 페이지만 골라 처리하려면 기본으로 꺼져 있는 replace_broken_text_layer를 쓰는 편이 효율적입니다.


출처

관련 서비스: RAG 챗봇, 직접 구축해드립니다