@mineproness/tensorloop 1.0.0

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.
package/index.js ADDED
@@ -0,0 +1,10 @@
1
+ import { Tokenizer as tokenizer } from "./src/Tokenizer/index.js";
2
+ import { Embedding as embeddding2 } from "./src/Embedding/index.js";
3
+ import { Linear as li2 } from "./src/Linear/index.js";
4
+ import { Softmax as softmax2 } from "./src/Softmax/index.js";
5
+ import { crossEntropy } from "./src/crossEntropy/index.js";
6
+ export const Tokenizer = tokenizer
7
+ export const Embedding = embeddding2
8
+ export const Linear = li2
9
+ export const Softmax = softmax2
10
+ export const CrossEntropy = crossEntropy
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@mineproness/tensorloop",
3
+ "version": "1.0.0",
4
+ "description": "The most powerfull Machine Learing Libeary for AI.",
5
+ "keywords": [
6
+ "ai",
7
+ "llm",
8
+ "Large",
9
+ "Language",
10
+ "model",
11
+ "Small",
12
+ "Language",
13
+ "Model"
14
+ ],
15
+ "license": "MIT",
16
+ "author": "mineproness",
17
+ "type": "module",
18
+ "main": "index.js",
19
+ "scripts": {
20
+ "test": "echo \"Error: no test specified\" && exit 1"
21
+ }
22
+ }
@@ -0,0 +1,10 @@
1
+ export class Embedding{
2
+ vectors: Float32Array[]
3
+ constructor(embeddingSize: number, vocabSize: number, configs: {
4
+ save: {
5
+ filename: string
6
+ }
7
+ })
8
+ forward(token: number | number[]) : number[] | number[][]
9
+ backward(token: number , inputGradient: number[], learingRate: number) : void
10
+ }
@@ -0,0 +1,48 @@
1
+ import fs, { existsSync } from 'fs'
2
+ import { GetVectors, SaveVectors } from '../GetConfigs.js'
3
+ // import { config } from 'process'
4
+
5
+ function GenerateVectors(embeddingSize, vocabSize) {
6
+ const vector = []
7
+ for (let token = 0; token < vocabSize; token++) {
8
+ vector[token] = new Float32Array(embeddingSize)
9
+ for (let a = 0; a < embeddingSize; a++) {
10
+ vector[token][a] = (Math.random() * 2 - 1) * 0.2
11
+ }
12
+ }
13
+ return vector
14
+ }
15
+
16
+ export class Embedding {
17
+ vectors = []
18
+ configs;
19
+ constructor(embeddingSize, vocabSize, configs) {
20
+ this.configs = configs
21
+ if (configs && configs.save) {
22
+ if (existsSync(configs.save.filename)) {
23
+ this.vectors = GetVectors(configs.save.filename, embeddingSize)
24
+ } else {
25
+ this.vectors = GenerateVectors(embeddingSize, vocabSize)
26
+ SaveVectors(configs.save.filename, this.vectors)
27
+ }
28
+ } else {
29
+ this.vectors = GenerateVectors(embeddingSize, vocabSize)
30
+
31
+ }
32
+ }
33
+ forward(token) {
34
+ if(Array.isArray(token)){
35
+ return token.map((e)=> this.vectors[e])
36
+ }else{
37
+ return this.vectors[token]
38
+ }
39
+ }
40
+ backward(token, inputGradient, learingRate){
41
+ for(let a = 0; a < this.vectors[token].length; a++){
42
+ this.vectors[token][a] -= learingRate * inputGradient[a]
43
+ }
44
+ }
45
+ Save(){
46
+ SaveVectors(this.configs.save.filename , this.vectors)
47
+ }
48
+ }
@@ -0,0 +1,35 @@
1
+ import fs from "fs";
2
+ import { join } from "path";
3
+
4
+ export function SaveVectors (filename, vectors){
5
+ const sizeOfArray = vectors.length;
6
+ const sizeOfEmbedding = vectors[0].length;
7
+ const floatArray = vectors.map((e)=> Buffer.from(e.buffer))
8
+ const combinedBuffer = Buffer.concat(floatArray)
9
+ fs.writeFileSync(filename , combinedBuffer)
10
+
11
+ }
12
+
13
+ export function GetVectors(filename, embeddingSize){
14
+ const fileBuffer = fs.readFileSync(filename)
15
+ const ELEMENTS_PER_ARRAY= embeddingSize;
16
+ const BYTES_PER_ELEMENT= Float32Array.BYTES_PER_ELEMENT
17
+ const BYTES_PER_ARRAY = ELEMENTS_PER_ARRAY * BYTES_PER_ELEMENT
18
+ const totalArraySaved = fileBuffer.byteLength / BYTES_PER_ARRAY;
19
+ const totalArray = []
20
+ for(let i = 0; i < totalArraySaved; i++){
21
+ const currentOffset = fileBuffer.byteOffset + (i * BYTES_PER_ARRAY)
22
+ const f32 = new Float32Array(fileBuffer.buffer, currentOffset, ELEMENTS_PER_ARRAY)
23
+ totalArray.push(f32)
24
+ }
25
+ return totalArray
26
+ }
27
+
28
+ export function GetVector(filename){
29
+ const buffer = fs.readFileSync(filename)
30
+ return new Float32Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Float32Array.BYTES_PER_ELEMENT)
31
+ }
32
+
33
+ export function Save(filename, vector){
34
+ return fs.writeFileSync(filename, Buffer.from(vector.buffer))
35
+ }
@@ -0,0 +1,11 @@
1
+ export class Linear{
2
+ Weights : Float32Array[]
3
+ Bias: Float32Array
4
+ constructor(embeddingSize : number, vocabSize : number, configs: {
5
+ save: {
6
+ filename: string[]
7
+ }
8
+ })
9
+ forward(input : number[]) : number[]
10
+ backward(outGradient : number[] , learingRate: number) : number[]
11
+ }
@@ -0,0 +1,69 @@
1
+ import { GetVector, GetVectors, Save, SaveVectors } from '../GetConfigs.js'
2
+ import { existsSync } from 'fs'
3
+ function GenerateWeightsBias(embeddingSize, vocabSize) {
4
+ const vectors = []
5
+ const Bias = new Float32Array(vocabSize)
6
+ for (let a = 0; a < vocabSize; a++) {
7
+ vectors[a] = new Float32Array(embeddingSize)
8
+ for (let t = 0; t < embeddingSize; t++) {
9
+ vectors[a][t] = (Math.random() * 2 - 1) * 0.02
10
+ }
11
+ Bias[a] = 0
12
+ }
13
+ return { vectors, Bias }
14
+ }
15
+
16
+ export class Linear {
17
+ Weights = []
18
+ Bias = []
19
+ configs;
20
+ input = [];
21
+ constructor(embeddingSize, vocabSize, configs) {
22
+ if (configs && configs.save) {
23
+ this.configs = configs
24
+ if (existsSync(configs.save.filename[0]) && existsSync(configs.save.filename[1])) {
25
+ const Vectors = GetVectors(configs.save.filename[0], embeddingSize)
26
+ const Bias = GetVector(configs.save.filename[1])
27
+ this.Weights = Vectors;
28
+ this.Bias = Bias
29
+ } else {
30
+ const { vectors, Bias } = GenerateWeightsBias(embeddingSize, vocabSize)
31
+ this.Weights = vectors;
32
+ this.Bias = Bias;
33
+ SaveVectors(configs.save.filename[0], this.Weights)
34
+ Save(configs.save.filename[1], this.Bias)
35
+ }
36
+ } else {
37
+ const { vectors, Bias } = GenerateWeightsBias(embeddingSize, vocabSize)
38
+ this.Weights = vectors;
39
+ this.Bias = Bias;
40
+ }
41
+ }
42
+ Save() {
43
+ SaveVectors(this.configs.save.filename[0], this.Weights)
44
+ Save(this.configs.save.filename[1], this.Bias)
45
+ }
46
+ forward(input) {
47
+ this.input = input
48
+ const output = []
49
+ for (let a = 0; a < this.Weights.length; a++) {
50
+ let sum = this.Bias[a]
51
+ for (let t = 0; t < input.length; t++) {
52
+ sum += input[t] * this.Weights[a][t]
53
+ }
54
+ output.push(sum)
55
+ }
56
+ return output
57
+ }
58
+ backward(outputGradient, learningRate) {
59
+ const inputGradient = new Float32Array(this.input.length)
60
+ for (let a = 0; a < this.Weights.length; a++) {
61
+ for (let at = 0; at < this.input.length; at++) {
62
+ inputGradient[at] += outputGradient[a] * this.Weights[a][at]
63
+ this.Weights[a][at] -= learningRate * this.input[at] * outputGradient[a]
64
+ }
65
+ this.Bias[a] -= learningRate * outputGradient[a]
66
+ }
67
+ return inputGradient
68
+ }
69
+ }
@@ -0,0 +1,14 @@
1
+ export class ReLU{
2
+ input;
3
+ forward(XLi){
4
+ this.input = XLi
5
+ return XLi.map((e)=> e > 0 ? e : 0)
6
+ }
7
+ backward(outputGradient){
8
+ const inputGradient = new Float32Array(this.input.length)
9
+ for(let i = 0; i < outputGradient.length; i++){
10
+ inputGradient[i] = this.input[i] > 0 ? outputGradient[i] : 0
11
+ }
12
+ return inputGradient
13
+ }
14
+ }
@@ -0,0 +1,4 @@
1
+ export class Softmax{
2
+ forward(xLi : number[]) : number[]
3
+ backward(probalitils: number[] , target : number) : number[]
4
+ }
@@ -0,0 +1,13 @@
1
+ export class Softmax{
2
+ forward(xLi){
3
+ const max = Math.max(...xLi)
4
+ const exp = xLi.map((e)=> Math.exp(e - max))
5
+ const sum = exp.reduce((a,b)=> a + b , 0)
6
+ return exp.map((e)=> e / sum)
7
+ }
8
+ backward(probs , target){
9
+ const pro = [...probs]
10
+ pro[target] -= 1
11
+ return pro
12
+ }
13
+ }
@@ -0,0 +1,11 @@
1
+ export class Tokenizer{
2
+ vocabs : string[]
3
+ vocabSize: number
4
+ IdtoWord : Record<string, string>
5
+ WordtoID : Record<string , number>
6
+ encoder(text: string) : {
7
+ tokens: string[]
8
+ tokenIDs: number[]
9
+ }
10
+ decoder(tokens: number[] | number[][]) : string
11
+ }
@@ -0,0 +1,92 @@
1
+ import { readFileSync } from 'fs'
2
+ import { join, dirname, format } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const __dirname = dirname(fileURLToPath(import.meta.url))
6
+ export class Tokenizer {
7
+ vocabs = [];
8
+ vocabSize = 0;
9
+ IdtoWord = {};
10
+ WordtoID = {};
11
+ constructor() {
12
+ this.vocabs = JSON.parse(readFileSync(join(__dirname, "vocabs.json"), "utf-8"))
13
+ this.vocabSize = this.vocabs.length
14
+ this.IdtoWord = Object.fromEntries(this.vocabs.map((e, idx) => [idx, e]))
15
+ this.WordtoID = Object.fromEntries(this.vocabs.map((e, idx) => [e, idx]))
16
+ }
17
+ encoder(text = "") {
18
+ const AddSpaces = text.toLocaleLowerCase().replaceAll(/([,.;'{}`~\|":><?])/g, " $1 ")
19
+ const splitedWords = AddSpaces.split(/\s+/).filter(e => e.length > 0)
20
+ const output = []
21
+ for (let a = 0; a < splitedWords.length; a++) {
22
+ const word = splitedWords[a]
23
+ if (this.WordtoID[word]) {
24
+ output.push(word)
25
+ } else {
26
+ let max = word.length
27
+ output.push("$12")
28
+ while (true) {
29
+ const regPatten = new RegExp(`.{0,${max}}`, "g")
30
+ const wordsliced = word.match(regPatten).filter((e) => e.length > 0)
31
+ const matched = wordsliced.flatMap(e => {
32
+ if (this.WordtoID[e]) {
33
+ return true
34
+ }
35
+ return false
36
+ }).reduce((prev, curr) => prev && curr)
37
+ if (matched) {
38
+ wordsliced.map((e) => output.push(e))
39
+ output.push("$130")
40
+ break
41
+ } else {
42
+ max -= 1
43
+ // break
44
+ }
45
+
46
+ }
47
+ }
48
+ }
49
+ return { tokens: output, tokenIDs: output.map((e) => this.WordtoID[e]) }
50
+ }
51
+ decoder(tokens = [1, 2, 3]) {
52
+ const output = []
53
+ let isSpace = false
54
+ // let index = 0
55
+ for (let token of tokens) {
56
+ const formated = this.IdtoWord[String(token)]
57
+ if (formated == "$12") {
58
+ output[output.length] = ""
59
+ isSpace = true
60
+ } else if (formated == "$130") {
61
+ isSpace = false
62
+ } else {
63
+ if (isSpace) {
64
+ output[output.length - 1] += formated
65
+ } else {
66
+ output.push(formated)
67
+ }
68
+ }
69
+ }
70
+ return Validate(output).join(" ").replaceAll(/\s+([,.;'{}`~\|":><?])/g, "$1")
71
+ }
72
+ }
73
+
74
+
75
+ function Validate(output = ["hello", "guys"]) {
76
+ const bestOutput = []
77
+ output.map((e, idx) => {
78
+ if (idx == 0) {
79
+ bestOutput[idx] = e[0].toLocaleUpperCase() + e.slice(1, e.length)
80
+ } else {
81
+ if (bestOutput[idx - 1] == ":" || bestOutput[idx - 1] == ".") {
82
+
83
+ bestOutput[idx] = e[0].toLocaleUpperCase() + e.slice(1, e.length)
84
+ } else {
85
+ bestOutput[idx] = e
86
+
87
+ }
88
+ }
89
+
90
+ })
91
+ return bestOutput
92
+ }