chandra2 / Intro.md
Hyungseoky's picture
Create Intro.md
8e68ea1 verified
|
Raw
History Blame Contribute Delete
24.7 kB

Chandra OCR 2 β€” 사내 Document Intelligence μ„œλΉ„μŠ€ 기술 λ¬Έμ„œ

μž‘μ„±μΌ: 2026-04-15
μž‘μ„±μž: AI Engineering Team
μ„œλΉ„μŠ€ μ„œλ²„: DGX H200 (10.150.6.159)
μƒνƒœ: 운영 쀑


1. κ°œμš”

Chandra OCR 2λŠ” Datalabμ—μ„œ κ°œλ°œν•œ μ΅œμ‹  OCR(Optical Character Recognition) λͺ¨λΈλ‘œ, λ¬Έμ„œ 이미지λ₯Ό κ΅¬μ‘°ν™”λœ HTML/Markdown/JSON으둜 λ³€ν™˜ν•˜λ©΄μ„œ λ ˆμ΄μ•„μ›ƒ 정보λ₯Ό λ³΄μ‘΄ν•©λ‹ˆλ‹€. olmOCR λ²€μΉ˜λ§ˆν¬μ—μ„œ 85.9% 점수둜 μ˜€ν”ˆμ†ŒμŠ€ OCR λͺ¨λΈ 쀑 졜고 μ„±λŠ₯(SOTA)을 κΈ°λ‘ν•˜κ³  있으며, 90개 μ΄μƒμ˜ μ–Έμ–΄λ₯Ό μ§€μ›ν•©λ‹ˆλ‹€.

μ‚¬λ‚΄μ—μ„œλŠ” κΈ°μ‘΄ DotsOCR(Qwen3-VL-235B 기반) νŒŒμ΄ν”„λΌμΈμ„ Chandra OCR 2둜 κ΅μ²΄ν•˜μ—¬, λ™μΌν•œ FastAPI μΈν„°νŽ˜μ΄μŠ€(POST /process-file/)λ₯Ό μœ μ§€ν•˜λ©΄μ„œ 더 높은 정확도와 효율적인 λ¦¬μ†ŒμŠ€ μ‚¬μš©μ„ μ‹€ν˜„ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

1.1 κΈ°μ‘΄ μ‹œμŠ€ν…œ λŒ€λΉ„ κ°œμ„ μ 

ν•­λͺ© κΈ°μ‘΄ (DotsOCR) ν˜„μž¬ (Chandra OCR 2)
μΆ”λ‘  λͺ¨λΈ Qwen3-VL-235B (MoE, ~235B params) Chandra OCR 2 (5B params)
λͺ¨λΈ 크기 ~130GB+ ~10.6GB
GPU μš”κ΅¬μ‚¬ν•­ λ©€ν‹° GPU ν•„μˆ˜ 단일 GPU (24GB+)
좜λ ₯ ν˜•μ‹ λ ˆμ΄μ•„μ›ƒ JSON (μ»€μŠ€ν…€ ν”„λ‘¬ν”„νŠΈ) HTML β†’ Markdown/JSON (λ„€μ΄ν‹°λΈŒ)
olmOCR 벀치마크 64.6% (Qwen3-VL-8B κΈ°μ€€) 85.9%
λ‹€κ΅­μ–΄ 지원 40+ μ–Έμ–΄ 90+ μ–Έμ–΄
ν•œκ΅­μ–΄ 정확도 82.3% 88.7%

2. λͺ¨λΈ μ†Œκ°œ

2.1 Chandra OCR 2λž€?

Chandra OCR 2λŠ” λ³΅μž‘ν•œ λ¬Έμ„œ β€” 손글씨, ν…Œμ΄λΈ”, μˆ˜μ‹, 양식 λ“± β€” 을 높은 μ •ν™•λ„λ‘œ μΈμ‹ν•˜μ—¬ κ΅¬μ‘°ν™”λœ λ””μ§€ν„Έ 포맷으둜 λ³€ν™˜ν•˜λŠ” OCR λͺ¨λΈμž…λ‹ˆλ‹€. λ‹¨μˆœν•œ ν…μŠ€νŠΈ μΆ”μΆœμ΄ μ•„λ‹ˆλΌ, λ¬Έμ„œμ˜ 곡간적 λ ˆμ΄μ•„μ›ƒ(λ°”μš΄λ”© λ°•μŠ€), μš”μ†Œ μœ ν˜•(ν…μŠ€νŠΈ, ν…Œμ΄λΈ”, μˆ˜μ‹ λ“±), 읽기 μˆœμ„œλ₯Ό ν•¨κ»˜ λ³΄μ‘΄ν•©λ‹ˆλ‹€.

2.2 λͺ¨λΈ μ•„ν‚€ν…μ²˜

