news 2026/10/16 13:41:24

PaddleOCR 2.6训练全流程:从环境配置到模型导出的实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PaddleOCR 2.6训练全流程:从环境配置到模型导出的实战指南

简介:面向OCR初学者及需要自定义训练任务的开发者,这份资料基于PaddleOCR 2.6版本梳理了一套完整的实操流程,内容覆盖深度学习环境配置、依赖安装、PPOCRLabel工具标注、识别与检测标签生成、数据集按检测结果划分、YML文件核心参数调整,以及模型训练、验证、推理导出和串联预测等环节,几乎涵盖了从零搭建OCR项目的全部步骤。资源包内为一份docx文档,大小仅78KB,文字精炼、层次分明,便于对照步骤逐步操作。教程里特别指出了实际项目中的常见坑,例如导出推理模型时预训练权重参数无法直接传入、需要手动改写配置文件中对应的路径;评估时如何设置步数以自动保存最优权重;批大小不能超过训练或验证图片数量等,这些经验能显著缩短调试时间。目前该资源已有1307人学习,是上手PaddleOCR自定义流程的高密度中文参考资料。

1. 把 PaddleOCR 2.6 训练流程跑通:先从一本正经的“大致教程”里挑出真正能用的东西

手头攒了一批票据截图和翻拍文档,通用 OCR 引擎识别率上不去,最直接的解法就是用 PaddleOCR 2.6 自己训一套检测 + 识别模型。PaddleOCR 自带 PPOCRLabel 标注工具、训练脚本和蒸馏模型库,只要数据整理得当,从零开始跑通“标注 → 划分 → 训练 → 导出 → 串联推理”这条路是可行的。这套教程的价值不在于命令多全,而在于它替你踩过了环境安装、标注格式、路径映射和权重导出这几个最容易翻车的环节。适合手里已经有了一批待识别图片,需要自己训练模型来提升准确率的工程师和研究者。接下来我把整个流程拆开,每一步该怎么走、参数怎么填、坑在哪里,一次说清。

2. 从零配置 PaddleOCR 2.6 环境:装库顺序就是第一道坑

2.1 虚拟环境与 GPU 版飞桨的安装顺序

实际动手前,先明确一个原则:PaddleOCR 在 2.6 版本里已经要求依赖飞桨的 Python 包,而 GPU 版飞桨的安装必须放在 PaddleOCR 之前。很多用户一上来就pip install paddleocr,等到跑训练时报paddle not installed或者版本不匹配,再回头补装,又发现已经把环境搞乱了。我一般会新开一个虚拟环境,专门命名成PaddleOCR,避免和兄弟项目互相污染。

# 创建并激活虚拟环境(Windows / Linux 通用) python -m venv PaddleOCR # Windows: PaddleOCR\Scripts\activate # Linux: source PaddleOCR/bin/activate # 先装 GPU 版飞桨,走百度镜像,速度有保障 python -m pip install paddlepaddle-gpu -i https://mirror.baidu.com/pypi/simple

这段命令的逻辑是:先解决底层深度学习框架,因为 PaddleOCR 的安装包会检测飞桨版本并拉取对应依赖。如果先装 PaddleOCR 再装飞桨,paddleocr的依赖解析可能锁定一个基础版本,后续升级 GPU 版会破坏环境一致性。镜像源这里用了百度的 PyPI 镜像,国内网络环境下明显比默认源稳定,尤其是 Paddle 系列这样的大包。

参数说明:paddlepaddle-gpu默认安装的是当前飞桨稳定的 GPU 版本,如果你的显卡是旧型号,建议到飞桨官网按 CUDA 版本选择对应的安装命令,这里不展开。装完可以用python -c "import paddle; print(paddle.__version__)"验证,输出带版本号就说明底层没问题。

2.2 requirements.txt 与 PyYAML 缺失的处理

飞桨就绪后,接着装项目本身的依赖。PaddleOCR 仓库下有一个requirements.txt,直接执行即可。但这步有一个几乎每个新人都要撞上的坑:安装过程提示缺少 module ‘yml’。

