ramnet-ops 0.1.0rc0__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.
Files changed (35) hide show
  1. ramnet_ops-0.1.0rc0/LICENSE +21 -0
  2. ramnet_ops-0.1.0rc0/MANIFEST.in +7 -0
  3. ramnet_ops-0.1.0rc0/PKG-INFO +309 -0
  4. ramnet_ops-0.1.0rc0/README.md +285 -0
  5. ramnet_ops-0.1.0rc0/RELEASING.md +47 -0
  6. ramnet_ops-0.1.0rc0/csrc/cuda_utils.cuh +390 -0
  7. ramnet_ops-0.1.0rc0/csrc/ram_attn.cuh +46 -0
  8. ramnet_ops-0.1.0rc0/csrc/ram_attn_bind.cpp +127 -0
  9. ramnet_ops-0.1.0rc0/csrc/ram_attn_ops.cpp +392 -0
  10. ramnet_ops-0.1.0rc0/csrc/ram_attn_ops.h +174 -0
  11. ramnet_ops-0.1.0rc0/csrc/ram_attn_segment_parallel.cu +927 -0
  12. ramnet_ops-0.1.0rc0/csrc/ram_attn_segment_parallel.cuh +76 -0
  13. ramnet_ops-0.1.0rc0/csrc/ram_attn_topk_addr.cu +469 -0
  14. ramnet_ops-0.1.0rc0/csrc/ram_attn_topk_addr.cuh +50 -0
  15. ramnet_ops-0.1.0rc0/csrc/ram_attn_topk_autoregressive.cu +380 -0
  16. ramnet_ops-0.1.0rc0/csrc/ram_attn_topk_autoregressive.cuh +58 -0
  17. ramnet_ops-0.1.0rc0/csrc/torch_compat.h +224 -0
  18. ramnet_ops-0.1.0rc0/csrc/torch_compat_cuda.cuh +86 -0
  19. ramnet_ops-0.1.0rc0/csrc/vector_ops.cuh +463 -0
  20. ramnet_ops-0.1.0rc0/pyproject.toml +35 -0
  21. ramnet_ops-0.1.0rc0/setup.cfg +4 -0
  22. ramnet_ops-0.1.0rc0/setup.py +97 -0
  23. ramnet_ops-0.1.0rc0/src/ramnet_ops/__init__.py +5 -0
  24. ramnet_ops-0.1.0rc0/src/ramnet_ops/impl/__init__.py +0 -0
  25. ramnet_ops-0.1.0rc0/src/ramnet_ops/impl/_cuda_autograd.py +336 -0
  26. ramnet_ops-0.1.0rc0/src/ramnet_ops/impl/_cuda_config.py +11 -0
  27. ramnet_ops-0.1.0rc0/src/ramnet_ops/impl/cuda_impl.py +325 -0
  28. ramnet_ops-0.1.0rc0/src/ramnet_ops/impl/torch_impl.py +223 -0
  29. ramnet_ops-0.1.0rc0/src/ramnet_ops/ram_attn.py +304 -0
  30. ramnet_ops-0.1.0rc0/src/ramnet_ops.egg-info/PKG-INFO +309 -0
  31. ramnet_ops-0.1.0rc0/src/ramnet_ops.egg-info/SOURCES.txt +33 -0
  32. ramnet_ops-0.1.0rc0/src/ramnet_ops.egg-info/dependency_links.txt +1 -0
  33. ramnet_ops-0.1.0rc0/src/ramnet_ops.egg-info/not-zip-safe +1 -0
  34. ramnet_ops-0.1.0rc0/src/ramnet_ops.egg-info/requires.txt +3 -0
  35. ramnet_ops-0.1.0rc0/src/ramnet_ops.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 Kaicheng Xiao, Haotian Li, Liran Dong
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,7 @@
1
+ include LICENSE
2
+ include README.md
3
+ include RELEASING.md
4
+ include csrc/*.cpp
5
+ include csrc/*.cu
6
+ include csrc/*.cuh
7
+ include csrc/*.h
@@ -0,0 +1,309 @@
1
+ Metadata-Version: 2.4
2
+ Name: ramnet-ops
3
+ Version: 0.1.0rc0
4
+ Summary: PyTorch and CUDA operators for RAM-Net attention
5
+ Maintainer: Kaicheng Xiao
6
+ License-Expression: MIT
7
+ Project-URL: Source, https://github.com/MuonCat/RAM-Net
8
+ Project-URL: Issues, https://github.com/MuonCat/RAM-Net/issues
9
+ Project-URL: Documentation, https://github.com/MuonCat/RAM-Net/tree/main/packages/ramnet-ops
10
+ Keywords: pytorch,cuda,attention,ram-net
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: C++
15
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: torch>=2.5
20
+ Requires-Dist: einops
21
+ Requires-Dist: numpy
22
+ Dynamic: license-file
23
+ Dynamic: requires-dist
24
+
25
+ <div align="center">
26
+
27
+ <img src="https://raw.githubusercontent.com/MuonCat/RAM-Net/main/assets/logo.png" alt="RAM-Net" width="420">
28
+
29
+ # ramnet-ops
30
+
31
+ [![arXiv](https://img.shields.io/badge/arXiv-2602.11958-b31b1b.svg?logo=arxiv&logoColor=white)](https://arxiv.org/abs/2602.11958)
32
+ [![Project Page](https://img.shields.io/badge/Project-Page-1f6feb.svg)](https://muoncat.github.io/ramnet_web/)
33
+ [![Weights](https://img.shields.io/badge/Weights-Hugging%20Face-FFD21E?logo=huggingface&logoColor=white)](https://huggingface.co/kaichengx/RAM-Net-Models/tree/main)
34
+ [![GitHub](https://img.shields.io/badge/GitHub-RAM--Net-181717?logo=github&logoColor=white)](https://github.com/MuonCat/RAM-Net)
35
+ [![Models](https://img.shields.io/badge/Models-ramnet-82afe6?logo=pytorch&logoColor=white)](https://github.com/MuonCat/RAM-Net/blob/main/packages/ramnet/README.md)
36
+ [![Operators](https://img.shields.io/badge/Operators-ramnet--ops-76B900?logo=nvidia&logoColor=white)](https://github.com/MuonCat/RAM-Net/blob/main/packages/ramnet-ops/README.md)
37
+ [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/MuonCat/RAM-Net/blob/main/LICENSE)
38
+
39
+ </div>
40
+
41
+ The attention computation core of RAM-Net: sparse address decoding, memory updates, readout, and autograd.
42
+ Import as `ramnet_ops` for CUDA kernels and a PyTorch reference implementation.
43
+
44
+ ## Structure
45
+
46
+ ```text
47
+ .
48
+ |-- src/
49
+ | `-- ramnet_ops/
50
+ | |-- ram_attn.py # Public API, input normalization, backend selection
51
+ | `-- impl/
52
+ | |-- torch_impl.py # PyTorch reference
53
+ | |-- cuda_impl.py # CUDA wrappers and segment layout
54
+ | |-- _cuda_autograd.py # FakeTensor and autograd registrations
55
+ | `-- _cuda_config.py # Address and index-capacity checks
56
+ `-- csrc/
57
+ |-- ram_attn_bind.cpp # Torch schemas, CUDA registration, extension entry point
58
+ |-- ram_attn_ops.cpp # Native wrappers, output allocation, kernel dispatch
59
+ |-- ram_attn_*.cu # Address, segment, and autoregressive kernels
60
+ `-- torch_compat* # Ordinary/stable Torch ABI interfaces
61
+ ```
62
+
63
+ ## Installation
64
+
65
+ Requires:
66
+
67
+ ```text
68
+ Python >= 3.10
69
+
70
+ ramnet-ops
71
+ |-- torch >= 2.5
72
+ |-- einops
73
+ `-- numpy
74
+ ```
75
+
76
+ ### 1. Install dependencies
77
+
78
+ If PyTorch is not already installed, we **recommend PyTorch ≥ 2.10 with CUDA 13.0 (`cu130`)** for the default ops wheels below.
79
+ See the [official installation guide](https://pytorch.org/get-started/locally/) for installation commands.
80
+ Then install the remaining dependencies from TestPyPI / PyPI:
81
+
82
+ ```bash
83
+ python -m pip install einops numpy
84
+ ```
85
+
86
+ ### 2. Install ramnet-ops
87
+
88
+ The default `ramnet-ops` wheels use both **Python and PyTorch stable ABIs** and target **CUDA 13.0 (`cu130`)**.
89
+ If your environment meets **all** of the following requirements, install directly from pip:
90
+
91
+ - **Python:** CPython ≥ 3.10.
92
+ - **PyTorch:** ≥ 2.10 with CUDA 13.0.
93
+ - **GPU:** SM 8.9, 9.0, 10.0, or 12.0.
94
+ - **Platform:** Windows x64 or Linux x86_64 with glibc ≥ 2.35.
95
+
96
+ ```bash
97
+ python -m pip install -i https://test.pypi.org/simple/ ramnet-ops
98
+ ```
99
+
100
+ Prebuilt wheels need no local compiler or CUDA Toolkit.
101
+ If your environment **does not meet all of the requirements above**, follow [Other Torch/CUDA builds (GitHub Releases)](#other-torchcuda-builds-github-releases) below to select another prebuilt wheel.
102
+
103
+ #### Other Torch/CUDA builds (GitHub Releases)
104
+
105
+ GitHub Releases provides additional wheels for older PyTorch versions, other CUDA builds, and GPUs outside the default `cu130` targets.
106
+ Open [GitHub Releases](https://github.com/MuonCat/RAM-Net/releases), select the desired package version under `ramnet-ops/v<VERSION>`, and expand **Assets** to find its `.whl` files.
107
+ Choose a wheel using [the selection guide below](#choose-a-matching-wheel), then copy its download link into `python -m pip install "<wheel URL>"`.
108
+ You must select the Torch/CUDA variant yourself; pip does not infer it from your environment.
109
+
110
+ With the matching PyTorch build already installed, the commands look like this for package version `0.1.0rc0`:
111
+
112
+ Windows x64, **Torch 2.8.0 / CUDA 12.8** (ordinary ABI):
113
+
114
+ ```bash
115
+ python -m pip install "https://github.com/MuonCat/RAM-Net/releases/download/ramnet-ops%2Fv0.1.0rc0/ramnet_ops-0.1.0rc0-1torch2_8_0cu128-cp310-abi3-win_amd64.whl"
116
+ ```
117
+
118
+ Linux x86_64, **Torch ≥ 2.10 / CUDA 12.6** (stable ABI):
119
+
120
+ ```bash
121
+ python -m pip install "https://github.com/MuonCat/RAM-Net/releases/download/ramnet-ops%2Fv0.1.0rc0/ramnet_ops-0.1.0rc0-1torchabi2_10cu126-cp310-abi3-manylinux_2_35_x86_64.whl"
122
+ ```
123
+
124
+ ##### Choose a matching wheel
125
+
126
+ First, match the **Torch ABI** marker in the filename to your installed PyTorch version:
127
+
128
+ - **Ordinary ABI (`torch2_6_0` or `torch2_8_0`):** requires exactly **PyTorch 2.6.0** or **2.8.0**, respectively.
129
+ - **Stable ABI (`torchabi2_10`):** supports **PyTorch ≥ 2.10** with a matching CUDA/platform combination; the Torch 2.14 SDK used to build these wheels is not required at runtime.
130
+
131
+ Next, find your **GPU row** and **PyTorch column** in the table below.
132
+ Each cell lists the available CUDA builds: choose one matching your installed PyTorch's CUDA version (`torch.version.cuda`), such as `cu126` for CUDA 12.6.
133
+
134
+ | [GPU CC](https://developer.nvidia.com/cuda/gpus) (representative GPUs) | PyTorch 2.6.0 | PyTorch 2.8.0 | PyTorch ≥ 2.10 |
135
+ | --- | --- | --- | --- |
136
+ | 7.5 (T4 / RTX 20) | 11.8 | ❌ | ❌ |
137
+ | 8.0 (A100) | 11.8 / 12.6 | 12.6 | 12.6 |
138
+ | 8.6 (RTX 30) | 11.8 / 12.6 | 12.6 | 12.6 |
139
+ | 8.9 (RTX 40 / L40S) | 12.6 | 12.6 / 12.8 | 12.6 / **13.0 ★** |
140
+ | 9.0 (H100 / H200) | 12.6 | 12.6 / 12.8 | 12.6 / **13.0 ★** |
141
+ | 10.0 (B200 / GB200) | ❌ | 12.8 | **13.0 ★** |
142
+ | 12.0 (RTX 50) | ❌ | 12.8 | **13.0 ★** |
143
+
144
+ ★ marks the default TestPyPI / PyPI build; ❌ means no prebuilt wheel is provided for that combination.
145
+
146
+ This table describes the architectures included in our wheels, not every GPU supported by each CUDA Toolkit.
147
+
148
+ Finally, match the **platform** suffix: `win_amd64` for Windows x64 or `manylinux_2_35_x86_64` for Linux x86_64 with glibc ≥ 2.35.
149
+ All wheels use `cp310-abi3` for GIL-enabled **CPython ≥ 3.10**.
150
+ Check the driver requirements below before installing; if no wheel matches your environment, see [From source](#from-source).
151
+
152
+ ##### NVIDIA drivers
153
+
154
+ The table lists driver baselines from NVIDIA's CUDA GA release notes; use these or newer drivers that support your GPU.
155
+
156
+ | CUDA | Windows driver | Linux driver |
157
+ | --- | --- | --- |
158
+ | [11.8](https://docs.nvidia.com/cuda/archive/11.8.0/cuda-toolkit-release-notes/index.html) | ≥ 522.06 | ≥ 520.61.05 |
159
+ | [12.6](https://docs.nvidia.com/cuda/archive/12.6.0/cuda-toolkit-release-notes/index.html) | ≥ 560.76 | ≥ 560.28.03 |
160
+ | [12.8](https://docs.nvidia.com/cuda/archive/12.8.0/cuda-toolkit-release-notes/index.html) | ≥ 570.65 | ≥ 570.26 |
161
+ | **[13.0 ★](https://docs.nvidia.com/cuda/archive/13.0.0/cuda-toolkit-release-notes/index.html)** | **R580+** | **≥ 580.65.06** |
162
+
163
+ CUDA 13.0 no longer bundles a Windows driver; NVIDIA requires the R580 branch or newer.
164
+ CUDA 11.x/12.x may run on older drivers through [minor-version compatibility](https://docs.nvidia.com/deploy/cuda-compatibility/minor-version-compatibility.html), subject to feature and PTX restrictions; newer GPUs may require newer drivers.
165
+
166
+ #### From source
167
+
168
+ Source installation supports both CUDA extension builds and PyTorch-only installations.
169
+
170
+ ##### With CUDA extension
171
+
172
+ Use this option when no prebuilt wheel matches your environment or when modifying the CUDA operators.
173
+ Prepare the build environment first:
174
+
175
+ - **PyTorch:** install the intended CUDA build (Torch ≥ 2.5).
176
+ - **CUDA Toolkit:** install a version compatible with that PyTorch build, including `nvcc`.
177
+ - **C++ compiler:** use a compiler supported by the Toolkit; on Windows, run the commands in an **x64 Native Tools Command Prompt for VS 2022**.
178
+
179
+ By default (`RAMNET_TORCH_STABLE_ABI=auto`), Torch 2.5–2.13 builds use the ordinary ABI and require that exact Torch version at runtime; Torch ≥ 2.14 builds use stable ABI targeting Torch ≥ 2.10.
180
+
181
+ Install the build tools in the same Python environment as PyTorch:
182
+
183
+ ```bash
184
+ python -m pip install "setuptools>=77.0.3" wheel ninja
185
+ ```
186
+
187
+ Then choose one of the following sources.
188
+
189
+ **Download and build with pip** — install the published source archive from TestPyPI / PyPI:
190
+
191
+ ```bash
192
+ python -m pip install -i https://test.pypi.org/simple/ ramnet-ops --no-binary=ramnet-ops --no-build-isolation
193
+ ```
194
+
195
+ **Clone from GitHub and build locally** — use the repository source, for example when modifying the operators:
196
+
197
+ ```bash
198
+ git clone https://github.com/MuonCat/RAM-Net.git
199
+ cd RAM-Net
200
+ python -m pip install ./packages/ramnet-ops --no-build-isolation
201
+ ```
202
+
203
+ The CUDA extension is compiled during installation.
204
+
205
+ ##### Environment variables
206
+
207
+ Set these before source installation; ABI and architecture settings apply only when building the CUDA extension.
208
+
209
+ | Variable | Default | Purpose |
210
+ | --- | --- | --- |
211
+ | `SKIP_CUDA` | `0` | Set to `1` to skip the CUDA extension and install only the Python package and PyTorch reference. |
212
+ | `RAMNET_TORCH_STABLE_ABI` | `auto` | Select the ABI from the build SDK; `0` forces ordinary ABI; `1` forces stable ABI and requires Torch ≥ 2.14 to build. |
213
+ | `TORCH_CUDA_ARCH_LIST` | GPUs visible during the build | Set the target GPU architectures explicitly, e.g. `8.9 9.0`. |
214
+
215
+ Set `SKIP_CUDA=1` to install from source without building the native CUDA extension.
216
+ PyTorch, `einops`, and `numpy` are still required; a CUDA Toolkit and C++ compiler are not needed.
217
+
218
+ ## Quick start
219
+
220
+ `random_access_memory_attention` performs the sparse reads and writes of a RAM-Net layer, covering address decoding, CAPE, and the Gated Sparse Update.
221
+ It takes address logits, values, and forgetting modulators, and returns the read outputs and the updated slot/mass state.
222
+
223
+ The table maps paper notation to parameters and tensor dimensions in the example below.
224
+ `B`, `T`, and `H` denote batch size, sequence length, and number of heads.
225
+
226
+ | Paper quantity / symbol | Operator parameter / axis |
227
+ | :---: | :---: |
228
+ | Address order $U$ (digits per address) | `U` |
229
+ | Address radix $d_p$ (values per digit) | `P` |
230
+ | Value dimension $d_v$ | `C` |
231
+ | Slots per head $d_p^U$ | `A = P ** U` |
232
+ | Selected slots $K$ | `top_k` |
233
+
234
+ This example computes attention outputs and the updated state, then backpropagates through both:
235
+
236
+ ```python
237
+ import torch
238
+ from ramnet_ops import random_access_memory_attention
239
+
240
+ device = "cuda" # Set to "cpu" for the PyTorch reference.
241
+ backend = "cuda" if device == "cuda" else "torch"
242
+ torch.manual_seed(0)
243
+
244
+ B, T, H, U, P, C = 2, 32, 4, 3, 4, 32
245
+ w_addr = torch.randn(B, T, H, U, P, device=device, requires_grad=True)
246
+ r_addr = torch.randn(B, T, H, U, P, device=device, requires_grad=True)
247
+ values = torch.randn(B, T, H, C, device=device, requires_grad=True)
248
+ gamma = torch.randn(B, T, H, device=device, requires_grad=True)
249
+
250
+ y, (slot, mass) = random_access_memory_attention(
251
+ w_addr, r_addr, values, gamma,
252
+ embed_num=2, top_k=8,
253
+ impl_backend=backend,
254
+ )
255
+ loss = y.square().mean() + slot.square().mean() + mass.square().mean()
256
+ loss.backward()
257
+ print(y.shape) # (B, T, H, C)
258
+ print(slot.shape) # (B, H, P ** U, C)
259
+ print(mass.shape) # (B, H, P ** U)
260
+ ```
261
+
262
+ `embed_num` selects how many heads, starting from head 0, use **Cyclic Address Positional Embedding (CAPE)** to cyclically shift read and write slot indices by token position.
263
+ With `H=4` and `embed_num=2`, heads 0 and 1 use CAPE, while heads 2 and 3 address by content alone.
264
+ Its range is `0` to `H`: `0` disables CAPE and `H` enables it for all heads.
265
+
266
+ From the repository root, run [ops_smoke.py](../../examples/ops_smoke.py) with `python examples/ops_smoke.py --device cuda`, or use `--device cpu` for the PyTorch reference.
267
+ This example demonstrates the API; it is not an experiment configuration.
268
+
269
+ ### Arguments
270
+
271
+ - `w_addr`, `r_addr`: write and read address logits of shape `(…, T, …, H, U, P)`. The operator applies a softmax over each digit.
272
+ - `values`: values to write, of shape `(…, T, …, H, C)`. The output `y` has the same shape and dtype.
273
+ - `gamma`: forgetting modulator of shape `(…, T, …, H)`, computed by the model for each token. Larger values overwrite old slot content faster.
274
+ - `init_ram`: the `(slot, mass)` state returned by a previous call, used to continue a sequence. Without it, every slot starts empty.
275
+ - `inplace`: if `True`, updates the `init_ram` tensors in place instead of returning new ones. This requires contiguous FP32 state and does not support gradients.
276
+ - `mask`: marks valid tokens. Masked tokens are not written to the state, and their outputs should be ignored.
277
+ - `embed_num`: number of heads that use CAPE, counted from head 0. These heads shift each token's addresses by its position.
278
+ - `top_k`: `K`, given as an int or a `(write_k, read_k)` pair. `None` keeps all slots and is supported only by the PyTorch backend.
279
+ - `top_k_re_norm`: explicitly enables renormalization after Top-K. Accepts a bool for both sides, or a two-item tuple/list of `(write, read)` bools; defaults to `False`.
280
+ - `t_dim`: index of the time axis. Dimensions before `H` other than the time axis are broadcast as batch dimensions.
281
+ - `impl_backend`: `'cuda'` or `'torch'`. By default, CUDA inputs use the CUDA backend when supported and otherwise fall back to PyTorch with a warning.
282
+
283
+ ## CUDA execution
284
+
285
+ The CUDA backend automatically selects between **autoregressive** and **parallel** execution.
286
+
287
+ **Autoregressive mode** handles single-token inputs (`T = 1`) when no input requires gradients.
288
+ A dedicated kernel decodes the current token's addresses, updates the selected write slots, and reads the selected read slots directly.
289
+
290
+ **Parallel mode** handles all other inputs, including training and prefill.
291
+ It decodes all tokens' addresses in parallel, treating each selected read or write access as an **event**.
292
+ Events targeting the same `(batch, head, slot)` are grouped into a **segment**.
293
+ The kernels process independent segments and their value channels in parallel while preserving causal dependencies within each segment, then accumulate read contributions into the token outputs.
294
+
295
+ ## Autograd and compile
296
+
297
+ Operators are registered under `torch.ops.ramnet_ops` with FakeTensor and first-order autograd support.
298
+ Compile coverage targets fixed shapes/configuration with `dynamic=False`, tested through `aot_eager`;
299
+ it does not establish Inductor or CUDA Graph support.
300
+
301
+ Segment capacity is `B * H * A`; event capacity is `B * H * T_padded * (write_k + read_k)`.
302
+ Masks do not reduce these allocations.
303
+ Higher-order gradients are not supported.
304
+
305
+ ## Development
306
+
307
+ See [RELEASING](RELEASING.md) for tests and publishing.
308
+
309
+ MIT License. See [LICENSE](LICENSE).
@@ -0,0 +1,285 @@
1
+ <div align="center">
2
+
3
+ <img src="https://raw.githubusercontent.com/MuonCat/RAM-Net/main/assets/logo.png" alt="RAM-Net" width="420">
4
+
5
+ # ramnet-ops
6
+
7
+ [![arXiv](https://img.shields.io/badge/arXiv-2602.11958-b31b1b.svg?logo=arxiv&logoColor=white)](https://arxiv.org/abs/2602.11958)
8
+ [![Project Page](https://img.shields.io/badge/Project-Page-1f6feb.svg)](https://muoncat.github.io/ramnet_web/)
9
+ [![Weights](https://img.shields.io/badge/Weights-Hugging%20Face-FFD21E?logo=huggingface&logoColor=white)](https://huggingface.co/kaichengx/RAM-Net-Models/tree/main)
10
+ [![GitHub](https://img.shields.io/badge/GitHub-RAM--Net-181717?logo=github&logoColor=white)](https://github.com/MuonCat/RAM-Net)
11
+ [![Models](https://img.shields.io/badge/Models-ramnet-82afe6?logo=pytorch&logoColor=white)](https://github.com/MuonCat/RAM-Net/blob/main/packages/ramnet/README.md)
12
+ [![Operators](https://img.shields.io/badge/Operators-ramnet--ops-76B900?logo=nvidia&logoColor=white)](https://github.com/MuonCat/RAM-Net/blob/main/packages/ramnet-ops/README.md)
13
+ [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/MuonCat/RAM-Net/blob/main/LICENSE)
14
+
15
+ </div>
16
+
17
+ The attention computation core of RAM-Net: sparse address decoding, memory updates, readout, and autograd.
18
+ Import as `ramnet_ops` for CUDA kernels and a PyTorch reference implementation.
19
+
20
+ ## Structure
21
+
22
+ ```text
23
+ .
24
+ |-- src/
25
+ | `-- ramnet_ops/
26
+ | |-- ram_attn.py # Public API, input normalization, backend selection
27
+ | `-- impl/
28
+ | |-- torch_impl.py # PyTorch reference
29
+ | |-- cuda_impl.py # CUDA wrappers and segment layout
30
+ | |-- _cuda_autograd.py # FakeTensor and autograd registrations
31
+ | `-- _cuda_config.py # Address and index-capacity checks
32
+ `-- csrc/
33
+ |-- ram_attn_bind.cpp # Torch schemas, CUDA registration, extension entry point
34
+ |-- ram_attn_ops.cpp # Native wrappers, output allocation, kernel dispatch
35
+ |-- ram_attn_*.cu # Address, segment, and autoregressive kernels
36
+ `-- torch_compat* # Ordinary/stable Torch ABI interfaces
37
+ ```
38
+
39
+ ## Installation
40
+
41
+ Requires:
42
+
43
+ ```text
44
+ Python >= 3.10
45
+
46
+ ramnet-ops
47
+ |-- torch >= 2.5
48
+ |-- einops
49
+ `-- numpy
50
+ ```
51
+
52
+ ### 1. Install dependencies
53
+
54
+ If PyTorch is not already installed, we **recommend PyTorch ≥ 2.10 with CUDA 13.0 (`cu130`)** for the default ops wheels below.
55
+ See the [official installation guide](https://pytorch.org/get-started/locally/) for installation commands.
56
+ Then install the remaining dependencies from TestPyPI / PyPI:
57
+
58
+ ```bash
59
+ python -m pip install einops numpy
60
+ ```
61
+
62
+ ### 2. Install ramnet-ops
63
+
64
+ The default `ramnet-ops` wheels use both **Python and PyTorch stable ABIs** and target **CUDA 13.0 (`cu130`)**.
65
+ If your environment meets **all** of the following requirements, install directly from pip:
66
+
67
+ - **Python:** CPython ≥ 3.10.
68
+ - **PyTorch:** ≥ 2.10 with CUDA 13.0.
69
+ - **GPU:** SM 8.9, 9.0, 10.0, or 12.0.
70
+ - **Platform:** Windows x64 or Linux x86_64 with glibc ≥ 2.35.
71
+
72
+ ```bash
73
+ python -m pip install -i https://test.pypi.org/simple/ ramnet-ops
74
+ ```
75
+
76
+ Prebuilt wheels need no local compiler or CUDA Toolkit.
77
+ If your environment **does not meet all of the requirements above**, follow [Other Torch/CUDA builds (GitHub Releases)](#other-torchcuda-builds-github-releases) below to select another prebuilt wheel.
78
+
79
+ #### Other Torch/CUDA builds (GitHub Releases)
80
+
81
+ GitHub Releases provides additional wheels for older PyTorch versions, other CUDA builds, and GPUs outside the default `cu130` targets.
82
+ Open [GitHub Releases](https://github.com/MuonCat/RAM-Net/releases), select the desired package version under `ramnet-ops/v<VERSION>`, and expand **Assets** to find its `.whl` files.
83
+ Choose a wheel using [the selection guide below](#choose-a-matching-wheel), then copy its download link into `python -m pip install "<wheel URL>"`.
84
+ You must select the Torch/CUDA variant yourself; pip does not infer it from your environment.
85
+
86
+ With the matching PyTorch build already installed, the commands look like this for package version `0.1.0rc0`:
87
+
88
+ Windows x64, **Torch 2.8.0 / CUDA 12.8** (ordinary ABI):
89
+
90
+ ```bash
91
+ python -m pip install "https://github.com/MuonCat/RAM-Net/releases/download/ramnet-ops%2Fv0.1.0rc0/ramnet_ops-0.1.0rc0-1torch2_8_0cu128-cp310-abi3-win_amd64.whl"
92
+ ```
93
+
94
+ Linux x86_64, **Torch ≥ 2.10 / CUDA 12.6** (stable ABI):
95
+
96
+ ```bash
97
+ python -m pip install "https://github.com/MuonCat/RAM-Net/releases/download/ramnet-ops%2Fv0.1.0rc0/ramnet_ops-0.1.0rc0-1torchabi2_10cu126-cp310-abi3-manylinux_2_35_x86_64.whl"
98
+ ```
99
+
100
+ ##### Choose a matching wheel
101
+
102
+ First, match the **Torch ABI** marker in the filename to your installed PyTorch version:
103
+
104
+ - **Ordinary ABI (`torch2_6_0` or `torch2_8_0`):** requires exactly **PyTorch 2.6.0** or **2.8.0**, respectively.
105
+ - **Stable ABI (`torchabi2_10`):** supports **PyTorch ≥ 2.10** with a matching CUDA/platform combination; the Torch 2.14 SDK used to build these wheels is not required at runtime.
106
+
107
+ Next, find your **GPU row** and **PyTorch column** in the table below.
108
+ Each cell lists the available CUDA builds: choose one matching your installed PyTorch's CUDA version (`torch.version.cuda`), such as `cu126` for CUDA 12.6.
109
+
110
+ | [GPU CC](https://developer.nvidia.com/cuda/gpus) (representative GPUs) | PyTorch 2.6.0 | PyTorch 2.8.0 | PyTorch ≥ 2.10 |
111
+ | --- | --- | --- | --- |
112
+ | 7.5 (T4 / RTX 20) | 11.8 | ❌ | ❌ |
113
+ | 8.0 (A100) | 11.8 / 12.6 | 12.6 | 12.6 |
114
+ | 8.6 (RTX 30) | 11.8 / 12.6 | 12.6 | 12.6 |
115
+ | 8.9 (RTX 40 / L40S) | 12.6 | 12.6 / 12.8 | 12.6 / **13.0 ★** |
116
+ | 9.0 (H100 / H200) | 12.6 | 12.6 / 12.8 | 12.6 / **13.0 ★** |
117
+ | 10.0 (B200 / GB200) | ❌ | 12.8 | **13.0 ★** |
118
+ | 12.0 (RTX 50) | ❌ | 12.8 | **13.0 ★** |
119
+
120
+ ★ marks the default TestPyPI / PyPI build; ❌ means no prebuilt wheel is provided for that combination.
121
+
122
+ This table describes the architectures included in our wheels, not every GPU supported by each CUDA Toolkit.
123
+
124
+ Finally, match the **platform** suffix: `win_amd64` for Windows x64 or `manylinux_2_35_x86_64` for Linux x86_64 with glibc ≥ 2.35.
125
+ All wheels use `cp310-abi3` for GIL-enabled **CPython ≥ 3.10**.
126
+ Check the driver requirements below before installing; if no wheel matches your environment, see [From source](#from-source).
127
+
128
+ ##### NVIDIA drivers
129
+
130
+ The table lists driver baselines from NVIDIA's CUDA GA release notes; use these or newer drivers that support your GPU.
131
+
132
+ | CUDA | Windows driver | Linux driver |
133
+ | --- | --- | --- |
134
+ | [11.8](https://docs.nvidia.com/cuda/archive/11.8.0/cuda-toolkit-release-notes/index.html) | ≥ 522.06 | ≥ 520.61.05 |
135
+ | [12.6](https://docs.nvidia.com/cuda/archive/12.6.0/cuda-toolkit-release-notes/index.html) | ≥ 560.76 | ≥ 560.28.03 |
136
+ | [12.8](https://docs.nvidia.com/cuda/archive/12.8.0/cuda-toolkit-release-notes/index.html) | ≥ 570.65 | ≥ 570.26 |
137
+ | **[13.0 ★](https://docs.nvidia.com/cuda/archive/13.0.0/cuda-toolkit-release-notes/index.html)** | **R580+** | **≥ 580.65.06** |
138
+
139
+ CUDA 13.0 no longer bundles a Windows driver; NVIDIA requires the R580 branch or newer.
140
+ CUDA 11.x/12.x may run on older drivers through [minor-version compatibility](https://docs.nvidia.com/deploy/cuda-compatibility/minor-version-compatibility.html), subject to feature and PTX restrictions; newer GPUs may require newer drivers.
141
+
142
+ #### From source
143
+
144
+ Source installation supports both CUDA extension builds and PyTorch-only installations.
145
+
146
+ ##### With CUDA extension
147
+
148
+ Use this option when no prebuilt wheel matches your environment or when modifying the CUDA operators.
149
+ Prepare the build environment first:
150
+
151
+ - **PyTorch:** install the intended CUDA build (Torch ≥ 2.5).
152
+ - **CUDA Toolkit:** install a version compatible with that PyTorch build, including `nvcc`.
153
+ - **C++ compiler:** use a compiler supported by the Toolkit; on Windows, run the commands in an **x64 Native Tools Command Prompt for VS 2022**.
154
+
155
+ By default (`RAMNET_TORCH_STABLE_ABI=auto`), Torch 2.5–2.13 builds use the ordinary ABI and require that exact Torch version at runtime; Torch ≥ 2.14 builds use stable ABI targeting Torch ≥ 2.10.
156
+
157
+ Install the build tools in the same Python environment as PyTorch:
158
+
159
+ ```bash
160
+ python -m pip install "setuptools>=77.0.3" wheel ninja
161
+ ```
162
+
163
+ Then choose one of the following sources.
164
+
165
+ **Download and build with pip** — install the published source archive from TestPyPI / PyPI:
166
+
167
+ ```bash
168
+ python -m pip install -i https://test.pypi.org/simple/ ramnet-ops --no-binary=ramnet-ops --no-build-isolation
169
+ ```
170
+
171
+ **Clone from GitHub and build locally** — use the repository source, for example when modifying the operators:
172
+
173
+ ```bash
174
+ git clone https://github.com/MuonCat/RAM-Net.git
175
+ cd RAM-Net
176
+ python -m pip install ./packages/ramnet-ops --no-build-isolation
177
+ ```
178
+
179
+ The CUDA extension is compiled during installation.
180
+
181
+ ##### Environment variables
182
+
183
+ Set these before source installation; ABI and architecture settings apply only when building the CUDA extension.
184
+
185
+ | Variable | Default | Purpose |
186
+ | --- | --- | --- |
187
+ | `SKIP_CUDA` | `0` | Set to `1` to skip the CUDA extension and install only the Python package and PyTorch reference. |
188
+ | `RAMNET_TORCH_STABLE_ABI` | `auto` | Select the ABI from the build SDK; `0` forces ordinary ABI; `1` forces stable ABI and requires Torch ≥ 2.14 to build. |
189
+ | `TORCH_CUDA_ARCH_LIST` | GPUs visible during the build | Set the target GPU architectures explicitly, e.g. `8.9 9.0`. |
190
+
191
+ Set `SKIP_CUDA=1` to install from source without building the native CUDA extension.
192
+ PyTorch, `einops`, and `numpy` are still required; a CUDA Toolkit and C++ compiler are not needed.
193
+
194
+ ## Quick start
195
+
196
+ `random_access_memory_attention` performs the sparse reads and writes of a RAM-Net layer, covering address decoding, CAPE, and the Gated Sparse Update.
197
+ It takes address logits, values, and forgetting modulators, and returns the read outputs and the updated slot/mass state.
198
+
199
+ The table maps paper notation to parameters and tensor dimensions in the example below.
200
+ `B`, `T`, and `H` denote batch size, sequence length, and number of heads.
201
+
202
+ | Paper quantity / symbol | Operator parameter / axis |
203
+ | :---: | :---: |
204
+ | Address order $U$ (digits per address) | `U` |
205
+ | Address radix $d_p$ (values per digit) | `P` |
206
+ | Value dimension $d_v$ | `C` |
207
+ | Slots per head $d_p^U$ | `A = P ** U` |
208
+ | Selected slots $K$ | `top_k` |
209
+
210
+ This example computes attention outputs and the updated state, then backpropagates through both:
211
+
212
+ ```python
213
+ import torch
214
+ from ramnet_ops import random_access_memory_attention
215
+
216
+ device = "cuda" # Set to "cpu" for the PyTorch reference.
217
+ backend = "cuda" if device == "cuda" else "torch"
218
+ torch.manual_seed(0)
219
+
220
+ B, T, H, U, P, C = 2, 32, 4, 3, 4, 32
221
+ w_addr = torch.randn(B, T, H, U, P, device=device, requires_grad=True)
222
+ r_addr = torch.randn(B, T, H, U, P, device=device, requires_grad=True)
223
+ values = torch.randn(B, T, H, C, device=device, requires_grad=True)
224
+ gamma = torch.randn(B, T, H, device=device, requires_grad=True)
225
+
226
+ y, (slot, mass) = random_access_memory_attention(
227
+ w_addr, r_addr, values, gamma,
228
+ embed_num=2, top_k=8,
229
+ impl_backend=backend,
230
+ )
231
+ loss = y.square().mean() + slot.square().mean() + mass.square().mean()
232
+ loss.backward()
233
+ print(y.shape) # (B, T, H, C)
234
+ print(slot.shape) # (B, H, P ** U, C)
235
+ print(mass.shape) # (B, H, P ** U)
236
+ ```
237
+
238
+ `embed_num` selects how many heads, starting from head 0, use **Cyclic Address Positional Embedding (CAPE)** to cyclically shift read and write slot indices by token position.
239
+ With `H=4` and `embed_num=2`, heads 0 and 1 use CAPE, while heads 2 and 3 address by content alone.
240
+ Its range is `0` to `H`: `0` disables CAPE and `H` enables it for all heads.
241
+
242
+ From the repository root, run [ops_smoke.py](../../examples/ops_smoke.py) with `python examples/ops_smoke.py --device cuda`, or use `--device cpu` for the PyTorch reference.
243
+ This example demonstrates the API; it is not an experiment configuration.
244
+
245
+ ### Arguments
246
+
247
+ - `w_addr`, `r_addr`: write and read address logits of shape `(…, T, …, H, U, P)`. The operator applies a softmax over each digit.
248
+ - `values`: values to write, of shape `(…, T, …, H, C)`. The output `y` has the same shape and dtype.
249
+ - `gamma`: forgetting modulator of shape `(…, T, …, H)`, computed by the model for each token. Larger values overwrite old slot content faster.
250
+ - `init_ram`: the `(slot, mass)` state returned by a previous call, used to continue a sequence. Without it, every slot starts empty.
251
+ - `inplace`: if `True`, updates the `init_ram` tensors in place instead of returning new ones. This requires contiguous FP32 state and does not support gradients.
252
+ - `mask`: marks valid tokens. Masked tokens are not written to the state, and their outputs should be ignored.
253
+ - `embed_num`: number of heads that use CAPE, counted from head 0. These heads shift each token's addresses by its position.
254
+ - `top_k`: `K`, given as an int or a `(write_k, read_k)` pair. `None` keeps all slots and is supported only by the PyTorch backend.
255
+ - `top_k_re_norm`: explicitly enables renormalization after Top-K. Accepts a bool for both sides, or a two-item tuple/list of `(write, read)` bools; defaults to `False`.
256
+ - `t_dim`: index of the time axis. Dimensions before `H` other than the time axis are broadcast as batch dimensions.
257
+ - `impl_backend`: `'cuda'` or `'torch'`. By default, CUDA inputs use the CUDA backend when supported and otherwise fall back to PyTorch with a warning.
258
+
259
+ ## CUDA execution
260
+
261
+ The CUDA backend automatically selects between **autoregressive** and **parallel** execution.
262
+
263
+ **Autoregressive mode** handles single-token inputs (`T = 1`) when no input requires gradients.
264
+ A dedicated kernel decodes the current token's addresses, updates the selected write slots, and reads the selected read slots directly.
265
+
266
+ **Parallel mode** handles all other inputs, including training and prefill.
267
+ It decodes all tokens' addresses in parallel, treating each selected read or write access as an **event**.
268
+ Events targeting the same `(batch, head, slot)` are grouped into a **segment**.
269
+ The kernels process independent segments and their value channels in parallel while preserving causal dependencies within each segment, then accumulate read contributions into the token outputs.
270
+
271
+ ## Autograd and compile
272
+
273
+ Operators are registered under `torch.ops.ramnet_ops` with FakeTensor and first-order autograd support.
274
+ Compile coverage targets fixed shapes/configuration with `dynamic=False`, tested through `aot_eager`;
275
+ it does not establish Inductor or CUDA Graph support.
276
+
277
+ Segment capacity is `B * H * A`; event capacity is `B * H * T_padded * (write_k + read_k)`.
278
+ Masks do not reduce these allocations.
279
+ Higher-order gradients are not supported.
280
+
281
+ ## Development
282
+
283
+ See [RELEASING](RELEASING.md) for tests and publishing.
284
+
285
+ MIT License. See [LICENSE](LICENSE).
@@ -0,0 +1,47 @@
1
+ # Releasing ramnet-ops
2
+
3
+ `ramnet` and `ramnet-ops` are built and published independently, with versions read from their own `pyproject.toml`.
4
+ Use `ramnet/v<VERSION>` for this package and `ramnet-ops/v<VERSION>` for the operators.
5
+
6
+ ## Tests
7
+
8
+ Install the candidate wheel and its [dependencies](README.md#installation), then run from the repository root on a CUDA GPU:
9
+
10
+ ```bash
11
+ python -m tests --part ops --device cuda
12
+ ```
13
+
14
+ - Add `--fp16` and/or `--bf16` for optional low-precision checks; BF16 requires a supported GPU.
15
+ - Use `--group contracts`, `--group behavior`, or `--group numerics` to select a group.
16
+ - Seeds default to `0 1 2`; use `--seeds 0` for a focused rerun.
17
+ - Use `--device cpu` for CPU-only checks; this does not validate the CUDA kernels.
18
+
19
+ After public API changes, also check model integration with `ramnet` and its dependencies installed:
20
+
21
+ ```bash
22
+ python -m tests --part models --device cuda
23
+ ```
24
+
25
+ Tests run locally; the build and publish workflows do not run them.
26
+ See the [test guide](../../tests/README.md) for selection options, parameter coverage, and acceptance criteria.
27
+
28
+ ## Release checklist
29
+
30
+ - [ ] Set a new `version` in [pyproject.toml](pyproject.toml).
31
+ - [ ] Update version references in [README → Other Torch/CUDA builds (GitHub Releases)](README.md#other-torchcuda-builds-github-releases)
32
+ - [ ] Push the release commit to `main` and wait for [ramnet-ops build](../../.github/workflows/ramnet-ops-build.yml) to succeed.
33
+ - [ ] Install a wheel from that run's artifacts and run the tests above.
34
+ - [ ] Create and push `ramnet-ops/v<VERSION>` at the exact build commit; the tag version must match `pyproject.toml` at that commit.
35
+ - [ ] Keep the successful build run ID and test results for publishing.
36
+
37
+ ## Publish
38
+
39
+ Run [ramnet-ops publish](../../.github/workflows/ramnet-ops-publish.yml) manually with:
40
+
41
+ - `build_run_id`: the numeric ID from the successful build's `/actions/runs/<ID>` URL.
42
+ - `tag`: the full `ramnet-ops/v<VERSION>` tag.
43
+ - `target`: `testpypi`, `pypi`, or `release` for GitHub Release only.
44
+
45
+ Publish to TestPyPI first, verify installation and tests, then publish to PyPI using the same build ID and tag.
46
+ The workflow checks build/tag/version agreement and reuses the original artifacts without rebuilding.
47
+ Every target creates or verifies the GitHub Release first; an existing matching release is reused without uploading its assets again.