Bỏ qua để đến nội dung

Kiến trúc hệ thống

Một X-Edge AI box chạy một stack ba dịch vụ tự chứa. Mọi thứ — cấu hình, phiên bản mô hình, lịch sử, log — đều nằm trên box; không có phụ thuộc cloud nào ở thời điểm chạy.

flowchart LR
  subgraph Box["X-Edge AI Box (Docker)"]
    FE["Frontend\nnginx + React"] -->|REST + SignalR| BE["Backend\nASP.NET orchestration"]
    BE -->|gRPC :50051| INF["Inference runtime\nPython + ONNX Runtime"]
    BE --- DB[("SQLite\nconfig · history · logs")]
    PLUG["Datasource plugins\nOPC UA · MQTT · CSV"] --- BE
  end
  SENSORS["PLCs · brokers · devices"] --> PLUG
  PLUG -->|predictions written back| SENSORS
  USER["Operator browser"] --> FE
Dịch vụVai tròCổng
FrontendGiao diện bảng điều khiển, phục vụ bởi nginx80 (443 với TLS)
BackendĐiều phối: datasource, mô hình, vòng đời suy luận, xác thực, lưu trữ5000
InferenceThực thi mô hình ONNX trên CPU/CUDA/TensorRT50051 (gRPC)

Các giao thức công nghiệp được hiện thực dưới dạng plugin được backend nạp lúc khởi động. Mỗi plugin mô tả các thiết lập kết nối của nó dưới dạng schema có kiểu, mà UI render thành một biểu mẫu động — thêm một giao thức không bao giờ đòi hỏi build lại UI.

  • Đầu vào (đường đọc): OPC UA (poll mỗi tick), MQTT (push kèm bộ bảo vệ dữ liệu cũ), và phát lại CSV.
  • Đầu ra (đường ghi): OPC UA, MQTT, và các file CSV xoay vòng. Địa chỉ của một tag đầu ra được dùng nguyên văn (một topic MQTT, một OPC UA NodeId, một cột CSV), và mỗi giá trị được co giãn theo value × scale + offset.

Hai đường này hỏng theo cách khác nhau một cách có chủ đích: một tag đầu vào chết sẽ dừng suy luận một cách rõ ràng (cấp dữ liệu cũ cho mô hình là kiểu hỏng tệ nhất đối với phát hiện bất thường), trong khi một sink đầu ra lỗi không bao giờ làm nghẽn suy luận — thay vào đó nó phát một thông báo Ghi đầu ra thất bại đã được gộp.

Một datasource đầu vào được bật cấp dữ liệu cho một mô hình được ghép cặp:

  1. Backend lấy mẫu các tag đã ánh xạ theo tốc độ lấy mẫu của datasource và truyền chúng tới runtime suy luận qua gRPC.
  2. Runtime duy trì một cửa sổ trượt gồm window size × tag count mẫu; khi đầy, mỗi mẫu mới tạo ra một dự đoán (health_score, failure_probability, rul_normalized).
  3. Các dự đoán chảy ngược lại và phân tán tới bảng điều khiển (SignalR), kho lịch sử, các sink đầu ra đã cấu hình, và audit trail SQLite trên box.

Do đó thông lượng co giãn theo tốc độ lấy mẫu × số datasource, không theo tốc độ của bên publish — một cảm biến 100 Hz được lấy mẫu ở 10 Hz cho ra 10 dự đoán/giây.

Backpressure theo từng consumer: các bảng điều khiển chậm không bao giờ được phép làm nghẽn suy luận (sự kiện của chúng bị bỏ trước), các sink đầu ra nhận một hàng đợi chặn không mất dữ liệu, làm chậm pipeline end-to-end khi một sink không theo kịp, và các dự đoán không hữu hạn (NaN/Inf) bị lọc và đếm. Tất cả những thứ này đều hiển thị dưới dạng bộ đếm — xem Giám sát.

Các mô hình được soạn ngoài box với modelctl (convert → validate → quantize → package), rồi được upload qua UI. Việc upload xác thực hợp đồng ONNX qua runtime suy luận (shape + SHA-256) mà không nạp nó; mô hình chỉ vào engine khi datasource của nó được bật. Nạp là một hot swap không thời gian chết, và các phiên bản là bất biến — upload lại một file đã thay đổi dưới cùng phiên bản sẽ bị từ chối. Rollback kích hoạt lại phiên bản hợp lệ trước đó.

Các cập nhật bảng điều khiển trực tiếp (lô cảm biến, dự đoán, tình trạng, thay đổi trạng thái, thông báo) đi qua một hub WebSocket SignalR. Luồng này là fire-and-forget và trong bộ nhớ — nó không bao giờ là nguồn sự thật. Nếu một trình duyệt ngắt kết nối, các sự kiện bị bỏ lỡ sẽ không được phát lại; trạng thái có thẩm quyền luôn đến từ REST API và cơ sở dữ liệu trên box.

LớpMục đíchGiới hạn
stdout của container (docker logs)Gỡ lỗi trực tiếp10 MB × 3 file mỗi dịch vụ
File xoay vòng trên volume bền vững (Warning+)Điều tra hậu sự cố — sống sót qua việc tạo lại container và hỏng cơ sở dữ liệu10 MB × 7 (backend) / × 6 (inference)
Kho log SQLiteTrang LogViewer và cảnh báo thông báo10.000 mục, quét mỗi 60 giây

Các dòng pipeline theo từng tick được ghi ở mức Debug; luồng Info mặc định chỉ mang các sự kiện vòng đời, heartbeat và cảnh báo.

Admin có thể xuất toàn bộ cấu hình suy luận (các datasource đầu vào và đầu ra bao gồm ánh xạ tag) thành một phong bì JSON có phiên bản và nhập lại nó trên một box khác. Secret được che khi xuất; việc nhập chạy trong một giao dịch duy nhất — bất kỳ lỗi theo từng mục nào cũng roll back toàn bộ file và trả về danh sách lỗi đầy đủ.