PyTorch 讀取權重出錯
checkpoint = torch.load(CONFIG['model_path'], weights_only=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/dist-packages/torch/serialization.py", line 1529, in load
raise pickle.UnpicklingError(_get_wo_message(str(e))) from None
_pickle.UnpicklingError: Weights only load failed. This file can still be loaded, to do so you have two options, do those steps only if you trust the source of the checkpoint.
(1) In PyTorch 2.6, we changed the default value of the `weights_only` argument in `torch.load` from `False` to `True`. Re-running `torch.load` with `weights_only` set to `False` will likely succeed, but it can result in arbitrary code execution. Do it only if you got the file from a trusted source.
(2) Alternatively, to load with `weights_only=True` please check the recommended steps in the following error message.
WeightsUnpickler error: Unsupported global: GLOBAL numpy._core.multiarray.scalar was not an allowed global by default. Please use `torch.serialization.add_safe_globals([numpy._core.multiarray.scalar])` or the `torch.serialization.safe_globals([numpy._core.multiarray.scalar])` context manager to allowlist this global if you trust this class/function.
Check the documentation of torch.load to learn more about types accepted by default with weights_only https://pytorch.org/docs/stable/generated/torch.load.html.
###########################################################################
這個錯誤是因為 PyTorch 2.6+ 更改了預設安全性設定。現在 torch.load 預設開啟了 weights_only=True,但你的模型權重存檔中包含了 numpy 的資料型別(通常是因為訓練時紀錄了某些 Numpy 標量),這被新版的安全性機制攔截了。
你有兩種解決方法,建議使用第一種:
方法 1:將 Numpy 加入「安全白名單」(推薦)
這是最標準的作法,既能保持 weights_only=True 的安全性,又能順利讀取檔案。在你的 torch.load 執行之前,加入這行程式碼:
import torch import numpy # 將 numpy 的標量型別加入安全名單 torch.serialization.add_safe_globals([numpy._core.multiarray.scalar]) # 然後再執行你原本的讀取 checkpoint = torch.load(CONFIG['model_path'], weights_only=True)
方法 2:關閉安全性檢查(最快但風險較高)
如果你完全信任這個模型檔(那是你自己產出的),你可以直接將參數改回 False:
# 加上 weights_only=False checkpoint = torch.load(CONFIG['model_path'], weights_only=False)
為什麼會這樣?
因為舊版 PyTorch 讀取權重時使用的是 pickle 模組,這存在惡意程式碼執行的風險。PyTorch 2.6 之後為了保護使用者,預設只允許讀取基本張量。由於你的 checkpoint 裡可能存了 numpy 格式的 loss 或 epoch 數值,導致被判定為「非權重資料」而阻擋。
建議動作: 先試試方法 1,這通常能解決 99% 從本地 3060 移到 Colab 時產生的權重讀取問題。
需要我幫你看看這段程式碼要安插在 training_v1.2.py 的哪個位置嗎?
###########################################################################
File "/content/drive/MyDrive/k_predict/training_v1.2.py", line 400, in train_single_fold
checkpoint = torch.load(CONFIG['model_path'], weights_only=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/dist-packages/torch/serialization.py", line 1529, in load
raise pickle.UnpicklingError(_get_wo_message(str(e))) from None
_pickle.UnpicklingError: Weights only load failed. This file can still be loaded, to do so you have two options, do those steps only if you trust the source of the checkpoint.
(1) In PyTorch 2.6, we changed the default value of the `weights_only` argument in `torch.load` from `False` to `True`. Re-running `torch.load` with `weights_only` set to `False` will likely succeed, but it can result in arbitrary code execution. Do it only if you got the file from a trusted source.
(2) Alternatively, to load with `weights_only=True` please check the recommended steps in the following error message.
WeightsUnpickler error: Unsupported global: GLOBAL numpy._core.multiarray.scalar was not an allowed global by default. Please use `torch.serialization.add_safe_globals([numpy._core.multiarray.scalar])` or the `torch.serialization.safe_globals([numpy._core.multiarray.scalar])` context manager to allowlist this global if you trust this class/function.
Check the documentation of torch.load to learn more about types accepted by default with weights_only https://pytorch.org/docs/stable/generated/torch.load.html.
###########################################################################
這是一個非常奇怪的情況。報錯訊息明確指出你的程式碼第 400 行是: checkpoint = torch.load(CONFIG['model_path'], weights_only=False)
但錯誤訊息卻仍然跳出 "Weights only load failed"。這通常是因為 Colab 目前環境中的 PyTorch 2.6 版本在處理含有 numpy 標量的舊版 pickle 存檔時,即便你手動設為 False,底層檢查機制仍可能因為某些環境衝突而噴出這個錯誤訊息(或是你的修改沒有被正確存檔/讀取)。
為了徹底解決這個問題,請在 training_v1.2.py 的最頂端(或是第 400 行之前),加入「白名單」宣告。這是目前 PyTorch 2.6 最穩定的解法:
解決方案:強制允許 Numpy 全域變數
請在 training_v1.2.py 中,將讀取模型的程式碼改成這樣:
import torch import numpy # --- 新增這兩行 --- if hasattr(torch.serialization, 'add_safe_globals'): torch.serialization.add_safe_globals([numpy._core.multiarray.scalar]) # ---------------- # 原本的讀取邏輯 checkpoint = torch.load(CONFIG['model_path'], weights_only=False)
為什麼明明設了 weights_only=False 還是報錯?
這可能是以下幾個原因:
-
Google Drive 快取問題:如果你是在本地修改了 .py 檔,Google Drive 桌面端同步到雲端可能需要一點時間。你在 Colab 執行的可能還是「舊版」的程式碼。
-
檢查方式:在 Colab 用 !cat /content/drive/MyDrive/k_predict/training_v1.2.py | sed -n '395,405p' 來查看該檔案第 395 到 405 行的真實內容。
-
-
PyTorch 2.6 的 Bug/嚴格檢查:在某些極端情況下,PyTorch 2.6 偵測到 numpy 標量時會直接觸發 UnpicklingError,即便你選擇不限制權重讀取。
建議操作流程:
-
先在 Colab 儲存格確認檔案內容: 執行 !grep "weights_only" /content/drive/MyDrive/k_predict/training_v1.2.py,確認內容真的是 False。
-
加入白名單:使用我上面提供的 add_safe_globals 方法。
-
重啟 Runtime:有時候 PyTorch 的底層 C++ 狀態會卡住,點選選單的 「執行階段」 > 「重新啟動工作階段」。
如果加了白名單還是報錯,請把 !cat 出來的第 400 行前後程式碼貼給我,我來確認是否有隱藏的語法衝突!
###########################################################################
後記:
確實加入白名單宣告 + weights_only=False 就有用了
結果嘗試把一些額外參數寫入 pth 來做到接續訓練也沒什麼用
因為 colab 本身就不讓你免費訓練的
越要用
就越是給你限制

留言板
歡迎留下建議與分享!希望一起交流!感恩!