Files
hunjing/tianmu/README.md

331 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 天目 · 本地 OCR 引擎
天目(Tiānmù)是魂镜的**本地 OCR 推理引擎**,基于 RapidOCR(PP-OCRv6)和 PaddleOCR-VL-1.6,纯 Python 实现,直接加载 ONNX / PaddlePaddle 模型进行本地文字识别和文档解析。
> 「天目」为观天象、察文字之眼,映照万物纹理;在魂镜中承载本地 OCR 感知能力,为人物的视觉感知提供文字提取与文档理解。
---
## 架构概览
```mermaid
flowchart LR
lingtai[灵台 · Backend]
tianmu[天目 · OCR Local Engine]
models[(models/ocr/ 目录)]
lingtai -->|POST /v1/ocr| tianmu
lingtai -->|POST /v1/ocr/vl| tianmu
lingtai -->|GET /healthz| tianmu
tianmu -->|RapidOCR ONNX Runtime| models
tianmu -->|PaddleOCR-VL 直接加载| models
```
## 提供的 API
| 端点 | 能力 | 引擎 |
| --- | --- | --- |
| `POST /v1/ocr` | 通用文字识别 | RapidOCR(PP-OCRv6) |
| `POST /v1/ocr/vl` | 复杂文档解析(Phase 3) | PaddleOCR-VL-1.6 |
| `GET /healthz` | 健康检查 | — |
### POST /v1/ocr
请求:
```json
{
"image": "<base64 或 HTTP URL>",
"engine": "auto",
"lang": ["ch", "en"]
}
```
响应:
```json
{
"engine": "ppocrv6",
"text": "识别后的文本...",
"blocks": [
{
"text": "字",
"confidence": 0.98,
"bbox": { "points": [[x1,y1],[x2,y1],[x2,y2],[x1,y2]] }
}
],
"duration_ms": 423,
"error": null
}
```
## 模型文件结构
所有模型统一放在项目根目录 `models/ocr/` 下,已预下载完毕:
```text
models/ocr/
├── ppocrv6/ # PP-OCRv6 ONNX 模型(168 MB)
│ ├── det/
│ │ ├── PP-OCRv6_det_tiny.onnx # 轻量检测(1.8 MB)
│ │ ├── PP-OCRv6_det_small.onnx # 默认检测(9.5 MB)
│ │ └── PP-OCRv6_det_medium.onnx # 高精度检测(59 MB)
│ ├── rec/
│ │ ├── PP-OCRv6_rec_tiny.onnx # 轻量识别(4.3 MB)
│ │ ├── PP-OCRv6_rec_small.onnx # 默认识别(20 MB)
│ │ ├── PP-OCRv6_rec_medium.onnx # 高精度识别(73 MB)
│ │ ├── ppocrv6_tiny_dict.txt # tiny 词表(27 KB)
│ │ └── ppocrv6_dict.txt # small/medium 词表(75 KB)
│ └── cls/
│ └── ch_ppocr_mobile_v2.0_cls_mobile.onnx # 方向分类(0.57 MB)
└── paddleocr-vl/ # PaddleOCR-VL-1.6(1.8 GB)
├── model.safetensors
├── config.json
├── tokenizer.json / tokenizer.model
└── modeling_paddleocr_vl.py
```
各模型来源:
| 模型 | 来源 | 下载方式 |
| --- | --- | --------- |
| PP-OCRv6(det/rec/cls) | [RapidAI/RapidOCR - ModelScope](https://www.modelscope.cn/models/RapidAI/RapidOCR) | 预下载或自动下载 |
| PaddleOCR-VL-1.6 | [PaddlePaddle/PaddleOCR-VL-1.6 - HuggingFace](https://huggingface.co/PaddlePaddle/PaddleOCR-VL-1.6) | 已预下载 |
## 快速开始
```bash
# 1. 进入天目目录
cd tianmu
# 2. 创建虚拟环境并安装依赖
uv venv -p 3.12
source .venv/bin/activate
# 3. 安装依赖(根据平台和需求选择)
# macOS(Apple Silicon)推荐
uv sync --system-certs --extra macos
# Linux/Windows(带 GPU 支持)
uv sync --extra all
# 仅 PP-OCRv6(所有平台)
uv sync --system-certs --extra rapidocr
# 4. 启动天目(推荐)
uv run tianmu
# 5. 验证健康检查
curl http://localhost:8101/healthz
# 6. 测试 OCR(base64 图片)
python3 tests/test_ocr.py
```
## 平台与依赖说明
| 平台 | 推荐命令 | 说明 |
| ------ | --------- | ------ |
| **macOS(Apple Silicon)** | `uv sync --system-certs --extra macos` | 自动使用 CPU/MPS,跳过 GPU 依赖 |
| **Linux(NVIDIA GPU)** | `uv sync --extra all` | 自动使用 CUDA 12.8 版本 |
| **Windows(NVIDIA GPU)** | `uv sync --extra all` | 自动使用 CUDA 12.8 版本 |
| **所有平台(仅 CPU)** | `uv sync --system-certs --extra rapidocr --extra vl` | 通用 CPU 版本 |
> **注意**:macOS 用户需要使用 `--system-certs` 标志来解决 SSL 证书验证问题,或在 `~/.zshrc` 中设置 `export UV_SYSTEM_CERTS=true`。
## 启动方式对比
| 命令 | 适用场景 | reload | 泄漏警告 |
| ------ | --------- | -------- | --------- |
| `uv run tianmu` | 开发(推荐) | ❌ | ❌ |
| `uv run uvicorn src.main:app --port 8101 --reload` | 开发热重载 | ✅ | ⚠️ reloader 进程可能打印 resource_tracker 警告 |
| `python3 -m src.main` | 快速测试 | ❌ | ❌ |
> `--reload` 下的 `resource_tracker` 警告是 uvicorn WatchFiles reloader 进程本身的多进程行为,不影响天目功能,纯属视觉问题。生产环境(Docker)无此问题。
## 启动和测试
天目提供三种测试方式:
### 方式一:远程图片测试
```bash
curl -s -X POST http://localhost:8101/v1/ocr \
-H "Content-Type: application/json" \
-d '{"image": "https://example.com/test-image.jpg"}' \
| python3 -m json.tool
```
### 方式二:base64 图片测试
```bash
# 使用内置测试脚本生成测试图片并调用
cd tianmu && source .venv/bin/activate
python3 tests/test_ocr.py
```
### 方式三:本地文件测试
```bash
curl -s -X POST http://localhost:8101/v1/ocr \
-H "Content-Type: application/json" \
-d "{\"image\": \"$(base64 -i /path/to/image.jpg | tr -d '\n')\"}" \
| python3 -m json.tool
```
## 配置
通过 `TIANMU_*` 环境变量配置(详见 `.env.example`):
| 变量 | 默认值 | 说明 |
| --- | --- | --- |
| `TIANMU_HOST` | `0.0.0.0` | 监听地址 |
| `TIANMU_PORT` | `8101` | 监听端口 |
| `TIANMU_MODELS_DIR` | `../models` | 模型文件根目录 |
| `TIANMU_DEVICE` | `auto` | 推理设备:auto / cuda / mps / cpu |
| `TIANMU_LOG_LEVEL` | `info` | 日志级别 |
## 项目结构
```text
tianmu/ # 源代码
├── pyproject.toml # 依赖(rapidocr / paddlepaddle)
├── README.md # 本文件
├── src/
│ ├── main.py # FastAPI 入口
│ ├── config.py # 配置加载(环境变量 → models/ 路径解析)
│ ├── endpoints/
│ │ ├── ocr.py # OCR 端点(/v1/ocr + /v1/ocr/vl)
│ │ └── health.py # 健康检查端点(/healthz)
│ ├── engine/
│ │ ├── rapidocr.py # RapidOCR(PP-OCRv6)推理引擎
│ │ └── paddleocr_vl.py # PaddleOCR-VL-1.6 引擎(预留)
│ ├── schemas/
│ │ └── ocr.py # Pydantic 请求/响应模型
│ └── utils/
│ └── logging.py # loguru 日志配置
└── tests/
├── test_ocr.py # OCR 集成测试(生成图片 + 调用 API)
└── __init__.py
docker/tianmu/ # Docker 构建文件
├── Dockerfile
└── .dockerignore
```
## 引擎选择
天目提供两个引擎,按需切换:
| 引擎 | 场景 | 速度 | 精度 | 依赖 |
| --- | --- | --- | --- | --- |
| PP-OCRv6(via RapidOCR) | 通用文字提取 | ~400ms(CPU) | ⭐⭐⭐⭐ | `rapidocr` |
| PaddleOCR-VL-1.6 | 复杂文档/表格/古籍 | ~3-12s(GPU) | ⭐⭐⭐⭐⭐ | `paddlepaddle` |
调用时通过 `engine` 参数指定:
```json
// 强制使用 PP-OCRv6
{"image": "...", "engine": "ppocrv6"}
// 强制使用 PaddleOCR-VL
{"image": "...", "engine": "paddleocr-vl"}
```
`engine` 不传或传 `auto` 时默认走 PP-OCRv6。
## Docker 部署
详见 `docker/README.md` 及 `docker-compose.app.yml` 中 `hunjing-tianmu` 服务定义。
```bash
# Docker 启动
docker compose -f docker/docker-compose.app.yml --profile tianmu up -d --build hunjing-tianmu
```
## 依赖分组
天目提供灵活的依赖安装方式,适应不同平台和场景:
### 基础分组
| Extra | 包含内容 | 适用平台 |
| ------- | --------- | --------- |
| `rapidocr` | PP-OCRv6 引擎(CPU) | 所有平台 |
| `rapidocr-gpu` | PP-OCRv6 引擎(GPU) | Linux/Windows 仅 |
| `vl` | PaddleOCR-VL 引擎 | 所有平台(GPU 自动适配) |
| `dev` | 开发工具(pytest, ruff, pre-commit) | 所有平台 |
| `lint` | 代码检查(black, mypy, ruff) | 所有平台 |
| `test` | 测试工具(pytest 系列) | 所有平台 |
### 组合分组
| Extra | 包含内容 | 适用平台 | 安装命令 |
| ------- | --------- | --------- | --------- |
| `all` | rapidocr + vl + GPU(非 macOS) | 所有平台(自动适配) | `uv sync --extra all` |
| `macos` | rapidocr + vl + dev + lint + test | macOS 专用 | `uv sync --system-certs --extra macos` |
| `gpu` | rapidocr-gpu + vl | Linux/Windows 专用 | `uv sync --extra gpu` |
| `dev-all` | dev + lint + test | 所有平台 | `uv sync --extra dev-all` |
### 安装示例
```bash
# macOS 开发环境(推荐)
uv sync --system-certs --extra macos
# Linux/Windows 生产环境(GPU)
uv sync --extra all
# 所有平台通用 CPU 版本(仅运行环境)
uv sync --system-certs --extra rapidocr --extra vl
# 仅 PP-OCRv6(轻量部署)
uv sync --system-certs --extra rapidocr
# 仅开发工具
uv sync --system-certs --extra dev-all
```
> **跨平台自动适配**:
>
> - **PyTorch**:在 Linux/Windows 上自动使用 CUDA 12.8 版本,在 macOS 上使用 CPU/MPS 版本
> - **ONNX Runtime**:在 macOS 上自动使用 CPU 版本,在 Linux/Windows 上可使用 GPU 版本
> - **SSL 证书**:macOS 用户需要 `--system-certs` 或设置 `UV_SYSTEM_CERTS=true`
## 测试
```bash
# 基础测试(无需启动服务)
pytest tests/ -v
# 集成测试(需先启动服务)
python3 tests/test_ocr.py
```
## 常见问题
### Q: macOS 上安装时出现 SSL 证书错误?
```bash
# 使用系统证书
uv sync --system-certs
# 或设置环境变量(永久解决)
export UV_SYSTEM_CERTS=true
uv sync
```
### Q: macOS 上 `onnxruntime-gpu` 安装失败?
天目已自动处理此问题。在 macOS 上使用 `--extra macos` 或 `--extra all` 时会自动跳过 GPU 依赖。如遇到问题,请确保使用最新的 `pyproject.toml` 配置。
### Q: 如何确认 PyTorch 使用了正确的后端?
```bash
# macOS 检查 MPS 支持
python -c "import torch; print(f'PyTorch: {torch.__version__}'); print(f'MPS available: {torch.backends.mps.is_available()}')"
# Linux 检查 CUDA 支持
python -c "import torch; print(f'PyTorch: {torch.__version__}'); print(f'CUDA available: {torch.cuda.is_available()}')"
```