Squashed 'vendor/ruvector/' content from commit b64c2172
git-subtree-dir: vendor/ruvector git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
This commit is contained in:
160
examples/ruvLLM/benches/attention.rs
Normal file
160
examples/ruvLLM/benches/attention.rs
Normal file
@@ -0,0 +1,160 @@
|
||||
//! Attention engine benchmarks for RuvLLM
|
||||
//!
|
||||
//! Benchmarks multi-head graph attention.
|
||||
|
||||
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||
use rand::{Rng, SeedableRng};
|
||||
use ruvllm::attention::GraphAttentionEngine;
|
||||
use ruvllm::config::EmbeddingConfig;
|
||||
use ruvllm::memory::SubGraph;
|
||||
use ruvllm::types::{EdgeType, MemoryEdge, MemoryNode, NodeType};
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn create_random_node(id: &str, dim: usize, seed: u64) -> MemoryNode {
|
||||
let mut rng = rand::rngs::StdRng::seed_from_u64(seed);
|
||||
let mut vec: Vec<f32> = (0..dim).map(|_| rng.gen::<f32>() - 0.5).collect();
|
||||
let norm: f32 = vec.iter().map(|x| x * x).sum::<f32>().sqrt();
|
||||
vec.iter_mut().for_each(|x| *x /= norm);
|
||||
|
||||
MemoryNode {
|
||||
id: id.into(),
|
||||
vector: vec,
|
||||
text: format!("Node {}", id),
|
||||
node_type: NodeType::Document,
|
||||
source: "bench".into(),
|
||||
metadata: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_subgraph(num_nodes: usize, num_edges: usize, dim: usize) -> SubGraph {
|
||||
let nodes: Vec<MemoryNode> = (0..num_nodes)
|
||||
.map(|i| create_random_node(&format!("n-{}", i), dim, i as u64))
|
||||
.collect();
|
||||
|
||||
let edges: Vec<MemoryEdge> = (0..num_edges.min(num_nodes.saturating_sub(1)))
|
||||
.map(|i| MemoryEdge {
|
||||
id: format!("e-{}", i),
|
||||
src: format!("n-{}", i),
|
||||
dst: format!("n-{}", (i + 1) % num_nodes),
|
||||
edge_type: EdgeType::Follows,
|
||||
weight: 0.8,
|
||||
metadata: HashMap::new(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
SubGraph {
|
||||
nodes,
|
||||
edges,
|
||||
center_ids: vec!["n-0".into()],
|
||||
}
|
||||
}
|
||||
|
||||
fn benchmark_attention_forward(c: &mut Criterion) {
|
||||
let config = EmbeddingConfig::default();
|
||||
let engine = GraphAttentionEngine::new(&config).unwrap();
|
||||
|
||||
let query = vec![0.1f32; config.dimension];
|
||||
let subgraph = create_subgraph(10, 9, config.dimension);
|
||||
|
||||
c.bench_function("attention_forward_10_nodes", |b| {
|
||||
b.iter(|| black_box(engine.attend(&query, &subgraph).unwrap()))
|
||||
});
|
||||
}
|
||||
|
||||
fn benchmark_attention_varying_nodes(c: &mut Criterion) {
|
||||
let config = EmbeddingConfig::default();
|
||||
let engine = GraphAttentionEngine::new(&config).unwrap();
|
||||
|
||||
let query = vec![0.1f32; config.dimension];
|
||||
|
||||
let mut group = c.benchmark_group("attention_nodes");
|
||||
for num_nodes in [5, 10, 20, 50, 100] {
|
||||
let subgraph = create_subgraph(num_nodes, num_nodes - 1, config.dimension);
|
||||
|
||||
group.bench_with_input(
|
||||
BenchmarkId::from_parameter(num_nodes),
|
||||
&subgraph,
|
||||
|b, subgraph| b.iter(|| black_box(engine.attend(&query, subgraph).unwrap())),
|
||||
);
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn benchmark_attention_varying_edges(c: &mut Criterion) {
|
||||
let config = EmbeddingConfig::default();
|
||||
let engine = GraphAttentionEngine::new(&config).unwrap();
|
||||
|
||||
let query = vec![0.1f32; config.dimension];
|
||||
|
||||
let mut group = c.benchmark_group("attention_edges");
|
||||
for num_edges in [0, 10, 25, 50, 100] {
|
||||
let subgraph = create_subgraph(50, num_edges, config.dimension);
|
||||
|
||||
group.bench_with_input(
|
||||
BenchmarkId::from_parameter(num_edges),
|
||||
&subgraph,
|
||||
|b, subgraph| b.iter(|| black_box(engine.attend(&query, subgraph).unwrap())),
|
||||
);
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn benchmark_attention_varying_dims(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("attention_dimension");
|
||||
for dim in [128, 256, 512, 768, 1024] {
|
||||
let config = EmbeddingConfig {
|
||||
dimension: dim,
|
||||
..EmbeddingConfig::default()
|
||||
};
|
||||
let engine = GraphAttentionEngine::new(&config).unwrap();
|
||||
|
||||
let query = vec![0.1f32; dim];
|
||||
let subgraph = create_subgraph(20, 19, dim);
|
||||
|
||||
group.bench_with_input(
|
||||
BenchmarkId::from_parameter(dim),
|
||||
&subgraph,
|
||||
|b, subgraph| b.iter(|| black_box(engine.attend(&query, subgraph).unwrap())),
|
||||
);
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn benchmark_cross_attention(c: &mut Criterion) {
|
||||
let config = EmbeddingConfig::default();
|
||||
let engine = GraphAttentionEngine::new(&config).unwrap();
|
||||
|
||||
let query = vec![0.1f32; config.dimension];
|
||||
let subgraph = create_subgraph(20, 19, config.dimension);
|
||||
|
||||
c.bench_function("cross_attention_20_nodes", |b| {
|
||||
b.iter(|| black_box(engine.cross_attend(&query, &subgraph).unwrap()))
|
||||
});
|
||||
}
|
||||
|
||||
fn benchmark_attention_empty_graph(c: &mut Criterion) {
|
||||
let config = EmbeddingConfig::default();
|
||||
let engine = GraphAttentionEngine::new(&config).unwrap();
|
||||
|
||||
let query = vec![0.1f32; config.dimension];
|
||||
let subgraph = SubGraph {
|
||||
nodes: vec![],
|
||||
edges: vec![],
|
||||
center_ids: vec![],
|
||||
};
|
||||
|
||||
c.bench_function("attention_empty_graph", |b| {
|
||||
b.iter(|| black_box(engine.attend(&query, &subgraph).unwrap()))
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
benchmark_attention_forward,
|
||||
benchmark_attention_varying_nodes,
|
||||
benchmark_attention_varying_edges,
|
||||
benchmark_attention_varying_dims,
|
||||
benchmark_cross_attention,
|
||||
benchmark_attention_empty_graph,
|
||||
);
|
||||
criterion_main!(benches);
|
||||
222
examples/ruvLLM/benches/memory.rs
Normal file
222
examples/ruvLLM/benches/memory.rs
Normal file
@@ -0,0 +1,222 @@
|
||||
//! Memory service benchmarks for RuvLLM
|
||||
//!
|
||||
//! Benchmarks HNSW insertion, search, and graph operations.
|
||||
|
||||
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
|
||||
use rand::{Rng, SeedableRng};
|
||||
use ruvllm::config::MemoryConfig;
|
||||
use ruvllm::memory::MemoryService;
|
||||
use ruvllm::types::{EdgeType, MemoryEdge, MemoryNode, NodeType};
|
||||
use std::collections::HashMap;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
fn create_random_node(id: &str, dim: usize, seed: u64) -> MemoryNode {
|
||||
let mut rng = rand::rngs::StdRng::seed_from_u64(seed);
|
||||
let mut vec: Vec<f32> = (0..dim).map(|_| rng.gen::<f32>() - 0.5).collect();
|
||||
let norm: f32 = vec.iter().map(|x| x * x).sum::<f32>().sqrt();
|
||||
vec.iter_mut().for_each(|x| *x /= norm);
|
||||
|
||||
MemoryNode {
|
||||
id: id.into(),
|
||||
vector: vec,
|
||||
text: format!("Node {}", id),
|
||||
node_type: NodeType::Document,
|
||||
source: "bench".into(),
|
||||
metadata: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn benchmark_memory_insert(c: &mut Criterion) {
|
||||
let rt = Runtime::new().unwrap();
|
||||
let config = MemoryConfig::default();
|
||||
let memory = rt.block_on(MemoryService::new(&config)).unwrap();
|
||||
|
||||
let mut counter = 0u64;
|
||||
|
||||
c.bench_function("memory_insert_single", |b| {
|
||||
b.iter(|| {
|
||||
counter += 1;
|
||||
let node = create_random_node(&format!("bench-{}", counter), 768, counter);
|
||||
black_box(memory.insert_node(node).unwrap())
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn benchmark_memory_insert_batch(c: &mut Criterion) {
|
||||
let rt = Runtime::new().unwrap();
|
||||
|
||||
let mut group = c.benchmark_group("memory_insert_batch");
|
||||
for batch_size in [10, 50, 100, 500] {
|
||||
group.throughput(Throughput::Elements(batch_size as u64));
|
||||
|
||||
let config = MemoryConfig::default();
|
||||
let memory = rt.block_on(MemoryService::new(&config)).unwrap();
|
||||
|
||||
let nodes: Vec<MemoryNode> = (0..batch_size)
|
||||
.map(|i| create_random_node(&format!("batch-{}", i), 768, i as u64))
|
||||
.collect();
|
||||
|
||||
group.bench_with_input(
|
||||
BenchmarkId::from_parameter(batch_size),
|
||||
&nodes,
|
||||
|b, nodes| {
|
||||
b.iter(|| {
|
||||
for node in nodes.clone() {
|
||||
black_box(memory.insert_node(node).unwrap());
|
||||
}
|
||||
})
|
||||
},
|
||||
);
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn benchmark_memory_search(c: &mut Criterion) {
|
||||
let rt = Runtime::new().unwrap();
|
||||
let config = MemoryConfig::default();
|
||||
let memory = rt.block_on(MemoryService::new(&config)).unwrap();
|
||||
|
||||
// Pre-populate with nodes
|
||||
for i in 0..1000 {
|
||||
let node = create_random_node(&format!("search-{}", i), 768, i as u64);
|
||||
memory.insert_node(node).unwrap();
|
||||
}
|
||||
|
||||
let query = vec![0.1f32; 768];
|
||||
|
||||
c.bench_function("memory_search_k10_1000", |b| {
|
||||
b.to_async(&rt).iter(|| async {
|
||||
black_box(memory.search_with_graph(&query, 10, 64, 0).await.unwrap())
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn benchmark_memory_search_varying_k(c: &mut Criterion) {
|
||||
let rt = Runtime::new().unwrap();
|
||||
let config = MemoryConfig::default();
|
||||
let memory = rt.block_on(MemoryService::new(&config)).unwrap();
|
||||
|
||||
// Pre-populate
|
||||
for i in 0..1000 {
|
||||
let node = create_random_node(&format!("k-{}", i), 768, i as u64);
|
||||
memory.insert_node(node).unwrap();
|
||||
}
|
||||
|
||||
let query = vec![0.1f32; 768];
|
||||
|
||||
let mut group = c.benchmark_group("memory_search_k");
|
||||
for k in [1, 5, 10, 20, 50, 100] {
|
||||
group.bench_with_input(BenchmarkId::from_parameter(k), &k, |b, &k| {
|
||||
b.to_async(&rt).iter(|| async {
|
||||
black_box(memory.search_with_graph(&query, k, 64, 0).await.unwrap())
|
||||
})
|
||||
});
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn benchmark_memory_search_varying_ef(c: &mut Criterion) {
|
||||
let rt = Runtime::new().unwrap();
|
||||
let config = MemoryConfig::default();
|
||||
let memory = rt.block_on(MemoryService::new(&config)).unwrap();
|
||||
|
||||
// Pre-populate
|
||||
for i in 0..1000 {
|
||||
let node = create_random_node(&format!("ef-{}", i), 768, i as u64);
|
||||
memory.insert_node(node).unwrap();
|
||||
}
|
||||
|
||||
let query = vec![0.1f32; 768];
|
||||
|
||||
let mut group = c.benchmark_group("memory_search_ef");
|
||||
for ef in [16, 32, 64, 128, 256] {
|
||||
group.bench_with_input(BenchmarkId::from_parameter(ef), &ef, |b, &ef| {
|
||||
b.to_async(&rt).iter(|| async {
|
||||
black_box(memory.search_with_graph(&query, 10, ef, 0).await.unwrap())
|
||||
})
|
||||
});
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn benchmark_memory_search_with_graph(c: &mut Criterion) {
|
||||
let rt = Runtime::new().unwrap();
|
||||
let config = MemoryConfig::default();
|
||||
let memory = rt.block_on(MemoryService::new(&config)).unwrap();
|
||||
|
||||
// Pre-populate with nodes and edges
|
||||
for i in 0..500 {
|
||||
let node = create_random_node(&format!("graph-{}", i), 768, i as u64);
|
||||
memory.insert_node(node).unwrap();
|
||||
}
|
||||
|
||||
for i in 0..499 {
|
||||
let edge = MemoryEdge {
|
||||
id: format!("edge-{}", i),
|
||||
src: format!("graph-{}", i),
|
||||
dst: format!("graph-{}", i + 1),
|
||||
edge_type: EdgeType::Follows,
|
||||
weight: 0.8,
|
||||
metadata: HashMap::new(),
|
||||
};
|
||||
memory.insert_edge(edge).unwrap();
|
||||
}
|
||||
|
||||
let query = vec![0.1f32; 768];
|
||||
|
||||
let mut group = c.benchmark_group("memory_search_hops");
|
||||
for hops in [0, 1, 2, 3] {
|
||||
group.bench_with_input(BenchmarkId::from_parameter(hops), &hops, |b, &hops| {
|
||||
b.to_async(&rt).iter(|| async {
|
||||
black_box(
|
||||
memory
|
||||
.search_with_graph(&query, 10, 64, hops)
|
||||
.await
|
||||
.unwrap(),
|
||||
)
|
||||
})
|
||||
});
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn benchmark_memory_scaling(c: &mut Criterion) {
|
||||
let rt = Runtime::new().unwrap();
|
||||
|
||||
let mut group = c.benchmark_group("memory_scaling");
|
||||
for num_nodes in [100, 500, 1000, 5000] {
|
||||
let config = MemoryConfig::default();
|
||||
let memory = rt.block_on(MemoryService::new(&config)).unwrap();
|
||||
|
||||
// Pre-populate
|
||||
for i in 0..num_nodes {
|
||||
let node = create_random_node(&format!("scale-{}", i), 768, i as u64);
|
||||
memory.insert_node(node).unwrap();
|
||||
}
|
||||
|
||||
let query = vec![0.1f32; 768];
|
||||
|
||||
group.bench_with_input(
|
||||
BenchmarkId::from_parameter(num_nodes),
|
||||
&num_nodes,
|
||||
|b, _| {
|
||||
b.to_async(&rt).iter(|| async {
|
||||
black_box(memory.search_with_graph(&query, 10, 64, 0).await.unwrap())
|
||||
})
|
||||
},
|
||||
);
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
benchmark_memory_insert,
|
||||
benchmark_memory_insert_batch,
|
||||
benchmark_memory_search,
|
||||
benchmark_memory_search_varying_k,
|
||||
benchmark_memory_search_varying_ef,
|
||||
benchmark_memory_search_with_graph,
|
||||
benchmark_memory_scaling,
|
||||
);
|
||||
criterion_main!(benches);
|
||||
124
examples/ruvLLM/benches/pipeline.rs
Normal file
124
examples/ruvLLM/benches/pipeline.rs
Normal file
@@ -0,0 +1,124 @@
|
||||
//! Pipeline benchmarks for RuvLLM
|
||||
//!
|
||||
//! Benchmarks the complete request-to-response pipeline.
|
||||
|
||||
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||
use ruvllm::{Config, Request, RuvLLM};
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
fn benchmark_query(c: &mut Criterion) {
|
||||
let rt = Runtime::new().unwrap();
|
||||
|
||||
let config = Config::builder()
|
||||
.embedding_dim(128)
|
||||
.router_hidden_dim(32)
|
||||
.learning_enabled(false)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let llm = rt.block_on(RuvLLM::new(config)).unwrap();
|
||||
|
||||
c.bench_function("query_simple", |b| {
|
||||
b.to_async(&rt)
|
||||
.iter(|| async { black_box(llm.query("What is Rust?").await.unwrap()) })
|
||||
});
|
||||
}
|
||||
|
||||
fn benchmark_query_lengths(c: &mut Criterion) {
|
||||
let rt = Runtime::new().unwrap();
|
||||
|
||||
let config = Config::builder()
|
||||
.embedding_dim(128)
|
||||
.router_hidden_dim(32)
|
||||
.learning_enabled(false)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let llm = rt.block_on(RuvLLM::new(config)).unwrap();
|
||||
|
||||
let queries = vec![
|
||||
("short", "Hi"),
|
||||
("medium", "What is machine learning and how does it work?"),
|
||||
("long", "Please explain in detail how neural networks process information, including concepts like forward propagation, backpropagation, gradient descent, and the role of activation functions in learning complex patterns from data."),
|
||||
];
|
||||
|
||||
let mut group = c.benchmark_group("query_by_length");
|
||||
for (name, query) in queries {
|
||||
group.bench_with_input(BenchmarkId::from_parameter(name), &query, |b, query| {
|
||||
b.to_async(&rt)
|
||||
.iter(|| async { black_box(llm.query(*query).await.unwrap()) })
|
||||
});
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn benchmark_concurrent_queries(c: &mut Criterion) {
|
||||
let rt = Runtime::new().unwrap();
|
||||
|
||||
let config = Config::builder()
|
||||
.embedding_dim(128)
|
||||
.router_hidden_dim(32)
|
||||
.learning_enabled(false)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let llm = std::sync::Arc::new(rt.block_on(RuvLLM::new(config)).unwrap());
|
||||
|
||||
let mut group = c.benchmark_group("concurrent_queries");
|
||||
for concurrency in [1, 2, 4, 8] {
|
||||
group.bench_with_input(
|
||||
BenchmarkId::from_parameter(concurrency),
|
||||
&concurrency,
|
||||
|b, &concurrency| {
|
||||
b.to_async(&rt).iter(|| async {
|
||||
let mut handles = Vec::new();
|
||||
for _ in 0..concurrency {
|
||||
let llm_clone = llm.clone();
|
||||
handles.push(tokio::spawn(async move {
|
||||
llm_clone.query("Test query").await.unwrap()
|
||||
}));
|
||||
}
|
||||
for handle in handles {
|
||||
black_box(handle.await.unwrap());
|
||||
}
|
||||
})
|
||||
},
|
||||
);
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn benchmark_session(c: &mut Criterion) {
|
||||
let rt = Runtime::new().unwrap();
|
||||
|
||||
let config = Config::builder()
|
||||
.embedding_dim(128)
|
||||
.router_hidden_dim(32)
|
||||
.learning_enabled(false)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let llm = rt.block_on(RuvLLM::new(config)).unwrap();
|
||||
|
||||
c.bench_function("session_multi_turn", |b| {
|
||||
b.to_async(&rt).iter(|| async {
|
||||
let session = llm.new_session();
|
||||
black_box(llm.query_session(&session, "First question").await.unwrap());
|
||||
black_box(llm.query_session(&session, "Follow up").await.unwrap());
|
||||
black_box(
|
||||
llm.query_session(&session, "Another follow up")
|
||||
.await
|
||||
.unwrap(),
|
||||
);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
benchmark_query,
|
||||
benchmark_query_lengths,
|
||||
benchmark_concurrent_queries,
|
||||
benchmark_session,
|
||||
);
|
||||
criterion_main!(benches);
|
||||
150
examples/ruvLLM/benches/router.rs
Normal file
150
examples/ruvLLM/benches/router.rs
Normal file
@@ -0,0 +1,150 @@
|
||||
//! Router benchmarks for RuvLLM
|
||||
//!
|
||||
//! Benchmarks FastGRNN router forward pass and training.
|
||||
|
||||
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||
use ruvllm::config::RouterConfig;
|
||||
use ruvllm::router::FastGRNNRouter;
|
||||
use ruvllm::types::RouterSample;
|
||||
|
||||
fn benchmark_router_forward(c: &mut Criterion) {
|
||||
let config = RouterConfig::default();
|
||||
let router = FastGRNNRouter::new(&config).unwrap();
|
||||
|
||||
let features = vec![0.1f32; config.input_dim];
|
||||
let hidden = vec![0.0f32; config.hidden_dim];
|
||||
|
||||
c.bench_function("router_forward", |b| {
|
||||
b.iter(|| black_box(router.forward(&features, &hidden).unwrap()))
|
||||
});
|
||||
}
|
||||
|
||||
fn benchmark_router_forward_batch_sizes(c: &mut Criterion) {
|
||||
let config = RouterConfig::default();
|
||||
let router = FastGRNNRouter::new(&config).unwrap();
|
||||
let hidden = vec![0.0f32; config.hidden_dim];
|
||||
|
||||
let mut group = c.benchmark_group("router_forward_features");
|
||||
for feature_dim in [64, 128, 256, 512] {
|
||||
let config = RouterConfig {
|
||||
input_dim: feature_dim,
|
||||
..RouterConfig::default()
|
||||
};
|
||||
let router = FastGRNNRouter::new(&config).unwrap();
|
||||
let features = vec![0.1f32; feature_dim];
|
||||
|
||||
group.bench_with_input(
|
||||
BenchmarkId::from_parameter(feature_dim),
|
||||
&features,
|
||||
|b, features| b.iter(|| black_box(router.forward(features, &hidden).unwrap())),
|
||||
);
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn benchmark_router_training(c: &mut Criterion) {
|
||||
let config = RouterConfig::default();
|
||||
let mut router = FastGRNNRouter::new(&config).unwrap();
|
||||
|
||||
let samples: Vec<RouterSample> = (0..32)
|
||||
.map(|i| RouterSample {
|
||||
features: vec![0.1; config.input_dim],
|
||||
label_model: i % 4,
|
||||
label_context: i % 5,
|
||||
label_temperature: 0.7,
|
||||
label_top_p: 0.9,
|
||||
quality: 0.8,
|
||||
latency_ms: 100.0,
|
||||
})
|
||||
.collect();
|
||||
|
||||
c.bench_function("router_train_batch_32", |b| {
|
||||
b.iter(|| black_box(router.train_batch(&samples, 0.001, 0.0, None, None)))
|
||||
});
|
||||
}
|
||||
|
||||
fn benchmark_router_training_batch_sizes(c: &mut Criterion) {
|
||||
let config = RouterConfig::default();
|
||||
|
||||
let mut group = c.benchmark_group("router_train_batch");
|
||||
for batch_size in [8, 16, 32, 64, 128] {
|
||||
let mut router = FastGRNNRouter::new(&config).unwrap();
|
||||
let samples: Vec<RouterSample> = (0..batch_size)
|
||||
.map(|i| RouterSample {
|
||||
features: vec![0.1; config.input_dim],
|
||||
label_model: i % 4,
|
||||
label_context: i % 5,
|
||||
label_temperature: 0.7,
|
||||
label_top_p: 0.9,
|
||||
quality: 0.8,
|
||||
latency_ms: 100.0,
|
||||
})
|
||||
.collect();
|
||||
|
||||
group.bench_with_input(
|
||||
BenchmarkId::from_parameter(batch_size),
|
||||
&samples,
|
||||
|b, samples| b.iter(|| black_box(router.train_batch(samples, 0.001, 0.0, None, None))),
|
||||
);
|
||||
}
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn benchmark_router_ewc(c: &mut Criterion) {
|
||||
let config = RouterConfig::default();
|
||||
let mut router = FastGRNNRouter::new(&config).unwrap();
|
||||
|
||||
let samples: Vec<RouterSample> = (0..32)
|
||||
.map(|i| RouterSample {
|
||||
features: vec![0.1; config.input_dim],
|
||||
label_model: i % 4,
|
||||
label_context: i % 5,
|
||||
label_temperature: 0.7,
|
||||
label_top_p: 0.9,
|
||||
quality: 0.8,
|
||||
latency_ms: 100.0,
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Pre-compute Fisher and optimal weights
|
||||
let fisher = router.compute_fisher(&samples);
|
||||
let optimal = router.get_weights();
|
||||
|
||||
c.bench_function("router_train_with_ewc", |b| {
|
||||
b.iter(|| {
|
||||
black_box(router.train_batch(&samples, 0.001, 0.4, Some(&fisher), Some(&optimal)))
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fn benchmark_fisher_computation(c: &mut Criterion) {
|
||||
let config = RouterConfig::default();
|
||||
let router = FastGRNNRouter::new(&config).unwrap();
|
||||
|
||||
let samples: Vec<RouterSample> = (0..100)
|
||||
.map(|i| RouterSample {
|
||||
features: vec![0.1; config.input_dim],
|
||||
label_model: i % 4,
|
||||
label_context: i % 5,
|
||||
label_temperature: 0.7,
|
||||
label_top_p: 0.9,
|
||||
quality: 0.8,
|
||||
latency_ms: 100.0,
|
||||
})
|
||||
.collect();
|
||||
|
||||
c.bench_function("router_compute_fisher_100", |b| {
|
||||
b.iter(|| black_box(router.compute_fisher(&samples)))
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
benchmark_router_forward,
|
||||
benchmark_router_forward_batch_sizes,
|
||||
benchmark_router_training,
|
||||
benchmark_router_training_batch_sizes,
|
||||
benchmark_router_ewc,
|
||||
benchmark_fisher_computation,
|
||||
);
|
||||
criterion_main!(benches);
|
||||
579
examples/ruvLLM/benches/sona_bench.rs
Normal file
579
examples/ruvLLM/benches/sona_bench.rs
Normal file
@@ -0,0 +1,579 @@
|
||||
//! SONA (Self-Optimizing Neural Architecture) Performance Benchmarks
|
||||
//!
|
||||
//! Comprehensive benchmarks for all SONA components:
|
||||
//! - MicroLoRA forward pass (target: <100μs)
|
||||
//! - Trajectory recording (target: <1μs per step)
|
||||
//! - ReasoningBank pattern extraction
|
||||
//! - InstantLoop full cycle (target: <1ms)
|
||||
//! - EWC++ loss computation
|
||||
|
||||
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
|
||||
use ruvllm::sona::*;
|
||||
|
||||
// ============================================================================
|
||||
// MicroLoRA Benchmarks
|
||||
// ============================================================================
|
||||
|
||||
fn micro_lora_benchmarks(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("micro_lora");
|
||||
|
||||
// Test different hidden dimensions
|
||||
for dim in [128, 256, 512] {
|
||||
group.throughput(Throughput::Elements(dim as u64));
|
||||
|
||||
// Rank 1 benchmarks
|
||||
group.bench_with_input(BenchmarkId::new("forward_rank1", dim), &dim, |b, &dim| {
|
||||
let lora = MicroLoRA::new(dim, 1);
|
||||
let input = vec![1.0f32; dim];
|
||||
let mut output = vec![0.0f32; dim];
|
||||
|
||||
b.iter(|| {
|
||||
lora.forward(black_box(&input), black_box(&mut output));
|
||||
});
|
||||
});
|
||||
|
||||
// Rank 2 benchmarks
|
||||
group.bench_with_input(BenchmarkId::new("forward_rank2", dim), &dim, |b, &dim| {
|
||||
let lora = MicroLoRA::new(dim, 2);
|
||||
let input = vec![1.0f32; dim];
|
||||
let mut output = vec![0.0f32; dim];
|
||||
|
||||
b.iter(|| {
|
||||
lora.forward(black_box(&input), black_box(&mut output));
|
||||
});
|
||||
});
|
||||
|
||||
// Scalar (non-SIMD) forward pass for comparison
|
||||
group.bench_with_input(BenchmarkId::new("forward_scalar", dim), &dim, |b, &dim| {
|
||||
let lora = MicroLoRA::new(dim, 1);
|
||||
let input = vec![1.0f32; dim];
|
||||
let mut output = vec![0.0f32; dim];
|
||||
|
||||
b.iter(|| {
|
||||
lora.forward_scalar(black_box(&input), black_box(&mut output));
|
||||
});
|
||||
});
|
||||
|
||||
// Gradient accumulation
|
||||
group.bench_with_input(
|
||||
BenchmarkId::new("accumulate_gradient", dim),
|
||||
&dim,
|
||||
|b, &dim| {
|
||||
let mut lora = MicroLoRA::new(dim, 1);
|
||||
let signal = LearningSignal::with_gradient(vec![0.5; dim], vec![0.1; dim], 0.8);
|
||||
|
||||
b.iter(|| {
|
||||
lora.accumulate_gradient(black_box(&signal));
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
// Apply accumulated gradients
|
||||
group.bench_with_input(
|
||||
BenchmarkId::new("apply_accumulated", dim),
|
||||
&dim,
|
||||
|b, &dim| {
|
||||
let mut lora = MicroLoRA::new(dim, 1);
|
||||
|
||||
// Pre-accumulate some gradients
|
||||
let signal = LearningSignal::with_gradient(vec![0.5; dim], vec![0.1; dim], 0.8);
|
||||
for _ in 0..10 {
|
||||
lora.accumulate_gradient(&signal);
|
||||
}
|
||||
|
||||
b.iter(|| {
|
||||
lora.apply_accumulated(black_box(0.001));
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Trajectory Recording Benchmarks
|
||||
// ============================================================================
|
||||
|
||||
fn trajectory_benchmarks(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("trajectory");
|
||||
|
||||
// Single step recording
|
||||
group.bench_function("record_step", |b| {
|
||||
let buffer = TrajectoryBuffer::new(10000);
|
||||
let id_gen = TrajectoryIdGen::new();
|
||||
|
||||
b.iter(|| {
|
||||
let trajectory = QueryTrajectory::new(id_gen.next(), vec![0.1, 0.2, 0.3, 0.4]);
|
||||
buffer.record(black_box(trajectory));
|
||||
});
|
||||
});
|
||||
|
||||
// Builder - complete trajectory construction
|
||||
for steps in [5, 10, 20] {
|
||||
group.bench_with_input(
|
||||
BenchmarkId::new("build_trajectory", steps),
|
||||
&steps,
|
||||
|b, &steps| {
|
||||
b.iter(|| {
|
||||
let mut builder = TrajectoryBuilder::new(1, vec![0.1, 0.2, 0.3, 0.4]);
|
||||
|
||||
for i in 0..steps {
|
||||
builder.add_step(vec![0.5; 128], vec![0.3; 64], 0.7);
|
||||
}
|
||||
|
||||
black_box(builder.build(0.85));
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Drain operations
|
||||
group.bench_function("drain_all", |b| {
|
||||
let buffer = TrajectoryBuffer::new(10000);
|
||||
|
||||
// Pre-fill buffer
|
||||
for i in 0..1000 {
|
||||
buffer.record(QueryTrajectory::new(i, vec![0.1, 0.2]));
|
||||
}
|
||||
|
||||
b.iter(|| {
|
||||
let drained = buffer.drain();
|
||||
black_box(drained);
|
||||
|
||||
// Refill for next iteration
|
||||
for i in 0..1000 {
|
||||
buffer.record(QueryTrajectory::new(i, vec![0.1, 0.2]));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
group.bench_function("drain_batch_100", |b| {
|
||||
let buffer = TrajectoryBuffer::new(10000);
|
||||
|
||||
// Pre-fill buffer
|
||||
for i in 0..1000 {
|
||||
buffer.record(QueryTrajectory::new(i, vec![0.1, 0.2]));
|
||||
}
|
||||
|
||||
b.iter(|| {
|
||||
let drained = buffer.drain_n(100);
|
||||
black_box(drained);
|
||||
|
||||
// Refill what we drained
|
||||
for i in 0..100 {
|
||||
buffer.record(QueryTrajectory::new(i, vec![0.1, 0.2]));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ReasoningBank Benchmarks
|
||||
// ============================================================================
|
||||
|
||||
fn reasoning_bank_benchmarks(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("reasoning_bank");
|
||||
|
||||
// Pattern extraction with K-means++
|
||||
for trajectory_count in [100, 500, 1000] {
|
||||
group.bench_with_input(
|
||||
BenchmarkId::new("extract_patterns", trajectory_count),
|
||||
&trajectory_count,
|
||||
|b, &count| {
|
||||
let config = PatternConfig {
|
||||
k_clusters: 10,
|
||||
embedding_dim: 128,
|
||||
max_iterations: 50,
|
||||
min_cluster_size: 3,
|
||||
quality_threshold: 0.5,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut bank = ReasoningBank::new(config);
|
||||
|
||||
// Add trajectories
|
||||
for i in 0..count {
|
||||
let mut trajectory = QueryTrajectory::new(
|
||||
i,
|
||||
vec![
|
||||
(i as f32 * 0.1) % 1.0,
|
||||
(i as f32 * 0.2) % 1.0,
|
||||
(i as f32 * 0.3) % 1.0,
|
||||
],
|
||||
);
|
||||
trajectory.finalize(0.7 + (i as f32 * 0.001) % 0.3, 1000);
|
||||
bank.add_trajectory(&trajectory);
|
||||
}
|
||||
|
||||
b.iter(|| {
|
||||
let patterns = bank.extract_patterns();
|
||||
black_box(patterns);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Query similar patterns
|
||||
group.bench_function("query_patterns", |b| {
|
||||
let config = PatternConfig {
|
||||
k_clusters: 20,
|
||||
embedding_dim: 128,
|
||||
min_cluster_size: 3,
|
||||
quality_threshold: 0.5,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut bank = ReasoningBank::new(config);
|
||||
|
||||
// Build up pattern database
|
||||
for i in 0..1000 {
|
||||
let mut trajectory = QueryTrajectory::new(i, vec![(i as f32 * 0.1) % 1.0; 128]);
|
||||
trajectory.finalize(0.8, 1000);
|
||||
bank.add_trajectory(&trajectory);
|
||||
}
|
||||
bank.extract_patterns();
|
||||
|
||||
let query = vec![0.5; 128];
|
||||
|
||||
b.iter(|| {
|
||||
let similar = bank.find_similar(black_box(&query), 5);
|
||||
black_box(similar);
|
||||
});
|
||||
});
|
||||
|
||||
// Pattern consolidation
|
||||
group.bench_function("consolidate_patterns", |b| {
|
||||
let config = PatternConfig {
|
||||
k_clusters: 30,
|
||||
embedding_dim: 128,
|
||||
min_cluster_size: 2,
|
||||
quality_threshold: 0.4,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut bank = ReasoningBank::new(config);
|
||||
|
||||
// Create many similar patterns
|
||||
for i in 0..500 {
|
||||
let mut trajectory = QueryTrajectory::new(i, vec![1.0 + (i as f32 * 0.001); 128]);
|
||||
trajectory.finalize(0.8, 1000);
|
||||
bank.add_trajectory(&trajectory);
|
||||
}
|
||||
bank.extract_patterns();
|
||||
|
||||
b.iter(|| {
|
||||
let mut bank_clone = bank.clone();
|
||||
bank_clone.consolidate(black_box(0.95));
|
||||
});
|
||||
});
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// EWC++ Benchmarks
|
||||
// ============================================================================
|
||||
|
||||
fn ewc_benchmarks(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("ewc_plus_plus");
|
||||
|
||||
// Fisher information update
|
||||
for param_count in [256, 512, 1024] {
|
||||
group.bench_with_input(
|
||||
BenchmarkId::new("update_fisher", param_count),
|
||||
¶m_count,
|
||||
|b, &count| {
|
||||
let config = EwcConfig {
|
||||
param_count: count,
|
||||
..Default::default()
|
||||
};
|
||||
let mut ewc = EwcPlusPlus::new(config);
|
||||
let gradients = vec![0.1; count];
|
||||
|
||||
b.iter(|| {
|
||||
ewc.update_fisher(black_box(&gradients));
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Task boundary detection
|
||||
group.bench_function("detect_boundary", |b| {
|
||||
let config = EwcConfig {
|
||||
param_count: 512,
|
||||
gradient_history_size: 100,
|
||||
..Default::default()
|
||||
};
|
||||
let mut ewc = EwcPlusPlus::new(config);
|
||||
|
||||
// Build up history
|
||||
for _ in 0..100 {
|
||||
ewc.update_fisher(&vec![0.1; 512]);
|
||||
}
|
||||
|
||||
let test_gradients = vec![0.15; 512];
|
||||
|
||||
b.iter(|| {
|
||||
let is_boundary = ewc.detect_task_boundary(black_box(&test_gradients));
|
||||
black_box(is_boundary);
|
||||
});
|
||||
});
|
||||
|
||||
// Apply constraints
|
||||
for task_count in [1, 5, 10] {
|
||||
group.bench_with_input(
|
||||
BenchmarkId::new("apply_constraints", task_count),
|
||||
&task_count,
|
||||
|b, &tasks| {
|
||||
let config = EwcConfig {
|
||||
param_count: 512,
|
||||
max_tasks: tasks,
|
||||
..Default::default()
|
||||
};
|
||||
let mut ewc = EwcPlusPlus::new(config);
|
||||
|
||||
// Create multiple tasks
|
||||
for _ in 0..tasks {
|
||||
for _ in 0..50 {
|
||||
ewc.update_fisher(&vec![0.1; 512]);
|
||||
}
|
||||
ewc.start_new_task();
|
||||
}
|
||||
|
||||
let gradients = vec![0.5; 512];
|
||||
|
||||
b.iter(|| {
|
||||
let constrained = ewc.apply_constraints(black_box(&gradients));
|
||||
black_box(constrained);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Regularization loss computation
|
||||
group.bench_function("regularization_loss", |b| {
|
||||
let config = EwcConfig {
|
||||
param_count: 512,
|
||||
max_tasks: 5,
|
||||
initial_lambda: 1000.0,
|
||||
..Default::default()
|
||||
};
|
||||
let mut ewc = EwcPlusPlus::new(config);
|
||||
|
||||
// Create tasks
|
||||
for _ in 0..5 {
|
||||
ewc.set_optimal_weights(&vec![0.0; 512]);
|
||||
for _ in 0..50 {
|
||||
ewc.update_fisher(&vec![0.1; 512]);
|
||||
}
|
||||
ewc.start_new_task();
|
||||
}
|
||||
|
||||
let current_weights = vec![0.1; 512];
|
||||
|
||||
b.iter(|| {
|
||||
let loss = ewc.regularization_loss(black_box(¤t_weights));
|
||||
black_box(loss);
|
||||
});
|
||||
});
|
||||
|
||||
// Task consolidation
|
||||
group.bench_function("consolidate_tasks", |b| {
|
||||
let config = EwcConfig {
|
||||
param_count: 512,
|
||||
max_tasks: 10,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
b.iter(|| {
|
||||
let mut ewc = EwcPlusPlus::new(config.clone());
|
||||
|
||||
// Create 10 tasks
|
||||
for _ in 0..10 {
|
||||
for _ in 0..20 {
|
||||
ewc.update_fisher(&vec![0.1; 512]);
|
||||
}
|
||||
ewc.start_new_task();
|
||||
}
|
||||
|
||||
ewc.consolidate_all_tasks();
|
||||
black_box(ewc.task_count());
|
||||
});
|
||||
});
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Integrated Benchmarks (Complete SONA Cycles)
|
||||
// ============================================================================
|
||||
|
||||
fn integrated_benchmarks(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("integrated");
|
||||
|
||||
// Complete instant learning cycle
|
||||
group.bench_function("instant_loop_full_cycle", |b| {
|
||||
let dim = 256;
|
||||
let mut lora = MicroLoRA::new(dim, 1);
|
||||
let buffer = TrajectoryBuffer::new(1000);
|
||||
let id_gen = TrajectoryIdGen::new();
|
||||
|
||||
b.iter(|| {
|
||||
// 1. Record trajectory (simulate 10 steps)
|
||||
let mut builder = TrajectoryBuilder::new(id_gen.next(), vec![0.5; dim]);
|
||||
|
||||
for i in 0..10 {
|
||||
builder.add_step(vec![0.3; dim], vec![0.2; 128], 0.7 + (i as f32 * 0.02));
|
||||
}
|
||||
|
||||
let trajectory = builder.build(0.85);
|
||||
|
||||
// 2. Convert to learning signal
|
||||
let signal = LearningSignal::from_trajectory(&trajectory);
|
||||
|
||||
// 3. Accumulate gradient
|
||||
lora.accumulate_gradient(&signal);
|
||||
|
||||
// 4. Apply if batch ready (every 10 iterations in real use)
|
||||
if lora.pending_updates() >= 10 {
|
||||
lora.apply_accumulated(0.001);
|
||||
}
|
||||
|
||||
// 5. Store trajectory
|
||||
buffer.record(black_box(trajectory));
|
||||
});
|
||||
});
|
||||
|
||||
// Pattern-based learning cycle
|
||||
group.bench_function("pattern_learning_cycle", |b| {
|
||||
let config = PatternConfig {
|
||||
k_clusters: 10,
|
||||
embedding_dim: 128,
|
||||
min_cluster_size: 3,
|
||||
quality_threshold: 0.6,
|
||||
..Default::default()
|
||||
};
|
||||
let mut bank = ReasoningBank::new(config);
|
||||
|
||||
// Pre-populate with some trajectories
|
||||
for i in 0..100 {
|
||||
let mut trajectory = QueryTrajectory::new(i, vec![0.5; 128]);
|
||||
trajectory.finalize(0.8, 1000);
|
||||
bank.add_trajectory(&trajectory);
|
||||
}
|
||||
|
||||
b.iter(|| {
|
||||
// 1. Add new trajectory
|
||||
let mut trajectory = QueryTrajectory::new(1000, vec![0.6; 128]);
|
||||
trajectory.finalize(0.85, 1000);
|
||||
bank.add_trajectory(&trajectory);
|
||||
|
||||
// 2. Extract patterns (would be done periodically)
|
||||
if bank.trajectory_count() % 50 == 0 {
|
||||
let patterns = bank.extract_patterns();
|
||||
black_box(patterns);
|
||||
}
|
||||
|
||||
// 3. Query similar patterns
|
||||
let query = vec![0.6; 128];
|
||||
let similar = bank.find_similar(&query, 3);
|
||||
black_box(similar);
|
||||
});
|
||||
});
|
||||
|
||||
// EWC-protected learning
|
||||
group.bench_function("ewc_protected_learning", |b| {
|
||||
let param_count = 512;
|
||||
let config = EwcConfig {
|
||||
param_count,
|
||||
max_tasks: 5,
|
||||
initial_lambda: 1000.0,
|
||||
..Default::default()
|
||||
};
|
||||
let mut ewc = EwcPlusPlus::new(config);
|
||||
|
||||
// Setup with one completed task
|
||||
ewc.set_optimal_weights(&vec![0.0; param_count]);
|
||||
for _ in 0..50 {
|
||||
ewc.update_fisher(&vec![0.1; param_count]);
|
||||
}
|
||||
ewc.start_new_task();
|
||||
|
||||
let mut lora = MicroLoRA::new(param_count, 1);
|
||||
|
||||
b.iter(|| {
|
||||
// 1. Get raw gradients from learning signal
|
||||
let signal =
|
||||
LearningSignal::with_gradient(vec![0.5; param_count], vec![0.1; param_count], 0.8);
|
||||
|
||||
// 2. Apply EWC constraints
|
||||
let constrained = ewc.apply_constraints(&signal.gradient_estimate);
|
||||
|
||||
// 3. Create constrained signal
|
||||
let constrained_signal = LearningSignal::with_gradient(
|
||||
signal.query_embedding.clone(),
|
||||
constrained,
|
||||
signal.quality_score,
|
||||
);
|
||||
|
||||
// 4. Apply to LoRA
|
||||
lora.accumulate_gradient(&constrained_signal);
|
||||
|
||||
// 5. Update Fisher
|
||||
ewc.update_fisher(&signal.gradient_estimate);
|
||||
});
|
||||
});
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Learning Signal Benchmarks
|
||||
// ============================================================================
|
||||
|
||||
fn learning_signal_benchmarks(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("learning_signal");
|
||||
|
||||
// Gradient estimation from trajectory
|
||||
for step_count in [5, 10, 20] {
|
||||
group.bench_with_input(
|
||||
BenchmarkId::new("from_trajectory", step_count),
|
||||
&step_count,
|
||||
|b, &steps| {
|
||||
let mut trajectory = QueryTrajectory::new(1, vec![0.5; 256]);
|
||||
|
||||
for i in 0..steps {
|
||||
trajectory.add_step(TrajectoryStep::new(
|
||||
vec![0.3; 256],
|
||||
vec![0.2; 128],
|
||||
0.7 + (i as f32 * 0.02),
|
||||
i,
|
||||
));
|
||||
}
|
||||
trajectory.finalize(0.85, 1000);
|
||||
|
||||
b.iter(|| {
|
||||
let signal = LearningSignal::from_trajectory(black_box(&trajectory));
|
||||
black_box(signal);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
micro_lora_benchmarks,
|
||||
trajectory_benchmarks,
|
||||
reasoning_bank_benchmarks,
|
||||
ewc_benchmarks,
|
||||
integrated_benchmarks,
|
||||
learning_signal_benchmarks,
|
||||
);
|
||||
|
||||
criterion_main!(benches);
|
||||
Reference in New Issue
Block a user