因为多次异常手动中断编译进程,导致lock文件没有被及时自动清理,编译文件始终处于无法detach的状态。重新编译文件无响应,手动终止时,显示
File "D:\XXX\backend.py", line 6, in <module> _backend = load(name='_hash_encoder', File "C:\anaconda3\envs\XXX\lib\site-packages\torch\utils\cpp_extension.py", line 1308, in load return _jit_compile( File "C:\anaconda3\envs\XXX\lib\site-packages\torch\utils\cpp_extension.py", line 1724, in _jit_compile baton.wait() File "C:\anaconda3\envs\XXX\lib\site-packages\torch\utils\file_baton.py", line 42, in wait time.sleep(self.wait_seconds)
尝试重新搭建新的虚拟环境,重启pycharm,均无果。发现是因为锁文件存在导致的编译过程无法继续,手动清理后可以正常编译。
问题背景
当使用PyTorch来编译和加载CUDA/C++扩展(例如,通过torch.utils.cpp_extension.load方法)时,PyTorch会在.cache目录下创建一个临时的编译环境。这个过程中会用到一个锁文件,以防止同时执行的编译进程之间发生冲突。然而,有时候,由于意外的程序终止或其他原因,这个锁文件可能没有被正确清理,导致后续尝试编译同一个扩展的操作被阻塞。
解决方案
如果遇到因锁文件而无法进行编译的问题,可以手动删除这个锁文件来解锁编译过程。具体步骤如下:
1. 定位.cache目录
这个目录通常位于用户的主目录下的.cache/torch_extensions路径中,例如~/.cache/torch_extensions。
或者“C:\anaconda3\envs\XXX\Lib\site-packages\torch\utils\cpp_extension.py”。找到
baton = FileBaton(os.path.join(build_directory, 'lock'))
所在行,大概是第1686行,设置断点。使用python调试器运行自己的.py代码,程序会运行直到达到设置的断点。当程序在断点处暂停时,使用
print(build_directory)
命令来打印build_directory的值。这将显示编译缓存目录的路径 "C:\Users\AppData\Local\torch_extensions\torch_extensions\Cache\py39_cu121\_hash_encoder",这是PyTorch用于存储编译扩展的临时文件和锁文件的地方。
2. 删除锁文件
在上述缓存目录路径中,找到尝试编译的扩展相关的子目录。
在这个子目录中,寻找名为lock的文件,然后将其删除。
3. 重新编译
删除锁文件后,重新运行编译命令,应该不会再因为锁文件的问题而被阻塞。
Lock文件介绍
在PyTorch编译和加载CUDA/C++扩展的过程中,lock文件用于同步多个并行编译进程,防止它们同时修改同一套编译产物或缓存。这是一种常见的机制,用于保证在使用共享资源时的线程安全或进程安全。下面是lock文件的一些主要用途和工作原理:
用途
避免冲突:当有多个进程尝试编译同一个CUDA/C++扩展时,lock文件确保同一时间只有一个进程能进行编译,从而避免编译产物被不同进程同时写入或修改,造成数据损坏。
资源管理:在编译过程中可能会生成临时文件或缓存,lock文件帮助管理这些资源,确保它们在正确的时间被创建和清理,防止因为资源未正确释放而导致的问题。
工作原理
创建锁定:当一个编译进程开始时,它会检查lock文件是否存在。如果不存在,该进程会创建一个lock文件,并继续编译操作。
检测锁定:如果另一个编译进程启动并发现lock文件已存在,它会知道另一个编译过程正在进行中,因此会等待直到lock文件被删除。
释放锁定:当持有lock文件的编译进程完成所有编译任务后,它会删除lock文件,表明编译资源现在是空闲的。这一操作向其他等待的进程发出信号,表明它们现在可以开始自己的编译过程。
问题
尽管lock文件是一种有效的同步机制,但在某些情况下可能会导致问题:
如果编译进程非正常终止(如因崩溃或强制退出),lock文件可能不会被正确删除。这会导致后续的编译尝试被不必要地阻塞。
在一些系统上,因为权限或文件系统的问题,lock文件可能无法被创建或删除,同样会影响编译过程。
解决方法
如果确认当前没有其他编译进程正在运行,且lock文件仍然存在,手动删除lock文件是解决编译阻塞问题的快速方法。但在执行这一操作前,确保确实没有其他编译进程在运行,以避免数据损坏或其他潜在问题。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/Yuanwai1995/article/details/137095420