0
0
Lập trình
Flame Kris
Flame Krisbacodekiller

Triển khai Mô Hình CNN-BiLSTM trên AWS Lambda

Đăng vào 7 tháng trước

• 8 phút đọc

Triển khai Mô Hình CNN-BiLSTM trên AWS Lambda

Triển khai mô hình học sâu của tôi vào sản xuất nghe có vẻ đơn giản ban đầu. Tôi có một mô hình Mạng Nơ-ron Tích chập + LSTM hai chiều (CNN-BiLSTM) để phát hiện Alzheimer dựa trên EEG, và tôi muốn cung cấp nó qua một API không máy chủ trên AWS. Tuy nhiên, việc này dẫn đến một loạt lỗi, và trong bài viết này, tôi cố gắng ghi lại những sai lầm mà tôi đã mắc phải, cho bản thân trong tương lai và những ai có thể đang thử nghiệm lần đầu và gặp khó khăn.

Tổng Quan

Trước khi đi vào các sai lầm, hãy cùng thảo luận ngắn gọn về mô hình học sâu. Nó kết hợp CNN và BiLSTM để phát hiện Alzheimer dựa trên dữ liệu EEG.

Ứng dụng này cho phép người dùng tải lên các tệp EEG .set và nhận dự đoán về Alzheimer, mất trí nhớ trước trán, và kết quả khỏe mạnh với điểm số tin cậy. Các tệp tải lên sẽ được gửi trực tiếp đến S3, sau đó một Lambda không máy chủ (được đóng gói với TensorFlow + MNE) sẽ lấy tệp đó, tiền xử lý, thực hiện suy diễn và trả về JSON cho trình duyệt.

Kiến Trúc Cấp Cao

  • Người dùng tải lên tệp EEG qua trình duyệt.

  • URL đã ký trước được phát hành để trình duyệt có thể tải lên trực tiếp đến S3.

  • Trình duyệt tải tệp lên S3 (không có máy chủ ở giữa).

  • Trình duyệt gọi /predict, truyền khóa đối tượng S3.

  • Lambda (đóng gói Docker TF + MNE) tải xuống, tiền xử lý và thực hiện suy diễn.

  • Phản hồi JSON trả về: { predicted_class, confidence }.

Thiết lập AWS (cơ bản)

  • S3 bucket: Riêng tư; CORS được kích hoạt cho miền frontend; đối tượng PUT qua các URL đã ký trước.

  • IAM: Vai trò thực thi cho Lambda với quyền đọc S3 (và PutObject để tạo URL đã ký trước).

  • ECR: Đẩy hình ảnh container (TensorFlow + MNE + mô hình).

  • Lambda (container): Bộ nhớ đủ (ví dụ: 2–4 GB+), thời gian chờ (ví dụ: 120s+), biến môi trường cho tên BUCKET.

  • API Gateway hoặc URL Function Lambda: Điểm cuối HTTPS công khai với CORS được kích hoạt.

URL đã ký trước là gì?

Trước khi tiếp tục, chúng ta hãy cùng tìm hiểu URL đã ký trước là gì?

Một URL đã ký trước của S3 là một liên kết tạm thời, đã ký cho phép ai đó tải lên hoặc tải xuống tệp trực tiếp đến/từ S3 mà không cần thông tin xác thực AWS.

  • Thông thường, chỉ những người dùng/nhóm IAM có quyền S3 thích hợp mới có thể tải lên tệp.

  • Nhưng trình duyệt (frontend) không nên có khóa AWS được mã hóa cứng (điều này không an toàn).

  • Thay vào đó, ứng dụng Lambda/Flask ở backend tạo một URL đã ký trước với thời gian hết hạn (1 giờ).

  • Sau đó, trình duyệt tải tệp trực tiếp lên S3 bằng liên kết đó, bỏ qua backend.

Để thực hiện điều này, chúng ta có đường dẫn /presign trong lambda_function.py.

Trước khi tải lên, frontend yêu cầu backend một liên kết tải lên tạm thời đã ký, tức là:

Copy
GET /presign?key=uploads/myfile.set

Backend sau đó sẽ tạo URL tạm thời qua boto3 và trả về JSON.

