pytorch无法把共享内存写入文件

环境:

在容器中跑pytorch模型的训练 

问题表现:

ERROR: Unexpected bus error encountered in worker. This might be caused by insufficient shared memory (shm).
Traceback (most recent call last):
  File "/root/anaconda3/lib/python3.8/multiprocessing/queues.py", line 239, in _feed
    obj = _ForkingPickler.dumps(obj)
  File "/root/anaconda3/lib/python3.8/multiprocessing/reduction.py", line 51, in dumps
    cls(buf, protocol).dump(obj)
  File "/root/anaconda3/lib/python3.8/site-packages/torch/multiprocessing/reductions.py", line 358, in reduce_storage
    fd, size = storage._share_fd_cpu_()
RuntimeError: unable to write to file </torch_27822_2114653298_869>: No space left on device (28)

问题原因:

torch.utils.data.dataloader使用了共享内存。容器根目录没有空间,导致共享内存写到文件的时候报错。

解决方案,dataloader不使用共享内存:

f
<think>我们被要求监控PyTorch在CPU内存推理时的占用情况。用户想知道如何监控CPU内存占用,特别是在推理过程中。根据引用,我们之前讨论了GPU显存的监控(如使用nvidia-smi或torch.cuda.memory_allocated()),但CPU内存监控需要不同的工具。解决方案:1.使用Python内置模块:`resource`(Linux/macOS)或`psutil`(跨平台)来监控进程的内存使用。2.在推理代码的关键位置插入内存检查点,记录内存使用情况。由于`resource`模块在Windows上不可用,因此推荐使用跨平台的`psutil`库。步骤:1.安装`psutil`(如果尚未安装):```bashpip installpsutil```2.在推理代码中,使用`psutil`来获取当前进程的内存信息。示例代码:```pythonimport psutilimport torch#获取当前进程process =psutil.Process() #在推理开始前获取内存使用mem_before= process.memory_info().rss/ (1024**2)#转换为MB#进行推理model.eval() withtorch.no_grad():#假设data_loader是数据加载器for inputsin data_loader:outputs =model(inputs)#在每次迭代后获取内存使用mem_during =process.memory_info().rss /(1024 **2)print(f"Memoryduringinference:{mem_during:.2f}MB")#推理结束后获取内存使用mem_after =process.memory_info().rss /(1024 **2) print(f"Memory beforeinference:{mem_before:.2f}MB")print(f"Memoryafter inference: {mem_after:.2f} MB") ```说明: -`rss`(Resident SetSize)表示进程使用的实际物理内存(包含共享库占用的内存)。 -单位转换:将字节转换为MB(除以1024的平方,即1024*1024)。注意:1.如果推理过程中内存持续增长,可能是因为中间结果没有释放,或者有全局列表等累积了数据。需要检查代码中是否有不必要的变量引用。2.PyTorch中,即使使用CPU,也可能有内存管理问题,例如缓存分配器保留内存。可以使用`torch.cuda.empty_cache()`来清理GPU缓存,但CPU内存主要依靠Python的垃圾回收机制。另外,对于PyTorch的CPU内存,还可以使用`torch`自带的内存分析工具(如`torch.cuda`是用于GPU的,但CPU没有直接对应的函数)。因此,使用`psutil`是通用方法。引用[3]中提到在推理过程中将输出移动到CPU(这里原本是在GPU上,但我们现在关注CPU),但同样要注意在CPU上累积大量输出也会导致内存增加。因此,如果不需要保留所有输出,应避免将它们全部存储在列表中。优化建议:如果内存占用过高,可以考虑:1.及时删除不再需要的变量(使用`del`语句)。2.确保没有全局列表或字典在循环中不断增长。3.使用生成器或流式处理,避免一次性加载所有数据。完整示例(监控CPU内存): ```pythonimport psutilimport torchfromyour_model importmodel#替换为你的模型from your_data_loader importdata_loader#替换为你的数据加载器process= psutil.Process()#记录初始内存initial_mem= process.memory_info().rss/ (1024**2)print(f"Initialmemory:{initial_mem:.2f}MB")#设置模型为评估模式model.eval()#禁用梯度计算with torch.no_grad():fori,batchin enumerate(data_loader):#执行推理outputs= model(batch)#每处理完一个批次,记录内存current_mem =process.memory_info().rss /(1024 **2)print(f"Batch{i}: Memoryused ={current_mem:.2f}MB")#如果不需要保留整个输出,可以只保留必要信息,然后删除输出#del outputs#或者如果你需要后续处理,但数据量很大,考虑分批写入文件等#最终内存final_mem =process.memory_info().rss /(1024 **2) print(f"Finalmemory:{final_mem:.2f}MB")```这样,我们就可以监控在推理过程中CPU内存的占用情况了。相关问题:1.如何监控PyTorch在GPU上的显存使用?2.PyTorch推理过程中如何避免内存泄漏?3.有哪些工具可以分析Python程序的内存使用情况?</think>### PyTorch CPU 内存监控方法 在 PyTorch 推理过程中监控 CPU 内存占用,推荐使用以下方法: #### 1. 使用 `psutil` 库(跨平台) ```python import psutil import torch # 获取当前进程 process = psutil.Process() # 推理前内存 mem_before = process.memory_info().rss / (1024 ** 2) # MB单位 # 执行推理 with torch.no_grad(): outputs = model(inputs) # 推理中内存 mem_during = process.memory_info().rss / (1024 ** 2) # 推理后内存 mem_after = process.memory_info().rss / (1024 ** 2) print(f"内存变化: {mem_before:.2f}MB → {mem_during:.2f}MB → {mem_after:.2f}MB") ``` 关键指标: - **RSS (Resident Set Size)**:进程实际使用的物理内存 - **VMS (Virtual Memory Size)**:进程使用的虚拟内存总量 - 单位换算:`1 MB = 1024*1024 bytes` #### 2. 使用 `tracemalloc`(Python 内置) ```python import tracemalloc import torch tracemalloc.start() # 开始跟踪 # 记录初始内存 snapshot1 = tracemalloc.take_snapshot() # 执行推理 with torch.no_grad(): outputs = model(inputs) snapshot2 = tracemalloc.take_snapshot() # 推理中快照 # 计算内存差异 top_stats = snapshot2.compare_to(snapshot1, 'lineno') for stat in top_stats[:10]: # 显示前10个内存占用点 print(stat) ``` #### 3. 结合 PyTorch 的内存分析 ```python from torch.profiler import profile, record_function with profile(activities=[torch.profiler.ProfilerActivity.CPU]) as prof: with record_function("model_inference"): with torch.no_grad(): outputs = model(inputs) print(prof.key_averages().table(sort_by="cpu_memory_usage", row_limit=10)) ``` #### 内存优化建议 1. **及时释放资源**: ```python del outputs # 显式删除不再需要的张量 torch.cuda.empty_cache() # 清理GPU缓存(即使使用CPU)[^3] ``` 2. **控制数据加载**: ```python # 使用生成器避免一次性加载所有数据 for batch in data_loader: output = model(batch) process_output(output) del batch, output # 及时释放 ``` 3. **监控内存泄漏**: ```python # 周期性检查内存增长 for epoch in range(epochs): mem_start = process.memory_info().rss run_inference() mem_end = process.memory_info().rss assert mem_end - mem_start < 100 # 允许<100MB增长 ``` #### 完整监控示例 ```python import psutil import time import torch def monitor_memory(interval=0.5): """实时监控内存变化""" process = psutil.Process() print("时间戳\t内存(MB)\t变化(MB)") last_mem = process.memory_info().rss while True: current_mem = process.memory_info().rss print(f"{time.time():.1f}\t{current_mem/1e6:.2f}\t{+(current_mem-last_mem)/1e6:.2f}") last_mem = current_mem time.sleep(interval) # 在推理线程中启动监控 import threading threading.Thread(target=monitor_memory).start() # 执行推理 model.eval() with torch.no_grad(): outputs = model(inputs) ``` > **关键提示**:对于生产环境,建议使用 `memory_profiler` 包进行行级内存分析: > ```bash > pip install memory_profiler > mprof run --include-children python script.py > mprof plot > ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值