Welvet - LOOM Neural Network Framework for .NET. 12 layer types (Dense, LSTM, RNN, Conv2D, Conv1D, MHA, LayerNorm, RMSNorm, SwiGLU, Softmax, Embedding, Parallel), transformer/LLM inference with streaming, neural tweening, K-Means clustering, Pearson/Spearman correlation, network grafting, step-based forward pass, 7 LR schedulers, 3 optimizers (SGD/AdamW/RMSprop), ensemble features, and bit-for-bit model sharing with Python/TypeScript/Go. Multi-platform: Linux, Windows, macOS, Android, iOS.
$ dotnet add package WelvetWrapper for Embedding Loom Via External (C-ABI) Toolchain
High-performance neural network library with transformer inference for .NET via C-ABI bindings. Zero runtime dependencies—just add the NuGet package and go.
| Feature Category | Feature | Loom/Welvet | ML.NET | TensorFlow.NET | ONNX Runtime | Accord.NET |
|---|---|---|---|---|---|---|
| Core | Runtime Dependency | None (Native) | .NET Native | TF C++ | ONNX C++ | .NET Native |
| Auto-Differentiation | ⚠️ Hybrid/Manual | ⚠️ Limited | ✅ Full | ❌ | ❌ | |
| Loading | Safetensors | ✅ Native | ❌ | ❌ | ❌ | ❌ |
| Structure Inference | ✅ Auto-Detect | ❌ | ❌ | ❌ | ❌ | |
| Training | Full Training | ✅ Complete | ⚠️ Limited | ✅ | ❌ Inference Only | ✅ |
| Neural Tweening | ✅ Hybrid Engine | ❌ | ❌ | ❌ | ❌ | |
| LR Schedulers | ✅ 7 Types | ⚠️ | ✅ | ❌ | ⚠️ | |
| Layer Support | Dense (MLP) | ✅ | ✅ | ✅ | ✅ | ✅ |
| Conv1D/2D | ✅ Native | ✅ | ✅ | ✅ | ✅ | |
| RNN / LSTM | ✅ Full Gate | ⚠️ | ✅ | ✅ | ⚠️ | |
| Transformer (MHA) | ✅ (Explicit) | ❌ | ✅ | ✅ | ❌ | |
| Parallel / MoE | ✅ Structure | ❌ | ❌ (Manual) | ❌ | ❌ | |
| Stitch Layers | ✅ Native | ❌ | ❌ | ❌ | ❌ | |
| Advanced | Step-Based Forward | ✅ Unique | ❌ | ❌ | ❌ | ❌ |
| K-Means / Stats | ✅ Parallel | ✅ | ❌ | ❌ | ✅ | |
| Cross-Lang ABI | ✅ Universal | ❌ | ❌ | ⚠️ | ❌ | |
| Platform | Streaming LLM | ✅ | ❌ | ✅ | ✅ | ❌ |
For detailed analysis, see docs/loom_assessment_comparison.md.
Models trained in C# can be loaded instantly in Python, Go, or TypeScript. Bit-for-bit identical results across all platforms.
| Platform | Package | Install |
|---|---|---|
| C#/.NET | NuGet | dotnet add package Welvet |
| Python | PyPI | pip install welvet |
| TypeScript/Node | NPM | npm install @openfluke/welvet |
| Go | GitHub | go get github.com/openfluke/loom |
Welvet includes pre-compiled binaries for:
dotnet add package Welvet
Or via NuGet Package Manager:
Install-Package Welvet
The simple API provides cross-platform consistency with Python, TypeScript, and Go:
using System.Text.Json;
using Welvet;
// Create network from JSON configuration
var config = @"{
""batch_size"": 1,
""grid_rows"": 1,
""grid_cols"": 1,
""layers_per_cell"": 2,
""layers"": [
{""type"": ""dense"", ""input_height"": 4, ""output_height"": 8, ""activation"": ""relu""},
{""type"": ""dense"", ""input_height"": 8, ""output_height"": 2, ""activation"": ""sigmoid""}
]
}";
var result = Network.CreateFromJson(config);
Console.WriteLine("✅ Network created!");
// Training data
var batches = new[] {
new { Input = new[] { 0f, 0f, 1f, 1f }, Target = new[] { 1f, 0f } },
new { Input = new[] { 1f, 1f, 0f, 0f }, Target = new[] { 0f, 1f } }
};
var trainConfig = new { Epochs = 100, LearningRate = 0.1f, LossType = "mse" };
var trainResult = NativeMethods.LoomTrain(
JsonSerializer.Serialize(batches),
JsonSerializer.Serialize(trainConfig)
);
Console.WriteLine("✅ Training complete!");
// Forward pass
float[] input = { 0f, 0f, 1f, 1f };
var outputPtr = NativeMethods.LoomForward(input, input.Length);
var output = JsonSerializer.Deserialize<float[]>(NativeMethods.PtrToStringAndFree(outputPtr));
Console.WriteLine($"Output: [{output[0]:F3}, {output[1]:F3}]"); // [0.95, 0.05]
// Save/Load - works across ALL platforms!
var modelPtr = NativeMethods.LoomSaveModel("my_model");
var modelJson = NativeMethods.PtrToStringAndFree(modelPtr);
Console.WriteLine($"✓ Model saved ({modelJson.Length} bytes)");
// Load in Python, TypeScript, or Go with identical results
NativeMethods.LoomLoadModel(modelJson, "my_model");
Simple API Functions:
| Function | Description |
|---|---|
CreateLoomNetwork(config) | Create network from JSON |
LoomForward(inputs, length) | Forward pass |
LoomBackward(gradients, length) | Backward pass |
LoomUpdateWeights(learningRate) | Update weights |
LoomTrain(batchesJSON, configJSON) | Train network |
LoomSaveModel(modelID) | Save to JSON string |
LoomLoadModel(jsonString, modelID) | Load from JSON |
LoomGetNetworkInfo() | Get network info |
LoomEvaluateNetwork(inputsJSON, expectedJSON) | Evaluate with metrics |
Execute networks one step at a time for online learning and stateful processing:
using Welvet;
// Create network
Network.CreateFromJson(config);
// Initialize stepping state
using var stepState = new StepState(inputSize: 4);
// Training loop - update weights after EACH step
for (int step = 0; step < 100000; step++)
{
stepState.SetInput(new float[] { 0.1f, 0.2f, 0.1f, 0.3f });
stepState.StepForward();
var output = stepState.GetOutput();
// Calculate gradients
var gradients = output.Select((o, i) => o - target[i]).ToArray();
// Backward pass and update
stepState.StepBackward(gradients);
NativeMethods.LoomApplyGradients(0.01f);
}
Neural tweening enables networks to adapt to changing goals in real-time without full backpropagation:
using Welvet;
Network.CreateFromJson(config);
// Create TweenState with chain rule (StepTweenChain mode)
using var tween = new TweenState(useChainRule: true);
// Continuously adapt to targets
foreach (var (observation, targetClass) in trainingStream)
{
float gap = tween.Step(observation, targetClass, outputSize: 4, learningRate: 0.02f);
Console.WriteLine($"Adaptation gap: {gap:F4}");
}
Track accuracy across task changes for benchmarking real-time adaptation:
using Welvet;
using var tracker = new AdaptationTracker(windowDurationMs: 1000, totalDurationMs: 10000);
tracker.SetModelInfo("Dense-5L", "StepTweenChain");
// Schedule task changes
tracker.ScheduleTaskChange(3333, taskId: 1, taskName: "AVOID");
tracker.ScheduleTaskChange(6666, taskId: 0, taskName: "CHASE");
tracker.Start("CHASE", taskId: 0);
// Run test loop
while (timeElapsed < 10000)
{
int currentTask = tracker.GetCurrentTask();
// ... run network ...
tracker.RecordOutput(isCorrect: correct);
}
var results = tracker.GetResults();
Console.WriteLine($"Avg accuracy: {results.RootElement.GetProperty("avg_accuracy").GetDouble():F1}%");
Combine multiple trained networks into a single parallel super-network:
using Welvet;
long h1 = NativeMethods.LoomCreateNetworkHandle(config);
long h2 = NativeMethods.LoomCreateNetworkHandle(config);
var handlesJson = JsonSerializer.Serialize(new[] { h1, h2 });
var resultPtr = NativeMethods.LoomGraftNetworks(handlesJson, "concat");
var result = NativeMethods.PtrToStringAndFree(resultPtr);
// Result: {"success": true, "num_branches": 2, "combine_mode": "concat"}
Built-in K-Means clustering and correlation analysis:
using Welvet;
// K-Means Clustering
var data = new[] { new[] { 1f, 1f }, new[] { 1.1f, 1.1f }, new[] { 5f, 5f }, new[] { 5.1f, 5.1f } };
var kmeansPtr = NativeMethods.LoomKMeansCluster(JsonSerializer.Serialize(data), k: 2, maxIter: 100);
var kmeans = JsonSerializer.Deserialize<JsonElement>(NativeMethods.PtrToStringAndFree(kmeansPtr));
Console.WriteLine($"Centroids: {kmeans.GetProperty("centroids")}");
// Correlation Matrix
var matrix = new[] { new[] { 1f, 2f, 3f }, new[] { 4f, 5f, 6f } };
var corrPtr = NativeMethods.LoomComputeCorrelation(JsonSerializer.Serialize(matrix));
Run LLaMA, SmolLM, GPT-2, and other transformers with streaming support:
using Welvet;
// Load model
Transformer.LoadTokenizer("models/SmolLM2-135M-Instruct/tokenizer.json");
Transformer.LoadModelFromDirectory("models/SmolLM2-135M-Instruct");
// Stream generation - tokens appear in real-time!
foreach (var token in Transformer.GenerateStream("The capital of France is", maxTokens: 50))
{
Console.Write(token);
}
// Or generate all at once
var text = Transformer.Generate("Once upon a time", maxTokens: 50, temperature: 0.7f);
The UniversalTest.cs example demonstrates all framework capabilities:
cd examples
dotnet run --project UniversalTest.csproj
Test Coverage (80/80 tests passing):
| Layer | Type String | Description |
|---|---|---|
| Dense | dense | Fully connected layer |
| LSTM | lstm | Long Short-Term Memory |
| RNN | rnn | Recurrent Neural Network |
| Conv2D | conv2d | 2D Convolution |
| Conv1D | conv1d | 1D Convolution |
| Multi-Head Attention | multi_head_attention | Transformer attention |
| LayerNorm | layer_norm | Layer normalization |
| RMSNorm | rms_norm | RMS normalization |
| SwiGLU | swiglu | SwiGLU activation layer |
| Softmax | softmax | Softmax classification |
| Embedding | embedding | Token embedding |
| Parallel | parallel | Branching with combine modes |
| Sequential | sequential | Grouped sub-layers |
Parallel Combine Modes: add, concat, multiply, average, grid_scatter, filter
Activation Functions: relu, sigmoid, tanh, softmax, gelu, swish, mish, leaky_relu, elu, selu, linear
The same JSON model works across all platforms - train once, deploy anywhere:
// C# - Save model
var modelJson = NativeMethods.PtrToStringAndFree(NativeMethods.LoomSaveModel("model"));
File.WriteAllText("model.json", modelJson);
# Python - Load same model
import welvet
with open("model.json") as f:
modelJson = f.read()
welvet.load_model_simple(modelJson, "model")
output = welvet.forward_simple([0.1, 0.2, 0.3, 0.4]) # Identical results!
// TypeScript - Load same model
import { loadLoomNetwork } from "@openfluke/welvet";
const modelJson = fs.readFileSync("model.json", "utf-8");
const network = loadLoomNetwork(modelJson, "model");
const output = network.ForwardCPU(JSON.stringify([[0.1, 0.2, 0.3, 0.4]]));
// Bit-for-bit identical!
// Go - Load same model
import "github.com/openfluke/loom/nn"
modelJson, _ := os.ReadFile("model.json")
network, _ := nn.LoadModelFromString(string(modelJson), "model")
output, _ := network.ForwardCPU([]float32{0.1, 0.2, 0.3, 0.4})
git clone https://github.com/openfluke/loom.git
cd loom/csharp
# Build
dotnet build -c Release
# Run examples
cd examples
dotnet run --project UniversalTest.csproj
Apache License 2.0 - see LICENSE for details.