1. Tổng quan
Trong bài tập thực hành này, bạn sẽ sử dụng Vertex AI để nhận kết quả dự đoán từ một mô hình phân loại hình ảnh được huấn luyện trước.
Kiến thức bạn sẽ học được
Bạn sẽ tìm hiểu cách:
- Nhập mô hình TensorFlow vào Vertex AI Model Registry
- Nhận kết quả dự đoán trực tuyến
- Cập nhật hàm phân phát TensorFlow
Tổng chi phí để chạy bài tập thực hành này trên Google Cloud là khoảng 1 USD.
2. Giới thiệu về Vertex AI
Bài tập thực hành này sử dụng sản phẩm AI mới nhất hiện có trên Google Cloud. Vertex AI tích hợp các sản phẩm ML trên Google Cloud thành một trải nghiệm phát triển liền mạch. Trước đây, các mô hình được huấn luyện bằng AutoML và các mô hình tuỳ chỉnh có thể truy cập thông qua các dịch vụ riêng biệt. Sản phẩm mới này kết hợp cả hai thành một API duy nhất, cùng với các sản phẩm mới khác. Bạn cũng có thể di chuyển các dự án hiện có sang Vertex AI.
Vertex AI bao gồm nhiều sản phẩm khác nhau để hỗ trợ quy trình làm việc ML từ đầu đến cuối. Bài tập thực hành này sẽ tập trung vào các sản phẩm được nêu bật bên dưới: Predictions và Workbench

3. Tổng quan về trường hợp sử dụng
Trong bài tập thực hành này, bạn sẽ tìm hiểu cách lấy một mô hình được huấn luyện tiền kỳ từ TensorFlow Hub và triển khai mô hình đó trên Vertex AI. TensorFlow Hub là một kho lưu trữ các mô hình đã huấn luyện cho nhiều miền có vấn đề, chẳng hạn như mô hình nhúng, tạo văn bản, chuyển giọng nói thành văn bản, phân đoạn hình ảnh và nhiều mô hình khác.
Ví dụ được sử dụng trong bài tập thực hành này là một mô hình phân loại hình ảnh MobileNet V1 được huấn luyện trước trên tập dữ liệu ImageNet. Bằng cách tận dụng các mô hình có sẵn từ TensorFlow Hub hoặc các kho lưu trữ học sâu tương tự khác, bạn có thể triển khai các mô hình học máy chất lượng cao cho một số nhiệm vụ dự đoán mà không phải lo lắng về việc huấn luyện mô hình.
4. Thiết lập môi trường
Bạn cần có một dự án trên Google Cloud Platform đã bật tính năng thanh toán để chạy lớp học lập trình này. Để tạo một dự án, hãy làm theo hướng dẫn tại đây.
Bước 1: Bật Compute Engine API
Chuyển đến Compute Engine rồi chọn Bật nếu bạn chưa bật.
Bước 2: Bật Vertex AI API
Chuyển đến phần Vertex AI của Cloud Console rồi nhấp vào Bật Vertex AI API.

Bước 3: Tạo một thực thể Vertex AI Workbench
Trong phần Vertex AI của Cloud Console, hãy nhấp vào Workbench:

Bật Notebooks API nếu bạn chưa bật.

Sau khi bật, hãy nhấp vào SỔ GHI CHÚ ĐƯỢC QUẢN LÝ:

Sau đó, chọn SỔ GHI CHÚ MỚI.

Đặt tên cho sổ ghi chú của bạn, rồi trong phần Quyền , hãy chọn Tài khoản dịch vụ

Chọn Cài đặt nâng cao.
Trong phần Bảo mật , hãy chọn "Bật thiết bị đầu cuối" nếu bạn chưa bật.

Bạn có thể để nguyên tất cả các chế độ cài đặt nâng cao khác.
Tiếp theo, hãy nhấp vào Tạo. Thực thể sẽ mất vài phút để được cung cấp.
Sau khi tạo thực thể, hãy chọn MỞ JUPYTERLAB.

5. Đăng ký mô hình
Bước 1: Tải mô hình lên Cloud Storage
Nhấp vào đường liên kết này để chuyển đến trang TensorFlow Hub cho mô hình MobileNet V1 được huấn luyện trên tập dữ liệu ImagNet.
Chọn Tải xuống để tải các cấu phần phần mềm mô hình đã lưu xuống.

Trong phần Cloud Storage của bảng điều khiển Cloud, hãy chọn TẠO

Đặt tên cho bộ chứa của bạn rồi chọn us-central1 làm vùng. Sau đó, nhấp vào TẠO