Sau đó, frontend (trình duyệt) với URL tải lên trực tiếp đến S3.

Nhưng bạn có thể hỏi Tại sao lại phải đi theo cách vòng vo này khi chúng ta có thể chỉ cần tải lên Lambda?

Vì giới hạn tải của API Gateway là 10 MB. Nếu tệp tải lên lớn hơn (như trường hợp này), nó sẽ bị từ chối. Trong khi đó, phương pháp S3 được xây dựng để mở rộng quy mô.

Những Sai Lầm

Ngay cả với hướng dẫn trực tuyến và sự giúp đỡ từ ChatGPT, tôi đã mắc phải một số sai lầm, và dưới đây là danh sách chúng:

Sai Lầm 1: “Chỉ số hình ảnh” ECR vs “hình ảnh”

Khi tải các tệp từ máy cục bộ lên ECR, tôi đã sử dụng Docker Buildx theo mặc định. Điều này dẫn đến loại Artifact: Chỉ số hình ảnh trong ECR. Tuy nhiên, Lambda chỉ chấp nhận một bản khai hình ảnh duy nhất (Linux/Amd64), dẫn đến lỗi.

Vì vậy, để khắc phục, chúng tôi phải buộc sử dụng Builder cổ điển, để kết quả là một bản khai duy nhất (không phải chỉ số).

Sai Lầm 2: Sử dụng các phiên bản tương thích

Phiên bản mới Tensorflow (2.17+) kéo theo Keras 3, cần optree.

Và các hình ảnh lambda cơ bản của AWS không có optree được xây dựng sẵn. Optree này sử dụng C++. Vì vậy, khi chúng ta pip install tensorflow, nó cố gắng biên dịch optree từ nguồn. Để biên dịch, bạn cần gcc, g++, cmake, và Unix Makefiles. Những điều này không có trong hình ảnh Lambda tiêu chuẩn. Điều này dẫn đến lỗi biên dịch, và nếu chúng ta muốn bao gồm chúng, nó sẽ dẫn đến một hình ảnh Docker lớn hơn rất nhiều.
Vì vậy, để khắc phục, tôi đã sử dụng TensorFlow 2.15 (Keras v2 được gói kèm). Điều này không có Keras 3, do đó không có optree.

Sai Lầm 3: Thiếu Quyền Truy Cập S3

Khi thiết lập vai trò IAM, tôi không nhận ra rằng tôi cần phải cho phép cụ thể vai trò của Lambda đọc/ghi trên bucket. Sau một thời gian tìm kiếm và kiểm tra nhật ký lỗi, cuối cùng tôi cũng nhận ra.

Vì vậy, tôi đã cập nhật vai trò thực thi của Lambda để bao gồm quyền truy cập S3 (cho phép GetObject và PutObject trên bucket của tôi). Chỉ sau đó, hàm của tôi mới có thể lấy các tệp EEG đã tải lên từ S3 và lưu kết quả nếu cần.

Sai Lầm 4: Quên về CORS (Chia sẻ Tài nguyên Gốc)

Trình duyệt của tôi sẽ cố gắng gọi điểm cuối API Gateway của Lambda, nhưng đó là chính sách CORS của trình duyệt.

Điều này rất khó chịu vì lỗi không đến từ mã của tôi hoặc AWS, mà từ trình duyệt vì lý do bảo mật. Thủ phạm là tôi đã quên kích hoạt CORS trên API Gateway và bucket S3 của mình.

Cuối cùng, tôi phát hiện ra rằng tôi cần cấu hình CORS để trang tĩnh của mình có thể gọi API và tải lên S3. Thực tế, tôi thậm chí đã thêm một ghi chú ở chân trang của ứng dụng nhắc nhở bản thân trong tương lai rằng: “Hãy chắc chắn rằng CORS được kích hoạt trên API Gateway và bucket S3 của bạn.”

Sau khi kích hoạt CORS trong API Gateway (cho phép miền của tôi/localhost và các phương thức HTTP cần thiết) và thêm chính sách CORS phù hợp trên bucket S3, frontend và backend cuối cùng đã bắt đầu giao tiếp đúng cách.

