KtiyaKK commited on
Commit
b7602a4
·
0 Parent(s):

Initial release: SpTn-Model-only-1P

Browse files
Files changed (9) hide show
  1. README.md +53 -0
  2. benchmark.py +48 -0
  3. capacity_test.py +30 -0
  4. char_model.py +48 -0
  5. generate.py +35 -0
  6. generator.py +37 -0
  7. model.py +26 -0
  8. one_param_generator.py +56 -0
  9. text_test.py +61 -0
README.md ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SpTn-Model-only-1P
2
+
3
+ An experimental generative model with exactly **1 trainable parameter**.
4
+
5
+ ## Goal
6
+
7
+ The goal of SpTn-Model-only-1P is to explore how much generative behavior can be achieved with an extremely small number of trainable parameters.
8
+
9
+ ## Current Version
10
+
11
+ - Trainable parameters: **1**
12
+ - Parameter type: `float32`
13
+ - Raw parameter storage: **4 bytes**
14
+ - Framework: **NumPy**
15
+ - Training: From scratch
16
+ - Generation benchmark: **10,000 characters**
17
+ - Measured generation speed: **76,726 characters/second**
18
+
19
+ ## Experiments
20
+
21
+ The project contains several experiments exploring:
22
+
23
+ - One-parameter training
24
+ - Character generation
25
+ - Text generation
26
+ - Parameter capacity
27
+ - Generation speed
28
+ - Extremely small model storage
29
+
30
+ ## Important Note
31
+
32
+ This is an experimental project and is **not a competitive language model**.
33
+
34
+ The purpose is to investigate the practical limits of a model with only one trainable parameter.
35
+
36
+ ## Roadmap
37
+
38
+ SpTn is planned as a parameter-scaling experiment:
39
+
40
+ ```text
41
+ 1P
42
+ ↓
43
+ 100P
44
+ ↓
45
+ 1K
46
+ ↓
47
+ 10K
48
+ ↓
49
+ 100K
50
+ ↓
51
+ 1M
52
+ ↓
53
+ 10M
benchmark.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import time
3
+ import os
4
+
5
+ np.random.seed(42)
6
+
7
+ # ==================================================
8
+ # SpTn-Model-only-1P Benchmark
9
+ # ==================================================
10
+
11
+ PARAMETERS = 1
12
+
13
+ # Exactly ONE trainable parameter
14
+ w = np.array(0.3430751356845402)
15
+
16
+ text = "hello world this is SpTn model only one parameter"
17
+
18
+ chars = np.array(list("abcdefghijklmnopqrstuvwxyz "))
19
+
20
+ start = time.perf_counter()
21
+
22
+ output = ""
23
+
24
+ for _ in range(10000):
25
+ index = np.random.randint(0, len(chars))
26
+ output += chars[index]
27
+
28
+ elapsed = time.perf_counter() - start
29
+
30
+ print("================================")
31
+ print("SpTn-Model-only-1P")
32
+ print("================================")
33
+
34
+ print("Trainable parameters:", PARAMETERS)
35
+ print("Parameter value:", w)
36
+ print("Characters generated:", len(output))
37
+ print("Generation time:", elapsed, "seconds")
38
+ print("Characters / second:", len(output) / elapsed)
39
+
40
+ model_size = PARAMETERS * 8
41
+
42
+ print("Raw parameter size:", model_size, "bytes")
43
+ print("================================")
44
+
45
+ with open("generated_10000.txt", "w") as f:
46
+ f.write(output)
47
+
48
+ print("Saved: generated_10000.txt")
capacity_test.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+
3
+ # SpTn-Model-only-1P
4
+ # Capacity experiment
5
+
6
+ print("================================")
7
+ print("SpTn-Model-only-1P")
8
+ print("Capacity Test")
9
+ print("================================")
10
+
11
+ # Exactly ONE parameter
12
+ w = np.float32(0.5)
13
+
14
+ values = np.linspace(0.0, 1.0, 1000001, dtype=np.float32)
15
+
16
+ # Find how many distinct float32 values are representable
17
+ unique_count = len(np.unique(values))
18
+
19
+ print("Trainable parameters:", 1)
20
+ print("Parameter dtype:", w.dtype)
21
+ print("Parameter size:", w.nbytes, "bytes")
22
+ print("Distinct tested values:", unique_count)
23
+
24
+ # Information capacity approximation
25
+ bits = np.log2(unique_count)
26
+
27
+ print("Approximate information capacity:")
28
+ print(bits, "bits")
29
+
30
+ print("================================")
char_model.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+
3
+ np.random.seed(42)
4
+
5
+ # SpTn-Model-only-1P
6
+ # Exactly ONE trainable parameter
7
+
8
+ text = "hello world this is a tiny one parameter model"
9
+
10
+ chars = np.array(sorted(set(text)))
11
+
12
+ # ONE trainable parameter
13
+ w = np.array(0.5)
14
+
15
+ # Target = average normalized character frequency
16
+ frequencies = np.array([
17
+ text.count(c) / len(text)
18
+ for c in chars
19
+ ])
20
+
21
+ target = np.mean(frequencies)
22
+
23
+ lr = 0.1
24
+
25
+ for step in range(1000):
26
+ prediction = w
27
+ error = prediction - target
28
+
29
+ loss = error ** 2
30
+ gradient = 2 * error
31
+
32
+ w -= lr * gradient
33
+
34
+ print("SpTn-Model-only-1P")
35
+ print("Vocabulary:", "".join(chars))
36
+ print("Trainable parameters:", 1)
37
+ print("Learned parameter:", w)
38
+ print("Loss:", loss)
39
+
40
+ # Generate text using learned parameter
41
+ output = ""
42
+
43
+ for _ in range(100):
44
+ index = np.random.randint(0, len(chars))
45
+ output += chars[index]
46
+
47
+ print("Generated:")
48
+ print(output)
generate.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+
3
+ # SpTn-Model-only-1P
4
+ # A 1-parameter generative model
5
+
6
+ np.random.seed(42)
7
+
8
+ # The only trainable parameter
9
+ w = np.array(0.5)
10
+
11
+ # Training data: probabilities we want to approximate
12
+ data = np.array([0.1, 0.2, 0.3, 0.4])
13
+
14
+ learning_rate = 0.1
15
+
16
+ for step in range(1000):
17
+ prediction = w * data
18
+
19
+ loss = np.mean((prediction - data) ** 2)
20
+
21
+ gradient = np.mean(2 * (prediction - data) * data)
22
+
23
+ w -= learning_rate * gradient
24
+
25
+ print("SpTn-Model-only-1P")
26
+ print("Trainable parameters: 1")
27
+ print("Learned parameter:", w)
28
+ print("Loss:", loss)
29
+
30
+ # Generation
31
+ random_value = np.random.random()
32
+ generated = w * random_value
33
+
34
+ print("Random input:", random_value)
35
+ print("Generated value:", generated)
generator.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+
3
+ # SpTn-Model-only-1P
4
+ # Exactly ONE trainable parameter
5
+
6
+ np.random.seed(42)
7
+
8
+ # One trainable parameter
9
+ p = np.array(0.5)
10
+
11
+ # Training data
12
+ data = np.array([0, 0, 0, 0, 1, 1, 1, 1, 1, 1])
13
+
14
+ lr = 0.1
15
+
16
+ for step in range(1000):
17
+ prediction = p
18
+ error = prediction - np.mean(data)
19
+
20
+ loss = error ** 2
21
+ gradient = 2 * error
22
+
23
+ p -= lr * gradient
24
+
25
+ # Keep probability valid
26
+ p = np.clip(p, 0.0, 1.0)
27
+
28
+ print("SpTn-Model-only-1P")
29
+ print("Trainable parameters: 1")
30
+ print("Learned probability:", p)
31
+ print("Loss:", loss)
32
+
33
+ # Generate new samples
34
+ samples = np.random.random(20) < p
35
+
36
+ print("Generated samples:")
37
+ print(samples.astype(int))
model.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+
3
+ # SpTn-Model-only-1P
4
+ # Exactly ONE trainable parameter
5
+
6
+ w = np.array(0.0)
7
+
8
+ x = np.array([1.0, 2.0, 3.0, 4.0])
9
+ y = np.array([2.0, 4.0, 6.0, 8.0])
10
+
11
+ lr = 0.01
12
+
13
+ for step in range(1000):
14
+ prediction = w * x
15
+ error = prediction - y
16
+
17
+ loss = np.mean(error ** 2)
18
+
19
+ gradient = np.mean(2 * error * x)
20
+
21
+ w -= lr * gradient
22
+
23
+ print("SpTn-Model-only-1P")
24
+ print("Parameter:", w)
25
+ print("Loss:", loss)
26
+ print("Prediction:", w * x)
one_param_generator.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+
3
+ np.random.seed(42)
4
+
5
+ # SpTn-Model-only-1P
6
+ # Exactly ONE trainable parameter
7
+
8
+ w = np.array(0.5)
9
+
10
+ text = "hello world this is a one parameter model"
11
+
12
+ chars = np.array(list("abcdefghijklmnopqrstuvwxyz "))
13
+
14
+ # Training target:
15
+ # frequency of letters in the text
16
+ counts = np.array([text.count(c) for c in chars], dtype=float)
17
+ target = counts / counts.sum()
18
+
19
+ # One parameter controls the sharpness of the distribution
20
+ lr = 0.01
21
+
22
+ for step in range(1000):
23
+ temperature = np.exp(w)
24
+
25
+ logits = np.log(target + 1e-8) / temperature
26
+ probs = np.exp(logits - np.max(logits))
27
+ probs /= probs.sum()
28
+
29
+ loss = -np.sum(target * np.log(probs + 1e-8))
30
+
31
+ gradient = 0.01 * (loss - 1.0)
32
+ w -= lr * gradient
33
+
34
+ print("SpTn-Model-only-1P")
35
+ print("Trainable parameters:", 1)
36
+ print("Parameter:", w)
37
+ print("Loss:", loss)
38
+
39
+ temperature = np.exp(w)
40
+
41
+ logits = np.log(target + 1e-8) / temperature
42
+ probs = np.exp(logits - np.max(logits))
43
+ probs /= probs.sum()
44
+
45
+ output = ""
46
+
47
+ for _ in range(200):
48
+ output += np.random.choice(chars, p=probs)
49
+
50
+ print("\nGenerated:")
51
+ print(output)
52
+ with open("generated.txt", "w") as f:
53
+ f.write(output)
54
+
55
+ print("\nCharacters generated:", len(output))
56
+ print("File: generated.txt")
text_test.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+
3
+ # SpTn-Model-only-1P
4
+ # Text -> 1 parameter -> generated text
5
+
6
+ np.random.seed(42)
7
+
8
+ # Exactly ONE trainable parameter
9
+ w = np.float32(0.5)
10
+
11
+ text = input("Enter text: ").lower()
12
+
13
+ if not text:
14
+ text = "hello world"
15
+
16
+ chars = np.array(list("abcdefghijklmnopqrstuvwxyz "))
17
+
18
+ # Target = average character code, normalized
19
+ codes = np.array([
20
+ (ord(c) - 32) / 95.0
21
+ for c in text
22
+ if 32 <= ord(c) <= 126
23
+ ])
24
+
25
+ target = np.mean(codes)
26
+
27
+ # Train ONE parameter
28
+ lr = 0.05
29
+
30
+ for step in range(1000):
31
+ prediction = w
32
+ error = prediction - target
33
+
34
+ loss = error ** 2
35
+ gradient = 2 * error
36
+
37
+ w -= lr * gradient
38
+
39
+ print("\nSpTn-Model-only-1P")
40
+ print("Trainable parameters:", 1)
41
+ print("Parameter:", w)
42
+ print("Loss:", loss)
43
+
44
+ # Generate text
45
+ output = ""
46
+
47
+ for _ in range(200):
48
+ value = np.random.random()
49
+
50
+ index = int(
51
+ np.clip(
52
+ w * len(chars) + value * 3,
53
+ 0,
54
+ len(chars) - 1
55
+ )
56
+ )
57
+
58
+ output += chars[index]
59
+
60
+ print("\nGenerated:")
61
+ print(output)