修复 PyTorch 模型加载错误:_pickle.UnpicklingError:无效的加载密钥,'x1f'

修复 PyTorch 模型加载错误:_pickle.UnpicklingError:无效的加载密钥,'x1f'
修复 PyTorch 模型加载错误:_pickle.UnpicklingError:无效的加载密钥,'x1f'

为什么 PyTorch 模型检查点失败:深入探讨加载错误

想象一下,花了整整一个月的时间训练 40 多个机器学习模型,却在尝试加载权重时遇到了一个神秘的错误: _pickle.UnpicklingError:无效的加载密钥,'x1f'。 😩 如果您正在使用 PyTorch 并遇到此问题,您就会知道它是多么令人沮丧。

当您的检查点文件由于损坏、格式不兼容或保存方式而出现问题时,通常会发生该错误。作为一名开发人员或数据科学家,在您即将取得进展时,处理此类技术故障可能会让人感觉碰壁。

就在上个月,我在尝试恢复 PyTorch 模型时遇到了类似的问题。无论我尝试了多少个版本的 PyTorch 或修改了多少个扩展,权重都无法加载。有一次,我什至尝试将文件作为 ZIP 存档打开,希望手动检查它 - 不幸的是,错误仍然存​​在。

在本文中,我们将详细解释此错误的含义、发生的原因,以及最重要的是如何解决它。无论您是初学者还是经验丰富的专业人士,到最后,您都会回到 PyTorch 模型的正轨。让我们深入了解一下! 🚀

命令 使用示例
zipfile.is_zipfile() 此命令检查给定文件是否是有效的 ZIP 存档。在此脚本的上下文中,它验证损坏的模型文件是否实际上是 ZIP 文件而不是 PyTorch 检查点。
zipfile.ZipFile() 允许读取和提取 ZIP 存档的内容。这用于打开和分析可能错误保存的模型文件。
io.BytesIO() 创建内存中二进制流来处理二进制数据,例如从 ZIP 存档中读取的文件内容,而不保存到磁盘。
torch.load(map_location=...) 加载 PyTorch 检查点文件,同时允许用户将张量重新映射到特定设备,例如 CPU 或 GPU。
torch.save() 以正确的格式重新保存 PyTorch 检查点文件。这对于修复损坏或格式错误的文件至关重要。
unittest.TestCase 该类是 Python 内置单元测试模块的一部分,有助于创建单元测试来验证代码功能和检测错误。
self.assertTrue() 验证单元测试中的条件是否为 True。在这里,它确认检查点加载成功且没有错误。
timm.create_model() 具体到 蒂姆 库中,该函数初始化预定义的模型架构。它用于在此脚本中创建“legacy_xception”模型。
map_location=device torch.load() 的一个参数,指定加载的张量应分配到的设备(CPU/GPU),以确保兼容性。
with archive.open(file) 允许读取 ZIP 存档内的特定文件。这使得能够处理 ZIP 结构中错误存储的模型权重。

了解并修复 PyTorch 检查点加载错误

当遇到可怕的事情时 _pickle.UnpicklingError:无效的加载密钥,'x1f',它通常表示检查点文件已损坏或以意外格式保存。在提供的脚本中,关键思想是使用智能恢复技术处理此类文件。例如,使用以下命令检查文件是否为 ZIP 存档 压缩文件 模块是至关重要的第一步。这确保了我们不会盲目地加载无效文件 火炬.load()。通过利用诸如 zip文件.ZipFileio.BytesIO,我们可以安全地检查和提取文件的内容。想象一下花费数周时间训练模型,而一个损坏的检查点停止了一切 - 您需要像这样的可靠的恢复选项!

在第二个脚本中,重点是 重新保存检查点 确保正确加载后。如果原始文件有小问题但仍然部分可用,我们使用 火炬.save() 修复并重新格式化它。例如,假设您有一个名为的损坏的检查点文件 CDF2_0.pth。通过重新加载并将其保存到新文件中,例如 固定_CDF2_0.pth,确保它遵循正确的 PyTorch 序列化格式。这种简单的技术对于保存在旧框架或环境中的模型来说是一个救星,使它们可以重复使用而无需重新训练。

