modelstudio 0.1.0__tar.gz → 0.2.0__tar.gz
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.
- {modelstudio-0.1.0 → modelstudio-0.2.0}/MANIFEST.in +3 -0
- modelstudio-0.2.0/PKG-INFO +196 -0
- modelstudio-0.2.0/README.md +165 -0
- modelstudio-0.2.0/benchmarks/bench_attention.py +39 -0
- modelstudio-0.2.0/benchmarks/bench_dataloader.py +46 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/benchmarks/bench_matmul.py +12 -3
- {modelstudio-0.1.0 → modelstudio-0.2.0}/benchmarks/bench_mlp.py +14 -4
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/cuda/cuda_backend.cu +3 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/oneapi/oneapi_backend.cpp +3 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/rocm/rocm_backend.cpp +3 -0
- modelstudio-0.2.0/docs/autograd.md +55 -0
- modelstudio-0.2.0/docs/backend-architecture.md +72 -0
- modelstudio-0.2.0/docs/data.md +32 -0
- modelstudio-0.2.0/docs/nn.md +51 -0
- modelstudio-0.2.0/docs/releasing.md +86 -0
- modelstudio-0.2.0/docs/tensor-api.md +48 -0
- modelstudio-0.2.0/examples/save_load.py +21 -0
- modelstudio-0.2.0/examples/tiny_transformer.py +35 -0
- modelstudio-0.2.0/examples/train_classifier.py +28 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/pyproject.toml +15 -4
- modelstudio-0.2.0/python/modelstudio/__init__.py +66 -0
- modelstudio-0.2.0/python/modelstudio/_version.py +1 -0
- modelstudio-0.2.0/python/modelstudio/data/__init__.py +4 -0
- modelstudio-0.2.0/python/modelstudio/data/dataloader.py +50 -0
- modelstudio-0.2.0/python/modelstudio/data/dataset.py +30 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/device.py +4 -2
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/dtypes.py +4 -2
- modelstudio-0.2.0/python/modelstudio/errors.py +18 -0
- modelstudio-0.2.0/python/modelstudio/nn/__init__.py +25 -0
- modelstudio-0.2.0/python/modelstudio/nn/embedding.py +17 -0
- modelstudio-0.2.0/python/modelstudio/nn/losses.py +59 -0
- modelstudio-0.2.0/python/modelstudio/nn/module.py +170 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/nn/normalization.py +14 -0
- modelstudio-0.2.0/python/modelstudio/nn/transformer.py +41 -0
- modelstudio-0.2.0/python/modelstudio/ops/__init__.py +49 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/ops/linalg.py +21 -1
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/ops/math.py +142 -1
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/ops/movement.py +33 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/ops/reductions.py +6 -0
- modelstudio-0.2.0/python/modelstudio/py.typed +1 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/runtime/__init__.py +2 -7
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/runtime/backend.py +3 -9
- modelstudio-0.2.0/python/modelstudio/serialization.py +63 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/tensor.py +55 -1
- modelstudio-0.2.0/python/modelstudio/testing/gradcheck.py +73 -0
- modelstudio-0.2.0/python/modelstudio.egg-info/PKG-INFO +196 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio.egg-info/SOURCES.txt +36 -1
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio.egg-info/requires.txt +2 -0
- modelstudio-0.2.0/scripts/smoke_test.py +39 -0
- modelstudio-0.2.0/tests/test_attention.py +27 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/tests/test_autograd.py +37 -1
- modelstudio-0.2.0/tests/test_buffers.py +39 -0
- modelstudio-0.2.0/tests/test_data.py +42 -0
- modelstudio-0.2.0/tests/test_dispatcher.py +36 -0
- modelstudio-0.2.0/tests/test_embedding.py +22 -0
- modelstudio-0.2.0/tests/test_gradcheck.py +26 -0
- modelstudio-0.2.0/tests/test_indexing.py +34 -0
- modelstudio-0.2.0/tests/test_losses.py +36 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/tests/test_nn.py +18 -0
- modelstudio-0.2.0/tests/test_norms.py +31 -0
- modelstudio-0.2.0/tests/test_reductions_axis.py +52 -0
- modelstudio-0.2.0/tests/test_serialization.py +38 -0
- modelstudio-0.2.0/tests/test_state_dict.py +71 -0
- modelstudio-0.2.0/tests/test_transformer.py +21 -0
- modelstudio-0.2.0/tests/test_unary_ops.py +47 -0
- modelstudio-0.2.0/tests/test_version.py +5 -0
- modelstudio-0.1.0/PKG-INFO +0 -196
- modelstudio-0.1.0/README.md +0 -173
- modelstudio-0.1.0/python/modelstudio/__init__.py +0 -38
- modelstudio-0.1.0/python/modelstudio/nn/__init__.py +0 -8
- modelstudio-0.1.0/python/modelstudio/nn/losses.py +0 -14
- modelstudio-0.1.0/python/modelstudio/nn/module.py +0 -76
- modelstudio-0.1.0/python/modelstudio/ops/__init__.py +0 -24
- modelstudio-0.1.0/python/modelstudio/testing/gradcheck.py +0 -33
- modelstudio-0.1.0/python/modelstudio.egg-info/PKG-INFO +0 -196
- modelstudio-0.1.0/tests/test_dispatcher.py +0 -21
- {modelstudio-0.1.0 → modelstudio-0.2.0}/CMakeLists.txt +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/LICENSE +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/CMakeLists.txt +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/cpu/cpu_backend.cpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/cpu/cpu_backend.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/cpu/kernels/add.cpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/cpu/kernels/matmul.cpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/cuda/README.md +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/cuda/cuda_backend.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/cuda/cuda_memory.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/oneapi/README.md +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/oneapi/oneapi_backend.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/oneapi/sycl_memory.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/rocm/README.md +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/rocm/hip_memory.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/backends/rocm/rocm_backend.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/bindings/python_bindings.cpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/core/device.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/core/dtype.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/core/error.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/core/shape.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/core/storage.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/core/tensor.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/dispatcher/backend.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/dispatcher/dispatcher.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/csrc/dispatcher/operator_registry.hpp +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/examples/train_mlp.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/autograd/__init__.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/autograd/engine.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/autograd/function.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/autograd/grad_mode.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/compile/__init__.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/compile/graph_capture.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/compile/ir.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/compile/passes.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/nn/activations.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/nn/linear.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/nn/parameter.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/ops/creation.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/optim/__init__.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/optim/adamw.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/optim/optimizer.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/optim/sgd.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/runtime/dispatcher.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/storage.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio/testing/__init__.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio.egg-info/dependency_links.txt +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/python/modelstudio.egg-info/top_level.txt +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/setup.cfg +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/tests/test_ops.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/tests/test_optim.py +0 -0
- {modelstudio-0.1.0 → modelstudio-0.2.0}/tests/test_tensor.py +0 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: modelstudio
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: An early-stage AI tensor framework with CPU tensors, autograd, and backend extension scaffolding.
|
|
5
|
+
Author: ModelStudio Contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/imattas/modelstudio
|
|
8
|
+
Project-URL: Repository, https://github.com/imattas/modelstudio
|
|
9
|
+
Project-URL: Issues, https://github.com/imattas/modelstudio/issues
|
|
10
|
+
Keywords: ai,autograd,deep-learning,neural-networks,tensor
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: numpy>=1.26
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
27
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
28
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
29
|
+
Requires-Dist: twine>=5; extra == "dev"
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
# ModelStudio
|
|
33
|
+
|
|
34
|
+
ModelStudio is an early-stage AI tensor framework. Version `0.2.0` provides a
|
|
35
|
+
CPU tensor/autograd MVP with neural-network modules, optimizers, serialization,
|
|
36
|
+
basic data loading, and small LLM-oriented building blocks.
|
|
37
|
+
|
|
38
|
+
It is not a PyTorch or TensorFlow replacement. CPU is the only working backend.
|
|
39
|
+
CUDA, ROCm, and oneAPI remain explicit scaffolds until real kernels are built
|
|
40
|
+
and tested.
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
From PyPI:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
python -m pip install modelstudio
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
For development:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
python -m pip install -e ".[dev]"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Feature Table
|
|
57
|
+
|
|
58
|
+
| Area | Status |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| CPU tensors | Working MVP |
|
|
61
|
+
| Autograd | Reverse-mode for core CPU ops |
|
|
62
|
+
| Reductions | `sum`, `mean`, `max` with axis and keepdims; `max` is value-only |
|
|
63
|
+
| Activations | ReLU, GELU, exp, log, tanh, sigmoid, SiLU, softmax, log-softmax |
|
|
64
|
+
| Losses | MSE and cross entropy |
|
|
65
|
+
| Modules | Parameters, buffers, state dicts, save/load |
|
|
66
|
+
| Layers | Linear, Embedding, LayerNorm, RMSNorm, TransformerBlock |
|
|
67
|
+
| Data | Dataset, TensorDataset, DataLoader |
|
|
68
|
+
| Compiler | Placeholder IR and passes |
|
|
69
|
+
|
|
70
|
+
## Backend Status
|
|
71
|
+
|
|
72
|
+
| Backend | Status |
|
|
73
|
+
| --- | --- |
|
|
74
|
+
| CPU | working MVP |
|
|
75
|
+
| CUDA | scaffold only |
|
|
76
|
+
| ROCm | scaffold only |
|
|
77
|
+
| oneAPI | scaffold only |
|
|
78
|
+
|
|
79
|
+
Unsupported accelerator devices fail with `ModelStudioBackendUnavailable`.
|
|
80
|
+
|
|
81
|
+
## Tensor Example
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
import modelstudio as ms
|
|
85
|
+
|
|
86
|
+
x = ms.randn((32, 784), requires_grad=True)
|
|
87
|
+
w = ms.randn((784, 10), requires_grad=True)
|
|
88
|
+
loss = (x @ w).mean()
|
|
89
|
+
loss.backward()
|
|
90
|
+
print(w.grad)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## MLP Example
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
import modelstudio as ms
|
|
97
|
+
from modelstudio import nn
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class MLP(nn.Module):
|
|
101
|
+
def __init__(self):
|
|
102
|
+
super().__init__()
|
|
103
|
+
self.fc1 = nn.Linear(784, 256)
|
|
104
|
+
self.fc2 = nn.Linear(256, 10)
|
|
105
|
+
|
|
106
|
+
def forward(self, x):
|
|
107
|
+
return self.fc2(ms.gelu(self.fc1(x)))
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
model = MLP()
|
|
111
|
+
optimizer = ms.optim.AdamW(model.parameters(), lr=3e-4)
|
|
112
|
+
x = ms.randn((16, 784))
|
|
113
|
+
target = ms.randn((16, 10))
|
|
114
|
+
loss = ms.mse_loss(model(x), target)
|
|
115
|
+
optimizer.zero_grad()
|
|
116
|
+
loss.backward()
|
|
117
|
+
optimizer.step()
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## State Dict and Save/Load
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
model = nn.Linear(4, 2)
|
|
124
|
+
ms.save(model.state_dict(), "model.ms")
|
|
125
|
+
state = ms.load("model.ms")
|
|
126
|
+
model.load_state_dict(state)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## DataLoader
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from modelstudio import data
|
|
133
|
+
|
|
134
|
+
dataset = data.TensorDataset(ms.randn((8, 4)), ms.arange(8))
|
|
135
|
+
loader = data.DataLoader(dataset, batch_size=2, shuffle=False)
|
|
136
|
+
for xb, yb in loader:
|
|
137
|
+
print(xb.shape, yb.shape)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Embedding
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
emb = nn.Embedding(num_embeddings=100, embedding_dim=32)
|
|
144
|
+
tokens = ms.tensor([[1, 2, 3]], dtype=ms.int64)
|
|
145
|
+
print(emb(tokens).shape)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Cross Entropy
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
logits = ms.randn((4, 10), requires_grad=True)
|
|
152
|
+
targets = ms.tensor([1, 2, 3, 4], dtype=ms.int64)
|
|
153
|
+
loss = ms.cross_entropy(logits, targets)
|
|
154
|
+
loss.backward()
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## TransformerBlock
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
block = nn.TransformerBlock(embed_dim=16, num_heads=4)
|
|
161
|
+
x = ms.randn((2, 8, 16), requires_grad=True)
|
|
162
|
+
y = block(x)
|
|
163
|
+
print(y.shape)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Commands
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
python -m pytest
|
|
170
|
+
python scripts/smoke_test.py
|
|
171
|
+
python examples/train_mlp.py
|
|
172
|
+
python examples/train_classifier.py
|
|
173
|
+
python examples/tiny_transformer.py
|
|
174
|
+
python examples/save_load.py
|
|
175
|
+
python benchmarks/bench_matmul.py
|
|
176
|
+
python benchmarks/bench_mlp.py
|
|
177
|
+
python benchmarks/bench_attention.py
|
|
178
|
+
python benchmarks/bench_dataloader.py
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Documentation
|
|
182
|
+
|
|
183
|
+
- [Tensor API](docs/tensor-api.md)
|
|
184
|
+
- [Neural network API](docs/nn.md)
|
|
185
|
+
- [Data utilities](docs/data.md)
|
|
186
|
+
- [Backend architecture](docs/backend-architecture.md)
|
|
187
|
+
- [Autograd design](docs/autograd.md)
|
|
188
|
+
- [Releasing](docs/releasing.md)
|
|
189
|
+
- [Contributing](CONTRIBUTING.md)
|
|
190
|
+
|
|
191
|
+
## Roadmap
|
|
192
|
+
|
|
193
|
+
- Expand tensor and autograd coverage.
|
|
194
|
+
- Wire native CPU kernels into Python bindings.
|
|
195
|
+
- Add tested CUDA, ROCm, and oneAPI packages when hardware-backed CI exists.
|
|
196
|
+
- Improve compiler graph capture and lowering.
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# ModelStudio
|
|
2
|
+
|
|
3
|
+
ModelStudio is an early-stage AI tensor framework. Version `0.2.0` provides a
|
|
4
|
+
CPU tensor/autograd MVP with neural-network modules, optimizers, serialization,
|
|
5
|
+
basic data loading, and small LLM-oriented building blocks.
|
|
6
|
+
|
|
7
|
+
It is not a PyTorch or TensorFlow replacement. CPU is the only working backend.
|
|
8
|
+
CUDA, ROCm, and oneAPI remain explicit scaffolds until real kernels are built
|
|
9
|
+
and tested.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
From PyPI:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
python -m pip install modelstudio
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
For development:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
python -m pip install -e ".[dev]"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Feature Table
|
|
26
|
+
|
|
27
|
+
| Area | Status |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| CPU tensors | Working MVP |
|
|
30
|
+
| Autograd | Reverse-mode for core CPU ops |
|
|
31
|
+
| Reductions | `sum`, `mean`, `max` with axis and keepdims; `max` is value-only |
|
|
32
|
+
| Activations | ReLU, GELU, exp, log, tanh, sigmoid, SiLU, softmax, log-softmax |
|
|
33
|
+
| Losses | MSE and cross entropy |
|
|
34
|
+
| Modules | Parameters, buffers, state dicts, save/load |
|
|
35
|
+
| Layers | Linear, Embedding, LayerNorm, RMSNorm, TransformerBlock |
|
|
36
|
+
| Data | Dataset, TensorDataset, DataLoader |
|
|
37
|
+
| Compiler | Placeholder IR and passes |
|
|
38
|
+
|
|
39
|
+
## Backend Status
|
|
40
|
+
|
|
41
|
+
| Backend | Status |
|
|
42
|
+
| --- | --- |
|
|
43
|
+
| CPU | working MVP |
|
|
44
|
+
| CUDA | scaffold only |
|
|
45
|
+
| ROCm | scaffold only |
|
|
46
|
+
| oneAPI | scaffold only |
|
|
47
|
+
|
|
48
|
+
Unsupported accelerator devices fail with `ModelStudioBackendUnavailable`.
|
|
49
|
+
|
|
50
|
+
## Tensor Example
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
import modelstudio as ms
|
|
54
|
+
|
|
55
|
+
x = ms.randn((32, 784), requires_grad=True)
|
|
56
|
+
w = ms.randn((784, 10), requires_grad=True)
|
|
57
|
+
loss = (x @ w).mean()
|
|
58
|
+
loss.backward()
|
|
59
|
+
print(w.grad)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## MLP Example
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
import modelstudio as ms
|
|
66
|
+
from modelstudio import nn
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class MLP(nn.Module):
|
|
70
|
+
def __init__(self):
|
|
71
|
+
super().__init__()
|
|
72
|
+
self.fc1 = nn.Linear(784, 256)
|
|
73
|
+
self.fc2 = nn.Linear(256, 10)
|
|
74
|
+
|
|
75
|
+
def forward(self, x):
|
|
76
|
+
return self.fc2(ms.gelu(self.fc1(x)))
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
model = MLP()
|
|
80
|
+
optimizer = ms.optim.AdamW(model.parameters(), lr=3e-4)
|
|
81
|
+
x = ms.randn((16, 784))
|
|
82
|
+
target = ms.randn((16, 10))
|
|
83
|
+
loss = ms.mse_loss(model(x), target)
|
|
84
|
+
optimizer.zero_grad()
|
|
85
|
+
loss.backward()
|
|
86
|
+
optimizer.step()
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## State Dict and Save/Load
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
model = nn.Linear(4, 2)
|
|
93
|
+
ms.save(model.state_dict(), "model.ms")
|
|
94
|
+
state = ms.load("model.ms")
|
|
95
|
+
model.load_state_dict(state)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## DataLoader
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from modelstudio import data
|
|
102
|
+
|
|
103
|
+
dataset = data.TensorDataset(ms.randn((8, 4)), ms.arange(8))
|
|
104
|
+
loader = data.DataLoader(dataset, batch_size=2, shuffle=False)
|
|
105
|
+
for xb, yb in loader:
|
|
106
|
+
print(xb.shape, yb.shape)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Embedding
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
emb = nn.Embedding(num_embeddings=100, embedding_dim=32)
|
|
113
|
+
tokens = ms.tensor([[1, 2, 3]], dtype=ms.int64)
|
|
114
|
+
print(emb(tokens).shape)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Cross Entropy
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
logits = ms.randn((4, 10), requires_grad=True)
|
|
121
|
+
targets = ms.tensor([1, 2, 3, 4], dtype=ms.int64)
|
|
122
|
+
loss = ms.cross_entropy(logits, targets)
|
|
123
|
+
loss.backward()
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## TransformerBlock
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
block = nn.TransformerBlock(embed_dim=16, num_heads=4)
|
|
130
|
+
x = ms.randn((2, 8, 16), requires_grad=True)
|
|
131
|
+
y = block(x)
|
|
132
|
+
print(y.shape)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Commands
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
python -m pytest
|
|
139
|
+
python scripts/smoke_test.py
|
|
140
|
+
python examples/train_mlp.py
|
|
141
|
+
python examples/train_classifier.py
|
|
142
|
+
python examples/tiny_transformer.py
|
|
143
|
+
python examples/save_load.py
|
|
144
|
+
python benchmarks/bench_matmul.py
|
|
145
|
+
python benchmarks/bench_mlp.py
|
|
146
|
+
python benchmarks/bench_attention.py
|
|
147
|
+
python benchmarks/bench_dataloader.py
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Documentation
|
|
151
|
+
|
|
152
|
+
- [Tensor API](docs/tensor-api.md)
|
|
153
|
+
- [Neural network API](docs/nn.md)
|
|
154
|
+
- [Data utilities](docs/data.md)
|
|
155
|
+
- [Backend architecture](docs/backend-architecture.md)
|
|
156
|
+
- [Autograd design](docs/autograd.md)
|
|
157
|
+
- [Releasing](docs/releasing.md)
|
|
158
|
+
- [Contributing](CONTRIBUTING.md)
|
|
159
|
+
|
|
160
|
+
## Roadmap
|
|
161
|
+
|
|
162
|
+
- Expand tensor and autograd coverage.
|
|
163
|
+
- Wire native CPU kernels into Python bindings.
|
|
164
|
+
- Add tested CUDA, ROCm, and oneAPI packages when hardware-backed CI exists.
|
|
165
|
+
- Improve compiler graph capture and lowering.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import platform
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
import modelstudio as ms
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def timeit(fn, iterations: int = 20, warmup: int = 5) -> float:
|
|
11
|
+
for _ in range(warmup):
|
|
12
|
+
fn()
|
|
13
|
+
start = time.perf_counter()
|
|
14
|
+
for _ in range(iterations):
|
|
15
|
+
fn()
|
|
16
|
+
return (time.perf_counter() - start) / iterations
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def main() -> None:
|
|
20
|
+
shape = (2, 4, 16, 8)
|
|
21
|
+
iterations = 20
|
|
22
|
+
warmup = 5
|
|
23
|
+
q = ms.randn(shape)
|
|
24
|
+
k = ms.randn(shape)
|
|
25
|
+
v = ms.randn(shape)
|
|
26
|
+
|
|
27
|
+
print(f"Python: {platform.python_version()}")
|
|
28
|
+
print(f"NumPy: {np.__version__}")
|
|
29
|
+
print(f"ModelStudio: {ms.__version__}")
|
|
30
|
+
print(f"Shape: {shape}")
|
|
31
|
+
print(f"Warmup: {warmup}")
|
|
32
|
+
print(f"Iterations: {iterations}")
|
|
33
|
+
print("Backend: CPU MVP")
|
|
34
|
+
elapsed = timeit(lambda: ms.scaled_dot_product_attention(q, k, v, causal=True), iterations, warmup)
|
|
35
|
+
print(f"Attention avg: {elapsed * 1_000:.3f} ms")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if __name__ == "__main__":
|
|
39
|
+
main()
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import platform
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
import modelstudio as ms
|
|
7
|
+
import numpy as np
|
|
8
|
+
from modelstudio import data
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def main() -> None:
|
|
12
|
+
samples = 1024
|
|
13
|
+
features = 32
|
|
14
|
+
batch_size = 64
|
|
15
|
+
iterations = 20
|
|
16
|
+
warmup = 5
|
|
17
|
+
dataset = data.TensorDataset(ms.randn((samples, features)), ms.arange(samples))
|
|
18
|
+
loader = data.DataLoader(dataset, batch_size=batch_size, shuffle=False)
|
|
19
|
+
|
|
20
|
+
def consume() -> int:
|
|
21
|
+
count = 0
|
|
22
|
+
for xb, _ in loader:
|
|
23
|
+
count += xb.shape[0]
|
|
24
|
+
return count
|
|
25
|
+
|
|
26
|
+
for _ in range(warmup):
|
|
27
|
+
consume()
|
|
28
|
+
start = time.perf_counter()
|
|
29
|
+
for _ in range(iterations):
|
|
30
|
+
consume()
|
|
31
|
+
elapsed = (time.perf_counter() - start) / iterations
|
|
32
|
+
|
|
33
|
+
print(f"Python: {platform.python_version()}")
|
|
34
|
+
print(f"NumPy: {np.__version__}")
|
|
35
|
+
print(f"ModelStudio: {ms.__version__}")
|
|
36
|
+
print(f"Samples: {samples}")
|
|
37
|
+
print(f"Features: {features}")
|
|
38
|
+
print(f"Batch size: {batch_size}")
|
|
39
|
+
print(f"Warmup: {warmup}")
|
|
40
|
+
print(f"Iterations: {iterations}")
|
|
41
|
+
print("Backend: CPU MVP")
|
|
42
|
+
print(f"DataLoader avg: {elapsed * 1_000:.3f} ms")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
if __name__ == "__main__":
|
|
46
|
+
main()
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import platform
|
|
3
4
|
import time
|
|
4
5
|
|
|
5
6
|
import modelstudio as ms
|
|
6
7
|
import numpy as np
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
def timeit(fn, iterations: int =
|
|
10
|
+
def timeit(fn, iterations: int = 30, warmup: int = 5) -> float:
|
|
11
|
+
for _ in range(warmup):
|
|
12
|
+
fn()
|
|
10
13
|
start = time.perf_counter()
|
|
11
14
|
for _ in range(iterations):
|
|
12
15
|
fn()
|
|
@@ -20,11 +23,17 @@ def main() -> None:
|
|
|
20
23
|
a_ms = ms.tensor(a_np)
|
|
21
24
|
b_ms = ms.tensor(b_np)
|
|
22
25
|
|
|
26
|
+
print(f"Python: {platform.python_version()}")
|
|
27
|
+
print(f"NumPy: {np.__version__}")
|
|
28
|
+
print(f"ModelStudio: {ms.__version__}")
|
|
29
|
+
print(f"Shape: {shape} x {shape}")
|
|
30
|
+
print("Backend: CPU MVP")
|
|
31
|
+
|
|
23
32
|
numpy_time = timeit(lambda: a_np @ b_np)
|
|
24
33
|
modelstudio_time = timeit(lambda: a_ms @ b_ms)
|
|
25
34
|
|
|
26
|
-
print(f"NumPy matmul: {numpy_time * 1_000:.3f} ms")
|
|
27
|
-
print(f"ModelStudio CPU:
|
|
35
|
+
print(f"NumPy matmul avg: {numpy_time * 1_000:.3f} ms")
|
|
36
|
+
print(f"ModelStudio CPU avg: {modelstudio_time * 1_000:.3f} ms")
|
|
28
37
|
|
|
29
38
|
|
|
30
39
|
if __name__ == "__main__":
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import platform
|
|
3
4
|
import time
|
|
4
5
|
|
|
5
6
|
import modelstudio as ms
|
|
7
|
+
import numpy as np
|
|
6
8
|
from modelstudio import nn
|
|
7
9
|
|
|
8
10
|
|
|
@@ -21,11 +23,19 @@ def main() -> None:
|
|
|
21
23
|
x = ms.randn((64, 128), requires_grad=True)
|
|
22
24
|
target = ms.randn((64, 64))
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
print(f"Python: {platform.python_version()}")
|
|
27
|
+
print(f"NumPy: {np.__version__}")
|
|
28
|
+
print(f"ModelStudio: {ms.__version__}")
|
|
29
|
+
print("Backend: CPU MVP")
|
|
27
30
|
|
|
28
31
|
iterations = 20
|
|
32
|
+
warmup = 5
|
|
33
|
+
for _ in range(warmup):
|
|
34
|
+
model.zero_grad()
|
|
35
|
+
x.zero_grad()
|
|
36
|
+
loss = ms.mse_loss(model(x), target)
|
|
37
|
+
loss.backward()
|
|
38
|
+
|
|
29
39
|
start = time.perf_counter()
|
|
30
40
|
for _ in range(iterations):
|
|
31
41
|
model.zero_grad()
|
|
@@ -33,7 +43,7 @@ def main() -> None:
|
|
|
33
43
|
loss = ms.mse_loss(model(x), target)
|
|
34
44
|
loss.backward()
|
|
35
45
|
elapsed = (time.perf_counter() - start) / iterations
|
|
36
|
-
print(f"ModelStudio MLP forward/backward: {elapsed * 1_000:.3f} ms")
|
|
46
|
+
print(f"ModelStudio MLP forward/backward avg: {elapsed * 1_000:.3f} ms")
|
|
37
47
|
|
|
38
48
|
|
|
39
49
|
if __name__ == "__main__":
|
|
@@ -5,14 +5,17 @@
|
|
|
5
5
|
namespace modelstudio::cuda {
|
|
6
6
|
|
|
7
7
|
Tensor CUDABackend::empty(const Shape&, DType) {
|
|
8
|
+
// TODO: Implement CUDA allocation and register this backend only when built and tested.
|
|
8
9
|
throw Error("CUDA backend scaffold is present, but CUDA kernels are not implemented");
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
Tensor CUDABackend::add(const Tensor&, const Tensor&) {
|
|
13
|
+
// TODO: Add a tested CUDA elementwise add kernel.
|
|
12
14
|
throw Error("CUDA add kernel is not implemented");
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
Tensor CUDABackend::matmul(const Tensor&, const Tensor&) {
|
|
18
|
+
// TODO: Add a tested CUDA matmul kernel or cuBLAS integration.
|
|
16
19
|
throw Error("CUDA matmul kernel is not implemented");
|
|
17
20
|
}
|
|
18
21
|
|
|
@@ -5,14 +5,17 @@
|
|
|
5
5
|
namespace modelstudio::oneapi {
|
|
6
6
|
|
|
7
7
|
Tensor OneAPIBackend::empty(const Shape&, DType) {
|
|
8
|
+
// TODO: Implement SYCL allocation and register this backend only when built and tested.
|
|
8
9
|
throw Error("oneAPI backend scaffold is present, but SYCL kernels are not implemented");
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
Tensor OneAPIBackend::add(const Tensor&, const Tensor&) {
|
|
13
|
+
// TODO: Add a tested SYCL elementwise add kernel.
|
|
12
14
|
throw Error("oneAPI add kernel is not implemented");
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
Tensor OneAPIBackend::matmul(const Tensor&, const Tensor&) {
|
|
18
|
+
// TODO: Add a tested SYCL matmul kernel or oneMKL integration.
|
|
16
19
|
throw Error("oneAPI matmul kernel is not implemented");
|
|
17
20
|
}
|
|
18
21
|
|
|
@@ -5,14 +5,17 @@
|
|
|
5
5
|
namespace modelstudio::rocm {
|
|
6
6
|
|
|
7
7
|
Tensor ROCmBackend::empty(const Shape&, DType) {
|
|
8
|
+
// TODO: Implement HIP allocation and register this backend only when built and tested.
|
|
8
9
|
throw Error("ROCm backend scaffold is present, but HIP kernels are not implemented");
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
Tensor ROCmBackend::add(const Tensor&, const Tensor&) {
|
|
13
|
+
// TODO: Add a tested HIP elementwise add kernel.
|
|
12
14
|
throw Error("ROCm add kernel is not implemented");
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
Tensor ROCmBackend::matmul(const Tensor&, const Tensor&) {
|
|
18
|
+
// TODO: Add a tested HIP matmul kernel or rocBLAS integration.
|
|
16
19
|
throw Error("ROCm matmul kernel is not implemented");
|
|
17
20
|
}
|
|
18
21
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Autograd
|
|
2
|
+
|
|
3
|
+
ModelStudio implements a small reverse-mode autograd engine for CPU tensors.
|
|
4
|
+
|
|
5
|
+
## Graph Construction
|
|
6
|
+
|
|
7
|
+
When gradient mode is enabled, tensor operations create result tensors with:
|
|
8
|
+
|
|
9
|
+
- parent tensor references
|
|
10
|
+
- a `grad_fn` label
|
|
11
|
+
- a backward closure that receives the upstream gradient
|
|
12
|
+
|
|
13
|
+
Operations skip graph construction if no input requires gradients or if the code
|
|
14
|
+
is running under `ms.no_grad()`.
|
|
15
|
+
|
|
16
|
+
## Backward Pass
|
|
17
|
+
|
|
18
|
+
`Tensor.backward()` performs a topological sort from the output tensor, seeds the
|
|
19
|
+
output gradient, then walks the graph in reverse topological order. Each backward
|
|
20
|
+
closure accumulates gradients into parent tensors.
|
|
21
|
+
|
|
22
|
+
Scalar outputs default to a gradient of one. Non-scalar outputs require an
|
|
23
|
+
explicit gradient.
|
|
24
|
+
|
|
25
|
+
## Gradient Accumulation
|
|
26
|
+
|
|
27
|
+
Gradients accumulate by default, matching the common neural-network training
|
|
28
|
+
workflow. Call `zero_grad()` on tensors, modules, or optimizers before a new
|
|
29
|
+
training step when accumulation is not desired.
|
|
30
|
+
|
|
31
|
+
## Broadcasting
|
|
32
|
+
|
|
33
|
+
Forward broadcasting can expand dimensions. During backward, ModelStudio reduces
|
|
34
|
+
the upstream gradient back to each input's original shape with `unbroadcast`.
|
|
35
|
+
This handles extra leading dimensions and dimensions of size one.
|
|
36
|
+
|
|
37
|
+
## `no_grad`
|
|
38
|
+
|
|
39
|
+
`ms.no_grad()` temporarily disables graph recording:
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
with ms.no_grad():
|
|
43
|
+
y = x * 2
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
This is used by optimizers and inference code.
|
|
47
|
+
|
|
48
|
+
## Limitations
|
|
49
|
+
|
|
50
|
+
- CPU tensors only
|
|
51
|
+
- Dynamic graph only
|
|
52
|
+
- No higher-order gradients
|
|
53
|
+
- No in-place autograd correctness checks
|
|
54
|
+
- Limited operation coverage
|
|
55
|
+
- No graph pruning beyond Python reference lifetimes
|