Files
vllm-omni/vllm_omni/core/dit_cache_manager.py
T

185 lines
6.2 KiB
Python
Raw Normal View History

"""
DiT Cache Manager for vLLM-omni.
2025-10-24 12:16:48 +08:00
This module provides caching functionality for DiT (Diffusion Transformer)
models to optimize inference performance and memory usage.
"""
import time
2025-10-24 12:16:48 +08:00
from typing import Any, Dict, List, Optional
import torch
2025-10-24 12:16:48 +08:00
from ..config import DiTCacheConfig, DiTCacheTensor
class DiTCacheManager:
"""Manages DiT-specific caching for optimized inference."""
2025-10-24 12:16:48 +08:00
def __init__(self, config: DiTCacheConfig):
self.config = config
self.cache_tensors: Dict[str, DiTCacheTensor] = {}
self.cache_groups: List[DiTCacheTensor] = config.cache_tensors
self.max_cache_size = config.max_cache_size
self.current_cache_size = 0
self.cache_hits = 0
self.cache_misses = 0
self.cache_timeout = 3600 # 1 hour default timeout
2025-10-24 12:16:48 +08:00
def allocate_cache(self, request_id: str, size: int) -> torch.Tensor:
"""Allocate cache for a specific request."""
# Check if we have enough space
if self.current_cache_size + size > self.max_cache_size:
self._evict_cache()
2025-10-24 12:16:48 +08:00
# Create tensor
tensor = torch.zeros(size, dtype=torch.float32)
2025-10-24 12:16:48 +08:00
# Store in cache
cache_tensor = DiTCacheTensor(
name=request_id,
tensor=tensor,
timestamp=time.time(),
access_count=0,
2025-10-24 12:16:48 +08:00
size_bytes=size * 4, # Assuming float32
)
2025-10-24 12:16:48 +08:00
self.cache_tensors[request_id] = cache_tensor
self.current_cache_size += cache_tensor.size_bytes
2025-10-24 12:16:48 +08:00
return tensor
2025-10-24 12:16:48 +08:00
def get_cache(self, request_id: str) -> Optional[torch.Tensor]:
"""Get cached tensor for a request."""
if request_id in self.cache_tensors:
cache_tensor = self.cache_tensors[request_id]
cache_tensor.access_count += 1
self.cache_hits += 1
return cache_tensor.tensor
else:
self.cache_misses += 1
return None
2025-10-24 12:16:48 +08:00
def store_cache(self, request_id: str, tensor: torch.Tensor) -> None:
"""Store a tensor in the cache."""
if request_id in self.cache_tensors:
# Update existing cache
old_tensor = self.cache_tensors[request_id]
self.current_cache_size -= old_tensor.size_bytes
2025-10-24 12:16:48 +08:00
new_size_bytes = tensor.numel() * 4 # Assuming float32
self.current_cache_size += new_size_bytes
2025-10-24 12:16:48 +08:00
self.cache_tensors[request_id] = DiTCacheTensor(
name=request_id,
tensor=tensor,
timestamp=time.time(),
access_count=old_tensor.access_count,
2025-10-24 12:16:48 +08:00
size_bytes=new_size_bytes,
)
else:
# Create new cache entry
new_size_bytes = tensor.numel() * 4
if self.current_cache_size + new_size_bytes > self.max_cache_size:
self._evict_cache()
2025-10-24 12:16:48 +08:00
self.cache_tensors[request_id] = DiTCacheTensor(
name=request_id,
tensor=tensor,
timestamp=time.time(),
access_count=0,
2025-10-24 12:16:48 +08:00
size_bytes=new_size_bytes,
)
self.current_cache_size += new_size_bytes
2025-10-24 12:16:48 +08:00
def release_cache(self, request_id: str) -> None:
"""Release cache for a request."""
if request_id in self.cache_tensors:
cache_tensor = self.cache_tensors[request_id]
self.current_cache_size -= cache_tensor.size_bytes
del self.cache_tensors[request_id]
2025-10-24 12:16:48 +08:00
def clear_expired_cache(self) -> None:
"""Clear expired cache entries."""
current_time = time.time()
expired_keys = []
2025-10-24 12:16:48 +08:00
for request_id, cache_tensor in self.cache_tensors.items():
if current_time - cache_tensor.timestamp > self.cache_timeout:
expired_keys.append(request_id)
2025-10-24 12:16:48 +08:00
for request_id in expired_keys:
self.release_cache(request_id)
2025-10-24 12:16:48 +08:00
def _evict_cache(self) -> None:
"""Evict cache entries based on strategy."""
if self.config.cache_strategy == "fifo":
self._evict_fifo()
elif self.config.cache_strategy == "lru":
self._evict_lru()
elif self.config.cache_strategy == "lfu":
self._evict_lfu()
else:
self._evict_fifo() # Default to FIFO
2025-10-24 12:16:48 +08:00
def _evict_fifo(self) -> None:
"""Evict cache entries using FIFO strategy."""
if not self.cache_tensors:
return
2025-10-24 12:16:48 +08:00
# Find oldest entry
2025-10-24 12:16:48 +08:00
oldest_key = min(
self.cache_tensors.keys(),
key=lambda k: self.cache_tensors[k].timestamp,
)
self.release_cache(oldest_key)
2025-10-24 12:16:48 +08:00
def _evict_lru(self) -> None:
"""Evict cache entries using LRU strategy."""
if not self.cache_tensors:
return
2025-10-24 12:16:48 +08:00
# Find least recently used entry
2025-10-24 12:16:48 +08:00
lru_key = min(
self.cache_tensors.keys(),
key=lambda k: self.cache_tensors[k].access_count,
)
self.release_cache(lru_key)
2025-10-24 12:16:48 +08:00
def _evict_lfu(self) -> None:
"""Evict cache entries using LFU strategy."""
if not self.cache_tensors:
return
2025-10-24 12:16:48 +08:00
# Find least frequently used entry
2025-10-24 12:16:48 +08:00
lfu_key = min(
self.cache_tensors.keys(),
key=lambda k: self.cache_tensors[k].access_count,
)
self.release_cache(lfu_key)
2025-10-24 12:16:48 +08:00
def get_statistics(self) -> Dict[str, Any]:
"""Get cache statistics."""
total_requests = self.cache_hits + self.cache_misses
hit_rate = self.cache_hits / total_requests if total_requests > 0 else 0
2025-10-24 12:16:48 +08:00
return {
"cache_size": self.current_cache_size,
"max_cache_size": self.max_cache_size,
"cache_utilization": self.current_cache_size / self.max_cache_size,
"cache_hits": self.cache_hits,
"cache_misses": self.cache_misses,
"hit_rate": hit_rate,
2025-10-24 12:16:48 +08:00
"num_cached_tensors": len(self.cache_tensors),
}
2025-10-24 12:16:48 +08:00
def clear_all_cache(self) -> None:
"""Clear all cache entries."""
self.cache_tensors.clear()
self.current_cache_size = 0
self.cache_hits = 0
self.cache_misses = 0
2025-10-24 12:16:48 +08:00
def set_cache_timeout(self, timeout: float) -> None:
"""Set cache timeout in seconds."""
2025-10-24 12:16:48 +08:00
self.cache_timeout = timeout