- vừa được xem lúc

TorchServe, công cụ hỗ trợ triển khai mô hình PyTorch

0 0 27

Người đăng: Pham Minh Hoang

Theo Viblo Asia

Lời mở đầu

Hôm nay tôi sẽ giới thiệu sơ qua cho các bạn công cụ triển khai mô hình dành riêng cho mô hình PyTorch. Công cụ này gọi là TorchServe, mới phát triển gần đây nên repo ít sao hơn Tensorflow Serving và bug cũng nhiều hơn ?. Link Git repo: https://github.com/pytorch/serve

Sơ đồ hệ thống TorchServe

Như hình trên, hệ thống TorchServe chia là 3 phần: API, Core ( Backend & Frontend ), Model Storage.

Trong API sẽ chia ra 2 phần: Management API và Inference API, cái đầu sẽ quản lí trạng thái của query, trạng thái của mô hình, số lượng worker , cái sau là nơi tiếp nhận request của người dùng.

Trong core của TorchServe chia ra 2 phần: Frontend và Backend. Frontend tiếp nhận request của người dùng nếu nhiều request thì sẽ được batching và trả về các log thông báo trạng thái requests. Các batch request này thông qua inference endpoint để tới Backend, ở đây Backend chia các batch request đến từng tiến trình worker, mỗi worker quản lí một instance của mô hình đã huấn luyện.

Vậy mô hình lấy ở đâu? Tất nhiên trong model storage rồi, ở đây chứa nhiều mô hình dùng cho các task khác nhau: Classification, Detection, Segmentation, ... Mỗi mô hình sẽ có nhiều phiên bản khác nhau. TorchServe sẽ tự động load mô hình dựa trên config của người dùng.

Cài đặt TorchServe và torch-model-archiver

Đầu tiên bạn cần clone repo về đã:

git clone https://github.com/pytorch/serve
cd serve

Dựa trên môi trường mà bạn cần, có các lựa chọn cài đặt sau:

  • Với CPU cho Torch 1.7.1
python ./ts_scripts/install_dependencies.py
  • Với GPU và Cuda 10.2
python ./ts_scripts/install_dependencies.py --cuda=cu102
  • Với GPU và Cuda 10.1
python ./ts_scripts/install_dependencies.py --cuda=cu101
  • Với GPU và Cuda 9.2
python ./ts_scripts/install_dependencies.py --cuda=cu92

=> Cài đặt các dependencies cần thiết

Tiếp đó cài 2 thư viện quan trọng: torchserve và torch-model-archiver có thể bằng conda hoặc pip

  • Với Conda
conda install torchserve torch-model-archiver -c pytorch
  • Với Pip
pip install torchserve torch-model-archiver

Lưu mô hình bằng TorchServe

Tạo 1 folder ở đâu cũng được, đặt tên là model_store

mkdir model_store

Tải về 1 mô hình mẫu để triển khai và dự đoán xem sao. Ở đây tôi dùng densene161

wget https://download.pytorch.org/models/densenet161-8d451a50.pth

Dùng thư viện torch-model-archive để lưu lại mô hình dưới format mà TorchServe hỗ trợ

torch-model-archiver \
--model-name densenet161 \
--version 1.0 \
--model-file ./serve/examples/image_classifier/densenet_161/model.py \
--serialized-file densenet161-8d451a50.pth \
--export-path model_store \
--extra-files ./serve/examples/image_classifier/index_to_name.json \
--handler image_classifier

Giải thích các tham số trong câu lệnh trên:

  • model-name: tên mô hình
  • version: phiên bản bao nhiêu
  • model-file: model file, nếu bạn lưu mô hình bằng torch save thì không cần ( Optional )
  • serialized-file: bắt buộc, mô hình đã huấn luyện chờ convert, ở đây typing đường dẫn tới mô hình
  • export-path: nơi xuất
  • extra-files: file json chứa label ( Optional )
  • handler: bắt buộc, file xử lý ( tiền xử lý, hậu xử lý dữ liệu ), có thể thừa kế từ các class có sẵn trong repo hoặc custom lại theo đúng ý mình.

Kết quả:

Chạy server TorchServe

Sau khi có file trên thì bạn dùng command này. Command này sẽ mở endpoint cho request của người dùng cũng như thực thi các tiến trình ẩn bên trong để serve mô hình.

torchserve \
--start --ncs \
--model-store model_store \
--models densenet161.mar
  • start: bắt đầu phiên làm việc của TorchServe
  • stop: kết thúc phiên làm việc của TorchServe
  • model-store: nơi chứa mô hình, cụ thể là folder chứa file có đuôi .mar ban nãy
  • models: mô hình cần load, ví dụ densenet161.mar
  • log-config: file config cho log
  • ts-config: file config đặc biệt cho TorchServe, như điều chỉnh port chẳng hạn
  • foreground: show log khi chạy trên terminal, nếu disable ts sẽ chạy ẩn
  • ncs: disable snapshot

Link Inference API: http://127.0.0.1:8080

Link Management API: http://127.0.0.1:8081

Link Metric API: http://127.0.0.1:8082

2 cái link dưới chưa đề cập đến, chúng ta cùng tìm hiểu link đầu nào. Link này dùng để dự đoán kết quả bằng REST API

Tải về 1 ảnh trước đã:

curl -O https://raw.githubusercontent.com/pytorch/serve/master/docs/images/kitten_small.jpg

Dùng command line để gửi image request có method POST tới TorchServe endpoint

curl http://127.0.0.1:8080/predictions/densenet161 -T kitten_small.jpg

Output:

{ "tabby": 0.5237820744514465, "tiger_cat": 0.18530139327049255, "lynx": 0.15431317687034607, "tiger": 0.056817926466464996, "Egyptian_cat": 0.04702862352132797
}

Dự đoán qua gRPC

  • Trước hết tải về các thư viện hỗ trợ giao thức gRPC đã
pip install -U grpcio protobuf grpcio-tools
  • Trong folder serve, dùng proto file để gen gRPC client stub
python -m grpc_tools.protoc \
--proto_path=frontend/server/src/main/resources/proto/ \
--python_out=ts_scripts \
--grpc_python_out=ts_scripts frontend/server/src/main/resources/proto/inference.proto frontend/server/src/main/resources/proto/management.proto

  • Đăng ký mô hình sử dụng
python ts_scripts/torchserve_grpc_client.py register densenet161
  • Dự đoán 1 mẫu bằng gRPC python client
python ts_scripts/torchserve_grpc_client.py infer densenet161 examples/image_classifier/kitten.jpg
  • Hủy đăng ký mô hình
python ts_scripts/torchserve_grpc_client.py unregister densenet161

Mặc định, TorchServe chiếm 2 port 7070 cho gRPC Inference API và 7071 cho gRPC Management API

Kết quả thì tôi chưa thử gRPC nên cũng không show ra cho các bạn xem được ( thực ra thử rồi nhưng dính bug, phương thức dự đoán này mới được cập nhật trên repo của torchserve nên lỗi cũng là chiện bình thường ? )

Management API

Khi bạn có nhiều mô hình, đây là lúc bạn cần một công cụ quản lý hiệu quả và tất nhiên torchserve hỗ trợ cái này thông qua API endpoint. Các chức năng được hỗ trợ

  1. Đăng ký 1 mô hình
  2. Tăng/giảm số lượng worker cho một mô hình chỉ định
  3. Mô tả trạng thái của mô hình
  4. Hủy đăng ký mô hình
  5. Show các mô hình đã đăng ký
  6. Chỉ định một phiên bản mô hình làm mặc định

Đăng ký mô hình

Dùng phương thức POST: POST /models

Liệt kê các tham số:

  • url: đường dẫn tới mô hình có đuôi .mar hoặc đường dẫn tải mô hình từ Internet. Ví dụ: https://torchserve.pytorch.org/mar_files/squeezenet1_1.mar
  • model_name: tên mô hình
  • handler: hãy chắc rằng handler có trong PYTHONPATH. Format: module_name: method_name
  • runtime: mặc định PYTHON
  • batch_size: mặc định 1
  • max_batch_delay: thời gian chờ batch, mặc định 100 ms
  • initial_workers: số lượng worker khởi tạo, mặc định 0, TorchServe sẽ không chạy khi không có worker
  • synchronous: tạo worker đồng bộ hay không đồng bộ, mặc định false
  • response_timeout: thời gian chờ, mặc định 120 s
curl -X POST "http://localhost:8081/models?url=https://torchserve.pytorch.org/mar_files/squeezenet1_1.mar" { "status": "Model \"squeezenet_v1.1\" Version: 1.0 registered with 0 initial workers. Use scale workers API to add workers for the model."
}

Đăng ký mô hình cùng với tạo worker

curl -v -X POST "http://localhost:8081/models?initial_workers=1&synchronous=false&url=https://torchserve.pytorch.org/mar_files/squeezenet1_1.mar" * Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8081 (#0)
> POST /models?initial_workers=1&synchronous=false&url=https://torchserve.pytorch.org/mar_files/squeezenet1_1.mar HTTP/1.1
> Host: localhost:8081
> User-Agent: curl/7.58.0
> Accept: */*
> < HTTP/1.1 202 Accepted
< content-type: application/json
< x-request-id: 61d2b2b4-2a3a-49d4-84c9-e6f2f92cd36d
< Pragma: no-cache
< Cache-Control: no-cache; no-store, must-revalidate, private
< Expires: Thu, 01 Jan 1970 00:00:00 UTC
< content-length: 47
< connection: keep-alive
< { "status": "Processing worker updates..."
}
* Connection #0 to host localhost left intact

Scale workers

Dùng phương thức PUT: PUT /models/{model_name}

Liệt kê tham số:

  • min_worker: (Optional) số lượng worker nhỏ nhất, mặc định 1
  • max_worker: (Optional) số lượng worker nhiều nhất, mặc định 1, TorchServe sẽ không tạo worker vượt quá con số này
  • number_gpu: (Optional) số GPU worker tạo, mặc định 0, nếu số worker vượt qua số GPU có trên máy thì các worker còn lại sẽ chạy trên CPU
  • synchronous: mặc định false
  • timeout: thời gian chờ worker hoàn thành các pending requests. Nếu vượt qua con số này, worker sẽ dừng hoạt động. Giá trị 0 sẽ dừng tiến trình worker ngay lập tức. Giá trị -1 sẽ đợi vô thời hạn. Mặc định -1
curl -v -X PUT "http://localhost:8081/models/squeezenet1_1/?min_worker=3" * Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8081 (#0)
> PUT /models/squeezenet1_1/?min_worker=3 HTTP/1.1
> Host: localhost:8081
> User-Agent: curl/7.58.0
> Accept: */*
> < HTTP/1.1 202 Accepted
< content-type: application/json
< x-request-id: b508190b-ef7d-4e7a-a361-6dac1036d2bd
< Pragma: no-cache
< Cache-Control: no-cache; no-store, must-revalidate, private
< Expires: Thu, 01 Jan 1970 00:00:00 UTC
< content-length: 47
< connection: keep-alive
< { "status": "Processing worker updates..."
}
* Connection #0 to host localhost left intact

Nếu mô hình có nhiều phiên bản: PUT /models/{model_name}/{version}

curl -v -X PUT "http://localhost:8081/models/squeezenet1_1/1.0?min_worker=3"

Mô tả mô hình

Dùng phương thức GET: GET /models/{model_name}

curl http://localhost:8081/models/squeezenet1_1 [ { "modelName": "squeezenet1_1", "modelVersion": "1.0", "modelUrl": "https://torchserve.pytorch.org/mar_files/squeezenet1_1.mar", "runtime": "python", "minWorkers": 3, "maxWorkers": 3, "batchSize": 1, "maxBatchDelay": 100, "loadedAtStartup": false, "workers": [ { "id": "9001", "startTime": "2020-12-16T15:13:43.722Z", "status": "READY", "gpu": true, "memoryUsage": 2044100608 }, { "id": "9002", "startTime": "2020-12-16T15:52:52.561Z", "status": "READY", "gpu": true, "memoryUsage": 2045640704 }, { "id": "9003", "startTime": "2020-12-16T15:52:52.561Z", "status": "READY", "gpu": true, "memoryUsage": 2060914688 } ] }
]

Nếu mô hình có nhiều phiên bản: GET /models/{model_name}/all

Hủy đăng ký mô hình

Dùng phương thức Delete: DELETE /models/{model_name}/{version}

curl -X DELETE http://localhost:8081/models/squeezenet1_1/1.0 { "status": "Model \"squeezenet1_1\" unregistered"
}

Liệt kê các mô hình đăng ký

Dùng phương thức GET: GET /models

Các tham số:

  • limit: (Optional) số item trả về, mặc định 100
  • next_page_token: (Optional) trang thứ mấy
curl "http://localhost:8081/models" { "models": [ { "modelName": "densenet161", "modelUrl": "densenet161.mar" }, { "modelName": "squeezenet1_1", "modelUrl": "https://torchserve.pytorch.org/mar_files/squeezenet1_1.mar" } ]
}

Set mô hình mặc định

Dùng phương thức PUT: PUT /models/{model_name}/{version}/set-default

curl -v -X PUT http://localhost:8081/models/squeezenet1_1/1.0/set-default * Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8081 (#0)
> PUT /models/squeezenet1_1/1.0/set-default HTTP/1.1
> Host: localhost:8081
> User-Agent: curl/7.58.0
> Accept: */*
> < HTTP/1.1 200 OK
< content-type: application/json
< x-request-id: 6db1cff1-7517-4826-b146-0e8605ecfd36
< Pragma: no-cache
< Cache-Control: no-cache; no-store, must-revalidate, private
< Expires: Thu, 01 Jan 1970 00:00:00 UTC
< content-length: 93
< connection: keep-alive
< { "status": "Default vesion succsesfully updated for model \"squeezenet1_1\" to \"1.0\""
}
* Connection #0 to host localhost left intact

Kết luận

Hôm nay viết đến đây thôi, ai có hứng thú thì lên repo của TorchServe để vọc vạch nhé.

References

https://github.com/pytorch/serve

Bình luận

Bài viết tương tự

- vừa được xem lúc

Hành trình AI của một sinh viên tồi

Mình ngồi gõ những dòng này vào lúc 2h sáng (chính xác là 2h 2 phút), quả là một đêm khó ngủ. Có lẽ vì lúc chiều đã uống cốc nâu đá mà giờ mắt mình tỉnh như sáo, cũng có thể là vì những trăn trở về lý thuyết chồng chất ánh xạ mình đọc ban sáng khiến không tài nào chợp mắt được hoặc cũng có thể do mì

0 0 131

- vừa được xem lúc

[Deep Learning] Key Information Extraction from document using Graph Convolution Network - Bài toán trích rút thông tin từ hóa đơn với Graph Convolution Network

Các nội dung sẽ được đề cập trong bài blog lần này. . Tổng quan về GNN, GCN. Bài toán Key Information Extraction, trích rút thông tin trong văn bản từ ảnh.

0 0 204

- vừa được xem lúc

Tìm hiểu về YOLO trong bài toán real-time object detection

1.Yolo là gì. . Họ các mô hình RCNN ( Region-Based Convolutional Neural Networks) để giải quyết các bài toán về định vị và nhận diện vật thể.

0 0 272

- vừa được xem lúc

Encoding categorical features in Machine learning

Khi tiếp cận với một bài toán machine learning, khả năng cao là chúng ta sẽ phải đối mặt với dữ liệu dạng phân loại (categorical data). Khác với các dữ liệu dạng số, máy tính sẽ không thể hiểu và làm việc trực tiếp với categorical variable.

0 0 244

- vừa được xem lúc

TF Lite with Android Mobile

Như các bạn đã biết việc đưa ứng dụng đến với người sử dụng thực tế là một thành công lớn trong Machine Learning.Việc làm AI nó không chỉ dừng lại ở mức nghiên cứu, tìm ra giải pháp, chứng minh một giải pháp mới,... mà quan trọng là đưa được những nghiên cứu đó vào ứng dụng thực tế, được sử dụng để

0 0 55

- vừa được xem lúc

Xây dựng hệ thống Real-time Multi-person Tracking với YOLOv3 và DeepSORT

Trong bài này chúng ta sẽ xây dựng một hệ thống sử dụng YOLOv3 kết hợp với DeepSORT để tracking được các đối tượng trên camera, YOLO là một thuật toán deep learning ra đời vào tháng 5 năm 2016 và nó nhanh chóng trở nên phổ biến vì nó quá nhanh so với thuật toán deep learning trước đó, sử dụng YOLO t

0 0 303