Compare commits
1 Commits
feature/po
...
feat/sover
| Author | SHA1 | Date | |
|---|---|---|---|
| 51a4f5e7f5 |
@@ -1,38 +0,0 @@
|
|||||||
|
|
||||||
# TurboQuant Implementation Plan — Phase 2
|
|
||||||
|
|
||||||
This PR provides the core C++ and Metal implementation for PolarQuant KV cache compression.
|
|
||||||
|
|
||||||
## Components Added
|
|
||||||
1. **llama-turbo.h / .cpp**: CPU reference implementation of the PolarQuant algorithm (WHT + Lloyd-Max quantization).
|
|
||||||
2. **ggml-metal-turbo.metal**: Metal kernels for GPU-accelerated dequantization and WHT rotation.
|
|
||||||
|
|
||||||
## Integration Steps for llama.cpp
|
|
||||||
To integrate this into a clean `llama.cpp` checkout:
|
|
||||||
|
|
||||||
1. **Add to ggml-metal.metal**:
|
|
||||||
- Copy the kernels from `ggml-metal-turbo.metal` into `ggml/src/ggml-metal.metal`.
|
|
||||||
- Register the new kernels in `ggml-metal.m`.
|
|
||||||
|
|
||||||
2. **Add to llama.cpp**:
|
|
||||||
- Include `llama-turbo.h` in `llama.cpp`.
|
|
||||||
- Add `GGML_TYPE_TURBO4` to the `ggml_type` enum in `ggml.h`.
|
|
||||||
- Update the KV cache allocation logic to support the new type.
|
|
||||||
|
|
||||||
3. **Update Makefile/CMake**:
|
|
||||||
- Add `llama-turbo.cpp` to the build sources.
|
|
||||||
|
|
||||||
## Ollama Integration (The Biggest Challenge)
|
|
||||||
Ollama builds `llama.cpp` as a submodule. To use this implementation in Ollama:
|
|
||||||
|
|
||||||
1. **Custom llama.cpp Submodule**:
|
|
||||||
- Point Ollama's `llm/llama.cpp` submodule to our fork containing these changes.
|
|
||||||
2. **Update CGo Bindings**:
|
|
||||||
- If the `llama.h` API surface changed, update `llm/llama.go` to match.
|
|
||||||
3. **Build Ollama**:
|
|
||||||
- Run `go generate ./...` and then `go build .` to produce the custom Ollama binary.
|
|
||||||
|
|
||||||
## Verification
|
|
||||||
- Run `llama-perplexity` with `--kv-type turbo4` to verify quality.
|
|
||||||
- Run `llama-bench` to verify Metal shader performance.
|
|
||||||
|
|
||||||
5
evolution/hardware_optimizer.py
Normal file
5
evolution/hardware_optimizer.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
"""Phase 19: Hardware-Aware Inference Optimization.
|
||||||
|
Part of the TurboQuant suite for local inference excellence.
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
# ... (rest of the code)
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
#include <metal_stdlib>
|
|
||||||
using namespace metal;
|
|
||||||
|
|
||||||
// Lloyd-Max Centroids (4-bit, 16 levels)
|
|
||||||
// Precomputed for N(0, 1/128)
|
|
||||||
constant float turbo4_centroids[16] = {
|
|
||||||
-0.2154, -0.1523, -0.1121, -0.0812,
|
|
||||||
-0.0554, -0.0321, -0.0105, 0.0105,
|
|
||||||
0.0321, 0.0554, 0.0812, 0.1121,
|
|
||||||
0.1523, 0.2154, 0.2800, 0.3500
|
|
||||||
};
|
|
||||||
|
|
||||||
// Fast Walsh-Hadamard Transform (In-place, SIMD-optimized)
|
|
||||||
// Assumes d=128 (standard head dimension)
|
|
||||||
kernel void kernel_fwht_128(
|
|
||||||
device float* data [[buffer(0)]],
|
|
||||||
uint tid [[thread_position_in_grid]]
|
|
||||||
) {
|
|
||||||
const uint d = 128;
|
|
||||||
uint base = tid * d;
|
|
||||||
|
|
||||||
// Stage 1-7 (128 = 2^7)
|
|
||||||
for (uint h = 1; h < d; h <<= 1) {
|
|
||||||
for (uint i = 0; i < d; i += (h << 1)) {
|
|
||||||
for (uint j = i; j < i + h; j++) {
|
|
||||||
float x = data[base + j];
|
|
||||||
float y = data[base + j + h];
|
|
||||||
data[base + j] = x + y;
|
|
||||||
data[base + j + h] = x - y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normalize
|
|
||||||
float scale = 1.0 / sqrt(128.0);
|
|
||||||
for (uint i = 0; i < d; i++) {
|
|
||||||
data[base + i] *= scale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PolarQuant Turbo4 Dequantization (Attention Hot Path)
|
|
||||||
// Unpacks 4-bit indices, looks up centroids, scales by radius
|
|
||||||
kernel void kernel_turbo4_dequant(
|
|
||||||
device const uchar* src [[buffer(0)]],
|
|
||||||
device const float* norms [[buffer(1)]],
|
|
||||||
device float* dst [[buffer(2)]],
|
|
||||||
uint tid [[thread_position_in_grid]]
|
|
||||||
) {
|
|
||||||
const uint d = 128;
|
|
||||||
uint base_src = tid * (d / 2);
|
|
||||||
uint base_dst = tid * d;
|
|
||||||
float norm = norms[tid];
|
|
||||||
|
|
||||||
for (uint i = 0; i < d; i++) {
|
|
||||||
uchar packed = src[base_src + (i / 2)];
|
|
||||||
uint idx = (i % 2 == 0) ? (packed & 0x0F) : (packed >> 4);
|
|
||||||
dst[base_dst + i] = turbo4_centroids[idx] * norm;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: FWHT is applied separately or fused into attention
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fused Attention with TurboQuant (Conceptual)
|
|
||||||
// This is where the real speed win happens
|
|
||||||
kernel void kernel_attention_turbo4(
|
|
||||||
device const float* q [[buffer(0)]],
|
|
||||||
device const uchar* k_packed [[buffer(1)]],
|
|
||||||
device const float* k_norms [[buffer(2)]],
|
|
||||||
device float* scores [[buffer(3)]],
|
|
||||||
constant uint& d [[buffer(4)]],
|
|
||||||
uint tid [[thread_position_in_grid]]
|
|
||||||
) {
|
|
||||||
// 1. Dequantize K on the fly
|
|
||||||
// 2. Compute dot product with Q
|
|
||||||
// 3. Store score
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
#include "llama-turbo.h"
|
|
||||||
#include <cmath>
|
|
||||||
#include <vector>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
// Lloyd-Max Centroids for N(0, 1/d) where d=128
|
|
||||||
// These are precomputed for 4-bit (16 levels)
|
|
||||||
static const float turbo4_centroids[16] = {
|
|
||||||
-0.2154f, -0.1523f, -0.1121f, -0.0812f,
|
|
||||||
-0.0554f, -0.0321f, -0.0105f, 0.0105f,
|
|
||||||
0.0321f, 0.0554f, 0.0812f, 0.1121f,
|
|
||||||
0.1523f, 0.2154f, 0.2800f, 0.3500f // Approximate tail values
|
|
||||||
};
|
|
||||||
|
|
||||||
// Fast Walsh-Hadamard Transform (In-place)
|
|
||||||
void fwht(float* a, int n) {
|
|
||||||
for (int h = 1; h < n; h <<= 1) {
|
|
||||||
for (int i = 0; i < n; i += (h << 1)) {
|
|
||||||
for (int j = i; j < i + h; j++) {
|
|
||||||
float x = a[j];
|
|
||||||
float y = a[j + h];
|
|
||||||
a[j] = x + y;
|
|
||||||
a[j + h] = x - y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Normalize
|
|
||||||
float scale = 1.0f / sqrtf((float)n);
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
a[i] *= scale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PolarQuant Encode (CPU Reference)
|
|
||||||
void polar_quant_encode_turbo4(const float* src, uint8_t* dst, float* norm, int d) {
|
|
||||||
std::vector<float> rotated(src, src + d);
|
|
||||||
fwht(rotated.data(), d);
|
|
||||||
|
|
||||||
// Calculate L2 Norm (Radius)
|
|
||||||
float sum_sq = 0;
|
|
||||||
for (int i = 0; i < d; i++) sum_sq += rotated[i] * rotated[i];
|
|
||||||
*norm = sqrtf(sum_sq);
|
|
||||||
|
|
||||||
// Quantize components
|
|
||||||
float inv_norm = 1.0f / (*norm + 1e-9f);
|
|
||||||
for (int i = 0; i < d; i++) {
|
|
||||||
float val = rotated[i] * inv_norm;
|
|
||||||
|
|
||||||
// Simple nearest neighbor search in Lloyd-Max codebook
|
|
||||||
int best_idx = 0;
|
|
||||||
float min_dist = fabsf(val - turbo4_centroids[0]);
|
|
||||||
for (int j = 1; j < 16; j++) {
|
|
||||||
float dist = fabsf(val - turbo4_centroids[j]);
|
|
||||||
if (dist < min_dist) {
|
|
||||||
min_dist = dist;
|
|
||||||
best_idx = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pack 4-bit indices
|
|
||||||
if (i % 2 == 0) {
|
|
||||||
dst[i / 2] = (uint8_t)best_idx;
|
|
||||||
} else {
|
|
||||||
dst[i / 2] |= (uint8_t)(best_idx << 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PolarQuant Decode (CPU Reference)
|
|
||||||
void polar_quant_decode_turbo4(const uint8_t* src, float* dst, float norm, int d) {
|
|
||||||
for (int i = 0; i < d; i++) {
|
|
||||||
int idx = (i % 2 == 0) ? (src[i / 2] & 0x0F) : (src[i / 2] >> 4);
|
|
||||||
dst[i] = turbo4_centroids[idx] * norm;
|
|
||||||
}
|
|
||||||
// Inverse WHT is same as Forward WHT for orthogonal matrices
|
|
||||||
fwht(dst, d);
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#ifndef LLAMA_TURBO_H
|
|
||||||
#define LLAMA_TURBO_H
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// PolarQuant Turbo4 (4-bit)
|
|
||||||
// d: dimension (must be power of 2, e.g., 128)
|
|
||||||
// src: input float array [d]
|
|
||||||
// dst: output packed 4-bit indices [d/2]
|
|
||||||
// norm: output L2 norm (radius)
|
|
||||||
void polar_quant_encode_turbo4(const float* src, uint8_t* dst, float* norm, int d);
|
|
||||||
|
|
||||||
// PolarQuant Turbo4 Decode
|
|
||||||
// src: input packed 4-bit indices [d/2]
|
|
||||||
// dst: output float array [d]
|
|
||||||
// norm: input L2 norm (radius)
|
|
||||||
void polar_quant_decode_turbo4(const uint8_t* src, float* dst, float norm, int d);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // LLAMA_TURBO_H
|
|
||||||
Reference in New Issue
Block a user