Trong bài viết trước về Hệ thống OCR nhận diện Chứng minh thư nhân dân Việt Nam, chúng tôi đã giới thiệu sản phẩm của team Vision, tiến trình triển khai cơ bản của sản phẩm cũng như một số mô hình được team sử dụng. Đa phần thời gian chúng tôi xử lý dữ liệu và huấn luyện mô hình bằng dòng lệnh.

Các tác vụ dần trở nên trùng lặp và tẻ nhạt khi số lượng dữ liệu lớn dần. Chúng tôi phải thực hiện nhiều thực nghiệm giống nhau. Chúng cũng tiêu tốn nhiều thời gian và nhân lực trong công tác theo dõi, phát hiện bug và các lỗi ngớ ngẩn. Điều này được khắc phục phần nào bằng cách viết một số script tự động như Bash, Makefile, hay Rakefile. Tuy nhiên, việc quản lý các quy trình và các thư viện phụ thuộc lại không khác gì một cơn ác mộng. Ngoài ra, việc chuyển một luồng có sẵn lên một máy chủ mới cũng tốn rất nhiều thời gian cho việc cài đặt ban đầu khi nhiều bug phát sinh.

Chính vì vậy, chúng tôi ưu tiên việc tự động hóa quy trình lên trước tiên. Tức là phải có một công cụ hỗ trợ luồng ETL, qua đó tự động hoá quy trình chuẩn bị dữ liệu, huấn luyện và trích xuất mô hình. Trong quá trình tìm kiếm, Kubeflow Pipelines  đã gây sự chú ý với chúng tôi bởi lẽ nó coi các Docker container như những tác vụ cần phải tự động hóa. Tuy nhiên, giải pháp này lại quá nặng nề và phức tạp khi được triển khai trên nền Kubernetes, không phù hợp với nhóm nghiên cứu chúng tôi. Sau nhiều sự cân nhắc, chúng tôi đã phát hiện ra một giải pháp phù hợp hơn, đó là: Airflow.

Qua bài viết này tôi sẽ trình bày cách chúng tôi đưa Airflow vào để sử dụng để tự động hóa quy trình cũng như những kinh nghiệm mà chúng tôi rút ra được.

Cấu trúc

Dưới đây là hình dung qua về cấu trúc mà chúng tôi sử dụng:

Sau khi có được một quy trình thủ công thủ công ổn định, chúng tôi gói mọi thứ thành Docker container. Việc đơn giản còn lại là viết code chỉ dẫn cho Airflow. Airflow sẽ diễn giải chúng thành một luồng tự động (ví dụ: xử lý dữ liệu, huấn luyện, kiểm thử và trích xuất mô hình) sẵn sàng để chúng tôi kích hoạt. /data/export ở hình vẽ phía trên là các thư mục được mount mẫu mà chúng tôi dùng để lưu trữ dữ liệu và các mô hình.

Việc cài đặt Airflow dễ dàng, song lại tốn thời gian với việc cài đặt thêm hệ cơ sở dữ liệu (ví dụ: Postgres) cho tác vụ lưu trữ, hay là tích hợp Docker… Vì vậy, chúng tôi dùng docker-compose để nhanh chóng cài đặt và khởi động Airflow chỉ bằng một lệnh cơ bản duy nhất docker-compose up airflow.

Ở đây chúng tôi sử dụng một Airflow image được tùy chỉnh riêng: hiepph/docker-airflow:latest. 

Airflow không mặc định hỗ trợ chạy Docker container bằng GPU, vì vậy chúng tôi phải viết một plugin cho tác vụ này: DockerGPUOperator. Đây là phiên bản cải tiến của DockerOperator với khả năng hỗ trợ và tùy chọn chọn thiết bị để chạy container với GPU.

Có rất nhiều practice trong việc sử dụng Airflow trên thị trường, sau nhiều sự đánh giá chúng tôi đã đề ra một tiêu chuẩn riêng cho các kỹ sư và nhà nghiên cứu của team.

plugins là nơi lưu trữ các plugin (ví dụ DockerGPUOperator như đã nêu ở trên). Việc tương tác với dữ liệu và mô hình cũng được thực hiện khá dễ dàng thông qua việc mount các thư mục dataexport.

