HPD-Parsing: 고처리량 문서 파싱용 계층 병렬 VLM
문서 레이아웃의 전역성과 내용의 지역성을 활용해 기존 VLM의 단일 궤적 생성을 '전역 레이아웃 조정+지역 내용 병렬 디코딩'으로 재구성하고, P-MTP로 문서 파싱 추론 처리량을 높인 기법을 분석한 글이다.
중국어 원문을 AI로 번역했습니다. 고유명사와 수치는 원문 표기를 우선하며, 중요한 판단에는 아래 출처 원문을 함께 확인하세요.
이 글은 VLM(Vision-Language Model, 시각 언어 모델), vLLM(대규모 모델 추론 및 서빙 프레임워크), 문서 파싱 시스템 개발 경험이 어느 정도 있는 엔지니어를 대상으로 하며, 바이두 페이파 PaddleOCR이 최근 발표한 HPD-Parsing을 중점적으로 소개한다. 모델 아키텍처, 계층 병렬 디코딩 원리, 성능 지표, 배포 방식, API 호출, 입출력 형식, 그리고 엔지니어링 적용 시 주의해야 할 문제를 포함한다.
一. 서문
최근 몇 년간 VLM(Vision-Language Model, 시각 언어 모델) 기반의 통합형 문서 파싱이 복잡한 문서 처리의 중요한 기술 노선으로 점차 자리 잡았다.
전통적인 문서 파싱 시스템은 보통 여러 전용 모델로 구성된 파이프라인을 사용한다:
PDF / 이미지 │ ▼ 문서 이미지 전처리 │ ▼ 레이아웃 분석(Layout Analysis) │ ├── OCR(문자 인식) ├── 표 인식 ├── 수식 인식 ├── 이미지 검출 └── 읽기 순서 복원 │ ▼ 후처리 │ ▼ Markdown / JSON
이러한 아키텍처는 모듈화 특성이 매우 좋지만 시스템이 상당히 복잡하다. 서로 다른 모듈 사이에는 데이터 변환, 좌표 매핑, 작업 스케줄링, 예외 처리 등의 문제가 존재한다.
반면 통합형 VLM 문서 파싱은 이러한 작업들을 하나의 모델로 통합하려고 시도한다:
문서 이미지 │ ▼ 시각 언어 모델 │ ▼ 구조화된 문서 결과
시스템 아키텍처 관점에서 보면 이런 방식이 분명 더 간결하다.
하지만 이는 새로운 문제를 하나 가져온다:
생성 속도.
전통적인 통합형 VLM은 보통 자기회귀 생성(Autoregressive Generation)을 사용한다. 즉 모델이 한 번에 하나의 Token(모델이 텍스트를 처리하는 기본 단위)을 생성하고, 이미 생성된 결과에 따라 다음 Token을 계속 생성한다.
그 과정은 간단히 다음과 같이 나타낼 수 있다:
Token 1 ↓ Token 2 ↓ Token 3 ↓ Token 4 ↓ ... ↓ Token N
일반적인 질의응답 작업에서는 이런 방식이 대체로 받아들일 만하다.
하지만 문서 파싱에는 매우 뚜렷한 특징이 하나 있다:
출력이 보통 매우 길다.
복잡한 한 페이지에는 동시에 다음이 포함될 수 있다:
- 제목
- 본문
- 다단 텍스트
- 이미지
- 이미지 캡션
- 표
- 수식
- 머리글
- 바닥글
- 페이지 번호
최종적으로 생성되는 구조화 결과는 수천 개, 심지어 그 이상의 Token을 포함할 수 있다.
따라서 출력 길이가 늘어날수록 자기회귀 생성의 순차적 의존성은 점점 더 뚜렷해진다.
HPD-Parsing은 바로 이런 배경에서 제안되었다.
二. HPD-Parsing이란 무엇인가?
HPD-Parsing의 전체 명칭은 다음과 같다:
Hierarchical Parallel Document Parsing(계층 병렬 문서 파싱)
이는 바이두 페이파 PaddleOCR이 내놓은 경량·고처리량 문서 파싱 모델이며, 모델 규모는 약 1B(10억) 파라미터이다.
공식적으로 발표된 핵심 지표는 다음과 같다:
- OmniDocBench v1.6 Overall: 94.91%
- 최고 처리량: 4,752 TPS(Tokens Per Second, 초당 Token 수)
- 공식 테스트 조건에서 자기회귀 베이스라인 대비 처리량 약 3.06배 향상
- 페이지 처리량 2.68 PPS(Pages Per Second, 초당 페이지 수) 달성
공식 Model Card는 HPD-Parsing을 새로운 통합형 문서 파싱 패러다임으로 규정한다. 즉 더 이상 전체 페이지를 단일 자기회귀 궤적으로 생성하지 않고, 하나의 메인 레이아웃 분기가 전역 구조를 조율한 뒤 국소 내용을 여러 개의 동시 분기에 할당해 파싱하며, 동시에 P-MTP(Progressive Multi-Token Prediction, 점진적 다중 Token 예측)를 결합해 디코딩 단계를 더욱 줄인다.
따라서 HPD-Parsing에서 가장 주목할 만한 점은 "또 하나의 1B 문서 파싱 모델"이 아니라:
추론 아키텍처 차원에서 문서 파싱의 생성 과정을 재설계했다는 점이다.
三. 전통적 VLM 문서 파싱의 성능 병목
3.1 단일 궤적 자기회귀 생성
한 페이지가 최종적으로 6000개의 Token을 생성해야 한다고 가정하자.
전통적 모델은 대략 다음과 같이 필요하다:
Step 1 → Token 1 Step 2 → Token 2 Step 3 → Token 3 Step 4 → Token 4 ... Step 6000 → Token 6000
그 핵심 특징은 다음과 같다:
현재 Token의 생성이 앞선 Token에 의존한다.
따라서 GPU가 매우 강력한 병렬 연산 능력을 갖추고 있더라도, Decode(디코딩 생성) 단계에는 여전히天然的인 순차 의존성이 존재한다.
3.2 문서 파싱은 사실 완전히 순차적일 필요가 없다
다음과 같은 페이지를 생각해 보자:
┌───────────────────────────────────┐ │ 제목 │ ├────────────────┬──────────────────┤ │ │ │ │ 본문 영역 │ 이미지 │ │ │ │ ├────────────────┴──────────────────┤ │ 표 │ ├───────────────────────────────────┤ │ 본문 │ └───────────────────────────────────┘
여기에는 실제로 뚜렷한 국소성이 존재한다.
예를 들어:
본문 영역 A
와:
이미지 영역 B
사이에는 강한 내용 생성 의존성이 존재하지 않는다.
따라서 다음과 같이 강제할 필요가 없다:
본문 A 파싱 완료 ↓ 이미지 B 파싱 ↓ 표 C 파싱 ↓ 본문 D 파싱
완전히 순차적으로 실행할 필요가 없다.
이것이 바로 HPD-Parsing의 핵심 관찰이다:
문서 레이아웃은 전역적 조율이 필요하지만, 구체적인 내용은 흔히 뚜렷한 영역 국소성을 지닌다.
논문도 바로 이 관찰에 기반해 HPD(Hierarchical Parallel Decoding, 계층 병렬 디코딩) 패러다임을 제안했다.
四. HPD-Parsing의 전체 아키텍처
HPD-Parsing은 InternVL3.5-1B를 Backbone(백본 모델)으로 사용하며, 동적 Tile(슬라이스) 메커니즘을 통해 고해상도 문서 이미지를 처리한다.
공식 Model Card는 최대 24개의 448×448 Tile을 사용할 수 있다고 설명한다.
전체 아키텍처는 다음과 같이 추상화할 수 있다:
문서 이미지 │ ▼ Dynamic Tiling(동적 이미지 슬라이싱) │ ▼ InternVL3. 5 - 1 B 시각 언어 백본 │ ▼ Main Layout Branch(메인 레이아웃 분기) │ 전역 문서 구조 조율 │ ┌──────────────┼──────────────┐ ▼ ▼ ▼ Content Branch Content Branch Content Branch 국소 영역 A 국소 영역 B 국소 영역 C │ │ │ ▼ ▼ ▼ P -MTP P -MTP P -MTP │ │ │ └──────────────┼──────────────┘ ▼ 구조화 결과
전체 아키텍처는 세 가지 핵심 구성 요소로 요약할 수 있다:
- 시각 인코딩 및 고해상도 이미지 처리
- Hierarchical Parallel Decoding(계층 병렬 디코딩)
- P-MTP(점진적 다중 Token 예측)
五. 시각 입력: InternVL3.5-1B와 Dynamic Tiling
HPD-Parsing은 InternVL3.5-1B를 기반 시각 언어 모델로 사용한다.
문서 파싱과 일반 이미지 이해의 가장 큰 차이 중 하나는:
문서 이미지 속 글자가 보통 매우 작다는 점이다.
예를 들어 A4 한 페이지에는 다음이 포함될 수 있다:
제목 본문 표 각주 수식 이미지 설명
만약 A4 페이지 전체를 단순히 고정 크기로 축소하면:
A4 페이지 ↓ 448 × 448
작은 글씨 텍스트가 쉽게 손실된다.
따라서 HPD-Parsing은 Dynamic Tiling(동적 슬라이싱) 방식으로 고해상도 문서를 처리한다.
간단히 이해하면 다음과 같다:
원본 페이지 ┌────────┬────────┬────────┐ │ Tile 1 │ Tile 2 │ Tile 3 │ ├────────┼────────┼────────┤ │ Tile 4 │ Tile 5 │ Tile 6 │ ├────────┼────────┼────────┤ │ Tile 7 │ Tile 8 │ Tile 9 │ └────────┴────────┴────────┘
공식 아키텍처 설명에서는 최대 24개의 448×448 Tile을 지원한다.
이를 통해 제한된 시각 Token 예산 안에서 문서의 세밀한 문자와 레이아웃 정보를 더 잘 보존할 수 있다.
六. 핵심 기술: Hierarchical Parallel Decoding
6.1 계층 병렬 디코딩이란 무엇인가?
HPD(Hierarchical Parallel Decoding, 계층 병렬 디코딩)의 핵심 사상은 다음과 같이 요약할 수 있다:
먼저 전역 레이아웃을 해결하고, 그다음 국소 내용을 병렬로 처리한다.
전통적 통합형 문서 파싱:
전체 페이지 │ ▼ 단일 생성 궤적 │ ▼ Token 1 → Token 2 → Token 3 → ... → Token N
HPD:
전체 페이지 │ ▼ 메인 레이아웃 분기 │ ├──────────────┬──────────────┐ ▼ ▼ ▼ 국소 내용 A 국소 내용 B 국소 내용 C │ │ │ ▼ ▼ ▼ 병렬 Decode 병렬 Decode 병렬 Decode
따라서 HPD는 다음을 동시에 활용한다:
- 문서의 전역 구조 정보;
- 문서 영역 사이의 국소 독립성;
- GPU 병렬 연산 능력.
七. Main Layout Branch: 메인 레이아웃 분기
HPD-Parsing은 단순히 페이지를 몇 개 영역으로 잘라 독립적으로 모델을 호출하는 것이 아니다.
그것은 먼저 다음을 구축해야 한다:
전역 Layout(레이아웃) 구조.
따라서 Main Layout Branch(메인 레이아웃 분기)가 존재한다.
그것은 주로 다음 질문에 답하는 역할을 한다:
페이지에는 어떤 영역이 있는가? 이 영역들은 어떤 유형인가? 그들 사이에는 어떤 관계가 있는가? 이 영역들의 읽기 순서는 무엇인가? 어떤 영역이 국소 내용을 추가로 생성해야 하는가?
페이지 │ ▼ Main Layout Branch │ ┌─────────┼─────────┐ ▼ ▼ ▼ Title Image Table │ │ │ ▼ ▼ ▼ Branch A Branch B Branch C
이것이 바로 HPD에서의 "Hierarchical(계층)"이다.
八. Content Branch: 국소 내용 분기
페이지 구조가 결정되면, 모델은 서로 다른 영역에 대해 국소 내용 분기를 생성한다.
페이지 │ ├── 제목 │ └── Content Branch A │ ├── 본문 │ └── Content Branch B │ ├── 표 │ └── Content Branch C │ └── 이미지 └── Content Branch D
각 Content Branch(내용 분기)는 하나의 국소 영역을 담당한다.
따라서:
Branch A ─────┐ Branch B ─────┤ Branch C ─────┼──→ 병렬 실행 Branch D ─────┘
전통적 방식:
A → B → C → D
A ─┐ B ─┤ C ─┼──→ 병렬 D ─┘
이것이 첫 번째 계층의 가속이다.
九. Dynamic Request Forking: 동적 요청 분기
위 아키텍처를 실제로 구현하려면 모델 구조만 수정해서는 충분하지 않다.
추론 프레임워크도 다음을 지원해야 한다:
하나의 부모 요청이 동적으로 여러 자식 요청을 생성하는 것.
이것이 바로 Dynamic Request Forking(동적 요청 분기)이다.
다음과 같이 이해할 수 있다:
Parent Request │ ├──── Child Request A │ ├──── Child Request B │ ├──── Child Request C │ └──── Child Request D
전통적인 vLLM 요청 스케줄링 모델은 이런 계층 분기를 위해 특별히 설계된 것이 아니므로, HPD-Parsing은 커스터마이즈된 버전의 vLLM을 사용한다.
공식 문서는 명확히 밝힌다:
HPD-Parsing은 vLLM 0.17.1 기반의 커스터마이즈 버전을 사용하며, 계층 병렬 디코딩에 필요한 동적 요청 분기 메커니즘을 추가하고 P-MTP 추측 디코딩을 지원한다.
이것이 바로 단순히:
pip install vllm
한 뒤 바로 HPD-Parsing을 로드할 수 없는 이유이기도 하다.
十. Shared Prefix KV Cache: 공유 프리픽스 키-값 캐시
여러 Content Branch는 흔히 동일한 프리픽스(prefix)를 공유한다.
System / Image / Layout Prefix │ ┌─────┼─────┐ ▼ ▼ ▼ A B C
만약 각 브랜치마다 Prefix(프리픽스)를 다시 계산한다면 계산 비용이 매우 높아진다.
따라서 HPD-Parsing은 Shared Prefix KV Cache(공유 프리픽스 키-값 캐시)를 사용한다.
Shared Prefix KV Cache │ ┌───────────┼───────────┐ ▼ ▼ ▼ Branch A Branch B Branch C
이렇게 하면 서로 다른 브랜치가 앞서 이미 계산해 둔 Key / Value를 공유할 수 있다.
공식 Model Card는 공유 프리픽스 KV Cache를 특별히 강조하며, vLLM의 Paged KV Cache(페이지드 키-값 캐시)가 동시 브랜치 및 프리픽스 공유를 지원할 수 있다고 지적한다.
11. P-MTP: 점진적 다중 토큰 예측
서로 다른 영역이 이미 병렬 처리될 수 있더라도, 각 Branch 내부에는 여전히 다음이 존재한다.
Token 1 ↓ Token 2 ↓ Token 3 ↓ Token 4 ↓ ...
따라서 HPD-Parsing은 다시 다음을 도입했다.
Progressive Multi-Token Prediction(점진적 다중 토큰 예측, P-MTP)
이는 Speculative Decoding(투기적 디코딩) 기술의 한 가지 응용에 속한다.
11.1 일반 자기회귀 Decode
예를 들어 12개의 Token을 생성해야 한다면:
Step 1 → Token 1 Step 2 → Token 2 Step 3 → Token 3 ... Step 12 → Token 12
약 12개의 Decode Step(디코딩 단계)이 필요하다.
11.2 P-MTP
P-MTP는 한 번의 반복에서 여러 미래 Token을 예측하려고 시도한다.
Step 1 → Token 1 Token 2 Token 3 Token 4 ... Step 2 → Token 5 Token 6 Token 7 Token 8 ...
실제 과정은 단순히 "한 번에 무조건 여러 Token을 생성하는" 것이 아니라, 투기적 예측과 검증 메커니즘을 결합하여 유효 Decode Step을 줄이는 것이다.
공식 서비스 시작 파라미터 중:
--speculative-config \ '{"method": "medusa" , "model" : ".../P-MTP" , "num_speculative_tokens" : 6 }'
그중:
num_speculative_tokens = 6
은 각 단계에서 최대 6개의 투기 Token을 사용한다는 의미이다.
12. HPD + P-MTP는 왜 눈에 띄게 가속할 수 있는가?
HPD는 실제로 두 방향에서 직렬 의존성을 줄인다.
첫 번째 층: Branch Parallelism(브랜치 병렬)
Layout │ ├── Branch A ├── Branch B ├── Branch C └── Branch D
해결하는 것:
서로 다른 문서 영역 사이의 직렬 의존성.
두 번째 층: Multi-Token Prediction(다중 Token 예측)
Branch A Step 1 → Token 1 ~ 6 Step 2 → Token 7 ~ 12 Step 3 → Token 13 ~ 18
단일 영역 내부의 Token-by-Token 직렬 문제.
HPD-Parsing │ ┌───────────┴───────────┐ ▼ ▼ Branch Parallelism P -MTP 분기 병렬 다중 Token 예측 │ │ ▼ ▼ 영역 간 직렬 감소 Token Decode Step 감소 │ │ └───────────┬───────────┘ ▼ 더 높은 추론 처리량
공식 실험에서도 문서 출력 길이가 증가함에 따라 HPD의 가속 이점이 더욱 확대되는 것으로 나타났다. 가장 긴 출력 길이 구간에서 공식은 최대 18.04× Decode Steps 감소, 3.67× Request Throughput(요청 처리량) 향상, 5.80× Single-Request Latency(단일 요청 지연) 감소를 보고했다.
13. HPD-Parsing의 성능 지표
HPD-Parsing 공식은 주로 OmniDocBench v1.6에서 평가를 진행한다.
그 핵심 지표는 다음과 같다.
지표 HPD-Parsing 모델 규모 약 1B OmniDocBench v1.6 Overall 94.91% 피크 TPS 4,752.1 PPS 2.68 Benchmark GPU NVIDIA A800 80GB Batch Size 512
공식 테스트에 따르면 Batch Size 512, NVIDIA A800 80GB, vLLM 환경에서:
PPS: 1.02 → 2.68 TPS: 1,554.8 → 4,752.1
대응:
PPS 향상: 2.62× TPS 향상: 3.06×
14. 다른 문서 파싱 모델과 비교할 때 어떻게 봐야 하는가?
여기서 특별히 강조할 점이 있다.
TPS는 페이지 파싱 속도와 직접적으로 동일시할 수 없다.
TPS:
Tokens Per Second(초당 Token 수)
PPS:
Pages Per Second(초당 페이지 수)
둘은 측정하는 대상이 다르다.
가정:
모델 A: 페이지당 1000 Token 출력 TPS = 3000
이론적으로:
PPS ≈ 3
그리고:
모델 B: 페이지당 3000 Token 출력 TPS = 5000
PPS ≈ 1.67
따라서 문서 파싱 모델을 선정할 때는 다음만 봐서는 안 된다.
또한 다음에도 주목해야 한다.
PPS P50 Latency P95 Latency P99 Latency GPU Memory Accuracy
15. HPD-Parsing과 DeepSeek-OCR-2의 처리량 비교
공식이 제시한 매우 가치 있는 비교가 있다.
HPD-Parsing은 페이지당 약 4,800개의 입력 Token을 처리하며, 이는 DeepSeek-OCR-2의 4배를 넘지만 더 높은 PPS와 TPS를 달성했다.
공식 데이터에 따르면:
HPD-Parsing 입력 Token ≈ 4,800 / page 그럼에도 도달: PPS = 2.68 TPS = 4 , 752.1
이는 HPD의 이점이 단순히 입력 Token을 줄이는 데서 오는 것이 아니라 주로 다음에서 온다는 것을 보여준다.
계층 병렬 디코딩 + 공유 프리픽스 KV Cache + P-MTP
다시 말해:
HPD-Parsing의 핵심 경쟁력은 추론 효율에 있으며, 모델 규모에만 있는 것이 아니다.
16. 정확도 성능
HPD-Parsing은 OmniDocBench v1.6에서 Overall이 다음에 도달한다.
94.91%
공식은 이를 현재 엔드투엔드 통합형 문서 파싱 모델 중 선도적인 결과라고 설명한다.
이는 HPD-Parsing의 목표가 다음이 아니라는 의미이다.
정확도를 낮춰 속도를 얻는 것
오히려:
비교적 높은 파싱 능력 유지 + Decode 재설계 ↓ 처리량 향상
다만 주의할 점:
Benchmark 결과는 기업의 실제 비즈니스 데이터에서의 최종 효과와 동등하지 않다.
실제 프로젝트에서의:
- 스캔 PDF
- 재무 보고서
- 계약서
- 기술 문서
- 논문
- 중국어 복잡 표
- 다단 조판
- 도장(인장)
- 필기 내용
은 공개 Benchmark와 뚜렷한 분포 차이가 있을 수 있다.
따라서 프로덕션 환경에서는 여전히 자체 비즈니스 데이터로 평가해야 한다.
17. 배포 환경 요구 사항
바이두 페이파이(PaddlePaddle) 공식 문서에 따르면, HPD-Parsing은 현재 다음을 요구한다.
GPU
이미 검증됨:
NVIDIA H100 NVIDIA H800 NVIDIA H20 NVIDIA A100 NVIDIA A800 NVIDIA A30 NVIDIA L20 RTX Pro 6000
NVIDIA 드라이버는 다음을 지원해야 한다.
CUDA 12.8+
운영체제
Linux x86-64
다른 운영체제는 Linux NVIDIA GPU 컨테이너를 실행할 수 있는 Docker 환경을 통해 사용해야 한다.
Python
미리 컴파일된 패키지를 사용하는 경우:
Python 3.10 ~ 3.13
Docker
> = 19.03
동시에 필요:
NVIDIA Container Toolkit
이러한 요구 사항은 모두 공식의 현재 사용 튜토리얼에서 온 것이다.
18. 쉽게 간과하는 문제: PaddleOCR를 설치할 필요가 없다
HPD-Parsing이 PaddleOCR 체계에 속하지만, 공식은 특별히 밝힌다.
HPD-Parsing은 paddleocr Python 패키지에 의존하지 않는다.
그것이 사용하는 것은:
HPD-Parsing │ ▼ 커스터마이즈 버전 vLLM │ ▼ GPU
이며, 전통적인:
Python ↓ paddleocr ↓ Paddle Inference
가 아니다.
따라서 일반 PaddleOCR 모델 방식대로 설치하고 호출해서는 안 된다.
19. 배포 방식 1: Docker
공식은 Docker 사용을 우선적으로 권장하는데, 이미 다음을 포함하고 있기 때문이다.
- 커스터마이즈 버전 vLLM
- HPD-Parsing에 필요한 의존성
- 추론 환경
공식 이미지:
ccr-2vdh3abv-pub.cnc.bj.baidubce.com/paddlepaddle/hpd-parsing-vllm:latest-nvidia-gpu
실행:
docker run \ -it \ --rm \ --gpus all \ --network host \ ccr- 2 vdh3abv-pub .cnc .bj .baidubce .com /paddlepaddle/hpd-parsing-vllm:latest-nvidia-gpu
기본 리스닝:
8118
공식 현재 문서에 따르면:
온라인 이미지: 약 20.2 GB 오프라인 이미지: 약 24.5 GB
오프라인 이미지:
ccr-2vdh3abv-pub.cnc.bj.baidubce.com/paddlepaddle/hpd-parsing-vllm:latest-nvidia-gpu-offline
오프라인 이미지는 이미 모델 가중치를 포함하고 있으므로, 인터넷에 접속할 수 없는 환경에 적합하다.
20. Docker 모델 캐시
온라인 이미지는 시작할 때 모델을 자동으로 다운로드한다.
만약 그대로 사용한다면:
docker run --rm ...
컨테이너 삭제 후 컨테이너 내부 캐시도 함께 사라질 수 있다.
따라서 프로덕션 환경에서는 캐시 마운트를 권장한다.
docker run \ -it \ --rm \ --gpus all \ --network host \ -v hpd_parsing_hf_cache:/home/hpd/.cache/huggingface \ ccr- 2 vdh3abv-pub.cnc.bj.baidubce.com/paddlepaddle/hpd-parsing-vllm:latest-nvidia-gpu
공식 문서에서도 이러한 캐시 재사용 방식을 제시했다.
21. 배포 방식 2: 미리 컴파일된 vLLM 설치
Docker를 사용할 수 없다면, 공식이 제공하는 커스터마이즈 버전 vLLM 미리 컴파일된 패키지를 직접 설치할 수 있다.
가상 환경 생성:
python -m venv .venv_hpd_parsing source .venv_hpd_parsing/bin/activate
설치:
python -m pip install \ https: / /paddle-model-ecology.bj.bcebos.com/paddlex /PaddleX3.0/deploy /hpd_parsing/vllm - 0.17 . 1 +hpdparsing-cp38-abi3-manylinux_2_31_x86_64.whl
그런 다음 모델 다운로드:
hf download PaddlePaddle/HPD-Parsing \ --local-dir ./HPD-Parsing
다운로드 후 반드시 확인:
HPD-Parsing/ ├── config.json └── P-MTP/ └── config.json
여기서:
P-MTP/
는 누락되어서는 안 된다.
왜냐하면 여기에는 P-MTP 추측 디코딩(speculative decoding)에 필요한 모델 가중치가 포함되어 있기 때문이다.
22. HPD-Parsing 서비스 시작하기
공식적으로 권장하는 서비스 시작 명령:
MODEL_PATH = "$(realpath ./HPD-Parsing)" MAX_PATCHES_WITH_RESIZE = true \ vllm serve "${MODEL_PATH}" \ --trust-remote-code \ --port 8118 \ --served-model-name HPD-Parsing \ --max-model-len 16384 \ --limit-mm-per-prompt '{"image": 1}' \ --gpu-memory-utilization 0.9 \ --attention-backend FLASHINFER \ --attention-config '{"use_prefill_query_quantization":true}' \ --enable-chunked-prefill \ --enable-prefix-caching \ --speculative-config \ "{" method ":"medusa","model":"${MODEL_PATH} / P - MTP","num_speculative_tokens":6}"
공식 문서에서 제시한 이 매개변수들은 HPD-Parsing이 성능을 정상적으로 발휘하는 데 중요한 구성 요소이다.
23. 시작 매개변수 상세 설명
매개변수 | 의미 | 역할 MAX_PATCHES_WITH_RESIZE=true | 최대 슬라이스 및 Resize 동작 | 공식 요구 사항 --trust-remote-code | 모델 원격 코드 신뢰 | 모델 사용자 정의 구현 로드 --port 8118 | 서비스 포트 | API 수신 포트 --served-model-name | 서비스 모델 이름 | API 호출 시 사용 --max-model-len | 최대 컨텍스트 길이 | 최대 컨텍스트 제어 --limit-mm-per-prompt | 요청당 최대 이미지 수 | 현재 설정은 1 --gpu-memory-utilization | GPU 메모리 사용률 | vLLM 메모리 사용 제어 --attention-backend FLASHINFER | Attention(어텐션 메커니즘) 백엔드 | 공식 권장 --enable-chunked-prefill | Chunked Prefill(청크 단위 프리필) | 긴 입력 최적화 --enable-prefix-caching | Prefix Caching(프리픽스 캐싱) | 프리픽스 재사용 지원 --speculative-config | 추측 디코딩 설정 | P-MTP 활성화
24. 왜 enable-prefix-caching이 매우 중요한가?
HPD의 아키텍처에는 본질적으로 다음이 존재한다:
Parent │ ├── Branch A ├── Branch B ├── Branch C └── Branch D
Prefix Caching이 없으면:
Prefix ├── A → 재계산 ├── B → 재계산 ├── C → 재계산 └── D → 재계산
으로 대량의 중복 계산이 발생한다.
Prefix Caching을 활성화하면:
Prefix KV Cache │ ┌──────────┼──────────┐ ▼ ▼ ▼ A B C
여러 분기가 공통 프리픽스를 재사용할 수 있다.
HPD에게 Prefix Caching은 평범한 "작은 최적화"가 아니라, 병렬 분기가 효율적으로 동작하기 위한 중요한 기반 시설이다.
25. OpenAI 호환 API
HPD-Parsing 서비스가 시작된 후, OpenAI Compatible API(OpenAI 호환 인터페이스)를 통해 호출할 수 있다.
python -m pip install openai
클라이언트:
from openai import OpenAI client = OpenAI( base_url = "http://127.0.0.1:8118/v1" , api_key = "EMPTY" , )
base_url
은 자신이 직접 배포한 HPD-Parsing 서비스를 가리킨다.
26. 입력 데이터 형식
HPD-Parsing은 OpenAI Chat Completions 스타일의 멀티모달 입력을 사용한다.
기본 구조:
{ "model" : "HPD-Parsing" , "messages" : [ { "role" : "user" , "content" : [ { "type" : "image_url" , "image_url" : { "url" : "data:image/png;base64,..." } } , { "type" : "text" , "text" : "document parsing with fork." } ] } ] , "max_tokens" : 8000 , "temperature" : 0 }
그중 가장 중요한 것은:
image_url
다음을 직접 사용할 수 있다:
data:image/png; base64 ,...
형태로 이미지를 전달한다.
공식 클라이언트 예시도 Base64 이미지 + 고정 Prompt 방식를 채택하고 있다.
27. Prompt는 왜 반드시 고정해야 하는가?
HPD-Parsing 공식은 다음을 사용하도록 요구한다:
document parsing with fork.
이 Prompt를 사용해야 한다.
주목:
이것은 일반적인 의미의 "이 이미지를 파싱해 주세요"가 아니다.
HPD-Parsing의 서버 측은 이 요청에 따라 해당하는 계층 병렬 파싱 모드로 진입한다.
따라서 다음으로 수정하는 것은 권장하지 않는다:
Please parse this document .
또는:
이 문서를 파싱해 주세요.
공식 문서는 문서 이미지를 파싱할 때 다음을 사용하도록 명확히 요구한다:
28. 전체 Python 호출 예시
import base64 from openai import OpenAI client = OpenAI( base_url = "http://127.0.0.1:8118/v1" , api_key = "EMPTY" , ) def encode_image(image_path: str) -> str: with open(image_path, "rb") as f: return base64.b64encode(f.read()).decode("utf-8") image_base64 = encode_image( "demo.png" ) response = client.chat.completions.create( model = "HPD-Parsing" , messages =[ { "role" : "user" , "content" : [ { "type" : "image_url" , "image_url" : { "url" : f "data:image/png;base64,{image_base64}" }, }, { "type" : "text" , "text" : "document parsing with fork." , }, ], } ], max_tokens = 8000 , temperature = 0 , ) result = response.choices[ 0 ].message.content print(result)
이 호출 방식은 공식의 현재 서비스화 호출 예시에 대응한다.
29. 입력 이미지는 무엇을 주의해야 하는가?
현재 서비스 설정이 다음과 같기 때문이다:
--limit-mm-per-prompt '{"image": 1 }'
이는 다음을 의미한다:
현재 하나의 요청은 한 장의 이미지로 제한된다.
따라서 원본 PDF에 100페이지가 있다면, 다음은 권장하지 않는다:
100페이지 이미지 ↓ 한 번의 API 요청
대신 다음과 같이 해야 한다:
PDF │ ▼ Page 1 ──→ Request 1 Page 2 ──→ Request 2 Page 3 ──→ Request 3 ... Page 100 → Request 100
그런 다음 상위 문서 작업 스케줄링 시스템이 다음을 담당한다:
작업 분할 + 동시 스케줄링 + 결과 병합 + 예외 재시도 + 순서 복원
30. 출력 데이터 형식
HPD-Parsing이 반환하는 것은 전통적인 OCR의 JSON이 아니다:
{ "text" : "..." , "boxes" : [ ... ] }
그것은 일종의 구조화된 문서 텍스트 표현이다.
핵심 구조는:
<BLOCK>block_type [x1, y1, x2, y2] <CHILD> content
<BLOCK>title [100, 80, 900, 150] <CHILD>문서 제목 <BLOCK>text [100, 180, 900, 400] <CHILD>여기는 본문 내용 <BLOCK>image [100, 450, 900, 800]
공식 문서는 각 레이아웃 블록이 <BLOCK>으로 시작하고, 이어서 차례로 다음을 포함한다고 명확히 밝힌다:
- Block 유형
- 바운딩 박스 좌표
- 선택적 <CHILD>
- 텍스트 내용
그리고 image 등 텍스트 내용이 없는 블록은 <CHILD>를 포함하지 않는다.
31. BLOCK 데이터 구조
다음을:
<BLOCK>text [100,200,800,400] <CHILD>Hello World
이렇게 이해할 수 있다:
{ "type" : "text" , "bbox" : [ 100 , 200 , 800 , 400 ] , "text" : "Hello World" }
type
은 레이아웃 블록 유형을 나타낸다.
예를 들어 공식 예시에 나타나는:
text title image image_caption header page_number
등의 유형이 있다.
32. 비즈니스 시스템에서는 자신의 JSON Schema로 변환할 것을 권장
HPD-Parsing의 원시 출력 형식은 매우 간결하지만, 정식 문서 파싱 시스템에서는 이 문자열을 그대로 다운스트림의 통합 데이터 구조로 사용하는 것은 권장하지 않는다.
더 합리적인 아키텍처는:
HPD-Parsing │ ▼ Raw Result │ ▼ HPD Output Parser │ ▼ Block Validator │ ▼ Unified Document Schema │ ┌───┼────┬──────┐ ▼ ▼ ▼ ▼ JSON Markdown HTML RAG
{ "blocks" : [ { "type" : "title" , "bbox" : [ 100 , 80 , 900 , 150 ] , "text" : "제목" } , { "type" : "text" , "bbox" : [ 100 , 180 , 900 , 400 ] , "text" : "본문 내용..." } , { "type" : "image" , "bbox" : [ 100 , 450 , 900 , 800 ] , "text" : "" } ] }
이렇게 하면 이후 다음 작업이 더 편리해진다:
- Markdown 내보내기
- HTML 재구성
- RAG(Retrieval-Augmented Generation, 검색 증강 생성)
- Chunk(텍스트 분할)
- Embedding(벡터 임베딩)
- 벡터 데이터베이스 적재
- 데이터베이스 저장
- 문서 구조 분석
33. 공식 BLOCK 파싱 코드
공식은 하나의 간단한 정규 표현식(Regular Expression, 정규식) 파싱 방식을 제공한다:
import re def parse_blocks ( input_text: str ) -> list [ dict ]: """解析输出中的所有版面块""" pattern = re. compile ( r"<BLOCK>(\w+)\s*[([^]]*)]" r"(?:<CHILD>)?(.*?)(?=<BLOCK>|\Z)", re.DOTALL, ) blocks = [] for block_type, coords_str, content in pattern.findall(input_text): blocks.append( { "type" : block_type, "bbox" : [ int (x.strip()) for x in coords_str.split( "," ) ], "text" : content.strip(), } ) return blocks
34. 프로덕션 환경에서는 정규식 파싱을 단순히 그대로 가져다 쓰지 말 것
위 코드는 다음 용도로는 매우 적합하다:
데모 테스트 빠른 검증
하지만 프로덕션 환경에 들어가면 전용 Parser(파서)를 추가로 설계할 것을 권장한다:
Raw HPD Result │ ▼ Syntax Parser │ ▼ Block Validator │ ▼ Coordinate Validator │ ▼ Content Normalizer │ ▼ Unified Document Schema
적어도 다음을 검사해야 한다:
1. BLOCK이 완전한가 2. bbox에 좌표 4개가 포함되어 있는가 3. 좌표가 범위를 벗어나지 않았는가 4. type이 허용된 Block 유형에 속하는가 5. CHILD 내용이 올바르게 연결되었는가 6. Block 순서가 읽기 순서에 부합하는가 7. 출력이 잘렸는가
이렇게 해야 비로소 모델 출력을 신뢰할 수 있는 비즈니스 데이터로 변환할 수 있다.
35. 실제 입력 예시
36. 실제 출력 예시
<BLOCK>header [159, 57, 378, 88]<CHILD>근대 닝샤(寧夏) 교육 연구 <BLOCK>text [132, 113, 840, 430]<CHILD>"바이취(白區)"라 불렸으며, 초등학교 대다수가 문을 닫았다. 계속 운영된 초등학교가 개설한 과정에는 국문, 수신(修身), 사서(四書) 등이 있었고, 이후 다시 닝샤 교육청이 편인한 복습 교과서로 바뀌었는데, 삼민주의, 어문, 산수, 위생, 자연, 역사, 지리, 공민, 노작, 체육, 음악, 미술 등이 있었다①. 반면 옌츠(鹽池)현의 유일한 여자 초등학교는 1935년에 문을 닫았는데, 이 학교는 1929년에 세워져 7년간 이어졌다. 처음 세워질 때는 현 당부(黨部) 정원에 있었고, 1933년 원먀오(文廟)로 이전했으며, 과정 편성에는 주로 국어, 산수, 그리고 백가성, 삼자경, 삼민, 수신, 자연, 도화, 수공 등이 있었고, 학생은 학년별로 수업을 받았다. 이 학교의 유일한 전임 교사는 처음에 상업에 종사했는데, 여자 초등학교가 설립된 후 상업을 버리고 교직을 맡았으며, 다른 교사들은 모두 외부에서 초빙한 겸임 교원이었다. 이 학교의 학생 수는 최대일 때도 겨우 열한두 명에 불과했다.② 이러한 현상은 1935년 의무교육 보급 전에 여성 교육에 대해 사회가 중시하지 않았을 뿐만 아니라 학부모들도 근본적으로 무관심한 태도를 취했음을 상당 부분 설명하며, 링우(靈武), 닝숴(寧朔), 닝샤 등 현에서는 여아 교육을 경시하는 것이 더욱 심각했다. <BLOCK>table_caption [285, 436, 684, 453]<CHILD>표 35 1935년도 닝샤성 초등학교 개황 통계 간표 \( ^{③} \) <BLOCK>table [136, 457, 839, 723]<CHILD><table><tr><td colspan="2"></td><td>성립</td><td>닝샤</td><td>닝숴</td><td>핑뤄</td><td>중웨이</td><td>중닝</td><td>진지</td><td>링우</td><td>옌츠</td><td>위왕</td><td>덩커우</td><td>총계</td></tr><tr><td rowspan="3">학교 수</td><td>완소</td><td>9</td><td>3</td><td>5</td><td>8</td><td>5</td><td>5</td><td>3</td><td>4</td><td>2</td><td>4</td><td>1</td><td>49</td></tr><tr><td>초소</td><td>4</td><td>32</td><td>21</td><td>25</td><td>22</td><td>28</td><td>16</td><td>13</td><td>6</td><td>9</td><td>3</td><td>179</td></tr><tr><td>합계</td><td>13</td><td>35</td><td>26</td><td>33</td><td>27</td><td>33</td><td>19</td><td>17</td><td>8</td><td>13</td><td>4</td><td>228</td></tr><tr><td rowspan="3">학생 수</td><td>남</td><td>1846</td><td>2029</td><td>1410</td><td>2217</td><td>1826</td><td>2041</td><td>797</td><td>1038</td><td>287</td><td>547</td><td>131</td><td>14169</td></tr><tr><td>여</td><td>550</td><td>61</td><td>73</td><td>201</td><td>202</td><td>347</td><td>111</td><td>51</td><td>82</td><td>122</td><td></td><td>1691</td></tr><tr><td>합계</td><td>2396</td><td>2090</td><td>1483</td><td>2418</td><td>2028</td><td>2388</td><td>908</td><td>1089</td><td>369</td><td>560</td><td>131</td><td>15860</td></tr><tr><td rowspan="3">교직원</td><td>남</td><td>88</td><td>52</td><td>43</td><td>71</td><td>58</td><td>65</td><td>27</td><td>32</td><td>13</td><td>21</td><td>6</td><td>477</td></tr><tr><td>여</td><td>16</td><td></td><td></td><td>1</td><td></td><td>1</td><td>4</td><td></td><td>1</td><td></td><td>1</td><td>24</td></tr><tr><td>합계</td><td>104</td><td>52</td><td>43</td><td>72</td><td>58</td><td>66</td><td>31</td><td>32</td><td>14</td><td>21</td><td>7</td><td>501</td></tr></table> <BLOCK>text [134, 729, 838, 777]<CHILD>1935년, 닝샤성은 총 학생 15860명으로 집계되었는데, 그중 여학생은 1690명에 불과했고 남학생은 14169명으로 여학생의 거의 10배였다. 옌츠현은 여학생이 <BLOCK>list [131, 813, 840, 914] <BLOCK>page_footnote [169, 818, 757, 835]<CHILD>①옌츠현 지방지 편찬위원회 편《옌츠현지》, 내부 발행, 1986년판, 제426쪽. <BLOCK>page_footnote [133, 838, 837, 873]<CHILD>②우창신(武常新)《옌츠현 여자 초등학교》, 옌츠현 위원회 문사자료연구위원회 편《옌츠현 문사자료》제3집, 1987년판, 제70~71쪽. <BLOCK>page_footnote [133, 876, 835, 912]<CHILD>③닝샤성 정부 비서처 편《닝샤성 정부 행정 보고》, 닝샤성 정부 비서처 인쇄, 1935년, 제16쪽. <BLOCK>page_number [169, 926, 227, 942]<CHILD>·190·
37. 배치 호출
문서 파싱 시스템은 보통 다음을 처리해야 한다:
document . pdf │ ├── page_001. png ├── page_002. png ├── page_003. png ├── ... └── page_100. png
공식적으로는 배치 처리 시 다중 스레드나 비동기 방식으로 요청을 동시 제출할 것을 권장한다.
from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor(max_workers= 16 ) as executor: results = list ( executor. map ( parse_one, image_paths, ) )
하지만 주의할 점이 있다:
max_workers=16은 공식 예시일 뿐이며, 모든 GPU를 16으로 설정해야 한다는 뜻은 아니다.
실제 동시성 정도는 다음에 따라 결정해야 한다:
GPU VRAM + 입력 이미지 크기 + 입력 Token + 출력 Token + max_model_len + KV Cache + 실제 처리량
을 기준으로 부하 테스트를 해야 한다.
38. 프로덕션 환경에서는 서비스화 배포를 더 권장
진짜 문서 파싱 플랫폼이라면, 각 작업이 스스로 모델을 로드하는 방식은 권장하지 않는다.
권장하지 않음:
Task 1 ↓ 모델 로드 ↓ GPU Task 2 ↓ 모델 로드 ↓ GPU
Document API │ ▼ Task Queue │ ┌───────────┴───────────┐ ▼ ▼ Worker / Client Worker / Client │ │ └───────────┬───────────┘ ▼ HPD-Parsing Server │ vLLM │ ▼ GPU
모델이 GPU에 장기 상주한다.
여러 비즈니스 요청이 하나의 추론 서비스로 들어가고, vLLM이 요청 스케줄링을 통일적으로 수행한다.
이것이야말로 HPD-Parsing의 고처리량 설계 목표에 더 부합한다.
39. max_tokens는 어떻게 설정해야 할까?
공식 클라이언트 예시:
max_tokens = 8000
이는 다음을 나타낸다:
현재 요청이 생성하도록 허용된 최대 출력 Token 수.
너무 작게 설정하면:
max_tokens = 2000
복잡한 페이지에서 출력이 잘릴 수 있다.
너무 크게 설정하면:
max_tokens = 20000
다음이 증가한다:
- KV Cache 압력
- VRAM 점유
- 요청 스케줄링 압력
따라서 프로덕션 환경에서는 실제 비즈니스 데이터를 토대로 통계를 내고:
P50 Output Length P95 Output Length P99 Output Length
그런 다음 합리적인 안전 여유를 두고 설정할 것을 권장한다.
40. max-model-len과 max_tokens의 차이
이 두 파라미터는 혼동하기 쉽다.
max-model-len
다음을 나타낸다:
모델이 처리하도록 허용된 최대 컨텍스트 길이.
max_tokens
현재 요청이 최대로 생성하는 Token 수.
max -model- len │ ├── Input Tokens │ └── Output Tokens ↑ max_tokens
Input Tokens + Output Tokens
은 모델 컨텍스트 한도를 초과할 수 없다.
공식 서비스 예시 기본값:
-- max -model- len 16384
이며, 이 값은 VRAM 상황에 따라 조정할 수 있다고 설명한다.
41. GPU VRAM 구성
공식 기본값:
--gpu-memory-utilization 0.9
즉, vLLM이 GPU VRAM의 약 90%를 사용하도록 허용한다는 뜻이다.
하지만 실제 VRAM에는 모델 가중치만 있는 것이 아니다.
다음도 포함된다:
Model Weights + Vision Encoder + KV Cache + Activation + vLLM Runtime + CUDA Runtime
HPD-Parsing에 얼마만큼의 VRAM(비디오 메모리)이 필요한지를 "모델이 1B 파라미터밖에 안 된다"는 이유만으로 단순하게 판단할 수는 없다.
특히 고해상도 이미지, 다중 동시 처리, 긴 출력 시나리오에서는 KV Cache가 VRAM의 중요한 소비원이 될 수 있다.
42. 왜 HPD-Parsing이 고동시성(고동시 처리)에 더 친화적인가?
전통적인 VLM:
Request A ↓ Decode 1 → 2 → 3 → 4 → ...
여러 요청을 Batch로 묶을 수 있지만, 각 요청 자체는 여전히 직렬 Decode를 가진다.
Request A ├── Branch A ├── Branch B └── Branch C Request B ├── Branch A ├── Branch B └── Branch C
vLLM은 더 큰 요청 풀에서 통합 스케줄링을 할 수 있다.
HPD-Parsing의 장점은 특히 다중 요청, 고처리량(고스루풋) 시나리오에 적합하다.
이것이 공식 성능 테스트가 Batch Size 512를 채택한 중요한 이유 중 하나이기도 하다.
43. 반복 출력 문제
극히 복잡한 Layout(판면)에 대해서는 모델이 반복 생성을 일으킬 수 있다.
공식 문서에서 제시한 한 가지 처리 방식은 다음과 같다:
extra_body ={ "repetition_penalty": 1.05 }
response = client.chat.completions.create( ... extra_body ={ "repetition_penalty": 1.05 } )
하지만 처음부터 기본값으로 사용하는 것은 권장하지 않는다.
더 합리적인 절차는 다음과 같다:
정상 설정 │ ▼ 비즈니스 데이터 부하 테스트 │ ├── 정상 → 기본값 유지 │ └── 반복 발생 │ ▼ repetition_penalty 조정
44. 로컬 Python API
서비스화 API 외에도, 공식에서는 vLLM Python API(Python 인터페이스)를 통해 직접 모델을 로드하는 방식을 제공한다.
핵심 코드:
from pathlib import Path import os from vllm import LLM, SamplingParams model_path = Path(os.environ[ "MODEL_PATH" ]) llm = LLM( model =str(model_path), trust_remote_code = True , max_model_len = 16384 , limit_mm_per_prompt ={ "image" : 1 }, gpu_memory_utilization = 0.9 , attention_backend = "FLASHINFER" , enable_prefix_caching = True , speculative_config ={ "method": "medusa", "model": str(model_path / "P-MTP"), "num_speculative_tokens": 6, }, ) sampling_params = SamplingParams( temperature = 0 , max_tokens = 8000 , )
그런 다음:
outputs = llm.chat( messages =messages, sampling_params =sampling_params, ) result = outputs[ 0 ].outputs[ 0 ].text
공식에서는 이 방식을 명확히 다음과 같이 규정한다:
단일 머신 일괄 처리 시나리오.
45. 서비스화 API와 로컬 API는 어떻게 선택하는가?
다음과 같은 방식으로 간단히 선택할 수 있다:
시나리오 권장 방식 프로덕션 환경 서비스화 배포 다중 비즈니스 시스템 공유 서비스화 배포 고동시성 서비스화 배포 API 서비스 서비스화 배포 단일 머신 실험 Python API 오프라인 일괄 처리 Python API Benchmark 둘 다 가능 빠른 검증 Python API
만약 당신의 목표가 다음과 같은 완전한 것을 구축하는 것이라면:
문서 파싱 서비스
그렇다면 우선 권장하는 것은:
HPD-Parsing + 맞춤형 vLLM + OpenAI Compatible API
46. HPD-Parsing과 전통적 OCR Pipeline의 차이
전통적 Pipeline(파이프라인):
PDF ↓ Page Render ↓ Layout Detection ↓ OCR ↓ Table Recognition ↓ Formula Recognition ↓ Reading Order ↓ Post Processing ↓ Markdown
PDF Page ↓ HPD-Parsing ↓ Structured Document
아키텍처 복잡도 측면에서 보면:
전통적 Pipeline 모듈이 많음 인터페이스가 많음 데이터 변환이 많음 후처리가 많음 HPD 모델 통일 인터페이스 단순 시스템 링크가 짧음
하지만 이러한 통일은 한 가지 문제를 의미하기도 한다:
모델 내부가 더 큰 블랙박스가 된다.
전통적 Pipeline에서는:
OCR 오류 Layout 오류 Table 오류
를 비교적 쉽게 찾아낼 수 있다.
반면 VLM에서는:
시각 이해 + Layout + OCR + 구조 이해 + 생성
이 공동으로 최종 결과에 영향을 미친다.
따라서 엔지니어링 측면에서 단순하게 이렇게 생각해서는 안 된다:
VLM이 반드시 전통적 OCR Pipeline을 전면 대체한다.
둘 사이에는 여전히 뚜렷한 응용 시나리오 차이가 존재한다.
47. HPD-Parsing은 어떤 시나리오에 더 적합한가?
모델 아키텍처와 성능 지표로 볼 때, 나는 다음 시나리오가 HPD-Parsing에 매우 적합하다고 생각한다.
1. 대규모 문서 파싱
하루 10만 페이지 하루 100만 페이지
이때는:
GPU 이용률 PPS TPS 동시성 능력
이 단일 요청 지연보다 더 중요하다.
2. 기업 지식베이스
계약서 재무 보고서 기술 문서 제품 매뉴얼 연구 보고서 표준 규격 회의 자료
이러한 문서는 보통:
판면이 복잡 + 출력이 김
HPD의 설계에 딱 맞는다.
3. RAG 데이터 적재
전형적 절차:
PDF ↓ Page Render ↓ HPD-Parsing ↓ Document Schema ↓ Chunk ↓ Embedding ↓ Vector Database
4. 고처리량 문서 파싱 서비스
사용자가 PDF 업로드 ↓ Document API ↓ 작업 큐 ↓ HPD Cluster ↓ 구조화 문서
이때 HPD의 병렬 Decode가 GPU를 더 충분히 활용할 수 있다.
48. 어떤 시나리오는 반드시 적합하지는 않은가?
1. NVIDIA GPU가 없는 경우
현재 공식 검증 환경은 모두 NVIDIA GPU이며, CUDA 12.8+를 요구한다.
순수 CPU
는 그것의 목표 실행 환경이 아니다.
2. 극히 낮은 호출량
만약:
하루에 겨우 수십 페이지
라면 전용으로 다음을 배포하는 것은:
A800 / H800 + vLLM + HPD
경제적이지 않을 수 있다.
3. 정밀한 규칙 제어에 강하게 의존하는 시나리오
예를 들어 일부 강규제 업무에서는 다음을 엄격히 보장해야 한다:
필드 위치 필드 유형 좌표 규칙 판면 규칙 데이터 형식
VLM + 전통적 OCR / Layout + 규칙 검증
이 순수 엔드투엔드 방식보다 더 신뢰할 수 있을 수 있다.
49. 프로덕션 환경에서 진짜로 주목해야 할 지표는 무엇인가?
만약 당신이 HPD-Parsing을 자신의 문서 파싱 서비스에 통합할 준비가 되어 있다면, 나는 다음만 주목하는 것을 권하지 않는다:
4752 TPS
적어도 아래 다섯 가지 지표를 테스트해야 한다.
1. Accuracy
파싱 정확도
2. PPS
다음에 답한다:
GPU 한 장이 1초에 몇 페이지를 파싱할 수 있는가?
3. P95 Latency
P50 P95 P99
한 페이지가 요청에서 반환까지 얼마나 걸리는가?
4. GPU Utilization
GPU Utilization Memory Utilization KV Cache Usage
5. Error Rate
요청 실패율 출력 절단율 모델 이상률 반복 출력률 파싱 실패율
최종적으로 진짜로 다음과 같은 Benchmark(기준 테스트)를 형성해야 한다:
지표 HPD-Parsing Accuracy 테스트 예정 P50 Latency 테스트 예정 P95 Latency 테스트 예정 P99 Latency 테스트 예정 PPS 테스트 예정 TPS 테스트 예정 GPU Memory 테스트 예정 GPU Utilization 테스트 예정 Error Rate 테스트 예정
50. HPD-Parsing의 진짜 가치
만약 HPD-Parsing을 단지 이렇게 이해한다면:
"바이두가 또 새로운 문서 파싱 모델을 발표했다."
사실 그것의 가장 중요한 가치를 붙잡지 못한 것이다.
진짜 주목할 만한 것은:
VLM 문서 파싱의 추론 방식을 재설계했다는 점이다.
전통적 사고는 더 많이:
더 큰 모델 ↓ 더 강한 능력 ↓ 더 높은 정밀도
HPD는 또 다른 차원을 추가했다:
Decode Architecture를 어떻게 재설계할 것인가? │ ▼ 직렬 의존성 감소 │ ▼ 국부 병렬 증가 │ ▼ Prefix KV Cache 공유 │ ▼ P -MTP │ ▼ 유효 Decode Steps 감소 │ ▼ GPU 이용률 향상 │ ▼ 전체 처리량 향상
따라서 HPD-Parsing의 혁신 중점은 단지:
Model Scaling
이 아니라, 다음에 더 가깝다:
Inference Architecture (추론 아키텍처)
51. 문서 파싱 서비스 아키텍처 관점에서 HPD를 이해하기
만약 HPD-Parsing을 하나의 완전한 문서 파싱 시스템에 넣는다면, 다음과 같이 설계할 수 있다:
Document │ ▼ File Preprocess (파일 전처리) │ ▼ Page Rendering (페이지 렌더링) │ ▼ Image Processing (이미지 처리) │ ▼ HPD-Parsing │ ┌────────────┴────────────┐ ▼ ▼ Layout/Text Images │ ▼ Post Processing (후처리) │ ▼ Unified Document Schema (통합 문서 데이터 구조) │ ┌──────┼──────┐ ▼ ▼ ▼ Markdown JSON RAG
다시 말해:
HPD-Parsing은 문서 파싱 시스템에서 핵심 이해 엔진으로 사용되는 것이 더 적합하며, 전체 문서 파싱 시스템 그 자체는 아니다.
주변에는 여전히 다음이 필요하다:
파일 처리 PDF 렌더링 작업 스케줄링 GPU 서비스 결과 저장 이상 재시도 후처리 출력 모니터링
52. 만약 기업급 문서 파싱 서비스에 사용한다면, 권장하는 전체 아키텍처
HPD-Parsing의 특징을 결합하면, 비교적 합리적인 프로덕션 아키텍처를 다음과 같이 설계할 수 있다:
Client │ ▼ API Gateway │ ▼ Document Service │ ┌─────────┴─────────┐ ▼ ▼ File Store Task Queue │ ▼ Page Processing │ ▼ HPD-Parsing Cluster │ ┌──────────┼──────────┐ ▼ ▼ ▼ GPU -1 GPU -2 GPU -3 │ │ │ └──────────┼──────────┘ ▼ Post Processing │ ▼ Unified Document JSON │ ┌─────────────────┼─────────────────┐ ▼ ▼ ▼ Markdown RAG Database
여기서 가장 중요한 설계 원칙은:
모델 서비스와 비즈니스 작업 스케줄링의 분리.
이렇게 하면 이후에 설령:
HPD-Parsing
을 다음으로:
PaddleOCR-VL MinerU 기타 VLM
으로 교체하더라도, 상위 작업 시스템에 영향을 주지 않는다.
53. HPD-Parsing의 기술 체인 요약
전체 모델은 다음과 같이 개괄할 수 있다:
Document Image │ ▼ Dynamic Tiling 동적 이미지 슬라이싱 │ ▼ InternVL3. 5 - 1 B 비전 언어 백본 │ ▼ Main Layout Branch 메인 레이아웃 분기 │ 전역 구조 조정 │ ┌───────────────┼───────────────┐ ▼ ▼ ▼ Content A Content B Content C 콘텐츠 분기 A 콘텐츠 분기 B 콘텐츠 분기 C │ │ │ ▼ ▼ ▼ P -MTP P -MTP P -MTP │ │ │ └───────────────┼───────────────┘ ▼ Structured Output 구조화 문서 결과
그 성능 최적화 경로는 다음과 같다.
단일 궤적 자기회귀 │ ▼ Hierarchical Parallel Decoding │ ▼ 동적 요청 분기 │ ▼ 로컬 Branch 병렬 │ ▼ Prefix KV Cache 공유 │ ▼ P -MTP 추측 디코딩 │ ▼ Decode Steps 감소 │ ▼ TPS / PPS 향상
54. 총결
HPD-Parsing의 핵심 사상은 한 문장으로 압축할 수 있다.
문서 레이아웃의 전역성과 콘텐츠의 국소성을 활용하여, 기존 VLM의 단일 궤적 자기회귀 생성을 "전역 레이아웃 조정 + 로컬 콘텐츠 병렬 디코딩"으로 재구성하고, 다시 P-MTP를 통해 각 분기 내부의 디코딩 단계를 줄임으로써 긴 출력 문서 파싱 작업의 추론 처리량을 향상시킨다.
그 기술 경로는 다음과 같이 정리할 수 있다.
InternVL3. 5 - 1 B │ ▼ Dynamic Tiling │ ▼ Main Layout Branch │ ▼ Hierarchical Parallel Decoding │ ├── Content Branch A ├── Content Branch B ├── Content Branch C └── Content Branch N │ ▼ Shared Prefix KV Cache │ ▼ P -MTP │ ▼ High-Throughput Parsing
현재 공식 공개 데이터로 보면, HPD-Parsing은 약 1B 파라미터로, OmniDocBench v1.6에서 94.91% Overall을 달성했으며, A800 80GB, Batch Size 512의 테스트 조건에서 약 4,752 TPS / 2.68 PPS를 달성했다. 공식은 또한 출력 길이가 증가함에 따라 HPD의 병렬 디코딩 우위가 더욱 확대된다고 보고했다.
따라서 만약 관심 지점이 다음과 같다면:
복잡한 문서 + 긴 출력 + 높은 동시성 + GPU 추론 + 대규모 문서 처리
그렇다면 HPD-Parsing은 주목할 가치가 있다.
다만 엔지니어링 실현 관점에서 보면, 현재 이것이 일반적인 PaddleOCR Python 모델이 아니라 다음과 같이 구성된 전용 추론 방안이라는 점도 유의해야 한다.
HPD-Parsing + 커스터마이즈 버전 vLLM + P-MTP + GPU
공식은 현재 Linux x86-64, NVIDIA GPU 및 CUDA 12.8+를 요구하며, 공식 Docker 이미지를 사용한 배포를 권장한다.
최종적으로 HPD-Parsing을 엔터프라이즈급 문서 파싱 시스템에 넣는다면, 내가 생각하는 가장 합리적인 위치는 다음과 같다.
HPD-Parsing을 핵심 문서 이해 엔진으로 삼고, 외곽의 작업 스케줄링, 파일 처리, 페이지 렌더링, 결과 후처리, 통합 Schema(데이터 구조), 스토리지 및 모니터링 시스템이 완전한 문서 파싱 서비스를 구성한다.
공식 자료
- PaddleOCR HPD-Parsing 공식 사용 튜토리얼
HPD-Parsing 공식 사용 튜토리얼
- HPD-Parsing Model Card
HPD-Parsing 공식 Model Card
- HPD-Parsing 논문
ALLINAI
Python 개발
135
文章
116k
阅读
206
粉丝