@mineproness/tensorloop 2.1.55 β†’ 2.1.56

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.
Files changed (51) hide show
  1. package/index.js +14 -20
  2. package/package.json +5 -2
  3. package/readme.md +907 -72
  4. package/src/Embedding/index.d.ts +5 -5
  5. package/src/Embedding/index.js +118 -33
  6. package/src/FFN/index.d.ts +5 -5
  7. package/src/FFN/index.js +34 -39
  8. package/src/Linear/index.d.ts +7 -8
  9. package/src/Linear/index.js +173 -49
  10. package/src/OperationManager.js +96 -0
  11. package/src/Relu/index.d.ts +5 -0
  12. package/src/Relu/index.js +103 -0
  13. package/src/SelfAttention/index.d.ts +7 -13
  14. package/src/SelfAttention/index.js +108 -55
  15. package/src/Softmax/index.d.ts +4 -3
  16. package/src/Softmax/index.js +192 -12
  17. package/src/Tokenizer/index.d.ts +1 -0
  18. package/src/Tokenizer/index.js +92 -7
  19. package/src/TransformerBlock/index.d.ts +6 -7
  20. package/src/TransformerBlock/index.js +24 -23
  21. package/src/getVec.js +28 -0
  22. package/src/shaders/CalculateAcc.wgsl +50 -0
  23. package/src/shaders/CalculateLoss.wgsl +35 -0
  24. package/src/shaders/ComputeDInput.wgsl +32 -0
  25. package/src/shaders/EB.wgsl +31 -0
  26. package/src/shaders/EF.wgsl +25 -0
  27. package/src/shaders/LB.wgsl +57 -0
  28. package/src/shaders/LF.wgsl +44 -0
  29. package/src/shaders/RB.wgsl +37 -0
  30. package/src/shaders/RF.wgsl +33 -0
  31. package/src/shaders/ReductionFunction.wgsl +28 -0
  32. package/src/shaders/SB.wgsl +36 -0
  33. package/src/shaders/SF.wgsl +65 -0
  34. package/src/shaders/SoftmaxBackward.wgsl +31 -0
  35. package/src/shaders/attentionShader/CompueFinalForwardOutput.wgsl +29 -0
  36. package/src/shaders/attentionShader/ComputeDA.wgsl +30 -0
  37. package/src/shaders/attentionShader/ComputeDV.wgsl +37 -0
  38. package/src/shaders/attentionShader/ComputeK.wgsl +30 -0
  39. package/src/shaders/attentionShader/ComputedQ.wgsl +31 -0
  40. package/src/shaders/attentionShader/attentionSocres.wgsl +40 -0
  41. package/src/shaders/attentionShader/sumGradient.wgsl +24 -0
  42. package/src/GELU/index.d.ts +0 -6
  43. package/src/GELU/index.js +0 -33
  44. package/src/GetConfigs.js +0 -35
  45. package/src/Model/index.d.ts +0 -10
  46. package/src/Model/index.js +0 -88
  47. package/src/PositionEmbedding/index.d.ts +0 -11
  48. package/src/PositionEmbedding/index.js +0 -49
  49. package/src/ReLU/index.d.ts +0 -5
  50. package/src/ReLU/index.js +0 -17
  51. package/src/gpiInit.js +0 -764
package/readme.md CHANGED
@@ -1,124 +1,959 @@
1
- # TensorLoop ➰
1
+ # Tensorloop
2
2
 
3
- A high-performance JavaScript library that provides essential AI and Large Language Model (LLM) development utilities. Build, train, and run neural network components like Embeddings, Linear layers, Activations, and Tokenizers directly in JavaScript.
3
+ **GPU-accelerated neural network and Transformer library for JavaScript using WebGPU.**
4
+
5
+ Tensorloop is a JavaScript library for building and training neural networks and GPT-style Transformer models directly with **WebGPU**.
6
+
7
+ It is designed around GPU computation while keeping the API relatively simple, making it possible to experiment with embeddings, linear layers, self-attention, Transformer blocks, softmax, and training without relying on Python-based ML frameworks.
8
+
9
+ > 🚧 **Status:** Experimental / actively developing
10
+
11
+ ---
12
+
13
+ ## ✨ Features
14
+
15
+ * ⚑ WebGPU-accelerated computation
16
+ * 🧠 Transformer architecture components
17
+ * πŸ”€ Token embeddings
18
+ * πŸ”’ Linear layers
19
+ * 🎯 Softmax and cross-entropy
20
+ * πŸ”„ Forward and backward propagation
21
+ * 🧩 Transformer blocks
22
+ * πŸ’Ύ Model weight saving
23
+ * πŸ“¦ JavaScript / Node.js
24
+ * πŸ–₯️ GPU computation through WebGPU
25
+ * πŸ› οΈ Designed for building LLM experiments from scratch
26
+
27
+ ---
28
+
29
+ ## 🧠 Transformer Architecture
30
+
31
+ Tensorloop can be used to construct a GPT-style language model using individual components.
32
+
33
+ A typical model can look like:
34
+
35
+ ```text
36
+ Token IDs
37
+ β”‚
38
+ β–Ό
39
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
40
+ β”‚ Tokenizerβ”‚
41
+ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
42
+ β”‚
43
+ β–Ό
44
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
45
+ β”‚ Embeddingβ”‚
46
+ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
47
+ β”‚
48
+ β–Ό
49
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
50
+ β”‚ TransformerBlockβ”‚
51
+ β”‚ Self-Attention β”‚
52
+ β”‚ + FFN β”‚
53
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
54
+ β”‚
55
+ β–Ό
56
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
57
+ β”‚ TransformerBlockβ”‚
58
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
59
+ β”‚
60
+ β–Ό
61
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
62
+ β”‚ TransformerBlockβ”‚
63
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
64
+ β”‚
65
+ β–Ό
66
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
67
+ β”‚ Linear β”‚
68
+ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
69
+ β”‚
70
+ β–Ό
71
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
72
+ β”‚ Softmax β”‚
73
+ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
74
+ β”‚
75
+ β–Ό
76
+ Token Probabilities
77
+ ```
78
+
79
+ The components can be connected manually, allowing you to experiment with the architecture instead of using a single black-box model.
4
80
 
5
81
  ---
6
82
 
