ruvector 0.1.31 → 0.1.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,512 +0,0 @@
1
- /**
2
- * Attention Fallbacks - Safe wrapper around @ruvector/attention with automatic array conversion
3
- *
4
- * This wrapper handles the array type conversion automatically, allowing users
5
- * to pass either regular arrays or Float32Arrays.
6
- *
7
- * @ruvector/attention requires Float32Array inputs.
8
- * This wrapper handles the conversion automatically.
9
- */
10
-
11
- // Lazy load to avoid import errors if not installed
12
- let attentionModule: any = null;
13
- let loadError: Error | null = null;
14
-
15
- function getAttentionModule() {
16
- if (attentionModule) return attentionModule;
17
- if (loadError) throw loadError;
18
-
19
- try {
20
- attentionModule = require('@ruvector/attention');
21
- return attentionModule;
22
- } catch (e: any) {
23
- loadError = new Error(
24
- `@ruvector/attention is not installed or failed to load: ${e.message}\n` +
25
- `Install with: npm install @ruvector/attention`
26
- );
27
- throw loadError;
28
- }
29
- }
30
-
31
- /**
32
- * Convert any array-like input to Float32Array
33
- */
34
- function toFloat32Array(input: number[] | Float32Array | Float64Array): Float32Array {
35
- if (input instanceof Float32Array) {
36
- return input;
37
- }
38
- return new Float32Array(input);
39
- }
40
-
41
- /**
42
- * Convert nested arrays to Float32Arrays
43
- */
44
- function toFloat32Arrays(inputs: (number[] | Float32Array | Float64Array)[]): Float32Array[] {
45
- return inputs.map(arr => toFloat32Array(arr));
46
- }
47
-
48
- /**
49
- * Convert Float32Array result back to regular array if needed
50
- */
51
- function fromFloat32Array(input: Float32Array): number[] {
52
- return Array.from(input);
53
- }
54
-
55
- /**
56
- * Attention output interface
57
- */
58
- export interface AttentionOutput {
59
- /** Output vector as regular array */
60
- values: number[];
61
- /** Output as Float32Array for performance-critical code */
62
- raw: Float32Array;
63
- }
64
-
65
- /**
66
- * Multi-head attention mechanism
67
- *
68
- * This wrapper automatically converts array inputs to Float32Array.
69
- */
70
- export class MultiHeadAttention {
71
- private inner: any;
72
- public readonly dim: number;
73
- public readonly numHeads: number;
74
-
75
- /**
76
- * Create a new multi-head attention instance
77
- *
78
- * @param dim - Embedding dimension (must be divisible by numHeads)
79
- * @param numHeads - Number of attention heads
80
- */
81
- constructor(dim: number, numHeads: number) {
82
- const attention = getAttentionModule();
83
- this.inner = new attention.MultiHeadAttention(dim, numHeads);
84
- this.dim = dim;
85
- this.numHeads = numHeads;
86
- }
87
-
88
- /**
89
- * Compute multi-head attention
90
- *
91
- * @param query - Query vector
92
- * @param keys - Array of key vectors
93
- * @param values - Array of value vectors
94
- * @returns Attention output
95
- *
96
- * @example
97
- * ```typescript
98
- * const mha = new MultiHeadAttention(64, 4);
99
- *
100
- * // Works with regular arrays
101
- * const result1 = mha.compute([...64 values], [[...64], [...64]], [[...64], [...64]]);
102
- *
103
- * // Also works with Float32Array
104
- * const q = new Float32Array(64);
105
- * const k = [new Float32Array(64)];
106
- * const v = [new Float32Array(64)];
107
- * const result2 = mha.compute(q, k, v);
108
- * ```
109
- */
110
- compute(
111
- query: number[] | Float32Array,
112
- keys: (number[] | Float32Array)[],
113
- values: (number[] | Float32Array)[]
114
- ): AttentionOutput {
115
- const raw = this.inner.compute(
116
- toFloat32Array(query),
117
- toFloat32Arrays(keys),
118
- toFloat32Arrays(values)
119
- );
120
- return {
121
- values: fromFloat32Array(raw),
122
- raw
123
- };
124
- }
125
-
126
- /**
127
- * Compute and return raw Float32Array (faster, no conversion)
128
- */
129
- computeRaw(
130
- query: Float32Array,
131
- keys: Float32Array[],
132
- values: Float32Array[]
133
- ): Float32Array {
134
- return this.inner.compute(query, keys, values);
135
- }
136
-
137
- get headDim(): number {
138
- return this.dim / this.numHeads;
139
- }
140
- }
141
-
142
- /**
143
- * Flash attention with tiled computation
144
- */
145
- export class FlashAttention {
146
- private inner: any;
147
- public readonly dim: number;
148
- public readonly blockSize: number;
149
-
150
- /**
151
- * Create a new flash attention instance
152
- *
153
- * @param dim - Embedding dimension
154
- * @param blockSize - Block size for tiled computation (default: 512)
155
- */
156
- constructor(dim: number, blockSize: number = 512) {
157
- const attention = getAttentionModule();
158
- this.inner = new attention.FlashAttention(dim, blockSize);
159
- this.dim = dim;
160
- this.blockSize = blockSize;
161
- }
162
-
163
- /**
164
- * Compute flash attention
165
- */
166
- compute(
167
- query: number[] | Float32Array,
168
- keys: (number[] | Float32Array)[],
169
- values: (number[] | Float32Array)[]
170
- ): AttentionOutput {
171
- const raw = this.inner.compute(
172
- toFloat32Array(query),
173
- toFloat32Arrays(keys),
174
- toFloat32Arrays(values)
175
- );
176
- return {
177
- values: fromFloat32Array(raw),
178
- raw
179
- };
180
- }
181
-
182
- computeRaw(
183
- query: Float32Array,
184
- keys: Float32Array[],
185
- values: Float32Array[]
186
- ): Float32Array {
187
- return this.inner.compute(query, keys, values);
188
- }
189
- }
190
-
191
- /**
192
- * Hyperbolic attention in Poincare ball model
193
- */
194
- export class HyperbolicAttention {
195
- private inner: any;
196
- public readonly dim: number;
197
- public readonly curvature: number;
198
-
199
- /**
200
- * Create a new hyperbolic attention instance
201
- *
202
- * @param dim - Embedding dimension
203
- * @param curvature - Hyperbolic curvature (typically 1.0)
204
- */
205
- constructor(dim: number, curvature: number = 1.0) {
206
- const attention = getAttentionModule();
207
- this.inner = new attention.HyperbolicAttention(dim, curvature);
208
- this.dim = dim;
209
- this.curvature = curvature;
210
- }
211
-
212
- /**
213
- * Compute hyperbolic attention
214
- */
215
- compute(
216
- query: number[] | Float32Array,
217
- keys: (number[] | Float32Array)[],
218
- values: (number[] | Float32Array)[]
219
- ): AttentionOutput {
220
- const raw = this.inner.compute(
221
- toFloat32Array(query),
222
- toFloat32Arrays(keys),
223
- toFloat32Arrays(values)
224
- );
225
- return {
226
- values: fromFloat32Array(raw),
227
- raw
228
- };
229
- }
230
-
231
- computeRaw(
232
- query: Float32Array,
233
- keys: Float32Array[],
234
- values: Float32Array[]
235
- ): Float32Array {
236
- return this.inner.compute(query, keys, values);
237
- }
238
- }
239
-
240
- /**
241
- * Linear attention (Performer-style) with O(n) complexity
242
- */
243
- export class LinearAttention {
244
- private inner: any;
245
- public readonly dim: number;
246
- public readonly numFeatures: number;
247
-
248
- /**
249
- * Create a new linear attention instance
250
- *
251
- * @param dim - Embedding dimension
252
- * @param numFeatures - Number of random features
253
- */
254
- constructor(dim: number, numFeatures: number) {
255
- const attention = getAttentionModule();
256
- this.inner = new attention.LinearAttention(dim, numFeatures);
257
- this.dim = dim;
258
- this.numFeatures = numFeatures;
259
- }
260
-
261
- /**
262
- * Compute linear attention
263
- */
264
- compute(
265
- query: number[] | Float32Array,
266
- keys: (number[] | Float32Array)[],
267
- values: (number[] | Float32Array)[]
268
- ): AttentionOutput {
269
- const raw = this.inner.compute(
270
- toFloat32Array(query),
271
- toFloat32Arrays(keys),
272
- toFloat32Arrays(values)
273
- );
274
- return {
275
- values: fromFloat32Array(raw),
276
- raw
277
- };
278
- }
279
-
280
- computeRaw(
281
- query: Float32Array,
282
- keys: Float32Array[],
283
- values: Float32Array[]
284
- ): Float32Array {
285
- return this.inner.compute(query, keys, values);
286
- }
287
- }
288
-
289
- /**
290
- * Local-global attention (Longformer-style)
291
- */
292
- export class LocalGlobalAttention {
293
- private inner: any;
294
- public readonly dim: number;
295
- public readonly localWindow: number;
296
- public readonly globalTokens: number;
297
-
298
- /**
299
- * Create a new local-global attention instance
300
- *
301
- * @param dim - Embedding dimension
302
- * @param localWindow - Size of local attention window
303
- * @param globalTokens - Number of global attention tokens
304
- */
305
- constructor(dim: number, localWindow: number, globalTokens: number) {
306
- const attention = getAttentionModule();
307
- this.inner = new attention.LocalGlobalAttention(dim, localWindow, globalTokens);
308
- this.dim = dim;
309
- this.localWindow = localWindow;
310
- this.globalTokens = globalTokens;
311
- }
312
-
313
- /**
314
- * Compute local-global attention
315
- */
316
- compute(
317
- query: number[] | Float32Array,
318
- keys: (number[] | Float32Array)[],
319
- values: (number[] | Float32Array)[]
320
- ): AttentionOutput {
321
- const raw = this.inner.compute(
322
- toFloat32Array(query),
323
- toFloat32Arrays(keys),
324
- toFloat32Arrays(values)
325
- );
326
- return {
327
- values: fromFloat32Array(raw),
328
- raw
329
- };
330
- }
331
-
332
- computeRaw(
333
- query: Float32Array,
334
- keys: Float32Array[],
335
- values: Float32Array[]
336
- ): Float32Array {
337
- return this.inner.compute(query, keys, values);
338
- }
339
- }
340
-
341
- /**
342
- * MoE configuration
343
- */
344
- export interface MoEConfig {
345
- dim: number;
346
- numExperts: number;
347
- topK: number;
348
- expertCapacity?: number;
349
- }
350
-
351
- /**
352
- * Mixture of Experts attention
353
- */
354
- export class MoEAttention {
355
- private inner: any;
356
- public readonly config: MoEConfig;
357
-
358
- /**
359
- * Create a new MoE attention instance
360
- *
361
- * @param config - MoE configuration
362
- */
363
- constructor(config: MoEConfig) {
364
- const attention = getAttentionModule();
365
- this.inner = new attention.MoEAttention({
366
- dim: config.dim,
367
- num_experts: config.numExperts,
368
- top_k: config.topK,
369
- expert_capacity: config.expertCapacity ?? 1.25,
370
- });
371
- this.config = config;
372
- }
373
-
374
- /**
375
- * Create with simple parameters
376
- */
377
- static simple(dim: number, numExperts: number, topK: number): MoEAttention {
378
- return new MoEAttention({ dim, numExperts, topK });
379
- }
380
-
381
- /**
382
- * Compute MoE attention
383
- */
384
- compute(
385
- query: number[] | Float32Array,
386
- keys: (number[] | Float32Array)[],
387
- values: (number[] | Float32Array)[]
388
- ): AttentionOutput {
389
- const raw = this.inner.compute(
390
- toFloat32Array(query),
391
- toFloat32Arrays(keys),
392
- toFloat32Arrays(values)
393
- );
394
- return {
395
- values: fromFloat32Array(raw),
396
- raw
397
- };
398
- }
399
-
400
- computeRaw(
401
- query: Float32Array,
402
- keys: Float32Array[],
403
- values: Float32Array[]
404
- ): Float32Array {
405
- return this.inner.compute(query, keys, values);
406
- }
407
- }
408
-
409
- // Hyperbolic math utilities
410
-
411
- /**
412
- * Project a vector into the Poincare ball
413
- */
414
- export function projectToPoincareBall(
415
- vector: number[] | Float32Array,
416
- curvature: number = 1.0
417
- ): number[] {
418
- const attention = getAttentionModule();
419
- const result = attention.projectToPoincareBall(toFloat32Array(vector), curvature);
420
- return fromFloat32Array(result);
421
- }
422
-
423
- /**
424
- * Compute hyperbolic (Poincare) distance between two points
425
- */
426
- export function poincareDistance(
427
- a: number[] | Float32Array,
428
- b: number[] | Float32Array,
429
- curvature: number = 1.0
430
- ): number {
431
- const attention = getAttentionModule();
432
- return attention.poincareDistance(toFloat32Array(a), toFloat32Array(b), curvature);
433
- }
434
-
435
- /**
436
- * Mobius addition in hyperbolic space
437
- */
438
- export function mobiusAddition(
439
- a: number[] | Float32Array,
440
- b: number[] | Float32Array,
441
- curvature: number = 1.0
442
- ): number[] {
443
- const attention = getAttentionModule();
444
- const result = attention.mobiusAddition(toFloat32Array(a), toFloat32Array(b), curvature);
445
- return fromFloat32Array(result);
446
- }
447
-
448
- /**
449
- * Exponential map from tangent space to hyperbolic space
450
- */
451
- export function expMap(
452
- base: number[] | Float32Array,
453
- tangent: number[] | Float32Array,
454
- curvature: number = 1.0
455
- ): number[] {
456
- const attention = getAttentionModule();
457
- const result = attention.expMap(toFloat32Array(base), toFloat32Array(tangent), curvature);
458
- return fromFloat32Array(result);
459
- }
460
-
461
- /**
462
- * Logarithmic map from hyperbolic space to tangent space
463
- */
464
- export function logMap(
465
- base: number[] | Float32Array,
466
- point: number[] | Float32Array,
467
- curvature: number = 1.0
468
- ): number[] {
469
- const attention = getAttentionModule();
470
- const result = attention.logMap(toFloat32Array(base), toFloat32Array(point), curvature);
471
- return fromFloat32Array(result);
472
- }
473
-
474
- /**
475
- * Check if attention module is available
476
- */
477
- export function isAttentionAvailable(): boolean {
478
- try {
479
- getAttentionModule();
480
- return true;
481
- } catch {
482
- return false;
483
- }
484
- }
485
-
486
- /**
487
- * Get attention module version
488
- */
489
- export function getAttentionVersion(): string | null {
490
- try {
491
- const attention = getAttentionModule();
492
- return attention.version?.() ?? null;
493
- } catch {
494
- return null;
495
- }
496
- }
497
-
498
- export default {
499
- MultiHeadAttention,
500
- FlashAttention,
501
- HyperbolicAttention,
502
- LinearAttention,
503
- LocalGlobalAttention,
504
- MoEAttention,
505
- projectToPoincareBall,
506
- poincareDistance,
507
- mobiusAddition,
508
- expMap,
509
- logMap,
510
- isAttentionAvailable,
511
- getAttentionVersion,
512
- };