在端侧 OCR 工程中,我们的目标非常明确:在精度损失 < 1% 的前提下,将模型体积压缩 10 倍,推理速度提升 5 倍。
这需要一套完整的 “瘦身” 方法论。
1. 数据工程:用“假数据”喂出“真模型” (Synthetic Data)
训练 OCR 最难的是 数据。营业执照涉及隐私,你不可能从网上爬 100 万张真实的执照来训练。
解决方案:合成数据(Data Synthesis)。
我们不需要真实图片,我们需要 “看起来像真的” 图片。
- 字体库(Fonts):营业执照的字体非常固定。主要是 宋体(SimSun)(正文)、黑体(SimHei)(标题)、以及特定的数字字体。收集这 5-10 种字体就够了。
- 语料库(Corpus):
- 企业名:从天眼查/企查查爬取 10 万个真实企业名。
- 地址:使用行政区划生成器生成标准地址。
- 经营范围:爬取真实的经营范围文本。
- 渲染引擎(Renderer):使用
TextRenderer或SynthText工具。- 背景增强:随机加入噪点、折痕、阴影、水印背景。
- 透视变换:随机进行旋转、拉伸,模拟手机拍摄的角度。
工程价值:通过合成 500 万张虚拟执照图片,我们解决了 90% 的训练数据问题。剩下的 10% 用真实数据微调(Fine-tune)。
2. 词表剪枝:只学该学的字 (Vocabulary Pruning)
通用的中文 OCR 模型通常使用 PP-OCR 字典,包含 6623 个字符。
但在营业执照上,很多字是永远不会出现的(比如生僻字、古文、表情符号)。
工程策略:
- 统计词频:扫描那 10 万个真实企业名和经营范围,统计所有出现过的汉字。
- 构建白名单:
- 保留常用汉字(约 2500 个)。
- 保留所有数字、英文字母、全半角标点。
- 特供字:手动加入“()”、“:”、“统一社会信用代码”等高频关键词。
- 结果:将分类头(Classification Head)的大小从 6623 缩减到 3000 左右。这直接减少了模型最后一层的参数量和计算量。
3. 骨干网络:轻量化的选择 (Backbone Selection)
不要在端侧用 ResNet50 或 VGG。那是大炮打蚊子。
我们需要 MobileNetV3 或 ShuffleNetV2。
模型架构设计 (CRNN 变体):
- Backbone: MobileNetV3-Small (去掉最后的几层,保留特征提取能力)。
- Neck: 这里的 Bi-LSTM(双向长短期记忆网络)通常比较耗时。在营业执照这种短文本场景下,可以裁剪层数,甚至用 1D-CNN 代替 RNN,牺牲一点点长文本语义,换取极大的速度提升。
- Head: CTC (Connectionist Temporal Classification) Loss。
目标体积:FP32 模型大小控制在 8MB 以内。
4. 知识蒸馏:大模型教小模型 (Knowledge Distillation)
小模型(Student)虽然快,但容易“学不透”。
我们需要一个大模型(Teacher,比如 100MB 的 ResNet 版 OCR)来教它。
训练策略:
- Teacher:先训练一个高精度的大模型,准确率 99.5%。
- Student:我们那个 5MB 的小模型。
- Loss Function:$$L = \alpha \cdot L_{CTC}(Student, GT) + \beta \cdot L_{KL}(Student, Teacher)$$让 Student 不仅学习 Ground Truth(真值),还要模仿 Teacher 的输出概率分布(Soft Targets)。Teacher 认为这就该是“A”,Student 就更容易学确信。
工程价值:通过蒸馏,小模型的准确率通常能提升 2-3 个百分点,逼近大模型。
5. 部署落地:量化与推理引擎 (Quantization & Inference)
训练完模型只是第一步,跑在手机上才是本事。
- 模型转换 (Converter):
- PyTorch -> ONNX -> NCNN / MNN / TNN。
- 推荐腾讯的 NCNN 或阿里的 MNN,它们针对 ARM 架构(Android/iOS)做了极致的汇编级优化。
- INT8 量化 (Quantization):
- 使用 Post-Training Quantization (PTQ)。
- 将 FP32(32位浮点数)权重转换为 INT8(8位整数)。
- 效果:模型体积直接 减半(从 8MB -> 4MB),推理速度在 NPU 上提升 2-3 倍。
- 注意:OCR 对精度敏感,量化时需要校准(Calibration),确保精度下降在可接受范围内(<0.5%)。
6. 总结
训练一个 “营业执照OCR识别” 专用模型,本质上是一场 “断舍离” 的工程实践。
- 舍弃 真实数据的依赖,拥抱合成数据。
- 舍弃 通用的大词表,构建专用小词表。
- 舍弃 笨重的 Backbone,选择 MobileNet。
- 舍弃 浮点数精度,拥抱 INT8 量化。
最终,你交付给 App 开发团队的,不是一个庞然大物,而是一个 5MB 的 .bin 文件。
它在千元机上也能实现 50ms 的极速识别。这就是端侧 AI 工程师的“工匠精神”。