用PPOCRLabel來幫PaddleOCR做OCR的微調和標註

Paddle OCR 應用場景開發微調 (官方github FAQ)
雖然這篇是在講 OCR,但多模態的大模型好像應該也得略懂 XD 所以試了一下地端佈署、Prompt、function call 再到workflow;畢竟想要讓OCR更準一點,如果有多模態協助,那效果還是挺不錯的啊 !
目前現有 PP-OCR系列模型列表:推理、訓練、預訓練,然後檢測跟識別;官方文件如下:
快速安裝:本來想用官方放的 docker,但是 root,然後改不太動,最後乾脆用自己的docker

首先就是識別,說明一下字典檔相關數據的生成,為了輸出的效果更符合目前優先的醫療收據應用場景,所以根據已搜集的7萬筆醫囑還有台灣常用字典檔做為語料庫,藉此產生大量的數據資料,來微調 ppocr-v3;這邊要怎樣生成呢 ? 可以參考 文字資料集產生(text_renderer)  或者是你前面有用 PPOCRLabelv2 標了一些數據,那麼就可以把標好的文字拿來再做數據集生成的組合


如果有整個先把前面附上的官網github連結看完,會發現在模型微調那頁有個最重要的說明:"在自己的場景中,透過模型變化,可以取得精確度較高的文字偵測與辨識模型。"以及強調了這句:"加入少量真實資料(偵測任務>=500張,辨識任務>=5000張),會大幅提升類別場景的偵測與辨識效果。"同時關於偵測模型的訓練也又說 " 選擇PP-OCRv3模型(配置:ch_PP-OCRv3_det_student.yml,預訓練模型:ch_PP-OCRv3_det_distill_train.tar)進行拓展,其精度和泛化性能是目前提供的最優化預訓練模型。" 識別模型也不例外說了 "選擇PP-OCRv3模型(設定檔:ch_PP-OCRv3_rec_distillation.yml,預訓練模型:ch_PP-OCRv3_rec_train.tar),其精確度與泛化效能是目前提供的最優預訓練模型。"個人另外發現,若是跑在 docker裡,來不及修改共享記記憶體時,可以在config裡的 data 的 loader 處補上這行 " use_shared_memory: False " 所以我的偵測和識別的訓練指令分別如下:
 
python3 -m paddle.distributed.launch --gpus '0,1,2,3' tools/train.py -c /opt/data/PaddleOCR/configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_student.yml -o Global.pretrained_model=/opt/data/PaddleOCR/pretrain_models/ch_PP-OCRv3_det_distill_train/student.pdparams

python3 tools/infer_det.py -c configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_student.yml -o Global.infer_img="/opt/data/Account-Documents/25-QR-Code/140_PXL_20240305_095734055.jpg" Global.pretrained_model="./output/ch_PP-OCR_V3_det/best_accuracy"

python3 tools/export_model.py -c /opt/data/PaddleOCR/configs/det/ch_PP-OCRv3/ch_PP-OCRv3_det_student.yml -o Global.pretrained_model="/opt/data/PaddleOCR/output/2024-05-21_ch_PP-OCR_V3_det/best_accuracy" Global.save_inference_dir="/opt/data/PaddleOCR/output/inference_2024-05-21_ch_PP-OCR_V3_det/"

python3 tools/infer/predict_det.py --det_algorithm="DB" --det_model_dir="/opt/data/PaddleOCR/output/inference_2024-05-21_ch_PP-OCR_V3_det/" --image_dir="/opt/data/PaddleOCR/inference_test/" --use_gpu=True
 
python3 -m paddle.distributed.launch --gpus '0,1,2,3' tools/train.py -c configs/rec/PP-OCRv3/ch_PP-OCRv3_rec_distillation.yml -o Global.pretrained_model=./pretrain_models/20230803/best_accuracy

python3 tools/export_model.py -c configs/rec/PP-OCRv3/ch_PP-OCRv3_rec_distillation.yml -o Global.pretrained_model=/opt/data/PaddleOCR/output/2024-05-26_ppocr_v3_rec_distillation/best_accuracy Global.save_inference_dir=/opt/data/PaddleOCR/output/inference_2024-05-26_ppocr_v3_rec_distillation/
 
python3 tools/infer/predict_system.py --image_dir="./inference_test/" --det_model_dir="./output/inference_2024-05-21_ch_PP-OCR_V3_det/" --rec_model_dir="./output/inference_2024-05-26_ppocr_v3_rec_distillation/Student/" --use_angle_cls=false --use_mp=True --total_process_num=4 --rec_char_dict_path="./configs/rec/PP-OCRv3/zhtw_common_dict.txt"

最後在V100*8的機器上費時51hr跑了100epoch,訓練acc: 0.84133,驗證acc:0.92796
來個 PaddleOCR 的 識別(REC) 訓練擷圖 ! 2023/07/15訓練集有100萬張,驗證集有1萬張。
這邊要加減補充一下 !!! 整個 PaddleOCR 就是分為 Detection (偵測,ch_PP-OCRv3_det) 跟 Recognition (識別,ch_PP-OCRv3_rec),其中,偵測又有所謂的表格,但就是要先處理識別,因為都只有簡體字 ! 經過一番實測,用 ch_PP-OCRv3_rec 並且將字典檔轉成繁體,且要注意因為字典檔內有些許繁體字,直接簡轉繁會造成重複,所以替換時要小心
最後就是到了把整個模型佈到 HuggingFace Hub 上了,像是

想用 python 直接調用自定義數據的訓練模型,但是看log最後都會變為使用官方預訓練模型 (會出現如 det=True, rec=True, type=ocr 等等,並另外本地端執行自定義數據訓練和官方預訓練模型確認是官方預訓練模型結果)。使用自訂模型

ocr = PaddleOCR(det_model_dir='{your_det_model_dir}', rec_model_dir='{your_rec_model_dir}', rec_char_dict_path='{your_rec_char_dict_path}', cls_model_dir='{your_cls_model_dir}', use_angle_cls=True)
result = ocr.ocr(img, cls=True, det=False, rec=False)

載入模型的時候報以下錯誤: ./pretrain_models/MobileNetV3_large_x0_5_pretrained/.pdparams not found, 可以參考這邊修改:下載預訓練模型

最後可以看一下這邊是怎樣計算你的模型訓練效果



WSL 安裝 PPOCRLabel。一切都是從這個神奇的需求開始的,因為要識別醫療診斷書中的醫囑內容,所以前期處理的OCR識別就非常重要,雖然 PaddleOCR (https://github.com/PaddlePaddle/PaddleOCR) 已經很強,但是卡在很多格式內容或者簡體和繁體字的問題,所以常常OCR識別後的內容就出包,然後導致醫囑的分析也就容易跟著翻車啦 (但BU端才不管你這些呢 >"<);所以只能再次抱著壯士斷腕的決心,再自己標註一次數據了 ! 那麼,值得一提的是,標註NLP的工具可以用標文字蠻不錯的 Doccano (https://github.com/doccano/doccano) 或者是可以標圖像和文字的 Label Studio (https://labelstud.io/),但是要標給OCR用,感覺上還是得用 PPOCRLabelv2但因為平常不太可能開著 Ubuntu 來工作,所以只能想辦法從 WINDOWS 10 上安裝 WSL (1或2),然後再幫它啟用桌面,然後採遠端桌面登入,接著再來安裝中文輸入法等等;總計有這幾個動作:

  • WINDOWS 10 啟用 WSL
  • WSL 啟動 Ubuntu 再啟用桌面
  • WINDOWS 10 遠端桌面至 WSL 的 Ubuntu
  • 安裝 PaddleOCR、PPOCRLabelv2 
  • 幫 WSL 的 Ubuntu 安裝繁體中文輸入法
但還是加減把 PaddleOCR 的應用場景開發過程,WINDOWS 10 安裝 PaddleOCR、PPOCRLabelv2 的一堆奇怪的問題記錄,參考文件都記錄下來吧

WINDOWS 10 啟用 WSL

先啟用 WSL 1 或 2,目前已知就是差在要怎樣直接遠端桌面,或者是透過 XLaunch來連線;我目前是啟用 WSL 2 ! 所以裝好後就是到 Microsoft 商店取得 Ubuntu 22.04.2 LTS (在上面的連結) 啦 ! 照官網所寫,其實安裝跟啟動非常簡單,然後就是設定帳號跟密碼,主要是給你能使用 sudo 這樣 ! 網上有的教學說要再另外裝 terminal,但我裝好是直接有個 Ubuntu 22.04.2 的終端機可以啟動啦 ! 

$ sudo apt update && sudo apt upgrade
$ sudo apt install -y xfce4 xrdp xfce4-goodies

再來就是要更新還有安裝遠端桌面和繁體中文輸入法所需套件,安裝xfce4過程中會出現選擇顯示管理DM選擇的提示,建議用lightdm。
$ sudo cp /etc/xrdp/xrdp.ini /etc/xrdp/xrdp.ini.bak
$ sudo sed -i 's/3389/3390/g' /etc/xrdp/xrdp.ini
$ sudo sed -i 's/max_bpp=32/#max_bpp=32\nmax_bpp=128/g' /etc/xrdp/xrdp.ini
$ sudo sed -i 's/xserverbpp=24/#xserverbpp=24\nxserverbpp=128/g' /etc/xrdp/xrdp.ini
$ echo xfce4-session > ~/.xsession
修改 xrdp 設定,並註解掉 X11 那兩行
$ sudo vi /etc/xrdp/startwm.sh
# test -x /etc/X11/Xsession && exec /etc/X11/Xsession
# exec /bin/sh /etc/X11/Xsession
然後新增 xfce 這兩行
# xfce
startxfce4
接著就是啟動 RDP 然後看狀態
$ sudo /etc/init.d/xrdp start
$ sudo /etc/init.d/xrdp status
* xrdp-sesman is running
* xrdp is running
接著就是安裝Fctix5設定新酷音輸入法;其中,別忘了要到設定裡的地區和語言設定語言支援,不過不知為啥,我的是沒辦法設定,但是卻有直接一個 Fctix5 的選項,點一點就這樣意外搞定?
$ sudo apt install fcitx5 fcitx5-chinese-addons fcitx5-config-qt fcitx5-chewing
以上就是在Windows 10 跑 WSL 2,然後設定遠端桌面跟注音輸入法(繁體),陸續參考了以下文章

接著就是安裝 PaddleOCR 還有 PPOCRLabelv2,每次在做這些工作時,總會想到為何那麼多人在抗中保台,結果放眼望去,台灣都沒相關的數據或者工具套件開源出來?XD

https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.6/PPOCRLabel/README_ch.md

https://zhuanlan.zhihu.com/p/523972865
PPv3-OCR自定義數據從訓練到部署

然後這時發現其實可以省掉上面的 WSL,直接裝 WINDOWS 版就可以了 XD
所以最後就補充一些碰到的問題,然後分別參考了那些連結解決的吧
最後 ! 附上一個PPOCRLabelv2標註的擷圖