Chandra OCR 2λŠ” Alibaba의 Qwen 3.5 λΉ„μ „-μ–Έμ–΄ λͺ¨λΈμ„ 기반(base model)으둜 ν•˜μ—¬, λ¬Έμ„œ νŠΉν™” νƒœμŠ€ν¬μ— νŒŒμΈνŠœλ‹ν•œ λͺ¨λΈμž…λ‹ˆλ‹€.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Chandra OCR 2 (5B)             β”‚
β”‚                                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ Vision       β”‚    β”‚ Language Model     β”‚  β”‚
β”‚  β”‚ Encoder      │───▢│ (Qwen 3.5 기반)    β”‚  β”‚
β”‚  β”‚              β”‚    β”‚                    β”‚  β”‚
β”‚  β”‚ 이미지 μž…λ ₯   β”‚    β”‚ HTML/Markdown 좜λ ₯  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                             β”‚
β”‚  Fine-tuned on document-specific tasks      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

μ£Όμš” ꡬ성 μš”μ†Œ:

  • Vision Encoder: λ¬Έμ„œ 이미지λ₯Ό μ‹œκ° ν† ν°μœΌλ‘œ μΈμ½”λ”©ν•˜λŠ” λΉ„μ „ 인코더
  • Language Model: Qwen 3.5 μ•„ν‚€ν…μ²˜ 기반 ν…μŠ€νŠΈ 생성 λͺ¨λΈ (5B νŒŒλΌλ―Έν„°)
  • Projection Layer: λΉ„μ „ 토큰을 μ–Έμ–΄ λͺ¨λΈ μž…λ ₯으둜 λ³€ν™˜ν•˜λŠ” νˆ¬μ‚¬ λ ˆμ΄μ–΄

2.3 ν•™μŠ΅ 방식

Chandra OCR 2의 ν•™μŠ΅μ€ β€œκ°•λ ₯ν•œ λ²”μš© 기반 λͺ¨λΈμ—μ„œ μ‹œμž‘ν•˜μ—¬, νƒœμŠ€ν¬ νŠΉν™” λ°μ΄ν„°λ‘œ 집쀑 νŒŒμΈνŠœλ‹β€ν•˜λŠ” 방식을 λ”°λ¦…λ‹ˆλ‹€.

기반 λͺ¨λΈ (Base Model)

Qwen 3.5λŠ” Alibaba의 Qwen νŒ€μ΄ κ°œλ°œν•œ λΉ„μ „-μ–Έμ–΄ λͺ¨λΈλ‘œ, 이미지와 ν…μŠ€νŠΈλ₯Ό ν•¨κ»˜ μ΄ν•΄ν•˜κ³  μΆ”λ‘ ν•  수 μžˆλŠ” λͺ¨λΈμž…λ‹ˆλ‹€. 이 λͺ¨λΈμ΄ Chandra OCR 2의 β€œμΈμ‹ λ°±λ³Έ(perception backbone)β€œμ„ μ œκ³΅ν•©λ‹ˆλ‹€.

νŒŒμΈνŠœλ‹ (Fine-tuning)

Datalab은 이 기반 λͺ¨λΈμ„ λ‹€μ–‘ν•œ μΉ΄ν…Œκ³ λ¦¬μ˜ λŒ€κ·œλͺ¨ λ¬Έμ„œ λ°μ΄ν„°μ…‹μœΌλ‘œ νŒŒμΈνŠœλ‹ν–ˆμŠ΅λ‹ˆλ‹€:

  • ν•™μˆ  λ…Όλ¬Έ, 기술 λ³΄κ³ μ„œ
  • 손글씨 양식 및 λ©”λͺ¨
  • λ³΅μž‘ν•œ ν…Œμ΄λΈ” (병합 μ…€, 닀쀑 헀더)
  • μˆ˜ν•™ μˆ˜μ‹ (인라인/블둝)
  • λ‹€κ΅­μ–΄ λ¬Έμ„œ (90+ μ–Έμ–΄)
  • μŠ€μΊ”λœ λ¬Έμ„œ 및 팩슀
  • 닀단 λ ˆμ΄μ•„μ›ƒ (μ‹ λ¬Έ, κ΅κ³Όμ„œ)
  • 양식 (μ²΄ν¬λ°•μŠ€, λΌλ””μ˜€ λ²„νŠΌ)
  • 차트, λ‹€μ΄μ–΄κ·Έλž¨

νŒŒμΈνŠœλ‹μ˜ 핡심은 λ‹¨μˆœ 문자 인식이 μ•„λ‹ˆλΌ λ ˆμ΄μ•„μ›ƒ 인식(layout-aware) OCR에 μ΄ˆμ μ„ 맞좘 κ²ƒμž…λ‹ˆλ‹€. λͺ¨λΈμ΄ β€œλ¬Έμ„œκ°€ μ–΄λ–»κ²Œ μƒκ²ΌλŠ”μ§€β€λ₯Ό λ‚΄μž¬ν™”ν•˜μ—¬, μ½˜ν…μΈ μ˜ 쑴재뿐 μ•„λ‹ˆλΌ μœ„μΉ˜μ™€ 곡간적 κ΄€κ³„κΉŒμ§€ μ΄ν•΄ν•©λ‹ˆλ‹€.