此外,包含单元测试可确保我们的解决方案是 可靠的 并始终如一地工作。使用 单元测试 模块中,我们可以自动验证检查点加载,如果您有多个模型,这尤其有用。我曾经需要处理一个研究项目中的 20 多个模型,手动测试每个模型需要花费数天的时间。通过单元测试,单个脚本可以在几分钟内验证所有测试!这种自动化不仅节省时间,还可以防止错误被忽视。

最后,脚本的结构确保了跨设备(CPU 和 GPU)与 地图位置 争论。这使得它非常适合不同的环境,无论您是在本地还是在云服务器上运行模型。想象一下:您已经在 GPU 上训练了模型,但需要将其加载到仅使用 CPU 的计算机上。如果没有 地图位置 参数,你可能会遇到错误。通过指定正确的设备,脚本可以无缝处理这些转换,确保您来之不易的模型在任何地方都能工作。 😊

解决 PyTorch 模型检查点错误:无效的加载密钥

使用正确的文件处理和模型加载的 Python 后端解决方案

import os
import torch
import numpy as np
import timm
import zipfile
import io
# Device setup
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print('Device being used:', device)
# Correct method to load a corrupted or zipped model checkpoint
mname = os.path.join('./CDF2_0.pth')
try:
    # Attempt to open as a zip if initial loading fails
    if zipfile.is_zipfile(mname):
        with zipfile.ZipFile(mname) as archive:
            for file in archive.namelist():
                with archive.open(file) as f:
                    buffer = io.BytesIO(f.read())
                    checkpoints = torch.load(buffer, map_location=device)
    else:
        checkpoints = torch.load(mname, map_location=device)
    print("Checkpoint loaded successfully.")
except Exception as e:
    print("Error loading the checkpoint file:", e)
# Model creation and state_dict loading
model = timm.create_model('legacy_xception', pretrained=True, num_classes=2).to(device)
if 'state_dict' in checkpoints:
    model.load_state_dict(checkpoints['state_dict'])
else:
    model.load_state_dict(checkpoints)
model.eval()
print("Model loaded and ready for inference.")

替代解决方案:重新保存检查点文件

基于Python的修复损坏的检查点文件的解决方案

import os
import torch
# Device setup
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print('Device being used:', device)
# Original and corrected file paths
original_file = './CDF2_0.pth'
corrected_file = './fixed_CDF2_0.pth'
try:
    # Load and re-save the checkpoint
    checkpoints = torch.load(original_file, map_location=device)
    torch.save(checkpoints, corrected_file)
    print("Checkpoint file re-saved successfully.")
except Exception as e:
    print("Failed to fix checkpoint file:", e)
# Verify loading from the corrected file
checkpoints_fixed = torch.load(corrected_file, map_location=device)
print("Verified: Corrected checkpoint loaded.")

两种解决方案的单元测试

用于验证检查点加载和模型 state_dict 完整性的单元测试

import torch
import unittest
import os
import timm
class TestCheckpointLoading(unittest.TestCase):
    def setUp(self):
        self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
        self.model_path = './fixed_CDF2_0.pth'
        self.model = timm.create_model('legacy_xception', pretrained=True, num_classes=2).to(self.device)
    def test_checkpoint_loading(self):
        try:
            checkpoints = torch.load(self.model_path, map_location=self.device)
            if 'state_dict' in checkpoints:
                self.model.load_state_dict(checkpoints['state_dict'])
            else:
                self.model.load_state_dict(checkpoints)
            self.model.eval()
            self.assertTrue(True)
            print("Checkpoint loaded successfully in unit test.")
        except Exception as e:
            self.fail(f"Checkpoint loading failed with error: {e}")
if __name__ == '__main__':
    unittest.main()

了解 PyTorch 检查点失败的原因以及如何预防

