{"record":{"id":"bc6f4c7b70c2681a","repo":"unslothai/unsloth","slug":"this-torch-cannot-register-the-pre-quant-construct","errorCode":null,"errorMessage":"this torch cannot register the pre-quant constructor allowlist (needs torch.serialization.add_safe_globals with (object, name) support, i.e. >= 2.6), so a pre-quant checkpoint cannot be deserialized without allowing arbitrary pickle globals","messagePattern":"this torch cannot register the pre-quant constructor allowlist \\(needs torch\\.serialization\\.add_safe_globals with \\(object, name\\) support, i\\.e\\. >= 2\\.6\\), so a pre-quant checkpoint cannot be deserialized without allowing arbitrary pickle globals","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"studio/backend/core/inference/diffusion_prequant.py","lineNumber":278,"sourceCode":"    floor answer the registration itself already checked.\"\"\"\n    if not _register_prequant_safe_globals():\n        return False\n    required = _SCHEME_REQUIRED_GLOBALS.get((scheme or \"\").strip().lower())\n    return True if required is None else required <= _RESOLVED_SAFE_GLOBALS\n\n\ndef _torch_load_prequant(path: str, **kwargs: Any) -> Any:\n    \"\"\"``torch.load`` a pre-quant checkpoint under the allowlist above.\n\n    ``weights_only = True`` is the whole point: a pickle that may name any global is remote code\n    execution the moment the artifact is not the one that was published. Everything the format\n    legitimately needs is allowlisted, so the restriction costs nothing and a mutated artifact\n    raises ``UnpicklingError`` into the caller's dense fallback instead of running. A torch that\n    cannot express the allowlist is refused outright, never reopened unrestricted.\"\"\"\n    import torch\n\n    if not _register_prequant_safe_globals():\n        raise RuntimeError(\n            \"this torch cannot register the pre-quant constructor allowlist (needs \"\n            \"torch.serialization.add_safe_globals with (object, name) support, i.e. >= 2.6), so \"\n            \"a pre-quant checkpoint cannot be deserialized without allowing arbitrary pickle \"\n            \"globals\"\n        )\n    return torch.load(path, weights_only = True, **kwargs)\n\n\n_PREQUANT_TOGGLE_TOKENS = {\"1\", \"true\", \"yes\", \"on\", \"0\", \"false\", \"no\", \"off\"}\n\n\ndef _allowed_prequant_roots() -> list:\n    \"\"\"Operator-allowlisted directories whose pre-quant checkpoints may be unpickled.\n\n    ``UNSLOTH_ALLOW_LOCAL_PREQUANT_PATH`` = one or more dirs (``os.pathsep``-separated). A\n    bare truthy/falsey toggle is ignored: it must name a directory, so no \"allow all\" mode.\"\"\"\n    import os\n","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/inference/diffusion_prequant.py#L260-L296","documentation":"_torch_load_prequant refuses to deserialize a pre-quant checkpoint when the installed torch cannot register the constructor allowlist for weights_only loading — torch.serialization.add_safe_globals with (object, name) support, i.e. torch >= 2.6. The alternative (unrestricted pickle) would be remote code execution on a mutated artifact, so an older torch is refused outright, never reopened unrestricted.","triggerScenarios":"Loading a pre-quant .pt checkpoint (not safetensors) on torch < 2.6 where _register_prequant_safe_globals() returns False. Deliberately raises RuntimeError rather than degrading to weights_only=False.","commonSituations":"Environments pinned to torch 2.4/2.5 (older CUDA stacks, ROCm builds, CI images); long-lived containers that never upgraded torch.","solutions":["Upgrade to torch >= 2.6 (pip install -U 'torch>=2.6')","Or convert the checkpoint to .safetensors, which loads without the pickle allowlist","Or use the dense (non-pre-quant) checkpoint variant and quantize at load time"],"exampleFix":"// before\ntorch==2.5.1  # requirements.txt, pre-quant load raises\n// after\ntorch>=2.6.0","handlingStrategy":"type-guard","validationCode":"import torch\nfrom packaging.version import Version\n\ndef can_load_prequant() -> bool:\n    return Version(torch.__version__) >= Version(\"2.6.0\")","typeGuard":"def prequant_supported() -> bool:\n    import torch\n    return hasattr(torch.serialization, \"add_safe_globals\") and Version(torch.__version__.split(\"+\")[0]) >= Version(\"2.6\")","tryCatchPattern":"try:\n    _torch_load_prequant(path)\nexcept RuntimeError:\n    # dense fallback path — do NOT fall back to weights_only=False\n    load_dense_checkpoint(path)","preventionTips":["Pin torch>=2.6 in environments that consume pre-quant checkpoints","Prefer .safetensors artifacts where possible","Never bypass with weights_only=False — the refusal is a security control"],"tags":["security","torch","version","quantization","deserialization"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}