2.4 λͺ¨λΈ μŠ€νŽ™

ν•­λͺ© κ°’
λͺ¨λΈλͺ… datalab-to/chandra-ocr-2
νŒŒλΌλ―Έν„° 수 5B (BF16)
λͺ¨λΈ 크기 ~10.6GB
기반 λͺ¨λΈ Qwen 3.5 (Vision-Language Model)
μ•„ν‚€ν…μ²˜ qwen3_5 (Transformers)
μ΅œλŒ€ 좜λ ₯ 토큰 12,384
μ •κ·œν™” μ’Œν‘œ 0-1000 (bbox)
λΌμ΄μ„ μŠ€ OpenRAIL-M (연ꡬ/개인/μŠ€νƒ€νŠΈμ—… 무료)

2.5 벀치마크 μ„±λŠ₯

olmOCR Benchmark (영문 λ¬Έμ„œ)

λͺ¨λΈ ArXiv Tables Multi-column Overall
Chandra 2 90.2 89.9 83.5 85.9
dots.ocr 1.5 85.9 90.7 85.3 83.9
Chandra 1 82.2 88.0 81.2 83.1
olmOCR 2 83.0 84.9 83.7 82.4
GPT-4o 53.5 70.0 69.3 69.9
Qwen 3 VL 8B 70.2 45.6 62.1 64.6

λ‹€κ΅­μ–΄ 벀치마크 (μ£Όμš” μ–Έμ–΄)

μ–Έμ–΄ Chandra 2 Gemini 2.5 Flash GPT-5 Mini
ν•œκ΅­μ–΄ (ko) 81.5% 84.8% 78.4%
일본어 (ja) 86.9% 80.0% 76.1%
쀑ꡭ어 (zh) 88.7% 70.0% 70.4%
μ˜μ–΄ (en) 94.8% 88.3% 93.8%
평균 (43개 μ–Έμ–΄) 77.8% 67.6% 60.5%

2.6 지원 λ¬Έμ„œ μœ ν˜•

μœ ν˜• μ„€λͺ…
손글씨 필기체, λ©”λͺ¨, μ˜μ‚¬ μ²˜λ°©μ „ λ“±
ν…Œμ΄λΈ” 병합 μ…€, 닀쀑 헀더, μž¬λ¬΄μ œν‘œ
μˆ˜μ‹ 인라인/블둝 μˆ˜μ‹ β†’ LaTeX λ³€ν™˜
양식 μ²΄ν¬λ°•μŠ€, λΌλ””μ˜€ λ²„νŠΌ, μž…λ ₯ ν•„λ“œ
닀단 λ ˆμ΄μ•„μ›ƒ μ‹ λ¬Έ, κ΅κ³Όμ„œ, ν•™μˆ  λ…Όλ¬Έ
차트/λ‹€μ΄μ–΄κ·Έλž¨ 데이터 μΆ”μΆœ, Mermaid λ³€ν™˜
화학식 SMILES ν‘œκΈ° λ³€ν™˜

3. μ‹œμŠ€ν…œ μ•„ν‚€ν…μ²˜

3.1 전체 ꡬ성도

                    μ™ΈλΆ€ ν΄λΌμ΄μ–ΈνŠΈ
                         β”‚
                    POST /process-file/
                         β”‚
                         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  DGX H200 μ„œλ²„ (10.150.6.159)                β”‚
β”‚                                                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                   β”‚
β”‚  β”‚  FastAPI μ„œλΉ„μŠ€        β”‚ ← 호슀트 μ‹€ν–‰ (uvicorn :10001)     β”‚
β”‚  β”‚  - 파일 μ—…λ‘œλ“œ/검증     β”‚                                   β”‚
β”‚  β”‚  - λ³΅ν˜Έν™” μš”μ²­          │──→ λ³΅ν˜Έν™” μ„œλ²„ (10.150.6.47:9001)  β”‚
β”‚  β”‚  - Officeβ†’PDF λ³€ν™˜     │──→ LibreOffice (libre1~4)        β”‚
β”‚  β”‚  - 이미지 μ „μ²˜λ¦¬        β”‚                                   β”‚
β”‚  β”‚  - Chandra OCR μš”μ²­    β”‚                                   β”‚
β”‚  β”‚  - κ²°κ³Ό νŒŒμ‹±/λ³€ν™˜       β”‚                                   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                   β”‚
β”‚             β”‚ http://localhost:10002                         β”‚
β”‚             β–Ό                                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                   β”‚
β”‚  β”‚  vLLM μ„œλ²„ (Docker)    β”‚ ← GPU #3 (H200 141GB)           β”‚
β”‚  β”‚  - chandra-ocr-2 λͺ¨λΈ  β”‚                                   β”‚
β”‚  β”‚  - OpenAI-compatible   β”‚                                   β”‚
β”‚  β”‚  - μ»¨ν…Œμ΄λ„ˆ λ‚΄λΆ€ :8000   β”‚                                   β”‚
β”‚  β”‚  - 호슀트 :10002        β”‚                                   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

