Giới thiệu
Pipeline, Triển khai và MLOps là những khái niệm rất quan trọng đối với các nhà khoa học dữ liệu ngày nay. Xây dựng mô hình trong Notebook là chưa đủ. Triển khai pipeline và quản lý quy trình đầu-cuối theo các thực tiễn tốt của MLOps đang trở thành trọng tâm của nhiều công ty. Hướng dẫn này thảo luận một số khái niệm quan trọng như Pipeline, CI/CD, API, Container, Docker, Kubernetes. Bạn cũng sẽ tìm hiểu về các framework và thư viện MLOps trong Python. Cuối cùng, hướng dẫn trình bày triển khai đầu-cuối: đóng gói container cho ứng dụng web ML dựa trên Flask và triển khai lên đám mây Microsoft Azure.
Các khái niệm chính
MLOps
MLOps là viết tắt của Machine Learning Operations. MLOps tập trung vào việc tinh giản quy trình đưa các mô hình học máy vào môi trường sản xuất, sau đó duy trì và giám sát chúng. MLOps là một chức năng mang tính hợp tác, thường bao gồm nhà khoa học dữ liệu, kỹ sư ML và kỹ sư DevOps. Từ MLOps là sự kết hợp của hai lĩnh vực khác nhau: machine learning và DevOps trong kỹ nghệ phần mềm.
MLOps có thể bao trùm mọi thứ từ pipeline dữ liệu đến sản xuất mô hình học máy. Ở một số nơi, bạn sẽ thấy MLOps chỉ được triển khai cho phần đưa mô hình học máy vào sản xuất, nhưng cũng có những doanh nghiệp áp dụng MLOps trên nhiều khía cạnh của vòng đời phát triển ML, bao gồm Phân tích Dữ liệu Thăm dò (EDA), Tiền xử lý Dữ liệu, Huấn luyện Mô hình, v.v.
Ban đầu MLOps là tập hợp các thực tiễn tốt, nhưng đang dần phát triển thành một cách tiếp cận độc lập để quản trị vòng đời ML. MLOps áp dụng cho toàn bộ vòng đời - từ tích hợp với khâu tạo mô hình (vòng đời phát triển phần mềm và tích hợp/liên tục giao nhận), điều phối và triển khai, đến sức khỏe hệ thống, chẩn đoán, quản trị và chỉ số kinh doanh.

Vì sao cần MLOps?
Có nhiều mục tiêu mà doanh nghiệp muốn đạt được thông qua MLOps. Một số mục tiêu phổ biến là:
- Tự động hóa
- Khả năng mở rộng
- Tái lập kết quả
- Giám sát
- Quản trị
MLOps so với DevOps
DevOps là cách tiếp cận lặp để đưa ứng dụng phần mềm vào sản xuất. MLOps vay mượn các nguyên tắc tương tự để đưa mô hình học máy vào sản xuất. Dù là DevOps hay MLOps, mục tiêu cuối cùng là nâng cao chất lượng và khả năng kiểm soát ứng dụng phần mềm/mô hình ML.
CI/CD: continuous integration, continuous delivery và continuous deployment
CI/CD là một thực hành bắt nguồn từ DevOps, đề cập đến quy trình liên tục phát hiện vấn đề, đánh giá lại và tự động cập nhật các mô hình học máy. Các khái niệm chính trong CI/CD là tích hợp liên tục, phân phối liên tục và triển khai liên tục. Nó tự động hóa pipeline học máy (xây dựng, kiểm thử và triển khai) và giảm đáng kể nhu cầu nhà khoa học dữ liệu can thiệp thủ công, giúp quy trình hiệu quả, nhanh chóng và ít sai sót do con người.

Pipeline
Pipeline học máy là cách kiểm soát và tự động hóa quy trình làm việc để tạo ra một mô hình học máy. Pipeline học máy gồm nhiều bước tuần tự, từ trích xuất và tiền xử lý dữ liệu đến huấn luyện và triển khai mô hình.
Pipeline học máy mang tính lặp, vì mỗi bước được lặp lại để liên tục cải thiện độ chính xác của mô hình và đạt được mục tiêu cuối cùng.