# 安装项目依赖 pip install -r requirements.txt # 缺失 module 'yml' 时补装 PyYAML pip install PyYAML

逻辑说明:PaddleOCR 的配置文件全部是 YAML 格式,解析依赖PyYAML,而该库在某些 Python 版本下不会自动被paddleocr拉起来,属于典型的依赖缺失。requirements.txt里一般不会写死PyYAML,因为飞桨本体有间接依赖,但环境隔离后解析链可能断裂,所以手动补一次最稳。

参数说明:先执行requirements.txt再补PyYAML,不要反过来。如果装 PyYAML 在前,pip install -r可能把它升级或覆盖到不兼容版本。

2.3 安装 PaddleOCR 与 paddleclas:一个负责识别,一个负责分类

模型训练前需要装两个核心 Python 包:PaddleOCR 和 paddleclas。

# 官方打包的 PaddleOCR,2.6 系列均适用 pip install "paddleocr>=2.6.0.3" # 分类组件,后续训练分类模型时会用到 pip install "paddleclas>=2.4.3"

这里有两个容易被忽略的点。第一,"paddleocr>=2.6.0.3"加引号是因为>符号在 shell 里有重定向含义,不加引号命令会解析错误;第二,paddleclas是走蒸馏和分类任务时的依赖,即使当前只做检测识别,也建议装上,否则个别工具脚本会在运行时才报缺失。装完可以把三个包版本打印出来,确认主体环境没问题再往下走。

2.4 验证环境:跑一次官方自带的小推理

环境装好不代表真能用,我的习惯是先用官方预训练模型做一次快速推理,排除 CUDA 或模型下载问题。

# verify_env.py # 运行示例:python verify_env.py import paddle from paddleocr import PaddleOCR print("paddle version:", paddle.__version__) # 这里不传 det_model_dir / rec_model_dir,PaddleOCR 2.6 会自动下载官方模型 ocr = PaddleOCR(use_angle_cls=True, lang="ch") result = ocr.ocr("https://paddleocr.bj.bcebos.com/dygraph_v2.0/demo/0001.jpg", cls=True) print("初步推理完成,识别段落数:", len(result))

这段代码的核心作用不是让你立刻上手预测,而是验证三件事:飞桨的 CUDA 调用是否正常、PaddleOCR 的模型下载链路是否通畅、中文识别管道能否完整跑通。如果result返回空列表,优先检查图片路径和网络;如果报 CUDA 错误,回到飞桨版本与显卡驱动的匹配上排查。

参数说明:use_angle_cls=True启用了方向分类器,适合文本方向不固定的图片;lang="ch"指定中文模型。实际训练场景里这两个参数不用特别关注,验证完环境就可以停了。

3. 标签生成与数据集划分:先分清检测集和识别集再动手

3.1 用 PPOCRLabel 生成检测标签和识别标签

数据标注是整套流程里最耗时却最容易出错的地方。PaddleOCR 2.6 仓库里带了标注工具PPOCRLabel,它同时输出检测和识别两套标签,这一步很关键,因为后续训练检测模型和训练识别模型用的是不同的标注文件。

# 进入标注工具目录 cd PPOCRLabel # 安装标注工具额外依赖 pip install -r requirements.txt # 启动中文版标注界面 python PPOCRLabel.py --lang ch

代码说明:PPOCRLabel.py --lang ch会启动一个图形界面,你可以在里面框选文字区域并自动转成文本框,然后通过“自动标注”功能调用官方 OCR 模型预打标。标注完成后,点击“导出标记结果”和“识别结果”,会生成两个文件:Label.txt(检测标签,记录每个文本框的坐标)和rec_gt.txt(识别标签,记录每个文本框对应的文字内容)。

参数说明:--lang ch指定界面语言为中文,和识别语言无关。真正的语言选择在模型训练配置里,这里只需要让界面顺手。标注框的四个坐标是左上、右上、右下、左下,导出的Label.txt格式为“图片路径 + 四组坐标 + 转义文本”,每行一条记录。