3.2 처리 νŒŒμ΄ν”„λΌμΈ

1. 파일 μ—…λ‘œλ“œ
   β””β†’ MIME νƒ€μž… 검증, 크기 μ œν•œ (10MB)

2. λ³΅ν˜Έν™”
   β””β†’ 10.150.6.47:9001 λ³΅ν˜Έν™” μ„œλ²„ 호좜
   β””β†’ 이미지 νŒŒμΌμ€ λ³΅ν˜Έν™” μƒλž΅

3. 파일 λ³€ν™˜
   β””β†’ Office 파일 (docx, pptx λ“±) β†’ LibreOffice μ»¨ν…Œμ΄λ„ˆλ‘œ PDF λ³€ν™˜
   β””β†’ PDF β†’ PyMuPDF둜 νŽ˜μ΄μ§€λ³„ 이미지 μΆ”μΆœ

4. 이미지 μ „μ²˜λ¦¬
   β””β†’ 해상도 리사이징 (min: 100,352px / max: 1,003,520px)

5. Chandra OCR μΆ”λ‘ 
   β””β†’ vLLM μ„œλ²„μ— OCR Layout ν”„λ‘¬ν”„νŠΈ + 이미지 전솑
   β””β†’ HTML ν˜•μ‹ 응닡 μˆ˜μ‹  (data-bbox, data-label 포함)

6. 좜λ ₯ νŒŒμ‹±
   β””β†’ HTML β†’ Markdown λ³€ν™˜ (μˆ˜μ‹, ν…Œμ΄λΈ” 보쑴)
   β””β†’ HTML β†’ JSON λ ˆμ΄μ•„μ›ƒ 블둝 μΆ”μΆœ (bbox, category, text)
   β””β†’ HTML β†’ λ ˆμ΄μ•„μ›ƒ μ‹œκ°ν™” 이미지 생성

7. 응닡 λ°˜ν™˜
   β””β†’ full_markdown, filtered_markdown, page_markdowns,
      page_processed_images, json, total_pages

3.3 ꡬ성 μš”μ†Œλ³„ 상세

ꡬ성 μš”μ†Œ 기술 μŠ€νƒ 포트 μ—­ν• 
FastAPI Python 3.12, uvicorn, aiohttp 10001 API μ„œλ²„, 파일 처리 μ˜€μΌ€μŠ€νŠΈλ ˆμ΄μ…˜
vLLM vllm-openai:v0.17.0, Docker 10002 (μ™ΈλΆ€) / 8000 (λ‚΄λΆ€) Chandra OCR 2 λͺ¨λΈ μ„œλΉ™
LibreOffice libre1~4 Docker μ»¨ν…Œμ΄λ„ˆ - Office β†’ PDF λ³€ν™˜
λ³΅ν˜Έν™” μ„œλ²„ 별도 μ„œλ²„ (10.150.6.47) 9001 μ•”ν˜Έν™” λ¬Έμ„œ λ³΅ν˜Έν™”

4. Chandra OCR 2의 μΆ”λ‘  방식

4.1 ν”„λ‘¬ν”„νŠΈ ꡬ쑰

Chandra OCR 2λŠ” 자체 λ„€μ΄ν‹°λΈŒ ν”„λ‘¬ν”„νŠΈλ₯Ό μ‚¬μš©ν•˜μ—¬ HTML ν˜•μ‹μ˜ λ ˆμ΄μ•„μ›ƒ 좜λ ₯을 μƒμ„±ν•©λ‹ˆλ‹€. κΈ°μ‘΄ DotsOCR의 λ ˆμ΄μ•„μ›ƒ JSON ν”„λ‘¬ν”„νŠΈμ™€λŠ” 근본적으둜 λ‹€λ₯Έ λ°©μ‹μž…λ‹ˆλ‹€.

OCR Layout ν”„λ‘¬ν”„νŠΈ (핡심)

λͺ¨λΈμ—κ²Œ 이미지λ₯Ό HTML λ ˆμ΄μ•„μ›ƒ λΈ”λ‘μœΌλ‘œ OCRν•˜λ„λ‘ μ§€μ‹œν•©λ‹ˆλ‹€. 각 블둝은 <div> νƒœκ·Έμ— data-bbox(λ°”μš΄λ”© λ°•μŠ€, 0-1000 μ •κ·œν™”)와 data-label(λ ˆμ΄λΈ”)을 ν¬ν•¨ν•©λ‹ˆλ‹€.

