Drtxdt/german-ocr

0

stars

2

commits

Python

primary language

Jul 31, 2026

updated

README

German OCR 任务

本项目对本地 models/german-ocr Qwen2-VL 模型进行单图推理、公开数据集评测和 NVIDIA GPU Docker 部署,支持:

  • German Synth OCR、SROIE、FUNSD 三套公开数据;
  • CER、WER、Exact Match 的严格与归一化指标;
  • 延迟、吞吐率、模型加载时间和 CUDA 峰值显存;
  • JSONL 逐条落盘、失败记录和断点续跑;
  • REST 单图/批量接口与容器内 CLI。

快速开始

1. 前置条件

  • Linux 或启用 WSL2 的 Windows;
  • NVIDIA GPU 与可用驱动,执行 nvidia-smi 能看到显卡;
  • Miniconda 或 Anaconda;
  • Python 3.11;
  • 本地模型权重。模型权重不会提交到 Git。
nvidia-smi
conda --version

2. 获取代码并进入目录

git clone <REPOSITORY_URL> german-ocr
cd german-ocr

如果代码已经位于 WSL:

cd /home/<user>/projects/german-ocr

3. 创建 Conda 环境(推荐)

下面的命令安装本项目已验证的 CUDA 12.1 版本组合:

conda create -n german-ocr python=3.11.15 pip -y
conda activate german-ocr

python -m pip install --upgrade pip
python -m pip install \
  torch==2.5.1+cu121 \
  torchvision==0.20.1+cu121 \
  --index-url https://download.pytorch.org/whl/cu121

python -m pip install \
  transformers==5.14.1 \
  datasets==5.0.0 \
  accelerate==1.14.0 \
  qwen-vl-utils==0.0.14 \
  pillow==12.3.0 \
  safetensors==0.8.0 \
  psutil==7.2.2 \
  requests==2.34.2

environment.lock.yml 是开发机的完整 Conda 快照,适合环境审计或在相同平台尝试完整复现:

conda env create -f environment.lock.yml
conda activate german-ocr

requirements.lock.txt 记录开发环境中的全部 PyPI 包,其中包含多个 CUDA runtime 条目;新环境优先使用上面的分步安装命令。

验证环境:

python -c "import torch; print('PyTorch:', torch.__version__); print('CUDA runtime:', torch.version.cuda); print('CUDA available:', torch.cuda.is_available()); print('GPU:', torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'none')"

python -c "import transformers, datasets; print('Transformers:', transformers.__version__); print('Datasets:', datasets.__version__)"

预期至少看到:

PyTorch: 2.5.1+cu121
CUDA runtime: 12.1
CUDA available: True

4. 放置模型

模型目录必须包含配置、processor/tokenizer 文件和权重:

german-ocr/
└── models/
    └── german-ocr/
        ├── config.json
        ├── model.safetensors
        ├── preprocessor_config.json
        └── tokenizer / processor 相关文件

检查关键文件:

test -f models/german-ocr/config.json
test -f models/german-ocr/model.safetensors
sha256sum models/german-ocr/model.safetensors

当前已验证权重的 SHA-256:

4013cd73d3634cd7d7742a6cf74c0945063998953ef47beb2ff45b78644ae9fa

5. 运行第一张图片

生成项目自带的德语测试图片:

python generate_sample.py

运行兼容入口:

python infer.py

显式指定图片、模型和结果文件:

python -m inference.infer \
  --image german_sample.png \
  --model models/german-ocr \
  --max-new-tokens 1024 \
  --repetition-penalty 1.05 \
  --min-visual-tokens 256 \
  --max-visual-tokens 4096 \
  --result benchmark.json

6. 下载公开数据集

完整来源与许可见 docs/datasets.md

python -m evaluation.dataset download --dataset german_synth
python -m evaluation.dataset download --dataset sroie
python -m evaluation.dataset download \
  --dataset funsd \
  --accept-funsd-license

一次下载全部:

python -m evaluation.dataset download \
  --dataset all \
  --accept-funsd-license

数据保存到:

data/raw/german_synth/
data/raw/sroie/
data/raw/funsd/
data/cache/

7. 冒烟评测

每个数据集只运行 1 条,用于检查模型、数据和结果目录:

python -m evaluation.evaluate \
  --dataset all \
  --split test \
  --limit 1 \
  --run-id smoke-v1

结果写入:

