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>` ํƒœ๊ทธ๋กœ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค:
```html
<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)**
```yaml
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 ์„œ๋น„์Šค
ํ˜„์žฌ ํ˜ธ์ŠคํŠธ์˜ ๊ฐ€์ƒํ™˜๊ฒฝ์—์„œ ์ง์ ‘ ์‹คํ–‰ ์ค‘:
```bash
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:**
```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:**
```bash
curl -X POST http://10.150.6.159:10001/process-file/ \
-F "file=@document.pdf"
```
**๊ณ ํ•ด์ƒ๋„ ๋ชจ๋“œ:**
```bash
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 ํ•„๋“œ ์ƒ์„ธ:**
```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 ์„œ๋น„์Šค ์ƒํƒœ ํ™•์ธ
```bash
# 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 ๋กœ๊ทธ ํ™•์ธ
```bash
# 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 ์„œ๋น„์Šค ์žฌ์‹œ์ž‘
```bash
# 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 ํ์‡„๋ง ํ•„์ˆ˜ ํ™˜๊ฒฝ๋ณ€์ˆ˜
```bash
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 |