Thuật ngữ Pipeline được dùng chung để mô tả chuỗi các bước độc lập được sắp xếp với nhau để hoàn thành một tác vụ. Tác vụ này có thể là học máy hoặc không. Pipeline học máy rất phổ biến nhưng không phải là loại pipeline duy nhất. Pipeline điều phối dữ liệu là một ví dụ khác. Theo tài liệu Microsoft, có ba kịch bản:

Triển khai
Triển khai mô hình học máy (hoặc pipeline) là quá trình đưa mô hình vào môi trường sản xuất, nơi các ứng dụng web, phần mềm doanh nghiệp (ERP) và API có thể sử dụng mô hình đã huấn luyện bằng cách cung cấp dữ liệu mới và nhận về dự đoán.
Nói ngắn gọn, Triển khai trong Học máy là cách tích hợp mô hình học máy vào môi trường sản xuất hiện hữu để đưa ra quyết định kinh doanh thực tiễn dựa trên dữ liệu. Đây là giai đoạn cuối của vòng đời học máy.
Thông thường thuật ngữ Triển khai Mô hình Học máy dùng để mô tả việc triển khai toàn bộ Pipeline Học máy, trong đó bản thân mô hình chỉ là một thành phần của Pipeline.

Như bạn thấy ở ví dụ trên, pipeline này bao gồm mô hình Hồi quy Logistic. Có nhiều bước trong pipeline phải được thực hiện trước khi bắt đầu huấn luyện, như Điền khuyết giá trị thiếu, Mã hóa One-Hot, Chuẩn hóa và Phân tích Thành phần Chính (PCA).
Giao diện Lập trình Ứng dụng (API)
Giao diện Lập trình Ứng dụng (API) là một phần mềm trung gian cho phép hai ứng dụng giao tiếp với nhau. Nói đơn giản, API là một hợp đồng giữa hai ứng dụng: nếu phần mềm phía người dùng cung cấp đầu vào theo định dạng xác định trước, API sẽ trả về kết quả cho người dùng. Nói cách khác, API là điểm cuối nơi bạn lưu trữ các mô hình học máy đã huấn luyện/(pipeline) để sử dụng. Trên thực tế, nó trông như sau:

Container
Bạn đã từng gặp vấn đề mã Python (hoặc mã khác) chạy tốt trên máy của bạn nhưng khi bạn của bạn chạy đúng mã đó thì lại không hoạt động chưa? Nếu bạn của bạn lặp lại đúng các bước, lẽ ra họ phải nhận được kết quả giống nhau, đúng không? Câu trả lời đơn giản là môi trường Python của bạn khác với của họ.
Môi trường bao gồm những gì?
Python (hoặc ngôn ngữ khác bạn dùng) và tất cả thư viện, phụ thuộc được dùng để xây dựng ứng dụng đó.
Nếu chúng ta có thể tạo ra một môi trường có thể chuyển sang máy khác (ví dụ: máy của bạn bè hoặc nhà cung cấp đám mây như Microsoft Azure, AWS hay GCP), chúng ta có thể tái lập kết quả ở mọi nơi. Container là một loại phần mềm đóng gói ứng dụng và mọi phụ thuộc của nó để ứng dụng có thể chạy ổn định từ môi trường tính toán này sang môi trường khác.
Cách trực quan nhất để hiểu container trong khoa học dữ liệu là nghĩ về những thùng hàng trên tàu. Mục tiêu là cô lập nội dung của từng thùng để chúng không lẫn vào nhau. Đó chính xác là những gì container làm trong khoa học dữ liệu.
Giờ khi đã hiểu ẩn dụ về container, hãy xem các lựa chọn thay thế để tạo môi trường cô lập cho ứng dụng. Một lựa chọn đơn giản là có một máy riêng cho mỗi ứng dụng.
Dùng máy riêng thì dễ hiểu nhưng không vượt trội so với container, vì duy trì nhiều máy cho mỗi ứng dụng rất tốn kém, khó bảo trì và khó mở rộng. Tóm lại, điều đó không thực tế trong nhiều tình huống thực tế.
Một lựa chọn khác để tạo môi trường cô lập là dùng máy ảo. Container vẫn được ưa chuộng hơn vì yêu cầu ít tài nguyên, rất linh động và khởi tạo nhanh.

