edgeflowjs
v0.1.0
Published
Lightweight, high-performance browser ML inference framework with native concurrency support
Maintainers
Readme
edgeFlow.js
Lightweight, high-performance browser ML inference framework.
Documentation · Examples · API Reference · English | 中文
✨ Features
- 🚀 Native Concurrency - Run multiple models in parallel, no more serial execution bottleneck
- 📦 Lightweight - Core bundle < 500KB, zero runtime dependencies
- 🔄 Native Batch Processing - Efficient batch inference out of the box
- 💾 Smart Memory Management - Automatic memory tracking and cleanup
- 🎯 Developer Friendly - Full TypeScript support with intuitive APIs
- 🔌 Modular Architecture - Import only what you need
- 📥 Advanced Model Loading - Preloading, sharding, resume download support
- 💿 Intelligent Caching - IndexedDB-based model caching for offline use
- ⚡ High Performance - WebGPU-first with automatic fallback to WebNN/WASM
📦 Installation
npm install edgeflowyarn add edgeflowpnpm add edgeflow🚀 Quick Start
Try the Demo
Run the interactive demo locally to test all features:
# Clone and install
git clone https://github.com/user/edgeflow.js.git
cd edgeflow.js
npm install
# Build and start demo server
npm run demoOpen http://localhost:3000 in your browser:
Load Model - Enter a Hugging Face ONNX model URL and click "Load Model"
https://huggingface.co/Xenova/distilbert-base-uncased-finetuned-sst-2-english/resolve/main/onnx/model_quantized.onnxTest Features:
- 🧮 Tensor Operations - Test tensor creation, math ops, softmax, relu
- 📝 Text Classification - Run sentiment analysis on text
- 🔍 Feature Extraction - Extract embeddings from text
- ⚡ Concurrent Execution - Test parallel inference
- 📋 Task Scheduler - Test priority-based task scheduling
- 💾 Memory Management - Test allocation and cleanup
Basic Usage
import { pipeline } from 'edgeflow';
// Create a sentiment analysis pipeline
const sentiment = await pipeline('sentiment-analysis');
// Run inference
const result = await sentiment.run('I love this product!');
console.log(result);
// { label: 'positive', score: 0.98, processingTime: 12.5 }Batch Processing
// Native batch processing support
const results = await sentiment.run([
'This is amazing!',
'This is terrible.',
'It\'s okay I guess.'
]);
console.log(results);
// [
// { label: 'positive', score: 0.95 },
// { label: 'negative', score: 0.92 },
// { label: 'neutral', score: 0.68 }
// ]Concurrent Execution
import { pipeline } from 'edgeflow';
// Create multiple pipelines
const classifier = await pipeline('text-classification');
const extractor = await pipeline('feature-extraction');
// Run concurrently - no more serial bottleneck!
const [classification, features] = await Promise.all([
classifier.run('Sample text'),
extractor.run('Sample text')
]);Image Classification
import { pipeline } from 'edgeflow';
const classifier = await pipeline('image-classification');
// From URL
const result = await classifier.run('https://example.com/image.jpg');
// From HTMLImageElement
const img = document.getElementById('myImage');
const result = await classifier.run(img);
// Batch
const results = await classifier.run([img1, img2, img3]);🎯 Supported Tasks
| Task | Pipeline | Status |
|------|----------|--------|
| Text Classification | text-classification | ✅ |
| Sentiment Analysis | sentiment-analysis | ✅ |
| Feature Extraction | feature-extraction | ✅ |
| Image Classification | image-classification | ✅ |
| Object Detection | object-detection | 🔜 |
| Text Generation | text-generation | 🔜 |
| Speech Recognition | automatic-speech-recognition | 🔜 |
⚡ Performance
Comparison with transformers.js
| Feature | transformers.js | edgeFlow.js | |---------|-----------------|-------------| | Concurrent Execution | ❌ Serial | ✅ Parallel | | Batch Processing | ⚠️ Partial | ✅ Native | | Memory Management | ⚠️ Basic | ✅ Complete | | Bundle Size | ~2-5MB | <500KB | | Dependencies | ONNX Runtime | Optional |
Benchmarks
Text Classification (BERT-base):
- transformers.js: 45ms (serial)
- edgeFlow.js: 42ms (parallel capable)
Concurrent 4 models:
- transformers.js: 180ms (4 × 45ms serial)
- edgeFlow.js: 52ms (parallel execution)🔧 Configuration
Runtime Selection
import { pipeline } from 'edgeflow';
// Automatic (recommended)
const model = await pipeline('text-classification');
// Specify runtime
const model = await pipeline('text-classification', {
runtime: 'webgpu' // or 'webnn', 'wasm', 'auto'
});Memory Management
import { pipeline, getMemoryStats, gc } from 'edgeflow';
const model = await pipeline('text-classification');
// Use the model
await model.run('text');
// Check memory usage
console.log(getMemoryStats());
// { allocated: 50MB, used: 45MB, peak: 52MB, tensorCount: 12 }
// Explicit cleanup
model.dispose();
// Force garbage collection
gc();Scheduler Configuration
import { configureScheduler } from 'edgeflow';
configureScheduler({
maxConcurrentTasks: 4,
maxConcurrentPerModel: 1,
defaultTimeout: 30000,
enableBatching: true,
maxBatchSize: 32,
});Caching
import { pipeline, Cache } from 'edgeflow';
// Create a cache
const cache = new Cache({
strategy: 'lru',
maxSize: 100 * 1024 * 1024, // 100MB
persistent: true, // Use IndexedDB
});
const model = await pipeline('text-classification', {
cache: true
});🛠️ Advanced Usage
Custom Model Loading
import { loadModel, runInference } from 'edgeflow';
// Load from URL with caching, sharding, and resume support
const model = await loadModel('https://example.com/model.bin', {
runtime: 'webgpu',
quantization: 'int8',
cache: true, // Enable IndexedDB caching (default: true)
resumable: true, // Enable resume download (default: true)
chunkSize: 5 * 1024 * 1024, // 5MB chunks for large models
onProgress: (progress) => console.log(`Loading: ${progress * 100}%`)
});
// Run inference
const outputs = await runInference(model, inputs);
// Cleanup
model.dispose();Preloading Models
import { preloadModel, preloadModels, getPreloadStatus } from 'edgeflow';
// Preload a single model in background (with priority)
preloadModel('https://example.com/model1.onnx', { priority: 10 });
// Preload multiple models
preloadModels([
{ url: 'https://example.com/model1.onnx', priority: 10 },
{ url: 'https://example.com/model2.onnx', priority: 5 },
]);
// Check preload status
const status = getPreloadStatus('https://example.com/model1.onnx');
// 'pending' | 'loading' | 'complete' | 'error' | 'not_found'Model Caching
import {
isModelCached,
getCachedModel,
deleteCachedModel,
clearModelCache,
getModelCacheStats
} from 'edgeflow';
// Check if model is cached
if (await isModelCached('https://example.com/model.onnx')) {
console.log('Model is cached!');
}
// Get cached model data directly
const modelData = await getCachedModel('https://example.com/model.onnx');
// Delete a specific cached model
await deleteCachedModel('https://example.com/model.onnx');
// Clear all cached models
await clearModelCache();
// Get cache statistics
const stats = await getModelCacheStats();
console.log(`${stats.models} models cached, ${stats.totalSize} bytes total`);Resume Downloads
Large model downloads automatically support resuming from where they left off:
import { loadModelData } from 'edgeflow';
// Download with progress and resume support
const modelData = await loadModelData('https://example.com/large-model.onnx', {
resumable: true,
chunkSize: 10 * 1024 * 1024, // 10MB chunks
parallelConnections: 4, // Download 4 chunks in parallel
onProgress: (progress) => {
console.log(`${progress.percent.toFixed(1)}% downloaded`);
console.log(`Speed: ${(progress.speed / 1024 / 1024).toFixed(2)} MB/s`);
console.log(`ETA: ${(progress.eta / 1000).toFixed(0)}s`);
console.log(`Chunk ${progress.currentChunk}/${progress.totalChunks}`);
}
});Model Quantization
import { quantize } from 'edgeflow/tools';
const quantized = await quantize(model, {
method: 'int8',
calibrationData: samples,
});
console.log(`Compression: ${quantized.compressionRatio}x`);
// Compression: 3.8xBenchmarking
import { benchmark } from 'edgeflow/tools';
const result = await benchmark(
() => model.run('sample text'),
{ warmupRuns: 5, runs: 100 }
);
console.log(result);
// {
// avgTime: 12.5,
// minTime: 10.2,
// maxTime: 18.3,
// throughput: 80 // inferences/sec
// }Memory Scope
import { withMemoryScope, tensor } from 'edgeflow';
const result = await withMemoryScope(async (scope) => {
// Tensors tracked in scope
const a = scope.track(tensor([1, 2, 3]));
const b = scope.track(tensor([4, 5, 6]));
// Process...
const output = process(a, b);
// Keep result, dispose others
return scope.keep(output);
});
// a and b automatically disposed🔌 Tensor Operations
import { tensor, zeros, ones, matmul, softmax, relu } from 'edgeflow';
// Create tensors
const a = tensor([[1, 2], [3, 4]]);
const b = zeros([2, 2]);
const c = ones([2, 2]);
// Operations
const d = matmul(a, c);
const probs = softmax(d);
const activated = relu(d);
// Cleanup
a.dispose();
b.dispose();
c.dispose();🌐 Browser Support
| Browser | WebGPU | WebNN | WASM | |---------|--------|-------|------| | Chrome 113+ | ✅ | ✅ | ✅ | | Edge 113+ | ✅ | ✅ | ✅ | | Firefox 118+ | ⚠️ Flag | ❌ | ✅ | | Safari 17+ | ⚠️ Preview | ❌ | ✅ |
📖 API Reference
Core
pipeline(task, options?)- Create a pipeline for a taskloadModel(url, options?)- Load a model from URLrunInference(model, inputs)- Run model inferencegetScheduler()- Get the global schedulergetMemoryManager()- Get the memory manager
Pipelines
TextClassificationPipelineSentimentAnalysisPipelineFeatureExtractionPipelineImageClassificationPipeline
Utilities
Tokenizer- Text tokenizationImagePreprocessor- Image preprocessingAudioPreprocessor- Audio preprocessingCache- Caching utilities
Tools
quantize(model, options)- Quantize a modelprune(model, options)- Prune model weightsbenchmark(fn, options)- Benchmark inferenceanalyzeModel(model)- Analyze model structure
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
MIT © edgeFlow.js Contributors
Get Started · API Docs · Examples
Made with ❤️ for the edge AI community
