brainy/brainy-models-package
David Snelling f898f0ce7b feat\!: migrate from TensorFlow.js to Transformers.js with ONNX Runtime
BREAKING CHANGE: Complete migration from TensorFlow.js to Transformers.js for embedding generation

This is a major architectural change that replaces TensorFlow.js (USE model) with Transformers.js (all-MiniLM-L6-v2) for significantly improved performance and reduced complexity.

Key Changes:
- Replace TensorFlow.js Universal Sentence Encoder with Transformers.js all-MiniLM-L6-v2
- Reduce model size from 525MB to 87MB (83% reduction)
- Reduce embedding dimensions from 512 to 384 (faster distance calculations)
- Remove TensorFlow.js Float32Array patching (caused ONNX conflicts)
- Implement smart bundled model detection for offline operation
- Add explicit model download script for Docker deployments
- Remove complex environment variables in favor of simple configuration
- Update all distance functions to use optimized pure JavaScript
- Remove TensorFlow-specific utilities and type definitions

Performance Improvements:
- Model loading: 5x faster (87MB vs 525MB)
- Memory usage: 75% reduction (~200-400MB vs ~1.5GB)
- Distance calculations: Faster pure JS vs GPU overhead for small vectors
- Cold start performance: Significantly improved

Files Changed:
- Updated package.json: New dependencies, simplified scripts
- Rewrote src/utils/embedding.ts: Complete Transformers.js implementation
- Updated src/utils/distance.ts: Optimized JavaScript distance functions
- Simplified src/setup.ts: Removed TensorFlow-specific patching
- Simplified src/utils/textEncoding.ts: Only Node.js TextEncoder/Decoder patches
- Deleted src/utils/robustModelLoader.ts: TensorFlow-specific loader
- Deleted src/types/tensorflowTypes.ts: TensorFlow type definitions
- Added scripts/download-models.cjs: Docker-compatible model downloader
- Added comprehensive documentation: README.md, OFFLINE_MODELS.md, analysis docs

Testing:
- All 19 tests passing
- Removed test mocking in favor of real implementation testing
- Updated test environment for Transformers.js compatibility
- Performance tests validate improved efficiency

This migration resolves production issues with Docker egress limitations and provides a more robust, performant foundation for vector operations.
2025-08-05 19:29:59 -07:00
..
dist feat: add brainy-models-package v0.8.0 with USE-lite model 2025-08-05 18:09:12 -07:00
models feat\!: migrate from TensorFlow.js to Transformers.js with ONNX Runtime 2025-08-05 19:29:59 -07:00
LICENSE feat: add brainy-models-package v0.8.0 with USE-lite model 2025-08-05 18:09:12 -07:00
package.json feat: add brainy-models-package v0.8.0 with USE-lite model 2025-08-05 18:09:12 -07:00
README.md feat: add brainy-models-package v0.8.0 with USE-lite model 2025-08-05 18:09:12 -07:00

Brainy Logo

License Node.js TypeScript PRs Welcome

Pre-bundled TensorFlow models for maximum reliability with Brainy vector database

Overview

This package provides offline access to the Universal Sentence Encoder model, eliminating network dependencies and ensuring consistent performance. It's designed as an optional companion to the main @soulcraft/brainy package for applications requiring maximum reliability.

🚀 Key Features

  • 🔒 Maximum Reliability: Fully offline model loading with zero network dependencies
  • 📦 Pre-bundled Models: Complete Universal Sentence Encoder model (~25MB) included
  • 🗜️ Model Compression: Multiple optimized variants (float16, int8) for different use cases
  • Performance Optimized: Use case-specific optimizations for memory and speed
  • 🛠️ Easy Integration: Drop-in replacement for online model loading
  • 📊 Comprehensive Metrics: Detailed model information and performance statistics

🔧 Installation

npm install @soulcraft/brainy-models

Prerequisites

  • Node.js >= 18.0.0
  • @soulcraft/brainy >= 0.33.0

🏁 Quick Start

Basic Usage

import { BundledUniversalSentenceEncoder } from '@soulcraft/brainy-models'

// Create encoder instance
const encoder = new BundledUniversalSentenceEncoder({
  verbose: true,
  preferCompressed: false
})

// Load the bundled model
await encoder.load()

// Generate embeddings
const texts = ['Hello world', 'How are you?', 'Machine learning is amazing']
const embeddings = await encoder.embedToArrays(texts)

console.log(`Generated ${embeddings.length} embeddings of ${embeddings[0].length} dimensions`)

// Clean up
encoder.dispose()

Integration with Brainy

import Brainy from '@soulcraft/brainy'
import { BundledUniversalSentenceEncoder } from '@soulcraft/brainy-models'

// Create bundled encoder
const bundledEncoder = new BundledUniversalSentenceEncoder({ verbose: true })
await bundledEncoder.load()

// Use with Brainy (custom integration)
const brainy = new Brainy({
  // Configure Brainy to use the bundled encoder
  customEmbedding: async (texts) => {
    return await bundledEncoder.embedToArrays(texts)
  }
})