Bạn có nhận ra sự khác biệt giữa Máy ảo và Container không? Khi dùng container, bạn không cần hệ điều hành khách. Hãy tưởng tượng 10 ứng dụng chạy trên máy ảo. Điều này sẽ cần 10 hệ điều hành khách, trong khi với container thì không cần.
Docker
Docker là một công ty cung cấp phần mềm (cũng gọi là Docker) cho phép người dùng xây dựng, chạy và quản lý container. Mặc dù container của Docker là phổ biến nhất, các lựa chọn khác ít nổi tiếng hơn như LXD và LXC cũng cung cấp giải pháp container.
Docker là công cụ được thiết kế để giúp việc tạo, triển khai và chạy ứng dụng bằng container trở nên dễ dàng hơn. Container được dùng để đóng gói ứng dụng với tất cả thành phần cần thiết như thư viện và các phụ thuộc khác, và phân phối tất cả như một gói duy nhất.

Làm rõ điều cường điệu
Suy cho cùng, Docker chỉ là một tệp với vài dòng hướng dẫn, được lưu trong thư mục dự án của bạn với tên "Dockerfile".
Một cách khác để hình dung Dockerfile là những công thức bạn sáng tạo trong bếp của mình. Khi bạn chia sẻ công thức đó và người khác làm theo đúng hướng dẫn, họ có thể tạo ra món ăn giống hệt. Tương tự, bạn có thể chia sẻ Dockerfile với người khác, và họ có thể tạo image và chạy container dựa trên Dockerfile đó.
Kubernetes
Được Google phát triển vào năm 2014, Kubernetes là hệ thống mã nguồn mở mạnh mẽ để quản lý các ứng dụng đóng gói dạng container. Nói đơn giản, Kubernetes là hệ thống để chạy và điều phối ứng dụng dạng container trên một cụm máy. Đây là nền tảng được thiết kế để quản lý trọn vẹn vòng đời của ứng dụng container hóa.
Tính năng
- Cân bằng tải: Tự động phân phối tải giữa các container.
- Mở rộng: Tự động mở rộng lên/xuống bằng cách thêm hoặc bớt container khi nhu cầu thay đổi, như giờ cao điểm, cuối tuần và ngày lễ.
- Lưu trữ: Duy trì lưu trữ nhất quán với nhiều phiên bản của một ứng dụng.
Tại sao cần Kubernetes khi đã có Docker?
Hãy tưởng tượng bạn phải chạy nhiều container Docker trên nhiều máy để hỗ trợ một ứng dụng ML cấp doanh nghiệp với khối lượng công việc thay đổi ngày đêm. Nghe có vẻ đơn giản nhưng làm thủ công thì rất vất vả.
Bạn cần khởi chạy đúng container vào đúng thời điểm, xác định cách chúng giao tiếp với nhau, xử lý lưu trữ và xử lý container hay phần cứng gặp sự cố. Đây là vấn đề Kubernetes giải quyết, bằng cách cho phép số lượng lớn container hoạt động hài hòa và giảm gánh nặng vận hành.
Google Kubernetes Engine là bản triển khai Kubernetes mã nguồn mở của Google trên Google Cloud Platform. Các lựa chọn phổ biến khác ngoài GKE là Amazon ECS và Microsoft Azure Kubernetes Service.
Tóm lược nhanh các thuật ngữ:
- Container là loại phần mềm đóng gói ứng dụng và toàn bộ phụ thuộc để ứng dụng chạy ổn định giữa các môi trường tính toán.
- Docker là phần mềm dùng để xây dựng và quản lý container.
- Kubernetes là hệ thống mã nguồn mở để quản lý ứng dụng container hóa trong môi trường cụm.