7
- ## πŸš€ Features
83
+ ## πŸ“¦ Installation
84
+
85
+ Install Tensorloop with npm:
86
+
87
+ ```bash
88
+ npm install @mineproness/tensorloop
89
+ ```
90
+
91
+ Tensorloop requires a runtime with WebGPU support.
92
+
93
+ For Node.js WebGPU environments, you can use a WebGPU implementation such as:
94
+
95
+ ```bash
96
+ npm install webgpu
97
+ ```
98
+
99
+ ---
100
+
101
+ ## πŸš€ Basic Example
102
+
103
+ The following example creates a small language model using:
104
+
105
+ * Tokenizer
106
+ * 64-dimensional embeddings
107
+ * 3 Transformer blocks
108
+ * Linear output layer
109
+ * Softmax
110
+ * Cross-entropy loss
111
+ * Backpropagation
112
+ * GPU computation
113
+
114
+ ```js
115
+ import {
116
+ Embedding,
117
+ Linear,
118
+ Tokenizer,
119
+ TransformerBlock,
120
+ Softmax
121
+ } from "@mineproness/tensorloop"
122
+
123
+ import { create, globals } from "webgpu"
124
+ import fs from "fs"
125
+
126
+ Object.assign(globalThis, globals)
127
+
128
+ const navigator = {
129
+ gpu: create(["adapter=NVIDIA GeForce 920M"])
130
+ }
131
+
132
+ const contextSize = 24
133
+ const lr = 0.02
134
+
135
+ async function train() {
136
+
137
+ // Load tokenizer
138
+ const tokenizer = new Tokenizer("./vocab.json")
139
+
140
+ // Initialize WebGPU
141
+ const adapter = await navigator.gpu.requestAdapter({
142
+ powerPreference: "low-power"
143
+ })
144
+
145
+ const device = await adapter.requestDevice()
146
+
147
+ // Token embedding
148
+ const embedding = new Embedding(
149
+ device,
150
+ 64,
151
+ tokenizer.vocabSize,
152
+ {
153
+ cpuReadBack: false,
154
+
155
+ save: {
156
+ filename: "model/vec.bin"
157
+ }
158
+ }
159
+ )
160
+
161
+ // Output projection
162
+ const linear = new Linear(
163
+ device,
164
+ 64,
165
+ tokenizer.vocabSize,
166
+ {
167
+ save: {
168
+ filename: [
169
+ "./model/bias.bin",
170
+ "./model/weights.bin"
171
+ ]
172
+ }
173
+ }
174
+ )
175
+
176
+ // Transformer blocks
177
+ const block = new TransformerBlock(
178
+ device,
179
+ 64,
180
+ {
181
+ dirname: "./model/block1"
182
+ }
183
+ )
184
+
185
+ const block1 = new TransformerBlock(
186
+ device,
187
+ 64,
188
+ {
189
+ dirname: "./model/block2"
190
+ }
191
+ )
192
+
193
+ const block2 = new TransformerBlock(
194
+ device,
195
+ 64,
196
+ {
197
+ dirname: "./model/block3"
198
+ }
199
+ )
200
+
201
+ // Output softmax
202
+ const softmax = new Softmax(
203
+ device,
204
+ 64,
205
+ tokenizer.vocabSize
206
+ )
207
+
208
+ // Load dataset
209
+ const tokens = fs
210
+ .readFileSync("./dataset.txt", "utf-8")
211
+ .split("\r\n")
212
+ .filter(e => e.length > 0)
213
+ .map(e => e.trim() + "<EOS>")
214
+ .map(e => tokenizer.encoder(e).tokenIDs)
215
+ .flat()
216
+
217
+ // Create next-token prediction pairs
218
+ const trainingPairs = []
219
+
220
+ for (let i = 0; i < tokens.length; i++) {
221
+
222
+ trainingPairs.push({
223
+ inputIDX: tokens.slice(
224
+ i,
225
+ i + contextSize
226
+ ),
227
+
228
+ targetIDX: tokens.slice(
229
+ i + 1,
230
+ i + contextSize + 1
231
+ )
232
+ })
233
+
234
+ }
235
+
236
+ const start = 0
237
+ const end = 8000
238
+
239
+ // Training
240
+ for (let epoch = 0; epoch < 100; epoch++) {
241
+
242
+ let totalLoss = 0
243
+ let totalAcc = 0
244
+
245
+ for (let i = start; i < end; i++) {
246
+
247
+ // -------------------------
248
+ // Forward pass
249
+ // -------------------------
250
+
251
+ let vec = await embedding.forward(
252
+ trainingPairs[i].inputIDX
253
+ )
254
+
255
+ vec = await block.forward(vec)
256
+
257
+ vec = await block1.forward(vec)
258
+
259
+ vec = await block2.forward(vec)
260
+
261
+ const logits = await linear.forward(vec)
262
+
263
+ const probs = await softmax.forward(logits)
264
+
265
+ // -------------------------
266
+ // Loss
267
+ // -------------------------
268
+
269
+ const { loss, acc } =
270
+ await softmax.crossEntropy(
271
+ probs,
272
+ trainingPairs[i].targetIDX
273
+ )
274
+
275
+ totalLoss += loss
276
+ totalAcc += acc
277
+
278
+ // -------------------------
279
+ // Backward pass
280
+ // -------------------------
281
+
282
+ const dLogits =
283
+ await softmax.backward(
284
+ probs,
285
+ trainingPairs[i].targetIDX
286
+ )
287
+
288
+ let dInput =
289
+ await linear.backward(
290
+ dLogits,
291
+ lr
292
+ )
293
+
294
+ dInput =
295
+ await block2.backward(
296
+ dInput,
297
+ lr
298
+ )
299
+
300
+ dInput =
301
+ await block1.backward(
302
+ dInput,
303
+ lr
304
+ )
305
+
306
+ dInput =
307
+ await block.backward(
308
+ dInput,
309
+ lr
310
+ )
311
+
312
+ embedding.backward(
313
+ trainingPairs[i].inputIDX,
314
+ dInput,
315
+ lr
316
+ )
317
+
318
+ // Clear cached tensors
319
+ await block.ClearInputCache()
320
+ await block1.ClearInputCache()
321
+ await block2.ClearInputCache()
322
+ await linear.ClearInputCache()
323
+ }
324
+
325
+ // -------------------------
326
+ // Save model
327
+ // -------------------------
328
+
329
+ await embedding.Save()
330
+ await linear.Save()
331
+ await block.Save()
332
+ await block1.Save()
333
+ await block2.Save()
334
+
335
+ console.log(
336
+ `Epoch ${epoch + 1} | ` +
337
+ `Loss: ${totalLoss / (end - start)} | ` +
338
+ `Accuracy: ${totalAcc / (end - start)}`
339
+ )
340
+ }
341
+ }
342
+
343
+ train()
344
+ ```
8
345
 