Tải mô hình TensorFlow Hub mà bạn đã tải xuống lên nhóm. Hãy nhớ giải nén tệp trước.

Nhóm của bạn sẽ có dạng như sau:
imagenet_mobilenet_v1_050_128_classification_5/
saved_model.pb
variables/
variables.data-00000-of-00001
variables.index
Bước 2: Nhập mô hình vào sổ đăng ký
Chuyển đến phần Model registry (Sổ đăng ký mô hình) của Vertex AI trong bảng điều khiển Cloud.

Chọn IMPORT
Chọn Import as new model (Nhập dưới dạng mô hình mới), sau đó cung cấp tên cho mô hình của bạn.

Trong phần Model settings (Cài đặt mô hình), hãy chỉ định vùng chứa TensorFlow được tạo sẵn gần đây nhất. Sau đó, chọn đường dẫn trong Cloud Storage nơi bạn đã lưu trữ các cấu phần phần mềm mô hình.

Bạn có thể bỏ qua phần Explainability (Khả năng giải thích).
Sau đó, chọn IMPORT
Sau khi nhập, bạn sẽ thấy mô hình của mình trong sổ đăng ký mô hình

6. Triển khai mô hình
Trong Model registry (Sổ đăng ký mô hình), hãy chọn 3 dấu chấm ở bên phải mô hình rồi nhấp vào Deploy to endpoint (Triển khai đến điểm cuối).

Trong phần Define your endpoint (Xác định điểm cuối), hãy chọn create new endpoint (tạo điểm cuối mới) rồi đặt tên cho điểm cuối.
Trong phần Model settings (Cài đặt mô hình), hãy đặt Maximum number of compute nodes (Số lượng nút tính toán tối đa) thành 1 và loại máy thành n1-standard-2 rồi để nguyên tất cả các chế độ cài đặt khác. Sau đó, nhấp vào TRIỂN KHAI.

Khi được triển khai, trạng thái triển khai sẽ thay đổi thành Deployed on Vertex AI (Đã triển khai trên Vertex AI).

7. Nhận kết quả dự đoán
Mở sổ ghi chú Workbench mà bạn đã tạo trong các bước thiết lập. Trong trình chạy, hãy tạo một sổ ghi chú TensorFlow 2 mới.

Thực thi ô sau để nhập các thư viện cần thiết
from google.cloud import aiplatform
import tensorflow as tf
import numpy as np
from PIL import Image
Mô hình MobileNet mà bạn đã tải xuống từ TensorFlow Hub được huấn luyện trên tập dữ liệu ImageNet. Kết quả của mô hình MobileNet là một số tương ứng với nhãn lớp trong tập dữ liệu ImageNet. Để chuyển số đó thành nhãn chuỗi, bạn cần tải nhãn hình ảnh xuống.
# Download image labels
labels_path = tf.keras.utils.get_file('ImageNetLabels.txt','https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt')
imagenet_labels = np.array(open(labels_path).read().splitlines())
Để truy cập vào điểm cuối, bạn cần xác định tài nguyên điểm cuối. Hãy nhớ thay thế {PROJECT_NUMBER} và {ENDPOINT_ID}.
PROJECT_NUMBER = "{PROJECT_NUMBER}"
ENDPOINT_ID = "{ENDPOINT_ID}"
endpoint = aiplatform.Endpoint(
endpoint_name=f"projects/{PROJECT_NUMBER}/locations/us-central1/endpoints/{ENDPOINT_ID}")
Bạn có thể tìm thấy số dự án trên trang chủ của bảng điều khiển.

Và mã nhận dạng điểm cuối trong phần Endpoints (Điểm cuối) của Vertex AI.

Tiếp theo, bạn sẽ kiểm thử điểm cuối.
Trước tiên, hãy tải hình ảnh sau xuống rồi tải lên thực thể của bạn.

