ให้บริการโมเดลการเรียนรู้เชิงลึก 3,000 รายการบน Amazon EKS ด้วย AWS Inferentia ในราคาต่ำกว่า 50 ดอลลาร์ต่อชั่วโมง

โหนดต้นทาง: 1146468

ลูกค้าจำนวนมากขึ้นกำลังค้นหาความจำเป็นในการสร้างไปป์ไลน์การอนุมานของแมชชีนเลิร์นนิง (ML) ที่ใหญ่ขึ้น ปรับขนาดได้ และคุ้มค่าใช้จ่ายมากขึ้นในระบบคลาวด์ นอกเหนือจากข้อกำหนดเบื้องต้นพื้นฐานเหล่านี้ ข้อกำหนดของไปป์ไลน์การอนุมาน ML ในการผลิตจะแตกต่างกันไปตามกรณีการใช้งานทางธุรกิจ สถาปัตยกรรมการอนุมานทั่วไปสำหรับแอปพลิเคชัน เช่น เครื่องมือแนะนำ การวิเคราะห์ความคิดเห็น และการจัดอันดับโฆษณา จำเป็นต้องให้บริการโมเดลจำนวนมาก ด้วยการผสมผสานระหว่าง ML แบบดั้งเดิมและโมเดลการเรียนรู้เชิงลึก (DL) แต่ละรุ่นต้องสามารถเข้าถึงได้ผ่านจุดปลายของ Application Programing Interface (API) และสามารถตอบสนองได้ภายในงบประมาณเวลาแฝงที่กำหนดไว้ล่วงหน้าตั้งแต่เวลาที่ได้รับคำขอ

ในโพสต์นี้ เราอธิบายสถาปัตยกรรมการอนุมาน ซึ่งพัฒนาขึ้นโดยความร่วมมือกับทีม Commerce Einstein ที่ Salesforce ซึ่งสร้างขึ้นจาก บริการ Amazon Elastic Kubernetes (Amazon EKS) ที่ไม่เพียงแต่จัดการกับข้อกำหนดเบื้องต้นพื้นฐานเท่านั้น แต่ยังรวมรุ่น PyTorch DL ที่ไม่ซ้ำกันหลายพันรายการไว้ในสถาปัตยกรรมที่ปรับขนาดได้ เราสำรวจส่วนผสมของ อเมซอน อีลาสติก คอมพิวท์ คลาวด์ ตระกูลอินสแตนซ์ (Amazon EC2) (c5, g4dn, Inf1) เพื่อพัฒนาการออกแบบที่เหมาะสมที่สุดจากด้านต้นทุนและประสิทธิภาพ เพื่อให้เป็นไปตามข้อกำหนดเหล่านี้ เราจึงสร้างบริการอนุมาน DL บน Amazon EKS โดยใช้ FastAPIซึ่งเป็นเซิร์ฟเวอร์ API ที่ใช้ Python น้ำหนักเบาและมีประสิทธิภาพ และพัฒนากลยุทธ์การบรรจุโมเดล bin เพื่อแบ่งปันทรัพยากรการประมวลผลและหน่วยความจำระหว่างโมเดลต่างๆ อย่างมีประสิทธิภาพ ในการโหลดการทดสอบสถาปัตยกรรม เราใช้โมเดล PyTorch โอเพ่นซอร์สสำหรับการประมวลผลภาษาธรรมชาติ (NLP) จาก Hugface.co (bert-base-casedประมาณ 800 MB) และจำลองไคลเอนต์นับพันที่ส่งคำขอไปยังพูลบริการพร้อมกัน เราใช้ การอนุมาน AWSซึ่งเป็นชิป ML แบบกำหนดเองบนอินสแตนซ์ Inf1 เพื่อบรรจุและให้บริการโมเดล PyTorch ที่ไม่ซ้ำกัน 3,000 รุ่น โดยรักษาต้นทุนให้ต่ำกว่า 50 ดอลลาร์/ชั่วโมง (ราคาแบบออนดีมานด์) โดยมีเวลาแฝงไปกลับ 70 มิลลิวินาที (P90) เทียบกับเป้าหมายของเราที่ 100 มิลลิวินาที คุณสามารถขยายสถาปัตยกรรมและแนวทางการปรับให้เหมาะสมนี้ไปยังโมเดล DL ที่กำหนดเองได้