지원 λ ˆμ΄λΈ” λͺ©λ‘:

λ ˆμ΄λΈ” μ„€λͺ…
Text 일반 ν…μŠ€νŠΈ 단락
Section-Header μ„Ήμ…˜/챕터 제λͺ©
Table ν…Œμ΄λΈ” (HTML ꡬ쑰 보쑴)
Image / Figure 이미지, λ„ν‘œ, 차트
Caption 이미지/ν…Œμ΄λΈ” μΊ‘μ…˜
Footnote 각주
Equation-Block μˆ˜μ‹ 블둝 (LaTeX)
List-Group λͺ©λ‘ (μˆœμ„œ/λΉ„μˆœμ„œ)
Form 양식 (μ²΄ν¬λ°•μŠ€, λΌλ””μ˜€ λ²„νŠΌ)
Code-Block μ½”λ“œ 블둝
Page-Header / Page-Footer 머리글/λ°”λ‹₯κΈ€
Table-Of-Contents λͺ©μ°¨
Complex-Block 볡합 λ ˆμ΄μ•„μ›ƒ
Chemical-Block 화학식 (SMILES)
Diagram λ‹€μ΄μ–΄κ·Έλž¨ (Mermaid)
Bibliography μ°Έκ³ λ¬Έν—Œ

4.2 λͺ¨λΈ 좜λ ₯ ν˜•μ‹

Chandra OCR 2λŠ” HTML을 좜λ ₯ν•˜λ©°, 각 λ ˆμ΄μ•„μ›ƒ 블둝이 <div> νƒœκ·Έλ‘œ κ΅¬λΆ„λ©λ‹ˆλ‹€:

<div data-bbox="64 66 850 105" data-label="Page-Header">
  <p>λ°˜λ„μ²΄ μ‹œμž₯ 뢄석 λ³΄κ³ μ„œ</p>
</div>
<div data-bbox="64 120 850 180" data-label="Section-Header">
  <h2>HBM μˆ˜κΈ‰ 전망</h2>
</div>
<div data-bbox="64 200 850 500" data-label="Text">
  <p>κΈ€λ‘œλ²Œ λ°˜λ„μ²΄ μ‹œμž₯은 2024λ…„ κΈ°μ€€...</p>
</div>
<div data-bbox="64 520 850 900" data-label="Table">
  <table><thead>...</thead><tbody>...</tbody></table>
</div>

4.3 좜λ ₯ νŒŒμ‹± νŒŒμ΄ν”„λΌμΈ

λͺ¨λΈμ˜ HTML 좜λ ₯은 μ„Έ κ°€μ§€ ν˜•νƒœλ‘œ λ³€ν™˜λ©λ‹ˆλ‹€:

Chandra HTML 좜λ ₯
    β”‚
    β”œβ”€β†’ parse_markdown()  β†’ Markdown ν…μŠ€νŠΈ
    β”‚     - μˆ˜μ‹: $...$ / $$...$$
    β”‚     - ν…Œμ΄λΈ”: HTML μœ μ§€
    β”‚     - 이미지: μ„€λͺ… ν…μŠ€νŠΈ
    β”‚
    β”œβ”€β†’ parse_chunks()    β†’ JSON λ°°μ—΄
    β”‚     - bbox: μ‹€μ œ 이미지 μ’Œν‘œ (0-1000 β†’ ν”½μ…€)
    β”‚     - category: λ ˆμ΄λΈ”
    β”‚     - text: HTML λ‚΄μš©
    β”‚
    └─→ draw_layout()     β†’ μ‹œκ°ν™” 이미지
          - λ ˆμ΄λΈ”λ³„ 색상 ꡬ뢄
          - λ°”μš΄λ”© λ°•μŠ€ μ˜€λ²„λ ˆμ΄

5. 배포 ꡬ성

5.1 μ„œλ²„ ν™˜κ²½

ν•­λͺ© κ°’
μ„œλ²„ DGX H200
IP 10.150.6.159
GPU NVIDIA H200 Γ— 8 (141GB VRAM 각)
Chandra ν• λ‹Ή GPU #3
OS Ubuntu
Docker 24.0+
Docker Compose v2

5.2 λͺ¨λΈ κ°€μ€‘μΉ˜

경둜: ~/projects/models/chandra-ocr-2/
파일:
β”œβ”€β”€ config.json
β”œβ”€β”€ generation_config.json
β”œβ”€β”€ model.safetensors          # ~10.6GB
β”œβ”€β”€ preprocessor_config.json
β”œβ”€β”€ processor_config.json
β”œβ”€β”€ tokenizer.json
β”œβ”€β”€ tokenizer_config.json
β”œβ”€β”€ chat_template.jinja
└── video_preprocessor_config.json

