Nền tảng Camera AI · InnoVerse, 2024–nay

Analytics trên server trung tâm và thiết bị edge Jetson cho cảnh báo camera

Luồng video trực tiếp từ camera được phân tích tự động: khi người hoặc phương tiện đi vào một vùng (zone) hoặc vượt qua một vạch ranh giới (line), vận hành viên nhận cảnh báo chỉ trong vài giây. Hệ thống có thể chạy trên server trung tâm, hoặc chạy trực tiếp trên thiết bị Jetson nhỏ gọn đặt tại site khi chính sách bảo mật không cho phép đưa video ra ngoài.

RTSP · YOLO · DeepStream · RabbitMQ · NestJS

Kết quả: Cảnh báo trong vài giây ngay cả khi tải cao; chủ động drop frame khi inference không theo kịp; mô hình edge giữ toàn bộ video trên phần cứng tại site khách hàng.

Bài toán thực tế

Đội vận hành cần nhận thông báo tức thì khi có người hoặc phương tiện đi vào vùng giới hạn hoặc vượt qua vạch ranh giới trên hàng loạt camera hoạt động 24/7. Một số site nghiêm cấm đưa luồng video ra khỏi khuôn viên; các site khác cho phép gửi luồng về xử lý tại server trung tâm.

Nhiều luồng RTSP trên mỗi site; một stream bị trễ hoặc mất kết nối không được phép kéo theo các stream khác.
Kết quả phát hiện (detection) đến muộn không còn giá trị vận hành; tính kịp thời (freshness) quan trọng hơn việc xử lý đủ 100% số frame.
Kiến trúc multi-tenant dùng chung nền tảng; mỗi khách hàng (tenant) chỉ được phép nhìn thấy camera và event thuộc phạm vi của mình.
Thiết bị edge tại hiện trường phải cập nhật được qua mạng hạn chế và tự động rollback khi gói cập nhật gặp lỗi.

Kiến trúc hệ thống

Mô hình A — Chạy analytics trên server trung tâm

Áp dụng khi chính sách an ninh cho phép truyền luồng video về server trung tâm để xử lý detection tập trung. Đây là một mô hình triển khai độc lập và hoàn chỉnh — không phải bước trung gian trước khi chuyển sang mô hình thiết bị edge ở lựa chọn B.

flowchart LR
  subgraph cameras ["Tại site"]
    cameras_0(["Cameras at the site"])
  end
  subgraph server ["Analytics server"]
    server_0["RTSP ingest"]
    server_1[["Bounded queue · drop-oldest"]]
    server_2["YOLO detect and track"]
    server_3["Zone and line rules"]
  end
  subgraph messaging ["Event paths"]
    messaging_0[["Alert queue"]]
    messaging_1[["Metric queue"]]
    messaging_2[["Archival queue"]]
    messaging_3["Redis alert dedup"]
  end
  subgraph control ["Control plane"]
    control_0["NestJS camera admin and APIs"]
    control_1["OIDC identity service"]
  end
  subgraph persist ["Stores"]
    persist_0[("PostgreSQL alerts")]
    persist_1[("TimescaleDB metrics")]
    persist_2[("Object storage clips")]
  end
  cameras_0 -->|"video streams"| server_0
  server_0 --> server_1
  server_1 --> server_2
  server_2 --> server_3
  server_3 --> messaging_0
  server_3 --> messaging_1
  server_3 --> messaging_2
  messaging_0 --> messaging_3
  messaging_3 --> persist_0
  messaging_1 --> persist_1
  messaging_2 --> persist_2
  control_0 -->|"config"| server_0
  control_1 --> control_0

Mô hình B — Thiết bị Jetson đặt tại site (thay thế cho A, không chạy nối tiếp sau A)

Áp dụng khi video tuyệt đối không được rời khỏi khuôn viên (site). Quá trình detection diễn ra ngay trên thiết bị Jetson tại chỗ; chỉ có metadata của cảnh báo được gửi ra ngoài. Mỗi site chỉ vận hành theo mô hình A hoặc B — không bao giờ ghép nối cả hai.

