Ocr

Tesseract:CPU使用率高,速度慢,僅在並行執行多個程序時

  • January 28, 2021

問題

pytesseract.image_to_string()當我通過 supervisordd 執行腳本時花費了太多時間,但是當直接在 shell 中執行時(在同一台伺服器上並與主管腳本同時)幾乎立即執行。

除了花費太多時間之外,這些程序還顯示出較高的 CPU 使用率。

通過 Supervisord 執行所用時間pytesseract.image_to_string():~30s通過 Bash 執行

所用時間:0.1spytesseract.image_to_string()

pytesseract.image_to_string()只有在通過 supervisord(大約 22 個實例)執行大量程序時,才會出現此問題。如果我減少實例的數量(減少到 10 個左右),通過 supervisord 執行的腳本也可以順利執行。

系統資訊

作業系統:Ubuntu 18.04.2 LTS(仿生)

Supervisord:版本 3.3.1

Tesseract:版本 4.0.0-beta.1

Python:版本 3.6

PyTesseract:版本 0.2.5

ulimit -a

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 127357
max locked memory       (kbytes, -l) 16384
max memory size         (kbytes, -m) unlimited
open files                      (-n) 8096
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 127357
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

如果您需要更多資訊,請告訴我。

編輯 1(或者我知道不是這個問題的根源)

我相當確定這不是 Supervisord 的問題。

當我從 ssh shell 執行一個實例時,函式pytesseract.image_to_string()

當我從新的 ssh shell 啟動另一個實例時,這兩個實例(從 ssh 啟動的實例)大部分時間都執行順利。

當我從新的 ssh shell 啟動另一個實例時,所有三個實例都開始阻塞,大約需要 10 秒才能執行該函式。隨著我通過 shell 添加更多實例,這個時間不斷增加。

因此,即使使用外殼也可以複製問題。

更多資訊

我執行了該程序,strace -T -f但我無法弄清楚究竟是什麼導致了時間峰值。

對於需要 1 秒的函式呼叫

Top 10 system calls sorted by time taken
1.504530    [pid 29921] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 30166
0.503915    [pid 29932] <... select resumed> )      = 0 (Timeout)
0.503472    [pid 29932] <... select resumed> )      = 0 (Timeout)
0.500524    [pid 29933] <... select resumed> )      = 0 (Timeout)
0.500515    [pid 29933] <... select resumed> )      = 0 (Timeout)
0.500514    [pid 29932] <... select resumed> )      = 0 (Timeout)
0.500512    [pid 29933] <... select resumed> )      = 0 (Timeout)
0.069869    [pid 30169] <... futex resumed> )       = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
0.035989    [pid 30167] <... futex resumed> )       = 0
0.016002    [pid 30168] <... futex resumed> )       = 0

對於需要 9 秒的函式呼叫

Top 10 system calls sorted by time taken
9.795787    [pid 29921] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 30106
0.515960    [pid 29933] <... select resumed> )      = 0 (Timeout)
0.511955    [pid 29933] <... select resumed> )      = 0 (Timeout)
0.507979    [pid 29932] <... select resumed> )      = 0 (Timeout)
0.507968    [pid 29932] <... select resumed> )      = 0 (Timeout)
0.505257    [pid 29932] <... select resumed> )      = 0 (Timeout)
0.503988    [pid 29932] <... select resumed> )      = 0 (Timeout)
0.503978    [pid 29932] <... select resumed> )      = 0 (Timeout)
0.503975    [pid 29932] <... select resumed> )      = 0 (Timeout)
0.503974    [pid 29932] <... select resumed> )      = 0 (Timeout)

在 tesseract 中禁用多處理解決了這個問題。可以通過OMP_THREAD_LIMIT=1在環境中設置來完成。

https://github.com/tesseract-ocr/tesseract/issues/898#issuecomment-315202167

在python程序中:

import os
os.environ['OMP_THREAD_LIMIT'] = '1'

它修復了執行緒成本。

引用自:https://unix.stackexchange.com/questions/530818