5.3 Docker Compose ꡬ성

vLLM μ„œλ²„ (GPU)

vllm-server:
  image: vllm/vllm-openai:v0.17.0
  container_name: chandra-vllm
  environment:
    - NVIDIA_VISIBLE_DEVICES=3
    - CUDA_VISIBLE_DEVICES=3
    - HF_HUB_OFFLINE=1
    - TRANSFORMERS_OFFLINE=1
  command: >
    --model /models/chandra-ocr-2
    --served-model-name chandra
    --dtype bfloat16
    --max-model-len 32768
    --max-num-seqs 64
    --max-num-batched-tokens 8192
    --enable-prefix-caching
    --gpu-memory-utilization 0.90
    --trust-remote-code
  deploy:
    resources:
      reservations:
        devices:
          - driver: nvidia
            device_ids: ["3"]
            capabilities: [gpu]

μ£Όμš” νŒŒλΌλ―Έν„° μ„€λͺ…:

νŒŒλΌλ―Έν„° κ°’ μ„€λͺ…
max-model-len 32768 μž…λ ₯+좜λ ₯ ν•©μ‚° μ΅œλŒ€ 토큰 수
max-num-seqs 64 λ™μ‹œ 처리 κ°€λŠ₯ν•œ μ‹œν€€μŠ€ 수
max-num-batched-tokens 8192 λ°°μΉ˜λ‹Ή μ΅œλŒ€ 토큰 수
gpu-memory-utilization 0.90 GPU λ©”λͺ¨λ¦¬ μ‚¬μš©λ₯  (90%)
enable-prefix-caching true OCR ν”„λ‘¬ν”„νŠΈκ°€ λ™μΌν•˜λ―€λ‘œ μΊμ‹±μœΌλ‘œ μ„±λŠ₯ ν–₯상

5.4 FastAPI μ„œλΉ„μŠ€

ν˜„μž¬ 호슀트의 κ°€μƒν™˜κ²½μ—μ„œ 직접 μ‹€ν–‰ 쀑:

nohup bash -c 'uvicorn main:app --host 0.0.0.0 --port 10001 \
  --workers 20 --log-level info | tee -a uvicorn.log' > nohup.out 2>&1 &

μ»¨ν…Œμ΄λ„ˆν™” 버전도 μ€€λΉ„λ˜μ–΄ 있으며, chandra-fastapi:latest μ΄λ―Έμ§€λ‘œ μ „ν™˜ κ°€λŠ₯ν•©λ‹ˆλ‹€.


6. API μ‚¬μš© κ°€μ΄λ“œ

6.1 μ—”λ“œν¬μΈνŠΈ

POST http://10.150.6.159:10001/process-file/

6.2 μš”μ²­ νŒŒλΌλ―Έν„°

νŒŒλΌλ―Έν„° νƒ€μž… κΈ°λ³Έκ°’ μ„€λͺ…
file File (ν•„μˆ˜) μ—…λ‘œλ“œν•  λ¬Έμ„œ 파일
highqual bool false 고해상도 처리 λͺ¨λ“œ

6.3 지원 파일 ν˜•μ‹

ꡬ뢄 ν™•μž₯자
PDF .pdf
Word .doc, .docx
PowerPoint .ppt, .pptx
Excel .xls, .xlsx
이미지 .jpg, .jpeg, .png, .bmp

6.4 호좜 μ˜ˆμ‹œ

Python:

import requests
import json

API_URL = "http://10.150.6.159:10001/process-file/"

with open("document.pdf", "rb") as f:
    response = requests.post(API_URL, files={"file": f})

result = response.json()

# 전체 λ§ˆν¬λ‹€μš΄
print(result["full_markdown"])

# νŽ˜μ΄μ§€λ³„ λ§ˆν¬λ‹€μš΄
for i, page_md in enumerate(result["page_markdowns"]):
    print(f"=== Page {i+1} ===")
    print(page_md)

# λ ˆμ΄μ•„μ›ƒ JSON
print(json.dumps(result["json"], indent=2, ensure_ascii=False))

curl:

curl -X POST http://10.150.6.159:10001/process-file/ \
  -F "file=@document.pdf"

고해상도 λͺ¨λ“œ:

curl -X POST "http://10.150.6.159:10001/process-file/?highqual=true" \
  -F "file=@document.pdf"

6.5 응닡 ν•„λ“œ