Using Compressed Models

import { BundledUniversalSentenceEncoder } from '@soulcraft/brainy-models'

// Use compressed model for memory-constrained environments
const encoder = new BundledUniversalSentenceEncoder({
  preferCompressed: true,
  verbose: true
})

await encoder.load()

// The encoder will automatically use the most appropriate compressed variant
const embeddings = await encoder.embedToArrays(['Sample text'])

📚 API Reference

BundledUniversalSentenceEncoder

Main class for loading and using bundled models.

Constructor

new BundledUniversalSentenceEncoder(options)

Options:

  • verbose?: boolean - Enable detailed logging (default: false)
  • preferCompressed?: boolean - Prefer compressed model variants (default: false)

Methods

load(): Promise<void>

Load the bundled model from local files.

await encoder.load()
embed(texts: string[]): Promise<tf.Tensor2D>

Generate embeddings as TensorFlow tensors.

const embeddings = await encoder.embed(['Hello world'])
// Remember to dispose of tensors when done
embeddings.dispose()
embedToArrays(texts: string[]): Promise<number[][]>

Generate embeddings as JavaScript arrays (automatically disposes tensors).

const embeddings = await encoder.embedToArrays(['Hello world'])
console.log(embeddings[0].length) // 512
getMetadata(): ModelMetadata | null

Get model metadata information.

const metadata = encoder.getMetadata()
console.log(metadata?.dimensions) // 512
isLoaded(): boolean

Check if the model is loaded.

if (encoder.isLoaded()) {
  // Model is ready to use
}
getModelInfo(): { inputShape: number[], outputShape: number[] } | null

Get model input/output shape information.

const info = encoder.getModelInfo()
console.log(info?.outputShape) // [-1, 512]
dispose(): void

Clean up model resources.

encoder.dispose()

ModelCompressor

Utility class for model compression and optimization.

Static Methods

quantizeModel(modelPath: string, outputPath: string, options?): Promise<void>

Compress a model using quantization.

import { ModelCompressor } from '@soulcraft/brainy-models'

await ModelCompressor.quantizeModel(
  '/path/to/model.json',
  '/path/to/compressed/model.json',
  { dtype: 'int8' }
)
getModelSize(modelPath: string): Promise<ModelSizeInfo>

Get detailed model size information.

const sizeInfo = await ModelCompressor.getModelSize('/path/to/model.json')
console.log(`Total size: ${sizeInfo.totalSize} bytes`)

Utility Functions

utils.checkModelsAvailable(): boolean

Check if bundled models are available.

import { utils } from '@soulcraft/brainy-models'

if (utils.checkModelsAvailable()) {
  console.log('Models are ready to use')
}

utils.listAvailableModels(): string[]

List available bundled models.

const models = utils.listAvailableModels()
console.log('Available models:', models)

🎯 Model Variants

The package includes multiple model variants optimized for different use cases:

Original (Float32)

  • Size: ~25MB
  • Use case: Maximum accuracy
  • Memory: High
  • Speed: Fast

Float16 Compressed

  • Size: ~12-15MB
  • Use case: Balanced performance
  • Memory: Medium
  • Speed: Fast

Int8 Quantized

  • Size: ~6-8MB
  • Use case: Memory-constrained environments
  • Memory: Low
  • Speed: Medium

⚙️ Scripts

The package includes several utility scripts:

Download Models

Download the complete Universal Sentence Encoder model:

npm run download-models

Compress Models

Create optimized model variants:

npm run compress-models

Test Models

Verify model functionality:

npm test

🔨 Development

Building the Package

npm run build

Running Tests

npm test

Creating a Release

npm run pack

⚖️ Comparison with Online Loading

Feature Online Loading Bundled Models
Reliability Network dependent 100% offline
First load time 30-60 seconds < 1 second
Subsequent loads Cached (~1 second) < 1 second
Package size ~3KB ~25MB
Network required Yes (first time) No
Offline support Limited Complete

💡 Use Cases

When to Use Bundled Models

  • Production applications requiring maximum reliability
  • Offline or air-gapped environments
  • Applications with strict SLA requirements
  • Edge computing and IoT devices
  • Development environments with unreliable internet

When to Use Online Loading

  • Development and prototyping
  • Applications where package size matters
  • Environments with reliable internet connectivity
  • Applications that rarely use embeddings

🔧 Troubleshooting

Model Not Found Error

Error: Bundled model not found. Please run "npm run download-models"

Solution: Run the download script to fetch the model files:

cd node_modules/@soulcraft/brainy-models
npm run download-models

Memory Issues

If you encounter memory issues, try using compressed models:

const encoder = new BundledUniversalSentenceEncoder({
  preferCompressed: true
})

Performance Optimization

For optimal performance:

  1. Memory-constrained: Use int8 quantized models
  2. Speed-critical: Use original float32 models
  3. Balanced: Use float16 compressed models

📄 License

MIT

🤝 Contributing

Contributions are welcome! Please see the main Brainy repository for contribution guidelines.

💬 Support

For issues and questions: