Thị giác máy tính 7 — Triển khai & MLOps cho CV
Thị giác máy tính 7 — Triển khai & MLOps cho CV
Một mô hình phát hiện gương mặt hay đọc CCCD chạy 92% accuracy trên notebook của data scientist thì chưa có giá trị. Câu hỏi thực chiến là: nó xử lý được 500 request/giây lúc cao điểm mở tài khoản không? độ trễ p99 bao nhiêu? khi khách dùng điện thoại đời mới với camera khác, độ chính xác tụt bao nhiêu và ai biết? nếu nó hỏng thì quay về bản cũ mất bao lâu? Bài này nói về việc đưa mô hình CV vào production và vận hành nó — với những đặc thù mà mô hình bảng số (tabular) không có: ảnh nặng (một ảnh selfie 2–5 MB, gấp nghìn lần một dòng feature), inference tốn compute (convolution trên hàng triệu pixel), và ràng buộc latency (khách đứng chờ liveness, không chấp nhận 5 giây).
Đây là bài "khép vòng" cho series: kiến thức từ phân loại & phát hiện, OCR và eKYC chỉ tạo ra giá trị khi được triển khai và giám sát đúng. Nó cũng là bản "CV-hoá" của các nguyên tắc MLOps chung ở Model Registry & deploy, giám sát & drift.
Đây là danh mục AI. Mọi đoạn code trong bài là pseudocode/kiến trúc minh hoạ để thấy luồng xử lý; không phải SQL/Python sandbox chạy được.
1. Vòng đời MLOps cho CV
Khác với ML tabular nơi feature engineering là trung tâm, dự án CV production quay quanh dữ liệu ảnh ở cả đầu (thu thập/gắn nhãn) lẫn cuối (drift/retrain). Toàn bộ vòng đời:
Ba mắt xích tô đậm hơn ở dự án CV: (1) dữ liệu & gắn nhãn — tốn nhất; (2) tối ưu inference — vì compute đắt; (3) giám sát drift ảnh — vì phân phối đầu vào đổi liên tục khi khách dùng thiết bị đa dạng.
2. Dữ liệu & gắn nhãn (data-centric)
Trong CV hiện đại, cải thiện dữ liệu thường cho lợi nhiều hơn tinh chỉnh kiến trúc mô hình. Andrew Ng gọi đây là data-centric AI: cố định mô hình, lặp trên chất lượng dữ liệu.
Thu thập ảnh đại diện
Sai lầm kinh điển: train trên ảnh CCCD chụp trong studio đẹp rồi thả ra thực tế nơi khách chụp ban đêm, chói đèn, tay run, CCCD trầy xước. Ảnh training phải đại diện cho phân phối thật:
| Chiều biến thiên | Ví dụ trong eKYC ngân hàng |
|---|---|
| Ánh sáng | Ngày/đêm, ngược sáng, đèn vàng, flash |
| Thiết bị | iPhone đời mới vs Android giá rẻ, camera trước 2 MP |
| Chất lượng | Mờ do rung tay, nén JPEG, độ phân giải thấp |
| Đối tượng | CCCD cũ/mới, có bọc nhựa, người đeo kính, khẩu trang |
| Nền/góc | Chụp nghiêng, có phản chiếu, nền lộn xộn |
Nguyên tắc: thu thập từ chính kênh production (sau khi có consent hợp lệ) để phân phối train khớp phân phối serving.
Annotation pipeline
Gắn nhãn ảnh đắt hơn tabular nhiều: một ảnh detection có thể cần vẽ chục bounding box, một ảnh segmentation cần tô từng pixel.
- Công cụ: CVAT, Label Studio, Roboflow — hỗ trợ box, polygon, keypoint, tiền-gán nhãn bằng model.
- Chất lượng nhãn: nhãn sai đầu độc mô hình. Dùng đo lường đồng thuận giữa người gán nhãn (inter-annotator agreement), gán chồng 2–3 người cho mẫu khó, có bước QA/adjudication.
- Guideline rõ ràng: "vẽ box sát mép CCCD hay chừa lề?", "CCCD bị che một góc có gán không?" — mọi mơ hồ trong guideline thành nhiễu trong dữ liệu.
Active learning — giảm công gắn nhãn
Không cần gán nhãn tất cả ảnh thu thập được. Active learning để mô hình tự chỉ ra ảnh nào đáng gán nhất — thường là ảnh nó không chắc chắn (uncertainty cao, xác suất gần ngưỡng) hoặc ảnh khác lạ so với dữ liệu đã có (diversity). Vòng lặp minh hoạ:
# Pseudocode minh hoạ — active learning loop
pool = unlabeled_images # hàng trăm nghìn ảnh chưa gán
model = train(labeled_seed)
for round in range(N):
scores = model.predict_proba(pool)
uncertainty = 1 - scores.max(axis=1) # gần 0.5 = mơ hồ
to_label = pool.top_k(uncertainty, k=2000) # chỉ gán 2000 ảnh khó nhất
new_labels = human_annotate(to_label) # người gán nhãn
labeled_seed += new_labels
model = train(labeled_seed) # thường +chính xác > gán ngẫu nhiên
Thực tế active learning giúp đạt cùng độ chính xác với 30–50% số nhãn so với gán ngẫu nhiên — tiết kiệm lớn khi thuê team annotation.
Data versioning
Ảnh không nhét vào Git được (nặng, binary). Dùng DVC, LakeFS, hoặc Git-LFS: Git lưu con trỏ + hash, dữ liệu thật nằm ở object store (S3/MinIO). Mục tiêu là tái lập (reproducibility): mỗi phiên bản mô hình gắn với đúng snapshot dataset đã train, để khi cần audit "bản này train từ ảnh nào" là truy được — điều bắt buộc trong môi trường ngân hàng.
3. Huấn luyện & registry
Phần này dùng chung nguyên tắc MLOps ở Model Registry & deploy, chỉ điểm khác biệt CV:
- Experiment tracking (MLflow/W&B): với CV, log thêm ảnh dự đoán mẫu (confusion cases, box vẽ lên ảnh), curve mAP/IoU, không chỉ số scalar. Nhìn ảnh sai giúp debug nhanh hơn nhìn con số.
- Model registry: mỗi model version gắn stage (
Staging→Production→Archived), metadata (dataset hash, config train, metric), lineage. Với CV cần lưu cả tiền xử lý (resize, normalize mean/std) như một phần "signature" — sai normalize là mô hình mù. - Versioning bộ ba: code + data + model phải khớp nhau. Một model artifact CV thường đi kèm file config chỉ rõ input size, class map, preprocessing.
4. Tối ưu inference — mắt xích quan trọng nhất của CV
Đây là chỗ CV khác ML tabular nhất. Model gốc (PyTorch FP32) chạy tốt khi train nhưng quá nặng/chậm/tốn điện để phục vụ, nhất là trên điện thoại. Bốn kỹ thuật thu nhỏ:
| Kỹ thuật | Ý tưởng | Đánh đổi |
|---|---|---|
| Quantization | Hạ độ chính xác số: FP32 → INT8 | Nhanh 2–4×, nhẹ ~4×; giảm nhẹ độ chính xác |
| Pruning | Cắt bỏ trọng số/kênh ít quan trọng | Nhẹ hơn; cần fine-tune lại |
| Distillation | "Thầy" (model to) dạy "trò" (model nhỏ) | Trò nhẹ mà giữ phần lớn chất lượng |
| Kiến trúc nhẹ | Chọn MobileNet/EfficientNet-lite từ đầu | Thiết kế sẵn cho edge |
- Quantization phổ biến nhất. Post-training quantization nhanh gọn; quantization-aware training (giả lập INT8 lúc train) giữ độ chính xác tốt hơn khi tụt nhiều. Với CPU/mobile, INT8 là mặc định.
- Distillation: train ResNet lớn làm thầy, rồi ép MobileNet nhỏ khớp đầu ra thầy — thường tốt hơn train MobileNet trực tiếp.
Chuyển đổi runtime: ONNX / TensorRT
Model PyTorch/TensorFlow nên export sang runtime tối ưu để chạy production:
- ONNX (Open Neural Network Exchange): định dạng trung gian, chạy bằng ONNX Runtime trên CPU/GPU đa nền tảng — tách rời khỏi framework train.
- TensorRT: engine của NVIDIA, tối ưu sâu cho GPU (fusion layer, kernel tuning, INT8/FP16) — nhanh nhất trên GPU NVIDIA nhưng khoá vào phần cứng đó.
- TFLite / Core ML: cho Android / iOS on-device.
# Pseudocode minh hoạ — export + quantize
import torch
model.eval()
torch.onnx.export(model, dummy_input, "face.onnx",
input_names=["img"], output_names=["embedding"],
dynamic_axes={"img": {0: "batch"}}) # batch động
# rồi quantize INT8 bằng onnxruntime / TensorRT trên tập calibration
Batching & GPU vs CPU
- Batching: gom nhiều ảnh xử lý một lần khai thác song song GPU — tăng throughput mạnh nhưng tăng latency một chút (chờ gom batch). Dynamic batching (Triton tự gom trong cửa sổ vài ms) cân bằng hai điều này.
- GPU vs CPU: GPU đáng tiền khi lưu lượng cao và model nặng (detection/segmentation). Lưu lượng thấp, model nhẹ đã quantize → CPU rẻ và đủ. Quy tắc: đo throughput/đồng chi phí cho từng loại, đừng mặc định GPU.
5. Serving: server, edge/on-device, cloud API
Ba mô hình phục vụ, thường kết hợp trong một hệ thống eKYC thật:
Server-side (REST/gRPC, Triton)
Mô hình chạy trên server ngân hàng, ứng dụng gọi qua API. NVIDIA Triton Inference Server là lựa chọn phổ biến cho CV vì hỗ trợ nhiều framework (ONNX/TensorRT/PyTorch), dynamic batching, chạy nhiều model đồng thời, có metric sẵn. gRPC thường nhanh hơn REST cho payload ảnh (nhị phân, ít overhead).
Edge / Mobile / on-device — trọng tâm eKYC
Chạy model ngay trên điện thoại khách (TFLite/Core ML). Với eKYC đây là lựa chọn rất hấp dẫn:
- Giảm độ trễ: phát hiện mặt, kiểm tra khung hình, hướng dẫn "nhìn thẳng/quay trái" chạy real-time trên máy, không round-trip mạng.
- Giữ dữ liệu trên máy: một phần xử lý (detect, crop, chất lượng ảnh) làm on-device, chỉ gửi lên server ảnh đã đủ tiêu chuẩn — giảm dữ liệu sinh trắc rời khỏi thiết bị, tốt cho quyền riêng tư (xem privacy & compliance).
- Model nhẹ: bắt buộc MobileNet/EfficientNet-lite đã quantize; không chạy nổi ResNet-152 trên máy giá rẻ.
Đánh đổi: model trên máy khách khó cập nhật (phụ thuộc app version) và có thể bị reverse-engineer. Vì vậy on-device thường chỉ làm bước sàng lọc/UX, còn quyết định định danh cuối cùng vẫn kiểm ở server — nơi ngân hàng kiểm soát được model và log.
Cloud API
Gọi dịch vụ CV bên thứ ba (FPT.AI, VNPT eKYC, hoặc cloud provider). Nhanh triển khai, không tự vận hành GPU, nhưng dữ liệu ảnh khách rời khỏi ngân hàng — với sinh trắc học phải cân nhắc pháp lý (NĐ13) rất kỹ, thường ưu tiên on-prem/server nội bộ cho dữ liệu nhạy cảm.
6. Giám sát production
Model CV xuống cấp âm thầm: không crash, chỉ dần dự đoán sai khi thế giới đổi. Đây là bản CV-hoá của giám sát & drift.
Data drift trên ảnh
Khó hơn tabular vì ảnh không có "cột" để so histogram. Cách làm:
- Trích embedding ảnh đầu vào (từ chính backbone model), theo dõi phân phối embedding thay đổi theo thời gian so với tập tham chiếu (train).
- Theo dõi thống kê ảnh cấp thấp: độ sáng, độ tương phản, độ mờ (blur score), độ phân giải, tỉ lệ ảnh có mặt phát hiện được.
- Nguyên nhân drift điển hình trong ngân hàng: mẫu điện thoại mới ra thị trường (camera khác), một đối tác thay camera quầy, mùa/ánh sáng đổi, khách vùng địa lý mới.
OOD & giảm độ chính xác
- Phát hiện ảnh lạ / OOD (out-of-distribution): ảnh không giống bất cứ gì lúc train (chụp nhầm bàn tay, ảnh chụp màn hình, tài liệu không phải CCCD). Đo bằng confidence thấp bất thường hoặc khoảng cách embedding lớn tới cụm dữ liệu train → tự động chuyển sang xét duyệt thủ công thay vì đoán liều.
- Giám sát metric có nhãn trễ: một phần hồ sơ được nhân viên KYC duyệt tay sau đó → dùng làm nhãn thật để tính accuracy/FAR/FRR thực tế theo tuần, phát hiện tụt sớm.
Feedback loop & retrain
Trọng tâm: chọn đúng ảnh để gán lại (ảnh khó/OOD, không phải ảnh dễ), version dữ liệu, retrain định kỳ hoặc theo trigger (drift vượt ngưỡng). Xử lý edge case ảnh chất lượng kém: thay vì cố đoán, hệ thống nên yêu cầu khách chụp lại (UX guard) và đưa vào tập dữ liệu để mô hình dần học các điều kiện xấu.
A/B & shadow cho model mới
Không bao giờ thay model CV trực tiếp trên production:
- Shadow mode: model mới chạy song song, nhận cùng ảnh, ghi log dự đoán nhưng không tác động quyết định — so với model cũ để đo chênh lệch an toàn.
- Canary / A/B: cho model mới phục vụ 5% lưu lượng, theo dõi metric (accuracy, FAR/FRR, latency, tỉ lệ chuyển thủ công), tăng dần nếu ổn, rollback tức thì nếu xấu. Với eKYC, chỉ số nhạy cảm nhất là FAR (chấp nhận nhầm người giả) — không được tăng khi lên bản mới.
7. Bảo mật & riêng tư ảnh
Ảnh khuôn mặt và CCCD là dữ liệu sinh trắc học/định danh — nhạy cảm bậc cao, chịu Nghị định 13/2023/NĐ-CP về bảo vệ dữ liệu cá nhân (chi tiết ở privacy & compliance). Nguyên tắc production:
- Tối thiểu hoá lưu trữ: không giữ ảnh thô lâu hơn cần thiết; sau khi định danh xong, cân nhắc chỉ giữ embedding (khó tái tạo mặt) thay vì ảnh gốc, theo chính sách lưu trữ.
- Mã hoá: ảnh mã hoá cả lúc truyền (TLS) và lúc lưu (at-rest). Object store chứa ảnh phải kiểm soát truy cập chặt, có audit log.
- Xử lý on-device như mục 5 để hạn chế ảnh rời thiết bị.
- Consent & mục đích: chỉ thu thập/dùng lại ảnh vào training khi có cơ sở pháp lý; ảnh làm training thường cần ẩn danh/tách định danh.
Use case thực tế
Bối cảnh: NCB triển khai eKYC mở tài khoản online. Cao điểm ~400 hồ sơ/giờ, khách dùng đủ loại điện thoại. Kiến trúc lai:
- On-device (app khách, TFLite): MobileNet-based face detector + kiểm tra chất lượng ảnh (đủ sáng, đủ nét, mặt chính diện) real-time, hướng dẫn quay đầu cho liveness. Ảnh không đạt bị chặn ngay, yêu cầu chụp lại → giảm 60% ảnh rác gửi lên server.
- Server (Triton, GPU, INT8/TensorRT): nhận ảnh đạt chuẩn, chạy OCR CCCD + face verification 1:1 (selfie vs CCCD) + anti-spoofing. Dynamic batching giữ p99 latency < 800 ms.
- Giám sát: theo dõi phân phối embedding + blur score theo ngày. Tháng 5, hệ thống báo drift: một dòng điện thoại mới bán chạy cho ảnh camera màu ám vàng → FRR (từ chối nhầm người thật) nhích từ 3% lên 7% ở nhóm máy đó.
- Feedback & retrain: active learning gom 3.000 ảnh khó (low-confidence + máy mới), gán nhãn qua CVAT, bổ sung dataset (version bằng DVC), retrain distilled model. Đánh giá offline đạt → chạy shadow 1 tuần, rồi canary 5% → 100%. FRR nhóm máy mới về 3.5%, FAR không đổi.
- Riêng tư: ảnh CCCD/selfie mã hoá at-rest, giữ theo chính sách lưu trữ; log training tách định danh; mọi truy cập object store có audit.
Kết quả: throughput đủ tải cao điểm, độ chính xác ổn định qua drift, và có đường rollback khi bản mới xấu — đúng tinh thần vận hành ML production.
Ghi nhớ
- Đặc thù CV production: ảnh nặng, inference tốn compute, ràng buộc latency — khiến tối ưu inference và giám sát drift ảnh quan trọng hơn hẳn ML tabular.
- Data-centric: thu thập ảnh đại diện phân phối thật (ánh sáng/thiết bị/chất lượng), annotation có QA & guideline, active learning giảm 30–50% công gắn nhãn, data versioning (DVC/LakeFS) để tái lập & audit.
- Tối ưu inference: quantization (INT8) là mặc định cho edge/CPU; pruning, distillation, kiến trúc nhẹ MobileNet; export ONNX/TensorRT/TFLite; batching tăng throughput nhưng thêm latency (dynamic batching cân bằng).
- Serving lai: on-device (TFLite) cho UX/liveness real-time + giữ dữ liệu trên máy; server (Triton) là nơi quyết định cuối và kiểm soát; cloud API cân nhắc kỹ với dữ liệu sinh trắc.
- Giám sát: theo dõi drift qua embedding + thống kê ảnh, phát hiện OOD để chuyển xét thủ công, dùng nhãn trễ đo FAR/FRR thật, feedback loop → retrain.
- Roll-out an toàn: shadow → canary/A/B → rollback; với eKYC canh FAR không được tăng khi lên bản mới.
- Riêng tư ảnh (NĐ13): tối thiểu hoá lưu trữ (ưu tiên giữ embedding), mã hoá at-rest/in-transit, xử lý on-device, consent rõ ràng khi dùng ảnh làm training — xem privacy & compliance.
Bài viết liên quan
Phân biệt AI/ML/DL, các kiểu học máy, quy trình ML end-to-end và thuật ngữ nền tảng.
Chất lượng dữ liệu, xử lý thiếu/ngoại lai, mã hoá, chuẩn hoá, tạo đặc trưng và tránh data leakage.
Mô hình ngôn ngữ lớn hoạt động ra sao, token, context window, tham số sinh, và kỹ thuật viết prompt.
Retrieval-Augmented Generation, vector database, tool calling, agent và MCP để xây ứng dụng LLM thực tế.