ν•„λ“œ νƒ€μž… μ„€λͺ…
job_id string μš”μ²­λ³„ 고유 μ‹λ³„μž (UUID)
filename string μ—…λ‘œλ“œλœ 원본 파일λͺ…
status string 처리 μƒνƒœ ("processed")
total_pages int 총 νŽ˜μ΄μ§€ 수
full_markdown string Base64 이미지 포함 전체 λ§ˆν¬λ‹€μš΄. λ¬Έμ„œ 원본 μž¬ν˜„μš©
filtered_markdown string 이미지 μ œμ™Έ ν…μŠ€νŠΈ μ „μš© λ§ˆν¬λ‹€μš΄. RAG/LLM μž…λ ₯에 적합
page_markdowns list[string] νŽ˜μ΄μ§€λ³„ λΆ„λ¦¬λœ λ§ˆν¬λ‹€μš΄ λ°°μ—΄
page_processed_images list[string] λ ˆμ΄μ•„μ›ƒ μ‹œκ°ν™” 이미지 (Base64 PNG). OCR ν’ˆμ§ˆ κ²€μ¦μš©
json list[dict] / dict κ΅¬μ‘°ν™”λœ λ ˆμ΄μ•„μ›ƒ 데이터 (bbox + category + text)

JSON ν•„λ“œ 상세:

{
  "bbox": [64, 66, 850, 105],
  "category": "Section-Header",
  "text": "<h2>HBM μˆ˜κΈ‰ 전망</h2>"
}
  • bbox: λ°”μš΄λ”© λ°•μŠ€ [x1, y1, x2, y2] (ν”½μ…€ λ‹¨μœ„)
  • category: λ ˆμ΄μ•„μ›ƒ 블둝 μœ ν˜•
  • text: ν•΄λ‹Ή λΈ”λ‘μ˜ HTML λ‚΄μš©

6.6 μ—λŸ¬ 응닡

HTTP μ½”λ“œ 상황
400 μ§€μ›ν•˜μ§€ μ•ŠλŠ” 파일 ν˜•μ‹
413 파일 크기 초과 (10MB μ œν•œ)
500 λ‚΄λΆ€ μ„œλ²„ 였λ₯˜

7. 운영 κ°€μ΄λ“œ

7.1 μ„œλΉ„μŠ€ μƒνƒœ 확인

# API μ„œλ²„ μƒνƒœ
curl http://10.150.6.159:10001/

# vLLM μ„œλ²„ μƒνƒœ
curl http://localhost:10002/health

# λͺ¨λΈ 정보
curl http://localhost:10002/v1/models

# Docker μƒνƒœ
docker ps | grep chandra

# GPU μ‚¬μš©λŸ‰
nvidia-smi

7.2 둜그 확인

# vLLM 둜그
docker compose logs -f vllm-server
docker compose logs --tail 100 vllm-server

# FastAPI 둜그 (호슀트 μ‹€ν–‰ μ‹œ)
tail -f uvicorn.log

# FastAPI 둜그 (μ»¨ν…Œμ΄λ„ˆ μ‹€ν–‰ μ‹œ)
docker compose logs -f fastapi

7.3 μ„œλΉ„μŠ€ μž¬μ‹œμž‘

# vLLM μ„œλ²„ μž¬μ‹œμž‘
docker compose down vllm-server
docker compose up -d vllm-server

# FastAPI μž¬μ‹œμž‘ (호슀트 μ‹€ν–‰ μ‹œ)
kill $(lsof -t -i :10001)
nohup bash -c 'uvicorn main:app --host 0.0.0.0 --port 10001 \
  --workers 20 --log-level info | tee -a uvicorn.log' > nohup.out 2>&1 &

7.4 νŠΈλŸ¬λΈ”μŠˆνŒ…

증상 원인 ν•΄κ²°
context length is only N max-model-len λΆ€μ‘± docker-compose.ymlμ—μ„œ κ°’ 증가 ν›„ μž¬κΈ°λ™
'category' KeyError DotsOCR ν”„λ‘¬ν”„νŠΈ μ‚¬μš© 쀑 Chandra λ„€μ΄ν‹°λΈŒ ν”„λ‘¬ν”„νŠΈλ‘œ ꡐ체 확인
Connection refused (10002) vLLM λͺ¨λΈ λ‘œλ”© 쀑 둜그 확인, λ‘œλ”© μ™„λ£Œ λŒ€κΈ° (1~3λΆ„)
GPU OOM λ™μ‹œ μš”μ²­ κ³Όλ‹€ max-num-seqs, gpu-memory-utilization μ‘°μ •
ν•œκΈ€ 깨짐 이미지 해상도 λΆ€μ‘± highqual=true λ˜λŠ” max_pixels 증가
Office λ³€ν™˜ μ‹€νŒ¨ LibreOffice μ»¨ν…Œμ΄λ„ˆ 문제 docker ps둜 libre1~4 μƒνƒœ 확인

8. 폐쇄망 배포 절차

사내 폐쇄망 ν™˜κ²½μ—μ„œμ˜ λ°°ν¬λŠ” μ™ΈλΆ€ PCμ—μ„œ λΉŒλ“œ ν›„ μ „μ†‘ν•˜λŠ” λ°©μ‹μœΌλ‘œ μˆ˜ν–‰ν•©λ‹ˆλ‹€.

