Repository navigation
[Fix] model_loader: Avoid unsafe pickle fallback when loading PyTorch checkpoints - #42760
Conversation
Remove the weights_only=False fallback for legacy tar checkpoints and pass weights_only=True to the remaining torch.load calls on model files, so a malicious checkpoint cannot execute code via pickle. Legacy tar checkpoints should be converted to safetensors offline. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
/rerun-test test/registered/unit/model_loader/test_weight_utils.py python/sglang/multimodal_gen/test/unit/test_weight_utils.py test/registered/vlm/test_vision_openai_server_a.py::TestDeepseekOCRServer test/registered/unit/multimodal/test_deepseek_ocr_geometry.py python/sglang/multimodal_gen/test/server/test_server_1_gpu.py::TestDiffusionServerOneGpu::test_diffusion_generation[wan2_1_t2v_1.3b_frame_interp_2x] |
|
🚀 🚀 🚀 |
|
@nvpohanh pls help to review, thanks! |
| loaded = _load_pt_file(path) | ||
| self.assertTrue(torch.equal(loaded["w"], torch.arange(4))) | ||
|
|
||
| def test_pickle_payload_is_not_executed(self): |
There was a problem hiding this comment.
[by Claude Code] Severity: style | Confidence: High
Issue
test_pickle_payload_is_not_executed does not cover the removed fallback. torch.save writes a zip file, so torch.load(weights_only=True) raises UnpicklingError on main too, before the legacy .tar format branch runs. I ran TestLoadPtFile against main's _load_pt_file, and both tests pass.
Example
A legacy tar file with members storages (pickle.dumps(0) + pickle.dumps([])), tensors (pickle.dumps(0)), and pickle (the _OpenOnUnpickle payload) creates the marker on main and raises RuntimeError on this PR (checked with torch 2.14).
Fix
Build the payload as that legacy tar file with tarfile instead of torch.save, so the test fails if the fallback comes back.
There was a problem hiding this comment.
Good catch, thanks. Replaced the torch.save payload with a hand-built legacy tar checkpoint (storages/tensors/pickle members). Checked with torch 2.14: on main's _load_pt_file the payload runs and the marker is created; on this branch it raises RuntimeError and nothing runs. The tensor state-dict test is unchanged. Also thanks for the history on the fallback.
torch.save writes a zip file, so the previous payload test also passed against the old fallback. Build a legacy tar checkpoint instead so the test fails if the weights_only=False fallback is reintroduced. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
/tag-and-rerun-ci |
|
[by Claude Code] I've started babysitting the NVIDIA CI of this PR. I'll check it every 30 minutes until all NV pipelines pass. If a relevant job fails, I may rerun it, merge the latest Anyone can stop me at any time: just post a comment asking me to stop (for example, |
|
[by Claude Code] The relevant CI failure (https://github.com/sgl-project/sglang/actions/runs/38384431344/job/115259669168) is not caused by this PR. It is a known breakage on |
Picks up sgl-project#44055, which fixes the unrelated CI failure https://github.com/sgl-project/sglang/actions/runs/38384431344/job/115259669168 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
[by Claude Code] I've started babysitting the NVIDIA CI of this PR. I'll check it every 30 minutes until all NV pipelines pass. If a relevant job fails, I may rerun it, merge the latest Anyone can stop me at any time: just post a comment asking me to stop (for example, |
|
/rerun-failed-ci |
…hts-only-upstream # Conflicts: # test/registered/unit/model_loader/test_weight_utils.py
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
[by Claude Code] I've started babysitting the NVIDIA CI of this PR. I'll check it every 30 minutes until all NV pipelines pass. If a relevant job fails, I may rerun it, merge the latest Anyone can stop me at any time: just post a comment asking me to stop (for example, |
|
/rerun-failed-ci |
|
[by Claude Code] @nguyendvk, the |
Picks up sgl-project#45038, which fixes the unrelated CI failure https://github.com/sgl-project/sglang/actions/runs/39122132737/job/117963435935 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/rerun-failed-ci |
1 similar comment
|
/rerun-failed-ci |
Starts a fresh PR Test Base run: the GitHub jobs API keeps returning 502 for run 39239074876 (https://github.com/sgl-project/sglang/actions/runs/39239074876/job/118205011160), so rerunning that run cannot pass its wait-for-base-b gate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/rerun-failed-ci |
1 similar comment
|
/rerun-failed-ci |
|
[by Claude Code] The relevant CI failure (base-c-test-8-gpu-b300 (0)) is not caused by this PR. It is a known CI breakage from |
Picks up sgl-project#45428, which fixes the unrelated CI failure https://github.com/sgl-project/sglang/actions/runs/39348980625/job/118556303062 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
[by Claude Code] I've started babysitting the NVIDIA CI of this PR. I'll check it every 30 minutes until all NV pipelines pass. If a relevant job fails, I may rerun it, merge the latest Anyone can stop me at any time: just post a comment asking me to stop (for example, |
|
[by Claude Code] The relevant CI failure (base-a-test-cpu (11)) is not caused by this PR. It is a known breakage on |
Picks up sgl-project#45476, which fixes the unrelated CI failure https://github.com/sgl-project/sglang/actions/runs/39532544294/job/119001829089 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/rerun-failed-ci |
|
[by Claude Code] All NV pipelines have passed. |
|
@mmangkad Could you review this? This is SGLang security issue. Thanks! |
Motivation
torch.load(weights_only=False)deserializes with pickle, so a crafted checkpoint can execute code when it is loaded._load_pt_filefell back to it for legacy tar checkpoints, and several loaders calledtorch.loadon model files withoutweights_only=True. This is the same class of issue as #35653 (RIFE) and is consistent with the contribution guide's rule against unpickling untrusted data.Modifications
weights_only=Falsefallback in_load_pt_file(srt/model_loader/weight_utils.pyandmultimodal_gen/runtime/loader/weight_utils.py). Legacy tar checkpoints now fail with torch's own error and should be converted to safetensors or a zip-format.ptoffline.weights_only=Truetotorch.loadindeepseek_ocr.py(x2),roberta.pyandrife_interpolator.py._load_pt_file: a tensor state dict still loads, and a pickle payload is not executed.srt/debug_utilsis unchanged: it reads developer-written tensor dumps, not model weights.Accuracy Tests
Not applicable: only the checkpoint deserialization path changes; no model forward code is touched.
Speed Tests and Profiling
Not applicable.
Checklist
🤖 Generated with Claude Code
CI States
Latest PR Test (Base): ✅ Run #39535409763
Latest PR Test (Extra): ❌ Run #39535409518
Latest PR Test (AMD ROCm 10): ❌ Run #39535409559