pytensorforge 0.1.0__py3-none-any.whl

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 (146) hide show
  1. cli.py +604 -0
  2. pytensorforge-0.1.0.dist-info/METADATA +103 -0
  3. pytensorforge-0.1.0.dist-info/RECORD +146 -0
  4. pytensorforge-0.1.0.dist-info/WHEEL +5 -0
  5. pytensorforge-0.1.0.dist-info/entry_points.txt +2 -0
  6. pytensorforge-0.1.0.dist-info/top_level.txt +2 -0
  7. src/__init__.py +0 -0
  8. src/activations/Activation.py +4 -0
  9. src/activations/ELU.py +11 -0
  10. src/activations/GELU.py +6 -0
  11. src/activations/ReLU.py +27 -0
  12. src/activations/SELU.py +14 -0
  13. src/activations/Sigmoid.py +27 -0
  14. src/activations/Softmax.py +84 -0
  15. src/activations/Tanh.py +29 -0
  16. src/activations/__init__.py +17 -0
  17. src/config.py +120 -0
  18. src/core/Matrix.py +3 -0
  19. src/core/Scalar.py +18 -0
  20. src/core/Tensor.py +866 -0
  21. src/core/Vector.py +31 -0
  22. src/core/__init__.py +0 -0
  23. src/data/__init__.py +0 -0
  24. src/data/chat_dataset.py +188 -0
  25. src/data/corpus.py +104 -0
  26. src/data/document_stream.py +178 -0
  27. src/data/parallel_encode.py +86 -0
  28. src/data/prefetch.py +62 -0
  29. src/data/shard_builder.py +119 -0
  30. src/data/shard_writer.py +81 -0
  31. src/data/sharded_dataset.py +112 -0
  32. src/data/streaming_dataset.py +132 -0
  33. src/data/validation.py +212 -0
  34. src/inference/__init__.py +0 -0
  35. src/inference/chat_template.py +384 -0
  36. src/inference/config.py +48 -0
  37. src/inference/engine.py +241 -0
  38. src/inference/export.py +133 -0
  39. src/inference/kv_cache.py +65 -0
  40. src/inference/runtime.py +161 -0
  41. src/inference/sampling.py +42 -0
  42. src/inference/scheduler.py +473 -0
  43. src/inference/text.py +67 -0
  44. src/initializers/Constant.py +9 -0
  45. src/initializers/GlorotNormal.py +15 -0
  46. src/initializers/GlorotUniform.py +26 -0
  47. src/initializers/HeNormal.py +15 -0
  48. src/initializers/HeUniform.py +14 -0
  49. src/initializers/Initializer.py +4 -0
  50. src/initializers/LecunNormal.py +16 -0
  51. src/initializers/LecunUniform.py +14 -0
  52. src/initializers/Ones.py +6 -0
  53. src/initializers/Orthogonal.py +14 -0
  54. src/initializers/RandomNormal.py +14 -0
  55. src/initializers/RandomUniform.py +14 -0
  56. src/initializers/Zeros.py +8 -0
  57. src/initializers/__init__.py +17 -0
  58. src/loss/CategoricalCrossEntropy.py +9 -0
  59. src/loss/CrossEntropyLoss.py +34 -0
  60. src/loss/CrossEntropyWithLogitsLoss.py +59 -0
  61. src/loss/Hinge.py +5 -0
  62. src/loss/Huber.py +22 -0
  63. src/loss/Loss.py +6 -0
  64. src/loss/MSE.py +7 -0
  65. src/loss/MSELoss.py +10 -0
  66. src/loss/SparseCategoricalCrossEntropy.py +15 -0
  67. src/loss/__init__.py +18 -0
  68. src/loss/bce.py +34 -0
  69. src/loss/mae.py +16 -0
  70. src/math/__init__.py +0 -0
  71. src/math/clip.py +37 -0
  72. src/math/exp.py +27 -0
  73. src/math/log.py +25 -0
  74. src/math/sigmoid.py +5 -0
  75. src/models/__init__.py +0 -0
  76. src/models/embedding/Embedding.py +65 -0
  77. src/models/embedding/__init__.py +0 -0
  78. src/models/gpt/__init__.py +0 -0
  79. src/models/gpt/attention.py +158 -0
  80. src/models/gpt/block.py +74 -0
  81. src/models/gpt/config.py +103 -0
  82. src/models/gpt/context.py +44 -0
  83. src/models/gpt/model.py +165 -0
  84. src/models/gpt/recompute.py +35 -0
  85. src/models/gpt/rope.py +84 -0
  86. src/models/regression/Linear.py +51 -0
  87. src/models/regression/Logistic.py +36 -0
  88. src/models/regression/__init__.py +0 -0
  89. src/models/seq/Sequential.py +297 -0
  90. src/models/seq/__init__.py +0 -0
  91. src/models/svm/__init__.py +0 -0
  92. src/models/tokenizer/BPETokenizer.py +228 -0
  93. src/models/tokenizer/__init__.py +0 -0
  94. src/models/transformers/Dropout.py +35 -0
  95. src/models/transformers/LastToken.py +10 -0
  96. src/models/transformers/LayerNorm.py +54 -0
  97. src/models/transformers/Linear.py +18 -0
  98. src/models/transformers/MultiHeadAttention.py +130 -0
  99. src/models/transformers/TransformerBlock.py +79 -0
  100. src/models/transformers/__init__.py +0 -0
  101. src/neural/Dense.py +58 -0
  102. src/neural/LSTM.py +167 -0
  103. src/neural/Layer.py +72 -0
  104. src/neural/Parameter.py +30 -0
  105. src/neural/RNN.py +83 -0
  106. src/neural/__init__.py +0 -0
  107. src/ops/__init__.py +0 -0
  108. src/ops/stack.py +40 -0
  109. src/optimizers/Adagrad.py +31 -0
  110. src/optimizers/Adam.py +98 -0
  111. src/optimizers/AdamW.py +84 -0
  112. src/optimizers/Batch.py +11 -0
  113. src/optimizers/Nesterov.py +35 -0
  114. src/optimizers/Optimizer.py +18 -0
  115. src/optimizers/RMSProp.py +35 -0
  116. src/optimizers/SGD.py +30 -0
  117. src/optimizers/SGDMomentum.py +28 -0
  118. src/optimizers/__init__.py +9 -0
  119. src/scaling/StandardScaler.py +15 -0
  120. src/scaling/__init__.py +0 -0
  121. src/serialization/__init__.py +0 -0
  122. src/serialization/checkpoint.py +58 -0
  123. src/serialization/modelio.py +132 -0
  124. src/serving/__init__.py +0 -0
  125. src/serving/app.py +792 -0
  126. src/serving/config.py +216 -0
  127. src/serving/errors.py +51 -0
  128. src/serving/http.py +599 -0
  129. src/serving/metrics.py +293 -0
  130. src/serving/model_server.py +287 -0
  131. src/serving/protocol.py +377 -0
  132. src/serving/security.py +200 -0
  133. src/serving/server.py +121 -0
  134. src/tokenization/__init__.py +0 -0
  135. src/tokenization/base.py +75 -0
  136. src/tokenization/bpe.py +190 -0
  137. src/tokenization/bytebpe.py +476 -0
  138. src/tokenization/registry.py +28 -0
  139. src/training/__init__.py +0 -0
  140. src/training/checkpoint_manager.py +101 -0
  141. src/training/experiment.py +71 -0
  142. src/training/losses.py +42 -0
  143. src/training/precision.py +141 -0
  144. src/training/profiler.py +38 -0
  145. src/training/scheduler.py +50 -0
  146. src/training/trainer.py +594 -0