results/smoke-v1/
├── predictions.jsonl
├── samples.csv
├── summary.json
├── report.md
└── run_config.json

8. SROIE 正式评测

当前 8 GB GPU 上验证过的 SROIE 配置:

python -m evaluation.evaluate \
  --dataset sroie \
  --split test \
  --min-visual-tokens 256 \
  --max-visual-tokens 4096 \
  --max-new-tokens 1024 \
  --repetition-penalty 1.05 \
  --run-id public-sroie-v2-t4096 \
  --resume

--resume 跳过已经干净完成的样本,并重试失败或达到生成上限的样本。

9. Docker 快速启动(可选)

需要 Docker Engine、NVIDIA Container Toolkit,并确保下面的命令能看到 GPU:

docker run --rm --gpus all \
  nvidia/cuda:12.1.1-base-ubuntu22.04 \
  nvidia-smi

构建和启动:

cp .env.example .env
docker compose build
docker compose up -d
docker compose ps

健康检查:

curl --noproxy 127.0.0.1 \
  --fail-with-body \
  http://127.0.0.1:8000/health/ready

单图 OCR:

curl --noproxy 127.0.0.1 \
  --silent --show-error --fail-with-body \
  -F "file=@/absolute/path/to/image.png" \
  http://127.0.0.1:8000/v1/ocr

停止服务:

docker compose down

更完整的 Docker 命令见 docs/commands-and-demo.md

命令格式

尖括号表示必须替换的值,方括号表示可选参数。实际命令中不要保留尖括号。

单图推理

python -m inference.infer \
  [--image <IMAGE_PATH>] \
  [--model <MODEL_PATH>] \
  [--prompt <PROMPT_TEXT>] \
  [--max-new-tokens <INTEGER>] \
  [--repetition-penalty <FLOAT>] \
  [--no-repeat-ngram-size <INTEGER>] \
  [--min-visual-tokens <INTEGER>] \
  [--max-visual-tokens <INTEGER>] \
  [--result <JSON_PATH>]
参数含义常用值
--image输入图片路径german_sample.png
--model本地模型目录models/german-ocr
--prompt覆盖 OCR 提示词德语或英文纯转写提示词
--max-new-tokens最大输出 token1024
--repetition-penalty重复惩罚1.05
--no-repeat-ngram-size禁止重复 n-gram,0 表示关闭08
--min-visual-tokens最小视觉 token256
--max-visual-tokens最大视觉 token4096
--result单图结果 JSONbenchmark.json

查看程序内置帮助:

python -m inference.infer --help

数据集下载

python -m evaluation.dataset download \
  --dataset <german_synth|sroie|funsd|all> \
  [--data-root <DATA_DIRECTORY>] \
  [--accept-funsd-license]

FUNSD 必须显式传入 --accept-funsd-license

python -m evaluation.dataset download --help

统一评测

python -m evaluation.evaluate \
  --dataset <german_synth|sroie|funsd|all> \
  --run-id <RUN_ID> \
  [--split <SPLIT>] \
  [--limit <INTEGER>] \
  [--sample-ids-file <TEXT_FILE>] \
  [--resume] \
  [--model <MODEL_PATH>] \
  [--data-root <DATA_DIRECTORY>] \
  [--results-root <RESULTS_DIRECTORY>] \
  [--min-visual-tokens <INTEGER>] \
  [--max-visual-tokens <INTEGER>] \
  [--max-new-tokens <INTEGER>] \
  [--repetition-penalty <FLOAT>] \
  [--no-repeat-ngram-size <INTEGER>] \
  [--prompt <PROMPT_TEXT>] \
  [--checkpoint-every <INTEGER>]
参数含义
--dataset数据集名称,必填
--run-id结果目录名,必填;不要复用不同配置的 ID
--split数据集 split,正式评测通常为 test
--limit只读取前 N 条,适合冒烟测试
--sample-ids-file只评测文本文件中列出的 sample ID
--resume从现有 JSONL 断点恢复
--model模型目录
--data-root数据根目录,默认 data/
--results-root结果根目录,默认 results/
--checkpoint-every每 N 条刷新汇总文件
python -m evaluation.evaluate --help

REST API

单图接口:

POST /v1/ocr
multipart/form-data field: file
curl --noproxy 127.0.0.1 \
  -F "file=@<ABSOLUTE_IMAGE_PATH>" \
  http://127.0.0.1:8000/v1/ocr