ภาพรวมโซลูชัน

ต่อไปนี้เป็นสถาปัตยกรรมที่เรียบง่าย ปรับขนาดได้ และมีความพร้อมใช้งานสูงโดยอิงตามโครงสร้างพื้นฐาน Amazon EKS มาตรฐานที่ปรับใช้ได้ทั่ว Availability Zone

คลัสเตอร์ Amazon EKS มีกลุ่มโหนดหลายกลุ่ม โดยมีกลุ่มอินสแตนซ์ EC2 หนึ่งกลุ่มต่อกลุ่มโหนด กลุ่มโหนดแต่ละกลุ่มสามารถรองรับอินสแตนซ์ประเภทต่างๆ ได้ เช่น CPU (c5), GPU (g4dn) และ AWS Inferentia (Inf1) และสามารถแพ็คได้หลายรุ่นต่ออินสแตนซ์เพื่อเพิ่มจำนวนโมเดลที่ให้บริการสูงสุด ถัดไป โมเดลที่ให้บริการแอปพลิเคชันและการอ้างอิงเฟรมเวิร์ก DL จะถูกจัดเก็บในคอนเทนเนอร์ และอิมเมจคอนเทนเนอร์เหล่านี้จะถูกจัดเก็บบน การลงทะเบียน Amazon Elastic Container (อเมซอน อีซีอาร์). อิมเมจคอนเทนเนอร์ถูกปรับใช้กับคลัสเตอร์โดยใช้การปรับใช้และรายการบริการ ซึ่งปรับแต่งสำหรับแต่ละกลุ่มอินสแตนซ์ แอปพลิเคชันที่ให้บริการแบบจำลองดาวน์โหลดสิ่งประดิษฐ์แบบจำลองจาก บริการจัดเก็บข้อมูลอย่างง่ายของ Amazon (Amazon S3) ที่การเริ่มต้นเซิร์ฟเวอร์ ซึ่งลดขนาดของอิมเมจคอนเทนเนอร์บน Amazon ECR และแยกข้อมูลโมเดลออกจากข้อกำหนดบริการ

บริการเช่น cluster-autoscaler, horizontal-pod-autoscaler, aws-load-balancer-controller, metrics-server, nginx-ingress-controller, neuron-device-plugin-daemonsetและ nvidia-device-plugin-daemonset ถูกนำไปใช้กับคลัสเตอร์ตามต้องการ การออกแบบนี้อาศัย Kubernetes coredns สำหรับการแก้ปัญหาชื่อของปลายทางบริการภายในคลัสเตอร์ แต่ละรุ่นสามารถระบุตำแหน่งได้โดยใช้ชื่อ DNS และชื่อรุ่นร่วมกัน ตัวอย่างเช่น, http://<model server ID>.<name space>.svc.cluster.local:8080/predictions/<model id>.

สำหรับการปรับแต่งชื่อ DNS เราสามารถใช้รายการขาเข้าได้

สถาปัตยกรรมได้รับการตั้งค่าให้ทำงานในห้าขั้นตอนง่ายๆ: สร้าง ติดตาม แพ็ค ปรับใช้ และทดสอบ สามารถเข้าถึงที่เก็บรหัสได้ใน GitHub ซื้อคืน

  1. ขั้นตอนการสร้างจะสร้างคอนเทนเนอร์พื้นฐานสำหรับประเภทอินสแตนซ์ที่เลือก โดยติดตั้งเลเยอร์ฐานที่จำเป็นทั้งหมดในคอนเทนเนอร์
  2. ขั้นตอนการติดตามจะคอมไพล์โมเดล เพื่อเพิ่มประสิทธิภาพสูงสุดบนอินสแตนซ์ GPU โมเดลต่างๆ ถูกทำให้เป็นอนุกรมในรูปแบบ TorchScript โดยใช้ไลบรารี PyTorch (torch.jit.trace) สำหรับอินสแตนซ์ Inf1 ค่า AWS เซลล์ประสาท การผสานรวมดั้งเดิมของ SDK กับ PyTorch ได้รับการยกระดับเพื่อคอมไพล์โมเดลให้อยู่ในรูปแบบ Neuron bfloat16 ต่อไปนี้เป็นข้อมูลโค้ดสำหรับติดตามโมเดลที่ทำงานใน bfloat16 บน AWS Inferentia หรือ Automatic Mixed Precision (AMP) บนอินสแตนซ์ GPU:
