零基础教程:用Chandra将PDF转为结构化HTML
你是不是也遇到过这些情况:
- 扫描版合同里有表格、手写签名和页脚,复制粘贴后格式全乱;
- 教学讲义PDF里的数学公式一粘就变乱码,还得手动重打;
- 一堆历史档案PDF想导入知识库,但OCR工具只输出纯文本,标题层级、段落关系、图片位置全丢了。
别折腾了——现在有一款开箱即用的工具,4GB显存就能跑,1秒出结果,直接吐出带完整排版的HTML,连表格边框、公式编号、多栏布局都原样保留。它就是 Chandra,2025年开源的「布局感知」OCR模型。
本文不讲原理、不调参数、不配环境,只做一件事:手把手带你从零开始,把任意PDF变成可编辑、可嵌入网页、可进RAG系统的结构化HTML。全程用命令行+可视化界面双路径,Mac/Windows/Linux通用,RTX 3060起步,连Docker都不用学。
1. 为什么是Chandra?不是其他OCR?
先说结论:如果你要的不是“识别文字”,而是“还原文档结构”,那Chandra和其他OCR根本不在一个维度。
| 能力项 | 普通OCR(如Tesseract) | 在线OCR(如Adobe Scan) | Chandra |
|---|---|---|---|
| 表格识别 | 文字能认,但行列错位、合并单元格丢失 | 基本能保结构,但复杂表单常崩溃 | 完整保留<table>、<tr>、<td>及colspan/rowspan属性 |
| 数学公式 | 输出LaTeX片段,需二次处理 | 公式变图片或乱码 | 直接生成<math>标签,支持MathML渲染 |
| 多栏排版 | 当成一整列读,段落顺序错乱 | 偶尔识别栏分隔线,但标题常被切碎 | 自动标注<div class="column">,保留视觉阅读流 |
| 手写内容 | 基本不可用 | 识别率低,无结构信息 | 标记为<span class="handwritten">,位置坐标精准到像素 |
| 输出格式 | 纯文本或简单HTML(无语义标签) | PDF或图片为主,HTML极少且无结构 | 同时输出Markdown/HTML/JSON,HTML含<section>、<header>、<figure>等语义化标签 |
关键不是“认得准”,而是“懂结构”。Chandra把PDF当“视觉文档”理解,而不是“文字图像”切割。它知道哪块是标题、哪段是脚注、哪个框是复选框——所以生成的HTML,浏览器能直接渲染,前端能直接用CSS美化,RAG系统能准确切分chunk。
一句话记住它的定位:不是OCR工具,是「PDF到结构化Web内容」的翻译器。
2. 三步完成部署:不用装vLLM,不用配CUDA
Chandra镜像(chandra)已预装所有依赖,包括vLLM推理后端、PDF解析库、字体渲染引擎。你唯一要做的,是拉取镜像并启动——整个过程5分钟内搞定。
2.1 确认硬件要求(真实可行)
- 显卡:NVIDIA GPU,显存≥4GB(RTX 3060 / 4060 / A4000均实测通过)
- 内存:≥8GB(处理百页PDF建议16GB)
- 磁盘:预留3GB空间(镜像约2.1GB,缓存+临时文件需额外空间)
- 系统:Windows 10/11(WSL2)、macOS(Intel/M系列芯片)、Ubuntu 20.04+
注意:官方明确提示“两张卡,一张卡起不来”——这不是bug,是vLLM多GPU并行设计的硬性要求。但单卡完全可用,只是启动时需加--num-gpus 1参数(下文会标出)。
2.2 一键拉取并运行镜像
打开终端(Windows用PowerShell,macOS/Linux用Terminal),执行:
# 拉取镜像(国内用户推荐使用加速源) docker pull registry.cn-hangzhou.aliyuncs.com/csdn_mirror/chandra:latest # 启动容器(关键:指定单卡模式 + 挂载PDF目录) docker run -it --gpus all \ --shm-size=2g \ -p 7860:7860 \ -v $(pwd)/pdf_input:/app/input \ -v $(pwd)/html_output:/app/output \ registry.cn-hangzhou.aliyuncs.com/csdn_mirror/chandra:latest \ --num-gpus 1参数说明:
--gpus all:让Docker识别你的GPU(即使只有一张)--shm-size=2g:避免大PDF加载时共享内存不足-p 7860:7860:暴露Streamlit Web界面端口-v $(pwd)/pdf_input:/app/input:将当前目录下的pdf_input文件夹映射为输入路径(请提前创建)-v $(pwd)/html_output:/app/output:将当前目录下的html_output文件夹映射为输出路径(请提前创建)--num-gpus 1:强制vLLM使用单卡模式(必加!否则报错)
启动成功后,终端会显示:Running on local URL: http://0.0.0.0:7860
在浏览器打开 http://localhost:7860,你就进入了Chandra的可视化操作台。
2.3 替代方案:不用Docker?用pip更轻量
如果你不想装Docker,或者只是偶尔处理几份PDF,推荐用Python包方式:
# 创建干净虚拟环境(推荐) python -m venv chandra_env source chandra_env/bin/activate # macOS/Linux # chandra_env\Scripts\activate # Windows # 安装(自动包含vLLM、PyMuPDF、Pillow等全部依赖) pip install chandra-ocr # 启动Streamlit界面 chandra_app同样访问 http://localhost:7860,界面与Docker版完全一致。
小技巧:首次运行会自动下载模型权重(约1.8GB),建议挂代理或用国内镜像源加速。
3. 实操演示:一份扫描合同PDF的全流程转换
我们以一份真实的扫描版《房屋租赁协议》PDF为例(含公章、手写签名、表格条款、页眉页脚)。目标:生成一份可直接嵌入公司内部Wiki的HTML页面。
3.1 上传PDF并设置选项
在 http://localhost:7860 界面中:
- 点击【Upload PDF】按钮,选择你的PDF文件(支持多选)
- 在右侧【Output Format】中,勾选HTML(同时可选Markdown/JSON,但本教程聚焦HTML)
- 【Layout Preservation】保持默认“High”(高保真模式,启用所有结构识别)
- 【Language】自动检测,中文文档无需修改;若含日文/韩文条款,可手动切换
注意:不要点“Batch Process”按钮——那是为目录批量处理准备的。单文件直接点下方【Convert】即可。
3.2 查看实时转换效果
点击【Convert】后,界面左侧会显示进度条和日志:
[INFO] Loading PDF (12 pages)... [INFO] Detecting layout blocks... ✓ [INFO] Recognizing text & formulas... ✓ [INFO] Structuring tables & forms... ✓ [INFO] Generating HTML output... ✓约3-8秒(取决于PDF页数和GPU性能),右侧会直接渲染出HTML预览效果:
- 标题“房屋租赁协议”自动包裹在
<h1>标签中 - “甲方”“乙方”条款用
<section class="party-section">分组 - 租金支付表格完整呈现为
<table class="contract-table">,含<thead>和<tbody> - 手写签名区域标记为
<div class="signature-area"><!-- 在生成的HTML <head> 中添加以下代码 --> <style> /* 适配Confluence的窄屏宽度 */ .contract-table { width: 100% !important; } .document-title { font-size: 1.5em !important; margin-bottom: 1em; } /* 移除可能冲突的字体声明 */ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI" !important; } </style>效果:粘贴到Confluence的“HTML宏”中,表格自动撑满宽度,标题字号统一,无需额外CSS。
4.2 场景二:从HTML中精准提取关键字段(如签约日期、金额)
问题:正则匹配不稳定,XPath太重。
解法:利用Chandra生成的语义化class名,用极简CSS选择器提取。from bs4 import BeautifulSoup with open("lease_agreement.html", "r", encoding="utf-8") as f: html = f.read() soup = BeautifulSoup(html, "html.parser") # 提取签约日期(通常在页脚或末尾段落) date_text = soup.select_one("footer .date") or soup.select_one(".contract-date") if date_text: print("签约日期:", date_text.get_text(strip=True)) # 提取总金额(表格中最后一行“合计”列) total_row = soup.select_one("table.contract-table tr:last-child") if total_row: amount_cell = total_row.select_one("td.amount") if amount_cell: print("合同总金额:", amount_cell.get_text(strip=True))优势:不依赖固定位置,靠语义class精准定位,PDF换版也不失效。
4.3 场景三:批量处理100份PDF,生成静态网站
问题:逐个上传太慢,且需统一导航。
解法:用CLI命令行批量处理,再用Hugo/Jekyll生成网站。# 将100份PDF放入 pdf_input/ 文件夹 mkdir pdf_input html_output # 批量转换(自动为每个PDF生成同名HTML) chandra-cli --input pdf_input/ --output html_output/ --format html --layout high # 生成简易索引页(用shell脚本) ls html_output/*.html | sed 's/html_output\///' | while read f; do echo "- [$f](./$f)" done > html_output/README.md结果:
html_output/文件夹下100个HTML文件+1个索引页,直接用python -m http.server 8000启动本地服务器,即可浏览全部合同。5. 常见问题与避坑指南
新手上路最容易卡在这几个地方,我们提前帮你踩平:
5.1 “启动报错:CUDA out of memory”怎么办?
这是最常见问题,本质是vLLM默认分配显存过大。解决方法:
- 在Docker命令末尾添加
--max-model-len 2048(降低上下文长度) - 或改用CPU模式(仅限小PDF):
--device cpu --num-gpus 0 - 推荐:RTX 3060用户加
--max-model-len 1024,速度几乎无损,显存占用降60%。
5.2 “中文显示为方块”或“公式乱码”?
Chandra生成的HTML默认使用系统字体。解决:
- 在生成的HTML
<head>中加入字体声明:<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet"> <style>body { font-family: 'Noto Sans SC', sans-serif; }</style> - 公式渲染需引入MathJax:在
<head>中加<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script> <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
5.3 “手写签名没识别出来”?
Chandra对手写体识别强,但需满足两个条件:
- 扫描分辨率≥200 DPI(手机拍的模糊照片需先用Photoshop锐化)
- 签名区域不能被公章完全覆盖(Chandra会优先识别印章,签名需部分露出)
实测技巧:用PDF编辑器在签名旁加一个浅色矩形框(透明度30%),Chandra会将其识别为<div class="highlight">,从而定位签名区域。
5.4 “输出HTML里有大量空div,怎么清理?”
这是Chandra保留布局坐标的需要,但影响阅读。安全清理方法:
- 删除所有
<div>中既无文字也无子元素的节点(用BeautifulSoup) - 保留含
class="page"、class="column"、class="signature-area"的div(它们承载结构信息) - 一行命令:
sed -i '/<div[^>]*><\/div>/d' lease_agreement.html(Linux/macOS)
6. 总结:你已经掌握了PDF结构化的核心能力
回顾一下,你刚刚完成了:
用5分钟完成Chandra部署,无需碰vLLM底层配置;
将一份复杂扫描PDF,一键转为语义化HTML,表格、公式、手写、多栏全部保留;
学会3种落地技巧:嵌入Wiki、精准提取字段、批量生成网站;
解决了显存不足、字体乱码、手写识别等高频问题。Chandra的价值,从来不是“又一个OCR”,而是把PDF从“不可编辑的图像”变成“可编程的Web文档”。你不再需要人工校对表格、不再担心公式失真、不再为知识库切片发愁——结构就在那里,HTML就是接口。
下一步,你可以:
- 把这个流程写成Shell脚本,每天凌晨自动处理新合同;
- 用生成的HTML喂给RAG系统,让合同条款支持自然语言提问;
- 基于
<section class="party-section">开发自动比对工具,识别不同版本差异。
技术的意义,是让重复劳动消失。而你,已经拿到了那把钥匙。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
- 在Docker命令末尾添加