add files
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
# Architecture
|
||||
|
||||
## Scope
|
||||
현재 구현 목표는 1차 목표인 Windows native, local-first CLI/library 변환 엔진입니다.
|
||||
|
||||
- 기본 parser: `Marker`
|
||||
- 기본 수식 parser: `Nougat`
|
||||
- PDF 분석과 chunk 계획: `PyMuPDF`
|
||||
- 출력: Markdown chunk files plus assets
|
||||
- 기본 chunk 목표: 20페이지
|
||||
- 기본 runtime: CUDA
|
||||
- UI, hosted API, 기본 LLM 보정 경로는 1차 목표 범위 밖입니다.
|
||||
|
||||
## Architecture Principles
|
||||
- Marker-first architecture를 유지합니다.
|
||||
- Nougat은 전체 문서 parser가 아니라 수식 parser입니다.
|
||||
- PyMuPDF는 무거운 변환 전에 빠른 page-level 분석과 chunk 계획을 담당합니다.
|
||||
- 출력은 AI Agent가 탐색하기 쉬운 deterministic Markdown bundle이어야 합니다.
|
||||
- 복잡한 table/figure/formula 손실 가능성은 fallback과 품질 검증으로 다룹니다.
|
||||
- 생성 Markdown은 원문 문서 내용 중심이어야 하며 경고/오류 로그로 오염시키지 않습니다.
|
||||
|
||||
## Pipeline
|
||||
1. Input normalization
|
||||
- PDF path를 `pathlib` 기반으로 정규화합니다.
|
||||
- 한글, 공백, 긴 Windows 경로를 지원합니다.
|
||||
- document slug를 결정적으로 생성합니다.
|
||||
|
||||
2. Page pre-analysis
|
||||
- PyMuPDF로 page count, text length, image count, text-layer quality를 확인합니다.
|
||||
- 페이지별 OCR 필요 여부를 추정합니다.
|
||||
- 긴 문서는 20페이지 목표 chunk 계획을 세우되 logical block boundary 보존을 고려합니다.
|
||||
|
||||
3. Marker parse
|
||||
- Marker가 layout, OCR, reading order, body text, headings, tables, figures, captions, semantic blocks를 담당합니다.
|
||||
- Marker Document Model 또는 이에 준하는 구조화 출력을 내부 block model로 매핑합니다.
|
||||
|
||||
4. Formula handoff
|
||||
- Marker equation block 또는 수식 패턴이 감지된 block만 Nougat에 전달합니다.
|
||||
- Nougat 결과는 LaTeX 문자열 후보로 취급하며 validation과 fallback 정책을 통과해야 합니다.
|
||||
- Nougat 실패 시 Marker 원문 수식 문자열을 사용합니다.
|
||||
|
||||
5. Semantic enrichment
|
||||
- 수식 번호, figure 번호, table 번호, caption, 본문 참조를 식별합니다.
|
||||
- 식별 confidence가 충분하면 내부 Markdown link로 연결합니다.
|
||||
- header/footer/page-number 반복 패턴은 본문 흐름에서 제거하거나 분리합니다.
|
||||
|
||||
6. Markdown rendering
|
||||
- heading, paragraph, list, blockquote, table, figure, equation block을 Markdown으로 렌더링합니다.
|
||||
- Markdown table을 우선하되 복잡한 표는 제한적 HTML table 또는 이미지 fallback을 사용합니다.
|
||||
- 각 chunk에는 문서 제목, page range, chunk 번호 등 최소 frontmatter를 넣을 수 있습니다.
|
||||
|
||||
7. Asset writing
|
||||
- 이미지는 `images/` 아래 결정적 파일명으로 저장합니다.
|
||||
- figure 번호가 있으면 `{document-slug}_fig-{figure-number}.png`를 우선합니다.
|
||||
- 충돌 또는 번호 부재 시 chunk/page/block identifier를 사용합니다.
|
||||
- hash 기반 deduplication으로 중복 asset 저장을 줄입니다.
|
||||
|
||||
8. Validation and reporting
|
||||
- math delimiter balance, LaTeX environment pairs, table parseability, image link existence, caption matching, chunk boundary integrity를 검증합니다.
|
||||
- CLI는 progress bar와 chunk별 성공/실패를 표시합니다.
|
||||
- 오류와 경고는 stderr와 local log에 기록합니다.
|
||||
|
||||
## Planned Layout
|
||||
```text
|
||||
samples/ # regression and quality corpus
|
||||
tests/ # focused pytest coverage
|
||||
scripts/ # validation / harness helpers
|
||||
phases/ # executable Harness phase tickets
|
||||
src/ # source package, planned
|
||||
venv/ # repo-local Windows virtual environment, ignored by git
|
||||
output/ # conversion output, ignored by git
|
||||
```
|
||||
|
||||
## Harness Boundary
|
||||
- `docs/HARNESS.md` defines the planner/generator/evaluator workflow for long-running work.
|
||||
- `phases/` files are execution tickets, not architecture policy. Architecture policy remains in `docs/ARCHITECTURE.md`, `docs/CONVERSION_POLICY.md`, and `docs/ADR.md`.
|
||||
- Each implementation phase must keep parser, formula, pre-analysis, renderer, runtime, and UI responsibilities separated according to this document.
|
||||
- Evaluator checks should use hard thresholds from each step's Sprint Contract and the focused quality strategy below.
|
||||
|
||||
## Output Contract
|
||||
출력은 문서 slug 디렉터리 아래에 묶입니다.
|
||||
|
||||
```text
|
||||
output/
|
||||
└── document-slug/
|
||||
├── document-slug_001.md
|
||||
├── document-slug_002.md
|
||||
└── images/
|
||||
├── document-slug_fig-001.png
|
||||
└── document-slug_fig-003.png
|
||||
```
|
||||
|
||||
세부 규칙:
|
||||
- chunk Markdown 파일명은 `<slug>_<chunk-index:03d>.md`
|
||||
- image asset은 `images/`
|
||||
- 같은 입력과 같은 옵션은 같은 output path를 생성해야 합니다.
|
||||
- 별도 문서 sidecar metadata/log 산출물은 기본 output contract에 포함하지 않습니다.
|
||||
- local log와 resume state/cache는 runtime artifact이며 문서 출력 contract와 구분합니다.
|
||||
|
||||
## Runtime Policy
|
||||
- 기본 runtime은 `cuda`
|
||||
- explicit `--runtime cuda` 또는 `--device cuda`에서 CUDA가 준비되지 않았으면 빠르게 실패
|
||||
- `--runtime auto`는 필요 시 CPU fallback 경고를 출력
|
||||
- GTX 1070 Ti 8GB 기준 batch size는 1~2 수준에서 시작
|
||||
- GPU OOM 시 가능한 경우 batch/page 단위를 줄여 재시도
|
||||
- 수식 parser 기본값은 `nougat`
|
||||
- verified PyTorch baseline은 `torch==2.7.1+cu126`
|
||||
|
||||
## Environment
|
||||
단일 repo-local Python 3.11 `venv`를 사용합니다.
|
||||
|
||||
```powershell
|
||||
conda create -p .\venv python=3.11 -y
|
||||
.\venv\python.exe -m pip install -r requirements.txt
|
||||
```
|
||||
|
||||
주요 pin:
|
||||
- `torch==2.7.1+cu126`
|
||||
- `torchvision==0.22.1+cu126`
|
||||
- `marker-pdf==1.10.2`
|
||||
- `nougat-ocr==0.1.17`
|
||||
- `transformers==4.57.6`
|
||||
- `albumentations==1.3.1`
|
||||
- `pypdfium2==4.30.0`
|
||||
- `opencv-python-headless==4.11.0.86`
|
||||
- `Pillow==10.4.0`
|
||||
- `fsspec==2026.2.0`
|
||||
|
||||
## Model Cache And Offline Mode
|
||||
- 모델 cache 위치는 명시적으로 관리해야 합니다.
|
||||
- 최초 다운로드 이후 offline 실행 시 이미 받은 weight를 우선 사용해야 합니다.
|
||||
- README에는 model download와 offline 실행 절차를 별도로 추가해야 합니다.
|
||||
|
||||
## Quality Strategy
|
||||
- 전체 Markdown snapshot 비교는 주요 검증 방식으로 사용하지 않습니다.
|
||||
- focused assertions를 우선합니다.
|
||||
- 검증 대상:
|
||||
- heading hierarchy
|
||||
- math delimiter balance
|
||||
- LaTeX `\begin` / `\end` pairs
|
||||
- image link existence
|
||||
- figure/table/formula caption matching
|
||||
- table parseability
|
||||
- chunk boundary integrity
|
||||
- Windows path and Korean filename handling
|
||||
- no-exception conversion
|
||||
|
||||
## Out of Scope for the First Goal
|
||||
- PyQt UI 구현
|
||||
- hosted conversion API 기본 경로화
|
||||
- LLM 보정 모드 기본 경로화
|
||||
- 생성 문서와 함께 배포되는 별도 sidecar metadata/log 산출물
|
||||
Reference in New Issue
Block a user