8.1 전솑 파일 λͺ©λ‘

파일 μš©λŸ‰ μ„€λͺ…
vllm-openai-v0.17.0.tar.gz ~4-5GB vLLM μ„œλ²„ Docker 이미지
chandra-fastapi.tar.gz ~1GB FastAPI μ„œλΉ„μŠ€ Docker 이미지 (선택)
chandra-ocr-2-model/ ~10.6GB λͺ¨λΈ κ°€μ€‘μΉ˜
docker-compose.yml - μ„œλΉ„μŠ€ ꡬ성 파일
μ†ŒμŠ€ μ½”λ“œ (*.py) - FastAPI μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ½”λ“œ

8.2 배포 μˆœμ„œ

[μ™ΈλΆ€ PC (인터넷 κ°€λŠ₯)]
  1. λͺ¨λΈ κ°€μ€‘μΉ˜ λ‹€μš΄λ‘œλ“œ (huggingface_hub)
  2. Docker 이미지 Pull/Build
  3. docker save | gzip β†’ tar.gz
  4. USB/μ™Έμž₯HDD둜 전솑

[폐쇄망 μ„œλ²„]
  5. docker load < *.tar.gz
  6. λͺ¨λΈ 파일 배치
  7. docker-compose.yml 배치
  8. docker compose up -d
  9. λ™μž‘ 확인

8.3 폐쇄망 ν•„μˆ˜ ν™˜κ²½λ³€μˆ˜

HF_HUB_OFFLINE=1          # HuggingFace Hub μ™ΈλΆ€ 접속 차단
TRANSFORMERS_OFFLINE=1     # Transformers μ™ΈλΆ€ 접속 차단

9. μ†ŒμŠ€ μ½”λ“œ ꡬ쑰

~/projects/chandra/scripts/
β”œβ”€β”€ main.py                  # FastAPI μ•± (μ—”λ“œν¬μΈνŠΈ μ •μ˜)
β”œβ”€β”€ config_chandra.py        # μ„€μ • (vLLM μ£Όμ†Œ, ν”„λ‘¬ν”„νŠΈ, ν—ˆμš© νƒ€μž… λ“±)
β”œβ”€β”€ tool_chandra.py          # λ¬Έμ„œ 처리 핡심 둜직 (ν”„λ‘¬ν”„νŠΈ, νŒŒμ‹±, μ‹œκ°ν™”)
β”œβ”€β”€ utils_chandra.py         # μœ ν‹Έλ¦¬ν‹° (이미지 처리, PDF λ³€ν™˜, LibreOffice 연동)
β”œβ”€β”€ inference_chandra.py     # vLLM 비동기 μΆ”λ‘  λͺ¨λ“ˆ
β”œβ”€β”€ docker-compose.yml       # Docker μ„œλΉ„μŠ€ ꡬ성
β”œβ”€β”€ Dockerfile               # FastAPI μ»¨ν…Œμ΄λ„ˆ λΉŒλ“œμš©
└── requirements.txt         # Python μ˜μ‘΄μ„±
파일 μ—­ν• 
main.py FastAPI μ•±. POST /process-file/ μ—”λ“œν¬μΈνŠΈ μ •μ˜. κΈ°μ‘΄ DotsOCRκ³Ό λ™μΌν•œ μΈν„°νŽ˜μ΄μŠ€ μœ μ§€
config_chandra.py vLLM μ„œλ²„ μ£Όμ†Œ, λͺ¨λΈλͺ…, 토큰 μ œν•œ, 이미지 리사이징 μ„€μ •, λ³΅ν˜Έν™” μ„œλ²„ μ£Όμ†Œ λ“±
tool_chandra.py Chandra λ„€μ΄ν‹°λΈŒ ν”„λ‘¬ν”„νŠΈ μ •μ˜, HTMLβ†’Markdown/JSON νŒŒμ‹±, λ ˆμ΄μ•„μ›ƒ μ‹œκ°ν™”, λ³΅ν˜Έν™”, μž¬μ‹œλ„ 둜직
utils_chandra.py 이미지 리사이징, PDF→이미지 λ³€ν™˜, LibreOffice 연동, λ§ˆν¬λ‹€μš΄ 문법 μ •μ œ
inference_chandra.py vLLM OpenAI-compatible API 비동기 호좜

10. 참고 자료

ν•­λͺ© 링크
Chandra GitHub https://github.com/datalab-to/chandra
Chandra OCR 2 (HuggingFace) https://huggingface.co/datalab-to/chandra-ocr-2
vLLM 곡식 λ¬Έμ„œ https://docs.vllm.ai
Qwen 3.5 λͺ¨λΈ https://github.com/QwenLM/Qwen3
olmOCR Benchmark https://github.com/allenai/olmocr
Datalab Playground https://www.datalab.to/playground