print('nTracing model ...')
example_inputs = ( torch.cat([inputs['input_ids']] * batch_size,0), torch.cat([inputs['attention_mask']] * batch_size,0)
)
os.makedirs(f'traced-{model_name}', exist_ok=True)
torch.set_num_threads(6)
if 'inf' in processor: model_traced = torch.neuron.trace(model, example_inputs, verbose=1, compiler_workdir=f'./traced-{model_name}/compile_wd_{processor}_bs{batch_size}_seq	{sequence_length}_pc{pipeline_cores}', compiler_args = ['--neuroncore-pipeline-cores', str(pipeline_cores)])
else: model_traced = torch.jit.trace(model, example_inputs)

  1. ขั้นตอนการแพ็คจะบรรจุแบบจำลองในคอนเทนเนอร์ที่มี FastAPI ซึ่งช่วยให้สามารถบรรจุแบบจำลองได้หลายแบบภายในคอนเทนเนอร์เดียวกัน
  2. ขั้นตอนการปรับใช้จะรันโมเดลในรันไทม์ที่กำหนดค่าไว้ (เช่น Kubernetes หรือ Docker) และอำนวยความสะดวกในการจัดการวงจรชีวิตแบบเต็มของคอนเทนเนอร์เซิร์ฟเวอร์โมเดล ข้อมูลโค้ดต่อไปนี้ตั้งค่าตัวเลือกการรันและเปิดใช้คอนเทนเนอร์ในรันไทม์ที่กำหนดค่าไว้:
echo "Runtime: $runtime"
echo "Processor: $processor" if [ "$runtime" == "docker" ]; then server=0 while [ $server -lt $num_servers ]; do run_opts="--name ${app_name}-${server} -e NUM_MODELS=$num_models -e POSTPROCESS=$postprocess -e QUIET=$quiet -P" if [ "$processor" == "gpu" ]; then run_opts="--gpus 0 ${run_opts}" fi CMD="docker run -d ${run_opts} ${registry}${model_image_name}${model_image_tag}" echo "$CMD" eval "$CMD" server=$((server+1)) done
elif [ "$runtime" == "kubernetes" ]; then kubectl create namespace ${namespace} --dry-run=client -o yaml | kubectl apply -f - ./generate-yaml.sh kubectl apply -f ${app_dir}
else echo "Runtime $runtime not recognized"
fi

  1. ขั้นตอนสุดท้ายจะทำการทดสอบกับเซิร์ฟเวอร์รุ่นที่ใช้งานในสภาพแวดล้อมรันไทม์

รุ่น ML บรรจุถัง

การบรรจุโมเดล PyTorch ML แบบ Bin ในอินสแตนซ์ EC2 เป็นสิ่งจำเป็นในการแบ่งปันทรัพยากรการประมวลผลและหน่วยความจำระหว่างรุ่นต่างๆ อย่างมีประสิทธิภาพ งานการบรรจุถังแบบจำลองสามารถกำหนดและแก้ไขเป็นปัญหาเป้ 0-1 โดยใช้การเพิ่มประสิทธิภาพแบบผสมผสาน ต่อไปนี้เป็นสูตรทางคณิตศาสตร์สำหรับการบรรจุลงถัง นโมเดล อยู่ภายใต้ข้อจำกัดของหน่วยความจำโปรเซสเซอร์สูงสุด (Mแม็กซ์) และการใช้ประโยชน์ (Cแม็กซ์). แนวทางนี้แนะนำการบรรจุแบบจำลองที่เหมาะสมที่สุดผ่านชุดอินสแตนซ์ EC2 ขั้นต่ำ

จำนวนของถังขยะถูกขยายใหญ่สุดเพื่อเริ่มต้นปัญหาด้วยวิธีแก้ปัญหาเล็กๆ น้อยๆ หนึ่งรุ่นต่อหนึ่งถัง และตัดแต่งเพื่อให้บรรลุเป้าหมายด้วยจำนวนถังขยะที่น้อยที่สุด

