分层存储架构
5.6.1 GPU HBM (最快最昂贵)
GPU 是KV Cache的首选存储位置。
HBM 特性:
| 特性 | HBM2e | HBM3 | HBM3e |
|---|---|---|---|
| 带宽 | 1.2 TB/s | 1.5 TB/s | 2.0 TB/s |
| 容量/堆栈 | 16 GB | 24 GB | 36 GB |
| 典型GPU配置 | 40-80 GB | 80 GB | 141 GB |
| 延迟 | ~100ns | ~100ns | ~100ns |
| 成本/GB | ~$20 | ~$15 | ~$12 |
HBM 存储优化策略:
latex
GPU HBM 中的KV Cache布局:
┌─────────────────────────────────────────────────────────────┐
│ A100-80GB HBM 内存布局 │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 模型权重 (FP16): ~35-40 GB │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ KV Cache (FP16): ~20-30 GB │ │
│ │ - 活跃请求的KV Cache │ │
│ │ - 高频访问的缓存数据 │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ 激活值: ~5-10 GB │ │
│ ├─────────────────────────────────────────────────────┤ │
│ │ 预留/碎片: ~5-10 GB │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘5.6.2 CPU DRAM (中等速度)
当GPU HBM不足时,可以将KV Cache卸载到CPU DRAM。
CPU DRAM特性
| 特性 | DDR4 | DDR5 |
|---|---|---|
| 带宽 | 25-50 GB/s | 50-100 GB/s |
| 单服务器容量 | 1-2 TB | 2-4 TB |
| 延迟 | ~100ns | ~80ns |
| 成本/GB | ~$3 | ~$4 |
CPU DRAM vs GPU HBM 对比:
| 指标 | GPU HBM | CPU DRAM | 差距 |
|---|---|---|---|
| 带宽 | 1.5 TB/s | 50 GB/s | 30x |
| 容量 | 80 GB | 2 TB | 0.04x |
| 延迟 | 100 ns | 100 ns | 1x |
| 成本/GB | $15 | $4 | 3.75x |
CPU卸载策略
python
class CPUOffloadKVCache:
"""将不活跃的KV Cache卸载到CPU DRAM"""
def __init__(self, gpu_cache_size: int, cpu_cache_size: int):
self.gpu_cache = {} #活跃的KV Cache
self.cpu_cache = {} # 不活跃的KV Cache
self.gpu_size_limit = gpu_cache_size
self.current_gpu_size = 0
def get(self, key: str) -> Optional[torch.Tensor]:
if key in self.gpu_cache:
return self.gpu_cache[key]
elif key in self.cpu_cache:
# 从CPU加载到GPU
kv = self.cpu_cache.pop(key)
self._evict_to_cpu_if_needed(kv.numel())
self.gpu_cache[key] = kv.cuda()
return self.gpu_cache[key]
return None
def put(self, key: str, kv: torch.Tensor):
if self.current_gpu_size + kv.numel() > self.gpu_size_limit:
self._evict_to_cpu_if_needed(kv.numel())
self.gpu_cache[key] = kv.cuda()
self.current_gpu_size += kv.numel()
def _evict_to_cpu_if_needed(self, needed_space: int):
"""LRU 策略将KV Cache卸载到CPU"""
while self.current_gpu_size + needed_space > self.gpu_size_limit:
# 找到最久未使用的KV Cache
lru_key = self._find_lru_key()
kv = self.gpu_cache.pop(lru_key)
self.cpu_cache[lru_key] = kv.cpu()
self.current_gpu_size -= kv.numel()5.6.3 SSD/NVMe (慢但容量大)
对于超大规模的KV Cache,可以使用SSD/NVMe存储。
SSD/NVMe特性
| 特性 | SATA SSD | NVMe Gen3 | NVMe Gen4 | NVMe Gen5 |
|---|---|---|---|---|
| 顺序读 | 500 MB/s | 3.5 GB/s | 7 GB/s | 14 GB/s |
| 顺序写 | 500 MB/s | 3 GB/s | 5 GB/s | 10 GB/s |
| 随机读IOPS | 100K | 500K | 1M | 2M |
| 容量 | 1-8 TB | 1-8 TB | 1-16 TB | 1-32 TB |
| 延迟 | 100μs | 10μs | 10μs | 10μs |
| 成本/GB | $0.08 | $0.10 | $0.08 | $0.06 |
SSD 存储策略:
5.6.4 远程存储
在多节点部署中,可以使用远程存储共享KV Cache。
远程存储选项
| 存储类型 | 带宽 | 延迟 | 适用场景 |
|---|---|---|---|
| 分布式内存 (RDMA) | 50-100 Gbps | 1-5 μs | 集群内共享 |
| 对象存储 (S3) | 10-100 Gbps | 10-100 ms | 长期归档 |
| 分布式文件系统 | 10-50 Gbps | 1-10 ms | 中等规模共享 |
5.6.5 各层之间的数据传输
数据传输优化策略:
分层存储性能对比:
| 存储层 | 容量 | 带宽 | 延迟 | 成本/GB/月 | 适用数据 |
|---|---|---|---|---|---|
| GPU HBM | 80 GB | 1.5 TB/s | 100 ns | $15 | 活跃请求 |
| CPU DRAM | 2 TB | 50 GB/s | 100 ns | $4 | 活跃会话 |
| NVMe SSD | 16 TB | 7 GB/s | 10 μs | $0.08 | 近期会话 |
| 远程内存 | 无限 | 50 Gbps | 5 μs | $2 | 集群共享 |
| 对象存储 | 无限 | 10 Gbps | 50 ms | $0.02 | 长期归档 |