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 |
|---|---|---|
| Frontend | Giao diện bảng điều khiển, phục vụ bởi nginx | 80 (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 |
| Inference | Thực thi mô hình ONNX trên CPU/CUDA/TensorRT | 50051 (gRPC) |
Plugin datasource
Phần tiêu đề “Plugin datasource”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.
Pipeline suy luận
Phần tiêu đề “Pipeline suy luận”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:
- 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.
- Runtime duy trì một cửa sổ trượt gồm
window size × tag countmẫu; khi đầy, mỗi mẫu mới tạo ra một dự đoán (health_score,failure_probability,rul_normalized). - 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.
Vòng đời mô hình
Phần tiêu đề “Vòng đời mô hình”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 đó.
Sự kiện thời gian thực
Phần tiêu đề “Sự kiện thời gian thự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.
Ghi log — ba lớp có giới hạn
Phần tiêu đề “Ghi log — ba lớp có giới hạn”| Lớp | Mục đích | Giới hạn |
|---|---|---|
stdout của container (docker logs) | Gỡ lỗi trực tiếp | 10 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ệu | 10 MB × 7 (backend) / × 6 (inference) |
| Kho log SQLite | Trang LogViewer và cảnh báo thông báo | 10.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.
Nhập / xuất cấu hình
Phần tiêu đề “Nhập / xuất cấu hình”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 đủ.