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

PyTorch

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

想象一下,花了整整一个月的时间训练 40 多个机器学习模型,却在尝试加载权重时遇到了一个神秘的错误: 。 😩 如果您正在使用 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 检查点加载错误

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

在第二个脚本中,重点是 确保正确加载后。如果原始文件有小问题但仍然部分可用,我们使用 修复并重新格式化它。例如,假设您有一个名为的损坏的检查点文件 。通过重新加载并将其保存到新文件中,例如 固定_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 检查点失败的原因以及如何预防

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

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

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

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

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

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

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