Mở hình ảnh bằng PIL. Sau đó, đổi kích thước và tỷ lệ theo 255. Xin lưu ý rằng bạn có thể tìm thấy kích thước hình ảnh mà mô hình mong đợi trên trang TensorFlow Hub của mô hình.
IMAGE_PATH = "test-image.jpg"
IMAGE_SIZE = (128, 128)
im = Image.open(IMAGE_PATH)
im = im.resize(IMAGE_SIZE
im = np.array(im)/255.0
Tiếp theo, hãy chuyển đổi dữ liệu NumPy thành một danh sách để có thể gửi trong phần nội dung của yêu cầu http.
x_test = im.astype(np.float32).tolist()
Cuối cùng, hãy thực hiện lệnh gọi dự đoán đến điểm cuối rồi tra cứu nhãn chuỗi tương ứng.
# make prediction request
result = endpoint.predict(instances=[x_test]).predictions
# post process result
predicted_class = tf.math.argmax(result[0], axis=-1)
string_label = imagenet_labels[predicted_class]
print(f"label ID: {predicted_class}")
print(f"string label: {string_label}")
8. [Không bắt buộc] Sử dụng TF Serving để tối ưu hoá kết quả dự đoán
Đối với các ví dụ thực tế hơn, có lẽ bạn sẽ muốn gửi trực tiếp hình ảnh đến điểm cuối thay vì tải hình ảnh đó vào NumPy trước. Cách này hiệu quả hơn nhưng bạn sẽ phải sửa đổi hàm phân phát của mô hình TensorFlow. Bạn cần sửa đổi để chuyển đổi dữ liệu đầu vào sang định dạng mà mô hình của bạn mong đợi.
Bước 1: Sửa đổi hàm phân phát
Mở một sổ ghi chú TensorFlow mới rồi nhập các thư viện cần thiết.
from google.cloud import aiplatform
import tensorflow as tf
Thay vì tải các cấu phần phần mềm mô hình đã lưu xuống, lần này bạn sẽ tải mô hình vào TensorFlow bằng hub.KerasLayer, gói một TensorFlow SavedModel dưới dạng lớp Keras. Để tạo mô hình, bạn có thể sử dụng Keras Sequential API với mô hình TF Hub đã tải xuống dưới dạng lớp và chỉ định hình dạng đầu vào cho mô hình.
tfhub_model = tf.keras.Sequential(
[hub.KerasLayer("https://tfhub.dev/google/imagenet/mobilenet_v1_050_128/classification/5")]
)
tfhub_model.build([None, 128, 128, 3])
Xác định URI cho nhóm mà bạn đã tạo trước đó.
BUCKET_URI = "gs://{YOUR_BUCKET}"
MODEL_DIR = BUCKET_URI + "/bytes_model"
Khi bạn gửi yêu cầu đến một máy chủ dự đoán trực tuyến, yêu cầu đó sẽ được một máy chủ HTTP nhận. Máy chủ HTTP trích xuất yêu cầu dự đoán từ phần nội dung yêu cầu HTTP. Yêu cầu dự đoán đã trích xuất được chuyển tiếp đến hàm phân phát. Đối với các vùng chứa dự đoán được tạo sẵn của Vertex AI, nội dung yêu cầu được truyền đến hàm phân phát dưới dạng tf.string.
Để truyền hình ảnh đến dịch vụ dự đoán, bạn cần mã hoá các byte hình ảnh đã nén thành base 64. Điều này giúp nội dung an toàn khỏi việc sửa đổi trong khi truyền dữ liệu nhị phân qua mạng.
Vì mô hình đã triển khai mong đợi dữ liệu đầu vào dưới dạng byte thô (chưa nén), nên bạn cần đảm bảo rằng dữ liệu được mã hoá base 64 được chuyển đổi trở lại thành byte thô (ví dụ: JPEG), sau đó được xử lý trước để khớp với các yêu cầu về dữ liệu đầu vào của mô hình, trước khi được truyền dưới dạng dữ liệu đầu vào cho mô hình đã triển khai.
Để giải quyết vấn đề này, bạn hãy xác định một hàm phân phát (serving_fn) và đính kèm hàm đó vào mô hình dưới dạng bước xử lý trước. Bạn thêm một trình trang trí @tf.function để hàm phân phát được hợp nhất với mô hình cơ bản (thay vì ở thượng nguồn trên CPU).
CONCRETE_INPUT = "numpy_inputs"
def _preprocess(bytes_input):
decoded = tf.io.decode_jpeg(bytes_input, channels=3)
decoded = tf.image.convert_image_dtype(decoded, tf.float32)
resized = tf.image.resize(decoded, size=(128, 128))
return resized
@tf.function(input_signature=[tf.TensorSpec([None], tf.string)])
def preprocess_fn(bytes_inputs):
decoded_images = tf.map_fn(
_preprocess, bytes_inputs, dtype=tf.float32, back_prop=False
)
return {
CONCRETE_INPUT: decoded_images
} # User needs to make sure the key matches model's input
@tf.function(input_signature=[tf.TensorSpec([None], tf.string)])
def serving_fn(bytes_inputs):
images = preprocess_fn(bytes_inputs)
prob = m_call(**images)
return prob
m_call = tf.function(tfhub_model.call).get_concrete_function(
[tf.TensorSpec(shape=[None, 128, 128, 3], dtype=tf.float32, name=CONCRETE_INPUT)]
)
tf.saved_model.save(tfhub_model, MODEL_DIR, signatures={"serving_default": serving_fn})
Khi bạn gửi dữ liệu để dự đoán dưới dạng gói yêu cầu HTTP, dữ liệu hình ảnh sẽ được mã hoá base64, nhưng mô hình TensorFlow sẽ lấy dữ liệu đầu vào numpy. Hàm phân phát của bạn sẽ thực hiện việc chuyển đổi từ base64 sang mảng numpy.
Khi đưa ra yêu cầu dự đoán, bạn cần định tuyến yêu cầu đến hàm phân phát thay vì mô hình, vì vậy, bạn cần biết tên lớp đầu vào của hàm phân phát. Chúng ta có thể lấy tên này từ chữ ký hàm phân phát.
loaded = tf.saved_model.load(MODEL_DIR)
serving_input = list(
loaded.signatures["serving_default"].structured_input_signature[1].keys()
)[0]
print("Serving function input name:", serving_input)
Bước 2: Nhập vào sổ đăng ký và triển khai
Trong các phần trước, bạn đã thấy cách nhập mô hình vào Vertex AI Model Registry (Sổ đăng ký mô hình Vertex AI) thông qua giao diện người dùng. Trong phần này, bạn sẽ thấy một cách thay thế bằng cách sử dụng SDK. Xin lưu ý rằng bạn vẫn có thể sử dụng giao diện người dùng tại đây nếu muốn.
model = aiplatform.Model.upload(
display_name="optimized-model",
artifact_uri=MODEL_DIR,
serving_container_image_uri="us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-8:latest",
)
print(model)
Bạn cũng có thể triển khai mô hình bằng SDK thay vì giao diện người dùng.
endpoint = model.deploy(
deployed_model_display_name='my-bytes-endpoint',
traffic_split={"0": 100},
machine_type="n1-standard-4",
accelerator_count=0,
min_replica_count=1,
max_replica_count=1,
)
Bước 3: Kiểm thử mô hình
Giờ đây, bạn có thể kiểm thử điểm cuối. Vì chúng ta đã sửa đổi hàm phân phát, nên lần này bạn có thể gửi trực tiếp hình ảnh (được mã hoá base64) trong yêu cầu thay vì tải hình ảnh vào NumPy trước. Điều này cũng cho phép bạn gửi hình ảnh lớn hơn mà không vượt quá giới hạn kích thước của Vertex AI Predictions.
Tải lại nhãn hình ảnh xuống
import numpy as np
labels_path = tf.keras.utils.get_file('ImageNetLabels.txt','https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt')
imagenet_labels = np.array(open(labels_path).read().splitlines())
Mã hoá hình ảnh Base64.
import base64
with open("test-image.jpg", "rb") as f:
data = f.read()
b64str = base64.b64encode(data).decode("utf-8")
Thực hiện lệnh gọi dự đoán, chỉ định tên lớp đầu vào của hàm phân phát mà chúng ta đã xác định trong biến serving_input trước đó.
instances = [{serving_input: {"b64": b64str}}]
# Make request
result = endpoint.predict(instances=instances).predictions
# Convert image class to string label
predicted_class = tf.math.argmax(result[0], axis=-1)
string_label = imagenet_labels[predicted_class]
print(f"label ID: {predicted_class}")
print(f"string label: {string_label}")
🎉 Xin chúc mừng! 🎉
Bạn đã tìm hiểu cách sử dụng Vertex AI để:
- Lưu trữ và triển khai mô hình được huấn luyện tiền kỳ
Để tìm hiểu thêm về các phần khác nhau của Vertex, hãy xem tài liệu.
9. Dọn dẹp
Vì sổ ghi chú được quản lý trong Vertex AI Workbench có tính năng tắt khi không hoạt động, nên chúng ta không cần lo lắng về việc tắt thực thể. Nếu muốn tắt thực thể theo cách thủ công, hãy nhấp vào nút Dừng trong phần Vertex AI Workbench của bảng điều khiển. Nếu muốn xoá hoàn toàn sổ ghi chú, hãy nhấp vào nút Xoá.

Để xoá Nhóm lưu trữ, hãy sử dụng trình đơn Điều hướng trong Cloud Console, duyệt đến Storage (Bộ nhớ), chọn nhóm của bạn rồi nhấp vào Delete (Xoá):
