内存管理 API¶
Genesis 提供高级的 CUDA 内存管理功能,包括引用计数内存池、综合统计信息和性能优化特性。
设备内存管理¶
设备方法¶
device.memory_allocated()¶
获取设备上当前分配的内存。
返回值: - int: 已分配的内存字节数
示例:
Python
import genesis
device = genesis.device('cuda')
allocated = device.memory_allocated()
print(f"已分配: {allocated / 1e6:.1f} MB")
device.memory_cached()¶
获取分配器当前缓存的内存。
返回值: - int: 已缓存的内存字节数
device.memory_reserved()¶
获取分配器保留的总内存。
返回值: - int: 已保留的内存字节数
device.max_memory_allocated()¶
获取会话期间分配的最大内存。
返回值: - int: 峰值已分配内存字节数
device.max_memory_cached()¶
获取会话期间缓存的最大内存。
返回值: - int: 峰值已缓存内存字节数
内存统计¶
device.memory_stats()¶
获取全面的内存使用统计信息。
返回值: - dict: 包含详细内存统计信息的字典
包含的统计信息: - allocated_bytes: 当前已分配内存 - cached_bytes: 当前已缓存内存
- reserved_bytes: 总保留内存 - inactive_split_bytes: 非活动分片中的内存 - active_bytes: 活动使用中的内存 - cache_hit_rate: 缓存命中率百分比 - num_allocations: 分配总次数 - num_cache_hits: 缓存命中次数 - num_cache_misses: 缓存未命中次数 - peak_allocated: 峰值已分配内存 - peak_cached: 峰值已缓存内存
示例:
Python
device = genesis.device('cuda')
stats = device.memory_stats()
print(f"缓存命中率: {stats['cache_hit_rate']:.1%}")
print(f"峰值内存: {stats['peak_allocated'] / 1e9:.2f} GB")
print(f"分配次数: {stats['num_allocations']}")
device.memory_summary()¶
获取人类可读的内存使用摘要。
返回值: - str: 格式化的内存使用摘要
示例:
内存控制¶
device.empty_cache()¶
清空内存缓存,释放已缓存但未使用的内存。
示例:
device.reset_memory_stats()¶
重置所有内存统计计数器。
示例:
内存性能分析¶
上下文管理器¶
genesis.profiler.profile_memory()¶
用于详细内存分析的上下文管理器。
示例:
Python
import genesis
device = genesis.device('cuda')
with genesis.profiler.profile_memory() as prof:
x = genesis.rand(4096, 4096, device=device)
y = genesis.matmul(x, x.T)
del x, y
# 获取详细的内存使用报告
print(prof.memory_summary())
print(f"峰值使用: {prof.peak_memory() / 1e6:.1f} MB")
内存事件¶
内存管理器跟踪详细的分配和释放事件:
分配事件¶
- 时间戳
- 分配大小
- 内存地址
- 分配持续时间
- 缓存命中/未命中状态
- 线程 ID
释放事件¶
- 时间戳
- 释放大小
- 内存地址
- 分配生命周期
- 线程 ID
高级功能¶
内存池配置¶
内存管理器对不同分配大小使用不同策略:
- 小分配 (<1MB): 使用缓存的引用计数内存池
- 大分配 (≥1MB): 使用段管理的直接 CUDA 分配
缓存优化¶
内存池自动优化缓存性能:
- 预热: 预分配常见大小
- 命中率跟踪: 监控缓存效果
- 自适应大小: 基于使用模式调整池大小
OOM 保护¶
内存管理器提供快速失败的 OOM 处理:
Python
try:
# 这可能导致 OOM
huge_tensor = genesis.zeros(100000, 100000, device='cuda')
except RuntimeError as e:
if "CUDA OOM" in str(e):
print("内存不足 - 请考虑减小张量大小")
性能监控¶
实时统计¶
实时监控内存使用:
Python
import genesis
import time
device = genesis.device('cuda')
# 重置统计以便干净测量
device.reset_memory_stats()
# 执行操作
for i in range(100):
x = genesis.rand(1000, 1000, device=device)
y = x + x
del x, y
if i % 10 == 0:
stats = device.memory_stats()
print(f"迭代 {i}: 缓存命中率: {stats['cache_hit_rate']:.1%}")
内存效率分析¶
Python
device = genesis.device('cuda')
# 分析内存效率
stats = device.memory_stats()
efficiency = stats['allocated_bytes'] / stats['reserved_bytes']
fragmentation = 1 - (stats['active_bytes'] / stats['allocated_bytes'])
print(f"内存效率: {efficiency:.1%}")
print(f"碎片化: {fragmentation:.1%}")
最佳实践¶
内存优化技巧¶
- 使用合适的张量大小: 尽量避免过小或过大的张量
- 清理中间结果: 删除不再需要的张量
- 监控缓存命中率: 追求 >95% 的命中率以获得最佳性能
- 使用上下文管理器: 在复杂操作中自动清理
示例: 优化的训练循环¶
Python
import genesis
device = genesis.device('cuda')
model = YourModel().to(device)
optimizer = genesis.optim.Adam(model.parameters())
# 重置统计以监控训练效率
device.reset_memory_stats()
for epoch in range(num_epochs):
for batch in dataloader:
# 前向传播
outputs = model(batch.to(device))
loss = criterion(outputs, targets.to(device))
# 反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 清理中间张量
del outputs, loss
# 每 100 个批次监控内存
if batch_idx % 100 == 0:
stats = device.memory_stats()
print(f"缓存命中率: {stats['cache_hit_rate']:.1%}")
故障排除¶
常见问题¶
- 低缓存命中率: 由张量大小变化引起。尽可能使用一致的大小。
- 内存碎片化: 定期使用
device.empty_cache()清理缓存 - OOM 错误: 监控峰值内存使用并减少批大小
- 内存泄漏: 使用适当的张量删除,避免循环引用
调试内存问题¶
Python
import genesis
device = genesis.device('cuda')
# 启用详细日志记录(如果可用)
genesis.set_memory_debug(True)
# 在整个执行过程中监控内存
def memory_checkpoint(name):
stats = device.memory_stats()
print(f"{name}: {stats['allocated_bytes'] / 1e6:.1f}MB 已分配, "
f"{stats['cache_hit_rate']:.1%} 命中率")
memory_checkpoint("开始")
x = genesis.rand(4096, 4096, device=device)
memory_checkpoint("分配后")
del x
memory_checkpoint("删除后")