尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
PaddleOCR微调导出模型权重加载失效:从环境到导出的完整避坑指南
简介面向使用 PaddleOCR 2.6 进行中文 OCR 训练与落地的开发者是一份从环境配置到模型推理的完整操作笔记。教程以检测模型为主线逐步讲解创建虚拟环境、安装 PaddleOCR/PPOCRLabel、生成 rec_gt.txt 与 Label.txt、划分检测和识别数据集并给出 ch_PP-OCRv3_det_cml_myself.yml 的配置要点包括路径、batchsize 和验证间隔。训练、验证、导出与串联预测均配有可直接参考的命令特别指出 export_model.py 中 Global.pretrained_model 传参失效、需把权重写入 yml 的常见坑点。资源为 1 个 docx 文档共 78KB便于快速检索和复制命令已有 1307 人浏览学习适合跑通自定义 OCR 数据集流程、希望减少试错成本的新手与进阶使用者。1. OCR 微调总在最后一步翻车导出模型加载的还是预训练权重训练了两天的 OCR 检测模型导出推理模型后一跑预测识别效果跟没训过一样——后来才发现导出的还是官方预训练权重自己微调的成果压根没被加载进去。这类问题在 PaddleOCR 2.6 的微调流程里非常典型尤其是第一次从检测/识别训练切到导出预测时环境、标注、路径、配置任何一个环节出错都会让你在最后一刻翻车。这篇笔记就是围绕这套 OCR 流程来写的环境配置、PPOCRLabel 标注、数据集划分、yml 训练配置、模型训练验证与导出最后是快速定位技巧。新手可以照着命令一步步跑通熟手可以重点看 export_model.py 那个传参失效的坑它最容易让人白训几天。2. 环境配置报 ModuleNotFoundErrorPyYAML 缺失与 PaddleOCR 2.6 安装2.1 现象装完 requirements.txt 仍然报 No module named yaml新建虚拟环境后按官方 quickstart 装依赖pip install -r requirements.txt执行完一运行python tools/train.py就立刻报错ModuleNotFoundError: No module named yaml有人会把报错描述成「缺少一个 module yml」然后去搜「yml module 安装」搜半天搜不到答案。这里首先要纠正一个认知报错信息里写的是yaml不是yml。yml 是配置文件的后缀名而解析 yml 文件靠的是 Python 的 PyYAML 库import 进来的模块名是yaml。搜错关键词会浪费很多时间。2.2 根因PyYAML 是 PaddleOCR 的硬依赖requirements 没有锁全PaddleOCR 2.6 的 config 解析模块在启动时会直接import yaml用来读取训练、评估、导出时用到的 .yml 配置文件。也就是说PyYAML 是一个必须提前装好的硬依赖但项目自带的 requirements.txt 在部分系统环境下并没有把它锁进去或者锁的版本和当前 Python 环境不兼容导致安装完 requirements 之后仍然缺失。这不是个例。很多深度学习项目都会在 requirements.txt 里遗漏这类「大家都默认系统里有」的底层库遇到这种情况先别怀疑代码先看 import 链路上缺了哪个包。缺什么就补什么比反复重装整个环境要快得多。2.3 解决分步安装 补装 PyYAML 的完整命令我一般会按下面这个顺序装每步都验证一次避免最后混在一起不知道谁出了问题python -m venv PaddleOCR # Windows 激活PaddleOCR\Scripts\activate # Linux/macOS 激活source PaddleOCR/bin/activate python -m pip install paddlepaddle-gpu -i https://mirror.baidu.com/pypi/simple pip install -r requirements.txt pip install PyYAML pip install paddleocr2.6.0.3 pip install paddleclas2.4.3提示如果机器上只有 CPU把第一行的 paddlepaddle-gpu 换成 paddlepaddle 即可后面的依赖不变。几个容易踩的点paddlepaddle-gpu不带版本号安装会拉取最新版新版 wheel 对 CUDA 版本有明确要求。装完后先用一条命令验证能不能正常导入python -c import paddle; print(paddle.__version__)如果报找不到 libcudart 之类的错误说明 wheel 和你机器的 CUDA 运行库不匹配需要去官方安装页面对照 CUDA 版本选对应版本重装不要强行往下走。paddleocr2.6.0.3是官方打包的发布版本负责提供 PaddleOCR 的调用能力源码目录 release/2.6 里的 tools 脚本负责训练和导出。两者版本要一致否则可能出现训练导出的模型结构和新版推理接口对不上的情况后面predict_system.py会莫名报错。2.4 常见坑GPU 包装错、官方包与源码混用我在实际项目里见过两种最典型的翻车。第一种是 GPU 包装上了但import paddle报错或paddle.is_compiled_with_cuda()返回 False训练时日志里没有任何报错就是速度慢得离谱。这种多半是 pip 把 CPU 版覆盖了 GPU 版或者虚拟环境没激活命令装到了全局环境里。排查时先确认当前解释器路径which python再确认是在虚拟环境内操作。第二种是把 pip 安装的 paddleocr 和 clone 下来的源码目录混着跑。训练必须进源码目录用tools/train.py推理可以走 pip 包的调用接口但如果你在同一段代码里既 import 了 pip 包的 PaddleOCR又把源码目录的模型导出来喂给它版本不一致时就会出现「模型加载成功但预测结果全是空的」这种黑匣子问题。我的习惯是训练阶段全程待在源码目录只用 tools 下的脚本等到部署阶段才切换到 pip 包并且固定好版本号不让它随便漂移。3. 标签生成与数据集划分PPOCRLabel 导出的文件怎么对齐3.1 跑通 PPOCRLabel--lang ch 启动中文标注PPOCRLabel 是 PaddleOCR 配套的标注工具进入源码目录下的 PPOCRLabel 文件夹先装依赖再启动cd PPOCRLabel pip install -r requirements.txt python PPOCRLabel.py --lang ch--lang ch参数把界面语言切到中文同时让默认字符编码按中文场景处理。启动后先让模型自动标注一遍再人工逐张校对框的位置和文本内容。漏框的要补框错字的要改字这一步偷懒的话后面训练出来的模型会把错误也一起学进去。标注完成后导出输出目录下会得到两个关键文件Label.txt和rec_gt.txt。新手最容易犯的错是只导出其中一个导致后面检测能用、识别没数据或者反过来。导出后先检查这两个文件是否都存在再往下走。3.2 两个标签文件的分工与格式差异这两个文件不能混用它们的格式和用途完全不同Label.txt是检测标签记录的是文本在图中的位置框每行包含图片路径、坐标点序列和文本内容格式类似图片路径 [ [x1,y1], [x2,y2], ... ], 文本内容。检测模型训练时只用框坐标。rec_gt.txt是识别标签记录的是裁剪后的文本图对应什么文字每行是图片路径 文本内容这种键值对。识别模型训练时只需要图和对应的文本行。所以后续划分数据集时检测数据集要把Label.txt里的图片路径提取出来识别数据集要从rec_gt.txt里提取。PPOCRLabel 目录下的两个脚本就是干这件事的但它们默认读取的路径、输出文件名和你的实际目录不一定对得上需要手动改参数。3.3 用 gen_det_train_val_test.py 划分检测数据集python PPOCRLabel/gen_det_train_val_test.py执行前必须打开脚本改参数核心是这几项标签文件路径指向 Label.txt、图片根目录、train/val/test 划分比例或数量、输出目录。改完再跑会生成train.txt、val.txt、test.txt三个文件。这里有一个决定后面训练是否顺利的细节train.txt 里的图片路径到底是绝对路径还是相对路径。如果脚本生成的是绝对路径yml 配置里只需要指定 train.txt 的路径就行图片路径不用管。如果生成的是相对路径你就必须保证它相对某个根目录有效稍后在 yml 里补data_dir。最好生成完随手打开 train.txt 看几行确认第一张图的路径是能直接用文件管理器打开的。3.4 用 gen_rec_follow_det.py 划分识别数据集检测数据集划分完接着执行python PPOCRLabel/gen_rec_follow_det.py这个脚本的作用是让识别数据集的划分和检测数据集保持一致避免同一张图的检测样本在训练集、识别样本在测试集导致验证指标虚高上线后立刻打回原形。我这次的项目里只分了训练集和测试集没有单独分验证集所以脚本生成的只有rec_train.txt和rec_test.txt没有rec_val.txt。如果你跟着这么干要注意后续 yml 的 Eval 配置必须有对应的验证文件可读不然验证阶段直接失败。我当时的做法是让 Eval 也用 test 集顶替或者手动从 test 里匀一部分出来当作 val如果你会改脚本建议直接给 gen_rec_follow_det.py 加上生成 val 的逻辑一劳永逸。4. 训练配置避坑清单路径拼接、batchsize 与 eval 频率4.1 坑一检测 train.txt 的路径格式决定了要不要配 data_dir现象train.py 启动后日志里反复出现图片读取失败loss 完全不动训练白跑。原因检测数据集的 train.txt 里如果已经是完整可访问的图片路径yml 中就不需要也不应该再配 data_dir但如果标签里记录的是相对路径而 yml 的 dataset 没有告诉加载器根目录在哪加载器按当前工作目录去拼十有八九找不到图。解决先看 train.txt 内容再决定配置方式。以ch_PP-OCRv3_det_cml.yml为例我改出来的检测训练配置是这样一段Train: dataset: name: SimpleDataSet label_file_path: ./OCR/ALL_1206/train.txt注意这里只给了label_file_path没有写data_dir。前提就是 train.txt 里的图片路径是完整的。如果换了一个脚本生成的是短路径那么必须补上 data_dir加载器会把data_dir label 中的路径拼成最终路径去读取图片。4.2 坑二识别数据集必须补 data_dir否则 rec_train.txt 全是死路径现象检测模型能正常训同样的套路切到识别模型一启动就报文件不存在。原因检测和识别两个任务的数据目录结构不同。检测标签里可以是完整图片路径而rec_train.txt里通常记录的是裁剪出来的小图相对路径比如crop_img/xxx.jpg只给 label_file_path 的话加载器并不知道 map 到哪个目录。解决识别配置里必须补data_dir指向 crop_img 的父目录Train: dataset: name: SimpleDataSet data_dir: ./OCR/ALL_1206/crop_img label_file_path: ./OCR/ALL_1206/rec_train.txt这里的坑在于 data_dir 到底指到哪一层。如果标签里写的是crop_img/xxx.jpgdata_dir 就填 crop_img 的上一级比如./OCR/ALL_1206/如果标签里只有xxx.jpgdata_dir 才直接填到 crop_img 这一层。判断依据很简单data_dir 标签里的路径拼出来得是一个真实存在的文件拼完之后自己拿文件管理器验证一遍。4.3 坑三batchsize 超过验证集图片数量eval 阶段直接崩现象eval 跑起来就报错错误信息指向 batch 维度不一致或者验证集输出的指标全是 0。原因batch_size 设置超过了验证集的图片总数数据加载器在凑 batch 的时候就凑不齐部分算子对最后一批数据做 reshape 时维度对不上直接抛异常。素材里的原话是「batchsize 设置不能超过输入训练图或验证图的数量」这是很实在的血泪经验。解决先数一下数据集里有多少条记录再填参数wc -l train.txt wc -l rec_train.txt比如验证集只有 100 张batch_size 就老老实实设 16 或 32。一个容易被忽略的连带问题是 batch_size 改了学习率也要跟着调。经验做法是 batch_size 加倍时学习率同步加 50% 到一倍不然收敛速度会明显变慢。我会在 yml 里把 batch_size 写小、把迭代步数写多稳定性优先。4.4 坑四权重保存太频繁磁盘爆满还不确定哪个该用现象训练跑了两三天output 目录下堆了一排 epoch 权重和一个 best_accuracy单个文件几百 MB磁盘说满就满。原因yml 里保存权重的步长设得太小每个 epoch 或者每几百步都落盘一份完整权重实际有用的只有验证集上精度最高的那一份。解决训练配置里把 eval 频率调高让模型每 10 步验证一次PaddleOCR 会自动保存验证集上最佳精度的权重文件名就是best_accuracy。同时把按 epoch 保存权重的参数调大避免中间权重堆积。我在 ch_PP-OCRv3_det_cml_myself.yml 里的做法是Global: eval_batch_step: - 0 - 10 save_epoch_step: 100eval_batch_step的第二个值 10 表示每 10 个 iteration 验证一次验证后如果精度提升就覆盖保存 best_accuracy。save_epoch_step调成 100意思是每 100 个 epoch 才手动保留一份完整权重日常就靠 best_accuracy 和 latest 两份文件顶着磁盘占用一下子降下来。5. 训练、验证、导出export_model.py 传参失效的根因与解法5.1 train.py 启动训练中途换预训练用 -o Global.pretrained_model训练本身的命令比较标准在源码根目录执行python tools/train.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml_myself.yml如果训练到一半发现效果不好想换一个预训练权重重新开始可以不用改 yml直接用 -o 覆盖参数python tools/train.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml_myself.yml -o Global.pretrained_modelpretrain_models/best_accuracy-o是命令行覆盖配置文件字段的标准用法格式是-o 配置路径值。这种写法的好处是不改动 yml 文件本体方便做多组对比实验。但要注意-o只在 train.py 和 eval.py 里生效可靠换到 export_model.py 就是另一回事了这是下一节的核心。5.2 eval.py 验证指定权重用 Global.checkpoints而不是 pretrained_model训练完要验证某个具体权重的效果用 eval.pypython tools/eval.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml_myself.yml -o Global.checkpoints./output/ch_PP-OCR_v3_det_1206/best_accuracy这里的关键是Global.checkpoints而不是Global.pretrained_model。eval.py 判断加载哪个权重时优先读 checkpoints 字段如果你只写了 pretrained_model它可能去加载官方预训练权重给你一个虚高的验证指标让你误以为训练效果很好。我见过有人拿着预训练模型的验证指标去对比自己的微调模型白高兴一场。验证时务必确认日志里打印的权重加载路径是你 output 目录下的那个文件。5.3 导出翻车现场Global.pretrained_model 命令行传参不生效按常规思路导出推理模型时把训练好的权重通过 -o 传进去命令长这样python tools/export_model.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml_myself.yml -o Global.pretrained_model./output/ch_PP-OCR_v3_det_1206/best_accuracy -o Global.save_inference_dir./inference/det_cml_ppocrv3_1206这段命令跑完没有任何报错看起来导出成功了。但把导出的模型拿去预测效果和你没微调差不多翻日志才发现export_model.py 加载权重的时候读的还是 yml 里配置的 pre训练模型路径命令行传进去的Global.pretrained_model压根没被加载逻辑使用。根因在于 export_model.py 内部的加载链路和 train.py 不一样命令行 -o 覆盖并没有真正传达到权重加载那一步。yml 里只要写了Global.pretrained_model导出时就会优先用它。也就是说命令行里写得再清楚脚本不认就是白搭这在 PaddleOCR 2.6 里算是个隐蔽的坑仅凭报错信息很难定位。5.4 解法把训练好的权重路径写进 yml 再导出正确的做法是直接修改 yml把pretrained_model改成训练产出的权重绝对路径或相对路径保存后重新执行导出命令并且不要再带 -o Global.pretrained_modelGlobal: pretrained_model: ./output/ch_PP-OCR_v3_det_1206/best_accuracy save_inference_dir: ./inference/det_cml_ppocrv3_1206python tools/export_model.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_cml_myself.yml导出完成后先别急着做预测验证一下导出的模型是不是新的进入./inference/det_cml_ppocrv3_1206目录看里面权重文件的生成时间是否和 output 目录下 best_accuracy 的时间接近。如果 inference 里的文件是几分钟前刚生成的说明这次导出加载的是训练后的权重如果时间戳是几小时前甚至更早说明脚本根本没重新加载还在用缓存或预训练权重。为了保险我还会做一个更严格的对照先把 yml 的 pretrained_model 改成 latest导出一份不同名字的 inference 目录对比两个目录里的模型文件大小。训练后期的 best_accuracy 和 latest 通常是同一份验证集最佳就是最新文件大小应该一致如果相差很大说明中间某个环节加载错了。5.5 串联推理predict_system.py 验证全链路模型导出完成后用 predict_system.py 做端到端预测python tools/infer/predict_system.py \ --image_dir./OCR/ALL_1206/test \ --det_model_dir./inference/det_cml_ppocrv3_1206/Student \ --rec_model_dir./inference/rec_ppocr_v3_distillation_1206/Student注意这里 det 和 rec 的目录都指向了 Student 子目录。这是因为 ch_PP-OCRv3_det_cml.yml 是蒸馏训练配置导出后的模型目录下会同时包含 Teacher 和 Student 两套权重推理只需要 Student 那套就够了。如果你用的不是蒸馏配置导出目录下可能直接就是inference.pdmodel和inference.pdiparams两个文件没有子目录这时 model_dir 直接指向目录本身即可。如果预测结果里框的位置乱七八糟优先怀疑 det_model_dir 指向错误如果文字识别出来的内容全是乱的优先查 rec_model_dir 和识别权重。图像和模型目录都对着再去看 --image_dir 路径下图片是否可读。6. 快速定位一张对照表 三个验证命令我把这整套流程里最容易踩的坑汇总成一张对照表后面对号入座就行阶段现象常见根因优先排查安装import yaml 报错PyYAML 缺失补装 PyYAML训练loss 不动、图片读取失败标签路径与 data_dir 不匹配打开 train.txt 看第一行路径验证eval 崩溃、指标为 0验证集数量小于 batch_sizewc -l 数行数导出预测效果差、等于没训export_model.py 加载的还是预训练权重检查 yml 的 pretrained_model推理识别结果为空Teacher/Student 模型目录选错指向 Student 子目录推理中文乱码或识别错行标签里有空格导致解析错位检查 rec_gt.txt 分隔符训练过程中最好的习惯是盯日志里有没有出现 best_accuracy 相关的记录只要它出现了说明 eval 链路是通的权重保存也是对的。训练完之后我会强制走三个验证命令ls -l ./output/ch_PP-OCR_v3_det_1206/ # 看 best_accuracy 的生成时间 ls -l ./inference/det_cml_ppocrv3_1206/Student/ # 看导出模型的生成时间 python tools/infer/predict_system.py --image_dirtest_001.jpg --det_model_dir./inference/det_cml_ppocrv3_1206/Student --rec_model_dir./inference/rec_ppocr_v3_distillation_1206/Student最后一步我会拿训练集里的一张原图去跑预测确认连训练集都能识别出来才敢说模型链路没问题。如果训练集上的效果都不行问题大概率出在权重加载或路径配置而不是模型本身。从那以后我每次做 OCR 微调导出前都强制走这三件事先打开 yml 确认 pretrained_model 指向 output 里最新的 best_accuracy再检查 inference 目录的生成时间最后用一张训练集原图复测识别效果。这三步看起来笨但每次都帮我拦住了「导出失败」这类最隐蔽的翻车希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

Ecology OA短信接口配置详解:中间表与SmsService双方案落地实践

Ecology OA短信接口配置详解:中间表与SmsService双方案落地实践

简介:面向泛微Ecology系统开发与实施人员的短信接口实现文档,核心思路是借中间表解耦:Ecology只负责把需要发送的短信数据写入中间表,由短信设备供应商或客户自行读取并发送,因而无需与每家短信设备逐一做集成开发。文…

📅 2026/10/16 18:52:07
从薪酬算起:人力资源数字化的全景数智演进路径

从薪酬算起:人力资源数字化的全景数智演进路径

从薪酬起家到全景数智,这句话我在过去一年多里反复听到。起因是身边几位做人力资源数字化的朋友,几乎在同一时间向我提起同一类问题:一家最早只做薪酬计算的厂商,凭什么能把“软件AI服务”打包成一套完整方案?它和那些…

📅 2026/10/16 18:47:05
强化学习入门:从监督学习到奖励机制,AI如何“挨打长记性”?

强化学习入门:从监督学习到奖励机制,AI如何“挨打长记性”?

AI圈子里有个说法,说强化学习像养孩子,而且是个典型的熊孩子。别的模型是“喂什么学什么”,给它看一万张猫图,它就能认猫;给它读一万篇新闻,它就能写稿。强化学习不是这么玩的,它更像你把一个小…

📅 2026/10/16 18:47:05
MORE NEWS

更多资讯

📰

Atoll 2.8 LTE仿真操作指南:从地图配置到网络性能预测全解析

简介:《Atoll-LTE仿真指导书2.8版本》是一份面向LTE/4G网络规划工程师与无线通信学习者的实操指南,以法国Forsk公司Atoll软件为对象,系统讲解从零搭建LTE仿真工程的完整流程,帮助用户掌握网络覆盖预测与参数配置方法。整个资源包仅…

📰

石器时代老游戏源码复现:服务端编译、数据库配置与联调避坑指南

简介:全套石器时代项目源代码,适合想研究经典 C 语言游戏/应用架构的开发者,也适合需要参考完整工程组织方式的初学者。包内共 378 个文件,以 174 个 .h 头文件和 170 个 .c 源文件为主体,配合 makefile、VC6 工程文件…

📰

C#驾考模拟器开发实战:从题库加载到状态机判分

简介:一份用于学习参考的C#模拟驾驶执照考试系统项目,定位清晰:面向初学C#或想了解Windows Forms桌面应用开发的读者,用自动生成试卷、逐题作答、自动评分的完整流程,帮助理解面向对象编程、随机算法、文件读写、事件驱…

📰

SAP CO模块核心原理:成本流、主数据与月结差异实战解析

简介:本资源是一份面向SAP初学者与财务/成本控制岗位从业者的CO模块系统性入门培训课件,聚焦Controlling(控制)模块的核心逻辑与实操要点,助力用户快速掌握企业成本归集、分配、分摊及绩效分析的关键能力。课件为单个P…

📰

2026年AI驱动电商增长:五大核心场景与落地实操指南

2026年聊AI驱动的电商增长,已经不是在聊新鲜概念了。流量红利见顶、投放成本走高、用户耐心越来越短,电商人最直观的感受是,过去躺赚的玩法基本失效。越来越多团队开始认真对待AI,不是因为它炫技,而是因为它切切实实解…

📰

用单个VLM控制机械臂:Show-Harness原理与复现

做机器人操作的朋友应该都有过这种体验:一个简单的“把红色方块放到篮子里”,写传统控制代码可能要一整天,感知模块、坐标转换、轨迹规划、抓取判定各写一版,最后还要为了某个边界情况反复调参。后来看到VLM(视觉语言模…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