การแสดงภาพต่อไปนี้แสดงตัวอย่างการจัดสรรการบรรจุถังสำหรับรุ่น 78 โดยแต่ละรุ่นมีหน่วยความจำและความต้องการในการประมวลผลที่ไม่ซ้ำกัน ในตัวอย่างนี้ มี 78 โมเดลที่บรรจุอยู่ใน 23 อินสแตนซ์ (g4dn, Inf1) ด้วยหน่วยความจำเป้าหมายสูงสุดที่ระบุ (7.4 GB) และความจุในการประมวลผล (83%) คำอธิบายสีระบุดัชนีรุ่น

เราสามารถใช้วิธีการก่อนหน้านี้เพื่อเพิ่มประสิทธิภาพโมเดล bin pack ข้ามอินสแตนซ์ได้ ตารางต่อไปนี้สรุปผลการบรรจุ bin สำหรับอินสแตนซ์ Inf1 และ g4dn เราเลือกกลุ่มอินสแตนซ์เหล่านี้เนื่องจากโมเดล NLP ที่ใช้หม้อแปลงไฟฟ้าต้องการการเร่งด้วยฮาร์ดแวร์เพื่อให้ได้เวลาแฝงที่คาดหวัง เราสามารถ bin pack รุ่นต่างๆ ได้มากขึ้นใน Inf1.6xlarge (หน่วยความจำ 48 GiB) เมื่อเทียบกับ g4dn.12xlarge (หน่วยความจำ 192 GiB) เนื่องจากความสามารถในการ Auto Casting ของคอมไพเลอร์ Neuron จะแปลงโมเดล FP32 เป็น 16 บิต bfloat โดยอัตโนมัติเพื่อเพิ่มปริมาณงาน

รุ่น อินสแตนซ์ EC2 ประเภทเซิร์ฟเวอร์ จำนวนรุ่นถังบรรจุต่ออินสแตนซ์ ราคาต่ออินสแตนซ์
(ตามความต้องการ), $/ชม.
ราคาต่อรุ่น-ชั่วโมง
($)
bert-เบส-เคส inf1.2xlarge FastAPI 24 0.362 0.015
bert-เบส-เคส g4dn.xlarge FastAPI 18 0.526 0.029
bert-เบส-เคส inf1.xlarge FastAPI 11 0.228 0.020
bert-เบส-เคส inf1.6xlarge FastAPI 76 1.180 0.015
bert-เบส-เคส g4dn.12xlarge FastAPI 72 3.912 0.054

วิธีการทดสอบและการสังเกต

ในการโหลดการทดสอบตามขนาด เราได้จำลองไคลเอนต์มากกว่า 40 ตัวที่ส่งคำขอพร้อมกันไปยังพูลการทดสอบ (โหลดจากไคลเอนต์หลายตัว) การโหลดระบบด้วยคำขอของผู้ใช้ที่มากขึ้นจะเพิ่มปริมาณงานโดยลดเวลาในการตอบสนอง การทดสอบได้รับการออกแบบเพื่อกวาดเส้นกราฟปริมาณงานและเวลาแฝงเพื่อค้นหาจุดข้อมูลด้วยการใช้ทรัพยากรที่เหมาะสมที่สุด เราวัดปริมาณงานและเวลาแฝง (P50, P90, P95) และสรุปผลลัพธ์ในตัวชี้วัดสี่ตัว: เวลาแฝง ปริมาณงาน (การอนุมานต่อวินาที) จำนวนรุ่นที่ให้บริการต่ออินสแตนซ์ และต้นทุน นอกจากนี้ เราได้สร้างการทดสอบเพื่อจำลองคำขอแบบ single-sequential และ single-random โดยใช้ curl เพื่อส่งคำขอ GET หรือ POST ไปยังแต่ละรุ่นในกลุ่มการทดสอบ จุดประสงค์ของการทดสอบเหล่านี้คือเพื่อวัดเวลาแฝงที่ดีที่สุดที่เราคาดไว้เป็นข้อมูลพื้นฐาน

