Hướng dẫn toàn tập Docker cho kỹ sư Machine Learning

Hướng dẫn toàn tập Docker cho kỹ sư Machine Learning

Giới thiệu


Các mô hình machine learning thường không hoạt động giống nhau ở các môi trường khác nhau. Một mô hình chạy ổn trên máy tính của bạn có thể gặp lỗi khi chuyển sang máy khác hoặc triển khai thực tế, do khác biệt về phiên bản thư viện, thiếu phụ thuộc hoặc vấn đề hệ thống. Điều này gây khó khăn, phức tạp khi hợp tác và triển khai.

Docker là giải pháp hiệu quả để khắc phục các vấn đề này, bằng cách đóng gói toàn bộ ứng dụng machine learning – bao gồm mô hình, mã nguồn, thư viện phụ thuộc, môi trường chạy – vào một container chuẩn hóa. Container này sẽ chạy nhất quán trên bất kỳ nền tảng nào. Bạn chỉ cần xây dựng một lần, sau đó có thể chạy ở mọi nơi mà không phải lo lắng về cấu hình hay xung đột phụ thuộc.

Bài viết này sẽ hướng dẫn bạn từng bước đóng gói một mô hình machine learning thành container qua một ví dụ thực tế, dễ hiểu. Bạn sẽ nắm được:

  • Kiến thức cơ bản về Docker trong Machine Learning
  • Quy trình xây dựng và triển khai mô hình machine learning
  • Cách đóng gói ứng dụng machine learning với Docker
  • Cách viết Dockerfile tối ưu cho ứng dụng ML

Hãy cùng bắt đầu với các bước đơn giản giúp bạn triển khai mô hình nhanh chóng và hiệu quả.

🔗 Xem mã nguồn trên GitHub

Yêu cầu chuẩn bị


Trước khi bắt đầu đóng gói mô hình machine learning bằng Docker, bạn cần chuẩn bị:

Bắt buộc:

  • Đã cài Python 3.11 (hoặc mới hơn)
  • FastAPI và các thư viện liên quan (sẽ hướng dẫn cài đặt chi tiết)
  • Biết sử dụng dòng lệnh cơ bản
  • Đã cài Docker Desktop (tải tại đây)
  • Có trình soạn thảo mã hoặc IDE

Tùy chọn:

  • Nắm kiến thức cơ bản về machine learning
  • Quen sử dụng môi trường ảo Python
  • Có kinh nghiệm sử dụng REST API

Kiểm tra Docker đã được cài đặt:

docker --version
docker run hello-world

Nếu cả hai lệnh đều hoạt động, bạn đã sẵn sàng!

Kiến thức cơ bản về Docker dành cho kỹ sư Machine Learning


Trước khi xây dựng container đầu tiên cho machine learning, hãy cùng tìm hiểu những khái niệm căn bản. Docker có thể hơi khó hiểu lúc ban đầu, nhưng khi nắm được những ý chính sau, bạn sẽ thấy mọi thứ dễ dàng hơn rất nhiều.

Docker là gì và tại sao kỹ sư machine learning nên quan tâm?

Docker là nền tảng giúp bạn đóng gói ứng dụng cùng tất cả các phụ thuộc thành một đơn vị chuẩn hóa gọi là container. Đối với kỹ sư machine learning, Docker giúp giải quyết hiệu quả các vấn đề thường gặp trong quá trình phát triển và triển khai.

Trong quy trình làm việc của machine learning, mã nguồn thường chạy khác nhau giữa các máy do khác phiên bản Python hoặc thư viện. Docker loại bỏ hoàn toàn sự không nhất quán này bằng cách đóng gói toàn bộ môi trường chạy, đảm bảo ứng dụng hoạt động giống nhau ở bất kỳ đâu.

Các dự án machine learning thường phụ thuộc vào loạt phần mềm phức tạp, yêu cầu phiên bản rất chính xác – ví dụ TensorFlow phải đúng bản CUDA, hoặc PyTorch có thể xung đột với một số bản NumPy. Docker container tách biệt hoàn toàn các phụ thuộc này, tránh xung đột và đơn giản hóa việc cài đặt.

