Xử lý lỗi thường gặp khi sync dữ liệu giữa DVC và Git
Khắc phục lỗi "Git index conflict" khi DVC cập nhật .gitignore
DVC tự động thêm các file dữ liệu vào .gitignore để tránh git track dữ liệu lớn. Khi nhiều người cùng làm việc hoặc cấu hình thay đổi, Git index có thể bị xung đột với file .dvc mới tạo.
Nguyên nhân: Git vẫn giữ trạng thái cũ của file trong index, trong khi DVC đã tạo file mới hoặc thay đổi trạng thái.
Cách xử lý: Sử dụng lệnh reset index của Git để đồng bộ lại trạng thái với filesystem.
git reset HEAD .
git add .
dvc push
Kết quả mong đợi: Git sẽ nhận diện lại các file .dvc mới, không còn cảnh báo conflict, và dữ liệu được đẩy lên remote storage thành công.
Giải quyết lỗi "File not found" khi pull DVC data
Lỗi này xảy ra khi file .dvc trỏ đến một file data không tồn tại trên remote storage hoặc path bị thay đổi do rename.
Nguyên nhân: Remote storage (S3, GCS, Azure) bị xóa file, hoặc cấu hình dvc.yaml thay đổi path mà không cập nhật file .dvc tương ứng.
Cách xử lý: Kiểm tra file .dvc cụ thể và reset cache local để force re-download.
cat data/data.xml.dvc
dvc checkout data/data.xml
dvc fetch data/data.xml
Kết quả mong đợi: DVC sẽ hiển thị thông tin hash của file, sau đó download lại file data từ remote storage về local cache và cập nhật workspace.
Verify kết quả đồng bộ
Chạy lệnh kiểm tra trạng thái toàn bộ repo để đảm bảo không còn file nào bị dirty hoặc conflict.
dvc status
Kết quả mong đợi: Xuất hiện thông báo Everything is up to date hoặc danh sách các file cần push/pull rõ ràng, không có lỗi.
Khắc phục sự cố kết nối giữa MLflow client và server
Xử lý lỗi "Connection refused" khi truy cập MLflow Server trên K8s
Lỗi này thường xảy ra khi client không thể kết nối đến port 5000 của MLflow server do Service Type hoặc NetworkPolicy bị chặn.
Nguyên nhân: Service được khai báo là ClusterIP nhưng client nằm ngoài cluster, hoặc Ingress không được cấu hình đúng path.
Cách xử lý: Kiểm tra Service type và expose đúng port. Nếu dùng Ingress, đảm bảo rule routing đúng.
kubectl get svc mlflow-server
kubectl describe svc mlflow-server
kubectl get ingress
Kết quả mong đợi: Service hiển thị Type: LoadBalancer hoặc NodePort nếu truy cập từ bên ngoài, hoặc Ingress có Address và Host đúng.
Khắc phục lỗi "Traceback (most recent call last): ConnectionError"
Lỗi này xảy ra khi MLflow client không tìm thấy server hoặc server không phản hồi do crash hoặc OOM (Out of Memory).
Nguyên nhân: Pod MLflow server bị restart liên tục, hoặc environment variable MLFLOW_TRACKING_URI sai.
Cách xử lý: Kiểm tra log của pod và đảm biến môi trường được set đúng.
kubectl logs -f mlflow-server-0
kubectl get pod mlflow-server-0 -o yaml | grep env
Kết quả mong đợi: Log hiển thị nguyên nhân crash (ví dụ: lỗi database connection, lỗi port conflict) và biến môi trường hiển thị MLFLOW_TRACKING_URI=http://mlflow-server:5000.
Cấu hình lại MLflow Server với Persistence (Helm Values)
Để tránh mất dữ liệu tracking khi pod bị xóa, cần cấu hình persistent volume cho database và artifact store.
Nguyên nhân: MLflow chạy với SQLite in-memory hoặc artifact store không có storage backend sẽ mất dữ liệu khi pod restart.
Cách xử lý: Tạo file values.yaml để cấu hình Helm chart MLflow với persistent volume.
File cấu hình: mlflow-helm-values.yaml
mlflow:
tracking:
enabled: true
service:
type: LoadBalancer
persistence:
enabled: true
size: 10Gi
artifactRoot: s3://my-bucket/mlflow-artifacts
database:
type: postgres
host: postgres-service
port: 5432
database: mlflow
user: mlflow_user
password: secure_password
ssl: false
Chạy lệnh cài đặt lại với file values:
helm install mlflow ./mlflow-chart -f mlflow-helm-values.yaml --namespace dataops
Kết quả mong đợi: Pod MLflow khởi động thành công, có PVC được gắn vào, và client có thể truy cập server qua URL mới.
Verify kết quả kết nối
Thực hiện test kết nối từ bên ngoài hoặc từ container khác.
curl -v http://mlflow-server-loadbalancer-ip:5000
Kết quả mong đợi: HTTP response 200 OK và hiển thị HTML của giao diện MLflow.
Tối ưu tốc độ build image Docker cho training/inference
Áp dụng Multi-stage Build để giảm kích thước image
Image training thường rất nặng (chứa CUDA, PyTorch, TensorFlow). Khi deploy inference, ta chỉ cần runtime, không cần compiler hay build tools.
Nguyên nhân: Build image truyền thống gộp tất cả dependencies vào một layer, làm tăng kích thước và thời gian pull.
Cách xử lý: Sử dụng Dockerfile multi-stage: một stage để build/install dependencies, stage thứ hai để copy chỉ các file cần thiết vào image nhẹ (như Alpine hoặc Slim).
File cấu hình: Dockerfile.optimized
FROM python:3.9-slim as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
FROM python:3.9-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "train.py"]
Kết quả mong đợi: Image cuối cùng chỉ khoảng 150MB-200MB thay vì 4GB+, thời gian build giảm 40-60%.
Tối ưu Docker Layer Caching cho ML Dependencies
Trong quy trình CI/CD, mỗi lần code thay đổi đều trigger build lại. Nếu không tối ưu cache, Docker sẽ download lại toàn bộ wheel packages.
Nguyên nhân: Sắp xếp lệnh COPY và RUN trong Dockerfile không hợp lý, làm cache layer bị invalid.
Cách xử lý: Copy file requirements.txt trước, chạy pip install, sau đó mới copy source code.
File cấu hình: Dockerfile.cache-optimized
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
Kết quả mong đợi: Khi chỉ sửa source code (không sửa dependencies), Docker re-use layer cache cũ, thời gian build giảm xuống dưới 5 giây.
Sử dụng BuildKit và Docker Build Cache Backend
Docker BuildKit cho phép tận dụng cache tốt hơn và hỗ trợ build parallel.
Nguyên nhân: Docker engine mặc định (v1.0) có giới hạn về cache và không hỗ trợ build parallel tốt.
Cách xử lý: Bật BuildKit và sử dụng cache backend (như registry hoặc local directory) để lưu cache build.
export DOCKER_BUILDKIT=1
docker build --cache-from mlflow-model:latest --cache-to type=registry,ref=mlflow-model:buildcache,tar=false -t mlflow-model:latest .
Kết quả mong đợi: Build log hiển thị các bước được cache (CACHED) và thời gian build giảm đáng kể khi dependencies không đổi.
Verify kết quả tối ưu
So sánh kích thước image và thời gian build trước và sau tối ưu.
docker images | grep mlflow-model
time docker build -t mlflow-model:test .
Kết quả mong đợi: Kích thước image nhỏ hơn 50% và thời gian build nhanh hơn ít nhất 30% so với phiên bản cũ.
Các best practices để bảo trì hệ thống DataOps lâu dài
Thiết lập chính sách retention cho MLflow Artifacts và DVC Data
Dữ liệu ML (models, datasets) tăng trưởng theo cấp số nhân. Nếu không xóa dữ liệu cũ, storage sẽ đầy và chi phí tăng.
Nguyên nhân: Không có quy trình tự động xóa các phiên bản model hoặc dataset cũ không còn sử dụng.
Cách xử lý: Cấu hình retention policy trong MLflow (sử dụng mlflow set retention) và script cron để xóa data cũ trong DVC remote.
File script: scripts/cleanup_old_models.sh
#!/bin/bash
MLFLOW_TRACKING_URI="http://mlflow-server:5000"
# Xóa các version model cũ hơn 30 ngày (giữ lại 5 version mới nhất)
mlflow models list-versions --model-name my-model | \
awk '{print $1}' | \
tail -n +6 | \
xargs -I {} mlflow models delete-version --model-name my-model --version {}
# Xóa data DVC cũ hơn 90 ngày (giả định có timestamp trong path)
find /var/dvc-remote -type f -mtime +90 -delete
Kết quả mong đợi: Các version model cũ và file data cũ bị xóa tự động, dung lượng storage giảm đáng kể.
Giám sát tài nguyên và cảnh báo sớm (Proactive Monitoring)
Hệ thống DataOps cần giám sát không chỉ uptime mà còn hiệu năng (latency, throughput, resource usage).
Nguyên nhân: Chỉ giám sát khi sự cố đã xảy ra (reactive) thay vì phát hiện sớm (proactive).
Cách xử lý: Tích hợp Prometheus với MLflow (sử dụng plugin) và Grafana để dashboard hóa các metric quan trọng như GPU usage, training time, inference latency.
File cấu hình: prometheus.yml (phần scrape config)
scrape_configs:
- job_name: 'mlflow'
static_configs:
- targets: ['mlflow-server:5000']
- job_name: 'kubernetes-nodes'
kubernetes_sd_configs:
- role: node
relabel_configs:
- source_labels: [__address__]
regex: '.*:10250'
action: replace
target_label: __address__
replacement: 'https://kubernetes.default.svc:443'
replacement: 'kubernetes.default.svc:443'
Kết quả mong đợi: Grafana hiển thị dashboard thời gian thực về resource usage và latency, cảnh báo gửi về Slack/Email khi vượt ngưỡng.
Chuẩn hóa quy trình rollback và disaster recovery
Khi deploy model mới gây lỗi hoặc hiệu năng giảm, cần khả năng rollback về version ổn định ngay lập tức.
Nguyên nhân: Không có quy trình rollback tự động hoặc mất dữ liệu khi incident xảy ra.
Cách xử lý: Cấu hình Kubernetes Rolling Update với maxUnavailable và maxSurge hợp lý, và lưu trữ backup database MLflow định kỳ.
File manifest: deployment.yaml (strategic field)
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
template:
spec:
containers:
- name: mlflow-model
image: my-registry/ml-model:latest
env:
- name: MLFLOW_MODEL_VERSION
value: "1.2.0"
Script backup database:
pg_dump -h postgres-service -U mlflow_user mlflow | gzip > /backup/mlflow-backup-$(date +%F).sql.gz
Kết quả mong đợi: Khi deploy lỗi, Kubernetes tự động rollback về version cũ, và dữ liệu tracking vẫn được an toàn nhờ backup định kỳ.
Verify kết quả bảo trì
Thực hiện test rollback và kiểm tra backup.
kubectl rollout undo deployment/mlflow-model
ls -lh /backup/
tar -tzf /backup/mlflow-backup-$(date +%F).sql.gz | head -n 10
Kết quả mong đợi: Deployment quay về version cũ thành công, và file backup tồn tại, có thể restore được.
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng DataOps với DVC, MLflow và Kubernetes cho vòng đời AI
« Phần 10: Troubleshooting và các mẹo tối ưu hiệu suất