เร็วขึ้น 31.8 เท่า ด้วยการเปลี่ยนไฟล์เพียงไฟล์เดียว

ผมได้ทดสอบ RAG ingestion pipeline และพบปัญหาคอขวด: เอกสารหนึ่งฉบับใช้เวลาประมวลผลถึง 50 วินาที

CPU ของผมว่างงานอยู่เฉยๆ แอปไม่ได้กำลังคำนวณคณิตศาสตร์หรือตรรกะอะไร แต่มันแค่รอให้ HTTP request หนึ่งเสร็จสิ้นก่อนที่จะเริ่มอันถัดไป

ผมจึงเขียนโมดูล embedding ใหม่ให้ทำงานแบบ asynchronous เวลาที่ใช้ประมวลผลลดลงจาก 49.61 วินาที เหลือเพียง 1.56 วินาที โดยไม่ต้องเปลี่ยนโครงสร้างพื้นฐาน (infrastructure) เลย

รายละเอียดการทดสอบ

  • Model: Amazon Titan Text Embeddings V2 (AWS Bedrock)
  • Dataset: 33 text chunks
  • Region: us-east-1

ผลลัพธ์

  • Sequential: 49.61 วินาที
  • Concurrent: 1.56 วินาที
  • Speedup: 31.8×

ทำไมมันถึงได้ผล โค้ดแบบ Sequential จะส่ง request และหยุดรอ (block) จนกว่าจะได้รับผลตอบกลับ แล้วจึงทำซ้ำแบบเดิมกับทุก chunk เมื่อมี 33 chunks และแต่ละอันใช้เวลา 1.5 วินาที คุณจึงเสียเวลาไปประมาณ 50 วินาที

ส่วนโค้ดแบบ Async จะส่งทุก request ออกไปพร้อมกัน โดยเวลาที่ใช้ทั้งหมดจะเท่ากับเวลาของ request ที่ช้าที่สุดเพียงอันเดียว

ผลกระทบเมื่อขยายขนาด (Scaling impact)

  • 31 chunks: 49.61 วินาที → 1.56 วินาที
  • 100 chunks: ~160 วินาที → ~3 วินาที
  • 500 chunks: ~800 วินาที → ~5 วินาที
  • 1,000 chunks: ~1,600 วินาที → ~10 วินาที

คำแนะนำสำหรับ pipeline ของคุณ

  • มองหาช่วงเวลาที่เครื่องว่าง (idle time) อย่าเพิ่งเพิ่มฮาร์ดแวร์หากโค้ดของคุณแค่กำลังรอการตอบสนองจากเครือข่าย
  • เคารพข้อจำกัดเรื่อง rate limits ของ AWS Bedrock โดยใช้ asyncio.Semaphore เพื่อจำกัดจำนวน concurrent requests
  • เลือกใช้ library แบบ non-blocking เช่น เปลี่ยนจาก boto3 เป็น aioboto3 หรือใช้ asyncio.to_thread() ครอบการเรียกใช้งานไว้

การเปลี่ยนไฟล์เพียงไฟล์เดียวช่วยกำจัดคอขวดออกไปได้ ใช้ความพยายามน้อย แต่ได้ผลลัพธ์มหาศาล

Source: https://dev.to/edwardyun/318x-speedup-by-changing-one-file-async-embedding-calls-on-aws-bedrock-4l61

Optional learning community: https://t.me/GyaanSetuAi