原帖在创建预训练 AlexNet 时失败,尚未执行 model(batch)。堆栈显示 torch.hub 正在读取本地缓存权重:
RuntimeError: PytorchStreamReader failed reading zip archive: failed finding central directory
根据失败时机缩小范围
models.alexnet(pretrained=True) 尚在下载或加载参数,输入图片、batch 尺寸和 GPU 显存还没有参与。先处理它实际读取的权重文件,之后再排查前向。central directory 是 ZIP 存档的目录结构,文件名叫 .pth 并不能保证内容就是完整权重。
这个错误说明当前文件不能按预期的 ZIP 存档读出目录。下载中断、错误页被存成权重、保存中断都是候选原因;仅靠这条消息不能证明是哪一个。
先定位缓存,不要删除整个目录:
from pathlib import Path
import torch
cache = Path(torch.hub.get_dir()) / "checkpoints"
print("josh050608")
print("cache:", cache)
print("alexnet files:", [(p.name, p.stat().st_size) for p in cache.glob("alexnet*")])
将堆栈或下载日志里的确切文件路径赋给 weight_path,只检查该文件:
import zipfile
from pathlib import Path
p = Path(weight_path)
print(p.resolve(), p.stat().st_size)
print("zip:", zipfile.is_zipfile(p))
if zipfile.is_zipfile(p):
with zipfile.ZipFile(p) as z:
print("bad entry:", z.testzip())
现代 torch.save 文件通常使用 ZIP;很早的合法权重也可能使用旧格式,所以 is_zipfile=False 不能单独作为损坏结论。结合来源、预期格式、下载大小和官方校验值判断。
若已确认这是失败的自动下载缓存,先将这一个文件改名备份,再通过原来的 torchvision 模型加载入口重新下载。不要靠修改扩展名、切换到 CPU 或设置 map_location 修复缺失的存档内容。网络需要能访问权重官方地址,磁盘也要有足够空间。
重新加载后再执行 model.eval() 与一个 batch 的前向。对于自己训练的唯一 checkpoint,应保留原件,寻找最近一次完整保存,而不是直接删除。
保留损坏证据,只替换确定的缓存项
从堆栈确认 weight_path 后,可以读取文件开头,排除“下载到了 HTML 错误页”这一分支。以下代码承接前面的 p = Path(weight_path),只读取前 80 字节,不尝试执行文件内容:
with p.open("rb") as stream:
prefix = stream.read(80)
print("size:", p.stat().st_size)
print("prefix:", repr(prefix))
若开头明显是网页、代理错误文本,应修正下载路径或网络后重新获取;若文件比下载日志预期小,怀疑截断,但仍应比较官方来源与校验信息。ZIP 测试可以发现结构或 CRC 异常,无法单独证明权重来自可信来源,也不验证模型结构匹配。
确认是可重新下载的官方缓存项后,可把它改名为带时间的备份,再调用原模型入口。不要同时删除其他模型权重;对于唯一的训练成果,应先找完整备份或上次 checkpoint,重命名扩展名无法补回丢失的数据。
下面用内存存档展示“完整 ZIP”和“尾部丢失”的区别,不生成模型权重,也不碰真实缓存:
import io
import zipfile
buffer = io.BytesIO()
with zipfile.ZipFile(buffer, "w") as archive:
archive.writestr("example.txt", "synthetic archive")
complete = buffer.getvalue()
truncated = complete[:-22]
print("complete/truncated:", zipfile.is_zipfile(io.BytesIO(complete)),
zipfile.is_zipfile(io.BytesIO(truncated)))
assert zipfile.is_zipfile(io.BytesIO(complete))
assert not zipfile.is_zipfile(io.BytesIO(truncated))
重新下载后先确认模型构造成功,再准备符合 AlexNet 输入预处理的 batch 做推理。加载错误消失而预测异常,是后续数据或模型使用问题;不要再拿这次 ZIP 报错解释所有失败。较新 torchvision 用 weights 参数选择预训练权重,维护旧代码时先核对实际安装版本,不必为了处理损坏缓存同时升级整个项目。
参考:原始求助帖;技术依据:torch.hub(2.5)、PyTorch 序列化格式(2.5)、Python zipfile。