src/training/losses.py ADDED
@@ -0,0 +1,42 @@
1
+ import numpy as np
2
+
3
+ from src.core.Tensor import Tensor
4
+
5
+
6
+ def masked_cross_entropy(logits, targets, mask):
7
+ data = logits.data
8
+ targets = np.asarray(targets, dtype=np.int64).reshape(-1)
9
+ weights = np.asarray(mask, dtype=np.float32).reshape(-1)
10
+
11
+ if data.ndim != 2 or data.shape[0] != targets.shape[0] or weights.shape[0] != targets.shape[0]:
12
+ raise ValueError("masked_cross_entropy expects logits (N, V), targets (N,) and mask (N,)")
13
+
14
+ count = float(weights.sum())
15
+ denom = max(count, 1.0)
16
+
17
+ shifted = data - data.max(axis=1, keepdims=True)
18
+ log_norm = np.log(np.exp(shifted).sum(axis=1))
19
+ rows = np.arange(targets.shape[0])
20
+ nll = log_norm - shifted[rows, targets]
21
+
22
+ out = Tensor(np.float32(float(np.dot(nll, weights)) / denom), requires_grad=logits.requires_grad,
23
+ parents=(logits,), op="MaskedCrossEntropy")
24
+ out.token_count = count
25
+
26
+ def _backward():
27
+ if not logits.requires_grad:
28
+ return
29
+
30
+ active = np.nonzero(weights)[0]
31
+
32
+ if active.size == 0:
33
+ return
34
+
35
+ probs = np.exp(shifted[active] - log_norm[active, None])
36
+ probs[np.arange(active.size), targets[active]] -= 1.0
37
+ probs *= (weights[active] * (float(out.grad) / denom))[:, None]
38
+ logits.grad[active] += probs
39
+
40
+ out._backward = _backward
41
+
42
+ return out
@@ -0,0 +1,141 @@
1
+ import math
2
+
3
+ import numpy as np
4
+
5
+ from src.core.Tensor import set_matmul_policy
6
+
7
+ PRECISIONS = ("fp32", "bf16", "fp16")
8
+ LOSS_SCALING = ("auto", "dynamic", "none")
9
+
10
+
11
+ def round_bf16(x):
12
+ x = np.ascontiguousarray(x, dtype=np.float32)
13
+ bits = x.view(np.uint32)
14
+ finite = (bits & np.uint32(0x7F800000)) != np.uint32(0x7F800000)
15
+ lsb = (bits >> np.uint32(16)) & np.uint32(1)
16
+ rounded = (bits + np.uint32(0x7FFF) + lsb) & np.uint32(0xFFFF0000)
17
+ is_nan = ~finite & ((bits & np.uint32(0x007FFFFF)) != np.uint32(0))
18
+ special = (bits & np.uint32(0xFFFF0000)) | np.where(is_nan, np.uint32(0x00400000), np.uint32(0))
19
+ return np.where(finite, rounded, special).astype(np.uint32).view(np.float32)
20
+
21
+
22
+ def round_fp16(x):
23
+ with np.errstate(over="ignore"):
24
+ return np.asarray(x, dtype=np.float32).astype(np.float16).astype(np.float32)
25
+
26
+
27
+ ROUNDERS = {"bf16": round_bf16, "fp16": round_fp16}
28
+
29
+
30
+ class autocast:
31
+
32
+ def __init__(self, precision):
33
+ if precision not in PRECISIONS:
34
+ raise ValueError(f"unknown precision '{precision}'; choose one of {PRECISIONS}")
35
+
36
+ self.precision = precision
37
+ self._previous = None
38
+
39
+ def __enter__(self):
40
+ self._previous = set_matmul_policy(ROUNDERS.get(self.precision))
41
+ return self
42
+
43
+ def __exit__(self, *exc):
44
+ set_matmul_policy(self._previous)
45
+ return False
46
+
47
+
48
+ class GradScaler:
49
+
50
+ def __init__(
51
+ self,
52
+ enabled=True,
53
+ init_scale=65536.0,
54
+ growth_factor=2.0,
55
+ backoff_factor=0.5,
56
+ growth_interval=2000,
57
+ min_scale=1.0,
58
+ max_scale=2.0 ** 24,
59
+ ):
60
+ if init_scale <= 0 or growth_factor <= 1 or not 0 < backoff_factor < 1 or growth_interval < 1:
61
+ raise ValueError("invalid loss scaler settings")
62
+
63
+ self.enabled = bool(enabled)
64
+ self.scale = float(init_scale) if enabled else 1.0
65
+ self.growth_factor = float(growth_factor)
66
+ self.backoff_factor = float(backoff_factor)
67
+ self.growth_interval = int(growth_interval)
68
+ self.min_scale = float(min_scale)
69
+ self.max_scale = float(max_scale)
70
+ self.good_steps = 0
71
+ self.skipped_steps = 0
72
+
73
+ def loss_multiplier(self):
74
+ return self.scale if self.enabled else 1.0
75
+
76
+ def grads_finite(self, params):
77
+ for p in params:
78
+ if p.requires_grad and p._grad is not None and not np.isfinite(p._grad).all():
79
+ return False
80
+
81
+ return True
82
+
83
+ def unscale_and_check(self, params):
84
+ if not self.enabled:
85
+ return True
86
+
87
+ if not self.grads_finite(params):
88
+ return False
89
+
90
+ inv = 1.0 / self.scale
91
+
92
+ for p in params:
93
+ if p.requires_grad and p._grad is not None:
94
+ p._grad *= inv
95
+
96
+ return True
97
+
98
+ def update(self, found_overflow):
99
+ if not self.enabled:
100
+ return
101
+
102
+ if found_overflow:
103
+ self.skipped_steps += 1
104
+ self.good_steps = 0
105
+ self.scale = max(self.min_scale, self.scale * self.backoff_factor)
106
+ return
107
+
108
+ self.good_steps += 1
109
+
110
+ if self.good_steps >= self.growth_interval:
111
+ self.good_steps = 0
112
+ self.scale = min(self.max_scale, self.scale * self.growth_factor)
113
+
114
+ def state_dict(self):
115
+ return {
116
+ "enabled": self.enabled,
117
+ "scale": self.scale,
118
+ "good_steps": self.good_steps,
119
+ "skipped_steps": self.skipped_steps,
120
+ }
121
+
122
+ def load_state_dict(self, state):
123
+ if bool(state.get("enabled", False)) != self.enabled:
124
+ raise ValueError("checkpoint loss-scaling mode does not match this run")
125
+
126
+ self.scale = float(state["scale"])
127
+ self.good_steps = int(state["good_steps"])
128
+ self.skipped_steps = int(state["skipped_steps"])
129
+
130
+ if not math.isfinite(self.scale) or self.scale <= 0:
131
+ raise ValueError("checkpoint carries an invalid loss scale")
132
+
133
+
134
+ def resolve_loss_scaling(precision, loss_scaling):
135
+ if loss_scaling not in LOSS_SCALING:
136
+ raise ValueError(f"unknown loss_scaling '{loss_scaling}'; choose one of {LOSS_SCALING}")
137
+
138
+ if loss_scaling == "auto":
139
+ return precision == "fp16"
140
+
141
+ return loss_scaling == "dynamic"
@@ -0,0 +1,38 @@
1
+ import time
2
+ from collections import defaultdict
3
+
4
+
5
+ class Profiler:
6
+
7
+ def __init__(self):
8
+ self.totals = defaultdict(float)
9
+ self.window = defaultdict(float)
10
+
11
+ def add(self, name, seconds):
12
+ self.totals[name] += seconds
13
+ self.window[name] += seconds
14
+
15
+ def section(self, name):
16
+ return _Section(self, name)
17
+
18
+ def take_window(self):
19
+ snapshot = dict(self.window)
20
+ self.window.clear()
21
+ return snapshot
22
+
23
+ def summary(self):
24
+ total = sum(self.totals.values()) or 1.0
25
+ return {k: {"seconds": v, "share": v / total} for k, v in sorted(self.totals.items())}
26
+
27
+
28
+ class _Section:
29
+
30
+ def __init__(self, profiler, name):
31
+ self.profiler = profiler
32
+ self.name = name
33
+
34
+ def __enter__(self):
35
+ self.start = time.perf_counter()
36
+
37
+ def __exit__(self, *exc):
38
+ self.profiler.add(self.name, time.perf_counter() - self.start)
@@ -0,0 +1,50 @@
1
+ import math
2
+
3
+
4
+ class LRScheduler:
5
+
6
+ def __init__(
7
+ self,
8
+ base_lr,
9
+ warmup_steps=0,
10
+ decay="cosine",
11
+ total_steps=None,
12
+ min_lr=0.0,
13
+ ):
14
+ if decay not in ("cosine", "linear", "constant"):
15
+ raise ValueError(f"unknown decay '{decay}'")
16
+
17
+ self.base_lr = base_lr
18
+ self.warmup_steps = warmup_steps
19
+ self.decay = decay
20
+ self.total_steps = total_steps
21
+ self.min_lr = min_lr
22
+ self.step_count = 0
23
+
24
+ def get_lr(self, step):
25
+ if self.warmup_steps and step < self.warmup_steps:
26
+ return self.base_lr * (step + 1) / self.warmup_steps
27
+
28
+ if self.decay == "constant" or not self.total_steps:
29
+ return self.base_lr
30
+
31
+ span = max(1, self.total_steps - self.warmup_steps)
32
+ progress = (step - self.warmup_steps) / span
33
+ progress = min(max(progress, 0.0), 1.0)
34
+
35
+ if self.decay == "linear":
36
+ return self.base_lr + (self.min_lr - self.base_lr) * progress
37
+
38
+ cosine = 0.5 * (1 + math.cos(math.pi * progress))
39
+ return self.min_lr + (self.base_lr - self.min_lr) * cosine
40
+
41
+ def step(self):
42
+ lr = self.get_lr(self.step_count)
43
+ self.step_count += 1
44
+ return lr
45
+
46
+ def state_dict(self):
47
+ return {"step_count": self.step_count}
48
+
49
+ def load_state_dict(self, state):
50
+ self.step_count = state["step_count"]