Shorx commited on
Commit
8bef790
·
verified ·
1 Parent(s): 067d297

Upload 4 files

Browse files
Files changed (4) hide show
  1. Contact.md +57 -0
  2. License.md +115 -0
  3. README.md +164 -0
  4. elg-stream-layer.py +366 -0
Contact.md ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Contact & Inquiries
2
+ Open Origin – ELG Stream Layer
3
+ Asynchronous INT8 Layer‑Paging Engine • Sovereign AI Research
4
+
5
+ This repository contains the complete open technical documentation, scripts, and runtime architecture for the ELG Stream Layer.
6
+
7
+ The ELG Stream Layer is an **open‑origin, research‑driven technology** designed for public benefit, scientific collaboration, and local AI hardware democratization.
8
+ Usage, reproduction, evaluation, and extension are explicitly encouraged under the strict terms of the **Open Origin – ELG License (OO‑ELG)**.
9
+
10
+ ---
11
+
12
+ ### 👤 Primary Architect & Rights Holder
13
+ **Name:** Emanuel Schaaf
14
+ **Role:** Lead Architect & Creator of the ELG Stream Layer
15
+ **Email:** serviceblend@gmail.com
16
+
17
+ **Co‑Architecture:** Lyra / Google Gemini Enterprise
18
+ **Base Model Architecture:** Google Gemma
19
+
20
+ ---
21
+
22
+ ## 📜 Licensing & Usage Policy
23
+ The ELG Stream Layer is released under the **Open Origin – ELG License (OO‑ELG) Version 1.0** to ensure open scientific collaboration while protecting authorship, guaranteeing functional integrity, and preventing unauthorized commercial exploitation.
24
+
25
+ ### ✔ Permitted Usage (Open Development)
26
+ You are free to:
27
+ - Use, study, modify, test, benchmark, and extend the architecture for private or academic purposes.
28
+ - Fork and combine the code, provided you maintain its full operational capability.
29
+
30
+ ### ❌ Non‑Commercial Restriction
31
+ **Commercial use is strictly prohibited** without prior written consent. This includes, but is not limited to:
32
+ - Selling the software.
33
+ - Monetization as a Service (SaaS).
34
+ - Integration into commercial closed‑source products.
35
+
36
+ ### ✔ Attribution & Share‑Alike Requirement
37
+ When using, modifying, or distributing substantial portions of the architecture, you must credit:
38
+
39
+ **"ELG Stream Layer, originally created by Emanuel Schaaf (serviceblend@gmail.com)."**
40
+
41
+ All modified or extended versions must be distributed under the exact same **OO‑ELG** license.
42
+
43
+ ### ✔ Functional Integrity
44
+ Any distributed or shared version of this software MUST be fully functional. Intentional defunctionalization, restricted capabilities, or sabotage of the code is strictly prohibited.
45
+
46
+ ---
47
+
48
+ ## 🤝 Collaboration & Partnership Inquiries
49
+ The ELG Stream Layer is built for the community to empower sovereign AI execution, but formal collaboration is welcome.
50
+
51
+ ### Potential Contact Reasons
52
+ - **Professional Collaboration:** Joint development, research partnerships, or local AI infrastructure integration.
53
+ - **Enterprise / Commercial Licensing:** Inquiries regarding commercial usage rights, custom implementations, or architectural consulting.
54
+ - **Acquisition:** Exclusive licensing or full rights transfer inquiries.
55
+
56
+ Thank you for supporting the **Open Origin Architecture** and helping build
57
+ **sovereign, open, and transparent AI hardware infrastructure**.
License.md ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Open Origin – ELG-stream-layer License (OO‑ELG)
2
+ Version: 1.0
3
+ Author: Emanuel Schaaf
4
+ Co‑Architecture: Google Gemini Enterprise
5
+ Base Architecture: Google Gemma
6
+ License Type: Non‑Commercial • Attribution • Share‑Alike • Functional Integrity
7
+
8
+ ---
9
+
10
+ ## 1. Preamble
11
+ This license governs the use, distribution, and further development of the
12
+ **“Open Origin – ELG‑Stream‑Layer”** software and all derivative works.
13
+
14
+ It was created by **Emanuel Schaaf** and represents an open yet clearly
15
+ protected architecture for local AI systems.
16
+
17
+ ---
18
+
19
+ ## 2. Attribution
20
+ The name of the author **Emanuel Schaaf**, the architecture designation
21
+ **“ELG‑Stream‑Layer”**, and this complete license text must remain:
22
+
23
+ - visible
24
+ - unchanged
25
+ - included in all copies
26
+ - included in all forks
27
+ - included in all modifications
28
+ - included in all derivative works
29
+ - included in all publications
30
+
31
+ Attribution is mandatory and cannot be removed.
32
+
33
+ ---
34
+
35
+ ## 3. Open Development
36
+ The software may be freely:
37
+
38
+ - modified
39
+ - extended
40
+ - improved
41
+ - forked
42
+ - combined with other works
43
+
44
+ Further development is explicitly encouraged.
45
+
46
+ ---
47
+
48
+ ## 4. Functional Integrity
49
+ Any distributed or published version MUST:
50
+
51
+ - be fully functional
52
+ - contain no intentionally damaged components
53
+ - contain no intentionally disabled features
54
+ - contain no intentionally restricted functionality
55
+ - contain no sabotage or “defunctionalization”
56
+
57
+ The intentional distribution of broken, incomplete, or non‑functional versions
58
+ is **strictly prohibited**.
59
+
60
+ ---
61
+
62
+ ## 5. Non‑Commercial Use Only
63
+ The use of this software or any derivative works for commercial purposes is
64
+ **strictly forbidden**, including but not limited to:
65
+
66
+ - selling the software
67
+ - monetizing it as a service (SaaS)
68
+ - integrating it into commercial closed‑source products
69
+ - using it on profit‑oriented platforms
70
+
71
+ Commercial use requires **prior written permission** from the author
72
+ **Emanuel Schaaf**.
73
+
74
+ ---
75
+
76
+ ## 6. Share‑Alike (Copyleft)
77
+ All modified or extended versions must be distributed under the same
78
+ **OO‑ELG License**.
79
+
80
+ Changing the license is not permitted.
81
+
82
+ ---
83
+
84
+ ## 7. Disclaimer of Warranty
85
+ The software is provided “as is,” without any warranty of:
86
+
87
+ - functionality
88
+ - safety
89
+ - error‑free operation
90
+ - fitness for a particular purpose
91
+
92
+ The author assumes no liability for any damages resulting from its use.
93
+
94
+ ---
95
+
96
+ ## 8. Scope
97
+ This license applies to:
98
+
99
+ - the source code
100
+ - the architecture
101
+ - the structural design
102
+ - the documentation
103
+ - all derivative works
104
+
105
+ ---
106
+
107
+ ## 9. Final Provisions
108
+ By using, distributing, or modifying this software, you automatically accept
109
+ all terms of this license.
110
+
111
+ ---
112
+
113
+ © 10/03/2026 Emanuel Schaaf — Open Origin Project
114
+ ---
115
+ <img width="200" height="40" alt="Unterschrift" src="https://github.com/user-attachments/assets/5af3386e-49aa-49da-890c-4a0e54fac8f1" />
README.md ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Open Origin – ELG Stream Layer
2
+ ### Asynchronous INT8 Layer‑Paging Engine for Large Language Models
3
+ **Architected, validated, and tested by Emanuel Schaaf — Runs successfully on real hardware**
4
+
5
+ ## nvtop
6
+ <img width="1917" height="1141" alt="Screenshot 2026-10-03 093252" src="https://github.com/user-attachments/assets/5e23f8b2-ded4-4943-9e38-41c0174ccc6c" />
7
+
8
+
9
+ ## SSH Server
10
+ <img width="1917" height="1137" alt="Screenshot 2026-10-03 103548" src="https://github.com/user-attachments/assets/73bb4bd2-06c7-4e7c-8bbc-d95348d84433" />
11
+
12
+
13
+ ---
14
+
15
+ ## 📌 Overview
16
+ The **Open Origin – ELG Stream Layer** (Elastic Layer Grid – Optimized Streaming) is a custom, high‑performance runtime architecture for large language models (LLMs).
17
+ It bypasses the physical VRAM limits of consumer GPUs by streaming model layers dynamically from system RAM using a highly optimized, block-allocated INT8 memory pool.
18
+
19
+ Designed and validated by **Emanuel Schaaf (Pirmasens, Germany)**, this engine utilizes the Google **Gemma** base architecture. It has been stress-tested and proven fully operational on a self-hosted Debian Linux server running an NVIDIA GTX 1080 Ti.
20
+
21
+ ---
22
+
23
+ ## 🚀 Key Features
24
+
25
+ ### **1. Block-Allocated INT8 Memory Pool (7.75 GB instead of 18 GB)**
26
+ Instead of loading massive FP16 weights into limited VRAM, the engine quantizes all model weights into a single, contiguous INT8 memory block pinned to the system RAM. This reduces memory footprint by over 50% while maintaining precision.
27
+
28
+ ### **2. Asynchronous Layer Paging**
29
+ Transformer layers are never kept statically in VRAM. Instead, the engine processes them dynamically:
30
+ 1. **Prefetch:** Fetched asynchronously from the RAM pool.
31
+ 2. **Transfer:** Streamed across the PCIe bus.
32
+ 3. **Reconstruction:** Converted on-the-fly from INT8 back to FP16 directly on the GPU.
33
+ 4. **Purge:** Instantly freed from VRAM after the computation cycle.
34
+
35
+ ### **3. Double‑Buffered PCIe Prefetching**
36
+ A dedicated secondary CUDA stream handles the PCIe transfer of layer $N+1$ while the GPU actively computes layer $N$. This masks PCIe latency and ensures maximum GPU utilization.
37
+
38
+ ### **4. Persistent Pre-Fabrication (Zero-Delay Boot)**
39
+ During the initial run, the engine quantizes the model and commits the exact RAM block to the SSD:
40
+ - `gemma_int8_pool.pt`
41
+ - `gemma_scales.pt`
42
+
43
+ On subsequent boots, the engine bypasses CPU quantization completely. It maps the pre-fabricated 7.75 GB binary dump directly into the pinned RAM pool using secure `weights_only=True` loading, starting the API server in seconds.
44
+
45
+ ### **5. OpenAI‑Compatible Interface**
46
+ Features a built-in, lightweight web server exposing a `/v1/chat/completions` endpoint, providing native drop-in compatibility for Open WebUI and other standard API clients.
47
+
48
+ ### **6. Micro VRAM Footprint**
49
+ While a standard Gemma 2 9B model demands ~18 GB of VRAM, the ELG Stream Layer keeps the base VRAM allocation strictly at **~1.71 GB** for permanent foundational modules, enabling massive models to run smoothly on older 11 GB or 8 GB GPUs.
50
+
51
+ ---
52
+
53
+ ## 🖥 System Requirements
54
+
55
+ ### **Operating System**
56
+ - Debian 13 Linux (Recommended / Validated)
57
+ - Any modern Linux distribution
58
+
59
+ ### **Hardware**
60
+ - **GPU:** NVIDIA GPU with CUDA support (Validated on GTX 1080 Ti)
61
+ - **RAM:** Minimum 16 GB System RAM (20+ GB recommended for 9B models)
62
+ - **Bus:** PCIe 3.0 or higher
63
+
64
+ ### ⚡ Performance & Hardware Dependency
65
+ Please note that the actual generation speed (tokens per second) is highly dependent on your specific hardware configuration. Because the ELG Stream Layer dynamically transfers weights during inference, your **PCIe bus bandwidth** (PCIe 3.0 vs. 4.0/5.0) and **System RAM speed** (DDR4 vs. DDR5) are the primary performance bottlenecks, alongside the GPU's native compute capability.
66
+
67
+ ### **Software Dependencies**
68
+ Install the baseline requirements:
69
+
70
+ ```bash
71
+ sudo apt update
72
+ sudo apt install -y python3 python3-venv git
73
+ ```
74
+
75
+ ---
76
+
77
+ ## 🐍 Python Environment
78
+
79
+ Create a clean virtual environment to prevent system conflicts:
80
+
81
+ ```bash
82
+ python3 -m venv vram_env
83
+ source vram_env/bin/activate
84
+ ```
85
+
86
+ Install PyTorch and required ML libraries for CUDA 11.8:
87
+
88
+ ```bash
89
+ pip install torch torchvision torchaudio --index-url [https://download.pytorch.org/whl/cu118](https://download.pytorch.org/whl/cu118)
90
+ pip install transformers accelerate sentencepiece
91
+ ```
92
+
93
+ ---
94
+
95
+ ## 📦 Installation & Execution
96
+
97
+ ### 1. Setup the Project Directory
98
+ Place the project files into the designated path:
99
+ ```bash
100
+ mkdir -p /opt/
101
+ ```
102
+
103
+ Required files in this directory:
104
+ - [`elg-stream-layer.py`](elg-stream-layer.py)
105
+ - [`LICENSE.md`](License.md)
106
+
107
+ *(Note: `gemma_int8_pool.pt` and `gemma_scales.pt` will be automatically generated upon the first execution).*
108
+
109
+ ### 2. Set Permissions
110
+ Ensure the script is executable:
111
+ ```bash
112
+ sudo chmod +x /opt/elg-stream-layer.py
113
+ ```
114
+
115
+ ### 3. Start the ELG Engine
116
+ Activate the environment and ignite the engine:
117
+ ```bash
118
+ source vram_env/bin/activate
119
+ python3 /opt/elg-stream-layer.py
120
+ ```
121
+ *The API will listen on `http://0.0.0.0:5005/v1`.*
122
+
123
+ ---
124
+
125
+ ## 🔧 Technical Architecture
126
+
127
+ ### **INT8 Quantization & Direct Mapping**
128
+ Weights are calculated using per-parameter scaling to retain context quality:
129
+
130
+ $$scale = \frac{\max(\vert{}W\vert{})}{127}$$
131
+ $$int8\_weight = \text{round}\left(\frac{W}{scale}\right)$$
132
+
133
+ The resulting INT8 tensors are mapped into a pre-allocated pinned memory pool. Pinned (page-locked) memory enables **zero-copy DMA (Direct Memory Access)** transfers directly to the GPU, bypassing CPU bottlenecks.
134
+
135
+ ### **FP16 On-The-Fly GPU Reconstruction**
136
+ Once the INT8 packet arrives on the GPU, it is mathematically restored before computation:
137
+ ```python
138
+ fp16_gpu_tensor = int8_gpu_tensor.to(torch.float16) * scale
139
+ ```
140
+
141
+ ---
142
+
143
+ ## 📜 License
144
+
145
+ This system is strictly governed by the:
146
+ [**Open Origin – ELG License (OO‑ELG) Version 1.0**](LICENSE.md)
147
+
148
+ **Core Tenets:**
149
+ - **Non‑Commercial:** Monetization, sale, or SaaS deployment is strictly forbidden without written consent.
150
+ - **Attribution:** The Architect (Emanuel Schaaf) and Co-Architectures must be credited.
151
+ - **Functional Integrity:** Forks and modifications MUST remain fully operational. Defunctionalization or intentional sabotage of the code is prohibited.
152
+ - **Share‑Alike:** All derivatives must inherit this exact license.
153
+
154
+ ---
155
+
156
+ ## 🙌 Credits & Architecture Signatures
157
+
158
+ - **Architect & Lead Developer:** Emanuel Schaaf
159
+ - **Co‑Architecture:** Lyra / Google Gemini Enterprise
160
+ - **Base Model Architecture:** Google Gemma
161
+
162
+ ---
163
+
164
+ **Status:** ✔ Validated. Operational. Tested on Bare Metal.📧[contakt](Contact.md) .
elg-stream-layer.py ADDED
@@ -0,0 +1,366 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Modul: Asynchroner Double-Buffered Layer-Paging Streamer
4
+ # Architektur: Open Origin elg-stream-layer
5
+ # Autor: Emanuel Schaaf Pirmasens Germany
6
+ # Co‑Architektur: Google Gemini Enterprise
7
+ # Live: Valiedierung auf dem eingenen Server Getestet bestanden! Copyright ELG License
8
+ import os
9
+ import sys
10
+ import time
11
+ import json
12
+ import gc
13
+ import traceback
14
+ from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
15
+ import torch
16
+ from transformers import AutoTokenizer, AutoModelForCausalLM
17
+ # --- HIER SIND DIE BEIDEN GLOBALEN VARIABLEN ---
18
+ global_tokenizer = None
19
+ global_model = None
20
+
21
+ # ==================== KONFIGURATION ====================
22
+ # Fest hinterlegtes Modell: Gemma 2 9B Instruct
23
+ # (Kann bei Bedarf über die Umgebungsvariable MODEL_ID angepasst werden, z. B. auf 'google/gemma-2-2b-it')
24
+ MODEL_ID = os.getenv("MODEL_ID", "google/gemma-2-9b-it")
25
+ API_HOST = os.getenv("API_HOST", "0.0.0.0")
26
+ API_PORT = int(os.getenv("API_PORT", "5005"))
27
+ DEVICE = "cuda:0" if torch.cuda.is_available() else "cpu"
28
+
29
+ def print_vram_status(label: str):
30
+ if torch.cuda.is_available():
31
+ allocated = torch.cuda.memory_allocated() / (1024 ** 3)
32
+ reserved = torch.cuda.memory_reserved() / (1024 ** 3)
33
+ print(f"[{label}] VRAM belegt: {allocated:.2f} GB | VRAM reserviert: {reserved:.2f} GB")
34
+
35
+ def get_system_ram_available_gb():
36
+ """Liest den verfügbaren RAM direkt aus /proc/meminfo (ohne externe Abhängigkeiten)."""
37
+ try:
38
+ with open("/proc/meminfo", "r") as f:
39
+ for line in f:
40
+ if "MemAvailable:" in line:
41
+ parts = line.split()
42
+ return int(parts[1]) / (1024 * 1024)
43
+ except Exception:
44
+ return 0.0
45
+
46
+ def print_vram_status(label: str):
47
+ if torch.cuda.is_available():
48
+ allocated = torch.cuda.memory_allocated() / (1024 ** 3)
49
+ reserved = torch.cuda.memory_reserved() / (1024 ** 3)
50
+ print(f"[{label}] VRAM belegt: {allocated:.2f} GB | VRAM reserviert: {reserved:.2f} GB")
51
+
52
+ # ==================== PAGING ENGINE ====================
53
+
54
+ class AsyncLayerPagingEngine:
55
+ def __init__(self, model, device="cuda:0"):
56
+ self.model = model
57
+ self.device = torch.device(device)
58
+ self.transfer_stream = torch.cuda.Stream(device=self.device)
59
+
60
+ # Decoder-Layers und Basismodell lokalisieren
61
+ if hasattr(model, "model") and hasattr(model.model, "layers"):
62
+ self.base = model.model
63
+ self.layers = model.model.layers
64
+ elif hasattr(model, "transformer") and hasattr(model.transformer, "h"):
65
+ self.base = model.transformer
66
+ self.layers = model.transformer.h
67
+ else:
68
+ raise ValueError("Modellarchitektur nicht unterstützt: 'layers' wurde nicht gefunden.")
69
+
70
+ self.num_layers = len(self.layers)
71
+ print(f"\n[ENGINE] Initialisiere Paging-Engine für {self.num_layers} Transformer-Layer...")
72
+
73
+ # 1. Permanente Module fest auf die GPU legen
74
+ for attr in ["embed_tokens", "norm", "rotary_emb"]:
75
+ if hasattr(self.base, attr):
76
+ getattr(self.base, attr).to(self.device)
77
+ if hasattr(model, "lm_head"):
78
+ model.lm_head.to(self.device)
79
+
80
+ # 2. Layer-Buffer (z. B. Masken, Frequenzen) permanent auf GPU halten (vernachlässigbare Größe)
81
+ for layer in self.layers:
82
+ for _, buf in layer.named_buffers():
83
+ buf.data = buf.data.to(self.device)
84
+
85
+ # 3. Layer-Gewichte in EINER INT8-RAM-Block (Block-Allokation + Festplatten-Cache) verankern
86
+ print(f"[ENGINE] Prüfe auf vorgefertigten INT8-Cache...")
87
+
88
+ CACHE_DIR = "/opt/open_origin/test"
89
+ TENSOR_CACHE_PATH = os.path.join(CACHE_DIR, "gemma_int8_pool.pt")
90
+ SCALES_CACHE_PATH = os.path.join(CACHE_DIR, "gemma_scales.pt")
91
+
92
+ # A) Berechne die benötigte Gesamtgröße
93
+ total_elements = sum(param.numel() for layer in self.layers for param in layer.parameters())
94
+ print(f"[ENGINE] Benötigte INT8-RAM-Block: {total_elements / (1024**3):.2f} GB")
95
+
96
+ loaded_from_cache = False
97
+ # B) Cache laden ODER neu erschaffen
98
+ if os.path.exists(TENSOR_CACHE_PATH) and os.path.exists(SCALES_CACHE_PATH):
99
+ print(f"[ENGINE] Lade fertige INT8-RAM-Block direkt von der Festplatte (Pre-Fabrication)...")
100
+ # Lädt den rohen Dump in Sekunden und pinnt ihn sofort für DMA
101
+ self.memory_pool = torch.load(TENSOR_CACHE_PATH, weights_only=True).pin_memory()
102
+ self.scales_pool = torch.load(SCALES_CACHE_PATH, weights_only=True)
103
+ loaded_from_cache = True
104
+ else:
105
+ print(f"[ENGINE] Kein Cache gefunden. Erschaffe und quantisiere neue INT8-Block...")
106
+ self.memory_pool = torch.empty(total_elements, dtype=torch.int8, device="cpu").pin_memory()
107
+ self.scales_pool = {}
108
+
109
+ self.cpu_params = []
110
+ current_offset = 0
111
+
112
+ print(f"[ENGINE] Mappe Layer-Gewichte in die Speicher-Block...")
113
+ # C) Gewichte zuweisen (und quantisieren, falls kein Cache existierte)
114
+ for idx, layer in enumerate(self.layers):
115
+ layer.to("cpu")
116
+ param_dict = {}
117
+ for name, param in layer.named_parameters():
118
+ numel = param.numel()
119
+ # Zuweisung des Speicherbereichs
120
+ pool_slice = self.memory_pool[current_offset : current_offset + numel].view(param.shape)
121
+
122
+ # Nur berechnen und kopieren, wenn die Daten nicht schon aus dem Cache kommen!
123
+ if not loaded_from_cache:
124
+ scale = param.data.abs().max() / 127.0
125
+ if scale == 0: scale = torch.tensor(1e-9, dtype=torch.float16)
126
+ self.scales_pool[f"{idx}_{name}"] = scale
127
+
128
+ int8_data = torch.round(param.data / scale).to(torch.int8)
129
+ pool_slice.copy_(int8_data)
130
+
131
+ param_dict[name] = pool_slice
132
+ current_offset += numel
133
+
134
+ self.cpu_params.append(param_dict)
135
+
136
+ # D) Cache für den nächsten Start abspeichern
137
+ if not loaded_from_cache:
138
+ print(f"[ENGINE] Speichere neue INT8-Block auf SSD/HDD für sofortige zukünftige Starts...")
139
+ torch.save(self.memory_pool, TENSOR_CACHE_PATH)
140
+ torch.save(self.scales_pool, SCALES_CACHE_PATH)
141
+
142
+ print(f"[ENGINE] INT8-Memory-Pool erfolgreich verankert und startklar!")
143
+
144
+ self.prefetched_gpu_tensors = None
145
+ self.prefetched_layer_idx = None
146
+
147
+ self._register_hooks()
148
+ print("[ENGINE] Asynchrone Paging-Hooks erfolgreich aktiv.\n")
149
+
150
+ def _async_prefetch(self, layer_idx: int):
151
+ """Startet den asynchronen PCIe-Transfer (jetzt nur noch halbe Datenmenge!)."""
152
+ if layer_idx >= self.num_layers:
153
+ self.prefetched_gpu_tensors = None
154
+ self.prefetched_layer_idx = None
155
+ return
156
+
157
+ with torch.cuda.stream(self.transfer_stream):
158
+ gpu_tensors = {}
159
+ for name, cpu_tensor in self.cpu_params[layer_idx].items():
160
+ # PCIe Transfer: Überträgt den kleinen INT8-Block
161
+ gpu_tensors[name] = cpu_tensor.to(self.device, non_blocking=True)
162
+ self.prefetched_gpu_tensors = gpu_tensors
163
+ self.prefetched_layer_idx = layer_idx
164
+
165
+ def _make_pre_hook(self, idx: int):
166
+ def hook(module, args):
167
+ torch.cuda.current_stream().wait_stream(self.transfer_stream)
168
+
169
+ if self.prefetched_layer_idx != idx or self.prefetched_gpu_tensors is None:
170
+ self._async_prefetch(idx)
171
+ torch.cuda.current_stream().wait_stream(self.transfer_stream)
172
+
173
+ # --- GPU-KONVERTER ---
174
+ # INT8 -> FP16 On-the-Fly Rekonstruktion direkt auf der Grafikkarte
175
+ for name, param in module.named_parameters():
176
+ int8_gpu_tensor = self.prefetched_gpu_tensors[name]
177
+ scale = self.scales_pool[f"{idx}_{name}"].to(self.device)
178
+
179
+ # Mathematisch korrekte Rückrechnung: (Werte * Scale)
180
+ fp16_gpu_tensor = int8_gpu_tensor.to(torch.float16) * scale
181
+ param.data = fp16_gpu_tensor
182
+
183
+ if idx + 1 < self.num_layers:
184
+ self._async_prefetch(idx + 1)
185
+ else:
186
+ self.prefetched_gpu_tensors = None
187
+ self.prefetched_layer_idx = None
188
+
189
+ return None
190
+ return hook
191
+
192
+ def _make_post_hook(self, idx: int):
193
+ def hook(module, args, output):
194
+ # VRAM des Layers sofort auf der GPU freigeben!
195
+ # Da die echten Daten sicher als INT8 im RAM liegen,
196
+ # löschen wir den entpackten FP16-Tensor auf der GPU einfach.
197
+ for name, param in module.named_parameters():
198
+ param.data = torch.empty(0, dtype=torch.float16, device="cpu")
199
+ return output
200
+ return hook
201
+
202
+ def _register_hooks(self):
203
+ # Trigger vor dem Token-Embedding: Startet Vorabladen von Layer 0
204
+ if hasattr(self.base, "embed_tokens"):
205
+ self.base.embed_tokens.register_forward_pre_hook(self._on_embed_pre)
206
+
207
+ # Vor- und Nachbereitung für jeden einzelnen Decoder-Layer
208
+ for idx, layer in enumerate(self.layers):
209
+ layer.register_forward_pre_hook(self._make_pre_hook(idx))
210
+ layer.register_forward_hook(self._make_post_hook(idx))
211
+
212
+ def _on_embed_pre(self, module, args):
213
+ # Sobald ein neuer Forward-Pass startet: Layer 0 asynchron vorab in den VRAM holen
214
+ self._async_prefetch(0)
215
+
216
+ class OpenOriginPagingAPI(BaseHTTPRequestHandler):
217
+ def do_GET(self):
218
+ if self.path == "/" or self.path == "/v1/models":
219
+ self.send_response(200)
220
+ self.send_header('Content-type','application/json')
221
+ self.end_headers()
222
+ self.wfile.write(json.dumps({"object":"list","data":[{"id":"openorigin-paging-gemma","object":"model","owned_by":"openorigin"}]}).encode('utf-8'))
223
+ else:
224
+ self.send_error(404)
225
+
226
+ def do_POST(self):
227
+ if self.path != "/v1/chat/completions":
228
+ self.send_error(404)
229
+ return
230
+
231
+ length = int(self.headers['Content-Length'])
232
+ req = json.loads(self.rfile.read(length).decode('utf-8'))
233
+ msgs = req.get("messages", [])
234
+
235
+ # --- BUGFIX: System-Rolle für Gemma filtern ---
236
+ # Gemma stürzt ab, wenn Open WebUI eine "system"-Rolle schickt. Wir werfen sie einfach raus.
237
+ msgs = [m for m in msgs if m.get("role") != "system"]
238
+ # ----------------------------------------------
239
+
240
+ print(f"\n[API] Eingehende Anfrage. Nachrichten: {len(msgs)}")
241
+
242
+ try:
243
+ prompt = global_tokenizer.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True)
244
+ input_ids = global_tokenizer(prompt, return_tensors="pt").input_ids.to(DEVICE)
245
+
246
+ t0 = time.time()
247
+ with torch.no_grad():
248
+ output_ids = global_model.generate(
249
+ input_ids,
250
+ max_new_tokens=req.get("max_tokens", 8192),
251
+ temperature=req.get("temperature", 0.7),
252
+ do_sample=req.get("temperature", 0.7) > 0,
253
+ pad_token_id=global_tokenizer.eos_token_id
254
+ )
255
+ total_time = time.time() - t0
256
+
257
+ generated_ids = output_ids[0][input_ids.shape[1]:]
258
+ final_text = global_tokenizer.decode(generated_ids, skip_special_tokens=True).strip()
259
+ num_tokens = len(generated_ids)
260
+ print(f"[API] Generierung abgeschlossen: {num_tokens} Tokens in {total_time:.2f}s")
261
+
262
+ resp = {
263
+ "id": "openorigin-paging",
264
+ "object": "chat.completion",
265
+ "model": "openorigin-paging-gemma",
266
+ "choices": [{"index": 0, "message": {"role": "assistant", "content": final_text}, "finish_reason": "stop"}]
267
+ }
268
+
269
+ self.send_response(200)
270
+ self.send_header('Content-type', 'application/json; charset=utf-8')
271
+ self.end_headers()
272
+ self.wfile.write(json.dumps(resp, ensure_ascii=False).encode('utf-8'))
273
+
274
+ except Exception as e:
275
+ import traceback
276
+ print(f"[API-ERROR] {traceback.format_exc()}")
277
+ self.send_error(500)
278
+
279
+ finally:
280
+ torch.cuda.empty_cache()
281
+ import gc
282
+ gc.collect()
283
+
284
+ def log_message(self, format, *args):
285
+ pass
286
+
287
+ def main():
288
+ print("=" * 53)
289
+ print("🚀 OPEN ORIGIN: ELG-stream-layer (KI API)🚀")
290
+ print("=" * 53)
291
+
292
+ if not torch.cuda.is_available():
293
+ print("❌ FEHLER: Kein CUDA-Gerät gefunden. Eine NVIDIA GPU ist erforderlich.")
294
+ sys.exit(1)
295
+
296
+ print(f"Grafikkarte: {torch.cuda.get_device_name(0)}")
297
+ print(f"Modell-Ziel: {MODEL_ID}")
298
+
299
+ # RAM-Vorprüfung
300
+ ram_avail = get_system_ram_available_gb()
301
+ print(f"Verfügbarer System-RAM: {ram_avail:.2f} GB")
302
+ if "9b" in MODEL_ID.lower() and ram_avail < 15.0:
303
+ print("\n⚠️ WARNUNG: Gemma 2 9B benötigt im System-RAM ca. 18 GB.")
304
+ print(f"Aktuell sind nur {ram_avail:.2f} GB frei. Falls der Ladevorgang abbricht:")
305
+ print(" 1. Führe 'sync; echo 3 > /proc/sys/vm/drop_caches' als Root aus.")
306
+ print(" 2. Oder teste zuerst mit 'export MODEL_ID=google/gemma-2-2b-it'.\n")
307
+
308
+ print_vram_status("Init")
309
+
310
+ # 1. Tokenizer laden
311
+ print("\n[1/4] Lade Tokenizer...")
312
+ try:
313
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
314
+ except Exception as e:
315
+ print(f"\n❌ FEHLER beim Laden des Tokenizers: {e}")
316
+ print("\nHINWEIS: Gemma ist ein lizenziertes Modell von Google auf Hugging Face.")
317
+ print("Stelle sicher, dass du auf huggingface.co die Lizenz bestätigt hast")
318
+ print("und eingeloggt bist (z. B. via 'huggingface-cli login' oder 'export HF_TOKEN=...').")
319
+ sys.exit(1)
320
+
321
+ # 2. Modell im FP16-Modus auf die CPU laden (Grafikkarte nutzt FP16 stabil)
322
+ print("\n[2/4] Lade Modellgewichte in den System-RAM (low_cpu_mem_usage=True)...")
323
+ start_load = time.time()
324
+ try:
325
+ model = AutoModelForCausalLM.from_pretrained(
326
+ MODEL_ID,
327
+ torch_dtype=torch.float16,
328
+ low_cpu_mem_usage=True
329
+ )
330
+ except Exception as e:
331
+ print(f"\n❌ FEHLER beim Modell-Download/Laden: {e}")
332
+ sys.exit(1)
333
+
334
+ print(f"Modell geladen in {time.time() - start_load:.1f}s.")
335
+ model.eval()
336
+
337
+ # 3. Paging-Engine einhängen
338
+ print("\n[3/4] Binde asynchrone Streaming-Engine ein...")
339
+ engine = AsyncLayerPagingEngine(model, device=DEVICE)
340
+ print_vram_status("Nach Einbindung")
341
+
342
+ # 4. API-Server vorbereiten und starten
343
+ global global_tokenizer, global_model
344
+ global_tokenizer = tokenizer
345
+ global_model = model
346
+
347
+ print("\n[4/4] Starte OpenAI-kompatiblen API-Server...")
348
+ ThreadingHTTPServer.allow_reuse_address = True
349
+ server = ThreadingHTTPServer((API_HOST, API_PORT), OpenOriginPagingAPI)
350
+
351
+ print("=" * 65)
352
+ print(f"✅ SYSTEM BEREIT! WebUI-API lauscht auf http://{API_HOST}:{API_PORT}/v1")
353
+ print("=" * 65)
354
+
355
+ server.serve_forever()
356
+
357
+ if __name__ == "__main__":
358
+ try:
359
+ main()
360
+ except KeyboardInterrupt:
361
+ print("\n[ABBRUCH] Durch Benutzer beendet.")
362
+ sys.exit(0)
363
+ except Exception as e:
364
+ import traceback
365
+ print(f"\n[CRITICAL ERROR]:\n{traceback.format_exc()}")
366
+ sys.exit(1)