Framework và Thư viện MLOps trong Python
MLflow
MLflow là nền tảng mã nguồn mở để quản lý vòng đời ML, bao gồm thử nghiệm, tái lập, triển khai và kho đăng ký mô hình tập trung. Hiện MLflow cung cấp MLflow Tracking, MLflow Projects, MLflow Models và Model Registry.
Metaflow
Metaflow là thư viện Python thân thiện với con người giúp nhà khoa học và kỹ sư xây dựng, quản lý các dự án khoa học dữ liệu thực tế. Metaflow ban đầu được phát triển tại Netflix để tăng năng suất cho các nhà khoa học dữ liệu làm việc trên nhiều dự án, từ thống kê cổ điển đến deep learning tiên tiến. Metaflow cung cấp API thống nhất cho tầng hạ tầng cần thiết để thực thi dự án khoa học dữ liệu từ thử nghiệm đến sản xuất.
Kubeflow
Kubeflow là nền tảng học máy mã nguồn mở, được thiết kế để cho phép pipeline học máy điều phối các quy trình phức tạp chạy trên Kubernetes. Kubeflow dựa trên phương pháp nội bộ của Google để triển khai mô hình TensorFlow gọi là TensorFlow Extended.
Kedro
Kedro là framework Python mã nguồn mở để tạo mã khoa học dữ liệu có thể tái lập, dễ bảo trì và mô-đun hóa. Nó vay mượn các khái niệm từ thực tiễn tốt trong kỹ nghệ phần mềm và áp dụng cho mã học máy; các khái niệm áp dụng gồm tính mô-đun, tách bạch mối quan tâm và quản lý phiên bản.
FastAPI
FastAPI là framework Web để phát triển RESTful API trong Python. FastAPI dựa trên Pydantic và type hints để kiểm tra, tuần tự hóa và giải tuần tự dữ liệu, đồng thời tự động sinh tài liệu OpenAPI.
ZenML
ZenML là framework MLOps mã nguồn mở, có thể mở rộng để tạo pipeline học máy sẵn sàng cho sản xuất. Được xây dựng cho nhà khoa học dữ liệu, nó có cú pháp đơn giản, linh hoạt, độc lập đám mây và công cụ, và có các giao diện/abstraction phù hợp với quy trình ML.
Ví dụ: Phát triển, Triển khai và MLOps cho Pipeline Đầu-cuối
Thiết lập bài toán
Một công ty bảo hiểm muốn cải thiện dự báo dòng tiền bằng cách dự đoán tốt hơn chi phí bệnh nhân, dựa trên nhân khẩu học và các chỉ số rủi ro sức khỏe cơ bản tại thời điểm nhập viện.

Mục tiêu của chúng ta là xây dựng và triển khai một ứng dụng web nơi thông tin nhân khẩu và sức khỏe của bệnh nhân được nhập vào biểu mẫu trên web, sau đó xuất ra số tiền chi phí dự đoán. Để đạt được điều này, chúng ta sẽ làm như sau:
- Huấn luyện và phát triển một pipeline học máy để triển khai (mô hình hồi quy tuyến tính đơn giản).
- Xây dựng ứng dụng web bằng framework Flask. Ứng dụng sẽ dùng pipeline ML đã huấn luyện để tạo dự đoán theo thời gian thực cho dữ liệu mới (mã front-end không phải trọng tâm của hướng dẫn này).
- Tạo Docker image và container.
- Đăng tải container lên Azure Container Registry (ACR).
- Triển khai ứng dụng web trong container bằng cách xuất bản lên ACR. Sau khi triển khai, ứng dụng sẽ công khai và có thể truy cập qua URL Web.
Pipeline Học máy
Tôi sẽ dùng PyCaret trong Python để huấn luyện và phát triển pipeline học máy được dùng trong ứng dụng web. Bạn có thể dùng bất kỳ framework nào vì các bước sau đó không phụ thuộc vào lựa chọn này.
# load dataset
from pycaret.datasets import get_data
insurance = get_data('insurance')
# init environment
from pycaret.regression import *
r1 = setup(insurance, target = 'charges', session_id = 123,
normalize = True,
polynomial_features = True, trigonometry_features = True,
feature_interaction=True,
bin_numeric_features= ['age', 'bmi'])
# train a model
lr = create_model('lr')
# save pipeline/model
save_model(lr, model_name = 'c:/username/pycaret-deployment-azure/deployment_28042020')
Khi bạn lưu mô hình trong PyCaret, toàn bộ pipeline biến đổi sẽ được tạo dựa trên cấu hình xác định trong hàm setup. Mọi phụ thuộc liên quan được điều phối tự động. Xem pipeline và mô hình được lưu trong biến 'deployment_28042020':