这里要重点提示:很多人标完Label.txt就把rec_gt.txt忘了,跑识别训练时报“找不到数据”,再回头找才发现识别标签根本没导出。两个文件必须都生成,缺一不可。

3.2 划分检测集:gen_det_train_val_test.py 的参数含义

标注完成后,数据还在一个大目录里,需要划分成训练集、验证集和测试集。PaddleOCR 的PPOCRLabel目录下提供了两个现成脚本,分工明确:先划分检测集,再基于检测集划分识别集。

# 用文本编辑器打开 gen_det_train_val_test.py,按需修改以下内容 # 核心参数通常有: # image_dir: 原始图片所在目录 # label_dir: Label.txt 所在目录 # train_ratio: 训练集比例,默认 0.7 # val_ratio: 验证集比例,默认 0.2 # test_ratio: 测试集比例,默认 0.1 # 修改后执行 python PPOCRLabel/gen_det_train_val_test.py

逻辑说明:这个脚本会读取Label.txt,按比例随机把样本拆成三份,并生成train.txt、val.txt、test.txt。每个.txt文件里每一行是“图片路径 + 对应检测标注”。注意,train.txt只存相对路径或绝对路径加标注,后续训练配置里不用再去拼接图片目录,因为标注信息里已经包含了图片路径。

参数说明:三个比例加起来必须等于 1,否则脚本会报错。数据量不大时,我建议训练集 0.8、验证集 0.1、测试集 0.1,因为 OCR 模型吃数据,验证集太大反而浪费训练样本。如果你的场景只有上千张图片,更极端一点可以训练集 0.9,验证集 0.05,测试集 0.05,但测试集至少要保证有几十张,否则评估指标没有意义。

3.3 划分识别集:gen_rec_follow_det.py 的关联拆分

识别数据集不能独立划分,必须跟着检测集走。原因是:识别模型训练时,输入的是一张“被裁剪出来的文本行图片”,这些图片由检测标注框裁剪而来。如果识别集的划分和检测集不一致,会出现同一张原始图片的一部分文本在训练集、一部分在验证集,造成数据泄露。

# 打开 gen_rec_follow_det.py,重点修改以下参数 # det_train_list: 上一步生成的 train.txt 路径 # det_val_list: 上一步生成的 val.txt 路径 # det_test_list: 上一步生成的 test.txt 路径 # crop_save_dir: 裁剪后的文本行图片保存目录,例如 ./crop_img # 修改后执行 python PPOCRLabel/gen_rec_follow_det.py

脚本做的事情是:读取检测划分文件,用检测框坐标把原图裁剪成文本小图,保存到crop_save_dir,并生成新的标注文件。由于我实际只做了训练集和测试集的划分,没有单独保留验证集,所以脚本生成的rec_train.txt和rec_test.txt已经够用了;如果你想加验证集,可以在脚本输出逻辑里多写一份rec_val.txt,只要保证和val.txt来自同一批检测框坐标即可。

参数说明:crop_save_dir最好用一个独立目录,并且和训练配置文件里的data_dir保持一致。这里容易出现路径错位,比如脚本把裁剪图保存到了./OCR/ALL_1206/crop_img,但训练配置里data_dir写成了./OCR/ALL_1206/crop_img2,那rec_train.txt里的相对路径就全部失效。

4. 训练 YML 配置与常见问题排查:预训练权重和路径填对一半就能跑

4.1 从官方配置改出你自己的训练文件

所有训练参数都集中在 YAML 文件里。PaddleOCR 2.6 的检测模型推荐看configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml.yml,这个文件本身是给蒸馏训练用的,包含学生模型和教师模型两段配置。自己训练时,不建议直接改原文件,而是复制一份出来,改成ch_PP-OCRv3_det_cml_myself.yml,避免原文件被改坏后无法回退。

# configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml_myself.yml Global: pretrained_model: ./pretrain_models/best_accuracy save_model_dir: ./output/ch_PP-OCR_v3_det_1206/ save_epoch_step: 50 eval_batch_step: [0, 10] cal_metric_during_train: True Architecture: model_type: det algorithm: DB Backbone: name: PPLCNetV3 Head: name: DBHead k: 50 Loss: name: DBLoss eps: 1.0e-6 Optimizer: name: Adam beta1: 0.9 beta2: 0.999 lr: name: Cosine learning_rate: 0.001 Train: dataset: name: SimpleDataSet data_dir: ./OCR/ALL_1206/ label_file_list: ./train.txt loader: batch_size_per_card: 16 num_workers: 8 Eval: dataset: name: SimpleDataSet data_dir: ./OCR/ALL_1206/ label_file_list: ./val.txt loader: batch_size_per_card: 8 num_workers: 4

这份配置最核心的字段就三个:Global.pretrained_model、Train.dataset.label_file_list、Eval.dataset.label_file_list。pretrained_model指向初始化权重,训练早期用官方权重收敛更快;label_file_list指向前面生成的train.txt和val.txt。特别注意,data_dir不是图片目录,而是标注列表中相对路径的基准目录。如果train.txt里每一行写的是相对路径,训练时 PaddleOCR 会把data_dir拼接上去,最终定位图片真的存在。

4.2 路径映射规律:train.txt 与 rec_train.txt 的差异处理

这里要区分检测训练和识别训练的路径规则。检测模块的train.txt里面写的是完整图片相对路径,通常长这样:

./OCR/ALL_1206/images/0001.jpg [{"points": [[x1,y1],[x2,y2],[x3,y3],[x4,y4]], ...}]

这种情况下,你只需要在配置里指定label_file_list: ./train.txt,图片路径靠data_dir自动拼接。因为相对路径里已经包含了图片子目录,data_dir可以只写到公共根目录,比如./OCR/ALL_1206/。

识别模块则不一样。前面gen_rec_follow_det.py生成的rec_train.txt,每一行一般是这样的结构:

crop_img/0001_0.jpg "文本内容"

这里crop_img是裁剪图片的保存子目录,但如果你把data_dir写成./OCR/ALL_1206/,拼接出来就是./OCR/ALL_1206/crop_img/0001_0.jpg,而实际图片确实存放在这个位置。所以识别模块的配置必须补足data_dir到能覆盖实际图片路径的位置。我一般会把识别配置的data_dir写成./OCR/ALL_1206/,这样既能覆盖crop_img子目录,也方便后续路径调整。

判断规律可以总结成一句话:看标注文件里第一列路径相对于哪个目录成立,data_dir就指向那个目录。不要想当然地把所有图片路径都写成绝对路径,那样换机器就要重改配置,相对路径加data_dir才是可迁移方案。

4.3 常见问题排查:batchsize、eval 步数与权重保存策略

训练配置里最容易踩坑的有三个参数:batchsize、eval 间隔和权重保存频率。

第一,batchsize 不能超过训练集或验证集的图片总数。这个“不能超过”不是软性警告,是硬性报错。PaddleOCR 在加载数据时会用total_batch_size = batch_size_per_card * device_num去除数据总量,如果余数为 0 还好说,但如果总样本数不足一个 batch,训练直接崩掉。比如你的验证集只有 60 张图,batch_size_per_card写成 16,那一个 batch 都凑不满,脚本会报“No data”或者 EOF 错误。所以配 batchsize 前先数一遍train.txt和val.txt的行数,保证行数至少为 batchsize 的两到三倍。

第二,eval_batch_step: [0, 10]表示训练到第 0 步开始评估,之后每隔 10 步验证一次。PaddleOCR 的 eval 阶段会自动保留当前最高精度的权重,文件名为best_accuracy。这里要特别说明:不要频繁设置save_epoch_step每几个 epoch 保存一次,因为训练过程中会生成大量中间权重,每个权重文件几百 MB 起步,磁盘很快就被塞满。默认做法是只靠 eval 选出最高精度权重保存,训练结束后用best_accuracy作为最终成果。

