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.
- cli.py +604 -0
- pytensorforge-0.1.0.dist-info/METADATA +103 -0
- pytensorforge-0.1.0.dist-info/RECORD +146 -0
- pytensorforge-0.1.0.dist-info/WHEEL +5 -0
- pytensorforge-0.1.0.dist-info/entry_points.txt +2 -0
- pytensorforge-0.1.0.dist-info/top_level.txt +2 -0
- src/__init__.py +0 -0
- src/activations/Activation.py +4 -0
- src/activations/ELU.py +11 -0
- src/activations/GELU.py +6 -0
- src/activations/ReLU.py +27 -0
- src/activations/SELU.py +14 -0
- src/activations/Sigmoid.py +27 -0
- src/activations/Softmax.py +84 -0
- src/activations/Tanh.py +29 -0
- src/activations/__init__.py +17 -0
- src/config.py +120 -0
- src/core/Matrix.py +3 -0
- src/core/Scalar.py +18 -0
- src/core/Tensor.py +866 -0
- src/core/Vector.py +31 -0
- src/core/__init__.py +0 -0
- src/data/__init__.py +0 -0
- src/data/chat_dataset.py +188 -0
- src/data/corpus.py +104 -0
- src/data/document_stream.py +178 -0
- src/data/parallel_encode.py +86 -0
- src/data/prefetch.py +62 -0
- src/data/shard_builder.py +119 -0
- src/data/shard_writer.py +81 -0
- src/data/sharded_dataset.py +112 -0
- src/data/streaming_dataset.py +132 -0
- src/data/validation.py +212 -0
- src/inference/__init__.py +0 -0
- src/inference/chat_template.py +384 -0
- src/inference/config.py +48 -0
- src/inference/engine.py +241 -0
- src/inference/export.py +133 -0
- src/inference/kv_cache.py +65 -0
- src/inference/runtime.py +161 -0
- src/inference/sampling.py +42 -0
- src/inference/scheduler.py +473 -0
- src/inference/text.py +67 -0
- src/initializers/Constant.py +9 -0
- src/initializers/GlorotNormal.py +15 -0
- src/initializers/GlorotUniform.py +26 -0
- src/initializers/HeNormal.py +15 -0
- src/initializers/HeUniform.py +14 -0
- src/initializers/Initializer.py +4 -0
- src/initializers/LecunNormal.py +16 -0
- src/initializers/LecunUniform.py +14 -0
- src/initializers/Ones.py +6 -0
- src/initializers/Orthogonal.py +14 -0
- src/initializers/RandomNormal.py +14 -0
- src/initializers/RandomUniform.py +14 -0
- src/initializers/Zeros.py +8 -0
- src/initializers/__init__.py +17 -0
- src/loss/CategoricalCrossEntropy.py +9 -0
- src/loss/CrossEntropyLoss.py +34 -0
- src/loss/CrossEntropyWithLogitsLoss.py +59 -0
- src/loss/Hinge.py +5 -0
- src/loss/Huber.py +22 -0
- src/loss/Loss.py +6 -0
- src/loss/MSE.py +7 -0
- src/loss/MSELoss.py +10 -0
- src/loss/SparseCategoricalCrossEntropy.py +15 -0
- src/loss/__init__.py +18 -0
- src/loss/bce.py +34 -0
- src/loss/mae.py +16 -0
- src/math/__init__.py +0 -0
- src/math/clip.py +37 -0
- src/math/exp.py +27 -0
- src/math/log.py +25 -0
- src/math/sigmoid.py +5 -0
- src/models/__init__.py +0 -0
- src/models/embedding/Embedding.py +65 -0
- src/models/embedding/__init__.py +0 -0
- src/models/gpt/__init__.py +0 -0
- src/models/gpt/attention.py +158 -0
- src/models/gpt/block.py +74 -0
- src/models/gpt/config.py +103 -0
- src/models/gpt/context.py +44 -0
- src/models/gpt/model.py +165 -0
- src/models/gpt/recompute.py +35 -0
- src/models/gpt/rope.py +84 -0
- src/models/regression/Linear.py +51 -0
- src/models/regression/Logistic.py +36 -0
- src/models/regression/__init__.py +0 -0
- src/models/seq/Sequential.py +297 -0
- src/models/seq/__init__.py +0 -0
- src/models/svm/__init__.py +0 -0
- src/models/tokenizer/BPETokenizer.py +228 -0
- src/models/tokenizer/__init__.py +0 -0
- src/models/transformers/Dropout.py +35 -0
- src/models/transformers/LastToken.py +10 -0
- src/models/transformers/LayerNorm.py +54 -0
- src/models/transformers/Linear.py +18 -0
- src/models/transformers/MultiHeadAttention.py +130 -0
- src/models/transformers/TransformerBlock.py +79 -0
- src/models/transformers/__init__.py +0 -0
- src/neural/Dense.py +58 -0
- src/neural/LSTM.py +167 -0
- src/neural/Layer.py +72 -0
- src/neural/Parameter.py +30 -0
- src/neural/RNN.py +83 -0
- src/neural/__init__.py +0 -0
- src/ops/__init__.py +0 -0
- src/ops/stack.py +40 -0
- src/optimizers/Adagrad.py +31 -0
- src/optimizers/Adam.py +98 -0
- src/optimizers/AdamW.py +84 -0
- src/optimizers/Batch.py +11 -0
- src/optimizers/Nesterov.py +35 -0
- src/optimizers/Optimizer.py +18 -0
- src/optimizers/RMSProp.py +35 -0
- src/optimizers/SGD.py +30 -0
- src/optimizers/SGDMomentum.py +28 -0
- src/optimizers/__init__.py +9 -0
- src/scaling/StandardScaler.py +15 -0
- src/scaling/__init__.py +0 -0
- src/serialization/__init__.py +0 -0
- src/serialization/checkpoint.py +58 -0
- src/serialization/modelio.py +132 -0
- src/serving/__init__.py +0 -0
- src/serving/app.py +792 -0
- src/serving/config.py +216 -0
- src/serving/errors.py +51 -0
- src/serving/http.py +599 -0
- src/serving/metrics.py +293 -0
- src/serving/model_server.py +287 -0
- src/serving/protocol.py +377 -0
- src/serving/security.py +200 -0
- src/serving/server.py +121 -0
- src/tokenization/__init__.py +0 -0
- src/tokenization/base.py +75 -0
- src/tokenization/bpe.py +190 -0
- src/tokenization/bytebpe.py +476 -0
- src/tokenization/registry.py +28 -0
- src/training/__init__.py +0 -0
- src/training/checkpoint_manager.py +101 -0
- src/training/experiment.py +71 -0
- src/training/losses.py +42 -0
- src/training/precision.py +141 -0
- src/training/profiler.py +38 -0
- src/training/scheduler.py +50 -0
- src/training/trainer.py +594 -0
src/optimizers/Adam.py
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from src.optimizers.Optimizer import SerialOptimizer
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Adam(SerialOptimizer):
|
|
7
|
+
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
lr=0.001,
|
|
11
|
+
beta1=0.9,
|
|
12
|
+
beta2=0.999,
|
|
13
|
+
eps=1e-8,
|
|
14
|
+
):
|
|
15
|
+
self.lr = lr
|
|
16
|
+
self.beta1 = beta1
|
|
17
|
+
self.beta2 = beta2
|
|
18
|
+
self.eps = eps
|
|
19
|
+
|
|
20
|
+
self.m = {}
|
|
21
|
+
self.v = {}
|
|
22
|
+
|
|
23
|
+
self.t = 0
|
|
24
|
+
|
|
25
|
+
def step(self, params):
|
|
26
|
+
|
|
27
|
+
self.t += 1
|
|
28
|
+
|
|
29
|
+
for p in params:
|
|
30
|
+
|
|
31
|
+
if not p.requires_grad:
|
|
32
|
+
continue
|
|
33
|
+
|
|
34
|
+
pid = id(p)
|
|
35
|
+
|
|
36
|
+
if pid not in self.m:
|
|
37
|
+
self.m[pid] = np.zeros_like(p.data)
|
|
38
|
+
self.v[pid] = np.zeros_like(p.data)
|
|
39
|
+
|
|
40
|
+
self.m[pid] = (
|
|
41
|
+
self.beta1 * self.m[pid]
|
|
42
|
+
+ (1 - self.beta1) * p.grad
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
self.v[pid] = (
|
|
46
|
+
self.beta2 * self.v[pid]
|
|
47
|
+
+ (1 - self.beta2) * (p.grad ** 2)
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
m_hat = self.m[pid] / (1 - self.beta1 ** self.t)
|
|
51
|
+
v_hat = self.v[pid] / (1 - self.beta2 ** self.t)
|
|
52
|
+
|
|
53
|
+
p.data -= (
|
|
54
|
+
self.lr
|
|
55
|
+
* m_hat
|
|
56
|
+
/ (np.sqrt(v_hat) + self.eps)
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def zero_grad(self, params):
|
|
60
|
+
for p in params:
|
|
61
|
+
p.zero_grad()
|
|
62
|
+
|
|
63
|
+
# def state_dict(self):
|
|
64
|
+
#
|
|
65
|
+
# return {
|
|
66
|
+
# "m": self.m,
|
|
67
|
+
# "v": self.v,
|
|
68
|
+
# "t": self.t,
|
|
69
|
+
# "lr": self.lr
|
|
70
|
+
# }
|
|
71
|
+
#
|
|
72
|
+
# def load_state_dict(self, state):
|
|
73
|
+
#
|
|
74
|
+
# self.m = state["m"]
|
|
75
|
+
# self.v = state["v"]
|
|
76
|
+
# self.t = state["t"]
|
|
77
|
+
# self.lr = state["lr"]
|
|
78
|
+
|
|
79
|
+
def state_dict(self):
|
|
80
|
+
return {
|
|
81
|
+
"lr": self.lr,
|
|
82
|
+
"beta1": self.beta1,
|
|
83
|
+
"beta2": self.beta2,
|
|
84
|
+
"eps": self.eps,
|
|
85
|
+
"t": self.t,
|
|
86
|
+
"m": self.m,
|
|
87
|
+
"v": self.v,
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
def load_state_dict(self, state):
|
|
91
|
+
|
|
92
|
+
self.lr = float(state["lr"])
|
|
93
|
+
self.beta1 = float(state["beta1"])
|
|
94
|
+
self.beta2 = float(state["beta2"])
|
|
95
|
+
self.eps = float(state["eps"])
|
|
96
|
+
self.t = int(state["t"])
|
|
97
|
+
self.m = state["m"].item() if isinstance(state["m"], np.ndarray) else state["m"]
|
|
98
|
+
self.v = state["v"].item() if isinstance(state["v"], np.ndarray) else state["v"]
|
src/optimizers/AdamW.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from src.optimizers.Optimizer import SerialOptimizer
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AdamW(SerialOptimizer):
|
|
7
|
+
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
lr=0.001,
|
|
11
|
+
beta1=0.9,
|
|
12
|
+
beta2=0.999,
|
|
13
|
+
eps=1e-8,
|
|
14
|
+
weight_decay=0.01,
|
|
15
|
+
):
|
|
16
|
+
self.lr = lr
|
|
17
|
+
self.beta1 = beta1
|
|
18
|
+
self.beta2 = beta2
|
|
19
|
+
self.eps = eps
|
|
20
|
+
self.weight_decay = weight_decay
|
|
21
|
+
|
|
22
|
+
self.m = {}
|
|
23
|
+
self.v = {}
|
|
24
|
+
|
|
25
|
+
self.t = 0
|
|
26
|
+
|
|
27
|
+
def step(self, params):
|
|
28
|
+
|
|
29
|
+
self.t += 1
|
|
30
|
+
|
|
31
|
+
for pid, p in enumerate(params):
|
|
32
|
+
|
|
33
|
+
if not p.requires_grad:
|
|
34
|
+
continue
|
|
35
|
+
|
|
36
|
+
if pid not in self.m:
|
|
37
|
+
self.m[pid] = np.zeros_like(p.data)
|
|
38
|
+
self.v[pid] = np.zeros_like(p.data)
|
|
39
|
+
|
|
40
|
+
p.data *= (1 - self.lr * self.weight_decay)
|
|
41
|
+
|
|
42
|
+
self.m[pid] = (
|
|
43
|
+
self.beta1 * self.m[pid]
|
|
44
|
+
+ (1 - self.beta1) * p.grad
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
self.v[pid] = (
|
|
48
|
+
self.beta2 * self.v[pid]
|
|
49
|
+
+ (1 - self.beta2) * (p.grad ** 2)
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
m_hat = self.m[pid] / (1 - self.beta1 ** self.t)
|
|
53
|
+
v_hat = self.v[pid] / (1 - self.beta2 ** self.t)
|
|
54
|
+
|
|
55
|
+
p.data -= (
|
|
56
|
+
self.lr
|
|
57
|
+
* m_hat
|
|
58
|
+
/ (np.sqrt(v_hat) + self.eps)
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
def zero_grad(self, params):
|
|
62
|
+
for p in params:
|
|
63
|
+
p.zero_grad()
|
|
64
|
+
|
|
65
|
+
def state_dict(self):
|
|
66
|
+
return {
|
|
67
|
+
"t": self.t,
|
|
68
|
+
"lr": self.lr,
|
|
69
|
+
"beta1": self.beta1,
|
|
70
|
+
"beta2": self.beta2,
|
|
71
|
+
"eps": self.eps,
|
|
72
|
+
"weight_decay": self.weight_decay,
|
|
73
|
+
"m": {k: v.copy() for k, v in self.m.items()},
|
|
74
|
+
"v": {k: v.copy() for k, v in self.v.items()},
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
def load_state_dict(self, state):
|
|
78
|
+
self.t = state["t"]
|
|
79
|
+
self.beta1 = state["beta1"]
|
|
80
|
+
self.beta2 = state["beta2"]
|
|
81
|
+
self.eps = state["eps"]
|
|
82
|
+
self.weight_decay = state["weight_decay"]
|
|
83
|
+
self.m = {k: v.copy() for k, v in state["m"].items()}
|
|
84
|
+
self.v = {k: v.copy() for k, v in state["v"].items()}
|
src/optimizers/Batch.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Nesterov:
|
|
5
|
+
|
|
6
|
+
def __init__(self, lr=0.01, momentum=0.9):
|
|
7
|
+
self.lr = lr
|
|
8
|
+
self.momentum = momentum
|
|
9
|
+
self.velocity = {}
|
|
10
|
+
|
|
11
|
+
def step(self, params):
|
|
12
|
+
|
|
13
|
+
for p in params:
|
|
14
|
+
|
|
15
|
+
if not p.requires_grad:
|
|
16
|
+
continue
|
|
17
|
+
|
|
18
|
+
if id(p) not in self.velocity:
|
|
19
|
+
self.velocity[id(p)] = np.zeros_like(p.data)
|
|
20
|
+
|
|
21
|
+
v_prev = self.velocity[id(p)].copy()
|
|
22
|
+
|
|
23
|
+
self.velocity[id(p)] = (
|
|
24
|
+
self.momentum * self.velocity[id(p)]
|
|
25
|
+
- self.lr * p.grad
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
p.data += (
|
|
29
|
+
-self.momentum * v_prev
|
|
30
|
+
+ (1 + self.momentum) * self.velocity[id(p)]
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
def zero_grad(self, params):
|
|
34
|
+
for p in params:
|
|
35
|
+
p.zero_grad()
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class Optimizer:
|
|
2
|
+
def __init__(self, parameters, grads, learning_rate):
|
|
3
|
+
self.parameters = parameters
|
|
4
|
+
self.grads = grads
|
|
5
|
+
self.learning_rate = learning_rate
|
|
6
|
+
|
|
7
|
+
def zero_out(self):
|
|
8
|
+
for p in self.grads:
|
|
9
|
+
p.zeros(p.shape)
|
|
10
|
+
|
|
11
|
+
def step(self):
|
|
12
|
+
raise NotImplementedError
|
|
13
|
+
|
|
14
|
+
class SerialOptimizer:
|
|
15
|
+
def state_dict(self):
|
|
16
|
+
raise NotImplementedError
|
|
17
|
+
def load_state_dict(self, state):
|
|
18
|
+
raise NotImplementedError
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class RMSProp:
|
|
5
|
+
|
|
6
|
+
def __init__(self, lr=0.001, beta=0.9, eps=1e-8):
|
|
7
|
+
self.lr = lr
|
|
8
|
+
self.beta = beta
|
|
9
|
+
self.eps = eps
|
|
10
|
+
self.cache = {}
|
|
11
|
+
|
|
12
|
+
def step(self, params):
|
|
13
|
+
|
|
14
|
+
for p in params:
|
|
15
|
+
|
|
16
|
+
if not p.requires_grad:
|
|
17
|
+
continue
|
|
18
|
+
|
|
19
|
+
if id(p) not in self.cache:
|
|
20
|
+
self.cache[id(p)] = np.zeros_like(p.data)
|
|
21
|
+
|
|
22
|
+
self.cache[id(p)] = (
|
|
23
|
+
self.beta * self.cache[id(p)]
|
|
24
|
+
+ (1 - self.beta) * (p.grad ** 2)
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
p.data -= (
|
|
28
|
+
self.lr
|
|
29
|
+
* p.grad
|
|
30
|
+
/ (np.sqrt(self.cache[id(p)]) + self.eps)
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
def zero_grad(self, params):
|
|
34
|
+
for p in params:
|
|
35
|
+
p.zero_grad()
|
src/optimizers/SGD.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from src.optimizers.Optimizer import Optimizer
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class SGD(Optimizer):
|
|
5
|
+
def __init__(self, parameters, grads, learning_rate = 0.01):
|
|
6
|
+
super().__init__(parameters, grads, learning_rate)
|
|
7
|
+
|
|
8
|
+
def step(self):
|
|
9
|
+
for p, grad in zip(self.parameters, self.grads):
|
|
10
|
+
p.data -= self.learning_rate * grad.data
|
|
11
|
+
|
|
12
|
+
class SGDescent:
|
|
13
|
+
def __init__(self, lr=0.01): self.lr = lr
|
|
14
|
+
|
|
15
|
+
def step(self, params):
|
|
16
|
+
for p in params:
|
|
17
|
+
if p.requires_grad:
|
|
18
|
+
p.data -= self.lr * p.grad
|
|
19
|
+
|
|
20
|
+
def zero_grad(self, params):
|
|
21
|
+
for p in params:
|
|
22
|
+
p.zero_grad()
|
|
23
|
+
|
|
24
|
+
def state_dict(self):
|
|
25
|
+
return {
|
|
26
|
+
"lr": self.lr
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
def load_state_dict(self, state):
|
|
30
|
+
self.lr = float(state["lr"])
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
class SGDMomentum:
|
|
4
|
+
|
|
5
|
+
def __init__(self, lr=0.01, momentum=0.9):
|
|
6
|
+
self.lr = lr
|
|
7
|
+
self.momentum = momentum
|
|
8
|
+
self.velocity = {}
|
|
9
|
+
|
|
10
|
+
def step(self, params):
|
|
11
|
+
|
|
12
|
+
for p in params:
|
|
13
|
+
|
|
14
|
+
if not p.requires_grad:
|
|
15
|
+
continue
|
|
16
|
+
|
|
17
|
+
if id(p) not in self.velocity:
|
|
18
|
+
self.velocity[id(p)] = np.zeros_like(p.data)
|
|
19
|
+
|
|
20
|
+
v = self.velocity[id(p)]
|
|
21
|
+
|
|
22
|
+
v[:] = self.momentum * v - self.lr * p.grad
|
|
23
|
+
|
|
24
|
+
p.data += v
|
|
25
|
+
|
|
26
|
+
def zero_grad(self, params):
|
|
27
|
+
for p in params:
|
|
28
|
+
p.zero_grad()
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class StandardScaler:
|
|
5
|
+
def fit(self, X):
|
|
6
|
+
self.mean = np.mean(X, axis=0)
|
|
7
|
+
self.std = np.std(X, axis=0)
|
|
8
|
+
self.std[self.std == 0] = 1.0
|
|
9
|
+
|
|
10
|
+
def transform(self, X):
|
|
11
|
+
return (X - self.mean) / self.std
|
|
12
|
+
|
|
13
|
+
def fit_transform(self, X):
|
|
14
|
+
self.fit(X)
|
|
15
|
+
return self.transform(X)
|
src/scaling/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import pickle
|
|
2
|
+
|
|
3
|
+
# How to use:
|
|
4
|
+
# model = Sequential(...)
|
|
5
|
+
#
|
|
6
|
+
# model.compile(
|
|
7
|
+
# optimizer="adam",
|
|
8
|
+
# loss="cross_entropy",
|
|
9
|
+
# )
|
|
10
|
+
#
|
|
11
|
+
# epoch, loss = Checkpoint.load(
|
|
12
|
+
# model,
|
|
13
|
+
# model.optimizer,
|
|
14
|
+
# "checkpoint.ptf",
|
|
15
|
+
# )
|
|
16
|
+
#
|
|
17
|
+
# model.fit(
|
|
18
|
+
# X_train,
|
|
19
|
+
# y_train,
|
|
20
|
+
# epochs=100,
|
|
21
|
+
# initial_epoch=epoch,
|
|
22
|
+
# )
|
|
23
|
+
|
|
24
|
+
class Checkpoint:
|
|
25
|
+
|
|
26
|
+
@staticmethod
|
|
27
|
+
def save(
|
|
28
|
+
model,
|
|
29
|
+
optimizer,
|
|
30
|
+
epoch,
|
|
31
|
+
loss,
|
|
32
|
+
path,
|
|
33
|
+
):
|
|
34
|
+
|
|
35
|
+
state = {
|
|
36
|
+
"epoch": epoch,
|
|
37
|
+
"loss": float(loss.data),
|
|
38
|
+
"model": model.state_dict(),
|
|
39
|
+
"optimizer": optimizer.state_dict(),
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
with open(path, "wb") as f:
|
|
43
|
+
pickle.dump(state, f)
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def load(
|
|
47
|
+
model,
|
|
48
|
+
optimizer,
|
|
49
|
+
path,
|
|
50
|
+
):
|
|
51
|
+
|
|
52
|
+
with open(path, "rb") as f:
|
|
53
|
+
state = pickle.load(f)
|
|
54
|
+
|
|
55
|
+
model.load_state_dict(state["model"])
|
|
56
|
+
optimizer.load_state_dict(state["optimizer"])
|
|
57
|
+
|
|
58
|
+
return state["epoch"], state["loss"]
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# import numpy as np
|
|
2
|
+
#
|
|
3
|
+
#
|
|
4
|
+
# def flatten(state):
|
|
5
|
+
# out = {}
|
|
6
|
+
#
|
|
7
|
+
# for layer_name, params in state.items():
|
|
8
|
+
#
|
|
9
|
+
# for param_name, value in params.items():
|
|
10
|
+
# out[f"{layer_name}.{param_name}"] = value
|
|
11
|
+
#
|
|
12
|
+
# return out
|
|
13
|
+
#
|
|
14
|
+
# class ModelIO:
|
|
15
|
+
#
|
|
16
|
+
# @staticmethod
|
|
17
|
+
# def save(model, path, metadata = None):
|
|
18
|
+
#
|
|
19
|
+
# np.savez_compressed(
|
|
20
|
+
# path,
|
|
21
|
+
# **flatten(model.state_dict())
|
|
22
|
+
# )
|
|
23
|
+
#
|
|
24
|
+
# @staticmethod
|
|
25
|
+
# def save_data(data, path):
|
|
26
|
+
#
|
|
27
|
+
# np.savez_compressed(
|
|
28
|
+
# path,
|
|
29
|
+
# **flatten(data)
|
|
30
|
+
# )
|
|
31
|
+
#
|
|
32
|
+
# @staticmethod
|
|
33
|
+
# def load(model, path):
|
|
34
|
+
#
|
|
35
|
+
# data = np.load(path)
|
|
36
|
+
#
|
|
37
|
+
# state = {}
|
|
38
|
+
#
|
|
39
|
+
# for key in data.files:
|
|
40
|
+
#
|
|
41
|
+
# layer, param = key.split(".")
|
|
42
|
+
#
|
|
43
|
+
# if layer not in state:
|
|
44
|
+
# state[layer] = {}
|
|
45
|
+
#
|
|
46
|
+
# state[layer][param] = data[key]
|
|
47
|
+
#
|
|
48
|
+
# model.load_state_dict(state)
|
|
49
|
+
#
|
|
50
|
+
# return model
|
|
51
|
+
|
|
52
|
+
import numpy as np
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def flatten(d, prefix=""):
|
|
56
|
+
out = {}
|
|
57
|
+
|
|
58
|
+
for k, v in d.items():
|
|
59
|
+
|
|
60
|
+
key = f"{prefix}.{k}" if prefix else k
|
|
61
|
+
|
|
62
|
+
if isinstance(v, dict):
|
|
63
|
+
out.update(flatten(v, key))
|
|
64
|
+
else:
|
|
65
|
+
out[key] = v
|
|
66
|
+
|
|
67
|
+
return out
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def unflatten(flat):
|
|
71
|
+
out = {}
|
|
72
|
+
|
|
73
|
+
for key, value in flat.items():
|
|
74
|
+
|
|
75
|
+
parts = key.split(".")
|
|
76
|
+
|
|
77
|
+
d = out
|
|
78
|
+
|
|
79
|
+
for p in parts[:-1]:
|
|
80
|
+
d = d.setdefault(p, {})
|
|
81
|
+
|
|
82
|
+
d[parts[-1]] = value
|
|
83
|
+
|
|
84
|
+
return out
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class ModelIO:
|
|
88
|
+
|
|
89
|
+
@staticmethod
|
|
90
|
+
def save(model, path, metadata=None):
|
|
91
|
+
|
|
92
|
+
state = {
|
|
93
|
+
"model": model.state_dict()
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if metadata is not None:
|
|
97
|
+
state["metadata"] = metadata
|
|
98
|
+
|
|
99
|
+
np.savez_compressed(
|
|
100
|
+
path,
|
|
101
|
+
**flatten(state)
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
@staticmethod
|
|
105
|
+
def load(model, path):
|
|
106
|
+
|
|
107
|
+
data = np.load(path, allow_pickle=True)
|
|
108
|
+
|
|
109
|
+
flat = {
|
|
110
|
+
k: data[k]
|
|
111
|
+
for k in data.files
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
state = unflatten(flat)
|
|
115
|
+
|
|
116
|
+
model.load_state_dict(state["model"])
|
|
117
|
+
|
|
118
|
+
return state.get("metadata", None)
|
|
119
|
+
|
|
120
|
+
@staticmethod
|
|
121
|
+
def read(path):
|
|
122
|
+
|
|
123
|
+
data = np.load(path, allow_pickle=True)
|
|
124
|
+
|
|
125
|
+
flat = {
|
|
126
|
+
k: data[k]
|
|
127
|
+
for k in data.files
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
state = unflatten(flat)
|
|
131
|
+
|
|
132
|
+
return state
|
src/serving/__init__.py
ADDED
|
File without changes
|