flowchart LR
  subgraph site ["Tại site"]
    site_0(["Cameras at the site"])
    site_1(["Orin NX appliance"])
  end
  subgraph appliance ["Trên appliance"]
    appliance_0["DeepStream and TensorRT engine"]
    appliance_1["Python appliance control software"]
    appliance_2["Signed USB or OTA update"]
  end
  subgraph leaving ["Dữ liệu rời khỏi site"]
    leaving_0[["Alert queue"]]
    leaving_1["Redis alert dedup"]
    leaving_2[("PostgreSQL alerts")]
  end
  site_0 -->|"local video only"| site_1
  site_1 --> appliance_0
  appliance_1 -->|"manages the appliance"| appliance_0
  appliance_2 -->|"verified update"| appliance_1
  appliance_0 -->|"alert metadata only — no video"| leaving_0
  leaving_0 --> leaving_1
  leaving_1 --> leaving_2

Sơ đồ minh họa tương tác

Sơ đồ minh họa cơ chế tương tác nêu trên. Giao diện mô phỏng trung tính, không chứa dữ liệu thật hay số đo thực tế. Không phải ảnh chụp màn hình sản phẩm.

Các quyết định kiến trúc then chốt

Mô hình A — Drop-oldest khi bounded queue đầy

Giữa bước giải mã (decode) và bước inference, khi hàng đợi đầy sẽ chủ động bỏ frame cũ nhất để giữ lại frame mới nhất.

Nếu để frame xếp hàng chờ đợi, các sự kiện xâm nhập zone/line sẽ bị đẩy lùi về sau; cảnh báo đến trễ vài phút không còn ý nghĩa vận hành.

Phương án đã loại bỏ: Hàng đợi không giới hạn (unbounded queue) — loại bỏ vì độ trễ cảnh báo sẽ tăng tuyến tính theo thời gian nghẽn cổ chai.

Đánh đổi: Chấp nhận bỏ qua một số frame khi quá tải để đổi lấy việc cảnh báo phát ra luôn phản ánh thời gian thực.

Mô hình A — Tách 3 luồng RabbitMQ và dùng Redis chống trùng cảnh báo

Tách riêng 3 hàng đợi cho alert, metric và archival; chặn các cảnh báo trùng lặp của cùng một sự kiện trong một khoảng thời gian ngắn (cooldown window).

Tác vụ lưu trữ video (archival) nặng không được phép làm nghẽn cảnh báo an ninh, và lưu lượng metric lớn không được chiếm dụng tài nguyên xử lý alert.

Phương án đã loại bỏ: Dùng chung một queue có gắn độ ưu tiên (priority queue) — loại bỏ vì worker vẫn có thể bị kẹt khi đang xử lý dở các tác vụ lưu trữ nặng.

Đánh đổi: Tăng số lượng queue và consumer cần quản lý. Trong trường hợp Redis dedup gặp sự cố, hệ thống ưu tiên cho phép gửi cảnh báo đi tiếp — thà trùng lặp còn hơn bỏ sót cảnh báo.

Mô hình B — Biên dịch TensorRT engine theo đúng dòng thiết bị đích

Mỗi bản build model chỉ được phép phát hành sau khi đã chạy kiểm định bằng chính video hiện trường trên thiết bị có cùng kiến trúc phần cứng với thiết bị ngoài site.

File engine của TensorRT phụ thuộc chặt vào kiến trúc GPU và phiên bản thư viện; engine biên dịch trên máy chủ GPU ở lab không thể chạy tương thích trên chip Orin NX.

Phương án đã loại bỏ: Sao chép trực tiếp file engine build trên máy chủ GPU sang thiết bị edge — loại bỏ sau khi gặp lỗi sai lệch kết quả trên phần cứng đích.

Đánh đổi: Cần duy trì cụm thiết bị build riêng cùng hàng đợi kiểm định trước khi đưa phiên bản model mới xuống hiện trường.

Mô hình B — Gói cập nhật có chữ ký số và tự động rollback khi lỗi

Gói cập nhật phần mềm được xác thực chữ ký số trước khi cài đặt; nếu phiên bản mới khởi động lỗi hoặc không vượt qua được kiểm tra sức khỏe (health check), thiết bị sẽ tự động quay về phiên bản ổn định trước đó. Dùng chung một định dạng gói cho cả cập nhật qua USB lẫn OTA.

Các site bị giới hạn kết nối mạng vẫn cần được cập nhật phần mềm định kỳ mà không đối mặt với nguy cơ làm tê liệt thiết bị từ xa.

Đánh đổi: Phải quản trị khóa ký số (signing keys) và kiểm thử kịch bản rollback ở mỗi đợt phát hành.

Sự cố thực tế & cách khắc phục

Một camera mất kết nối hoặc gửi luồng lỗi từng làm treo luôn tiến trình xử lý của các camera bình thường khác.

Cô lập lỗi theo từng luồng: chỉ khởi động lại kết nối của camera gặp sự cố với thời gian chờ tăng dần (exponential backoff), giữ cho các stream khác tiếp tục chạy bình thường.

Đặt các tác vụ xử lý nặng ngay bên trong pipeline giải mã video làm nghẽn toàn bộ luồng hình ảnh đó.

Giữ cho video pipeline chỉ làm nhiệm vụ đọc và chuyển tiếp vùng nhớ frame ngay trên GPU; các tác vụ hậu xử lý nặng được tách hẳn ra ngoài.

Biên dịch engine sai cấu hình GPU khiến chỉ số FPS nhìn rất cao nhưng lại bỏ sót các vật thể kích thước nhỏ.

Bắt buộc biên dịch và đánh giá độ chính xác của model ngay trên đúng dòng phần cứng đích bằng tập video thực tế của site trước khi duyệt phát hành.

Phần tôi chịu trách nhiệm, trực tiếp viết và phân công

Chịu trách nhiệm (Own)

  • Kiến trúc tách biệt control plane và analytics data plane
  • Quy trình kiểm định model mới trên dữ liệu video thực tế của site và phê duyệt trước khi phát hành
  • Hệ thống NestJS API và OIDC identity dùng chung cho các sản phẩm enterprise
  • Định nghĩa event schema, chính sách drop-frame, cơ chế ký số bản cập nhật và bộ lọc cô lập tenant — tuyệt đối không ủy thác

Trực tiếp viết (Write)

  • Luồng inference phía server cùng các API quản lý camera và event
  • Vòng lặp xử lý DeepStream C++ và phần mềm Python điều khiển thiết bị tại site
  • Cơ chế định tuyến RabbitMQ và chống trùng cảnh báo (dedup) bằng Redis trên luồng alert

Phân công (Delegate)

  • Giao diện UI và ứng dụng mobile sau khi đã chốt API contract
  • Các tác vụ convert dữ liệu lặp lại sau khi đã định hình chuẩn xử lý

Quy mô vận hành

  • Technical Lead dẫn dắt đội ngũ tối đa 10 kỹ sư; trực tiếp viết code phần inference và API
  • Nền tảng control-plane cốt lõi được tái sử dụng cho 3 sản phẩm enterprise
  • Hai mô hình triển khai độc lập: xử lý tập trung trên server và xử lý tại chỗ trên thiết bị Jetson Orin NX

Ranh giới phạm vi

  • Tác vụ CUDA trên luồng này sử dụng runtime của TensorRT và bộ giải mã phần cứng NVDEC; không viết custom CUDA kernel riêng.
  • Bộ phát hiện (detector) dùng họ model YOLO thông qua ONNX; phiên bản model và thuật toán tracker được cấu hình theo đặc thù từng site.
  • TensorRT engine được biên dịch tại lab trên đúng dòng GPU đích; không bao giờ đem file engine build trên GPU datacenter sang chạy trên Orin.

Các chỉ số giám sát khi vận hành

Độ trễ cảnh báo (alert latency) sau khi áp dụng cơ chế drop-frameTỷ lệ frame bị drop và tốc độ FPS đầu vào trên từng streamĐộ sâu hàng đợi (queue depth) của luồng alert so với luồng archival

Nguyên tắc bất di bất dịch trong thiết kế

  • Một stream bị quá tải hoặc đứt kết nối không bao giờ được làm gián đoạn các stream khác.
  • Cảnh báo phải đến tay vận hành viên trong vài giây ngay cả khi tải cao, không được phép trễ hàng chục giây.
  • Mọi truy vấn đều phải cô lập theo tenant; một tenant tuyệt đối không thể đọc được camera hay sự kiện của tenant khác.

Phạm vi ứng dụng rộng hơn

  • Hệ thống camera giám sát cố định quy mô lớn hoạt động trên đường truyền mạng không ổn định.
  • Các khu vực yêu cầu giữ toàn bộ dữ liệu hình ảnh tại chỗ nhưng vẫn cần quản trị tập trung.
  • Trung tâm điều hành cần cảnh báo xâm nhập vùng/vạch có độ tin cậy cao và ít báo giả.