User
请你写一份详细的完整的非常详细的全流程步骤给我、每一个步骤都要说的详细、哪些要我自己来哪些适合交给Codex都要说清楚、另外你要明确我的身份、不要默认那些英文的名词我会知道是什么意思、都给我解释、但是解释要详细、不要科普级别的。 我的背景:电子信息工程大学生,会 C 和 Python,有基本编程基础,理解变量、函数、全局变量等概念。了解 Windows/Linux,会一些基本命令行操作。知道 IP、域名、服务器等基本概念,但网络知识不深入。 我没有系统学习过传统软件开发,对数据库、Web 开发、前后端、框架、包管理、部署、DevOps 等技术栈不要默认我了解。Docker 我只知道大概用途,没有实际使用经验。 给我讲解时,可以使用正常的计算机术语,但第一次出现一个软件开发领域的概念或工具时,请先说明“它是什么、用来干什么”,然后再继续,不需要把编程基础知识从零讲起。用过 Git/GitHub,主要通过 GitHub Desktop 完成提交、同步、推送等基本操作,知道版本控制的大概用途,但不熟悉 Git 命令行、分支管理细节和底层原理。不要降低技术深度,只补充我缺失的前置知识。
Assistant
我会把它写成一份“可以照着执行”的工程手册,而不是泛泛的教程。主线我会固定为:Windows 主机 + WSL2 Ubuntu + NVIDIA GPU + PaddleOCR PP-OCRv5 文字识别微调,并把“你必须理解/亲自确认的环节”和“适合交给 Codex 自动完成的环节”明确分开。
Assistant
有一个设计原则我会放在最前面:OCR 的训练标签必须忠实于画面里实际写了什么,不能把“原字幕写错/写俗了的字”直接改成你认为的粤语正字当作 OCR 标签。 否则模型学到的不是 OCR,而是“看见 A 猜成 B”。如果你还希望最终输出规范粤语正字,应把它做成第二阶段的文字规范化模块。这个区分会决定数据集是否正确。
Assistant
下面这份我会按你的实际背景来写:你有 C/Python 基础、能理解程序和命令行,但没有做过深度学习训练、没有系统的软件工程/DevOps 背景。因此我不会解释变量、函数、循环这类东西;但像虚拟环境、依赖、checkpoint、训练集/验证集/测试集、YAML、CUDA runtime、数据泄漏、CER 等第一次出现时,我会解释到足够你真正动手,而不是只给一句科普定义。
还有两个版本选择先说明。现在 PaddleOCR 最新公开版本已经到 3.7.0,并发布了 PP-OCRv6;但本项目第一版我仍建议用 PP-OCRv5_server_rec,因为当前官方“二次开发/微调”文档就是直接以它作为完整范例,而且它明确覆盖繁体中文、生僻字等场景。等 v0.1 跑通以后,再把 PP-OCRv6_medium_rec 拉进来做 A/B benchmark,而不是第一天同时面对“新模型 + 新环境 + 新数据”三个变量。(GitHub)
另外,你的 RTX 5070 Ti 属于 Blackwell / sm_120。PaddlePaddle 官方表目前对消费级 Blackwell 推荐 CUDA 12.9;更重要的是,PaddleOCR 官方仍明确提示 Windows 原生环境下 50 系显卡的文字识别训练存在已知问题。所以我下面不走 Windows 原生训练,而是走 Windows + WSL2 Ubuntu + Linux PaddlePaddle。NVIDIA 官方也支持在 WSL2 中直接使用 Windows NVIDIA 驱动提供 CUDA 能力,并明确提醒不要再在 WSL 中安装 Linux NVIDIA 显卡驱动。(NVIDIA Developer)
:::writing{variant=“document” id=“57314” title=“从零微调粤语正字 OCR:PP-OCRv5 全流程工程手册”}
从零微调粤语正字 OCR:完整工程路线
0. 你的起点、最终目标,以及我对你的技术假设
0.1 你的身份
这份教程假定你是:
- 电子信息工程大学生;
- 会 C 和 Python;
- 理解变量、函数、作用域、文件读写、基本数据结构;
- 知道 Windows/Linux 的基本使用;
- 能进行简单命令行操作;
- 使用过 Git/GitHub,但主要通过 GitHub Desktop;
- 没有系统做过模型训练;
- 没有系统学习过传统软件开发工程;
- 不默认你熟悉包管理、虚拟环境、依赖管理、Docker、Web 前后端、数据库、部署、DevOps;
- 你有 Codex,可以让它直接帮助你读项目、写脚本、修改配置、运行命令、分析报错。
因此这套流程的原则不是“所有东西都手工做一遍”,而是:
你负责做必须由人判断的事情;Codex 负责机械、重复、容易写错但可以验证的工程工作。
这是非常重要的分工。
你最终要学会的是:
为什么这样训练、数据为什么这样准备、结果为什么可信。
而不是背 PaddleOCR 的每个 API。
1. 先把我们究竟要训练什么说清楚
1.1 OCR 实际上通常分成两个模型
典型 OCR pipeline:
一张完整视频画面
↓
Text Detection
文字检测
↓
找到“哪里有字”
↓
例如裁出:
┌─────────────────┐
│ 我唔知佢去咗邊 │
└─────────────────┘
↓
Text Recognition
文字识别
↓
我唔知佢去咗邊
Text Detection:文字检测
任务是:
图片里的文字在哪里?
输出通常是矩形框或多边形框。
它不负责真正判断字是什么。
Text Recognition:文字识别
任务是:
已经给你一块包含文字的图片,这些文字是什么?
我们第一次微调的就是:
PP-OCRv5_server_rec
这里的:
PP-OCRv5:PaddleOCR 第五代 PP-OCR 系列;server:偏精度、计算量更大的版本;rec:Recognition,即“识别”。
官方目前仍提供这个模型的预训练权重、训练配置、评估和导出流程。(GitHub)
1.2 为什么第一版不训练 Detection?
因为你的目标是影视字幕。
影视字幕通常:
- 出现在固定区域;
- 横排;
- 字体较统一;
- 字号相近;
- 每行结构简单;
- 可以先裁掉画面上方 60%~70%;
- PaddleOCR 原版检测器通常已经很容易找到字幕。
所以第一阶段:
检测模型保持原版。
只训练:
Recognition Model。
这会让项目难度降低一个数量级。
2. 一个非常重要的概念:OCR ≠ 粤语正字纠错
这一节一定不要跳。
假设画面实际写的是:
我係屋企
但根据语义,你认为这里更规范应该写:
我喺屋企
如果你训练 OCR 时:
图片里明明是:
係
Ground Truth 却写:
喺
这是错误的数据。
2.1 Ground Truth 是什么?
Ground Truth,简称 GT,中文常叫“真实标签”或“标准答案”。
监督学习时,每张图片都需要一个正确答案。
例如:
000001.png<TAB>我唔知佢去咗邊
图片:
┌────────────────┐
│ 我唔知佢去咗邊 │
└────────────────┘
标签:
我唔知佢去咗邊
模型看到图片后输出结果,然后计算:
预测结果 vs Ground Truth
差多少。
再根据这个误差更新模型参数。
2.2 Ground Truth 必须描述“图上写了什么”
所以正确系统应该是:
字幕图片
↓
OCR
↓
忠实文本
↓
可选:粤语正字规范化模块
↓
规范粤语
例如:
图片实际写:
我係屋企
OCR:
我係屋企
正字规范化:
我喺屋企
而不是训练 OCR 直接:
係 → 喺
否则 OCR 会学会“猜”。
3. 我们最终做成什么项目
项目名先叫:
cantonese-ocr
第一阶段版本:
Cantonese-OCR-v0.1
目标不是:
从零训练 OCR。
而是:
在 PP-OCRv5 已经具有的繁体中文视觉能力基础上,用香港粤语字幕数据进行 Fine-tuning。
4. Fine-tuning 到底是什么?
Fine-tuning,中文通常叫“微调”。
神经网络模型里有大量参数,例如:
weight_000001
weight_000002
weight_000003
...
它们 collectively 叫:
模型权重(weights)
PP-OCRv5 已经训练过海量:
- 中文;
- 繁体中文;
- 英文;
- 日文;
- 生僻字;
- 各种字体;
所以它已经知道:
“汉字大概长什么样”。
我们不重新从随机参数开始。
而是:
官方模型
↓
已有参数
↓
给它更多粤语字幕
↓
用很小的学习率继续训练
↓
Cantonese OCR
这就是 Fine-tuning。
5. Pretrained Model 和 Checkpoint 的区别
以后会频繁看到两个词。
Pretrained Model
预训练模型。
这是:
训练开始前用来初始化模型的已有权重。
我们使用:
PP-OCRv5_server_rec_pretrained.pdparams
Checkpoint
训练检查点。
比如你已经训练到第 8 Epoch:
Epoch 1
Epoch 2
...
Epoch 8
程序把当前:
- 模型参数;
- Optimizer 状态;
- 当前训练阶段;
保存下来。
然后电脑关机。
第二天可以:
checkpoint
↓
继续 Epoch 9
这就是 Resume Training。
重要:
pretrained_model和checkpoints不是同一个概念。
第一次 Fine-tune:
pretrained_model = 官方权重
checkpoints = 空
断点续训:
checkpoints = 自己之前保存的 checkpoint
6. 为什么选择 WSL2,而不是 Windows 原生?
6.1 WSL2 是什么?
WSL:
Windows Subsystem for Linux
WSL2 可以理解成:
Windows 内部运行了一个深度集成的 Linux 环境。
你仍然用 Windows:
Windows 11
├── 浏览器
├── QQ
├── VS Code
├── Codex
└── WSL2
└── Ubuntu Linux
训练实际发生在 Ubuntu 里面。
6.2 为什么不是 Docker?
Docker 是:
把程序、依赖和用户态运行环境打包成 Container(容器)的工具。
它确实非常适合复现 AI 环境。
但你第一次训练模型,我不建议同时学习:
Docker
+
WSL
+
CUDA
+
Paddle
+
OCR training
这会增加故障层。
所以:
v0.1 不用 Docker。
等模型跑通之后再考虑容器化。
6.3 为什么 WSL 特别适合你的 5070 Ti?
RTX 5070 Ti 属于 NVIDIA Blackwell sm_120。NVIDIA 官方 CUDA GPU 表把 RTX 5070 Ti 列在 Compute Capability 12.0;PaddlePaddle 当前表对消费 Blackwell 推荐 CUDA 12.9。(NVIDIA Developer)
PaddleOCR 官方目前又明确写着:
Windows 50 系 GPU 的 PaddlePaddle wheel 对文字识别训练仍存在已知问题。(GitHub)
所以:
Windows Native
不作为我们的主训练环境。
7. 第一阶段职责划分
这是以后整个项目最重要的工作原则。
| 工作 | 你 | Codex |
|---|---|---|
| 决定目标输出是什么 | ✅ 必须 | 辅助 |
| 决定哪些粤字必须支持 | ✅ | 帮你统计 |
| 判断字幕正确标签 | ✅ 必须 | 预识别 |
| 安装命令 | 看结果 | ✅ 执行/排错 |
| 写 Python 脚本 | 审核目标 | ✅ |
| 建项目目录 | 不必手工 | ✅ |
| 写 YAML | 理解关键参数 | ✅ |
| 下载模型 | 监督 | ✅ |
| 运行训练 | 观察 | ✅ |
| 分析训练 log | 学习判断 | ✅ 辅助 |
| 判断 OCR 是否真的改善 | ✅ 必须 | 统计 |
| 修改超参数 | 决策 | ✅ 修改 |
| Git commit | 审查 | ✅ 或 GitHub Desktop |
| Ground Truth 最终审核 | ✅ 必须 | ❌ 不可替代 |
一句话:
Codex 是工程师助手,不是 Ground Truth 的裁判。
8. Phase 0:建立“项目规格”,先不要训练
预计你本人:20~40 分钟。
创建:
docs/labeling_policy.md
这是:
数据标注规范。
Codex 可以帮你起草,但最终规则必须由你确认。
至少确定:
字符原则
图上:
嚟
标签必须:
嚟
不能写:
黎
保留繁体
例如:
邊
後
嚟
點
不要自动简体化。
不进行语义纠错
图片:
係度
标签:
係度
即使你认为:
喺度
才更规范。
Unicode Normalize
建议使用:
NFC
但不要自动使用:
NFKC
Unicode Normalization 是:
把某些视觉上或语义上等价、但编码方式不同的 Unicode 字符统一表示。
NFKC 比 NFC 更激进,可能处理 Compatibility Character,因此对于 HKSCS / CJK 字符研究项目,第一版不要随意使用。
Codex 可以统一实现:
unicodedata.normalize("NFC", label)
空格
建议:
- 去掉行首空格;
- 去掉行尾空格;
- 保留真正出现在字幕中间的空格;
- 标签中不允许 Tab。
因为 PaddleOCR 的标签文件使用:
图片路径<TAB>文字
Tab 本身就是分隔符。
官方数据格式也要求图片路径与标签之间使用 \t。(GitHub)
9. Phase 1:准备 WSL2
9.1 先在 Windows PowerShell 检查
打开:
Windows Terminal → PowerShell
运行:
# wsl.exe:Windows 自带的 WSL 管理程序。
# --status:要求 WSL 输出当前安装状态、默认版本、Kernel 等信息。
# 本命令不会修改系统,只做检查。
wsl.exe --status
再运行:
# wsl.exe:WSL 管理程序。
# --list:列出已经安装的 Linux Distribution(发行版)。
# --verbose:显示更多信息,尤其是当前发行版使用 WSL 1 还是 WSL 2。
wsl.exe --list --verbose
理想结果类似:
NAME STATE VERSION
Ubuntu-24.04 Running 2
重点:
VERSION = 2
9.2 如果没有 Ubuntu
运行:
# wsl.exe:WSL 管理工具。
# --install:安装 WSL 及指定 Linux 发行版。
# -d:distribution 的缩写,用来指定要安装哪个 Linux 发行版。
# Ubuntu-24.04:我们指定 Ubuntu 24.04 LTS。
wsl.exe --install -d Ubuntu-24.04
之后更新 WSL:
# wsl.exe:WSL 管理工具。
# --update:更新 WSL Kernel 和相关组件到 Microsoft 当前提供的版本。
wsl.exe --update
如果 Windows 要求重启,重启。
10. Phase 2:检查 5070 Ti 是否能从 WSL 访问
进入 Ubuntu。
然后:
# nvidia-smi:NVIDIA System Management Interface。
# 它读取 NVIDIA 驱动提供的 GPU 状态,包括显卡型号、驱动版本、显存占用等。
# 本命令没有额外参数,只进行状态查询。
nvidia-smi
你必须看到类似:
NVIDIA GeForce RTX 5070 Ti Laptop GPU
还应该看到:
Driver Version
CUDA Version
这里 CUDA Version 更准确地说是:
当前 NVIDIA Driver 能支持到的 CUDA API 版本。
不是在告诉你:
“Ubuntu 已经安装了一个完整 CUDA Toolkit。”
这是非常常见的误解。
11. 特别重要:现在不要安装 Ubuntu NVIDIA Driver
NVIDIA 官方 WSL 指南明确说明:
WSL 使用 Windows 主机 NVIDIA Driver 映射出的 CUDA Driver,不要在 WSL 里安装 Linux NVIDIA 显卡驱动。(NVIDIA Docs)
所以如果某个旧教程让你:
apt install nvidia-driver-xxx
不要照做。
我们也暂时不需要:
nvcc
因为我们不是从源码编译 CUDA 程序。
12. Phase 3:安装 Linux 基础开发工具
你现在已经进入 Ubuntu。
运行:
# sudo:以管理员权限执行后面的命令。
# apt-get:Ubuntu/Debian 系统的软件包管理工具。
# update:更新“可安装软件版本列表”,本身通常不会升级已安装软件。
sudo apt-get update
然后:
# sudo:管理员权限。
# apt-get:Ubuntu 软件包管理工具。
# install:安装后面列出的系统软件包。
# -y:安装过程中遇到 yes/no 确认时自动选择 yes。
#
# git:版本控制工具,用于克隆 PaddleOCR。
# python3:Python 3 解释器。
# python3-venv:Python 官方虚拟环境模块。
# python3-pip:Python 包管理器 pip。
# wget:命令行文件下载工具。
# curl:HTTP/HTTPS 命令行请求与下载工具。
# ffmpeg:视频/音频处理工具,之后抽帧和处理视频会用。
# build-essential:包含 gcc、g++、make 等常见编译工具。
# libgl1:OpenCV 等图像库常用的 OpenGL 运行库。
# libglib2.0-0:OpenCV 等程序常依赖的 GLib 运行库。
sudo apt-get install -y git python3 python3-venv python3-pip wget curl ffmpeg build-essential libgl1 libglib2.0-0
13. Phase 4:建立项目目录
我们的项目不要直接乱改 PaddleOCR。
最终结构建议:
cantonese-ocr/
│
├── .venv/
│
├── third_party/
│ └── PaddleOCR/
│
├── configs/
│
├── data/
│ ├── raw_videos/
│ ├── raw_frames/
│ ├── crops/
│ ├── rec/
│ │ ├── train/
│ │ ├── val/
│ │ └── test/
│ └── metadata/
│
├── scripts/
│
├── fonts/
│
├── artifacts/
│ ├── pretrained/
│ ├── runs/
│ └── exports/
│
├── reports/
│
└── docs/
13.1 third_party 是什么?
在软件项目中:
third_party
通常用来存放:
来自其他项目/公司的外部源代码。
PaddleOCR 不是我们自己写的,所以放这里。
这样以后:
我们的代码
和:
PaddleOCR 官方代码
不会混在一起。
14. 这一步适合直接交给 Codex
给 Codex:
请在 ~/projects/cantonese-ocr 创建一个用于 PaddleOCR 微调的项目目录。
要求:
1. 不要修改 PaddleOCR 官方源代码。
2. 建立 third_party、configs、data、scripts、fonts、artifacts、reports、docs。
3. data/raw_videos、data/raw_frames、artifacts/runs 等大文件目录应加入 .gitignore。
4. 建立 README.md,记录项目目标:微调 PP-OCRv5_server_rec 用于香港粤语影视字幕识别。
5. 建立 docs/labeling_policy.md 初稿,但不要替我决定粤语正字规范。
6. 所有自动生成的标签必须 UTF-8。
7. 先不要训练模型。
你负责:
看 Codex 建出来的结构是否符合上面设计。
15. Phase 5:克隆固定版本的 PaddleOCR
不要直接永远追:
main
因为 main 每天可能变化。
这涉及一个软件工程概念:
Reproducibility——可复现性
意思是:
三个月以后,我们应该知道当初到底用了哪一版代码。
因此固定:
PaddleOCR v3.7.0
当前官方 Release 页面显示 v3.7.0 在 2026 年 6 月发布。(GitHub)
运行:
# cd:change directory,切换当前工作目录。
# ~/projects/cantonese-ocr/third_party:
# "~" 表示当前 Linux 用户的 home 目录。
cd ~/projects/cantonese-ocr/third_party
# git:版本控制工具。
# clone:把远程 Git Repository 克隆到本地。
# --branch v3.7.0:直接检出 v3.7.0 这个固定 Release Tag。
# --depth 1:浅克隆,只下载当前所需的一层历史,减少下载量。
# URL:PaddleOCR 官方 GitHub Repository。
# PaddleOCR:把本地目录固定命名为 PaddleOCR。
git clone --branch v3.7.0 --depth 1 https://github.com/PaddlePaddle/PaddleOCR.git PaddleOCR
16. Phase 6:创建 Python Virtual Environment
Virtual Environment 是什么?
Python 很多库都会被:
pip install
装进 Python 环境。
问题在于不同项目需要不同版本:
项目 A:
numpy 1.x
项目 B:
numpy 2.x
如果全部安装在同一个 Python:
很容易冲突。
所以使用:
Virtual Environment,Python 虚拟环境。
它会给当前项目建立独立:
site-packages
即独立依赖空间。
运行:
# cd:进入项目根目录。
cd ~/projects/cantonese-ocr
# python3:调用 Python 3。
# -m:让 Python 运行一个已安装模块,而不是运行 .py 文件。
# venv:Python 标准库提供的虚拟环境创建模块。
# .venv:创建出来的虚拟环境目录名称。
python3 -m venv .venv
激活:
# source:让当前 Shell 执行指定脚本,并让它对当前 Shell 环境生效。
# .venv/bin/activate:虚拟环境自带的激活脚本。
# 激活后 python3/pip 将优先指向这个项目的虚拟环境。
source .venv/bin/activate
以后终端前面一般会出现:
(.venv)
17. pip 是什么?
pip 是:
Python Package Manager,Python 包管理工具。
例如:
numpy
opencv-python
paddlepaddle
都是 Python Package。
我们尽量使用:
python3 -m pip
而不是裸:
pip
原因是这样能确定:
使用的是“当前 python3 对应的 pip”。
更新基础工具:
# python3:当前虚拟环境中的 Python。
# -m pip:让该 Python 运行 pip 模块。
# install:要求 pip 安装软件包。
# --upgrade:如果已经安装,则升级到可获得的更新版本。
# pip:Python 包管理器自身。
# setuptools:常见 Python 包构建/安装基础工具。
# wheel:Python 二进制/分发包格式的基础支持工具。
python3 -m pip install --upgrade pip setuptools wheel
18. Phase 7:安装 PaddlePaddle GPU
PaddlePaddle 是什么?
PaddlePaddle 是:
深度学习 Framework(框架)。
Framework 在这里不是 Web 框架。
它负责:
- Tensor 运算;
- GPU 计算;
- 自动求导;
- Optimizer;
- 模型参数;
- 训练;
- 保存权重。
它和 PyTorch 属于同一层。
关系是:
NVIDIA GPU
↓
CUDA
↓
PaddlePaddle
↓
PaddleOCR
↓
PP-OCRv5
18.1 为什么使用 cu129?
cu129:
CUDA 12.9
PaddlePaddle 当前官方硬件表对:
Blackwell sm_120
RTX 5090 / 5080 / 5070
推荐 CUDA 12.9。RTX 5070 Ti 同样属于 NVIDIA 官方列出的 sm_120 Compute Capability 12.0。(NVIDIA Developer)
运行:
# python3:当前虚拟环境 Python。
# -m pip:使用当前 Python 的 pip。
# install:安装软件包。
# paddlepaddle-gpu==3.3.0:
# 安装 PaddlePaddle GPU 版本,并固定为 3.3.0。
# "==" 表示精确固定版本,而不是自动升级最新版。
# -i:指定 pip 使用的 Python Package Index。
# 最后的 URL 是 PaddlePaddle 官方 CUDA 12.9 Wheel 软件源。
python3 -m pip install paddlepaddle-gpu==3.3.0 -i https://www.paddlepaddle.org.cn/packages/stable/cu129/
PaddlePaddle 官方 Linux 安装体系已经提供 CUDA 12.9 wheel;官方表也提供 cp39~cp313 等多个 Python 构建。(飞桨)
19. 安装 PaddleOCR Training Dependencies
进入 PaddleOCR:
# cd:切换工作目录。
# 路径指向我们刚刚固定克隆的 PaddleOCR v3.7.0。
cd ~/projects/cantonese-ocr/third_party/PaddleOCR
安装依赖:
# python3:当前虚拟环境 Python。
# -m pip:使用该 Python 的 pip。
# install:安装依赖。
# -r:让 pip 从 requirements 文件逐项读取需要安装的软件包。
# requirements.txt:PaddleOCR 官方训练代码提供的依赖清单。
python3 -m pip install -r requirements.txt
PaddleOCR 官方训练安装流程也是:
clone repository
→ install requirements.txt
的方式。(GitHub)
20. Phase 8:做一次环境体检
这一步不要跳。
运行:
# python3:当前虚拟环境 Python。
# -c:直接执行后面引号里的 Python 程序,而不是读取 .py 文件。
#
# import paddle:确认 PaddlePaddle 能成功导入。
# paddle.__version__:打印实际安装的 Paddle 版本。
# paddle.device.get_device():显示当前 Paddle 选择的计算设备。
# paddle.utils.run_check():执行 Paddle 官方环境自检。
python3 -c "import paddle; print('Paddle:', paddle.__version__); print('Device:', paddle.device.get_device()); paddle.utils.run_check()"
你希望看到:
PaddlePaddle is installed successfully!
以及 GPU。
如果这里失败:
不要继续准备训练。
先让 Codex 修环境。
21. 让 Codex 建立 doctor.py
这是非常推荐的工程习惯。
Doctor Script:
一键检查当前机器与项目环境是否正常的诊断程序。
交给 Codex:
请在 cantonese-ocr/scripts 下创建 doctor.py。
要求输出:
1. 操作系统和 Kernel。
2. Python 版本和 Python executable 路径。
3. 当前 virtual environment。
4. PaddlePaddle 版本。
5. Paddle 是否 compiled with CUDA。
6. Paddle 当前 device。
7. CUDA device 数量。
8. GPU 名称。
9. 当前显存信息(如 API 可以获取)。
10. PaddleOCR git tag / commit hash。
11. requirements 关键包版本。
12. 项目磁盘剩余空间。
13. 检查 data、artifacts、configs 必需目录。
14. 最后明确打印 PASS / FAIL。
15. 不要自动修改系统。
以后每次环境怪掉:
先跑 doctor。
22. Phase 9:下载 PP-OCRv5 官方预训练模型
先建立:
artifacts/pretrained/
可以让 Codex 做。
然后进入 PaddleOCR:
# cd:切换到 PaddleOCR 源码目录。
cd ~/projects/cantonese-ocr/third_party/PaddleOCR
下载:
# wget:HTTP/HTTPS 文件下载工具。
# -O:指定下载结果保存到哪个文件。
# ../../artifacts/pretrained/...:
# 从 third_party/PaddleOCR 返回项目根目录,再保存进 artifacts/pretrained。
# URL:PaddleOCR 官方提供的 PP-OCRv5_server_rec 预训练权重。
wget -O ../../artifacts/pretrained/PP-OCRv5_server_rec_pretrained.pdparams https://paddle-model-ecology.bj.bcebos.com/paddlex/official_pretrained_model/PP-OCRv5_server_rec_pretrained.pdparams
这个文件是:
*.pdparams
也就是 Paddle 模型参数文件。
官方 PP-OCRv5 微调文档使用的就是这个预训练权重。(GitHub)
23. 现在先不要训练自己的数据
先证明:
环境
+
代码
+
模型
三者真的能够正常工作。
这叫:
Smoke Test(冒烟测试)
软件工程里的 Smoke Test:
不是验证所有细节,只检查系统最关键路径能不能跑通。
24. Phase 10:让官方 Demo 数据先训练一次
PaddleOCR 官方提供 recognition demo dataset。(GitHub)
这个阶段完全适合交给 Codex。
给 Codex:
我们现在只做环境 smoke test,不做正式粤语训练。
请:
1. 使用 PaddleOCR v3.7.0。
2. 使用 PP-OCRv5_server_rec。
3. 使用官方 text recognition demo dataset。
4. 使用官方 PP-OCRv5_server_rec pretrained model。
5. 单 GPU。
6. 把 batch size 调到保守值,先从 32 开始。
7. distributed=false。
8. 只训练很短的一次,例如足以确认 loss 正常下降即可。
9. 不允许修改 PaddleOCR Python 源代码。
10. 如果需要改参数,请复制官方 YAML 到 cantonese-ocr/configs/smoke_test.yml,不要直接改官方配置。
11. 保存完整 console log 到 reports/smoke_test.log。
12. 完成后告诉我:
- GPU 是否真正工作;
- 最大显存占用;
- loss 是否下降;
- 是否保存 checkpoint;
- 是否发生 NaN 或 OOM。
25. OOM 是什么?
以后你很可能看到:
CUDA out of memory
简称:
OOM — Out Of Memory
意思通常是:
GPU 显存不够。
不是 32GB 系统 RAM。
主要受:
Batch Size
影响。
26. Batch Size 是什么?
训练时不是:
看一张图
更新一次参数
通常是:
同时拿 32 张
算一次 loss
更新一次参数
这个:
32
就是 Batch Size。
越大:
- 显存占用通常越高;
- GPU 利用率可能更高;
- Gradient 更稳定;
但不是越大越好。
你 5070 Ti Laptop 第一版:
Batch = 32
保守起步。
如果显存很富余:
48
64
再测试。
如果 OOM:
24
16
27. Phase 11:正式建立 Benchmark
这里开始是项目真正重要的部分。
Benchmark 是什么?
Benchmark:
一组固定测试数据 + 固定评价方法。
目的:
原模型
vs
微调模型
必须参加同一场考试。
否则你无法证明微调有效。
28. 我建议你建立三个 Benchmark
A. cantonese_in_domain_test
与你最常处理的视频类似:
- 相似字幕;
- 相似分辨率;
- 相似视频质量;
测:
实际使用效果。
B. cantonese_cross_domain_test
来自:
- 不同节目;
- 不同字体;
- 不同压制来源;
- 不同字幕颜色;
测:
泛化能力。
C. general_traditional_test
普通繁体中文字。
测:
微调粤语之后,有没有把原本会的繁体中文忘掉。
这个现象叫:
Catastrophic Forgetting,灾难性遗忘。
模型只在一个很窄的数据集继续训练时:
粤字变强了
↓
普通中文却变差
这就是我们要避免的。
29. 非常重要:Test Set 永远不要参与训练
我们把数据分成:
Training Set
用于真正更新模型参数。
Validation Set
训练过程中用于:
- 选择最佳 checkpoint;
- 判断过拟合;
- 调 Learning Rate;
- 调 Epoch。
Test Set
最终考试。
原则:
Test Set 不参与训练,也不参与超参数选择。
否则属于:
Data Leakage —— 数据泄漏。
也就是模型间接“看过考试答案”。
30. Dataset Split 不要按图片随机分
影视字幕特别容易犯这个错误。
假设:
Episode 01
同一句字幕停留 2 秒
你抽出 20 帧。
如果随机分:
Frame 1 → Train
Frame 2 → Train
Frame 3 → Test
Train 和 Test 几乎一模一样。
测试成绩就会虚高。
正确方法
按照:
视频
节目
Episode
Source
切分。
例如:
Episode 01–08 → Train
Episode 09 → Validation
Episode 10 → Test
更严格的是:
节目 A → train
节目 B → validation
节目 C → cross-domain test
31. Phase 12:建立真实字幕训练数据
PaddleOCR Recognition 模型要的数据不是:
1920×1080 完整画面
而是:
已经裁好的文字行
例如:
000001.png
┌────────────────┐
│ 我唔知佢去咗邊 │
└────────────────┘
标签:
我唔知佢去咗邊
32. 每个训练样本应该保存什么 Metadata?
不要只有:
000001.jpg
建议维护一个:
metadata.jsonl
或者:
samples.csv
每个样本至少包括:
sample_id
image_path
label
source_video
episode
timestamp
resolution
subtitle_line
split
ocr_prefill
verified
其中:
verified
表示:
人类是否已经确认 Ground Truth。
33. 为什么不能让 Codex 自动生成所有真实 GT?
因为如果:
原 OCR:
係咪架
真实图片:
係咪㗎
然后 Codex直接把 OCR 结果当 Ground Truth:
模型就会继续学习:
㗎 → 架
所以:
OCR 可以做预标注。
但是:
真实 Ground Truth 必须由人确认。
34. 最理想的标注工作流
真实字幕截图
↓
原 PP-OCRv5 自动识别
↓
生成预填文本
↓
人工逐条确认/修改
↓
verified=true
↓
进入 Dataset
这样你不用从空白开始输入。
35. 这部分强烈建议 Codex 给你写标注 GUI
GUI:
Graphical User Interface,图形界面。
我们不需要你学习 Web 前后端。
让 Codex写一个简单本地工具。
Prompt:
请给这个 OCR 项目写一个人工校对工具。
技术要求:
1. Python。
2. 只在本机运行。
3. 可以使用 Tkinter 或非常简单的本地 GUI。
4. 上方显示字幕 crop 图片。
5. 下方显示 PP-OCRv5 预识别文本。
6. 我可以直接编辑文本。
7. Enter 保存并进入下一张。
8. 支持上一张。
9. 支持标记“无法辨认/排除”。
10. 自动保存进度。
11. 所有文本 UTF-8。
12. 保存原始 OCR prediction 和人工 Ground Truth。
13. 不允许自动把简体转繁体。
14. 不允许自动做粤语正字纠错。
15. 保存 Unicode code point 信息,方便发现异体字。
36. 第一批真实数据需要多少?
不要第一天追求 50 万。
建议:
Benchmark
至少:
500~1000 行
而且必须高质量人工审核。
第一版 Train
理想:
3000~10000 行真实字幕
如果暂时没有:
500~2000 行真实
+
大量 synthetic
也可以先验证 Fine-tuning。
37. Synthetic Data 是什么?
Synthetic:
人工程序生成的训练数据。
例如我们知道字符串:
你喺度做咩呀
然后程序自己:
- 选择字体;
- 选择背景;
- 写上文字;
- 描边;
- 模糊;
- JPEG 压缩;
生成:
┌──────────────────┐
│ 你喺度做咩呀 │
└──────────────────┘
因为文字是程序自己写上去的,所以 Ground Truth 天然就是:
你喺度做咩呀
不需要人工标注。
38. Synthetic Data 的核心价值
特别适合训练:
㗎
㖭
噃
喺
嘅
嚟
啲
咗
冇
佢
畀
攞
搵
等低频字符。
例如:
真实数据中:
㗎
只有 37 次。
可以 synthetic 生成:
1000 次
让模型反复看到。
39. 但 Synthetic 不能替代真实字幕
这里有一个概念:
Domain Gap,领域差异。
Synthetic:
干净字体
理想描边
人工 blur
真实视频:
H.264/H.265 压缩
运动背景
锐化
重编码
Halo
Chroma bleeding
截图缩放
实际字幕渲染器
两者不同。
所以不要:
100% Synthetic
然后声称模型真实视频很好。
40. 第一版数据比例
可先从:
Real 70%
Synthetic 30%
或者真实数据非常少时:
Real 50%
Synthetic 50%
开始。
之后通过 benchmark 判断。
41. Synthetic Renderer 适合完全交给 Codex
要求 Codex 实现:
scripts/generate_synthetic.py
至少支持:
- 随机真实视频背景;
- 白字;
- 黄字;
- 黑描边;
- 阴影;
- 多字号;
- 多字体;
- Blur;
- Gaussian Noise;
- JPEG Compression;
- Downscale → Upscale;
- Brightness;
- Contrast;
- 轻微锐化;
- 字幕边缘 aliasing;
- Rare character oversampling。
不要一开始加入:
- 30°旋转;
- 巨大透视;
- 极端扭曲;
因为真实影视字幕通常不会那样。
42. 字体问题
粤字训练不能只看:
文字字符串
还要有:
能真正渲染这些 Unicode Character 的 Font。
如果字体没有:
𠵱
生成出来可能是:
□
也就是 tofu / missing glyph。
所以 Codex 生成 synthetic 前必须:
检查字体是否真的覆盖目标字符。
要求它输出:
font_coverage.csv
例如:
font_name,char,U+codepoint,supported
FontA,㗎,U+35CE,true
FontA,𠵱,U+20D71,false
43. Phase 13:粤语 Character Audit
这是整个项目非常关键的一步。
PP-OCRv5 使用:
ppocr/utils/dict/ppocrv5_dict.txt
官方配置中 character_dict_path 就指向这个 dictionary。(GitHub)
43.1 Dictionary 在 OCR 中是什么?
Recognition 最后输出的不是直接 Unicode 字符。
它内部类似:
class 00001
class 00002
class 00003
...
Dictionary 建立:
index → character
关系。
例如概念上:
100 → 你
101 → 我
102 → 佢
所以:
模型想识别一个字符,该字符原则上必须存在于输出字符空间。
44. 不要第一天直接改 Dictionary
因为一旦改变字符数量:
模型最后输出层的:
Output Dimension
也可能改变。
例如:
18382 classes
变成:
18412 classes
这可能导致:
官方 pretrained classifier head 与新模型 output shape 不兼容。
所以第一阶段:
先检查,后修改。
45. 让 Codex 写字符审计工具
要求:
scripts/audit_charset.py
读取:
PP-OCRv5 官方 dictionary
+
所有 train labels
+
所有 validation labels
+
所有 test labels
输出:
reports/charset_audit.csv
字段:
character
unicode
frequency_train
frequency_val
frequency_test
in_ppocrv5_dict
example_labels
46. 加入 HKSCS 数据
HKSCS:
Hong Kong Supplementary Character Set,《香港增补字符集》。
香港政府当前 HKSCS-2016 有 5,033 个字符,其中 4,591 个为中文字符,并且官方说明其中一类就是“粤方言用字”。官方也提供 JSON 数据、粤语读音和相关字符资料。(香港中文大学)
注意:
我们不是把全部 5,033 字无脑塞进模型。
而是建立:
Target Cantonese Character List
优先支持真正会出现在影视字幕里的字。
47. Character Audit 最终把字分三类
A 类
字典已有
+
数据很多
不特殊处理。
B 类
字典已有
+
模型容易认错
这是 v0.1 微调重点。
例如:
係 / 喺
黎 / 嚟
架 / 㗎
既 / 嘅
左 / 咗
C 类
目标需要
+
官方字典不存在
这类不要混进第一次训练。
做成:
v0.2 Character Expansion。
48. Phase 14:建立 Master Dataset
不要手工维护:
train_list.txt
val_list.txt
test_list.txt
三套独立真相。
应该有一个唯一 Source of Truth:
metadata.jsonl
然后 Codex 生成:
train_list.txt
val_list.txt
test_list.txt
这样可以减少:
- 标签不一致;
- 同一图片进入多个 split;
- 路径错误。
49. PaddleOCR Recognition Label 格式
官方格式本质上:
图片路径<TAB>标签
例如:
train/000001.png 我唔知佢去咗邊
train/000002.png 你喺度做咩
注意中间是:
真正的 Tab Character。
不是多个空格。(GitHub)
50. Dataset Validator 必须有
让 Codex 写:
scripts/validate_dataset.py
检查:
- 图片是否存在;
- 图片能否读取;
- 图片 width/height > 0;
- label 是否为空;
- 是否含 Tab;
- UTF-8 是否正常;
- Unicode 是否可解码;
- label 是否超过
max_text_length; - 是否出现 dictionary 外字符;
- 同一图片是否重复;
- train/val/test 是否重复;
- perceptual duplicate 是否跨 split;
- 是否存在相同 source 跨 split。
最后必须:
VALIDATION PASS
才允许训练。
51. Perceptual Duplicate 是什么?
完全一样的图片可以用文件 hash 查。
但视频相邻帧可能:
像素略有不同
内容几乎完全相同
所以需要:
Perceptual Hash,感知哈希。
它把图片视觉内容变成一个简短 fingerprint。
两张图:
pHash distance 很小
说明视觉上高度相似。
防止:
Train frame 100
Test frame 101
这种隐性数据泄漏。
52. Phase 15:跑原模型 Baseline
这是:
微调前考试。
模型:
官方 PP-OCRv5_server_rec
测试:
cantonese_in_domain_test
cantonese_cross_domain_test
general_traditional_test
53. 我们不用只看 Accuracy
至少计算四类指标。
53.1 Exact Line Accuracy
整行完全正确才算正确。
GT:
我唔知佢去咗邊
Prediction:
我唔知佢去左邊
即使只有一个字错:
该整行 = Wrong
这是很严格的指标。
53.2 CER
CER:
Character Error Rate,字符错误率。
基于:
Levenshtein Edit Distance,编辑距离。
包含:
- Substitution:替换;
- Deletion:漏字;
- Insertion:多字。
公式:
CER = (S + D + I) / N
例如:
GT:
去咗邊
Prediction:
去左邊
一个 substitution。
53.3 Target Character Accuracy
专门测:
喺
嘅
咗
㗎
嚟
啲
这对你的项目比普通总 Accuracy 更重要。
53.4 Confusion Matrix
统计:
喺 → 係 48次
㗎 → 架 21次
嚟 → 黎 17次
咗 → 左 14次
这样我们真正知道:
模型哪里弱。
54. 让 Codex 写统一 evaluator
要求:
scripts/evaluate.py
输入:
model
dictionary
test dataset
输出:
metrics.json
predictions.csv
confusions.csv
errors.html
其中 errors.html 最好:
图片
GT
Prediction
错误字符
这样你直接浏览错误样本。
55. Phase 16:建立 Fine-tuning YAML
YAML 是什么?
YAML 是:
一种人类较容易阅读的 Configuration File 格式。
它不是程序逻辑。
用来写:
learning_rate: 0.00001
batch_size: 32
epoch_num: 15
PaddleOCR大量训练配置使用 YAML/YML。
56. 不要直接修改官方 PP-OCRv5 YAML
复制:
configs/rec/PP-OCRv5/PP-OCRv5_server_rec.yml
到我们自己的:
cantonese-ocr/configs/
ppocrv5_server_cantonese_v01.yml
Codex负责修改。
57. 第一版建议参数
核心概念先解释。
Epoch
一个 Epoch:
整个 Training Set 基本被模型看过一次。
如果:
10000 samples
跑 10 Epoch:
理论上每个样本会参与多轮训练。
Learning Rate
Learning Rate:
每次更新权重时,更新步子有多大。
过大:
模型快速破坏已有能力
loss 震荡
过小:
学习非常慢
Fine-tuning 通常比从零训练:
使用更小 Learning Rate。
PP-OCRv5 官方训练配置原始 LR 是 0.0005。(GitHub)
我们第一次 Fine-tune 可以从:
0.00001
即:
1e-5
开始。
58. v0.1 建议 YAML 核心
示意:
Global:
# 训练轮数。第一次 fine-tuning 不需要照官方预训练那样跑很久。
epoch_num: 15
# 使用 GPU。
use_gpu: true
# 单 GPU,不使用 distributed training。
distributed: false
# 官方 PP-OCRv5 预训练权重。
pretrained_model: ../../artifacts/pretrained/PP-OCRv5_server_rec_pretrained.pdparams
# 不使用断点续训 checkpoint。
checkpoints:
# 保存我们自己的训练结果。
save_model_dir: ../../artifacts/runs/cantonese_v01
# 第一版保持官方 PP-OCRv5 dictionary,不扩字符。
character_dict_path: ./ppocr/utils/dict/ppocrv5_dict.txt
# 先保持 25。如果真实字幕大量超过 25,再单独处理。
max_text_length: 25
Optimizer:
name: Adam
lr:
name: Cosine
# 微调采用更低学习率。
learning_rate: 0.00001
warmup_epoch: 1
59. Adam 是什么?
Adam:
一种 Optimizer,优化器。
Optimizer 决定:
Loss
↓
Gradient
↓
应该怎样修改模型参数
你暂时不需要自己推导 Adam 数学公式。
第一版:
保持官方 Adam。
不要:
同时换模型
同时换 Optimizer
同时换 Loss
同时换数据
否则出现变化时你不知道原因。
60. Cosine Learning Rate 是什么?
训练过程中 Learning Rate 不一定固定。
Cosine Scheduler:
用类似余弦曲线逐渐降低 Learning Rate。
开始:
1e-5
后期越来越小。
这样后期参数更新更细。
保持官方设计即可。
61. Batch Size 配置
PP-OCRv5 config 使用 MultiScaleSampler。
里面有:
first_bs: &bs 128
YAML 中:
&bs
叫:
Anchor。
后面:
*bs
代表引用它。
所以 Codex修改 Batch 时:
不要只改一个地方然后留下不一致。
建议第一版:
first_bs: &bs 32
62. num_workers 是什么?
DataLoader:
训练时负责不断从磁盘读取图片、做 preprocessing,并送给 GPU。
num_workers:
同时有多少个 CPU Worker 帮忙准备数据。
你是 8940HX + 32GB RAM。
第一版:
4
或者:
6
即可。
不要一开始开:
16
32
因为可能增加内存压力和 WSL file I/O 问题。
63. Phase 17:第一次真正训练之前先做 100~300 Step Smoke Training
目的不是获得好模型。
只证明:
Dataset 正确
↓
Dictionary 正确
↓
Pretrained weights 正确加载
↓
Forward 正常
↓
Backward 正常
↓
Loss 正常
↓
Checkpoint 正常
观察:
loss
应该总体有下降趋势。
不是每一步都严格下降。
64. Loss 是什么?
Loss:
模型 prediction 与正确答案之间差距的数学量。
训练就是不断:
minimize loss
如果:
Loss = NaN
说明计算出现异常。
如果:
Loss 完全不变
通常说明训练有问题。
65. 正式训练命令
假设 Codex 已经生成:
../../configs/ppocrv5_server_cantonese_v01.yml
进入 PaddleOCR:
# cd:切换到 PaddleOCR 源码根目录。
# PaddleOCR 的 tools/train.py 和相对路径配置以这里为基准最稳定。
cd ~/projects/cantonese-ocr/third_party/PaddleOCR
运行:
# python3:使用当前 virtual environment 的 Python。
# tools/train.py:PaddleOCR 官方训练入口程序。
# -c:configuration 的缩写,指定训练使用的 YAML 配置文件。
# ../../configs/...:我们自己维护的 Cantonese fine-tuning 配置。
python3 tools/train.py -c ../../configs/ppocrv5_server_cantonese_v01.yml
这就是你真正的 Fine-tuning。
66. 训练时你应该看什么?
不要盯着屏幕上所有数字。
重点看:
GPU
GPU utilization
VRAM usage
Loss
总体应该下降。
Validation Accuracy
总体应该改善后趋于稳定。
Validation Edit Distance
应该改善。
有没有 OOM / NaN
绝对不能忽略。
67. 训练不是 Epoch 越多越好
假设:
Epoch 1 Val CER 4.2%
Epoch 5 Val CER 2.6%
Epoch 9 Val CER 2.3%
Epoch 15 Val CER 3.1%
说明后面可能:
Overfitting——过拟合。
68. Overfitting 是什么?
模型过度记住 Training Data:
Train 越来越好
Validation 开始变差
说明它没有真正学到泛化规律。
所以:
最佳 checkpoint 不一定是最后一个 epoch。
69. Phase 18:正式 Benchmark 微调结果
必须比较:
Baseline
vs
Cantonese v0.1
同一个 test set。
输出表类似:
| Metric | Baseline | v0.1 |
|---|---|---|
| Cantonese CER | 5.2% | 2.7% |
| Exact Line Accuracy | 71.4% | 83.6% |
| 喺 accuracy | 82% | 96% |
| 嘅 accuracy | 88% | 97% |
| 㗎 accuracy | 61% | 91% |
| General Traditional CER | 1.8% | 1.9% |
重点不是这些示例数字本身。
重点是:
用这样的结构判断。
70. 什么情况下 v0.1 才算成功?
至少满足:
Cantonese
CER 明显下降。
Target Character
主要粤字明显改善。
General Traditional
没有出现不可接受的大幅下降。
Cross-domain
不是只在一个节目有效。
71. Phase 19:Error Mining
以后真正提升模型,靠的不是:
“再多跑 20 Epoch。”
而是:
Error Mining——错误样本挖掘。
流程:
跑大量真实视频
↓
收集 OCR 错误
↓
按错误类型统计
↓
加入训练数据
↓
再次 Fine-tune
例如发现:
㗎 → 架
特别多。
就加入:
更多真实 㗎
+
更多 synthetic 㗎
72. 建议建立 Hard Samples 数据库
Hard Sample:
当前模型特别容易识别错的样本。
例如:
低清
黄色字幕
复杂背景
高压缩
稀有粤字
目录:
data/hard_samples/
每次版本:
v0.1 errors
v0.2 errors
...
持续加入。
73. Phase 20:防止灾难性遗忘
不要只训练:
㗎㗎㗎
喺喺喺
嘅嘅嘅
否则模型可能失去普通中文字能力。
训练集最好混入:
一般繁体中文
+
普通粤语字幕
+
Rare Cantonese
+
Synthetic Hard Samples
也就是:
Replay / mixed-domain fine-tuning。
74. Phase 21:真正处理 Dictionary Missing Character
只在 Character Audit 确认后进行。
假设:
目标 Character:X
不在官方 dictionary。
这时:
v0.2
再做:
Character Set Expansion。
75. 扩 Dictionary 的原则
新 dictionary:
cantonese_ppocrv5_dict.txt
不要:
重新排序全部字符。
优先保持:
原官方字符顺序
+
末尾 append 新字符
这样已有字符 index 至少保持不变。
但是:
新增字符依然可能改变输出 head dimension。
所以这一阶段不能简单“加几行就行”。
让 Codex先:
- 检查官方 checkpoint load log;
- 检查哪个 output layer shape mismatch;
- 确认 PaddleOCR 当前版本如何处理 mismatched parameters;
- 写一个最小实验;
- 验证旧字符权重有没有被错误丢弃。
这是 v0.2,不属于第一次 2 小时实验。
76. 特别提醒:不要为了 HKSCS 全覆盖,直接追求 5000 字
HKSCS 包含:
- 粤方言字;
- 人名;
- 地名;
- 科学名词;
- 部件;
- 各种符号。
你的任务是:
粤语影视字幕 OCR。
不是:
香港政府所有电子字符 OCR。
所以实际:
Corpus frequency
+
Error frequency
+
业务需求
比:
是否属于 HKSCS
更重要。
77. Phase 22:导出 Inference Model
训练保存的模型和最终使用的模型不是完全同一种形式。
Inference Model:
为实际预测/部署准备的固定模型。
当前官方 PP-OCRv5 导出后通常得到:
inference.json
inference.pdiparams
inference.yml
(GitHub)
进入 PaddleOCR:
# cd:进入 PaddleOCR 源码目录。
cd ~/projects/cantonese-ocr/third_party/PaddleOCR
运行:
# python3:当前 virtual environment Python。
# tools/export_model.py:PaddleOCR 官方模型导出程序。
# -c:指定我们训练时使用的 YAML。
# -o:override,即临时覆盖 YAML 中的某些配置值。
#
# Global.pretrained_model=...:
# 指定要导出的训练权重,这里应替换成实际 best_accuracy checkpoint 路径。
#
# Global.save_inference_dir=...:
# 指定导出的 inference model 保存目录。
python3 tools/export_model.py -c ../../configs/ppocrv5_server_cantonese_v01.yml -o Global.pretrained_model=../../artifacts/runs/cantonese_v01/best_accuracy.pdparams Global.save_inference_dir=../../artifacts/exports/cantonese_v01
注意:
实际
best_accuracy文件名以你的训练输出为准,让 Codex先检查目录,不要盲抄路径。
78. 导出以后必须重新 Benchmark
这是很重要的工程习惯:
Training checkpoint
测一次。
然后:
Exported inference model
再测一次。
两者结果应该基本一致。
如果完全不同:
最常见问题之一就是:
Dictionary 或 preprocess config 不一致。
PaddleOCR 官方 FAQ 也特别强调,自定义 dictionary 必须在训练与推理阶段保持一致。(GitHub)
79. Phase 23:给模型建立版本档案
每个版本都不要只保存:
best_accuracy.pdparams
完整保存:
artifacts/releases/cantonese-ocr-v0.1/
│
├── model/
├── config.yml
├── dictionary.txt
├── metrics.json
├── charset_audit.csv
├── confusions.csv
├── requirements.txt
├── environment.json
├── git_commit.txt
├── dataset_manifest.json
└── README.md
80. 为什么这叫“模型工程”,而不只是跑训练?
因为六个月后你要能回答:
这个模型用什么代码训练的?
Paddle 什么版本?
什么数据?
什么字典?
多少 Epoch?
哪个 LR?
哪个 benchmark?
为什么说它比旧版好?
如果答不出来:
模型不可复现。
81. Phase 24:最终视频字幕 Pipeline
Recognition Model 完成后:
Video
↓
Frame Extraction
↓
Subtitle ROI Crop
↓
Text Detection
↓
Text Recognition
↓
Temporal Voting
↓
Subtitle Segment Merge
↓
Optional Cantonese Normalization
↓
SRT / ASS
82. Frame Extraction
不用每一帧都 OCR。
60fps 两秒:
120 frames
但字幕可能完全没变化。
可以:
2~5 fps OCR
或者检测字幕区域变化。
83. Temporal Voting
例如同一句字幕识别 7 次:
我唔知佢去咗邊
我唔知佢去咗邊
我唔知佢去左邊
我唔知佢去咗邊
我唔知佢去咗邊
我唔知佢去咗邊
我唔知佢去咗邊
多数票:
我唔知佢去咗邊
这个会非常适合视频 OCR。
84. Phase 25:粤语正字规范化应该放这里
OCR 输出:
我係屋企
如果你确定项目目标还包括语言规范化:
OCR Text
↓
Cantonese Normalizer
↓
我喺屋企
Normalizer 可以以后采用:
- Rules;
- Cantonese dictionary;
- Language Model;
- Small LLM;
- Context-aware correction。
但必须与视觉 OCR 分开评估。
85. 你和 Codex 最合适的实际工作模式
你做
主要负责:
1. 定义目标
什么叫正确。
2. Ground Truth
确认真实标签。
3. 观察 Sample
模型为什么错。
4. 判断指标
是否真的改善。
5. 决策
下一轮加入什么数据。
Codex 做
1. 环境检查
读取版本、跑 doctor。
2. Python 工具
写:
extract
crop
dedupe
audit
validate
evaluate
render synthetic
3. YAML
修改 config。
4. 自动化
数据转换。
5. 跑训练
执行命令。
6. Log 分析
发现 OOM、NaN、pretrained parameter mismatch。
7. 报告
生成 metrics。
86. 不要这样使用 Codex
不要说:
帮我把 OCR 微调好。
这种 Prompt 太宽。
应该:
现在只做 Dataset Validator。
不修改训练配置。
先检查 train/val/test leakage。
输出报告。
遇到问题不要自动删除数据。
也就是:
一次交给 Codex 一个清晰阶段。
87. 我建议你的 Codex 工作纪律
每个阶段要求 Codex:
1. 先说明准备修改哪些文件。
2. 不修改 third_party/PaddleOCR 官方源代码。
3. 每次修改后运行测试。
4. 保存 log。
5. 出错时先解释 root cause。
6. 不要靠反复随机升级依赖解决问题。
7. 不要自动升级 Paddle/PaddleOCR。
8. 不要自动修改 Ground Truth。
9. 不确定数据时停止并标记。
10. 给出 git diff。
这会极大减少 AI coding agent 把项目越修越乱的概率。
88. 第一次训练时推荐的 Codex Prompt
你可以直接给它:
你现在是这个项目的训练工程助手。
项目目标:
使用 PaddleOCR v3.7.0 中的 PP-OCRv5_server_rec,对香港粤语影视字幕 Recognition 任务进行 fine-tuning。
环境:
Windows 11 主机;
WSL2 Ubuntu 24.04;
NVIDIA RTX 5070 Ti Laptop;
单 GPU;
Python virtual environment;
PaddlePaddle GPU cu129。
限制:
1. 不修改 PaddleOCR third_party 官方源码。
2. 不升级已固定的软件版本。
3. 不修改 Ground Truth。
4. 不修改官方 ppocrv5_dict.txt。
5. 配置全部放在项目 configs。
6. 训练输出全部放 artifacts/runs。
7. 所有实验保存完整 log。
8. 先运行 dataset validator。
9. 再运行 charset audit。
10. 然后做 100~300 step smoke training。
11. smoke test 成功后才允许跑正式 training。
12. 如果 GPU OOM,先把 batch size 降低,而不是修改模型结构。
13. 如果出现 pretrained parameter mismatch,停止训练并报告具体 parameter names 和 shapes。
14. 训练完成后运行统一 benchmark。
15. 输出 baseline 和 fine-tuned 的 CER、exact line accuracy、target-character accuracy、confusion matrix。
89. 常见故障:GPU 没被使用
现象:
CPU 100%
GPU 0%
检查顺序:
nvidia-smi
↓
doctor.py
↓
paddle.device.get_device()
↓
paddle.is_compiled_with_cuda()
↓
cu129 Paddle wheel
不要第一反应:
“安装另一个 CUDA Toolkit”。
90. 常见故障:Unsupported GPU Architecture
因为:
5070 Ti = Blackwell sm_120
首先确认:
WSL Linux
Paddle 3.3.x
cu129
最新 NVIDIA Windows Driver
不要退到旧:
CUDA 11.8
Paddle 当前表对 sm_120 推荐的是 CUDA 12.9/13.0。(飞桨)
91. 常见故障:CUDA OOM
处理顺序:
Batch 32
↓
24
↓
16
如果还 OOM:
再检查:
- 是否有其他 GPU 程序;
- 是否同时启动两个 training;
- 是否 Windows 端其他 AI 程序占显存。
92. 常见故障:Accuracy 接近 0
重点检查:
label file 格式
Tab 分隔
character_dict_path
max_text_length
图片路径
dictionary missing character
encoding
而不是马上增加 Epoch。
93. 常见故障:Train 很好,Validation 很差
大概率:
Overfitting。
处理:
- 更多真实数据;
- 减少 Epoch;
- 更低 Learning Rate;
- 更合理 augmentation;
- 检查 Train/Validation domain 是否差异过大。
94. 常见故障:粤字变好,但普通中文变差
这是:
Catastrophic Forgetting。
处理:
Cantonese samples
+
General Traditional replay data
重新微调。
同时继续保留:
general_traditional_test
95. 常见故障:Synthetic 非常好,真实视频很差
这是:
Domain Gap。
说明 synthetic 太干净。
解决不是:
继续生成 100 万张一样的 synthetic
而是:
更多真实字幕
+
更真实的 backgrounds/compression/fonts
+
Hard Sample Mining
96. 2 小时版本到底能做到哪里?
如果你今天从完全没有环境开始:
前 0~30 分钟
目标:
WSL
+
GPU
+
Python venv
30~60 分钟
目标:
Paddle
+
PaddleOCR
+
PP-OCRv5 pretrained
+
doctor PASS
60~90 分钟
目标:
官方 demo smoke test
+
跑自己的几十/几百条 benchmark
90~120 分钟
如果你已经有:
几百~一两千条正确标注的 crop
可以:
smoke fine-tune
+
保存第一个 checkpoint
+
简单 baseline comparison
97. 如果你现在完全没有标注数据
两小时内现实目标应该变成:
环境跑通
+
原模型 Benchmark
+
标注工具完成
+
Character Audit 完成
+
Synthetic Generator 初版
而不是:
强行产生一个“完成的粤语模型”。
因为没有 Ground Truth 的情况下:
训练速度没有意义。
98. 第一版真正实用模型的现实时间
以你有 Codex 为前提:
环境和 pipeline
半天以内基本可以搞定。
建好 500~1000 条可靠 Benchmark
通常比安装环境更耗人。
3000~10000 条高质量真实字幕
这才是真正的大头。
如果有 soft subtitle 可以自动对齐,会快非常多。
Synthetic Pipeline
Codex 很适合帮你一天内做得比较完整。
Training
反而往往是整个项目最简单的一段。
真正时间主要花在:
Dataset + Error Analysis。
99. 你第一周真正应该追求什么?
不要追求:
99.999% Accuracy
而是完成闭环:
Data
↓
Train
↓
Evaluate
↓
Find Errors
↓
Add Data
↓
Train Again
只要这个闭环建立起来:
模型后续就可以稳定迭代。
100. Version Roadmap
建议:
v0.0
原版 PP-OCRv5 baseline
v0.1
官方 dictionary
+
common Cantonese fine-tuning
v0.2
hard sample mining
+
更多真实数据
v0.3
rare character / HKSCS character expansion
v0.4
cross-domain subtitle styles
v0.5
video temporal voting
v1.0
稳定字幕 OCR pipeline
101. 到什么时候才考虑 PP-OCRv6?
等:
v0.1 pipeline
完全跑通以后。
因为当前 PaddleOCR 3.7.0 已经包含 PP-OCRv6,官方称其中 medium recognition 的综合精度高于 PP-OCRv5_server。(GitHub)
那时做:
同一 Dataset
同一 Test Set
同一 Evaluation
比较:
PP-OCRv5_server_rec Fine-tuned
vs
PP-OCRv6_medium_rec Fine-tuned
谁真正对粤语字幕强,就用谁。
不是因为:
“v6 数字比较大”。
102. 最终验收标准
当你的项目能够做到下面这些,就可以认为第一阶段真正完成:
[ ] WSL2 GPU 稳定
[ ] doctor.py PASS
[ ] 固定 PaddleOCR/Paddle 版本
[ ] 官方模型 baseline 已记录
[ ] Ground Truth policy 已固定
[ ] Train/Val/Test 无泄漏
[ ] Character Audit 完成
[ ] 官方 dictionary coverage 已知
[ ] Synthetic renderer 可工作
[ ] Training smoke test PASS
[ ] Full fine-tune 可重复
[ ] Best checkpoint 可定位
[ ] CER 自动计算
[ ] Cantonese confusion matrix 自动计算
[ ] General Traditional retention 有测试
[ ] Exported inference model 可运行
[ ] Export 前后精度一致
[ ] 每个版本都有 manifest
[ ] 实际视频 OCR 可以调用模型
做到这里,你已经不只是:
“跟教程跑过一次 Fine-tuning”。
而是真正建立了:
一个可持续迭代的粤语 OCR 模型研发流程。
103. 你现在实际应该执行的顺序
第一天不要想着一口气做到 v1。
严格按照:
① WSL2
↓
② GPU
↓
③ Python venv
↓
④ Paddle cu129
↓
⑤ PaddleOCR v3.7.0
↓
⑥ doctor PASS
↓
⑦ 官方 PP-OCRv5 demo smoke test
↓
⑧ 建 500~1000 条 Benchmark
↓
⑨ 跑官方模型 Baseline
↓
⑩ Character Audit
↓
⑪ 准备第一批 Train Data
↓
⑫ 100~300 step Fine-tune Smoke Test
↓
⑬ Full Fine-tune
↓
⑭ Benchmark
↓
⑮ Error Mining
其中真正不能让 Codex替你做决定的主要是:
Ground Truth
Benchmark 是否公平
哪些错误值得修
最终模型是否达到你的使用要求
剩余绝大部分机械工程工作,都非常适合交给 Codex。
:::
这份路线里最重要的技术选择,是先保持 PP-OCRv5 官方字符字典不变,先把常见粤字“认错”问题做好,再单独处理字典中完全不存在的 HKSCS/罕见字符。这样你第一次微调不会同时碰到“训练 + 新字符输出层 + checkpoint shape 不匹配”三个问题。
如果按这套路线正式开始,你现在的第一个实际动作就是 Phase 1~10:把 WSL/Paddle/PaddleOCR/官方 PP-OCRv5 smoke test 跑通;在这一步成功前,不值得花时间生成几万张训练数据。
