การเข้า
Hi!
ในบทความนี้ ผมจะแบ่งปันประสบการณ์ของผมในการสร้างสถาปัตยกรรมไมโครเซอร์วิสสำหรับโปรเจ็กต์ที่ใช้โครงข่ายประสาทเทียม
เรามาพูดถึงข้อกำหนดทางสถาปัตยกรรม ดูไดอะแกรมโครงสร้างต่างๆ วิเคราะห์ส่วนประกอบแต่ละส่วนของสถาปัตยกรรมที่เสร็จสมบูรณ์ และประเมินตัวชี้วัดทางเทคนิคของโซลูชันกัน
เพลิดเพลินไปกับการอ่าน!
คำไม่กี่คำเกี่ยวกับปัญหาและแนวทางแก้ไข
แนวคิดหลักคือการประเมินความน่าดึงดูดใจของบุคคลในระดับสิบคะแนนจากภาพถ่าย
ในบทความนี้ เราจะละทิ้งการอธิบายทั้งโครงข่ายประสาทเทียมที่ใช้และกระบวนการเตรียมและฝึกอบรมข้อมูล อย่างไรก็ตาม ในสิ่งพิมพ์ต่อไปนี้ เราจะกลับมาวิเคราะห์ขั้นตอนการประเมินในเชิงลึกอีกครั้งอย่างแน่นอน
ตอนนี้เราจะผ่านขั้นตอนการประเมินที่ระดับบนสุด และจะมุ่งเน้นไปที่การโต้ตอบของไมโครเซอร์วิสในบริบทของสถาปัตยกรรมโครงการโดยรวม
เมื่อดำเนินการตามไปป์ไลน์การประเมินความน่าดึงดูดใจ งานจะถูกแบ่งออกเป็นองค์ประกอบต่อไปนี้:
- การเลือกใบหน้าในภาพถ่าย
- การให้คะแนนของแต่ละคน
- แสดงผล
ประการแรกได้รับการแก้ไขโดยกองกำลังของผู้ฝึกหัดล่วงหน้า
แผนภาพการทำงานของไปป์ไลน์การประเมินผล
การวิเคราะห์ข้อกำหนดทางสถาปัตยกรรมโครงการ
ในวงจรชีวิต
วงจรชีวิตของโปรเจ็กต์ ML
โปรเจ็กต์นี้ก็ไม่มีข้อยกเว้น - มีการตัดสินใจที่จะรวมไปป์ไลน์การประเมินเข้ากับบริการออนไลน์ ซึ่งจำเป็นต้องดื่มด่ำไปกับสถาปัตยกรรม มีการระบุข้อกำหนดพื้นฐานต่อไปนี้:
- พื้นที่จัดเก็บบันทึกแบบรวม – บริการทั้งหมดควรเขียนบันทึกไว้ในที่เดียว ซึ่งควรสะดวกในการวิเคราะห์
- ความเป็นไปได้ของการปรับสเกลแนวนอนของบริการประเมิน - เนื่องจากมีแนวโน้มว่าจะเกิดปัญหาคอขวดมากที่สุด
- ควรจัดสรรทรัพยากรโปรเซสเซอร์จำนวนเท่ากันเพื่อประเมินแต่ละภาพเพื่อหลีกเลี่ยงค่าผิดปกติในการกระจายเวลาสำหรับการอนุมาน
- การปรับใช้ทั้งบริการเฉพาะและสแต็กโดยรวมอย่างรวดเร็ว (ใหม่)
- ความสามารถ (หากจำเป็น) ในการใช้ออบเจ็กต์ทั่วไปในบริการต่างๆ
สถาปัตยกรรม
หลังจากวิเคราะห์ข้อกำหนดแล้ว ก็เห็นได้ชัดว่าสถาปัตยกรรมไมโครเซอร์วิสเข้ากันได้เกือบสมบูรณ์แบบ
เพื่อกำจัดอาการปวดหัวที่ไม่จำเป็น Telegram API จึงถูกเลือกเป็นส่วนหน้า
ขั้นแรก มาดูแผนภาพโครงสร้างของสถาปัตยกรรมที่เสร็จแล้ว จากนั้นไปที่คำอธิบายของแต่ละองค์ประกอบ และทำให้กระบวนการประมวลผลภาพที่ประสบความสำเร็จเป็นระเบียบเรียบร้อย
แผนภาพโครงสร้างของสถาปัตยกรรมที่เสร็จสมบูรณ์
มาดูรายละเอียดเพิ่มเติมเกี่ยวกับแต่ละองค์ประกอบของไดอะแกรมซึ่งแสดงถึงความรับผิดชอบเดี่ยวในกระบวนการประเมินภาพ
ไมโครเซอร์วิส “atrai-telegram-bot”
ไมโครเซอร์วิสนี้สรุปการโต้ตอบทั้งหมดกับ Telegram API มี 2 สถานการณ์หลัก: การทำงานกับอิมเมจที่กำหนดเอง และการทำงานกับผลลัพธ์ของไปป์ไลน์การประเมิน ลองดูทั้งสองสถานการณ์ในแง่ทั่วไป
เมื่อได้รับข้อความที่กำหนดเองพร้อมรูปภาพ:
- ทำการกรอง ประกอบด้วยการตรวจสอบดังต่อไปนี้:
- ความพร้อมใช้งานของขนาดภาพที่เหมาะสมที่สุด
- จำนวนอิมเมจของผู้ใช้ที่อยู่ในคิวแล้ว
- เมื่อผ่านการกรองเริ่มต้น รูปภาพจะถูกบันทึกลงในโวลุ่มนักเทียบท่า
- งานถูกสร้างขึ้นในคิว "to_estimate" ซึ่งรวมถึงเส้นทางไปยังรูปภาพที่อยู่ในโวลุ่มของเรา
- หากขั้นตอนข้างต้นเสร็จสมบูรณ์ ผู้ใช้จะได้รับข้อความพร้อมเวลาประมวลผลภาพโดยประมาณ ซึ่งคำนวณตามจำนวนงานในคิว หากมีข้อผิดพลาดเกิดขึ้น ผู้ใช้จะได้รับแจ้งอย่างชัดเจนโดยการส่งข้อความพร้อมข้อมูลเกี่ยวกับสิ่งที่อาจเกิดขึ้นผิดพลาด
นอกจากนี้ ไมโครเซอร์วิสนี้ยังฟังคิว “after_estimate” เช่นเดียวกับคนทำงานคื่นฉ่าย ซึ่งมีไว้สำหรับงานที่ผ่านไปป์ไลน์การประเมินแล้ว
เมื่อได้รับงานใหม่จาก “after_estimate”:
- หากประมวลผลรูปภาพได้สำเร็จ เราจะส่งผลไปยังผู้ใช้ หากไม่ เราจะแจ้งข้อผิดพลาด
- การลบรูปภาพที่เป็นผลลัพธ์ของไปป์ไลน์การประเมิน
ไมโครเซอร์วิสการประเมินผล “ตัวประมาณค่าประเมิน”
ไมโครเซอร์วิสนี้เป็นพนักงานขึ้นฉ่ายและสรุปทุกอย่างที่เกี่ยวข้องกับไปป์ไลน์การประเมินรูปภาพ มีอัลกอริธึมการทำงานเพียงอันเดียวที่นี่ มาวิเคราะห์กันดีกว่า
เมื่อได้รับงานใหม่จาก “to_estimate”:
- มาเรียกใช้รูปภาพผ่านขั้นตอนการประเมินผล:
- กำลังโหลดภาพเข้าสู่หน่วยความจำ
- เรานำภาพมาตามขนาดที่ต้องการ
- ค้นหาใบหน้าทั้งหมด (MTCNN)
- เราประเมินใบหน้าทั้งหมด (เรารวมใบหน้าที่พบในขั้นตอนสุดท้ายเป็นชุดและอนุมาน ResNet34)
- แสดงภาพสุดท้าย
- มาวาดกรอบขอบกัน
- การวาดเรตติ้ง
- การลบรูปภาพที่กำหนดเอง (ต้นฉบับ)
- บันทึกเอาต์พุตจากไปป์ไลน์การประเมิน
- เราวางงานไว้ในคิว "after_estimate" ซึ่งไมโครเซอร์วิส "attrai-telegram-bot" จะรับฟังตามที่กล่าวไว้ข้างต้น
Graylog (+ mongoDB + การค้นหาแบบยืดหยุ่น)
ทางเลือกตกอยู่กับเขา ไม่ใช่ทางเลือกปกติ
เนื่องจากก่อนหน้านี้เคยทำงานกับสแต็ก ELK เท่านั้น ฉันจึงได้รับประสบการณ์ที่ดีโดยรวมขณะทำงานกับ Graylog สิ่งเดียวที่น่าหดหู่คือความเหนือกว่าในฟีเจอร์ของ Kibana เหนือเว็บอินเตอร์เฟสของ Graylog
RabbitMQ
ในโครงการนี้มันถูกใช้เป็น
Redis
บางครั้งจำเป็นต้องใช้ออบเจ็กต์ทั่วไปที่ใช้โครงสร้างข้อมูลบางอย่างในไมโครเซอร์วิส Python ที่แตกต่างกัน
ตัวอย่างเช่น Redis จัดเก็บแฮชแมปในรูปแบบ “telegram_user_id => จำนวนงานที่ใช้งานอยู่ในคิว” ซึ่งช่วยให้คุณสามารถจำกัดจำนวนคำขอจากผู้ใช้รายหนึ่งให้เป็นค่าที่แน่นอน และด้วยเหตุนี้ จึงป้องกันการโจมตี DoS ได้
มาทำให้กระบวนการประมวลผลภาพที่ประสบความสำเร็จเป็นทางการกัน
- ผู้ใช้ส่งภาพไปยังบอตโทรเลข
- "attrai-telegram-bot" ได้รับข้อความจาก Telegram API และแยกวิเคราะห์
- งานที่มีรูปภาพถูกเพิ่มลงในคิวแบบอะซิงโครนัส "to_estimate"
- ผู้ใช้จะได้รับข้อความพร้อมเวลาการประเมินที่วางแผนไว้
- “attrai-estimator” รับงานจากคิว “to_estimate” รันการประมาณค่าผ่านไปป์ไลน์ และสร้างงานลงในคิว “after_estimate”
- "attrai-telegram-bot" ฟังคิว "after_estimate" ส่งผลไปยังผู้ใช้
DevOps
สุดท้าย หลังจากตรวจสอบสถาปัตยกรรมแล้ว คุณสามารถไปยังส่วนที่น่าสนใจไม่แพ้กัน นั่นก็คือ DevOps
ฝูงนักเทียบท่า
เมื่อใช้ "ฝูง" โหนดทั้งหมดในคลัสเตอร์ของเราสามารถแบ่งออกเป็น 2 ประเภท - ผู้ปฏิบัติงานและผู้จัดการ บนเครื่องประเภทแรก กลุ่มของคอนเทนเนอร์ (สแต็ค) จะถูกปรับใช้ เครื่องจักรประเภทที่สองมีหน้าที่รับผิดชอบในการปรับขนาด การปรับสมดุล และ
คลัสเตอร์ที่มีผู้จัดการผู้นำหนึ่งคนและพนักงานสามคน
ขนาดคลัสเตอร์ขั้นต่ำที่เป็นไปได้คือ 1 โหนด โดยเครื่องเดียวจะทำหน้าที่เป็นผู้จัดการผู้นำและผู้ปฏิบัติงานไปพร้อมๆ กัน ขึ้นอยู่กับขนาดของโครงการและข้อกำหนดขั้นต่ำสำหรับความทนทานต่อข้อผิดพลาด จึงตัดสินใจใช้แนวทางนี้
มองไปข้างหน้าฉันจะบอกว่าตั้งแต่การส่งมอบการผลิตครั้งแรกซึ่งอยู่ในช่วงกลางเดือนมิถุนายนไม่มีปัญหาใด ๆ ที่เกี่ยวข้องกับองค์กรคลัสเตอร์นี้ (แต่ไม่ได้หมายความว่าองค์กรดังกล่าวจะเป็นที่ยอมรับในสื่อกลางและขนาดใหญ่ใด ๆ โครงการซึ่งอยู่ภายใต้ข้อกำหนดความทนทานต่อข้อผิดพลาด)
นักเทียบท่าสแต็ค
ในโหมดฝูง เขามีหน้าที่รับผิดชอบในการปรับใช้สแต็ก (ชุดบริการนักเทียบท่า)
รองรับการกำหนดค่านักเทียบท่าทำให้คุณสามารถใช้ตัวเลือกการปรับใช้เพิ่มเติมได้
ตัวอย่างเช่น การใช้พารามิเตอร์เหล่านี้ ทรัพยากรสำหรับอินสแตนซ์ไมโครเซอร์วิสการประเมินผลแต่ละรายการนั้นมีจำกัด (เราจัดสรรแกน N สำหรับอินสแตนซ์ N ในไมโครเซอร์วิสเองเราจำกัดจำนวนแกนประมวลผลที่ PyTorch ใช้ไว้ที่หนึ่งแกน)
attrai_estimator:
image: 'erqups/attrai_estimator:1.2'
deploy:
replicas: 4
resources:
limits:
cpus: '4'
restart_policy:
condition: on-failure
…
สิ่งสำคัญคือต้องทราบว่า Redis, RabbitMQ และ Graylog เป็นบริการแบบมีสถานะ และไม่สามารถปรับขนาดได้ง่ายเหมือนกับ “ตัวประมาณค่าประเมิน”
คาดเดาคำถาม - ทำไมไม่ Kubernetes?
ดูเหมือนว่าการใช้ Kubernetes ในโครงการขนาดเล็กและขนาดกลางนั้นมีค่าใช้จ่ายสูง คุณสามารถรับฟังก์ชันที่จำเป็นทั้งหมดได้จาก Docker Swarm ซึ่งค่อนข้างใช้งานง่ายสำหรับผู้ควบคุมคอนเทนเนอร์และยังมีอุปสรรคในการเข้าต่ำอีกด้วย
โครงสร้างพื้นฐาน
ทั้งหมดนี้ถูกปรับใช้บน VDS โดยมีคุณสมบัติดังต่อไปนี้:
- ซีพียู: Intel® Xeon® Gold 4 CPU 5120 คอร์ @ 2.20GHz
- RAM: 8 GB
- SSD: 160GB
หลังจากการทดสอบโหลดในพื้นที่ ดูเหมือนว่าเมื่อมีผู้ใช้หลั่งไหลเข้ามาอย่างมาก เครื่องนี้ก็เพียงพอแล้ว
แต่ทันทีหลังจากการปรับใช้ ฉันโพสต์ลิงก์ไปยังหนึ่งในอิมเมจบอร์ดที่ได้รับความนิยมมากที่สุดใน CIS (ใช่แล้ว อันเดียวกันนั้น) หลังจากนั้นผู้คนก็เริ่มสนใจ และภายในไม่กี่ชั่วโมง บริการก็ประมวลผลรูปภาพนับหมื่นภาพได้สำเร็จ ในเวลาเดียวกัน ในช่วงเวลาเร่งด่วน ทรัพยากร CPU และ RAM ไม่ได้ถูกใช้ไปครึ่งหนึ่งด้วยซ้ำ
กราฟิกเพิ่มเติมบางส่วน
จำนวนผู้ใช้ที่ไม่ซ้ำและคำขอประเมินผลตั้งแต่การปรับใช้ ขึ้นอยู่กับวัน
การกระจายเวลาอนุมานไปป์ไลน์การประเมินผล
ผลการวิจัย
โดยสรุป ฉันสามารถพูดได้ว่าสถาปัตยกรรมและวิธีการในการจัดการคอนเทนเนอร์มีความสมเหตุสมผลอย่างสมบูรณ์ - แม้ในช่วงเวลาเร่งด่วนก็ไม่มีเวลาการประมวลผลลดลงหรือลดลง
ฉันคิดว่าโครงการขนาดเล็กและขนาดกลางที่ใช้การอนุมานแบบเรียลไทม์ของโครงข่ายประสาทเทียมบน CPU ในกระบวนการสามารถนำแนวทางปฏิบัติที่อธิบายไว้ในบทความนี้มาใช้ได้สำเร็จ
ฉันจะเพิ่มว่าในตอนแรกบทความนั้นยาวกว่า แต่เพื่อไม่ให้โพสต์แบบอ่านยาวฉันจึงตัดสินใจละเว้นบางประเด็นในบทความนี้ - เราจะกลับมาหาพวกเขาอีกครั้งในการตีพิมพ์ในอนาคต
คุณสามารถกระตุ้นบอทบน Telegram - @AttraiBot ได้ มันจะใช้งานได้จนถึงสิ้นฤดูใบไม้ร่วงปี 2020 เป็นอย่างน้อย ฉันขอเตือนคุณว่าไม่มีการจัดเก็บข้อมูลผู้ใช้ ไม่ว่าจะเป็นภาพต้นฉบับหรือผลลัพธ์ของไปป์ไลน์การประเมิน ทุกอย่างจะถูกทำลายหลังการประมวลผล
ที่มา: will.com