Khả năng tái tạo là nền tảng trong nghiên cứu và sản xuất machine learning. Khi bạn đóng gói mã nguồn, thư viện và các phụ thuộc hệ thống thành một image duy nhất, bạn dễ dàng tái tạo đúng kết quả mọi thí nghiệm.

Khi triển khai mô hình, bạn thường phải cấu hình lại môi trường trên nhiều máy chủ hoặc nền tảng đám mây khác nhau. Docker cho phép bạn xây dựng môi trường một lần, chạy ở bất cứ đâu, giúp triển khai nhanh chóng và ổn định.

Sự khác biệt giữa Docker Image và Container

Đây là khái niệm quan trọng mà nhiều người mới dễ nhầm lẫn.

Docker image giống như bản thiết kế phần mềm.

Nó là tệp chỉ đọc, bao gồm:

  • Hệ điều hành (thường là Linux nhẹ)
  • Mã nguồn ứng dụng
  • Tất cả thư viện và phụ thuộc
  • Các tệp cấu hình
  • Hướng dẫn khởi động ứng dụng

Hãy liên tưởng image như khai báo một lớp (class) trong lập trình: nó mô tả chi tiết, nhưng không thực thi.

Container là một phiên bản đang chạy của image.

Nó giống như một đối tượng được tạo ra từ lớp. Bạn có thể tạo nhiều container từ một image, như tạo nhiều đối tượng từ một lớp.

# Đây là IMAGE - bản thiết kế
docker build -t my-ml-model:v1 .
# Đây là các CONTAINER - các môi trường chạy thực tế
docker run --name experiment-1 my-ml-model:v1
docker run --name experiment-2 my-ml-model:v1
docker run --name experiment-3 my-ml-model:v1

Bạn tạo một image và có thể khởi động nhiều container độc lập từ image đó. Mỗi container là một môi trường riêng biệt, nhưng đều dựa trên cùng một bản thiết kế.

Dockerfile

Dockerfile là nơi bạn viết tập hợp các hướng dẫn để xây dựng một image. Đây là tệp văn bản (thường đặt tên là Dockerfile, không có đuôi mở rộng), Docker sẽ đọc lần lượt từ trên xuống dưới.

Docker xây dựng image theo từng lớp (layer). Mỗi lệnh trong Dockerfile tạo ra một layer mới. Docker sử dụng cache cho các layer này, giúp tốc độ build nhanh hơn khi các layer không thay đổi.

Lưu trữ dữ liệu bằng Volume

Container là tạm thời – khi xóa container, mọi dữ liệu bên trong cũng mất. Đây là vấn đề lớn với kỹ sư machine learning, khi cần lưu log huấn luyện, checkpoint mô hình, hoặc kết quả thực nghiệm.

Volume cho phép bạn gắn kết (mount) một thư mục từ máy chủ vào container:

docker run -v /duongdan/trenmay:/duongdan/trongcontainer my-model

Bây giờ, mọi dữ liệu ghi vào /duongdan/trongcontainer thực chất được lưu ngoài container tại /duongdan/trenmay, sẽ không bị mất khi xóa container.

Trong quy trình ML, bạn thường gắn kết như sau:

docker run 
  -v $(pwd)/data:/app/data 
  -v $(pwd)/models:/app/models 
  -v $(pwd)/logs:/app/logs 
  my-training-container

Như vậy, mô hình đã huấn luyện, tập dữ liệu, log sẽ được lưu bên ngoài container.

Mạng và ánh xạ cổng

Container chạy trong không gian mạng riêng. Để truy cập dịch vụ bên trong container, bạn cần ánh xạ cổng:

docker run -p 8000:8000 my-api

Lệnh này sẽ kết nối cổng 8000 của máy chủ với cổng 8000 của container (theo dạng host_port:container_port).

Với API machine learning, bạn có thể chạy song song nhiều phiên bản mô hình:

# Chạy song song hai phiên bản
docker run -d -p 8000:8000 --name wine-api-v1 yourusername/wine-predictor:v1
docker run -d -p 8001:8000 --name wine-api-v2 yourusername/wine-predictor:v2
# v1 phục vụ tại http://localhost:8000, v2 tại http://localhost:8001

Vì sao nên chọn Docker thay cho môi trường ảo?

Có thể bạn sẽ hỏi: “Tại sao không dùng venv hoặc conda?” Dưới đây là lý do Docker phù hợp hơn cho machine learning:

Môi trường ảo chỉ cô lập các gói Python, không cô lập các thư viện hệ thống (như CUDA, libgomp, libgfortran), không xử lý khác biệt hệ điều hành (Windows/Linux), hay các phụ thuộc hệ thống khác.

Docker cô lập toàn bộ môi trường. Container chạy giống nhau trên MacBook, máy Windows của đồng nghiệp, hoặc server Linux trên cloud. Ngoài ra, bạn có thể dễ dàng chạy nhiều phiên bản Python song song – điều này khó thực hiện với môi trường ảo.

Đóng gói ứng dụng Machine Learning bằng Docker


Sau khi đã nắm kiến thức cơ bản, hãy thực hành với ví dụ: mô hình dự đoán chất lượng rượu vang dựa trên bộ dữ liệu wine của scikit-learn, triển khai thành API sẵn sàng sử dụng. Các bước gồm:

  • Xây dựng, huấn luyện mô hình Random Forest
  • Tạo ứng dụng FastAPI phục vụ dự đoán
  • Viết Dockerfile tối ưu
  • Build và chạy container trên máy
  • Kiểm thử các endpoint API
  • Đẩy image lên Docker Hub để chia sẻ

Cùng bắt đầu nhé!

Bước 1: Tạo cấu trúc dự án

Tạo thư mục dự án với cấu trúc sau:

wine-predictor/
├── train_model.py
├── app.py
├── requirements.txt
├── Dockerfile
└── .dockerignore

Sau đó, tạo và kích hoạt môi trường ảo:

python3 -m venv v1
source v1/bin/activate

Cài đặt các gói cần thiết:

pip install fastapi uvicorn pandas scikit-learn

Bước 2: Xây dựng mô hình Machine Learning

Tạo file train_model.py:

import pickle
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler
# Load dữ liệu rượu vang
wine = load_wine()
X, y = wine.data, wine.target
# Chia dữ liệu
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)
# Chuẩn hóa đặc trưng
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Huấn luyện mô hình
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train_scaled, y_train)
# Đánh giá
accuracy = model.score(X_test_scaled, y_test)
print(f"Độ chính xác mô hình: {accuracy:.2f}")
# Lưu mô hình và scaler
with open('model.pkl', 'wb') as f:
    pickle.dump(model, f)
with open('scaler.pkl', 'wb') as f:
    pickle.dump(scaler, f)
print("Đã lưu mô hình và scaler!")

Chạy script để huấn luyện và lưu mô hình:

python3 train_model.py

Bạn sẽ thấy độ chính xác và thông báo lưu thành công.

Bước 3: Xây dựng ứng dụng FastAPI

Tạo file app.py:

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import pickle
import numpy as np
app = FastAPI(title="Wine Quality Predictor")
# Nạp mô hình và scaler khi khởi động
with open('model.pkl', 'rb') as f:
    model = pickle.load(f)
with open('scaler.pkl', 'rb') as f:
    scaler = pickle.load(f)
wine_classes = ['Class 0', 'Class 1', 'Class 2']
class WineFeatures(BaseModel):
    alcohol: float
    malic_acid: float
    ash: float
    alcalinity_of_ash: float
    magnesium: float
    total_phenols: float
    flavanoids: float
    nonflavanoid_phenols: float
    proanthocyanins: float
    color_intensity: float
    hue: float
    od280_od315_of_diluted_wines: float
    proline: float
    model_config = {
        "json_schema_extra": {
            "example": {
                "alcohol": 13.2,
                "malic_acid": 2.77,
                "ash": 2.51,
                "alcalinity_of_ash": 18.5,
                "magnesium": 96.0,
                "total_phenols": 2.45,
                "flavanoids": 2.53,
                "nonflavanoid_phenols": 0.29,
                "proanthocyanins": 1.54,
                "color_intensity": 5.0,
                "hue": 1.04,
                "od280_od315_of_diluted_wines": 3.47,
                "proline": 920.0
            }
        }
    }