第三,Global.pretrained_model在训练过程中不要随意修改。如果你先从官方权重开始训练,跑到一半想接着自己的best_accuracy继续,可以单独用命令行参数覆盖,不用动 YAML 文件。但如果 YAML 里同时写了pretrained_model和训练路径,PaddleOCR 的加载逻辑是:优先从pretrained_model初始化,这会导致你之前的训练成果被官方权重盖掉。这一点在下一章展开。

5. 训练、验证到导出推理模型:参数传递的坑与端到端预测

5.1 训练命令与中途更换预训练权重

配置没问题后,执行训练命令:

python tools/train.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml_myself.yml

这条命令会按照 YAML 里的配置启动训练。如果你中途训练中断,想用当前的best_accuracy继续跑,可以用参数覆盖预训练权重:

python tools/train.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml_myself.yml \ -o Global.pretrained_model="pretrain_models/best_accuracy"

逻辑说明:-o参数用于在命令行覆盖 YAML 里的任意字段,优先级高于文件配置。一般用在不想改配置文件的场景。但如果 YAML 里已经写了pretrained_model指向官方权重,而且你用的是训练中断恢复,那么直接用-o覆盖依然是从官方权重重新开始,而不是接着之前的训练进度。PaddleOCR 判断“是否恢复训练”的标准是检查输出目录里有没有latest.pdopt和latest.pdparams,而不是看pretrained_model。

参数说明:pretrain_models/best_accuracy路径不要加.pdparams后缀,PaddleOCR 会自动补齐。如果你把完整文件名写进去,反而会报找不到权重文件。

5.2 验证命令与指定权重评估

训练结束后,评估模型精度有两种方式:直接跑 eval 脚本指定Global.checkpoints,或者在训练过程中看日志里的 eval 指标。单独验证指定权重时,命令长这样:

python tools/eval.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml_myself.yml \ -o Global.checkpoints="D:/model/PaddleOCR-release-2.6/output/ch_PP-OCR_v3_det_1206/best_accuracy"

这条命令的关键参数是Global.checkpoints,它指向要验证的权重文件的公共前缀,也就是“不带.pdparams的文件路径”。PaddleOCR 会加载best_accuracy.pdparams和best_accuracy.pdopt,如果只存在前者,也能正常评估。验证脚本会输出 precision、recall、hmean 三项指标,这三项都在 0.8 以上基本可以放心导出。

5.3 export_model.py 导出推理模型的常见坑

导出推理模型这一步,我遇到过最隐蔽的坑:直接命令行传Global.pretrained_model不会生效,导出的模型仍然加载的是 YAML 里配置的预训练权重,而不是你指定的训练成果。

# 表面看起来没问题的写法,实际会踩坑 python tools/export_model.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml_myself.yml \ -o Global.pretrained_model="D:/model/PaddleOCR-release-2.6/output/ch_PP-OCR_v3_det_1206/best_accuracy" \ -o Global.save_inference_dir="./inference/det_cml_ppocrv3_1206"

这里-o Global.pretrained_model并没有真正覆盖 YAML 文件里的值,因为export_model.py在解析命令行参数时对Global.pretrained_model的处理逻辑与train.py不同。表现形式是导出的推理模型尺寸异常小,或者预测结果明显不对。解决办法是把训练后的权重直接写进 YAML 文件的pretrained_model字段,再执行导出命令:

# 修改 ch_PP-OCRv3_det_cml_myself.yml Global: pretrained_model: D:/model/PaddleOCR-release-2.6/output/ch_PP-OCR_v3_det_1206/best_accuracy save_inference_dir: ./inference/det_cml_ppocrv3_1206
# 修改后再导出,这次加载的就是你训练好的权重 python tools/export_model.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml_myself.yml

导出完成后,save_inference_dir目录下会生成inference.pdmodel、inference.pdiparams等文件。但如果你走的是蒸馏训练,导出目录里可能还有Student和Teacher两个子目录。实际部署时要用Student目录,因为教师模型只负责训练阶段的蒸馏指导,不参与推理。