Trên lý thuyết, Airflow thực hiện các tác vụ dựa trên hướng dẫn DAG. DAG hiểu ngắn gọn trong thuật ngữ của Airflow là một Python script, trong đó có chứa các hướng dẫn thực hiện tác vụ theo luồng. Các hướng dẫn này sẽ được lưu trữ trong thư mục dags, và sẽ được liên tục cập nhật mới nhất bởi Airflow. DAG hỗ trợ rất nhiều chỉ dẫn như BashOperator, PythonOperator… song theo tiêu chuẩn đề ra chúng tôi chỉ sử dụng DockerOperator DockerGPUOperatorViệc này sẽ làm giảm sự phức tạp phát sinh trong việc chọn Operator phù hợplệ thuộc vào thư viện thứ ba. Việc viết tác vụ dưới dạng DAG cũng khá dễ dàng, bởi lẽ chúng tôi vẫn được viết dưới syntax quen thuộc của Python cùng các thư viện hỗ trợ. Chúng tôi đã chuyển hướng từ tập trung tự động hóa và quản lý luồng sang viết một script hướng dẫn đơn giản.

Để lấy ví dụ về việc sử dụng DAG, giả sử ta có luồng như dưới đây:

Sau quá trình tiền xử lý dữ liệu, ta sẽ huấn luyện, kiểm thử và cuối cùng là trích xuất mô hình. Tôi có một ví dụ script mẫu:

Có thể thấy, ta dễ dàng viết được luồng tự động của các tác vụ và chỉ ra tác vụ nào thì dùng GPU.

Demo

Trăm nghe không bằng một thấy.  Sau đây là một demo đơn giản chúng tôi sử dụng Airflow để tự động hóa pipeline huấn luyện một mô hình phát hiện khẩu trang.

Mục tiêu của mô hình là phát hiện toàn bộ khuôn mặt trong khung hình và xác định xem ai đang đeo khẩu trang. Một bài toán detection cơ bản. Mô hình được sử dụng là EfficientDet, còn dữ liệu chúng tôi sử dụng được công khai bởi AIZOOTech.

Để đơn giản hóa, chúng tôi đã xử lý sẵn dữ liệu và sử dụng luồng đơn giản như hình bên dưới:

Quá trình huấn huyện sẽ lấy dữ liệu trong thư mục data, sau đó ta sẽ thực hiện kiểm thử và trích xuất mô hình. Quá trình kiểm thử sẽ out hình ảnh kết quả lưu trong thư mục results, trích xuất mô hình ra thư mục export. Codebase cụ thể sẽ như sau:

Còn đây là DAG mẫu mà tôi đã viết:

Giờ thì ta có thể vào trang admin (ip:8080) của Airflow để kích hoạt (trigger) tác vụ:

Trong mục GraphView, có thể thấy pipeline được biểu diễn dưới dạng đồ thị:

Ngoài ra, bạn cũng có thể kiểm tra rất nhiều thông tin khác của tác vụ. Nhưng ở đây, tôi sẽ chỉ tập trung vào TreeView – nơi liệt kê các thực nghiệm và trạng thái hoàn thành của các tác vụ.

Vậy là luồng đã chạy thành công và không xuất hiện lỗi. Bên cạnh đó, ta có thể thấy tôi đã chạy nhiều thực nghiệm khác nhau trước đó và đa số không thành công.

Giờ thì hãy kiểm tra thư mục results:

Và trong thư mục export đã có mô hình được trích xuất và sẵn sàng sử dụng với Serving!

Phía trên là demo cơ bản về việc sử dụng Airflow. Tất nhiên, Airflow hỗ trợ rất nhiều những chức năng khác chưa được đề cập trong bài. Sức sáng tạo  là tùy thuộc vào bạn với Docker container và DAG.

Như vậy, Airflow giúp giảm đi rất nhiều tài nguyên thời gian và nhân lực thông qua việc tập trung vào tự động hóa. Trong tương lai, chúng tôi dự kiến sẽ sử dụng Airflow trên nền tảng của mình, nhằm tự động hóa các quy trình huấn luyện cho khách hàng thông qua API. Chi tiết sẽ được trình bày trong một bài viết tương lai.

Phạm Hoàng Hiệp – FPT Head Office

Tin liên quan: