Node-RED Vision Platform
A comprehensive Node-RED package for ML inference, Firebase integration, and dataset management. Supports YOLO, Paddle, RF-DETR, TensorRT, and anomaly detection models with Docker-based inference serving and NVIDIA Triton support.
Quick Start
Installation
From npm (CLI)
cd ~/.node-red
NPM_TOKEN="$(gcloud auth print-access-token)" npm install @rosepetal/node-red-contrib-vision-platformRequirements
- Node.js 16+
- Docker (for inference nodes)
- Firebase project (for dataset nodes)
Node Categories
Config Nodes - Firebase Configuration
| Node | Purpose | Key Features |
|---|---|---|
| firebase-config | Configure Firebase connection | Authentication, dataset sync, model management |
Dataset Nodes - Data Management
| Node | Purpose | Key Features |
|---|---|---|
| dataset-upload | Upload images to Firebase datasets | Batch upload, concurrent processing, progress tracking, PNG compression |
| from-dataset | Retrieve images from datasets | Random sampling, filtered selection, tag-based queries |
| list-dataset | List available datasets | Dataset enumeration, metadata retrieval, real-time sync |
| list-model | List available ML models | Model enumeration, task normalization |
Inference Nodes - ML Model Serving
| Node | Purpose | Key Features |
|---|---|---|
| inferencer | Run ML model inference | YOLO, Paddle, RF-DETR, TensorRT, Anomaly detection |
| ocr-inferencer | OCR-specific inference | Text recognition, document processing pipelines |
| triton-inferencer | NVIDIA Triton inference | TensorRT optimization, gRPC + shared memory, Firebase model auto-conversion |
Architecture
Modular Design
The codebase follows a bounded-context modular architecture on both the Node.js and Python sides:
- Node.js modules (
nodes/inference/modules/): Six bounded contexts —inference-core(7-stage pipeline),grpc-client(connection pool),container-lifecycle(Docker management),image-processing(image I/O and shared memory),model-management(model resolution and download), andshared(constants and utilities). - Python server (
inference-server/): Composition-root pattern —server.pywires togetherrpc/(gRPC handlers),models/(model loading, TensorRT, state),workers/(worker pool and process management), andbatching/(dynamic batching).
Inference Pipeline
Each prediction follows a 7-stage chain: validate → resolve-model → ensure-model → process-images → execute-inference → convert-results → assemble-response. The thin node files (inferencer.js, ocr-inferencer.js) delegate all logic to the pipeline modules.
Docker-Based Inference
- Container Management: Automatic Docker container lifecycle
- gRPC Protocol: High-performance model communication
- Multi-Model Support: Run multiple models concurrently
- Auto-Warmup: Optional model pre-warming for faster first inference
Supported Model Types
| Model | Tasks |
|---|---|
| YOLO | Detection, Segmentation, Classification |
| Paddle | Detection, OCR, Recognition, Document Rotation |
| RF-DETR | Detection |
| TensorRT | Detection, Segmentation, Classification |
| Anomaly | Anomaly Detection |
Firebase Integration
- Dataset management and synchronization
- Image upload with automatic thumbnailing
- Tag-based image filtering and retrieval
- Model download and versioning
Project Structure
node-red-contrib-vision-platform/
├── node-red-contrib-vision-platform/
│ ├── lib/ # Shared utilities
│ │ ├── firebase.js # Firebase CommonJS wrapper
│ │ ├── firebase.mjs # Firebase ESM module
│ │ ├── dataset-utils.js # Dataset helper functions
│ │ └── result-conversion.js # Result type conversions
│ └── nodes/
│ ├── config/ # Configuration nodes
│ ├── dataset/ # Dataset management nodes
│ ├── inference/ # ML inference nodes
│ │ ├── inferencer.js # Inferencer node (thin wrapper)
│ │ ├── ocr-inferencer.js # OCR node (thin wrapper)
│ │ ├── http-endpoints.js # Admin REST API
│ │ ├── config_prefabs/ # 13 model configuration presets
│ │ ├── serving/proto/ # gRPC service definitions
│ │ └── modules/ # Modular architecture
│ │ ├── inference-core/ # Pipeline: 7-stage inference chain
│ │ ├── grpc-client/ # gRPC connection pool & operations
│ │ ├── container-lifecycle/ # Docker container management
│ │ ├── image-processing/ # Image I/O, shared memory
│ │ ├── model-management/ # Model resolution, download, config
│ │ └── shared/ # Constants, utilities, node helpers
│ └── triton-inferencer/ # NVIDIA Triton inference node
│ ├── triton-inferencer.js # Node logic + HTTP admin endpoints
│ ├── modules/ # Triton-specific modules
│ │ ├── triton-server.js # Singleton Docker lifecycle
│ │ ├── triton-client.js # gRPC client + shared memory
│ │ ├── firebase-model-manager.js # Firebase → TensorRT pipeline
│ │ └── model-repository.js # Triton repository API
│ └── proto/ # Triton gRPC protocol definitions
├── inference-server/ # Python gRPC inference server
│ └── serving/inference_server/
│ ├── server.py # Composition root (thin)
│ ├── rpc/ # gRPC handlers & response builders
│ ├── models/ # Model loading, TensorRT, state
│ ├── workers/ # Worker pool, process management
│ └── batching/ # Dynamic batching
├── triton-server/ # Triton server Docker configuration
├── docs/ # VitePress documentation
├── package.json
└── README.mdConfiguration
Firebase Setup
- Deploy a firebase-config node
- Configure Firebase credentials
- Datasets and models will sync automatically
Inference Setup
- Ensure Docker is running
- Deploy an inferencer node
- Select model type and configuration
- Connect image input to trigger inference
Troubleshooting
Common Issues
- Docker Connection: Ensure Docker daemon is running
- Firebase Auth: Verify credentials in firebase-config node
- Model Loading: Check model path and Docker image availability
- Memory Issues: Adjust container memory limits for large models
Performance Tips
- Use warmup for latency-sensitive applications
- Process batches when possible for throughput
- Monitor container health via node status
Releasing
A release ships three artifacts that must all exist at the same version (the nodes pull detection:${version} / triton:${version} at runtime, where the version is package.json's): the npm package and the detection and triton Docker images.
Releases are prepared on dev and published by CI when the release PR merges to main. Two manual steps, everything else is automatic:
# 1. on dev, with your work committed and pushed:
./release.sh patch # or minor / major / an explicit 1.4.2 (default: patch)
# 2. merge the dev -> main PR it opened (GitHub UI)release.sh (on dev) merges origin/main back in, bumps the version, builds and pushes both Docker images at full GPU-arch coverage, commits the bump, and opens (or reuses) the dev -> main PR. If the build fails, the bump is reverted and nothing is pushed.
Merging the PR triggers the publish workflow on main, which verifies both images exist in the registry, publishes the npm package, creates the v{version} tag, and creates the GitHub Release with auto-generated notes — so npm can never ship pointing at an image that was never built, dev and main never drift on version, and every release is visible on GitHub. Merges to main whose version is already tagged are a no-op for the workflow.
One caveat: the images are built from dev before the PR merges — run ./release.sh as the last step before merging, and if more commits land on the PR afterwards, re-run it (bump again) so the images match the released code.
build-docker.sh is the lower-level build tool for local/dev iteration (single image, local rpdet checkout, per-GPU TRT pruning) — not the release path.
Documentation
Full documentation available in the docs/ directory.
License
Apache-2.0
Part of the Rosepetal development toolkit for Node-RED computer vision applications.