Ứng dụng Web phía front-end
Hướng dẫn này không tập trung vào việc xây dựng ứng dụng Flask. Phần này chỉ nêu để đầy đủ. Khi pipeline học máy đã sẵn sàng, chúng ta cần một ứng dụng web có thể đọc pipeline đã huấn luyện để dự đoán cho các điểm dữ liệu mới. Ứng dụng này có hai phần:
- Front-end (thiết kế bằng HTML)
- Back-end (phát triển bằng Flask)
Giao diện front-end trông như sau:

Front-end của ứng dụng này chỉ là HTML đơn giản với một ít CSS. Nếu bạn muốn xem mã, vui lòng xem repo này. Giờ khi chúng ta đã có ứng dụng web hoạt động đầy đủ, có thể bắt đầu quá trình đóng gói ứng dụng bằng Docker.
Back-end của ứng dụng
Back-end của ứng dụng là một tệp Python tên app.py. Nó được xây dựng bằng framework Flask.
from flask import Flask,request, url_for, redirect, render_template, jsonify
from pycaret.regression import *
import pandas as pd
import pickle
import numpy as np
app = Flask(__name__)
model = load_model('deployment_28042020')
cols = ['age', 'sex', 'bmi', 'children', 'smoker', 'region']
@app.route('/')
def home():
return render_template("home.html")
@app.route('/predict',methods=['POST'])
def predict():
int_features = [x for x in request.form.values()]
final = np.array(int_features)
data_unseen = pd.DataFrame([final], columns = cols)
prediction = predict_model(model, data=data_unseen, round = 0)
prediction = int(prediction.Label[0])
return render_template('home.html',pred='Expected Bill will be {}'.format(prediction))
@app.route('/predict_api',methods=['POST'])
def predict_api():
data = request.get_json(force=True)
data_unseen = pd.DataFrame([data])
prediction = predict_model(model, data=data_unseen)
output = prediction.Label[0]
return jsonify(output)
if __name__ == '__main__':
app.run(debug=True)
Container Docker
Nếu bạn dùng Windows, bạn sẽ cần cài đặt Docker cho Windows. Nếu bạn dùng Ubuntu, Docker có sẵn theo mặc định và không cần cài đặt.
Bước đầu tiên để đóng gói ứng dụng là viết Dockerfile trong cùng thư mục nơi ứng dụng của bạn nằm. Dockerfile chỉ là một tệp chứa tập lệnh hướng dẫn. Dockerfile cho dự án này như sau:
FROM python:3.7
RUN pip install virtualenv
ENV VIRTUAL_ENV=/venv
RUN virtualenv venv -p python3
ENV PATH="VIRTUAL_ENV/bin:$PATH"
WORKDIR /app
ADD . /app
# install dependencies
RUN pip install -r requirements.txt
# expose port
EXPOSE 5000
# run application
CMD ["python", "app.py"]
Dockerfile phân biệt chữ hoa/thường và phải đặt trong thư mục dự án cùng các tệp khác. Dockerfile không có phần mở rộng và có thể tạo bằng bất kỳ trình soạn thảo nào. Chúng tôi đã dùng Visual Studio Code để tạo.
Triển khai lên đám mây
Sau khi thiết lập đúng Dockerfile, chúng ta sẽ viết một số lệnh để tạo Docker image từ tệp này, nhưng trước tiên cần một dịch vụ để lưu trữ image. Trong ví dụ này, chúng ta sẽ dùng Microsoft Azure để lưu trữ ứng dụng.
Azure Container Registry
Nếu bạn chưa có tài khoản Microsoft Azure hoặc chưa từng dùng, bạn có thể đăng ký miễn phí. Khi bạn đăng ký lần đầu, bạn nhận được tín dụng miễn phí trong 30 ngày đầu. Bạn có thể dùng tín dụng đó để xây dựng và triển khai ứng dụng web trên Azure. Sau khi đăng ký, làm theo các bước sau:
- Đăng nhập tại https://portal.azure.com
- Nhấp Create a Resource
- Tìm Container Registry và nhấp Create
- Chọn Subscription, Resource group và Registry name (trong ví dụ của chúng tôi: pycaret.azurecr.io là tên registry)