เราทำการทดลองหลายครั้งเพื่อค้นหารูปแบบที่เหมาะสมที่สุดที่บรรจุอยู่ในชุดอินสแตนซ์ EC2 ขั้นต่ำ ซึ่งจะทำให้ได้ประสิทธิภาพสูงสุดด้วยต้นทุนที่ต่ำที่สุด ตารางต่อไปนี้สรุปผลการทดสอบบางส่วน พบผลลัพธ์ที่ดีที่สุดเมื่อใช้อินสแตนซ์ Inf40xl 1.6 ตัวที่เปิดใช้งานการแคช DNS โดยให้บริการโมเดล 3,040 ตัวที่มีปริมาณงาน 6,230 คำขอต่อวินาทีใน 66 มิลลิวินาที (เวลาแฝง P90) ในราคา $47.2/ชั่วโมง (ตามความต้องการ) การปรับใช้อินสแตนซ์แบบผสมที่ดีที่สุดโดยใช้อินสแตนซ์ 32 inf1.6xl และ 21 g4dn.12xl ส่งผลให้มีโมเดลให้บริการ 3,048 รุ่น แต่มีปริมาณงานต่ำกว่ามากที่ 248 คำขอต่อวินาที โดยมีค่าใช้จ่ายรายชั่วโมงเพิ่มขึ้น 119.91 ดอลลาร์ต่อชั่วโมง แม้ว่าเราจะไม่ได้ใช้อินสแตนซ์ Spot ของ EC2 เป็นตัวช่วยในการปรับต้นทุนให้เหมาะสมในสถาปัตยกรรมนี้ แต่เราขอแนะนำอย่างยิ่งให้ใช้ Spot หากปริมาณงานการอนุมานของคุณมีความยืดหยุ่นด้านเวลาและทนต่อข้อผิดพลาด ตารางต่อไปนี้สรุปการสังเกตของเราในประเภทอินสแตนซ์ต่างๆ

ประสบการณ์ # อินสแตนซ์
(ชนิดจำนวน x)
Models (น้ำ) การตอบสนองตามลำดับ (นางสาว) สุ่มตอบกลับ (นางสาว) ทางเข้า (คำขอ/วินาที) เวลาในการตอบสนองพร้อมโหลด P90 (นางสาว) ต้นทุนตามความต้องการ ($/ชม.)
1 3xinf1.6xl 144 21 - 32 21 - 30 142 57 3.54
2 5xinf1.6xl 240 23 - 35 21 - 35 173 56 5.9
3 21xinf1.6xl 1008 23 - 39 23 - 35 218 24 24.78
4 32xinf1.6xl 1536 26 - 33 25 - 37 217 23 37.76
5 4 x g4dn.12xl 288 27 - 34 28 - 37 178 30 15.64
6 14 x g4dn.12xl 1008 26 - 35 31 - 41 154 30 54.76
7 32xinf1.6xl+
21 x g4dn.12xl
3048 27 - 35 24 - 45 248 28 119.91
8 40xinf1.6xl 3002 24 - 31 25 - 38 1536 33 47.2
9 40xinf1.6xl
(ด้วยการแคช DNS)
3040 24 - 31 25 - 38 6230 66 47.2

สรุป

ด้วยสถาปัตยกรรมที่ปรับขนาดได้นี้ เราสามารถปรับขนาดการอนุมานในโมเดล PyTorch 3,000 โมเดล บรรลุเวลาแฝงเป้าหมายที่ 100 มิลลิวินาที ในขณะเดียวกันก็รักษาต้นทุนให้ต่ำกว่า 50 ดอลลาร์ต่อชั่วโมง (ตามความต้องการ) ได้ด้วยการเพิ่มประสิทธิภาพสำหรับต้นทุนด้วยโมเดลการบรรจุในถังอย่างมีประสิทธิภาพในชุดขั้นต่ำ ของอินสแตนซ์ EC2 จากการทดสอบทั้งหมด อินสแตนซ์ Inf1 ให้ปริมาณงานสูงสุด ต้นทุนต่ำสุด เวลาตอบสนองที่เร็วที่สุด และอัตราส่วนการบรรจุถังขยะสูงสุดเมื่อเทียบกับอินสแตนซ์อื่นๆ ลูกค้า AWS ชอบ Snap, Airbnb, Sprinklr และอีกมากมาย ได้ใช้ AWS Inferentia เพื่อให้ได้ประสิทธิภาพสูงสุดและต้นทุนต่ำสุดในการปรับใช้ที่หลากหลาย แม้ว่าโมเดล DL ที่ทดสอบจะต้องใช้การเร่งด้วยฮาร์ดแวร์ในประเภทอินสแตนซ์ Inf1 และ g4dn คุณสามารถจับคู่ประเภทโมเดลอื่นๆ กับอินสแตนซ์ประเภทต่างๆ (Inf1, CPU, GPU) และรุ่น bin pack ได้โดยใช้วิธีการที่อธิบายไว้

