Download src/verseflow/kernel/paged_latent_pool.py from julius119/VerseFlow-Studio: direct link, hf CLI and curl.
- Browser
- Download file 2.37 kB
-
https://huggingface.co/julius119/VerseFlow-Studio/resolve/main/src/verseflow/kernel/paged_latent_pool.py
- Command line
-
hf download hf://julius119/VerseFlow-Studio/src/verseflow/kernel/paged_latent_pool.py
-
curl -L -o paged_latent_pool.py https://huggingface.co/julius119/VerseFlow-Studio/resolve/main/src/verseflow/kernel/paged_latent_pool.py
2.37 kB
| """ | |
| Paged Video Latent 内存池与连续批处理引擎 (vLLM Style) | |
| Author: XiaoZhe (Commercial Contact: janejulius119@gmail.com / WeChat: julius119) | |
| """ | |
| import torch | |
| import logging | |
| from typing import Dict, List | |
| logger = logging.getLogger("VerseFlow.PagedLatentPool") | |
| class LatentBlock: | |
| def __init__(self, block_id: int, block_size: int, num_channels: int, height: int, width: int, dtype=torch.float16): | |
| self.block_id = block_id | |
| self.ref_count = 0 | |
| self.data = torch.empty((block_size, num_channels, height, width), dtype=dtype, device="cuda") | |
| class PagedVideoLatentMemoryPool: | |
| """视频扩散模型 Paged Latent 显存池,消除显存碎片""" | |
| def __init__(self, total_blocks: int = 1024, block_size: int = 16, channels: int = 4, height: int = 64, width: int = 64): | |
| self.block_size = block_size | |
| self.free_blocks: List[LatentBlock] = [ | |
| LatentBlock(i, block_size, channels, height, width) for i in range(total_blocks) | |
| ] | |
| self.allocated_blocks: Dict[int, LatentBlock] = {} | |
| self.block_table: Dict[str, List[int]] = {} | |
| def allocate(self, sequence_id: str, num_frames: int) -> List[int]: | |
| num_blocks_needed = (num_frames + self.block_size - 1) // self.block_size | |
| if len(self.free_blocks) < num_blocks_needed: | |
| raise RuntimeError(f"Paged 显存池开销溢出: 需要 {num_blocks_needed} 页,剩余 {len(self.free_blocks)} 页") | |
| allocated_ids = [] | |
| for _ in range(num_blocks_needed): | |
| block = self.free_blocks.pop() | |
| block.ref_count = 1 | |
| self.allocated_blocks[block.block_id] = block | |
| allocated_ids.append(block.block_id) | |
| self.block_table[sequence_id] = allocated_ids | |
| logger.info(f"🧠 [PagedLatent] 序列 {sequence_id} 成功分配 {num_blocks_needed} 个 Block 页") | |
| return allocated_ids | |
| def free_sequence(self, sequence_id: str): | |
| if sequence_id not in self.block_table: | |
| return | |
| for block_id in self.block_table[sequence_id]: | |
| block = self.allocated_blocks.pop(block_id, None) | |
| if block: | |
| block.ref_count = 0 | |
| self.free_blocks.append(block) | |
| del self.block_table[sequence_id] | |
| logger.info(f"♻️ [PagedLatent] 序列 {sequence_id} 显存页成功回收") |