stream-ai-runtime 0.1.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.
@@ -0,0 +1,5 @@
1
+ Metadata-Version: 2.4
2
+ Name: stream-ai-runtime
3
+ Version: 0.1.0
4
+ Summary: Zero-OOM streaming runtime for AI models
5
+ Dynamic: summary
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,7 @@
1
+ from setuptools import setup, find_packages
2
+ setup(
3
+ name="stream-ai-runtime",
4
+ version="0.1.0",
5
+ packages=find_packages(),
6
+ description="Zero-OOM streaming runtime for AI models"
7
+ )
@@ -0,0 +1,5 @@
1
+ Metadata-Version: 2.4
2
+ Name: stream-ai-runtime
3
+ Version: 0.1.0
4
+ Summary: Zero-OOM streaming runtime for AI models
5
+ Dynamic: summary
@@ -0,0 +1,9 @@
1
+ setup.py
2
+ stream_ai_runtime.egg-info/PKG-INFO
3
+ stream_ai_runtime.egg-info/SOURCES.txt
4
+ stream_ai_runtime.egg-info/dependency_links.txt
5
+ stream_ai_runtime.egg-info/top_level.txt
6
+ stream_runtime/__init__.py
7
+ stream_runtime/buffer_manager.py
8
+ stream_runtime/config.py
9
+ stream_runtime/engine.py
@@ -0,0 +1 @@
1
+ stream_runtime
@@ -0,0 +1,3 @@
1
+ from .config import StreamRuntimeConfig
2
+ from .buffer_manager import DoubleBufferManager
3
+ from .engine import StreamModel
@@ -0,0 +1,30 @@
1
+ import torch
2
+
3
+ class DoubleBufferManager:
4
+ def __init__(self, shape, dtype=torch.float32, device="cuda"):
5
+ self.device = device
6
+ self.buffer_ping = torch.empty(shape, dtype=dtype, device=device)
7
+ self.buffer_pong = torch.empty(shape, dtype=dtype, device=device)
8
+ self.current_slot = 0
9
+ self.compute_stream = torch.cuda.Stream()
10
+ self.copy_stream = torch.cuda.Stream()
11
+ self.copy_done = [torch.cuda.Event(), torch.cuda.Event()]
12
+ self.compute_done = [torch.cuda.Event(), torch.cuda.Event()]
13
+
14
+ def prefetch_next_chunk(self, cpu_tensor):
15
+ next_slot = 1 - self.current_slot
16
+ with torch.cuda.stream(self.copy_stream):
17
+ self.compute_done[next_slot].wait(self.copy_stream)
18
+ target = self.buffer_pong if next_slot == 1 else self.buffer_ping
19
+ target.copy_(cpu_tensor, non_blocking=True)
20
+ self.copy_done[next_slot].record(self.copy_stream)
21
+
22
+ def get_ready_buffer(self):
23
+ with torch.cuda.stream(self.compute_stream):
24
+ self.copy_done[self.current_slot].wait(self.compute_stream)
25
+ ready_buf = self.buffer_ping if self.current_slot == 0 else self.buffer_pong
26
+ return ready_buf
27
+
28
+ def mark_compute_complete(self):
29
+ self.compute_done[self.current_slot].record(self.compute_stream)
30
+ self.current_slot = 1 - self.current_slot
@@ -0,0 +1,6 @@
1
+ from dataclasses import dataclass
2
+
3
+ @dataclass
4
+ class StreamRuntimeConfig:
5
+ chunk_size_mb: int = 128
6
+ device: str = "cuda"
@@ -0,0 +1,26 @@
1
+ import torch
2
+ import torch.nn as nn
3
+ from .buffer_manager import DoubleBufferManager
4
+
5
+ class StreamModel:
6
+ def __init__(self, num_layers=32, dim=2048):
7
+ self.num_layers = num_layers
8
+ self.dim = dim
9
+ self.cpu_weights = [torch.randn(dim, dim, pin_memory=True) for _ in range(num_layers)]
10
+ self.buffer_mgr = DoubleBufferManager((dim, dim))
11
+
12
+ def forward(self, x):
13
+ with torch.cuda.stream(self.buffer_mgr.copy_stream):
14
+ self.buffer_mgr.buffer_ping.copy_(self.cpu_weights[0], non_blocking=True)
15
+ self.buffer_mgr.copy_done[0].record(self.buffer_mgr.copy_stream)
16
+
17
+ for i in range(self.num_layers):
18
+ if i + 1 < self.num_layers:
19
+ self.buffer_mgr.prefetch_next_chunk(self.cpu_weights[i + 1])
20
+ buf = self.buffer_mgr.get_ready_buffer()
21
+ with torch.cuda.stream(self.buffer_mgr.compute_stream):
22
+ x = torch.matmul(x, buf)
23
+ self.buffer_mgr.mark_compute_complete()
24
+
25
+ torch.cuda.synchronize()
26
+ return x