本项目对本地 models/german-ocr Qwen2-VL 模型进行单图推理、公开数据集评测和 NVIDIA GPU Docker 部署,支持:
nvidia-smi 能看到显卡;nvidia-smi
conda --version
git clone <REPOSITORY_URL> german-ocr
cd german-ocr
如果代码已经位于 WSL:
cd /home/<user>/projects/german-ocr
下面的命令安装本项目已验证的 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
模型目录必须包含配置、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
生成项目自带的德语测试图片:
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
完整来源与许可见 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/
每个数据集只运行 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 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 跳过已经干净完成的样本,并重试失败或达到生成上限的样本。
需要 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 | 最大输出 token | 1024 |
--repetition-penalty | 重复惩罚 | 1.05 |
--no-repeat-ngram-size | 禁止重复 n-gram,0 表示关闭 | 0 或 8 |
--min-visual-tokens | 最小视觉 token | 256 |
--max-visual-tokens | 最大视觉 token | 4096 |
--result | 单图结果 JSON | benchmark.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
单图接口:
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
从第一轮结果按输入 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
2 commits
Python
98.3%
Dockerfile
1.7%
本项目对本地 models/german-ocr Qwen2-VL 模型进行单图推理、公开数据集评测和 NVIDIA GPU Docker 部署,支持:
nvidia-smi 能看到显卡;nvidia-smi
conda --version
git clone <REPOSITORY_URL> german-ocr
cd german-ocr
如果代码已经位于 WSL:
cd /home/<user>/projects/german-ocr
下面的命令安装本项目已验证的 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
模型目录必须包含配置、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
生成项目自带的德语测试图片:
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
完整来源与许可见 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/
每个数据集只运行 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 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 跳过已经干净完成的样本,并重试失败或达到生成上限的样本。
需要 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 | 最大输出 token | 1024 |
--repetition-penalty | 重复惩罚 | 1.05 |
--no-repeat-ngram-size | 禁止重复 n-gram,0 表示关闭 | 0 或 8 |
--min-visual-tokens | 最小视觉 token | 256 |
--max-visual-tokens | 最大视觉 token | 4096 |
--result | 单图结果 JSON | benchmark.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
单图接口:
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
从第一轮结果按输入 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
2 commits
Python
98.3%
Dockerfile
1.7%