批量接口,最多 8 张:

POST /v1/ocr/batch
multipart/form-data repeated field: files
curl --noproxy 127.0.0.1 \
  -F "files=@<IMAGE_1>" \
  -F "files=@<IMAGE_2>" \
  http://127.0.0.1:8000/v1/ocr/batch

启用 API Key 后:

curl --noproxy 127.0.0.1 \
  -H "Authorization: Bearer <GERMAN_OCR_API_KEY>" \
  -F "file=@<ABSOLUTE_IMAGE_PATH>" \
  http://127.0.0.1:8000/v1/ocr

SROIE 分层校准

从第一轮结果按输入 token 将 SROIE 分成低、中、高三档,每档确定性抽取 10 条:

python -m evaluation.calibrate \
  --source-run public-test-v1 \
  --dataset sroie \
  --per-bucket 10

使用生成的固定清单测试 4096 档:

python -m evaluation.evaluate \
  --dataset sroie \
  --split test \
  --sample-ids-file results/public-test-v1/sroie-calibration-30.txt \
  --min-visual-tokens 256 \
  --max-visual-tokens 4096 \
  --max-new-tokens 1024 \
  --run-id sroie-cal-v2-t4096 \
  --resume

异常输出解码消融

python -m evaluation.retry_experiment \
  --source-run public-sroie-v2-t4096 \
  --experiment-id sroie-retry-ablation-v1 \
  --resume

结果写入 results/sroie-retry-ablation-v1/comparison.md,各变体结果写入 results/sroie-retry-ablation-v1--<profile>/。该实验用于失败分析。

结果文件

每次评测写入 results/<run-id>/

  • predictions.jsonl:逐样本原始结果和状态;
  • samples.csv:适合 Excel 与 PPT;
  • summary.json:机器可读汇总;
  • report.md:Accuracy 和 Performance 报告;
  • run_config.json:模型、数据、提示词和生成参数快照。

Normalized 指标只进行 Unicode NFC、换行统一和连续空白折叠,保留大小写、标点、数字和德语字符。

单元测试

conda activate german-ocr
python -m unittest discover -s tests -v

Contributors

Drtxdt

2 commits

Drtxdt/german-ocr

0

stars

2

commits

Python

primary language

Jul 31, 2026

updated

README

German OCR 任务

本项目对本地 models/german-ocr Qwen2-VL 模型进行单图推理、公开数据集评测和 NVIDIA GPU Docker 部署,支持:

  • German Synth OCR、SROIE、FUNSD 三套公开数据;
  • CER、WER、Exact Match 的严格与归一化指标;
  • 延迟、吞吐率、模型加载时间和 CUDA 峰值显存;
  • JSONL 逐条落盘、失败记录和断点续跑;
  • REST 单图/批量接口与容器内 CLI。

快速开始

1. 前置条件

  • Linux 或启用 WSL2 的 Windows;
  • NVIDIA GPU 与可用驱动,执行 nvidia-smi 能看到显卡;
  • Miniconda 或 Anaconda;
  • Python 3.11;
  • 本地模型权重。模型权重不会提交到 Git。
nvidia-smi
conda --version

2. 获取代码并进入目录

git clone <REPOSITORY_URL> german-ocr
cd german-ocr

如果代码已经位于 WSL:

cd /home/<user>/projects/german-ocr

3. 创建 Conda 环境(推荐)

下面的命令安装本项目已验证的 CUDA 12.1 版本组合:

conda create -n german-ocr python=3.11.15 pip -y
conda activate german-ocr

python -m pip install --upgrade pip
python -m pip install \
  torch==2.5.1+cu121 \
  torchvision==0.20.1+cu121 \
  --index-url https://download.pytorch.org/whl/cu121

python -m pip install \
  transformers==5.14.1 \
  datasets==5.0.0 \
  accelerate==1.14.0 \
  qwen-vl-utils==0.0.14 \
  pillow==12.3.0 \
  safetensors==0.8.0 \
  psutil==7.2.2 \
  requests==2.34.2

environment.lock.yml 是开发机的完整 Conda 快照,适合环境审计或在相同平台尝试完整复现:

conda env create -f environment.lock.yml
conda activate german-ocr

requirements.lock.txt 记录开发环境中的全部 PyPI 包,其中包含多个 CUDA runtime 条目;新环境优先使用上面的分步安装命令。

验证环境:

python -c "import torch; print('PyTorch:', torch.__version__); print('CUDA runtime:', torch.version.cuda); print('CUDA available:', torch.cuda.is_available()); print('GPU:', torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'none')"

python -c "import transformers, datasets; print('Transformers:', transformers.__version__); print('Datasets:', datasets.__version__)"

预期至少看到:

PyTorch: 2.5.1+cu121
CUDA runtime: 12.1
CUDA available: True

4. 放置模型

模型目录必须包含配置、processor/tokenizer 文件和权重:

german-ocr/
└── models/
    └── german-ocr/
        ├── config.json
        ├── model.safetensors
        ├── preprocessor_config.json
        └── tokenizer / processor 相关文件

检查关键文件:

test -f models/german-ocr/config.json
test -f models/german-ocr/model.safetensors
sha256sum models/german-ocr/model.safetensors

当前已验证权重的 SHA-256:

4013cd73d3634cd7d7742a6cf74c0945063998953ef47beb2ff45b78644ae9fa

5. 运行第一张图片

生成项目自带的德语测试图片:

python generate_sample.py

运行兼容入口:

python infer.py

显式指定图片、模型和结果文件:

python -m inference.infer \
  --image german_sample.png \
  --model models/german-ocr \
  --max-new-tokens 1024 \
  --repetition-penalty 1.05 \
  --min-visual-tokens 256 \
  --max-visual-tokens 4096 \
  --result benchmark.json

6. 下载公开数据集

完整来源与许可见 docs/datasets.md

python -m evaluation.dataset download --dataset german_synth
python -m evaluation.dataset download --dataset sroie
python -m evaluation.dataset download \
  --dataset funsd \
  --accept-funsd-license

一次下载全部:

python -m evaluation.dataset download \
  --dataset all \
  --accept-funsd-license

数据保存到:

data/raw/german_synth/
data/raw/sroie/
data/raw/funsd/
data/cache/

7. 冒烟评测

每个数据集只运行 1 条,用于检查模型、数据和结果目录:

python -m evaluation.evaluate \
  --dataset all \
  --split test \
  --limit 1 \
  --run-id smoke-v1

结果写入:

results/smoke-v1/
├── predictions.jsonl
├── samples.csv
├── summary.json
├── report.md
└── run_config.json

8. SROIE 正式评测

当前 8 GB GPU 上验证过的 SROIE 配置:

python -m evaluation.evaluate \
  --dataset sroie \
  --split test \
  --min-visual-tokens 256 \
  --max-visual-tokens 4096 \
  --max-new-tokens 1024 \
  --repetition-penalty 1.05 \
  --run-id public-sroie-v2-t4096 \
  --resume

--resume 跳过已经干净完成的样本,并重试失败或达到生成上限的样本。

9. Docker 快速启动(可选)

需要 Docker Engine、NVIDIA Container Toolkit,并确保下面的命令能看到 GPU:

docker run --rm --gpus all \
  nvidia/cuda:12.1.1-base-ubuntu22.04 \
  nvidia-smi

构建和启动:

cp .env.example .env
docker compose build
docker compose up -d
docker compose ps

健康检查:

curl --noproxy 127.0.0.1 \
  --fail-with-body \
  http://127.0.0.1:8000/health/ready

单图 OCR:

curl --noproxy 127.0.0.1 \
  --silent --show-error --fail-with-body \
  -F "file=@/absolute/path/to/image.png" \
  http://127.0.0.1:8000/v1/ocr

停止服务:

docker compose down

更完整的 Docker 命令见 docs/commands-and-demo.md

命令格式

尖括号表示必须替换的值,方括号表示可选参数。实际命令中不要保留尖括号。

单图推理

python -m inference.infer \
  [--image <IMAGE_PATH>] \
  [--model <MODEL_PATH>] \
  [--prompt <PROMPT_TEXT>] \
  [--max-new-tokens <INTEGER>] \
  [--repetition-penalty <FLOAT>] \
  [--no-repeat-ngram-size <INTEGER>] \
  [--min-visual-tokens <INTEGER>] \
  [--max-visual-tokens <INTEGER>] \
  [--result <JSON_PATH>]