Sai Lầm 5: Cấu hình sai API Gateway (Tại sao tôi lại nhận được 404?)

Sau tất cả những điều này, khi tôi truy cập API, tôi nhận được lỗi HTTP 404. Vì vậy, tôi đã kiểm tra lại mã Lambda của mình – các hàm cho /predict/health đã tồn tại.

Nhưng sau đó tôi nhận ra rằng sai lầm nằm ở cấu hình API Gateway của tôi. Tôi đã không thiết lập đúng các đường dẫn tài nguyên hoặc các tích hợp cho các tuyến đường. API Gateway không chuyển tiếp /predict hoặc /health đến Lambda của tôi, do đó dẫn đến lỗi 404.

Khi tôi truy cập …/health từ trình duyệt, API Gateway thực sự mong đợi một cái gì đó như …/default/health, điều này rõ ràng là không tồn tại.

Khi tôi phát hiện điều này, tôi đã quay lại bảng điều khiển AWS, sửa chữa định nghĩa đường dẫn (đảm bảo chúng khớp với những gì client của tôi đang gọi), và triển khai API đến giai đoạn chính xác.

Kết Luận

Vì vậy, trong quá trình triển khai, tôi đã mắc phải một số sai lầm như các bản khai Docker, sự không tương thích phiên bản, thiếu quyền IAM, lỗi CORS, và cấu hình sai API Gateway. Mỗi sai lầm này đã làm chậm tôi, nhưng cũng buộc tôi phải hiểu cách AWS Lambda, S3 và API Gateway thực sự hoạt động cùng nhau.

Cấu hình cuối cùng rất đơn giản cho người dùng—tải lên một tệp EEG, chờ vài giây, và nhận dự đoán với độ tin cậy. Nhưng phía sau, có một hệ thống cẩn thận: S3 để lưu trữ, URL đã ký trước để tải lên an toàn, các container Lambda để suy diễn, và API Gateway như cầu nối.

Vì vậy, nếu bạn đang đưa mô hình đầu tiên của mình lên đám mây, hãy chuẩn bị cho một số va chạm—nhưng cũng hãy mong đợi sẽ ra ngoài phía bên kia với những kỹ năng kỹ thuật sắc bén hơn.

👉 Bạn có thể thử ứng dụng đã được triển khai tại đây: [Link]
👉 Mã nguồn có sẵn trên GitHub

vivekvohra / EEG-CNN-BiLSTM

Học Sâu để Phát Hiện Alzheimer từ Dữ Liệu EEG

EEG-CNN-BiLSTM (demo AWS Lambda + S3)

Demo hoàn chỉnh phục vụ một bộ phân loại EEG CNN-BiLSTM từ AWS Lambda (hình ảnh container) với một frontend tĩnh trên S3. Bạn có thể tải lên một tệp EEGLAB .set (hoặc thực hiện một dự đoán demo), và nhận lại xác suất lớp.

Trực tiếp: https://az-eeg-site-109598917777.s3.ap-south-1.amazonaws.com

Copy
EG-CNN-BiLSTM/
├── backend/                  # Mã Lambda + Docker
│   ├── lambda_function.py
│   ├── preprocess.py
│   ├── Dockerfile.dockerfile
│   ├── requirements.txt
│   └── model/
│       └── alzheimer_eeg_cnn_bilstm_model.h5
├── frontend/                 # Trang tĩnh S3
│   ├── index.html
│   ├── app.js
│   └── style.css
├── research/                 # tài liệu & sổ tay
│   ├── train.ipynb
│   └── conference.pdf
├── LICENSE
└── README.md

Video demo

Ghi lại.2025-09-18.003432.mp4

Nội dung bên trong

  • Mô hình: Keras .h5 CNN-BiLSTM được lưu với TF 2.x (được gán cho TF 2.15 tại thời điểm chạy).

  • Backend (backend/):

    • lambda_function.py – Ứng dụng Flask được bọc bởi serverless-wsgi cho API Gateway HTTP API.

    • preprocess.py – tải .set và chuẩn bị đầu vào cho mạng.

    • Dockerfile.dockerfile

Xem trên GitHub

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào