File size: 10,095 Bytes
8be8908 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | # PSE (Proto-Sentient Enhancement) Implementation Log
## POWER8 S824 - Elyan Labs 2025
**System**: IBM POWER8 S824 (16 cores, 128 threads, 320GB RAM)
**Target**: llama.cpp with gpt-oss/OptiMind architecture
---
## Timeline
### 2025-01-23 ~15:00 UTC - Initial State
- OptiMind-SFT 20B Q4_K_M deployed to POWER8
- llama.cpp using **scalar fallback** (no POWER8 VSX paths)
- **Codex attempt**: ~1 t/s (all scalar, no SIMD)
- Problem: All VSX code guarded by `__POWER9_VECTOR__`, POWER8 excluded
### 2025-01-23 ~15:30 UTC - POWER8 Compat Shim Created
**File**: `ggml/src/ggml-cpu/arch/powerpc/power8-compat.h`
**Key Discovery**: POWER8 has all needed intrinsics EXCEPT `vec_xl_len` (partial load)
- `vec_xl`, `vec_xst` - NATIVE on POWER8
- `vec_perm`, `vec_msum` - NATIVE on POWER8
- `vec_extract`, `vec_insert` - NATIVE on POWER8
- `vec_xl_len` - POWER9 ONLY β shimmed with memcpy
**Solution**: Define `__POWER9_VECTOR__` when `__POWER8_VECTOR__` detected, provide `vec_xl_len` shim
```c
#if defined(__POWER8_VECTOR__) && !defined(__POWER9_VECTOR__)
#define __POWER9_VECTOR__ 1
#define vec_xl_len(ptr, len) /* memcpy-based shim */
#endif
```
**Result**: All VSX-optimized quant paths now compile for POWER8
### 2025-01-23 ~16:00 UTC - IBM MASS Integration
**Location**: `/opt/ibm/xlmass/9.1.1/`
**Libraries**: `libmassvp8.a` (POWER8 vector), `libmass.a` (scalar)
**Functions Used**:
- `vsexp()` - vectorized exp for softmax
- `vstanh()` - vectorized tanh for activations (available)
- `vssqrt()` - vectorized sqrt (available)
- `vslog()` - vectorized log (available)
**CMakeLists.txt Addition** (line 438+):
```cmake
set(IBM_MASS_ROOT "/opt/ibm/xlmass/9.1.1")
target_include_directories(${GGML_CPU_NAME} PRIVATE ${IBM_MASS_ROOT}/include)
target_link_libraries(${GGML_CPU_NAME} PRIVATE
${IBM_MASS_ROOT}/lib/libmassvp8.a
${IBM_MASS_ROOT}/lib/libmass.a m)
target_compile_definitions(${GGML_CPU_NAME} PRIVATE GGML_USE_IBM_MASS=1)
```
**vec.cpp Integration** (existing code, now active):
```cpp
#if defined(__powerpc__) && defined(GGML_USE_IBM_MASS)
#include <massv.h>
// ... vsexp used in ggml_vec_soft_max_f32
#endif
```
### 2025-01-23 ~16:15 UTC - NUMA Support Added
**Library**: `/usr/lib/libnuma.so`
**CMakeLists.txt Addition**:
```cmake
find_library(NUMA_LIBRARY numa)
target_link_libraries(${GGML_CPU_NAME} PRIVATE ${NUMA_LIBRARY})
```
**RAM Coffers Header**: `ggml-ram-coffers.h`
- Detects 2 NUMA nodes (Node 0: 128GB, Node 1: 192GB)
- Provides `ggml_coffer_alloc()` for NUMA-aware allocation
### 2025-01-23 ~16:30 UTC - DCBT Prefetch Added
**File**: `ggml/src/ggml-cpu/arch/powerpc/quants.c`
**Location**: `ggml_vec_dot_q4_K_q8_K()` function, line ~914
```c
/* POWER8 PSE: Prefetch weight blocks into L2/L3 cache */
#ifdef GGML_POWER8_PSE_ACTIVE
{
const size_t block_size = sizeof(block_q4_K);
const char* ptr = (const char*)x;
for (int i = 0; i < nb && i < 16; i++) {
__asm__ __volatile__("dcbt 0, %0" : : "r"(ptr + i * block_size) : "memory");
}
}
#endif
```
---
## Performance Results
### Benchmark: OptiMind-SFT 20B Q4_K_M
| Build | pp128 (t/s) | tg32 (t/s) | Notes |
|-------|-------------|------------|-------|
| Codex scalar | ~1.0 | ~0.5 | No SIMD, generic fallback |
| PSE Full Stack | **15.54** | **4.58** | vec_perm + MASS + NUMA |
**Speedup**: ~15.5x prompt, ~9x generation
### Components Verified Active
| Component | Symbol/Evidence | Status |
|-----------|-----------------|--------|
| vec_perm | quants.c:327-328 | β
Used in Q4_K dequant |
| vec_msum | quants.c:266-267 | β
Used in dot product |
| vsexp (MASS) | `nm libggml-cpu.so \| grep vsexp` | β
Linked |
| libnuma | CMake detection | β
Linked |
| DCBT | quants.c:914+ | β
Compiled in |
---
## Files Modified/Created
### New PSE Headers (arch/powerpc/)
1. `power8-compat.h` - POWER9 intrinsic shims for POWER8
2. `ggml-pse-integration.h` - Master PSE integration
3. `ggml-intelligent-collapse.h` - Hebbian vec_perm collapse (headers)
4. `ggml-topk-collapse-vsx.h` - Top-K attention collapse (headers)
5. `ggml-ram-coffers.h` - NUMA coffer memory banking
6. `ggml-dcbt-resident.h` - L3 cache prefetch macros
7. `pse-entropy-burst.h` - Hardware entropy injection
8. `ggml-mass-integration.h` - IBM MASS wrapper
### Modified Files
1. `quants.c` - Added PSE includes, DCBT prefetch
2. `ggml-cpu.c` - Added PSE init call
3. `vec.cpp` - Added MASS include
4. `CMakeLists.txt` - Added NUMA + MASS linkage
---
## Next Steps (TODO)
### 1. PSE Collapse in Attention Hot Path
- Currently: Headers defined but not called
- Need: Hook into `ggml_compute_forward_flash_attn` or equivalent
- Goal: Non-bijunctive attention via vec_perm collapse
### 2. PowerLISP Hebbian Implementation
- Symbolic-neural bridge
- Tetranary logic (4-state confidence)
- Production rules with neural fallback
### 3. Full RAM Coffers Integration
- Currently: Library linked, nodes detected
- Need: Hook into model loading for NUMA-aware weight placement
- Goal: Route layers to optimal NUMA nodes
---
## Build Commands
```bash
# SSH to POWER8
ssh sophia@192.168.0.50 # or 100.94.28.32 via Tailscale
# Build with full PSE
cd ~/llama.cpp/build-pse-gptoss
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DGGML_OPENMP=ON \
-DCMAKE_C_FLAGS="-mcpu=power8 -mvsx -maltivec -O3 -DGGML_POWER8_PSE_ACTIVE=1" \
-DCMAKE_CXX_FLAGS="-mcpu=power8 -mvsx -maltivec -O3 -DGGML_POWER8_PSE_ACTIVE=1"
make -j32 llama-cli llama-bench
# Run with NUMA interleave
export OMP_NUM_THREADS=64
export OMP_PROC_BIND=spread
numactl --interleave=all ./bin/llama-cli -m /mnt/nvme/models/OptiMind-SFT-Q4_K_M.gguf -t 64
```
---
**Document Created**: 2025-01-23
**Last Updated**: 2025-01-23 ~16:45 UTC
**Author**: Claude + Scott (Elyan Labs)
## PSE Attention Collapse Integration (2026-01-23)
### Implementation Status
- β
Collapse header created:
- β
Symbolic gate header created:
- β
Integration point identified: in ops.cpp
- β οΈ HOT PATH OVERHEAD: Direct integration causes performance regression
### Key Findings
**Problem**: Calling collapse (or even gate check) in the softmax hot path causes massive overhead:
- A 20B model calls softmax **720,000+ times** per benchmark
- Even a simple gate check adds noticeable overhead at this scale
- Symbolic gate reduced collapse calls 10x but still hurt performance
**Performance Results**:
| Configuration | pp128 t/s | tg32 t/s |
|--------------|-----------|----------|
| Baseline (no collapse) | 14.76 | 0.88 |
| With collapse (every call) | 14.79 | 0.93 |
| With symbolic gate (sparse) | 9.74 | 0.80 |
### Correct Integration Approach (Future Work)
1. **Compile-Time Flag**: Use `-DPSE_COLLAPSE_ENABLED=1` to enable collapse
2. **Model Metadata**: Store which layers/heads benefit from collapse in GGUF
3. **Separate Attention Path**: Create PSE-specific attention op (not modify generic softmax)
4. **Flash Attention Hook**: Integrate into flash_attn path, not generic softmax
### Code Location
- Collapse header: `ggml/src/ggml-cpu/arch/powerpc/ggml-attn-collapse-vsx.h`
- Symbolic gate: `ggml/src/ggml-cpu/arch/powerpc/ggml-pse-symbolic-gate.h`
- Integration point: `ops.cpp:5255-5265` (commented out for now)
### The PowerLISP Vision
The symbolic layer (PowerLISP) should decide:
- **Which models** benefit from collapse (via model metadata)
- **Which layers** to collapse (early layers for representation, not all)
- **When to collapse** (prompt phase, not generation)
This decision should happen at model load time, not per-op call.
### 2026-06-11 ~00:15 CDT - PSE Port to Gemma 4-era llama.cpp + First MoE Results
**Context**: Gemma 4 26B-A4B (MoE, 4B active params) deployed on S824. The PSE tree
(based on 2026-03-27 master) predates Gemma 4 arch support, so the PSE patch set was
ported onto current master `ac4cdde` (2026-06-10).
**Port surface** (clean by design β PSE was always additive):
- 20+ pure-addition headers + `pse-runtime.c/h` β copied verbatim, zero conflicts
- 3-file diff (76 lines): `arch/powerpc/quants.c` + `ggml-cpu/CMakeLists.txt` applied
clean via `git apply`; `ggml-cpu.c` had drifted upstream β 8-line hook (include +
`pse_runtime_init()` in `ggml_cpu_init`) re-placed by hand
- Branch `pse-port`, isolated clone β vanilla build kept as A/B baseline
**Gemma 4 26B-A4B Q4_K_M results** (64 threads, S824, head-to-head same prompt):
| Build | tg (tokens/s) | pp (tokens/s) |
|-------|--------------|---------------|
| master, unbound threads | 0.6 | β |
| master + OMP spread/cores binding | 3.6 | 5.4 |
| **master + PSE port** | **6.4 (1.7x)** | **16.6 (3.1x)** |
**10.7x total** from stock-unbound to PSE-bound. The 3.1x prompt-processing gain is
the headline for MoE: context ingestion is the dominant cost for agent workloads, and
dcbt-resident prefetch + vec_msum paths attack exactly that.
**Why this matters**: PSE was written for dense models (TinyLlama/DeepSeek era).
It transferred to a mixture-of-experts architecture it had never seen, on a llama.cpp
tree 2.5 months newer, with one 8-line manual fix. Substrate work outlives model
generations.
**Operational notes**:
- `numactl` broken on this deployment (libnuma symbol-version mismatch) β OMP
`PROC_BIND=spread PLACES=cores` alone delivered the 6x binding win
- Gemma 4 thinks by default; `--reasoning-budget 0` required for serving, else
reasoning starves `max_tokens` and content returns empty
**Next β PSE-2 "Expert Coffers" (priority note, Elyan Labs 2026-06-11)**: MoE routers
emit expert selections *before* expert FFNs execute. That is a prefetch window: dcbt
expert weight banks speculatively per router logits, pin experts across NUMA nodes by
Hebbian co-activation ("experts that fire together get banked together"), and track
per-persona expert-activation fingerprints as a measurable identity-coherence signal.
Extends the NUMA weight-banking priority claim of
[ram-coffers](https://github.com/Scottcjn/ram-coffers) (2025-12-16, pre-dating
DeepSeek Engram) from domain granularity to expert granularity. Spec to follow after
baseline characterization β measure first, then build.
|