Thực hành DVC: mỗi lần khách gửi dữ liệu mới là một commit truy ngược được
Khi khách hỏi "model tháng trước học trên dữ liệu nào?", FDE cần trả lời bằng một commit hash, không phải bằng trí nhớ.
- 1dvc addTạo file .dvc nhỏ chứa MD5 hash, kích thước và số file của dữ liệu
- 2git commit file .dvcMetadata dữ liệu được version cùng source code
- 3dvc pushĐẩy dữ liệu thật lên remote khách cho phép: S3, Azure, GCS, SSH
- 4dvc reproChỉ chạy lại stage có input đổi; commit dvc.lock để ghim lần chạy
- 5git checkout + dvc checkoutQuay về đúng dữ liệu và code của một model cũ
Mỗi đợt dữ liệu khách gửi thành một commit, dữ liệu nằm ở remote và quay về được bất cứ lúc nào.
Đồ hoạ: FDE Times
Tóm tắt nhanh
- Git giữ file .dvc nhỏ chứa MD5 hash, kích thước và số file; dữ liệu thật nằm ở remote như S3.
- Mỗi lần git checkout, luôn chạy thêm dvc checkout để dữ liệu khớp với code.
- dvc repro bỏ qua stage không đổi, còn dvc.lock commit vào Git ghim lại một lần chạy tái lập được.
Thứ Hai khách gửi file dữ liệu tuần này. Thứ Tư họ gửi bản “đã sửa lỗi”. Thứ Sáu, model mới cho kết quả tệ hơn và câu hỏi đầu tiên trong cuộc họp là: model đang chạy production được train trên bản nào?
Nếu câu trả lời của bạn là “chắc là bản thứ Tư”, bạn đã mất một phần niềm tin của khách. Đây là tình huống FDE gặp liên tục khi triển khai ML tại hiện trường: dữ liệu không đứng yên, và code có Git nhưng dữ liệu thì thường nằm trong một thư mục tên final_v3_moi.csv.
Hướng dẫn này đi qua một quy trình bạn có thể dựng trên laptop trong một buổi tối, dùng DVC. Trang chủ DVC tóm tắt triết lý của nó bằng ý quản lý dữ liệu theo đúng cách người ta quản lý code, và tài liệu Get Started gọi thẳng nó là “Git for data”.
Bạn sẽ xây gì, và cần gì trước?
Thử hình dung một khách hàng bán lẻ gửi file data/data.xml mỗi tuần. Bài thực hành nhắm tới ba điều: mỗi đợt dữ liệu ứng với một Git commit, dữ liệu thật nằm trên kho lưu trữ khách cho phép, và bạn lấy lại được bất kỳ đợt nào khi cần.
Bạn cần Git, DVC đã cài, và một repo Git đã khởi tạo DVC theo trang Get Started. Điểm cần hiểu trước khi gõ lệnh: về mặt kỹ thuật, bản thân DVC không phải hệ thống quản lý version. Nó giao phần lịch sử cho Git; nội dung file .dvc quyết định phiên bản dữ liệu nào đang áp dụng.
Bước 1–2: biến đợt dữ liệu đầu tiên thành một commit
Đưa file vào DVC:
dvc add data/data.xml
DVC tạo ra file metadata data/data.xml.dvc. Mở nó ra để kiểm tra: file này ghi kích thước, số lượng file và quan trọng nhất là một MD5 hash, chính hash này định danh phiên bản dữ liệu.
Sau đó commit file metadata vào Git, không phải bản thân dữ liệu:
git add data/data.xml.dvc
git commit -m "Dữ liệu khách: đợt tuần 1"
Từ lúc này, metadata của dữ liệu nằm trong lịch sử Git ngay cạnh source code. Ví dụ trên đã rút gọn: khi chạy dvc add, hãy đọc output của DVC vì nó có thể gợi ý thêm file cần git add.
Bước 3: đặt dữ liệu ở nơi khách cho phép
Git chỉ có file nhỏ, vậy dữ liệu thật đi đâu? DVC dùng remote, tức kho lưu trữ bên ngoài cho dữ liệu và model, hỗ trợ S3, Azure, GCS, SSH và nhiều loại khác. Với FDE, điều này quan trọng vì khách thường quyết định dữ liệu được phép nằm ở đâu.
dvc remote add myremote s3://mybucket
dvc push
Lệnh dvc push tải dữ liệu trong cache lên remote đã cấu hình. Đây là ví dụ đơn giản hoá; trước khi cấu hình remote thật cho khách, hãy đọc kỹ trang Remote Storage trong tài liệu DVC.
Để chắc chắn mọi thứ chạy đúng, mở bucket ra xem: dữ liệu vừa push phải nằm ở đó. Nếu khách chỉ cho dùng máy chủ nội bộ qua SSH, bạn đổi URL remote chứ không đổi quy trình.
Bước 4: đợt dữ liệu thứ hai đến
Khách gửi bản mới. Bạn ghi đè file và lặp lại đúng nhịp cũ:
dvc add data/data.xml
git add data/data.xml.dvc
git commit -m "Dữ liệu khách: đợt tuần 2"
dvc push
Mở lại data/data.xml.dvc và so với commit trước: MD5 đã đổi. Nếu khách bảo “bản này giống hệt tuần trước” mà hash khác, bạn vừa phát hiện một thay đổi thầm lặng trước khi nó làm hỏng model.
Bước 5: quay về đúng dữ liệu của một model cũ
Quay lại câu hỏi trong cuộc họp thứ Sáu. Bạn tìm commit của model production (dùng git log) và checkout nó. Trong ví dụ dưới, a1b2c3d chỉ là hash minh hoạ, hãy thay bằng hash thật trong repo của bạn:
git checkout a1b2c3d
dvc checkout
Quy tắc đáng thuộc lòng: mỗi lần gọi git checkout, luôn gọi thêm dvc checkout. Lý do quay về điểm đã nói từ đầu: DVC không tự giữ lịch sử, Git giữ, và Git chỉ biết tới file .dvc. Vì thế lệnh đầu chỉ đổi file .dvc về bản cũ; lệnh sau mới đưa dữ liệu trong thư mục làm việc về đúng phiên bản mà file đó trỏ tới.
Thời gian chờ phụ thuộc vào dung lượng dữ liệu, nên với dataset lớn đừng hứa với khách một con số trước khi tự đo.
Bước 6: chỉ train lại phần cần train lại
Để dvc repro có việc mà làm, repo cần một pipeline. Dưới đây là một file dvc.yaml tối giản với một stage tên filter, đọc dữ liệu khách và ghi ra file đã lọc. Đây là ví dụ đơn giản hoá: filter.py là script bạn tự viết, và cú pháp đầy đủ của dvc.yaml nằm trong tài liệu DVC.
stages:
filter:
cmd: python filter.py
deps:
- data/data.xml
- filter.py
outs:
- data/filtered.csv
Pipeline DVC hoạt động như một build system. Bạn chạy:
dvc repro
DVC chỉ chạy lại stage có input thay đổi, và in ra những dòng như “Stage ‘filter’ didn’t change, skipping” cho phần còn lại. Thử ngay: chạy dvc repro hai lần liền, lần thứ hai sẽ bỏ qua filter; sau đó dvc add đợt dữ liệu mới và chạy lại, stage sẽ chạy thật.
Sau mỗi lần chạy, hash của các dependency và output thay đổi được cập nhật vào dvc.lock. Commit file này vào Git, vì nó ghim lại trạng thái pipeline của một lần chạy tái lập được. Khi đã quen với một stage, bạn thêm dần các stage tạo feature và train theo đúng mẫu trên.
Những lỗi hay gặp
Lỗi phổ biến nhất là chỉ git checkout rồi train, trong khi thư mục data/ vẫn là bản mới nhất. Model “cũ” bạn tái lập thực chất là model mới với code cũ.
Lỗi thứ hai là commit file .dvc nhưng quên dvc push. Đồng nghiệp hoặc server của khách có commit nhưng không có dữ liệu tương ứng. Hãy coi git commit và dvc push là một cặp không tách rời.
Lỗi thứ ba là không commit dvc.lock. Khi đó bạn có dữ liệu đã version nhưng không chứng minh được lần train nào dùng đầu vào nào.
Ở site khách hàng, kỹ năng này trông ra sao?
Ở hiện trường, giá trị của DVC không nằm ở lệnh mà ở câu trả lời bạn đưa ra được. Khi khách hỏi vì sao model tuần này khác tuần trước, bạn chỉ vào hai commit, hai MD5 hash và dvc.lock của mỗi lần chạy. Cuộc tranh luận chuyển từ cảm giác sang bằng chứng.
Việc đầu tiên nên làm khi nhận một dự án mới: hỏi khách dữ liệu được phép lưu ở đâu, rồi chọn remote theo đó trước khi nhận đợt dữ liệu đầu tiên. Dựng quy trình sau khi đã có ba bản “final” thì muộn hơn nhiều.
Với developer Việt Nam muốn chuyển sang FDE, hãy để ý các JD nhắc tới “reproducibility”, “data versioning” hay “MLOps tại site khách hàng”. Một dòng CV như “version 12 đợt dữ liệu khách hàng bằng DVC trên S3, tái lập model bất kỳ từ commit” nói nhiều hơn một danh sách công cụ.
Khách sẽ luôn gửi thêm dữ liệu. Câu hỏi duy nhất là đến lần thứ mười, bạn còn biết model nào học từ bản nào hay không.