一个被忽视的原因 _pickle.UnpicklingError 当使用 PyTorch 检查点保存时发生 旧版本 库但加载了较新的版本,反之亦然。 PyTorch 更新有时会导致序列化和反序列化格式发生变化。这些更改可能会使旧模型不兼容,从而在尝试恢复它们时导致错误。例如,使用 PyTorch 1.6 保存的检查点可能会导致 PyTorch 2.0 中出现加载问题。

另一个关键方面是确保使用保存检查点文件 火炬.save() 有正确的国家词典。如果有人错误地使用非标准格式保存模型或权重,例如直接对象而不是其 state_dict,这可能会导致加载过程中出现错误。为了避免这种情况,最好的做法是始终只保存 state_dict 并相应地重新加载重量。这使得检查点文件变得轻量级、可移植并且不易出现兼容性问题。

最后,特定于系统的因素(例如所使用的操作系统或硬件)可能会影响检查点加载。例如,使用 GPU 张量保存在 Linux 计算机上的模型在使用 CPU 的 Windows 计算机上加载时可能会导致冲突。使用 map_location 如前所示,参数有助于适当地重新映射张量。在多个环境中工作的开发人员应始终验证不同设置上的检查点,以避免最后一刻出现意外。 😅

有关 PyTorch 检查点加载问题的常见问题

  1. 为什么我得到 _pickle.UnpicklingError 加载我的 PyTorch 模型时?
  2. 此错误通常是由于检查点文件不兼容或损坏而发生。在保存和加载之间使用不同的 PyTorch 版本时也可能会发生这种情况。
  3. 如何修复损坏的 PyTorch 检查点文件?
  4. 你可以使用 zipfile.ZipFile() 检查文件是否是 ZIP 存档或重新保存检查点 torch.save() 修复后。
  5. 的作用是什么 state_dict 在 PyTorch 中?
  6. state_dict 包含字典格式的模型权重和参数。始终保存并加载 state_dict 为了更好的便携性。
  7. 如何在 CPU 上加载 PyTorch 检查点?
  8. 使用 map_location='cpu' 论证中 torch.load() 将张量从 GPU 重新映射到 CPU。
  9. PyTorch 检查点会因版本冲突而失败吗?
  10. 是的,较旧的检查点可能无法在较新版本的 PyTorch 中加载。建议保存和加载时使用一致的 PyTorch 版本。
  11. 如何检查 PyTorch 检查点文件是否损坏?
  12. 尝试使用加载文件 torch.load()。如果失败,请使用类似工具检查文件 zipfile.is_zipfile()
  13. 保存和加载 PyTorch 模型的正确方法是什么?
  14. 始终保存使用 torch.save(model.state_dict()) 并加载使用 model.load_state_dict()
  15. 为什么我的模型无法在其他设备上加载?
  16. 当张量保存为 GPU 但加载到 CPU 上时,就会发生这种情况。使用 map_location 来解决这个问题。
  17. 如何跨环境验证检查点?
  18. 使用编写单元测试 unittest 检查不同设置(CPU、GPU、操作系统)上的模型加载情况。
  19. 我可以手动检查检查点文件吗?
  20. 是的,您可以将扩展名更改为 .zip 并使用以下命令打开它 17 号 或档案管理员检查内容。

克服 PyTorch 模型加载错误

加载 PyTorch 检查点有时会因文件损坏或版本不匹配而引发错误。通过验证文件格式并使用适当的工具,例如 压缩文件 或重新映射张量,您可以有效地恢复经过训练的模型并节省重新训练的时间。

开发人员应该遵循最佳实践,例如保存 状态字典 仅并跨环境验证模型。请记住,解决这些问题所花费的时间可确保您的模型保持功能性、可移植性并与任何部署系统兼容。 🚀

PyTorch 加载错误解决方案的来源和参考
  1. 详细解释 火炬.load() 以及 PyTorch 中的检查点处理。来源: PyTorch 文档
  2. 洞察 泡菜 错误和文件损坏故障排除。来源: Python 官方文档
  3. 使用以下命令处理 ZIP 文件并检查档案 压缩文件 图书馆。来源: Python ZipFile 库
  4. 使用指南 蒂姆 用于创建和管理预训练模型的库。来源: timm GitHub 存储库