條目
Привет!
在本文中,我將分享我使用神經網路為專案建立微服務架構的經驗。
讓我們討論架構需求,查看各種結構圖,分析最終架構的每個元件,並評估解決方案的技術指標。
享受閱讀!
關於問題及其解決方案的幾句話
主要想法是根據照片以十分制的方式評估一個人的吸引力。
在本文中,我們將不再描述所使用的神經網路以及資料準備和訓練的過程。 然而,在以下出版物之一中,我們肯定會重新深入分析評估流程。
現在我們將在頂層進行評估管道,並將重點放在整個專案架構中微服務的互動。
在進行吸引力評估流程時,任務被分解為以下組成部分:
- 選擇照片中的臉孔
- 對每個人的評價
- 渲染結果
第一個是透過預先訓練的力量來解決的
評估流程的功能圖
專案架構需求分析
在生命週期中
機器學習專案的生命週期
這個專案也不例外 - 我們決定將評估管道包裝到線上服務中,這需要我們沉浸在架構中。 確定了以下基本要求:
- 統一日誌儲存-所有服務都應該將日誌寫在一個地方,以便於分析
- 評估服務橫向擴展的可能性 - 作為最可能的瓶頸
- 應分配相同數量的處理器資源來評估每個影像,以避免推理時間分配中出現異常值
- 快速(重新)部署特定服務和整個堆疊
- 如有必要,能夠在不同服務中使用通用對象
架構
分析需求後,很明顯微服務架構幾乎完美契合。
為了擺脫不必要的麻煩,選擇 Telegram API 作為前端。
首先,讓我們來看看已完成架構的結構圖,然後繼續描述每個元件,並將成功的影像處理過程形式化。
完成架構的結構圖
讓我們更詳細地討論該圖的每個組件,在圖像評估過程中表示它們的單一職責。
微服務“attrai-telegram-bot”
此微服務封裝了與 Telegram API 的所有互動。 有 2 個主要場景:使用自訂影像和使用評估管道的結果。 讓我們一般性地看一下這兩種情況。
當收到帶有圖像的自訂訊息時:
- 執行過濾,包括以下檢查:
- 最佳圖像尺寸的可用性
- 佇列中已存在的使用者圖像數量
- 透過初始過濾時,映像保存在docker磁碟區中
- 「to_estimate」佇列中會產生一個任務,其中包括位於我們磁碟區中的影像的路徑等
- 如果上述步驟成功完成,用戶將收到一條訊息,其中包含大約的圖像處理時間,該時間是根據隊列中的任務數量計算得出的。 如果發生錯誤,將透過發送一條包含可能出現問題的訊息的訊息來明確通知使用者。
此外,該微服務與 celery Worker 一樣,監聽「after_estimate」隊列,該隊列適用於已通過評估管道的任務。
當從「after_estimate」收到新任務時:
- 如果影像處理成功,我們會將結果傳送給使用者;如果沒有成功,我們會通知錯誤。
- 刪除評估管道結果的影像
評估微服務“attra-estimator”
該微服務是一個 celery Worker,封裝了與影像評估管道相關的所有內容。 這裡只有一種有效的演算法──讓我們來分析一下。
當從「to_estimate」收到新任務時:
- 讓我們透過評估管道運行影像:
- 將圖像載入到記憶體中
- 我們將影像調整為所需的尺寸
- 尋找所有臉孔 (MTCNN)
- 我們評估所有人臉(我們將上一步中找到的人臉包裝到一個批次中並推理ResNet34)
- 渲染最終影像
- 讓我們繪製邊界框
- 繪製評級
- 刪除自訂(原始)影像
- 保存評估管道的輸出
- 我們將任務放入「after_estimate」佇列中,該佇列由上面討論的「attrai-telegram-bot」微服務監聽。
Graylog(+ mongoDB + Elasticsearch)
選擇權落到了他身上,而不是一般的人身上
作為一個以前只使用過 ELK 堆疊的人,我在使用 Graylog 時獲得了整體積極的體驗。 唯一令人沮喪的是 Kibana 功能相對於 Graylog Web 介面的優越性。
的RabbitMQ
在這個項目中它被用作
Redis的
有時需要在不同的Python微服務中使用通用物件來實作某些資料結構。
例如,Redis 儲存「telegram_user_id => 佇列中活動任務數」形式的雜湊圖,它允許您將一個使用者的請求數量限制為特定值,從而防止 DoS 攻擊。
讓我們形式化成功的影像處理過程
- 使用者將圖像傳送到 Telegram 機器人
- 「attrai-telegram-bot」從 Telegram API 接收訊息並解析它
- 帶有圖像的任務被加入到非同步隊列“to_estimate”
- 用戶收到一則包含計劃評估時間的訊息
- 「attrai-estimator」從「to_estimate」佇列中取得任務,透過管道運行估計並將任務產生到「after_estimate」佇列中
- 「attrai-telegram-bot」監聽「after_estimate」佇列,將結果傳送給用戶
DevOps的
最後,在回顧了架構之後,您可以繼續進行同樣有趣的部分 - DevOps
碼頭工人
使用“群”,叢集中的所有節點可以分為兩種類型—工作節點和管理節點。 在第一種類型的機器上,部署容器組(堆疊),第二種類型的機器負責擴展、平衡和
具有一名領導者經理和三名工人的集群
最小可能的叢集大小是 1 個節點;一台機器將同時充當領導者管理器和工作人員。 根據專案的規模和容錯的最低要求,決定使用這種方法。
展望未來,我想說,自從六月中旬第一次生產交付以來,這個集群組織沒有出現任何問題(但這並不意味著這樣的組織在任何中大型企業中都是可以接受的)項目,受容錯要求的約束)。
Docker 堆疊
在 Swarm 模式下,他負責部署堆疊(Docker 服務集)
它支援 docker-compose 配置,允許您另外使用部署選項。
例如,使用這些參數,每個評估微服務實例的資源都是有限的(我們為 N 個實例分配 N 個核心,在微服務本身中我們將 PyTorch 使用的核心數量限制為 XNUMX)
attrai_estimator:
image: 'erqups/attrai_estimator:1.2'
deploy:
replicas: 4
resources:
limits:
cpus: '4'
restart_policy:
condition: on-failure
…
值得注意的是,Redis、RabbitMQ 和 Graylog 是有狀態服務,它們無法像「atrai-estimator」那樣輕鬆擴展
預示著一個問題——為什麼不是 Kubernetes?
看起來,在中小型專案中使用 Kubernetes 是一種開銷;所有必要的功能都可以從 Docker Swarm 中獲得,這對於容器編排器來說相當人性化,而且入門門檻也很低。
基礎設施
所有這些都部署在具有以下特徵的VDS上:
- CPU:4 核心 Intel® Xeon® Gold 5120 CPU @ 2.20GHz
- RAM:8 GB
- 固態硬盤:160 GB
經過本地負載測試,似乎在用戶大量湧入的情況下,這台機器就足夠了。
但是,部署後,我立即發布了CIS 中最受歡迎的圖像板之一的連結(是的,就是同一個),之後人們開始感興趣,並且在幾個小時內該服務成功處理了數萬張圖像。 同時,在高峰時刻,CPU和RAM資源連一半都沒有使用。
更多圖形
自部署以來的唯一用戶數和評估請求數,具體取決於日期
評估管道推理時間分佈
發現
總而言之,我可以說容器編排的架構和方法完全證明了自己的合理性——即使在高峰時刻,處理時間也沒有下降或下降。
我認為,在其過程中使用神經網路在CPU上進行即時推理的中小型專案可以成功地採用本文中描述的實踐。
我要補充一點,最初這篇文章較長,但為了不發表長篇文章,我決定省略本文中的一些要點 - 我們將在以後的出版物中重新討論它們。
你可以在 Telegram 上戳一下這個機器人 - @AttraiBot,它至少會工作到 2020 年秋季末。 讓我提醒您,不儲存任何用戶資料 - 既不是原始影像,也不是評估管道的結果 - 一切都在處理後被拆除。
來源: www.habr.com