PaddleOCR-VL
PaddleOCR-VL 是 PaddleOCR 的视觉-语言模型升级版本,结合了传统OCR的高效性和大语言模型的理解能力,提供更智能的文档处理和理解能力。
🌟 核心特性
- ✅ 视觉-语言融合:结合视觉识别和语言理解
- ✅ 文档智能理解:不仅识别文字,还能理解文档含义
- ✅ 灵活的提示词:通过自然语言控制OCR行为
- ✅ 多模态输出:支持文本、表格、JSON等多种格式
- ✅ 中文优化:针对中文场景深度优化
- ✅ 高效推理:保持PaddleOCR的高速特性
- ✅ 易于部署:支持CPU和GPU,部署简单
📦 安装与使用
环境准备
# 安装 PaddlePaddle
pip install paddlepaddle-gpu
# 安装 PaddleOCR-VL
pip install paddleocr-vl
# 或从源码安装
git clone https://github.com/PaddlePaddle/PaddleOCR-VL.git
cd PaddleOCR-VL
pip install -e .
快速开始
from paddleocr_vl import PADDLEOCRVL
# 初始化模型
ocr_vl = PADDLEOCRVL(
use_gpu=True,
lang='ch' # 中文模型
)
# 基础OCR
result = ocr_vl("document.jpg", prompt="识别图像中的所有文字")
print(result['text'])
# 结构化提取
result = ocr_vl(
"invoice.jpg",
prompt="提取发票信息,包括发票号、日期、金额等,以JSON格式输出"
)
print(result['json'])
不同任务模式
# 1. 纯文本OCR
text = ocr_vl("image.jpg", prompt="OCR")
# 2. 表格提取
table = ocr_vl(
"table.jpg",
prompt="提取表格内容,以Markdown表格格式输出"
)
# 3. 关键信息提取
info = ocr_vl(
"form.jpg",
prompt="提取表单中的姓名、身份证号、地址等关键信息"
)
# 4. 文档分类
category = ocr_vl(
"document.jpg",
prompt="判断这是什么类型的文档(合同、发票、证书等)"
)
# 5. 文档问答
answer = ocr_vl(
"document.jpg",
prompt="文档中提到的签约日期是什么时候?"
)
🏗️ 技术架构
graph TB
A[输入图像] --> B[PaddleOCR引擎]
B --> C[文本检测]
B --> D[文本识别]
C --> E[文本块序列]
D --> E
E --> F[视觉语言模型]
G[用户提示] --> F
F --> H[语义理解]
H --> I[结构化输出]
B -->|高效检测| C1[DB/SAST]
B -->|准确识别| D1[CRNN/SVTR]
F -->|知识增强| F1[领域知识]
H -->|智能解析| H1[结果生成]
核心组件
- OCR引擎: 基于PaddleOCR的高效文本检测和识别
- 视觉编码器: 提取图像的视觉特征
- 语言模型: 理解和生成自然语言
- 多模态融合: 融合视觉和文本信息
🎯 应用场景
1. 智能发票识别
from paddleocr_vl import PADDLEOCRVL
import json
def smart_invoice_ocr(image_path):
"""智能发票识别"""
ocr_vl = PADDLEOCRVL(use_gpu=True, lang='ch')
result = ocr_vl(
image_path,
prompt="""
请识别这张发票,提取以下信息:
1. 发票代码
2. 发票号码
3. 开票日期
4. 购买方名称和税号
5. 销售方名称和税号
6. 商品明细(名称、数量、单价、金额)
7. 价税合计
8. 备注
以JSON格式输出,确保所有金额精确到分。
"""
)
# 解析JSON
invoice_info = json.loads(result['text'])
return invoice_info
# 使用示例
invoice = smart_invoice_ocr("invoice.jpg")
print(f"发票号码: {invoice['invoice_number']}")
print(f"价税合计: ¥{invoice['total_amount']}")
2. 证件信息提取
def extract_id_card(image_path, side='front'):
"""身份证信息提取"""
ocr_vl = PADDLEOCRVL(use_gpu=True, lang='ch')
if side == 'front':
prompt = """
这是一张身份证正面照片,请提取:
- 姓名
- 性别
- 民族
- 出生日期
- 住址
- 公民身份号码
以JSON格式输出。
"""
else:
prompt = """
这是一张身份证背面照片,请提取:
- 签发机关
- 有效期限
以JSON格式输出。
"""
result = ocr_vl(image_path, prompt=prompt)
return json.loads(result['text'])
# 使用
front_info = extract_id_card("id_front.jpg", side='front')
back_info = extract_id_card("id_back.jpg", side='back')
id_card_info = {**front_info, **back_info}
print(id_card_info)
3. 合同关键信息提取
def extract_contract_info(image_path):
"""合同关键信息提取"""
ocr_vl = PADDLEOCRVL(use_gpu=True, lang='ch')
result = ocr_vl(
image_path,
prompt="""
请识别这份合同,提取以下关键信息:
1. 合同标题
2. 甲方(全称、法定代表人、联系方式)
3. 乙方(全称、法定代表人、联系方式)
4. 合同金额
5. 签订日期
6. 履行期限
7. 违约责任条款
8. 特别约定事项
以结构化JSON格式输出。
"""
)
contract_info = json.loads(result['text'])
return contract_info
4. 表格智能识别
def intelligent_table_extraction(image_path):
"""智能表格提取"""
ocr_vl = PADDLEOCRVL(use_gpu=True, lang='ch')
result = ocr_vl(
image_path,
prompt="""
请识别图中的表格:
1. 分析表格结构(行数、列数)
2. 识别表头
3. 提取所有单元格内容
4. 以Markdown表格格式输出
5. 如果有合并单元格,请注明
"""
)
# 获取Markdown表格
markdown_table = result['text']
# 也可以转为DataFrame
import pandas as pd
from io import StringIO
# 解析Markdown表格为DataFrame
lines = markdown_table.strip().split('\n')
data = [line.split('|')[1:-1] for line in lines if '|' in line and '---' not in line]
df = pd.DataFrame(data[1:], columns=data[0])
return {
'markdown': markdown_table,
'dataframe': df
}
5. 文档分类与路由
def classify_document(image_path):
"""文档分类"""
ocr_vl = PADDLEOCRVL(use_gpu=True, lang='ch')
result = ocr_vl(
image_path,
prompt="""
请判断这是什么类型的文档,从以下类别中选择:
1. 发票(增值税发票、普通发票等)
2. 合同(购销合同、劳动合同等)
3. 证件(身份证、营业执照、资格证书等)
4. 报表(财务报表、统计报表等)
5. 公文(通知、函、请示等)
6. 其他
输出格式:
{
"category": "类别名称",
"subcategory": "子类别",
"confidence": 0.95
}
"""
)
classification = json.loads(result['text'])
# 根据分类路由到不同的处理流程
if classification['category'] == '发票':
return process_invoice(image_path)
elif classification['category'] == '合同':
return process_contract(image_path)
elif classification['category'] == '证件':
return process_certificate(image_path)
else:
return process_general_document(image_path)
6. 多页文档批处理
from pathlib import Path
def batch_process_documents(input_dir, output_dir):
"""批量处理文档"""
ocr_vl = PADDLEOCRVL(use_gpu=True, lang='ch')
input_path = Path(input_dir)
output_path = Path(output_dir)
output_path.mkdir(exist_ok=True)
results = []
for img_file in input_path.glob("*.jpg"):
try:
print(f"处理: {img_file.name}")
# 先分类
doc_type = classify_document(str(img_file))
# 根据类型提取信息
if doc_type['category'] == '发票':
info = smart_invoice_ocr(str(img_file))
elif doc_type['category'] == '合同':
info = extract_contract_info(str(img_file))
else:
# 通用OCR
result = ocr_vl(str(img_file), prompt="提取所有文本内容")
info = {'text': result['text']}
# 保存结果
output_file = output_path / f"{img_file.stem}.json"
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(info, f, ensure_ascii=False, indent=2)
results.append({
'file': img_file.name,
'type': doc_type['category'],
'status': 'success'
})
except Exception as e:
results.append({
'file': img_file.name,
'status': 'error',
'error': str(e)
})
# 保存处理报告
with open(output_path / 'report.json', 'w') as f:
json.dump(results, f, indent=2, ensure_ascii=False)
return results
🔧 高级配置
自定义配置
from paddleocr_vl import PADDLEOCRVL
# 详细配置
ocr_vl = PADDLEOCRVL(
# OCR配置
use_gpu=True,
gpu_mem=8000,
lang='ch',
det_model='DB', # 检测模型
rec_model='SVTR', # 识别模型
# VL配置
vl_model='chinese-base', # 视觉语言模型
max_seq_length=2048, # 最大序列长度
# 性能配置
use_angle_cls=True, # 方向分类
use_space_char=True, # 识别空格
drop_score=0.5, # 置信度阈值
# 输出配置
output_format='json', # json/markdown/text
enable_mkldnn=True # 使用MKLDNN加速
)
提示词模板
# 定义常用提示词模板
PROMPT_TEMPLATES = {
'invoice': """
提取发票信息:发票代码、号码、日期、购销方、金额等。
以JSON格式输出。
""",
'contract': """
提取合同关键信息:甲乙方、金额、日期、主要条款。
以JSON格式输出。
""",
'table': """
识别表格内容,保持结构。
以Markdown表格格式输出。
""",
'form': """
提取表单中的所有字段和对应的值。
以键值对JSON格式输出。
"""
}
# 使用模板
result = ocr_vl(
"invoice.jpg",
prompt=PROMPT_TEMPLATES['invoice']
)
后处理优化
def post_process_result(result, doc_type):
"""后处理OCR结果"""
if doc_type == 'invoice':
# 发票特定后处理
# 验证税号格式
if 'tax_number' in result:
result['tax_number'] = validate_tax_number(result['tax_number'])
# 金额格式化
if 'total_amount' in result:
result['total_amount'] = format_amount(result['total_amount'])
elif doc_type == 'id_card':
# 身份证后处理
# 验证身份证号
if 'id_number' in result:
result['id_number'] = validate_id_number(result['id_number'])
return result
def validate_tax_number(tax_number):
"""验证税号格式"""
# 移除非数字字符
tax_number = ''.join(filter(str.isdigit, tax_number))
# 验证长度
if len(tax_number) in [15, 18, 20]:
return tax_number
return None
def format_amount(amount):
"""格式化金额"""
# 移除非数字和小数点
amount = ''.join(c for c in amount if c.isdigit() or c == '.')
try:
return float(amount)
except:
return None
📊 性能对比
| 特性 | PaddleOCR-VL | PaddleOCR | GOT-OCR |
|---|---|---|---|
| 文本识别准确率 | 96% | 95% | 97% |
| 语义理解能力 | ⭐⭐⭐⭐⭐ | ⭐ | ⭐⭐⭐⭐⭐ |
| 处理速度 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 部署难度 | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ |
| 资源消耗 | 中 | 低 | 高 |
💡 最佳实践
-
提示词设计
- 明确任务目标
- 指定输出格式
- 提供示例(少样本学习)
-
图像质量
- 确保图像清晰
- 适当的分辨率(300 DPI)
- 避免过度压缩
-
批量处理
- 使用GPU加速
- 适当的batch_size
- 异步处理提高吞吐量
-
结果验证
- 设置置信度阈值
- 关键字段后处理验证
- 人工复核关键数据
📚 资源链接
- GitHub: https://github.com/PaddlePaddle/PaddleOCR-VL
- 文档: https://paddleocr-vl.readthedocs.io/
- 模型: https://paddleocr.bj.bcebos.com/
- 论坛: https://aistudio.baidu.com/
⚠️ 注意事项
- 首次运行会下载模型文件
- GPU版本需要CUDA支持
- 视觉语言模型需要更多内存
- 提示词设计会影响结果质量
- 敏感数据处理注意隐私保护
🆚 适用场景
选择 PaddleOCR-VL 当:
- 需要智能文档理解
- 处理中文文档为主
- 需要结构化信息提取
- 要求较快的处理速度
- 需要灵活的输出格式
选择其他工具当:
- 纯文本提取 → PaddleOCR
- 最高准确率 → GOT-OCR
- 资源受限 → Tesseract
- 英文为主 → Tesseract/EasyOCR
🔄 更新日志
- 2024.08: 发布 v1.0,支持更多文档类型
- 2024.05: Beta版本,优化中文场景
- 2024.02: Alpha版本,首次公开测试