9
- - **Transformer Block**: Complete modular block managing full attention and forward/backward training passes.
10
- - **Embedding Vectors**: High-speed lookup and embedding initialization.
11
- - **Linear Layer**: Fully connected layers with manageable weights and biases.
12
- - **Activations**: Forward and backward propagation for **Softmax**, **ReLU**, **GELU**.
13
- - **Loss Functions**: **CrossEntropy** loss calculation for training classification tasks.
14
- - **Attention & Positioning**: Built-in **Self-Attention** and **Positional Embedding** matrices.
15
- - **Text Processing**: Built-in **Tokenizer** to convert raw text into token IDs and back.
16
- - **Special Tokens**: Native support for `<PAD>` and `<EOS>`.
17
- - **FFN BLOCK**: It add a layer to understand Complex Patterns.
18
- - **GPU SUPPORT**: Now, The tensorloop can Do Math with GPU.
19
346
  ---
20
347
 
348
+ # πŸ”€ Tokenization
21
349
 
22
- ## πŸ— Core Architecture
350
+ Tensorloop can work with a custom tokenizer.
23
351
 
24
- ### Transformer Block
25
- The `TransformerBlock` encapsulates attention, layer normalization, and feed-forward networks into a single trainable module.
352
+ For example:
26
353
 
27
- ```typescript
28
- import { TransformerBlock } from '@mineproness/tensorloop'
354
+ ```js
355
+ const tokenizer = new Tokenizer("./vocab.json")
356
+ ```
29
357
 
30
- // Initialize the block with an embedding size and save directory
31
- const transformer = new TransformerBlock(1024, {
32
- dirname: "./model/transformer_layers"
33
- })
358
+ Encode text into token IDs:
34
359
 
35
- // Forward Pass: Processes an array of typed float arrays
36
- const output = transformer.forward(inputVectors)
360
+ ```js
361
+ const result = tokenizer.encoder(
362
+ "Hello world"
363
+ )
37
364
 
38
- // Backward Pass: Calculates gradients and updates weights using a learning rate
39
- const dInput = transformer.backward(dOutput, 0.001)
365
+ console.log(result.tokenIDs)
366
+ ```
40
367
 
41
- // Clear cache to free up system memory after an iteration
42
- transformer.clearInputCache()
368
+ The resulting token IDs can then be passed directly into the embedding layer:
43
369
 
44
- // Persist the transformer block weights to disk
45
- transformer.Save()
370
+ ```js
371
+ const vectors = await embedding.forward(
372
+ result.tokenIDs
373
+ )
46
374
  ```
47
375
 
376
+ This makes it possible to use your own tokenizer and vocabulary instead of requiring a predefined tokenizer.
377
+
48
378
  ---
49
379
 
50
- ## πŸ›  Configurations
380
+ # 🧩 Embedding
381
+
382
+ The `Embedding` layer converts token IDs into dense vectors.
383
+
384
+ Example:
385
+
386
+ ```js
387
+ const embedding = new Embedding(
388
+ device,
389
+ 64,
390
+ tokenizer.vocabSize
391
+ )
392
+ ```
393
+
394
+ Here:
395
+
396
+ ```text
397
+ 64
398
+ ```
399
+
400
+ is the embedding dimension.
401
+
402
+ For a vocabulary of `V` tokens, the embedding matrix contains:
403
+
404
+ ```text
405
+ V Γ— 64
406
+ ```
407
+
408
+ parameters.
409
+
410
+ Forward pass:
411
+
412
+ ```js
413
+ const vectors = await embedding.forward(tokens)
414
+ ```
415
+
416
+ ---
51
417
 
52
- You can configure saving mechanisms by passing a configuration object to the `Embedding` and `Linear` classes.
418
+ # 🧱 TransformerBlock
53
419
 
54
- ```javascript
55
- import { Embedding, Linear } from '@mineproness/tensorloop'
420
+ Transformer blocks combine the main components required for Transformer-based models.
56
421
 