Sau khi registry được tạo, bước đầu tiên là dựng Docker image bằng dòng lệnh. Điều hướng đến thư mục dự án và chạy lệnh sau:
docker build -t pycaret.azurecr.io/pycaret-insurance:latest .

- pycaret.azurecr.io là tên registry bạn nhận được khi tạo resource trên cổng Azure
- pycaret-insurance là tên image và latest là thẻ (tag); bạn có thể đặt tùy ý
Chạy container từ Docker image
Khi image đã được tạo, chúng ta sẽ chạy container cục bộ và kiểm thử ứng dụng trước khi đẩy lên Azure Container Registry. Để chạy container cục bộ, thực thi lệnh sau:
docker run -d -p 5000:5000 pycaret.azurecr.io/pycaret-insurance
Bạn có thể xem ứng dụng hoạt động bằng cách truy cập localhost:5000 trên trình duyệt. Ứng dụng web sẽ mở ra.

Nếu bạn thấy màn hình này, nghĩa là ứng dụng đã chạy trên máy cục bộ và giờ chỉ còn việc đẩy lên đám mây. Để triển khai trên Azure, tiếp tục đọc:
Xác thực thông tin Azure
Một bước cuối cùng trước khi bạn có thể tải container lên ACR là xác thực thông tin Azure trên máy cục bộ. Thực thi lệnh sau trên dòng lệnh:
docker login pycaret.azurecr.io
Bạn sẽ được yêu cầu nhập tên người dùng và mật khẩu. Tên người dùng là tên registry của bạn (trong ví dụ này là "pycaret"). Bạn có thể tìm mật khẩu trong phần access keys của tài nguyên Azure Container Registry bạn đã tạo.

Đẩy container lên Azure Container Registry
Sau khi đã xác thực với ACR, bạn có thể đẩy container đã tạo lên ACR bằng cách chạy lệnh:
docker push pycaret.azurecr.io/pycaret-insurance:latest
Tùy kích thước container, lệnh push có thể mất thời gian để tải container lên đám mây.
Ứng dụng Web
Để tạo ứng dụng web trên Azure, thực hiện các bước sau:
- Đăng nhập cổng Azure
- Nhấp create a resource
- Tìm web app và nhấp create
- Liên kết image ACR của bạn với ứng dụng


Ứng dụng hiện đã chạy trên Azure Web Services.

Kết luận
MLOps giúp đảm bảo các mô hình đã triển khai được bảo trì tốt, hoạt động đúng kỳ vọng và không gây tác động xấu đến doanh nghiệp. Vai trò này rất quan trọng trong việc bảo vệ doanh nghiệp khỏi rủi ro do mô hình trôi dạt theo thời gian, hoặc mô hình được triển khai nhưng không được bảo trì hay giám sát.
MLOps đứng đầu bảng xếp hạng Công việc mới nổi trên LinkedIn, với mức tăng trưởng 9,8 lần trong năm năm.
Bạn có thể xem MLOps Fundamentals Skill Track mới trên DataCamp, bao quát toàn bộ vòng đời của ứng dụng học máy, từ thu thập yêu cầu kinh doanh đến thiết kế, phát triển, triển khai, vận hành và bảo trì. Datacamp cũng có khóa Understanding Data Engineering tuyệt vời. Đăng ký ngay hôm nay để khám phá cách kỹ sư dữ liệu đặt nền móng cho khoa học dữ liệu, không cần mã.