@app.get("/")
def read_root():
    return {
        "message": "Wine Quality Prediction API",
        "endpoints": {
            "/predict": "POST - Gửi dự đoán",
            "/health": "GET - Kiểm tra trạng thái API",
            "/docs": "GET - Tài liệu API"
        }
    }
@app.get("/health")
def health_check():
    return {"status": "healthy", "model_loaded": model is not None, "scaler_loaded": scaler is not None}
@app.post("/predict")
def predict(features: WineFeatures):
    try:
        input_data = np.array([[
            features.alcohol, features.malic_acid, features.ash,
            features.alcalinity_of_ash, features.magnesium,
            features.total_phenols, features.flavanoids,
            features.nonflavanoid_phenols, features.proanthocyanins,
            features.color_intensity, features.hue,
            features.od280_od315_of_diluted_wines, features.proline
        ]])
        input_scaled = scaler.transform(input_data)
        prediction = model.predict(input_scaled)
        probabilities = model.predict_proba(input_scaled)[0]
        pred_index = int(prediction[0])
        return {
            "prediction": wine_classes[pred_index],
            "prediction_index": pred_index,
            "confidence": float(probabilities[pred_index]),
            "all_probabilities": {
                wine_classes[i]: float(p) for i, p in enumerate(probabilities)
            }
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

Có thể kiểm thử API bằng lệnh:

uvicorn app:app --reload

Truy cập http://localhost:8000/docs để xem tài liệu API trực quan.

Bước 4: Tạo file requirements.txt

Liệt kê các thư viện Python vào requirements.txt:

fastapi==0.115.5
uvicorn[standard]==0.30.6
scikit-learn==1.5.2
numpy==2.1.3
pydantic==2.9.2

Khóa cứng phiên bản để môi trường luôn ổn định, dễ tái tạo.

Bước 5: Viết Dockerfile

Đây là bước quan trọng – viết Dockerfile:

# Dùng image Python chính thức
FROM python:3.11-slim
WORKDIR /app
# Copy requirements trước để tận dụng cache
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy mã nguồn và mô hình
COPY app.py .
COPY model.pkl .
COPY scaler.pkl .
EXPOSE 8000
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]

Giải thích nhanh:

  • FROM python:3.11-slim: Sử dụng bản Python nhẹ, giảm dung lượng image.
  • WORKDIR /app: Đặt thư mục làm việc là /app.
  • COPY requirements.txt .: Copy requirements trước để cache hiệu quả.
  • RUN pip install –no-cache-dir -r requirements.txt: Cài đặt các thư viện Python.
  • COPY app.py . / COPY model.pkl . / COPY scaler.pkl .: Copy mã nguồn và mô hình.
  • EXPOSE 8000: Khai báo container sẽ lắng nghe cổng 8000.
  • CMD […]: Lệnh khởi động ứng dụng khi container chạy.

Bước 6: Build Docker image

Build image bằng lệnh:

docker buildx build -t wine-predictor:v1 .

Kiểm tra image đã tạo:

docker images

Bạn sẽ thấy image wine-predictor và dung lượng hiển thị.

Bước 7: Chạy container

Chạy container từ image vừa build:

docker run -d -p 8000:8000 --name wine-api wine-predictor:v1
  • -d: Chạy nền
  • -p 8000:8000: Ánh xạ cổng 8000
  • –name wine-api: Đặt tên container
  • wine-predictor:v1: Tên image

API đã sẵn sàng! Kiểm tra trạng thái:

curl http://localhost:8000/health

Kết quả trả về sẽ là:

{
  "status": "healthy",
  "model_loaded": true,
  "scaler_loaded": true
}

Bước 8: Gửi dự đoán

Thử gửi một dự đoán mới bằng curl:

curl -X POST "http://localhost:8000/predict" \
  -H "Content-Type: application/json" \
  -d '{
    "alcohol": 13.2,
    "malic_acid": 2.77,
    "ash": 2.51,
    "alcalinity_of_ash": 18.5,
    "magnesium": 96.0,
    "total_phenols": 2.45,
    "flavanoids": 2.53,
    "nonflavanoid_phenols": 0.29,
    "proanthocyanins": 1.54,
    "color_intensity": 5.0,
    "hue": 1.04,
    "od280_od315_of_diluted_wines": 3.47,
    "proline": 920.0
  }'

Kết quả trả về sẽ là:

{
  "prediction": "Class 1",
  "prediction_index": 1,
  "confidence": 0.97,
  "all_probabilities": {
    "Class 0": 0.02,
    "Class 1": 0.97,
    "Class 2": 0.01
  }
}

Bước 9: (Tùy chọn) Đẩy image lên Docker Hub

Đăng ký tài khoản miễn phí tại hub.docker.com nếu chưa có.

Đăng nhập:

docker login

Gắn tag image với username:

docker tag wine-predictor:v1 yourusername/wine-predictor:v1

Đẩy image lên kho:

docker push yourusername/wine-predictor:v1

Giờ bạn có thể kéo và chạy image này ở bất kỳ đâu:

docker pull yourusername/wine-predictor:v1
docker run -d -p 8000:8000 yourusername/wine-predictor:v1

Mô hình đã sẵn sàng chia sẻ với cộng đồng hoặc đồng nghiệp!

Thực hành tốt khi xây dựng Docker image cho Machine Learning


1. Dùng multi-stage build để giảm dung lượng image

Xây dựng image cho ứng dụng ML nên dùng multi-stage build:

# Stage build
FROM python:3.11 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
# Stage chạy
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY app.py model.pkl scaler.pkl ./
ENV PATH=/root/.local/bin:$PATH
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]

Tách riêng quá trình build và chỉ copy những thành phần cần thiết vào image cuối giúp giảm dung lượng và tăng bảo mật.

2. Không huấn luyện mô hình bên trong Docker image

Việc huấn luyện nên thực hiện ngoài Docker. Chỉ copy mô hình đã huấn luyện vào image. Cách này giúp build image nhanh, có thể tái tạo dễ dàng, tập trung vào phục vụ (serving) thay vì huấn luyện (training).

3. Sử dụng file .dockerignore

Loại trừ các file dữ liệu, notebook, file thử nghiệm và file lớn không cần thiết. Điều này giúp build context nhỏ gọn, image không bị tăng dung lượng ngoài ý muốn.

# .dockerignore
__pycache__/
*.pyc
*.pyo
.ipynb_checkpoints/
data/
models/
logs/
.env
.git

4. Gắn phiên bản cho mô hình và image

Tag image với phiên bản mô hình để dễ quản lý, hoàn nguyên khi cần. Ví dụ:

docker buildx build -t wine-predictor:v1.0 .
docker buildx build -t wine-predictor:v1.1 .

Tổng kết


Bạn đã có thể đóng gói mô hình machine learning bằng Docker! Qua bài viết này, bạn đã biết:

  • Kiến thức nền tảng về Docker: image, container, Dockerfile, layer, cache
  • Cách xây dựng API dự đoán bằng FastAPI
  • Viết Dockerfile tối ưu cho ứng dụng ML
  • Quy trình build, chạy container đơn giản

Docker giúp mô hình ML của bạn chạy đồng nhất mọi nơi – từ máy cá nhân, cloud đến máy của đồng nghiệp. Không còn lo lắng về môi trường, triển khai trở nên nhất quán và tin cậy.

Khi đã thành thạo, bạn có thể mở rộng với CI/CD, Kubernetes, các công cụ giám sát để xây dựng hệ thống machine learning quy mô lớn, chuyên nghiệp.

Bắt tay đóng gói mô hình của bạn ngay hôm nay. Chúc bạn thành công!

Tham khảo thêm các gợi ý ChatGPT sáng tạo nội dung hay nhất của tôi.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top