เรียนรู้เพิ่มเติมเกี่ยวกับชิป AWS Inferentia และ อินสแตนซ์ EC2 Inf1 เพื่อเริ่มต้นใช้งานไปป์ไลน์ ML แบบกำหนดเองของคุณบน AWS Inferentia โดยใช้ เซลล์ประสาท SDK.


เกี่ยวกับผู้เขียน

อเล็กซ์ เอียนคูลสกี้ เป็น Principal Solutions Architect โดยมุ่งเน้นที่ปริมาณงานอัตโนมัติโดยใช้คอนเทนเนอร์ Alex เป็นโครงสร้างพื้นฐานแบบฟูลสแตกและสถาปนิกซอฟต์แวร์ และได้สร้างแพลตฟอร์มโดยใช้ Docker เพื่อช่วยเร่งความเร็วของนวัตกรรมโดยการนำเทคโนโลยีคอนเทนเนอร์มาใช้กับปัญหาด้านวิศวกรรม วิทยาศาสตร์ข้อมูล และ AI ตลอด 10 ปีที่ผ่านมา เขาได้ทำงานเพื่อต่อสู้กับการเปลี่ยนแปลงสภาพภูมิอากาศ ทำให้ AI และ ML เป็นประชาธิปไตย และทำให้การเดินทางปลอดภัยยิ่งขึ้น ดูแลสุขภาพดีขึ้น และใช้พลังงานอย่างชาญฉลาดยิ่งขึ้น

มหาเทวัน บาละสุบรามาเนียม เป็น Principal Solutions Architect for Autonomous Computing โดยมีประสบการณ์เกือบ 20 ปีในด้านการเรียนรู้เชิงลึกที่สร้างด้วยฟิสิกส์ การสร้างและการนำ Digital Twin ไปใช้ในระบบอุตสาหกรรมตามขนาด Mahadevan สำเร็จการศึกษาระดับปริญญาเอกสาขาวิศวกรรมเครื่องกลจากสถาบันเทคโนโลยีแมสซาชูเซตส์ และมีสิทธิบัตรและสิ่งพิมพ์มากกว่า 25 รายการให้เครดิตของเขา

ซุนดาร์ รังคนาธาน เป็นหัวหน้าฝ่ายพัฒนาธุรกิจ ML Frameworks ในทีม Amazon EC2 เขามุ่งเน้นไปที่ปริมาณงาน ML ขนาดใหญ่ในบริการต่างๆ ของ AWS เช่น Amazon EKS, Amazon ECS, Elastic Fabric Adapter, AWS Batch และ Amazon SageMaker ประสบการณ์ของเขารวมถึงบทบาทความเป็นผู้นำในการจัดการผลิตภัณฑ์และการพัฒนาผลิตภัณฑ์ที่ NetApp, Micron Technology, Qualcomm และ Mentor Graphics

โจชัว คอร์เรีย เป็นสมาชิก Salesforce Principal ของเจ้าหน้าที่ด้านเทคนิคที่ทำงานในทีม Commerce Einstein Joshua มีความหลงใหลอย่างลึกซึ้งในการสร้างโครงสร้างพื้นฐานที่ปรับขนาดได้ ยืดหยุ่น และคุ้มค่าสำหรับการเรียนรู้ของเครื่อง Joshua สนุกกับการทำงานที่จุดตัดของวิศวกรรมซอฟต์แวร์และวิทยาศาสตร์ข้อมูลเพื่อนำแบบจำลองที่ทันสมัยมาสู่การผลิต

ที่มา: https://aws.amazon.com/blogs/machine-learning/serve-3000-deep-learning-models-on-amazon-eks-with-aws-inferentia-for-under-50-an-hour/

ประทับเวลา:

เพิ่มเติมจาก บล็อก AWS Machine Learning