Skip to main content
net10.0

Local embedding generation using Microsoft.Extensions.AI and ONNX Runtime

Published
Feb 13, 2026
8mo ago
Total Downloads
21.0K
21,022

Install

dotnet add package ElBruno.LocalEmbeddings --version 1.0.2
ProductVersions
.NET
net10.0

README

LocalEmbeddings

NuGet License: MIT

A .NET library for generating text embeddings locally using ONNX Runtime and Microsoft.Extensions.AI abstractions—no external API calls required.

Features

  • Local Embedding Generation - Run inference entirely on your machine using ONNX Runtime
  • Microsoft.Extensions.AI Integration - Implements IEmbeddingGenerator<string, Embedding<float>> for seamless ecosystem compatibility
  • HuggingFace Model Support - Use popular sentence transformer models from HuggingFace Hub
  • Automatic Model Caching - Models are downloaded once and cached locally for fast subsequent loads
  • Dependency Injection Support - First-class integration with IServiceCollection and the Options pattern
  • Thread-Safe - Concurrent embedding generation from multiple threads
  • Batched Inference - Efficient processing of multiple texts in a single call

Installation

dotnet add package elbruno.LocalEmbeddings

Or via the NuGet Package Manager:

Install-Package elbruno.LocalEmbeddings

Quick Start

Direct Usage

using LocalEmbeddings;
using LocalEmbeddings.Options;

// Create the generator with default settings
var generator = new LocalEmbeddingGenerator(new LocalEmbeddingsOptions());

// Generate a single embedding
var result = await generator.GenerateAsync(["Hello, world!"]);
float[] embedding = result[0].Vector.ToArray();

// Generate multiple embeddings (batched)
var texts = new[] { "First document", "Second document", "Third document" };
var embeddings = await generator.GenerateAsync(texts);

// Don't forget to dispose when done
generator.Dispose();

With Custom Model

var options = new LocalEmbeddingsOptions
{
    ModelName = "sentence-transformers/all-MiniLM-L6-v2",
    MaxSequenceLength = 256
};

using var generator = new LocalEmbeddingGenerator(options);
var embeddings = await generator.GenerateAsync(["Your text here"]);

Configuration Options

The LocalEmbeddingsOptions class provides the following configuration:

Property Type Default Description
ModelName string "sentence-transformers/all-MiniLM-L6-v2" HuggingFace model identifier
ModelPath string? null Path to a local model directory (bypasses download)
CacheDirectory string? null Custom directory for model cache
MaxSequenceLength int 512 Maximum token sequence length
EnsureModelDownloaded bool true Download model on startup if not cached
var options = new LocalEmbeddingsOptions
{
    ModelName = "sentence-transformers/all-MiniLM-L6-v2",
    CacheDirectory = @"C:\models\cache",
    MaxSequenceLength = 256,
    EnsureModelDownloaded = true
};

Dependency Injection

LocalEmbeddings provides multiple overloads of AddLocalEmbeddings() for flexible DI registration:

Basic Registration

using LocalEmbeddings.Extensions;

services.AddLocalEmbeddings();

With Configuration Action

services.AddLocalEmbeddings(options =>
{
    options.ModelName = "sentence-transformers/all-MiniLM-L6-v2";
    options.MaxSequenceLength = 256;
});

With Model Name Only

services.AddLocalEmbeddings("sentence-transformers/all-MiniLM-L6-v2");

With Pre-configured Options

var options = new LocalEmbeddingsOptions
{
    ModelName = "sentence-transformers/all-MiniLM-L6-v2",
    MaxSequenceLength = 256
};
services.AddLocalEmbeddings(options);

From Configuration (appsettings.json)

{
  "LocalEmbeddings": {
    "ModelName": "sentence-transformers/all-MiniLM-L6-v2",
    "MaxSequenceLength": 256,
    "CacheDirectory": "/path/to/cache"
  }
}
services.AddLocalEmbeddings(configuration.GetSection("LocalEmbeddings"));

Injecting the Generator

public class MyService
{
    private readonly IEmbeddingGenerator<string, Embedding<float>> _embeddings;

    public MyService(IEmbeddingGenerator<string, Embedding<float>> embeddings)
    {
        _embeddings = embeddings;
    }

    public async Task<float[]> GetEmbeddingAsync(string text)
    {
        var result = await _embeddings.GenerateAsync([text]);
        return result[0].Vector.ToArray();
    }
}

Supported Models

Default Model

The default model is sentence-transformers/all-MiniLM-L6-v2, which produces 384-dimensional embeddings. It offers an excellent balance of quality and performance.

Custom ONNX Models

You can use any HuggingFace sentence transformer model that has ONNX exports:

// Use a different HuggingFace model
var options = new LocalEmbeddingsOptions
{
    ModelName = "sentence-transformers/paraphrase-MiniLM-L6-v2"
};

Local Model Path

For offline scenarios or custom models, specify a local directory:

var options = new LocalEmbeddingsOptions
{
    ModelPath = @"C:\models\my-custom-model",
    EnsureModelDownloaded = false
};

The model directory must contain:

  • model.onnx - The ONNX model file
  • tokenizer.json or vocab.txt - Tokenizer files

Cache Locations

Models are automatically cached in platform-specific locations:

Platform Cache Directory
Windows %LOCALAPPDATA%\LocalEmbeddings\models
Linux $XDG_DATA_HOME/LocalEmbeddings/models or ~/.local/share/LocalEmbeddings/models
macOS ~/.local/share/LocalEmbeddings/models

Override with the CacheDirectory option:

var options = new LocalEmbeddingsOptions
{
    CacheDirectory = "/custom/cache/path"
};

API Reference

LocalEmbeddingGenerator

The main class for generating embeddings. Implements IEmbeddingGenerator<string, Embedding<float>>.

public sealed class LocalEmbeddingGenerator : IEmbeddingGenerator<string, Embedding<float>>
{
    // Constructor
    public LocalEmbeddingGenerator(LocalEmbeddingsOptions options);
    
    // Properties
    public EmbeddingGeneratorMetadata Metadata { get; }
    
    // Methods
    public Task<GeneratedEmbeddings<Embedding<float>>> GenerateAsync(
        IEnumerable<string> values,
        EmbeddingGenerationOptions? options = null,
        CancellationToken cancellationToken = default);
    
    public TService? GetService<TService>(object? key = null) where TService : class;
    
    public void Dispose();
}

LocalEmbeddingsOptions

Configuration options for the embedding generator.

public sealed class LocalEmbeddingsOptions
{
    public string ModelName { get; set; }
    public string? ModelPath { get; set; }
    public string? CacheDirectory { get; set; }
    public int MaxSequenceLength { get; set; }
    public bool EnsureModelDownloaded { get; set; }
}

ServiceCollectionExtensions

Extension methods for DI registration in LocalEmbeddings.Extensions namespace.

public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddLocalEmbeddings(
        this IServiceCollection services,
        Action<LocalEmbeddingsOptions>? configure = null);
    
    public static IServiceCollection AddLocalEmbeddings(
        this IServiceCollection services,
        LocalEmbeddingsOptions options);
    
    public static IServiceCollection AddLocalEmbeddings(
        this IServiceCollection services,
        string modelName);
    
    public static IServiceCollection AddLocalEmbeddings(
        this IServiceCollection services,
        IConfiguration configuration);
}

Building from Source

Prerequisites

Build

git clone https://github.com/elbruno/elbruno.localembeddings.git
cd elbruno.localembeddings
dotnet build

Run Tests

dotnet test

Requirements

  • .NET 10.0 or later
  • ONNX Runtime compatible platform (Windows, Linux, macOS)

License

This project is licensed under the MIT License - see the LICENSE file for details.

Changes from Previous Version

No structural changes between v1.0.1 and v1.0.2.

Adoption Assessment

Assess this package against its supported frameworks, license, maintenance signals and dependency graph before making it a project standard.

Compatibility metadata lists 1 target framework; confirm the exact target used by your application.

Related Guides & Workflows

Learn how to evaluate, integrate, or audit this package in your .NET project.