Skip to content

Commit 48d008b

Browse files
committed
Automatic embedding store invalidation
1 parent 854df15 commit 48d008b

File tree

3 files changed

+91
-7
lines changed

3 files changed

+91
-7
lines changed

BingusApi/EmbeddingServices/RocksDbStore.cs

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55

66
namespace BingusApi.EmbeddingServices
77
{
8-
public class RocksDbStore : IEmbeddingStore
8+
public class RocksDbStore : IEmbeddingStore, IDisposable
99
{
10+
public const string ModelUidKey = "<model_uid>";
11+
1012
private readonly RocksDb rocksDb;
1113

1214
public RocksDbStore(RocksDb rocksDb)
@@ -16,14 +18,21 @@ public RocksDbStore(RocksDb rocksDb)
1618

1719
private static byte[] SerializeString(string value) => Encoding.UTF8.GetBytes(value);
1820

21+
private static string DeserializeString(byte[] value) => Encoding.UTF8.GetString(value);
22+
1923
public void Add(string key, Vector<float> embedding)
2024
{
21-
rocksDb.Put(SerializeString(key), RocksDbSerializer.SerializeVector(embedding));
25+
Add(key, RocksDbSerializer.SerializeVector(embedding));
2226
}
2327

2428
public void Add(string key, float[] embedding)
2529
{
26-
rocksDb.Put(SerializeString(key), RocksDbSerializer.SerializeArray(embedding));
30+
Add(key, RocksDbSerializer.SerializeArray(embedding));
31+
}
32+
33+
public void Add(string key, byte[] data)
34+
{
35+
rocksDb.Put(SerializeString(key), data);
2736
}
2837

2938
public byte[]? GetBytes(string key)
@@ -47,5 +56,61 @@ public bool Has(string key)
4756
{
4857
return rocksDb.HasKey(SerializeString(key));
4958
}
59+
60+
public void Dispose()
61+
{
62+
rocksDb?.Dispose();
63+
GC.SuppressFinalize(this);
64+
}
65+
66+
public static RocksDbStore Create(
67+
string dbPath,
68+
string modelUid,
69+
ILogger<RocksDbStore>? logger
70+
)
71+
{
72+
var preexisting = Directory.Exists(dbPath) && Directory.GetFiles(dbPath).Length > 0;
73+
74+
var options = new DbOptions().SetCreateIfMissing(true);
75+
var db = RocksDb.Open(options, dbPath);
76+
var store = new RocksDbStore(db);
77+
78+
var lastModelUidB = store.GetBytes(ModelUidKey);
79+
if (lastModelUidB != null)
80+
{
81+
var lastModelUid = DeserializeString(lastModelUidB);
82+
if (lastModelUid != modelUid)
83+
{
84+
logger?.LogWarning(
85+
"Model UID has changed from \"{LastModelUid}\" to \"{ModelUid}\". Deleting the store.",
86+
lastModelUid,
87+
modelUid
88+
);
89+
90+
// Delete the store
91+
store.Dispose();
92+
foreach (var file in Directory.GetFiles(dbPath))
93+
{
94+
File.Delete(file);
95+
}
96+
97+
// Recreate the store
98+
return Create(dbPath, modelUid, logger);
99+
}
100+
}
101+
else
102+
{
103+
if (preexisting)
104+
{
105+
logger?.LogWarning(
106+
"No model UID found in existing store. Writing current model UID \"{ModelUid}\".",
107+
modelUid
108+
);
109+
}
110+
store.Add(ModelUidKey, SerializeString(modelUid));
111+
}
112+
113+
return store;
114+
}
50115
}
51116
}

BingusApi/Program.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using BingusLib.FaqHandling;
55
using BingusLib.HNSW;
66
using HNSW.Net;
7-
using RocksDbSharp;
87

98
var builder = WebApplication.CreateBuilder(args);
109

@@ -45,9 +44,6 @@ string GetConfig(string fileName)
4544
builder.Services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
4645

4746
// Add dependencies
48-
builder.Services.AddSingleton<IEmbeddingStore>(sp => new RocksDbStore(
49-
RocksDb.Open(new DbOptions().SetCreateIfMissing(true), "embedding_cache")
50-
));
5147
builder.Services.AddSingleton(sp =>
5248
new JsonConfigHandler<BingusConfig>(GetConfig(bingusConfig)).InitializeConfig(
5349
BingusConfig.Default,
@@ -61,6 +57,13 @@ string GetConfig(string fileName)
6157
)
6258
);
6359

60+
// Create persistent embedding store dependent on model hash
61+
builder.Services.AddSingleton<IEmbeddingStore>(sp =>
62+
{
63+
var modelUid = sp.GetRequiredService<BingusConfig>().GetModelUid();
64+
return RocksDbStore.Create("embedding_cache", modelUid, sp.GetService<ILogger<RocksDbStore>>());
65+
});
66+
6467
// Initialize Bingus library dependencies
6568
builder.Services.AddHttpClient();
6669
builder.Services.AddSingleton(sp => sp.GetRequiredService<BingusConfig>().GetSentenceEncoder(sp));

BingusLib/Config/BingusConfig.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,21 @@ public SentenceEncoder GetSentenceEncoder(IServiceProvider serviceProvider)
5757
throw new JsonConfigException("No valid sentence encoder type was selected.");
5858
}
5959
}
60+
61+
public string GetModelUri()
62+
{
63+
return EncoderType.ToLower() switch
64+
{
65+
"use" => UseModelPath,
66+
"api" => ApiUri,
67+
"llama" => LlamaModelPath,
68+
_ => throw new JsonConfigException("No valid sentence encoder type was selected."),
69+
};
70+
}
71+
72+
public string GetModelUid()
73+
{
74+
return $"{EncoderType.ToLower()}@{GetModelUri()}";
75+
}
6076
}
6177
}

0 commit comments

Comments
 (0)