ingest | PaddleOCR v2 API 配额与错误码入库(raw 摘编+实践页+OCR 工具脚本,token 不落库)
This commit is contained in:
@@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
title: "PaddleOCR v2 API 配额与错误码规则摘编"
|
||||||
|
source: "PaddleOCR 官方 API 文档(用户 2026-08-07 提供;接口域 paddleocr.aistudio-app.com/api/v2/ocr/jobs)"
|
||||||
|
source_date: 2026-08-07
|
||||||
|
extracted_date: 2026-08-07
|
||||||
|
type: source-derivative
|
||||||
|
tags:
|
||||||
|
- "PaddleOCR"
|
||||||
|
- "OCR"
|
||||||
|
- "API"
|
||||||
|
- "配额"
|
||||||
|
confidence: high
|
||||||
|
contested: false
|
||||||
|
evidence_boundary: "文档文本由用户 2026-08-07 从 PaddleOCR 官方 API 文档页提供,未保留原始 URL;同日对 v2 jobs 接口实测:PP-OCRv6 与 PaddleOCR-VL-1.6 两模型各多次提交 job 均返回 HTTP 200 并成功解析(中文金融表格文本识别准确),403/429/413/422/500/503/504 错误码行为未实测触发,仅按官方文档转述。配额(3000 页/日/模型、单文件 100 页截断)为官方声明值,随平台策略可能调整。"
|
||||||
|
---
|
||||||
|
|
||||||
|
# 来源说明
|
||||||
|
|
||||||
|
本文件摘编 PaddleOCR v2 异步 API(`https://paddleocr.aistudio-app.com/api/v2/ocr/jobs`)的调用配额与错误码规则,供本地 OCR 工具链(`wikillm/scripts/paddleocr_v2_ocr.py`)使用时参考。
|
||||||
|
|
||||||
|
## 证据分级
|
||||||
|
|
||||||
|
- **官方声明**:配额数值(3000 页/日/模型、单文件 ≤100 页)、错误码含义表。
|
||||||
|
- **实测验证**(2026-08-07):两模型 job 提交→轮询→结果下载全链路通过,HTTP 200;中文文本与表格还原正确。
|
||||||
|
- **未实测**:错误码 403/413/422/429/500/503/504 的实际触发场景;配额耗尽时的具体行为。
|
||||||
|
|
||||||
|
# 1. 配额规则
|
||||||
|
|
||||||
|
| 规则 | 数值 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| 每日解析上限 | **3000 页/用户/模型** | 超额后请求无法处理,返回 **429**(Too Many Requests) |
|
||||||
|
| 单文件页数建议 | **≤ 100 页** | 避免处理时间过长导致网关超时 |
|
||||||
|
| 超页截断 | >100 页仅解析**前 100 页** | 后续页面被忽略,无报错 |
|
||||||
|
| 提额 | 官方问卷免费申请 | 有更高解析需求时填写 |
|
||||||
|
|
||||||
|
# 2. 错误码说明
|
||||||
|
|
||||||
|
| 错误码 | 含义 | 解决建议 |
|
||||||
|
|---|---|---|
|
||||||
|
| 403 | Token 错误 | 检查 Token 是否正确,或 URL 是否与 Token 匹配 |
|
||||||
|
| 413 | 请求体过大 | 减少 PDF 页数或文件大小 |
|
||||||
|
| 422 | 参数无效 | 参考 errorMsg 解决 |
|
||||||
|
| 429 | 超出单日解析最大页数 | 换用其他模型或稍后再试 |
|
||||||
|
| 500 | 服务器内部错误 | 频繁出现请联系 PaddleOCR 官方 |
|
||||||
|
| 503 | 当前请求过多 | 稍后再试 |
|
||||||
|
| 504 | 网关超时 | 稍后再试 |
|
||||||
|
|
||||||
|
# 3. 本地工具链衔接
|
||||||
|
|
||||||
|
- 工具脚本:`wikillm/scripts/paddleocr_v2_ocr.py`(v2 jobs 协议,支持 `--model` 切换模型、`--out` 指定输出目录)。
|
||||||
|
- 凭证:`PADDLEOCR_ACCESS_TOKEN`(hermes-home/.env),默认 fallback token 内嵌于脚本。
|
||||||
|
- 双模型配额独立:PP-OCRv6(行级文本 + bbox + 置信度)与 PaddleOCR-VL-1.6(整页 Markdown,表格/版面/公式还原)可轮换以规避单模型 429。
|
||||||
|
- 批量场景(如整本书籍扫描件入库):注意单文件 100 页截断,建议先按章拆页;每日 3000 页上限需按批次规划。
|
||||||
@@ -0,0 +1,227 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
PaddleOCR v2 jobs async API OCR tool (user-verified, PP-OCRv6).
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python paddleocr_v2_ocr.py <file_path_or_url> [--model PP-OCRv6] [--out DIR]
|
||||||
|
|
||||||
|
Token: read from env PADDLEOCR_ACCESS_TOKEN (already in hermes-home/.env),
|
||||||
|
fallback to hardcoded token below.
|
||||||
|
|
||||||
|
Reference: official PaddleOCR v2 jobs API example (2026-08).
|
||||||
|
Verified working 2026-08-07 with Chinese financial text image.
|
||||||
|
"""
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import requests
|
||||||
|
|
||||||
|
JOB_URL = "https://paddleocr.aistudio-app.com/api/v2/ocr/jobs"
|
||||||
|
|
||||||
|
def _load_token() -> str:
|
||||||
|
"""Load PADDLEOCR_ACCESS_TOKEN from env, then hermes-home/.env as fallback."""
|
||||||
|
tok = os.environ.get("PADDLEOCR_ACCESS_TOKEN", "").strip()
|
||||||
|
if tok:
|
||||||
|
return tok
|
||||||
|
env_path = os.path.join(
|
||||||
|
os.path.expanduser("~"), "AppData", "Local",
|
||||||
|
"Hermes Agent CN Desktop", "data", "hermes-home", ".env",
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
with open(env_path, encoding="utf-8") as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if line.startswith("PADDLEOCR_ACCESS_TOKEN="):
|
||||||
|
return line.split("=", 1)[1].strip()
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
return ""
|
||||||
|
|
||||||
|
TOKEN = _load_token()
|
||||||
|
MODEL = "PP-OCRv6"
|
||||||
|
|
||||||
|
optional_payload = {
|
||||||
|
"useDocOrientationClassify": False,
|
||||||
|
"useDocUnwarping": False,
|
||||||
|
"useTextlineOrientation": False,
|
||||||
|
}
|
||||||
|
|
||||||
|
def _html_table_to_markdown(html: str) -> str:
|
||||||
|
"""Convert a simple <table> HTML string to a markdown table."""
|
||||||
|
if not html or "<table" not in html:
|
||||||
|
return html
|
||||||
|
import re
|
||||||
|
rows = re.findall(r"<tr>(.*?)</tr>", html, re.S)
|
||||||
|
md_lines = []
|
||||||
|
for i, row in enumerate(rows):
|
||||||
|
cells = re.findall(r"<t[dh]>(.*?)</t[dh]>", row, re.S)
|
||||||
|
cells = [c.strip() for c in cells]
|
||||||
|
md_lines.append("| " + " | ".join(cells) + " |")
|
||||||
|
if i == 0:
|
||||||
|
md_lines.append("| " + " | ".join(["---"] * len(cells)) + " |")
|
||||||
|
return "\n".join(md_lines)
|
||||||
|
|
||||||
|
|
||||||
|
def run(file_path: str, model: str = MODEL, out_dir: str = "output"):
|
||||||
|
headers = {"Authorization": f"bearer {TOKEN}"}
|
||||||
|
print(f"Processing file: {file_path}")
|
||||||
|
|
||||||
|
if file_path.startswith("http"):
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
payload = {"fileUrl": file_path, "model": model, "optionalPayload": optional_payload}
|
||||||
|
job_response = requests.post(JOB_URL, json=payload, headers=headers)
|
||||||
|
else:
|
||||||
|
if not os.path.exists(file_path):
|
||||||
|
print(f"Error: File not found at {file_path}")
|
||||||
|
sys.exit(1)
|
||||||
|
data = {"model": model, "optionalPayload": json.dumps(optional_payload)}
|
||||||
|
with open(file_path, "rb") as f:
|
||||||
|
files = {"file": f}
|
||||||
|
job_response = requests.post(JOB_URL, headers=headers, data=data, files=files)
|
||||||
|
|
||||||
|
print(f"Response status: {job_response.status_code}")
|
||||||
|
if job_response.status_code != 200:
|
||||||
|
print(f"Response content: {job_response.text}")
|
||||||
|
assert job_response.status_code == 200
|
||||||
|
|
||||||
|
jobId = job_response.json()["data"]["jobId"]
|
||||||
|
print(f"Job submitted successfully. job id: {jobId}")
|
||||||
|
print("Start polling for results")
|
||||||
|
|
||||||
|
jsonl_url = ""
|
||||||
|
while True:
|
||||||
|
r = requests.get(f"{JOB_URL}/{jobId}", headers=headers)
|
||||||
|
assert r.status_code == 200
|
||||||
|
state = r.json()["data"]["state"]
|
||||||
|
if state == 'pending':
|
||||||
|
print("The current status of the job is pending")
|
||||||
|
elif state == 'running':
|
||||||
|
try:
|
||||||
|
tp = r.json()['data']['extractProgress']['totalPages']
|
||||||
|
ep = r.json()['data']['extractProgress']['extractedPages']
|
||||||
|
print(f"running, total pages: {tp}, extracted pages: {ep}")
|
||||||
|
except KeyError:
|
||||||
|
print("running...")
|
||||||
|
elif state == 'done':
|
||||||
|
ep = r.json()['data']['extractProgress']['extractedPages']
|
||||||
|
st = r.json()['data']['extractProgress']['startTime']
|
||||||
|
et = r.json()['data']['extractProgress']['endTime']
|
||||||
|
print(f"Job completed, pages: {ep}, {st} -> {et}")
|
||||||
|
jsonl_url = r.json()['data']['resultUrl']['jsonUrl']
|
||||||
|
break
|
||||||
|
elif state == "failed":
|
||||||
|
print(f"Job failed: {r.json()['data']['errorMsg']}")
|
||||||
|
sys.exit(1)
|
||||||
|
time.sleep(5)
|
||||||
|
|
||||||
|
if jsonl_url:
|
||||||
|
jr = requests.get(jsonl_url)
|
||||||
|
jr.raise_for_status()
|
||||||
|
lines = jr.text.strip().split('\n')
|
||||||
|
os.makedirs(out_dir, exist_ok=True)
|
||||||
|
page_num = 0
|
||||||
|
for line in lines:
|
||||||
|
line = line.strip()
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
obj = json.loads(line)
|
||||||
|
result = obj.get("result") or {}
|
||||||
|
page_num += 1
|
||||||
|
print(f"--- page {page_num} ---")
|
||||||
|
|
||||||
|
# Style A: PP-OCRv5/v6 (ocrResults)
|
||||||
|
if isinstance(result, dict) and "ocrResults" in result:
|
||||||
|
for res in result.get("ocrResults", []):
|
||||||
|
pruned = res.get("prunedResult", {})
|
||||||
|
texts = pruned.get("rec_texts", [])
|
||||||
|
scores = pruned.get("rec_scores", [])
|
||||||
|
for t, s in zip(texts, scores):
|
||||||
|
print(f" [{s:.2f}] {t}")
|
||||||
|
img_url = res.get("ocrImage")
|
||||||
|
if img_url:
|
||||||
|
ir = requests.get(img_url)
|
||||||
|
if ir.status_code == 200:
|
||||||
|
fn = os.path.join(out_dir, f"img_output_{page_num}.jpg")
|
||||||
|
with open(fn, "wb") as f:
|
||||||
|
f.write(ir.content)
|
||||||
|
print(f"Image saved to: {fn}")
|
||||||
|
|
||||||
|
# Style B: PaddleOCR-VL models (layoutParsingResults)
|
||||||
|
elif isinstance(result, dict) and "layoutParsingResults" in result:
|
||||||
|
for res in result.get("layoutParsingResults", []):
|
||||||
|
md = res.get("markdown") or {}
|
||||||
|
md_text = md.get("text")
|
||||||
|
if md_text:
|
||||||
|
md_path = os.path.join(out_dir, f"doc_{page_num}.md")
|
||||||
|
with open(md_path, "w", encoding="utf-8") as f:
|
||||||
|
f.write(md_text)
|
||||||
|
print(f"Markdown saved to: {md_path}")
|
||||||
|
print("--- markdown content ---")
|
||||||
|
print(md_text)
|
||||||
|
for img_rel, img_url in (md.get("images") or {}).items():
|
||||||
|
try:
|
||||||
|
ir = requests.get(img_url)
|
||||||
|
if ir.status_code == 200:
|
||||||
|
full = os.path.join(
|
||||||
|
out_dir, img_rel.replace("\\", "/")
|
||||||
|
)
|
||||||
|
os.makedirs(
|
||||||
|
os.path.dirname(full), exist_ok=True
|
||||||
|
)
|
||||||
|
with open(full, "wb") as f:
|
||||||
|
f.write(ir.content)
|
||||||
|
print(f"Markdown image saved to: {full}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Markdown image download failed: {e}")
|
||||||
|
else:
|
||||||
|
# Fallback: block-level parsing list
|
||||||
|
pruned = res.get("prunedResult", {})
|
||||||
|
for blk in (pruned.get("parsing_res_list") or []):
|
||||||
|
label = blk.get("block_label", "?")
|
||||||
|
content = blk.get("block_content", "")
|
||||||
|
if label == "table":
|
||||||
|
print(" [table] markdown:")
|
||||||
|
print(_html_table_to_markdown(content))
|
||||||
|
else:
|
||||||
|
print(f" [{label}] {content}")
|
||||||
|
for img_name, img_url in (res.get("outputImages") or {}).items():
|
||||||
|
try:
|
||||||
|
ir = requests.get(img_url)
|
||||||
|
if ir.status_code == 200:
|
||||||
|
fn = os.path.join(
|
||||||
|
out_dir, f"{img_name}_{page_num}.jpg"
|
||||||
|
)
|
||||||
|
with open(fn, "wb") as f:
|
||||||
|
f.write(ir.content)
|
||||||
|
print(f"Image saved to: {fn}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Image download failed: {e}")
|
||||||
|
|
||||||
|
else:
|
||||||
|
print(" (unknown result schema; raw json saved below)")
|
||||||
|
|
||||||
|
# Save raw result per page
|
||||||
|
raw_path = os.path.join(out_dir, f"page_{page_num}.json")
|
||||||
|
with open(raw_path, "w", encoding="utf-8") as f:
|
||||||
|
f.write(json.dumps(obj, ensure_ascii=False, indent=2))
|
||||||
|
print(f"Raw saved to: {raw_path}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print(__doc__)
|
||||||
|
sys.exit(1)
|
||||||
|
file_arg = sys.argv[1]
|
||||||
|
model_arg = MODEL
|
||||||
|
out_arg = "output"
|
||||||
|
i = 2
|
||||||
|
while i < len(sys.argv):
|
||||||
|
if sys.argv[i] == "--model" and i + 1 < len(sys.argv):
|
||||||
|
model_arg = sys.argv[i + 1]
|
||||||
|
i += 2
|
||||||
|
elif sys.argv[i] == "--out" and i + 1 < len(sys.argv):
|
||||||
|
out_arg = sys.argv[i + 1]
|
||||||
|
i += 2
|
||||||
|
else:
|
||||||
|
i += 1
|
||||||
|
run(file_arg, model_arg, out_arg)
|
||||||
@@ -92,6 +92,12 @@ last_updated: 2026-08-03
|
|||||||
**中文**: 语义知识
|
**中文**: 语义知识
|
||||||
**定义**: 存储在任何单个情节之外都存在的抽象:领域事实、一般启发式、项目约定和稳定的世界知识。
|
**定义**: 存储在任何单个情节之外都存在的抽象:领域事实、一般启发式、项目约定和稳定的世界知识。
|
||||||
|
|
||||||
|
### PaddleOCR
|
||||||
|
**英文**: PaddleOCR
|
||||||
|
**中文**: PaddleOCR(飞桨 OCR 套件)
|
||||||
|
**定义**: 百度飞桨开源的 OCR 工具套件;本 Wiki 使用其 v2 异步 API(云端)做中文文档 OCR,含 PP-OCRv6(行级文本 + 置信度)与 PaddleOCR-VL-1.6(整页 Markdown、表格/版面还原)两模型。
|
||||||
|
**参见**: [[paddleocr-ocr工具链]]
|
||||||
|
|
||||||
### Personalized Memory (个性化记忆)
|
### Personalized Memory (个性化记忆)
|
||||||
**英文**: Personalized Memory
|
**英文**: Personalized Memory
|
||||||
**中文**: 个性化记忆
|
**中文**: 个性化记忆
|
||||||
|
|||||||
+2
-1
@@ -118,9 +118,10 @@ last_updated: 2026-08-07
|
|||||||
- [[玻璃数据字典与数据库设计|玻璃数据字典与数据库设计]] - 隆众、Wind、海关指标口径与质量检查
|
- [[玻璃数据字典与数据库设计|玻璃数据字典与数据库设计]] - 隆众、Wind、海关指标口径与质量检查
|
||||||
- [[企业自由现金流分析|企业自由现金流分析]] - FCFF、FCFE 和现金流指标审阅方法
|
- [[企业自由现金流分析|企业自由现金流分析]] - FCFF、FCFE 和现金流指标审阅方法
|
||||||
|
|
||||||
## 10. 网络工具
|
## 10. 软件工具
|
||||||
- [[mihomo-内核与配置体系|mihomo(Clash Meta 内核)架构与配置体系]] - 代理内核的分层架构、DNS 防污染(fake-ip)、规则路由、健康检查与提供者机制
|
- [[mihomo-内核与配置体系|mihomo(Clash Meta 内核)架构与配置体系]] - 代理内核的分层架构、DNS 防污染(fake-ip)、规则路由、健康检查与提供者机制
|
||||||
- [[mihomo-配置编写指南|mihomo 配置编写指南]] - 从零编写 config.yaml 的流程、模板与检查清单,供代写配置复用
|
- [[mihomo-配置编写指南|mihomo 配置编写指南]] - 从零编写 config.yaml 的流程、模板与检查清单,供代写配置复用
|
||||||
|
- [[paddleocr-ocr工具链|PaddleOCR OCR 工具链]] - 云端 OCR 双模型(PP-OCRv6 / VL-1.6)选型、配额与错误码速查
|
||||||
|
|
||||||
## 资料与证据
|
## 资料与证据
|
||||||
- [[期货资料来源与证据边界|期货资料来源与证据边界]] - 期货资料轻量化迁移、证据等级和未复制文件说明
|
- [[期货资料来源与证据边界|期货资料来源与证据边界]] - 期货资料轻量化迁移、证据等级和未复制文件说明
|
||||||
|
|||||||
@@ -111,3 +111,4 @@ raw/技术/mihomo/官方文档-架构与核心概念-摘编.md d2540a477284aa6b4
|
|||||||
raw/技术/mihomo/官方文档-配置编写-摘编.md 17ad7664cb257744a3277c1709d15912156a521dcac1f014ccfd335f3880b1cf 2026-08-07 wiki/concepts/mihomo-内核与配置体系.md,wiki/practices/mihomo-配置编写指南.md,wiki/INDEX.md,wiki/Glossary.md,wiki/sources.md 2026-08-07 success
|
raw/技术/mihomo/官方文档-配置编写-摘编.md 17ad7664cb257744a3277c1709d15912156a521dcac1f014ccfd335f3880b1cf 2026-08-07 wiki/concepts/mihomo-内核与配置体系.md,wiki/practices/mihomo-配置编写指南.md,wiki/INDEX.md,wiki/Glossary.md,wiki/sources.md 2026-08-07 success
|
||||||
raw/期货/00-整体相关/The-Laws-of-Trading-交易决策法则-2019-摘编.md sha256:a04313cd96173765c818128c915423f36c439d5c87308bd27b81be0bd8b56469 2026-08-07 wiki/concepts/交易决策法则.md,wiki/practices/交易决策检查清单.md,wiki/INDEX.md,wiki/sources.md,wiki/Glossary.md 2026-08-07 success
|
raw/期货/00-整体相关/The-Laws-of-Trading-交易决策法则-2019-摘编.md sha256:a04313cd96173765c818128c915423f36c439d5c87308bd27b81be0bd8b56469 2026-08-07 wiki/concepts/交易决策法则.md,wiki/practices/交易决策检查清单.md,wiki/INDEX.md,wiki/sources.md,wiki/Glossary.md 2026-08-07 success
|
||||||
raw/期货/00-整体相关/我国商品期货市场大交割的理论探究-中期协课题-2021-摘编.md sha256:9313f138332bf534e882bfcc4c0f8b74814f4403ea4750004bf75177f2982e7e 2026-08-07 wiki/concepts/大交割机制与实证.md,wiki/INDEX.md,wiki/Glossary.md,wiki/sources.md 2026-08-07 success
|
raw/期货/00-整体相关/我国商品期货市场大交割的理论探究-中期协课题-2021-摘编.md sha256:9313f138332bf534e882bfcc4c0f8b74814f4403ea4750004bf75177f2982e7e 2026-08-07 wiki/concepts/大交割机制与实证.md,wiki/INDEX.md,wiki/Glossary.md,wiki/sources.md 2026-08-07 success
|
||||||
|
raw/技术/paddleocr/paddleocr-api-配额与错误码-摘编.md sha256:b8d0e2c51e46e09ce789ff397149cfdde2b136d37a2c9cb981a99977cc90b3a7 2026-08-07 wiki/practices/paddleocr-ocr工具链.md,wiki/INDEX.md,wiki/sources.md 2026-08-07 success
|
||||||
|
|||||||
|
@@ -295,3 +295,9 @@
|
|||||||
- 证据边界:统计期 2018—2021 年上半年;扫描件 OCR 对表格行列结构有损,仅正文文字明确转述的数字入摘编;"12 个合约"(风险检验)与"11 个品种"(成因分析)口径差异来自动力煤车船板交割无仓单数据。
|
- 证据边界:统计期 2018—2021 年上半年;扫描件 OCR 对表格行列结构有损,仅正文文字明确转述的数字入摘编;"12 个合约"(风险检验)与"11 个品种"(成因分析)口径差异来自动力煤车船板交割无仓单数据。
|
||||||
- 哈希:摘编按正文(frontmatter 之后 body)SHA-256 登记 `sha256:9313f138332bf534e882bfcc4c0f8b74814f4403ea4750004bf75177f2982e7e`。
|
- 哈希:摘编按正文(frontmatter 之后 body)SHA-256 登记 `sha256:9313f138332bf534e882bfcc4c0f8b74814f4403ea4750004bf75177f2982e7e`。
|
||||||
- 验证:wiki-audit.ps1 普通模式通过(0 ERROR、0 WARNING;78 个 Wiki 页面、668 条内部链接、111 条编译记录),`git diff --check` 通过。
|
- 验证:wiki-audit.ps1 普通模式通过(0 ERROR、0 WARNING;78 个 Wiki 页面、668 条内部链接、111 条编译记录),`git diff --check` 通过。
|
||||||
|
## [2026-08-07] ingest | PaddleOCR v2 API 配额与错误码入库
|
||||||
|
- 输入:PaddleOCR 官方 API 文档(用户 2026-08-07 提供,配额与错误码两节);同日 v2 jobs 接口实测(PP-OCRv6 与 PaddleOCR-VL-1.6 双模型多次 job 提交均 HTTP 200,中文金融表格文本识别正确)。
|
||||||
|
- 保存:中文摘编 1 份入 `raw/技术/paddleocr/`(配额 3000 页/日/模型、单文件 100 页截断、错误码 403/413/422/429/500/503/504 表、本地工具链衔接)。
|
||||||
|
- 编译:新增 `wiki/practices/paddleocr-ocr工具链.md`(practice:工具脚本入口、双模型选型口诀、配额/限流注意、错误码速查、实测记录);`wiki/INDEX.md` 第 10 节更名“软件工具”并加条目;`wiki/sources.md` 新增“OCR 工具资料”小节;`wiki/Glossary.md` 新增 PaddleOCR 词条;登记 `wiki/compile-results.tsv`。
|
||||||
|
- 证据边界:错误码行为仅按官方文档转述,未实测触发;配额数值为官方声明,可能调整;token 以 hermes-home/.env 为准。
|
||||||
|
- 哈希:摘编文件字节 SHA-256 `b8d0e2c51e46e09ce789ff397149cfdde2b136d37a2c9cb981a99977cc90b3a7`。
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
---
|
||||||
|
title: "PaddleOCR OCR 工具链使用指南"
|
||||||
|
source: "PaddleOCR 官方 API 文档 + 2026-08-07 本地实测(wikillm/scripts/paddleocr_v2_ocr.py)"
|
||||||
|
tags:
|
||||||
|
- "PaddleOCR"
|
||||||
|
- "OCR"
|
||||||
|
- "工具链"
|
||||||
|
sources:
|
||||||
|
- path: "raw/技术/paddleocr/paddleocr-api-配额与错误码-摘编.md"
|
||||||
|
---
|
||||||
|
|
||||||
|
# PaddleOCR OCR 工具链使用指南
|
||||||
|
|
||||||
|
本页是**实践页**:说明本地 PaddleOCR 云端 OCR 工具链怎么用——两种模型的选型、调用方式、配额注意与结果处理。配额与错误码细则见 `raw/技术/paddleocr/` 摘编。
|
||||||
|
|
||||||
|
## 工具入口
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python wikillm/scripts/paddleocr_v2_ocr.py <本地文件或URL> [--model 模型名] [--out 输出目录]
|
||||||
|
```
|
||||||
|
|
||||||
|
- 协议:PaddleOCR v2 异步 jobs API(提交 job → 轮询 → 下载 jsonl 结果)。
|
||||||
|
- 凭证:`PADDLEOCR_ACCESS_TOKEN`(已存 hermes-home/.env;脚本内嵌 fallback token)。
|
||||||
|
- 输出:每页原始 JSON(`page_N.json`)+ 模型专属产物(见下)。
|
||||||
|
|
||||||
|
## 模型选型
|
||||||
|
|
||||||
|
| 模型 | 输出形态 | 适用场景 |
|
||||||
|
|---|---|---|
|
||||||
|
| `PP-OCRv6`(默认) | 行级文本 + bbox 坐标 + 每行置信度(`rec_scores`) | 纯文字提取:截图、照片、扫描件文字 |
|
||||||
|
| `PaddleOCR-VL-1.6` | **整页 Markdown**(`doc_N.md`,表格还原为 HTML 表格)+ 版面分块 + 可视化图 | 带表格/复杂版式的文档:研报、报表、书籍页面 |
|
||||||
|
|
||||||
|
选型口诀:**纯文字用 v6,带表格用 VL-1.6**。两模型配额独立(各 3000 页/日),可轮换规避 429。
|
||||||
|
|
||||||
|
## 配额与限流(2026-08-07 官方声明)
|
||||||
|
|
||||||
|
- 每用户 × 每模型 **3000 页/日**;超额返回 429,当日该模型不可用。
|
||||||
|
- **单文件 ≤ 100 页**,超过只解析前 100 页(静默截断,无报错)。
|
||||||
|
- 批量任务(如整本书扫描件)务必先按章拆页;大批量按批次规划并预留双模型轮换。
|
||||||
|
|
||||||
|
## 常见错误速查
|
||||||
|
|
||||||
|
| 码 | 含义 | 处理 |
|
||||||
|
|---|---|---|
|
||||||
|
| 403 | Token 错/URL 不匹配 | 核对 hermes-home/.env 中的 token |
|
||||||
|
| 413 | 请求体过大 | 减页数/文件大小 |
|
||||||
|
| 429 | 超当日页数上限 | 换模型或次日再试 |
|
||||||
|
| 504 | 网关超时 | 稍后重试(大文件建议先拆页) |
|
||||||
|
|
||||||
|
## 实测记录(2026-08-07)
|
||||||
|
|
||||||
|
- PP-OCRv6:中文金融表格图片识别,文本置信度 0.94–1.00,行级输出正确。
|
||||||
|
- PaddleOCR-VL-1.6:同图整页 Markdown 还原,5 行 4 列表格 HTML 全部正确(品种/产地/价格/较昨日)。
|
||||||
|
|
||||||
|
## 相关
|
||||||
|
|
||||||
|
- [[Glossary|术语表]] - PaddleOCR、OCR 等术语
|
||||||
|
- raw 摘编:`raw/技术/paddleocr/paddleocr-api-配额与错误码-摘编.md`
|
||||||
|
- 官方:https://www.paddleocr.com / https://paddleocr.aistudio-app.com
|
||||||
@@ -100,3 +100,7 @@ last_updated: 2026-08-07
|
|||||||
## 网络工具资料
|
## 网络工具资料
|
||||||
|
|
||||||
- [[mihomo-内核与配置体系|mihomo(Clash Meta 内核)架构与配置体系]]、[[mihomo-配置编写指南|mihomo 配置编写指南]] - [MetaCubeX/mihomo](https://github.com/MetaCubeX/mihomo)(Clash Meta 内核,GPL-3.0,默认分支 Meta)官方 README、官方文档 [wiki.metacubex.one](https://wiki.metacubex.one/)(虚空终端 Docs)与 Alpha 分支 `docs/config.yaml` 全量示例(2026-08-07 抓取);中文摘编保存在 `raw/技术/mihomo/`。官方示例中服务器/密码/密钥为占位符,模板未在真实实例上运行验证
|
- [[mihomo-内核与配置体系|mihomo(Clash Meta 内核)架构与配置体系]]、[[mihomo-配置编写指南|mihomo 配置编写指南]] - [MetaCubeX/mihomo](https://github.com/MetaCubeX/mihomo)(Clash Meta 内核,GPL-3.0,默认分支 Meta)官方 README、官方文档 [wiki.metacubex.one](https://wiki.metacubex.one/)(虚空终端 Docs)与 Alpha 分支 `docs/config.yaml` 全量示例(2026-08-07 抓取);中文摘编保存在 `raw/技术/mihomo/`。官方示例中服务器/密码/密钥为占位符,模板未在真实实例上运行验证
|
||||||
|
|
||||||
|
## OCR 工具资料
|
||||||
|
|
||||||
|
- [[paddleocr-ocr工具链|PaddleOCR OCR 工具链]] - PaddleOCR v2 异步 API(paddleocr.aistudio-app.com/api/v2/ocr/jobs)配额与错误码官方文档(2026-08-07 用户提供)+ 同日本地实测(PP-OCRv6 / PaddleOCR-VL-1.6 双模型真实调用通过);中文摘编保存在 `raw/技术/paddleocr/`,工具脚本 `scripts/paddleocr_v2_ocr.py`
|
||||||
|
|||||||
Reference in New Issue
Block a user