Hiệu suất của TensorFlow Serve phụ thuộc nhiều vào ứng dụng mà nó chạy, môi trường mà nó được triển khai và phần mềm khác mà nó chia sẻ quyền truy cập vào các tài nguyên phần cứng cơ bản. Do đó, việc điều chỉnh hiệu suất của nó phần nào phụ thuộc vào từng trường hợp và có rất ít quy tắc chung được đảm bảo mang lại hiệu suất tối ưu trong mọi cài đặt. Như đã nói, tài liệu này nhằm mục đích nắm bắt một số nguyên tắc chung và các phương pháp hay nhất để chạy Dịch vụ TensorFlow.
Vui lòng sử dụng hướng dẫn Yêu cầu suy luận hồ sơ với TensorBoard để hiểu hành vi cơ bản trong tính toán mô hình của bạn đối với các yêu cầu suy luận và sử dụng hướng dẫn này để liên tục cải thiện hiệu suất của mô hình.
Mẹo nhanh
- Độ trễ của yêu cầu đầu tiên quá cao? Bật khởi động mô hình .
- Quan tâm đến việc sử dụng tài nguyên hoặc thông lượng cao hơn? Định cấu hình theo đợt
Điều chỉnh hiệu suất: Mục tiêu và thông số
Khi tinh chỉnh hiệu suất của TensorFlow Serve, bạn thường có 2 loại mục tiêu và 3 nhóm tham số cần điều chỉnh để cải thiện các mục tiêu đó.
Mục tiêu
TensorFlow Serve là một hệ thống phục vụ trực tuyến dành cho các mô hình học máy. Giống như nhiều hệ thống phân phối trực tuyến khác, mục tiêu hiệu suất chính của nó là tối đa hóa thông lượng trong khi vẫn giữ độ trễ cuối dưới giới hạn nhất định . Tùy thuộc vào chi tiết và mức độ hoàn thiện của ứng dụng, bạn có thể quan tâm nhiều hơn đến độ trễ trung bình hơn độ trễ ở đuôi , nhưng một số khái niệm về độ trễ và thông lượng thường là số liệu mà bạn đặt ra mục tiêu hiệu suất. Lưu ý rằng chúng tôi không thảo luận về tính khả dụng trong hướng dẫn này vì đó là chức năng của môi trường triển khai.
Thông số
Chúng ta có thể nghĩ đại khái về 3 nhóm tham số có cấu hình xác định hiệu suất quan sát được: 1) mô hình TensorFlow 2) yêu cầu suy luận và 3) máy chủ (phần cứng & nhị phân).
1) Mô hình TensorFlow
Mô hình xác định tính toán mà TensorFlow Serve sẽ thực hiện khi nhận được mỗi yêu cầu đến.
Bên dưới, TensorFlow Serve sử dụng thời gian chạy TensorFlow để thực hiện suy luận thực tế về yêu cầu của bạn. Điều này có nghĩa là độ trễ trung bình của việc phân phát yêu cầu bằng Dịch vụ TensorFlow thường ít nhất bằng độ trễ thực hiện suy luận trực tiếp với TensorFlow. Điều này có nghĩa là nếu trên một máy nhất định, việc suy luận trên một ví dụ duy nhất mất 2 giây và bạn có mục tiêu về độ trễ dưới giây, thì bạn cần lập hồ sơ các yêu cầu suy luận, hiểu các hoạt động TensorFlow và biểu đồ phụ nào trong mô hình của bạn đóng góp nhiều nhất vào độ trễ đó và thiết kế lại mô hình của bạn với độ trễ suy luận như một hạn chế về thiết kế.
Xin lưu ý, mặc dù độ trễ trung bình của việc thực hiện suy luận với TensorFlow Serve thường không thấp hơn so với việc sử dụng TensorFlow trực tiếp, nhưng TensorFlow Serve tỏa sáng đang giúp giảm độ trễ đuôi cho nhiều khách hàng truy vấn nhiều mô hình khác nhau, đồng thời sử dụng hiệu quả phần cứng cơ bản để tối đa hóa thông lượng .
2) Yêu cầu suy luận
Bề mặt API
Dịch vụ TensorFlow có hai bề mặt API (HTTP và gRPC), cả hai đều triển khai API PredictionService (ngoại trừ Máy chủ HTTP không hiển thị điểm cuối MultiInference
). Cả hai bề mặt API đều được điều chỉnh cao và tăng độ trễ tối thiểu nhưng trên thực tế, bề mặt gRPC được quan sát là có hiệu suất cao hơn một chút.
Phương thức API
Nói chung, bạn nên sử dụng các điểm cuối Phân loại và Hồi quy vì chúng chấp nhận tf.Example , đây là một mức độ trừu tượng cao hơn; tuy nhiên, trong một số trường hợp hiếm gặp về các yêu cầu có cấu trúc lớn (O(Mb)), người dùng hiểu biết có thể sử dụng PredictRequest và mã hóa trực tiếp các tin nhắn Protobuf của họ thành TensorProto, đồng thời bỏ qua quá trình tuần tự hóa và giải tuần tự hóa từ tf. Ví dụ, đây là một nguồn tăng hiệu suất nhẹ.
Kích thước lô
Có hai cách chính mà việc tạo khối có thể giúp ích cho hiệu suất của bạn. Bạn có thể định cấu hình ứng dụng khách của mình để gửi các yêu cầu theo đợt tới Dịch vụ TensorFlow hoặc bạn có thể gửi các yêu cầu riêng lẻ và định cấu hình Dịch vụ TensorFlow để chờ đến một khoảng thời gian xác định trước và thực hiện suy luận theo một đợt đối với tất cả các yêu cầu đến trong khoảng thời gian đó. Việc định cấu hình loại phân khối thứ hai cho phép bạn đạt được Dịch vụ TensorFlow ở QPS cực cao, đồng thời cho phép nó mở rộng quy mô tuyến tính các tài nguyên điện toán cần thiết để theo kịp. Điều này sẽ được thảo luận thêm trong hướng dẫn cấu hình và README theo đợt .
3) Máy chủ (Phần cứng & nhị phân)
Hệ nhị phân TensorFlow Serve thực hiện tính toán khá chính xác về phần cứng mà nó chạy trên đó. Vì vậy, bạn nên tránh chạy các ứng dụng sử dụng nhiều điện toán hoặc bộ nhớ khác trên cùng một máy, đặc biệt là những ứng dụng sử dụng tài nguyên động.
Cũng như nhiều loại khối lượng công việc khác, TensorFlow Serve hiệu quả hơn khi được triển khai trên ít máy hơn, lớn hơn (nhiều CPU và RAM) hơn (tức là Deployment
với replicas
thấp hơn theo thuật ngữ Kubernetes). Điều này là do tiềm năng triển khai nhiều người thuê để sử dụng phần cứng tốt hơn và chi phí cố định thấp hơn (máy chủ RPC, thời gian chạy TensorFlow, v.v.).
Máy gia tốc
Nếu máy chủ của bạn có quyền truy cập vào trình tăng tốc, hãy đảm bảo rằng bạn đã triển khai mô hình của mình để thực hiện các phép tính dày đặc trên trình tăng tốc - việc này sẽ được thực hiện tự động nếu bạn đã sử dụng API TensorFlow cấp cao, nhưng nếu bạn đã xây dựng biểu đồ tùy chỉnh hoặc muốn ghim các phần cụ thể của biểu đồ trên các bộ tăng tốc cụ thể, bạn có thể cần đặt thủ công một số đồ thị con nhất định trên các bộ tăng tốc (tức là sử dụng with tf.device('/device:GPU:0'): ...
).
CPU hiện đại
Các CPU hiện đại đã liên tục mở rộng kiến trúc tập lệnh x86 để cải thiện khả năng hỗ trợ cho SIMD (Nhiều dữ liệu một lệnh) và các tính năng quan trọng khác cho các phép tính dày đặc (ví dụ: nhân và cộng trong một chu kỳ xung nhịp). Tuy nhiên, để chạy trên các máy cũ hơn một chút, TensorFlow và TensorFlow Serve được xây dựng với giả định khiêm tốn rằng tính năng mới nhất trong số này không được CPU chủ hỗ trợ.
Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
Nếu bạn thấy mục nhật ký này (có thể khác với 2 tiện ích mở rộng được liệt kê) khi khởi động Dịch vụ TensorFlow, điều đó có nghĩa là bạn có thể xây dựng lại Dịch vụ TensorFlow và nhắm mục tiêu nền tảng máy chủ cụ thể của mình và tận hưởng hiệu suất tốt hơn. Xây dựng TensorFlow Phục vụ từ nguồn tương đối dễ dàng bằng Docker và được ghi lại ở đây .
Cấu hình nhị phân
TensorFlow Serve cung cấp một số nút cấu hình chi phối hành vi thời gian chạy của nó, chủ yếu được đặt thông qua cờ dòng lệnh . Một số trong số này (đáng chú ý nhất là tensorflow_intra_op_parallelism
và tensorflow_inter_op_parallelism
) được chuyển xuống để định cấu hình thời gian chạy TensorFlow và được định cấu hình tự động, mà người dùng hiểu biết có thể ghi đè bằng cách thực hiện nhiều thử nghiệm và tìm cấu hình phù hợp cho khối lượng công việc và môi trường cụ thể của họ.
Vòng đời của một TensorFlow Phục vụ yêu cầu suy luận
Chúng ta hãy điểm qua ngắn gọn vòng đời của một ví dụ nguyên mẫu về yêu cầu suy luận TensorFlow Serve để xem hành trình mà một yêu cầu điển hình trải qua. Trong ví dụ của chúng tôi, chúng tôi sẽ đi sâu vào Yêu cầu dự đoán đang được nhận bởi bề mặt API gRPC phục vụ TensorFlow 2.0.0.
Trước tiên, chúng ta hãy xem sơ đồ trình tự cấp thành phần, sau đó chuyển sang mã triển khai chuỗi tương tác này.
Sơ đồ trình tự
Lưu ý rằng Client là thành phần do người dùng sở hữu, Prediction Service, Servables và Server Core thuộc sở hữu của TensorFlow Serve và TensorFlow Runtime thuộc sở hữu của Core TensorFlow .
Chi tiết trình tự
-
PredictionServiceImpl::Predict
nhận đượcPredictRequest
- Chúng tôi gọi
TensorflowPredictor::Predict
, truyền bá thời hạn yêu cầu từ yêu cầu gRPC (nếu một yêu cầu đã được đặt). - Bên trong
TensorflowPredictor::Predict
, chúng tôi tra cứu (mô hình) có thể phục vụ mà yêu cầu đang tìm cách thực hiện suy luận, từ đó chúng tôi truy xuất thông tin về SavingModel và quan trọng hơn là điều khiển đối tượngSession
trong đó biểu đồ mô hình (có thể là một phần) nạp vào. Đối tượng có thể phục vụ này đã được tạo và cam kết trong bộ nhớ khi mô hình được phục vụ TensorFlow tải. Sau đó, chúng tôi gọi nội bộ::RunPredict để thực hiện dự đoán. - Trong
internal::RunPredict
, sau khi xác thực và xử lý trước yêu cầu, chúng tôi sử dụng đối tượngSession
để thực hiện suy luận bằng cách sử dụng lệnh gọi chặn tới Session::Run , tại thời điểm đó, chúng tôi nhập cơ sở mã của TensorFlow lõi. Sau khiSession::Run
trả về và tensoroutputs
của chúng tôi đã được điền, chúng tôi chuyển đổi đầu ra thànhPredictionResponse
và trả kết quả lên ngăn xếp cuộc gọi.