参数含义常用值
--image输入图片路径german_sample.png
--model本地模型目录models/german-ocr
--prompt覆盖 OCR 提示词德语或英文纯转写提示词
--max-new-tokens最大输出 token1024
--repetition-penalty重复惩罚1.05
--no-repeat-ngram-size禁止重复 n-gram,0 表示关闭08
--min-visual-tokens最小视觉 token256
--max-visual-tokens最大视觉 token4096
--result单图结果 JSONbenchmark.json

查看程序内置帮助:

python -m inference.infer --help

数据集下载

python -m evaluation.dataset download \
  --dataset <german_synth|sroie|funsd|all> \
  [--data-root <DATA_DIRECTORY>] \
  [--accept-funsd-license]

FUNSD 必须显式传入 --accept-funsd-license

python -m evaluation.dataset download --help

统一评测

python -m evaluation.evaluate \
  --dataset <german_synth|sroie|funsd|all> \
  --run-id <RUN_ID> \
  [--split <SPLIT>] \
  [--limit <INTEGER>] \
  [--sample-ids-file <TEXT_FILE>] \
  [--resume] \
  [--model <MODEL_PATH>] \
  [--data-root <DATA_DIRECTORY>] \
  [--results-root <RESULTS_DIRECTORY>] \
  [--min-visual-tokens <INTEGER>] \
  [--max-visual-tokens <INTEGER>] \
  [--max-new-tokens <INTEGER>] \
  [--repetition-penalty <FLOAT>] \
  [--no-repeat-ngram-size <INTEGER>] \
  [--prompt <PROMPT_TEXT>] \
  [--checkpoint-every <INTEGER>]
参数含义
--dataset数据集名称,必填
--run-id结果目录名,必填;不要复用不同配置的 ID
--split数据集 split,正式评测通常为 test
--limit只读取前 N 条,适合冒烟测试
--sample-ids-file只评测文本文件中列出的 sample ID
--resume从现有 JSONL 断点恢复
--model模型目录
--data-root数据根目录,默认 data/
--results-root结果根目录,默认 results/
--checkpoint-every每 N 条刷新汇总文件
python -m evaluation.evaluate --help

REST API

单图接口:

POST /v1/ocr
multipart/form-data field: file
curl --noproxy 127.0.0.1 \
  -F "file=@<ABSOLUTE_IMAGE_PATH>" \
  http://127.0.0.1:8000/v1/ocr

批量接口,最多 8 张:

POST /v1/ocr/batch
multipart/form-data repeated field: files
curl --noproxy 127.0.0.1 \
  -F "files=@<IMAGE_1>" \
  -F "files=@<IMAGE_2>" \
  http://127.0.0.1:8000/v1/ocr/batch

启用 API Key 后:

curl --noproxy 127.0.0.1 \
  -H "Authorization: Bearer <GERMAN_OCR_API_KEY>" \
  -F "file=@<ABSOLUTE_IMAGE_PATH>" \
  http://127.0.0.1:8000/v1/ocr

SROIE 分层校准

从第一轮结果按输入 token 将 SROIE 分成低、中、高三档,每档确定性抽取 10 条:

python -m evaluation.calibrate \
  --source-run public-test-v1 \
  --dataset sroie \
  --per-bucket 10

使用生成的固定清单测试 4096 档:

python -m evaluation.evaluate \
  --dataset sroie \
  --split test \
  --sample-ids-file results/public-test-v1/sroie-calibration-30.txt \
  --min-visual-tokens 256 \
  --max-visual-tokens 4096 \
  --max-new-tokens 1024 \
  --run-id sroie-cal-v2-t4096 \
  --resume

异常输出解码消融

python -m evaluation.retry_experiment \
  --source-run public-sroie-v2-t4096 \
  --experiment-id sroie-retry-ablation-v1 \
  --resume

结果写入 results/sroie-retry-ablation-v1/comparison.md,各变体结果写入 results/sroie-retry-ablation-v1--<profile>/。该实验用于失败分析。

结果文件

每次评测写入 results/<run-id>/

  • predictions.jsonl:逐样本原始结果和状态;
  • samples.csv:适合 Excel 与 PPT;
  • summary.json:机器可读汇总;
  • report.md:Accuracy 和 Performance 报告;
  • run_config.json:模型、数据、提示词和生成参数快照。

Normalized 指标只进行 Unicode NFC、换行统一和连续空白折叠,保留大小写、标点、数字和德语字符。

单元测试

conda activate german-ocr
python -m unittest discover -s tests -v

Contributors

Drtxdt

2 commits

Languages

Python

98.3%

Dockerfile

1.7%