unsloth/tests/saving
Daniel Han 64f6526160
Fix export-time trust_remote_code bypass in FP8/INT8/GGUF-LoRA export (#6869)
* Fix export-time trust_remote_code bypass in FP8/INT8/GGUF-LoRA export

The torchao, compressed-tensors, and LoRA GGUF export paths re-read the merged
checkpoint and used to set trust_remote_code from the checkpoint config's static
auto_map (the torchao path also scanned the staged tokenizer/processor configs).
A model that loads with built-in Transformers classes can carry an auto_map entry,
which skips the load-time remote-code consent scan (that only runs when the load
already requested trust_remote_code) yet flips trust_remote_code on at export,
running unvetted custom code.

Derive the reload trust_remote_code from the approved load decision instead: a new
_loaded_via_remote_code() checks whether the in-memory model / tokenizer was itself
loaded from custom code (its class lives in the transformers_modules package),
walking PEFT / wrapper layers. Built-in-loaded models no longer gain trust from
config metadata; genuine custom-code models (loaded with consent) still reload
correctly. Add CPU-only regression tests.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Harden _loaded_via_remote_code against a None/missing __module__

Read type(node).__module__ via getattr and require a string before startswith,
so a dynamically created or C-extension class with a None module does not raise
during export. Add a regression test.

* Split model and tokenizer trust for the compressed subprocess, walk processor components

The compressed-tensors export collapsed model and tokenizer trust into
one --trust-remote-code flag, so an approved custom tokenizer would have
let an unapproved model's custom code run inside the quantization
subprocess. The subprocess now takes --trust-remote-code-tokenizer for
the processor load and keeps --trust-remote-code for the model loads,
matching the torchao path's separate model_trust / tok_trust.

_loaded_via_remote_code now also walks processor components (tokenizer,
image_processor, feature_extractor, video_processor), so an approved
custom tokenizer held inside a built-in ProcessorMixin keeps its trust
on the export reload instead of failing with trust_remote_code=False.
The walk is a bounded BFS with a seen set so wrapper cycles terminate.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-07-05 05:16:39 -07:00
..
gpt-oss-merge Windows installer: fix DiskPart UAC mid-install, drive-root cache, and spurious unsloth.exe rename warning (#6296) 2026-06-22 03:09:08 -07:00
language_models Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
non_peft Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
text_to_speech_models Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
vision_models Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
test_compressed_export_schemes.py Add FP8/FP4 compressed export to save_pretrained_merged (#6706) 2026-06-30 03:40:16 -07:00
test_export_api_surface.py Add FP8/FP4 compressed export to save_pretrained_merged (#6706) 2026-06-30 03:40:16 -07:00
test_export_dispatch.py Add FP8/FP4 compressed export to save_pretrained_merged (#6706) 2026-06-30 03:40:16 -07:00
test_fix_sentencepiece_gguf_robustness.py Formatting: ruff line-length 100, kwarg-spacing passes, drop blank after short local imports (#6079) 2026-06-08 04:24:13 -07:00
test_gguf_export_and_inference.py Add FP8/FP4 compressed export to save_pretrained_merged (#6706) 2026-06-30 03:40:16 -07:00
test_imatrix_export.py Add FP8/FP4 compressed export to save_pretrained_merged (#6706) 2026-06-30 03:40:16 -07:00
test_is_gpt_oss_detection.py Reduce comments across recent fixes (#6776) 2026-06-30 23:13:36 -07:00
test_llm_compressor_install_pin.py Pin llm-compressor auto-install to a vetted version range (#6778) 2026-07-01 04:48:38 -07:00
test_normalize_tied_weights_keys.py Fix save crash for legacy list-form _tied_weights_keys (NemotronH) (#6540) 2026-06-22 02:11:46 -07:00
test_patch_saving_none_tokenizer.py Fix tokenizer save gemma (#5115) 2026-04-22 09:03:20 -07:00
test_preserve_tokenizer_eos_token.py Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
test_qwen3_5_vlm_full_finetune_key_remap.py Merge qwen35_export CI fixes 2026-06-08 22:02:05 +05:30
test_save_shell_injection.py Add FP8/FP4 compressed export to save_pretrained_merged (#6706) 2026-06-30 03:40:16 -07:00
test_save_subprocess_utf8_encoding.py Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00
test_torchao_remote_code_consent.py Fix export-time trust_remote_code bypass in FP8/INT8/GGUF-LoRA export (#6869) 2026-07-05 05:16:39 -07:00
test_unsloth_save.py Reduce and tighten comments and docstrings across the test suite (#6429) 2026-06-18 01:07:09 -07:00