5.4 用 predict_system.py 串联检测与识别模型

训练完检测模型后,如果识别模型也是你自己训练的,需要先按同样流程导出识别推理模型,再用串联脚本做端到端预测:

python tools/infer/predict_system.py \ --image_dir="D:/model/PaddleOCR-release-2.6/OCR/ALL_1206/test" \ --det_model_dir="./inference/det_cml_ppocrv3_1206/Student" \ --rec_model_dir="./inference/rec_ppocr_v3_distillation_1206/Student"

这条命令把检测和识别两个推理模型串在一起:predict_system.py先跑检测模型,把图片里的文本区域框出来,再裁剪框内图像送给识别模型,最终输出文字行和置信度。--image_dir可以传一个目录,也可以传单张图片路径。推理结果会保存到output目录下,同时打印在终端里。

参数说明:--det_model_dir指向导出后的检测模型目录,--rec_model_dir指向识别模型目录。如果目录下同时存在Student和Teacher,只填Student即可。--image_dir传目录时,脚本会遍历目录下所有常见格式的图片文件。

从那以后,每次导出推理模型我都强制走一遍“先看 YAML 里的 pretrained_model 是不是训练成果路径,再跑 export_model.py”的流程。命令行-o传参在这个场景下不值得信赖,与其查报错不如直接改文件。这套流程跑完,检测模型和识别模型都能稳定导出并端到端预测,后续微调也只是在数据和路径上做文章。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 13:40:15

DAB双向隔离DC-DC变换器Simulink闭环仿真与移相控制实战解析

我在做某个储能样机的双向电源时,第一版硬件直接烧了两组管子,原因很简单——移相角度给反了,副边桥的时序没有严格跟着原边走。后来我养成了一个习惯:任何新的隔离型DC-DC拓扑,先花两天在Simulink里把闭环跑顺&#x…

作者头像 李华
网站建设 2026/10/16 13:39:23

ThinkPHP+Laravel双框架实战:乡村政务举报投诉系统架构与实现

最近在开发一整套乡村政务举报投诉办公系统时,我选择了"ThinkPHP Laravel"双框架的组合方案。这个题目看起来有点让人疑惑:一个项目为什么同时用两个PHP框架?实际上,这套系统分成公众端和管理端两部分:公众…

作者头像 李华
网站建设 2026/10/16 13:34:36

一行Python代码生成酷炫二维码的原理与实战

1. 这行代码到底在干什么?——从“酷炫二维码”说起你肯定见过那种扫出来不是跳链接、而是弹出动画、播放音乐、甚至显示表白文字的二维码。朋友圈里有人发个“扫码听我唱情歌”,有人发“扫码看我P的结婚照”,还有人发“扫码解锁隐藏彩蛋”……

作者头像 李华
网站建设 2026/10/16 13:31:22

GB28181模拟器开发核心:信令状态机与RTP时间同步

简介:这是一款轻量级GB28181-2016国标摄像机软件模拟器,面向安防监控系统开发者、测试工程师及协议学习者,用于快速验证平台侧对国标设备的注册、心跳保活、视频点播(INVITE流程)及目录查询等核心交互逻辑,…

作者头像 李华
网站建设 2026/10/16 13:28:37

STM32按键状态机:单击双击长按的确定性实现

简介:本资源是一份面向嵌入式初学者与STM32进阶开发者的按键状态机实战项目,聚焦单片机中复杂按键行为(单击、双击、长按)的精准识别与工程化实现。针对传统延时消抖或简单计数难以兼顾实时性与鲁棒性的痛点,项目基于S…

作者头像 李华
网站建设 2026/10/16 13:28:05

SpringBoot+MySQL+微信小程序:乐器社区网站毕业设计项目全拆解

又到一年毕业季,每年这个时候,后台私信里问得最多的就是“Java方向做什么毕业设计比较简单又能过审”。今天想聊的这个项目——基于SpringBootMySQL的乐器社区网站,外加微信小程序端的乐器宣传平台,就是我眼中典型的“性价比极高”…

作者头像 李华