Tesseract:CPU使用率高,速度慢,僅在並行執行多個程序時
問題
pytesseract.image_to_string()
當我通過 supervisordd 執行腳本時花費了太多時間,但是當直接在 shell 中執行時(在同一台伺服器上並與主管腳本同時)幾乎立即執行。除了花費太多時間之外,這些程序還顯示出較高的 CPU 使用率。
通過 Supervisord 執行所用時間
pytesseract.image_to_string()
:~30s通過 Bash 執行所用時間:0.1s
pytesseract.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'
它修復了執行緒成本。