57
- // Initialize an Embedding layer and auto-save the weights
58
- const embedding = new Embedding(1024, 2000, 16 {
59
- save: {
60
- filename: "./model/vectors.bin"
422
+ ```js
423
+ const block = new TransformerBlock(
424
+ device,
425
+ 64,
426
+ {
427
+ dirname: "./model/block1"
61
428
  }
62
- })
429
+ )
430
+ ```
431
+
432
+ Multiple blocks can be stacked:
433
+
434
+ ```js
435
+ vec = await block.forward(vec)
436
+
437
+ vec = await block1.forward(vec)
438
+
439
+ vec = await block2.forward(vec)
440
+ ```
441
+
442
+ And during training:
443
+
444
+ ```js
445
+ dInput = await block2.backward(
446
+ dInput,
447
+ lr
448
+ )
449
+
450
+ dInput = await block1.backward(
451
+ dInput,
452
+ lr
453
+ )
454
+
455
+ dInput = await block.backward(
456
+ dInput,
457
+ lr
458
+ )
459
+ ```
460
+
461
+ This allows Tensorloop to build deeper Transformer networks by stacking blocks.
462
+
463
+ ---
464
+
465
+ # 🎯 Linear Layer
466
+
467
+ The `Linear` layer projects the Transformer representation into vocabulary space.
468
+
469
+ ```js
470
+ const linear = new Linear(
471
+ device,
472
+ 64,
473
+ tokenizer.vocabSize
474
+ )
475
+ ```
476
+
477
+ For example:
478
+
479
+ ```text
480
+ Embedding size = 64
481
+ Vocabulary = 3,000
482
+
483
+ 64 β†’ 3,000
484
+ ```
485
+
486
+ The output contains one logit for every vocabulary token.
487
+
488
+ ---
489
+
490
+ # πŸ“Š Softmax
491
+
492
+ The `Softmax` layer converts logits into probabilities.
493
+
494
+ ```js
495
+ const probs = await softmax.forward(logits)
496
+ ```
497
+
498
+ The predicted probability distribution can then be evaluated using cross-entropy:
499
+
500
+ ```js
501
+ const { loss, acc } =
502
+ await softmax.crossEntropy(
503
+ probs,
504
+ targetTokens
505
+ )
506
+ ```
507
+
508
+ ---
509
+
510
+ # πŸ”„ Backpropagation
511
+
512
+ Tensorloop supports manually controlled backpropagation.
513
+
514
+ The gradients flow backwards through the network:
515
+
516
+ ```text
517
+ Softmax
518
+ ↓
519
+ Linear
520
+ ↓
521
+ TransformerBlock 3
522
+ ↓
523
+ TransformerBlock 2
524
+ ↓
525
+ TransformerBlock 1
526
+ ↓
527
+ Embedding
528
+ ```
529
+
530
+ In code:
531
+
532
+ ```js
533
+ const dLogits =
534
+ await softmax.backward(
535
+ probs,
536
+ targetIDX
537
+ )
538
+
539
+ let dInput =
540
+ await linear.backward(
541
+ dLogits,
542
+ lr
543
+ )
544
+
545
+ dInput =
546
+ await block2.backward(
547
+ dInput,
548
+ lr
549
+ )
550
+
551
+ dInput =
552
+ await block1.backward(
553
+ dInput,
554
+ lr
555
+ )
556
+
557
+ dInput =
558
+ await block.backward(
559
+ dInput,
560
+ lr
561
+ )
562
+
563
+ embedding.backward(
564
+ inputIDX,
565
+ dInput,
566
+ lr
567
+ )
568
+ ```
569
+
570
+ This gives you direct control over the training process.
571
+
572
+ ---
573
+
574
+ # ⚑ WebGPU
575
+
576
+ Tensorloop is designed around WebGPU.
577
+
578
+ Example:
579
+
580
+ ```js
581
+ import { create, globals } from "webgpu"
63
582
 
64
- // Initialize a Linear layer (requires an array to save Weights and Biases separately)
65
- const linear = new Linear(1024, 2000, {
66
- save: {
67
- filename: ["./model/Weights.bin", "./model/Bias.bin"]
583
+ Object.assign(globalThis, globals)
584
+
585
+ const navigator = {
586
+ gpu: create([
587
+ "adapter=NVIDIA GeForce 920M"
588
+ ])
589
+ }
590
+ ```
591
+
592
+ Then request the GPU device:
593
+
594
+ ```js
595
+ const adapter =
596
+ await navigator.gpu.requestAdapter()
597
+
598
+ const device =
599
+ await adapter.requestDevice()
600
+ ```
601
+
602
+ The device is passed to Tensorloop layers:
603
+
604
+ ```js
605
+ const embedding =
606
+ new Embedding(device, 64, vocabSize)
607
+
608
+ const linear =
609
+ new Linear(device, 64, vocabSize)
610
+
611
+ const block =
612
+ new TransformerBlock(device, 64)
613
+ ```
614
+
615
+ This lets the layers perform their GPU computations through WebGPU.
616
+
617
+ ---
618
+
619
+
620
+
621
+ # πŸ”€ Training the Tokenizer
622
+
623
+ Tensorloop includes a tokenizer that can learn a vocabulary directly from your dataset.
624
+
625
+ ```js
626
+ import fs from "fs"
627
+ import { Tokenizer } from "./index.js"
628
+
629
+ const tokenizer = new Tokenizer("./vocab.json")
630
+
631
+ tokenizer.trainTokenizer(
632
+ fs.readFileSync("./dataset.txt", "utf-8"),
633
+ 6,
634
+ "./vocab.json"
635
+ )
636
+ ```
637
+
638
+ ## `trainTokenizer()`
639
+
640
+ ```js
641
+ tokenizer.trainTokenizer(
642
+ text,
643
+ maxMergeLength,
644
+ outputPath
645
+ )
646
+ ```
647
+
648
+ | Parameter | Description |
649
+ | ---------------- | ---------------------------------------------------- |
650
+ | `text` | Training text used to build the tokenizer vocabulary |
651
+ | `maxMergeLength` | Maximum length used when creating token merges |
652
+ | `outputPath` | Location where the generated vocabulary is saved |
653
+
654
+ ### Example
655
+
656
+ ```js
657
+ tokenizer.trainTokenizer(
658
+ fs.readFileSync("./dataset.txt", "utf-8"),
659
+ 6,
660
+ "./vocab.json"
661
+ )
662
+ ```
663
+
664
+ Here:
665
+
666
+ ```text
667
+ 6
668
+ ```
669
+
670
+ is the **maximum merge length**.
671
+
672
+ The tokenizer learns merges from the dataset and saves the resulting vocabulary to:
673
+
674
+ ```text
675
+ vocab.json
676
+ ```
677
+
678
+ ### Tokenizer Workflow
679
+
680
+ ```text
681
+ dataset.txt
682
+ β”‚
683
+ β–Ό
684
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
685
+ β”‚ trainTokenizer()β”‚
686
+ β”‚ β”‚
687
+ β”‚ maxMergeLength=6β”‚
688
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
689
+ β”‚
690
+ β–Ό
691
+ vocab.json
692
+ β”‚
693
+ β–Ό
694
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
695
+ β”‚ Tokenizer β”‚
696
+ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
697
+ β”‚
698
+ β–Ό
699
+ tokenizer.encoder()
700
+ β”‚
701
+ β–Ό
702
+ Token IDs
703
+ ```
704
+
705
+ Once the vocabulary has been created, load it with:
706
+
707
+ ```js
708
+ const tokenizer = new Tokenizer("./vocab.json")
709
+ ```
710
+
711
+ Then encode text:
712
+
713
+ ```js
714
+ const result = tokenizer.encoder(
715
+ "Hello world"
716
+ )
717
+
718
+ console.log(result.tokenIDs)
719
+ ```
720
+
721
+ The resulting token IDs can be passed directly into Tensorloop's embedding layer:
722
+
723
+ ```js
724
+ const vectors = await embedding.forward(
725
+ result.tokenIDs
726
+ )
727
+ ```
728
+
729
+ This allows you to create a tokenizer vocabulary from your own dataset and then use that vocabulary for Transformer training.
730
+
731
+
732
+ ---
733
+
734
+
735
+
736
+
737
+ # πŸ’Ύ Saving Models
738
+
739
+ Tensorloop layers can save their parameters to files.
740
+
741
+ Embedding:
742
+
743
+ ```js
744
+ const embedding = new Embedding(
745
+ device,
746
+ 64,
747
+ vocabSize,
748
+ {
749
+ save: {
750
+ filename: "model/vec.bin"
751
+ }
752
+ }
753
+ )
754
+ ```
755
+
756
+ Linear:
757
+
758
+ ```js
759
+ const linear = new Linear(
760
+ device,
761
+ 64,
762
+ vocabSize,
763
+ {
764
+ save: {
765
+ filename: [
766
+ "./model/bias.bin",
767
+ "./model/weights.bin"
768
+ ]
769
+ }
770
+ }
771
+ )
772
+ ```
773
+
774
+ Transformer blocks can use their own directories:
775
+
776
+ ```js
777
+ const block = new TransformerBlock(
778
+ device,
779
+ 64,
780
+ {
781
+ dirname: "./model/block1"
68
782
  }
69
- })
783
+ )
70
784
  ```
71
785
 
72
- > πŸ“Œ **Note:** The `Linear` layer requires a two-element filename array to separate the Weights and Bias files. Always use the `.bin` extension.
786
+ A model can therefore be organized like:
787
+
788
+ ```text
789
+ model/
790
+ β”œβ”€β”€ vec.bin
791
+ β”œβ”€β”€ weights.bin
792
+ β”œβ”€β”€ bias.bin
793
+ β”‚
794
+ β”œβ”€β”€ block1/
795
+ β”‚ β”œβ”€β”€ ...
796
+ β”‚
797
+ β”œβ”€β”€ block2/
798
+ β”‚ β”œβ”€β”€ ...
799
+ β”‚
800
+ └── block3/
801
+ β”œβ”€β”€ ...
802
+ ```
73
803
 
74
804
  ---
75
805
 
76
- ## ⚑ Optimizations
806
+ # πŸ§ͺ Example Model Configuration
807
+
808
+ The example above uses:
809
+
810
+ | Component | Configuration |
811
+ | ------------------- | --------------------------: |
812
+ | Embedding dimension | 64 |
813
+ | Context length | 24 |
814
+ | Transformer blocks | 3 |
815
+ | Vocabulary | `tokenizer.vocabSize` |
816
+ | Learning rate | 0.02 |
817
+ | Training pairs | 8,000 |
818
+ | Epochs | 100 |
819
+ | Optimizer | SGD-style parameter updates |
820
+
821
+ The vocabulary size is determined dynamically from the tokenizer:
822
+
823
+ ```js
824
+ tokenizer.vocabSize
825
+ ```
77
826
 
78
- - **Float32Array Powered**: Built on top of native typed arrays for maximum numerical performance and low memory overhead.
79
- - **Heavy Workloads**: Easily handles large scaling operations, including dense 1024 embedding sizes.
80
- - **Vanilla JavaScript**: Written entirely in raw JavaScript to eliminate bloated dependencies and optimize V8 execution.
827
+ So the same architecture can be used with different vocabulary sizes.
81
828
 
82
829
  ---
83
830
 
84
- ## πŸ”€ Tokenizer
831
+ # πŸ“ Example Project
832
+
833
+ A simple project can look like:
834
+
835
+ ```text
836
+ my-model/
837
+ β”‚
838
+ β”œβ”€β”€ dataset.txt
839
+ β”œβ”€β”€ vocab.json
840
+ β”œβ”€β”€ train.js
841
+ β”‚
842
+ └── model/
843
+ β”œβ”€β”€ vec.bin
844
+ β”œβ”€β”€ weights.bin
845
+ β”œβ”€β”€ bias.bin
846
+ β”‚
847
+ β”œβ”€β”€ block1/
848
+ β”œβ”€β”€ block2/
849
+ └── block3/
850
+ ```
851
+
852
+ Run training with:
853
+
854
+ ```bash
855
+ node train.js
856
+ ```
85
857
 
86
- The tokenizer splits raw text strings into token IDs, which can then be fully decoded back into human-readable text.
858
+ ---
87
859
 
88
- ### Example Usage:
860
+ # πŸ› οΈ Design Philosophy
89
861
 
90
- ```javascript
91
- import { Tokenizer } from '@mineproness/tensorloop'
862
+ Tensorloop is intended to make the internals of neural networks accessible from JavaScript.
92
863
 
93
- const tokenizer = new Tokenizer()
94
- const text = "Hello, Welcome to My Channel."
864
+ Instead of hiding everything behind a single high-level training function, Tensorloop exposes the individual operations:
95
865
 
96
- // Encode text to token IDs
97
- const { tokenIDs } = tokenizer.encoder(text)
98
- console.log(tokenIDs) // Output example: ["hello", "$12", "well", "come", "$130"...]
866
+ ```js
867
+ embedding.forward()
868
+ transformer.forward()
869
+ linear.forward()
870
+ softmax.forward()
99
871
 
100
- // Decode token IDs back to text
101
- const decoded = tokenizer.decoder(tokenIDs)
102
- console.log(decoded) // Output: "Hello, Welcome to My Channel."
872
+ softmax.backward()
873
+ linear.backward()
874
+ transformer.backward()
875
+ embedding.backward()
103
876
  ```
104
877
 
878
+ This makes it useful for:
879
+
880
+ * Learning how neural networks work
881
+ * Experimenting with Transformer architectures
882
+ * Building small language models
883
+ * WebGPU experiments
884
+ * GPU programming experiments
885
+ * Creating custom neural-network layers
886
+ * Understanding forward and backward propagation
887
+
105
888
  ---
106
889
 
107
- ## πŸ’‘ Best Practices & Suggestions
890
+ # 🧠 Building an LLM From Scratch
891
+
892
+ Tensorloop can be used as a foundation for experimenting with GPT-style language models.
893
+
894
+ A simplified training pipeline is:
895
+
896
+ ```text
897
+ Dataset
898
+ β”‚
899
+ β–Ό
900
+ Tokenizer
901
+ β”‚
902
+ β–Ό
903
+ Token IDs
904
+ β”‚
905
+ β–Ό
906
+ Embedding
907
+ β”‚
908
+ β–Ό
909
+ Transformer Blocks
910
+ β”‚
911
+ β–Ό
912
+ Linear Projection
913
+ β”‚
914
+ β–Ό
915
+ Softmax
916
+ β”‚
917
+ β–Ό
918
+ Cross Entropy
919
+ β”‚
920
+ β–Ό
921
+ Backpropagation
922
+ β”‚
923
+ └──────────────► Update weights
924
+ ```
108
925
 
109
- ### 1. Use TypeScript
110
- We highly recommend using **TypeScript** with TensorLoop to enforce type safety and leverage IDE autocomplete features for all active classes and methods.
926
+ The architecture can then be expanded with additional Transformer blocks, larger embeddings, larger vocabularies, and other normalization or optimization techniques.
111
927
 
112
928
  ---
113
929
 
114
- ### 2. Always use NodeJS 20 Higher
115
- This Package optimized for node js 20 or higher. If you use older version it Maybe Break Easliy.
930
+ # πŸ”¬ Experimental
931
+
932
+ Tensorloop is still an experimental project.
933
+
934
+ The API and internal implementation may change as new features are added.
935
+
936
+ The project is primarily intended for experimentation, learning, and building custom GPU-accelerated neural-network systems.
937
+
938
+ ---
939
+
940
+ # πŸ“œ License
941
+
942
+
943
+
944
+ MIT License
945
+
946
+
947
+ ---
948
+
949
+ ## πŸ‘¨β€πŸ’» Author
950
+
951
+ Created by **mineproness**.
952
+
953
+ Tensorloop is part of the broader **@mineproness** ecosystem of JavaScript AI/ML experiments.
116
954
 
117
955
  ---
118
- ### 3. Use GELU Always.
119
-
120
- Gelu is Better Activation because it is not turn a gradient 0 so it is so smoothly works.
121
956
 
122
- ## ⭐ Support the Project
957
+ # ⭐ If you find Tensorloop interesting
123
958
 
124
- Thank you for visiting! If you find this library useful for your AI or LLM workflows, please consider giving us a star on **[GitHub](https://github.com/mineproness-org/tensorloop)**!
959
+ Give the project a star ⭐ and experiment with building your own neural networks and Transformer models directly in JavaScript.