[英]Celery + Redis for multiprocessing
我使用 tesseract、openCV 和 Google Vision 構建了一個用於光學字符識別的應用程序。 我有 4 種可用的文件類型可供識別(如收據)。 因此用戶可以選擇文件(圖像),然后選擇文檔的確切類型並單擊“識別”。 會發生這樣一個過程:
所以這是常見的場景。 但是我也提供給用戶選擇文檔的類型,叫做“我不知道類型”;)而function,選擇了這種類型后執行,只是經過for循環(遍歷所有類型我們擁有的文件)。 因此,當我們每次使用 openCV+Tesseract 完成工作時都返回我們的文檔類型,很明顯我們只會得到一個非 None 類型,這將是正確的,我們將使用它來識別。 所以這個 function 的執行時間最長,因為我們需要補足 4 個 openCV 對齊和最多 4 個 tesseract 識別才能找到合適的文檔類型。 我想通過為這個特定的 function 實現多處理來加速我的程序。 我決定為這些目的使用 Celery+Redis。 這個想法是:
所以這些是我的功能,我在上面說過:
raw_img_path - 用戶使用 UI 選擇的路徑 dt - 用戶使用 UI 選擇的文檔類型
calc_receipt - 用於識別我們何時知道文檔類型:
def calc_receipt(self, raw_img_path, dt):
aligned_img_path = OpenCV.align_img(
template_path="some\\path\\for\\chosen\\type",
raw_img_path="user\\image\\path",
result_img_path="aligned\\image\\path",
)
tesseract_result = Tesseract.read_from_img(
img_path="aligned\\image\\path",
)
if tesseract_result:
return aligned_img_path, dt
return '', DocumentType.NONE
calc_receipts - 用於識別我們何時不知道類型:
def calc_receipts(self, raw_img_path, selected_doc_type):
for dt in map_receipt_to_receipts[selected_doc_type]:
aligned_img_path, doc_type = self.calc_receipt(raw_img_path, dt)
if doc_type is not DocumentType.NONE:
return aligned_img_path, doc_type
可用類型列表:
map_receipt_to_receipts = {
DocumentType.NONE: [],
DocumentType.DONT_KNOW: [
DocumentType.RESTAURANT,
DocumentType.CAFE,
DocumentType.BAR,
DocumentType.COFFEE_SHOP,
],
DocumentType.RESTAURANT: [
DocumentType.RESTAURANT,
],
DocumentType.CAFE: [
DocumentType.CAFE,
],
DocumentType.BAR: [
DocumentType.BAR,
],
DocumentType.COFFEE_SHOP: [
DocumentType.COFFEE_SHOP,
],
}
class DocumentType 是為方便起見而制作的:
class DocumentType(EnumBase):
NONE = 0
DONT_KNOW = 1
RESTAURANT = 2
CAFE = 3
BAR = 4
COFFEE_SHOP = 5
據我所知,我需要重建 calc_receipts() function。 我有一些問題:
A1: Celery worker 作為獨立進程啟動。 是的,您可以以編程方式啟動它,但這非常罕見(我使用它近 6 年,從未需要它)。 我想一旦您熟悉了 Celery,您就會發現最適合您的選擇。 直到你發現你真的需要以這種方式啟動它,我建議將它作為一個獨立的進程運行。 在生產中,您可能希望它作為系統服務。
A2:老實說,沒有“芹菜客戶端”之類的東西...... Celery 建立在受支持的代理提供的消息傳遞功能之上。 根據分布式生產者/消費者(或發布/訂閱)模式來考慮它。 如果“客戶端”的意思是“生產者” - 將消息(任務)發送到特定隊列(或使用最常見的默認隊列)的東西,那么是的,你可以通過編程方式做到這一點,事實上這就是我們大多數人都在這樣做。
A3:您不關心 Redis。 這完全是 Celery 的工作。 如果我理解你,你需要構建一個簡單的工作流,可能使用 Chord 原語(因為你需要等到所有任務都完成)。 為此,您需要熟悉Celery 工作流程。
A4:我使用 Celery 和 Redis(實際上是 AWS ElastiCache)作為代理和結果后端。 我相信 Redis 可能是 Celery 最常用的代理,可能是因為它的設置和使用非常簡單。 Celery 文檔可能看起來不清楚,但它包含大量信息。 此外,您還有數以千計的博客文章描述了人們如何在各種情況下使用 Celery。 像往常一樣,從簡單的事情開始,少做工人,然后嘗試以分布式方式執行一些小任務。 我按照Celery 文檔的第一步學習了 Celery。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.