Skip to content

Commit b58789f

Browse files
authored
Update trust_remote_code (#2256)
This pull request improves the handling of the `trust_remote_code` (or `hf_remote`) option when loading models from Hugging Face repositories, making the default behavior more secure and ensuring users must explicitly opt in to executing remote code. It also updates documentation and adds warnings to inform users about the security implications. **Security and behavior changes:** * Changed the default for `hf_remote`/`trust_remote_code` to `False` in both `builder.py` and `base.py`, so arbitrary code from Hugging Face repositories is never executed unless the user explicitly enables it. This matches the default behavior in the `transformers` library. [[1]](diffhunk://#diff-11d14636083c4529597f09601b8f66e5df0094978debab425bfe6dd850cfcb50L199-R214) [[2]](diffhunk://#diff-8a33668cd8981709ba426dab1b3d3145bd0756d1ebf1203657ba8b8aae860d45L89-R103) * Added warnings in both `builder.py` and `base.py` to clearly notify users when they have enabled `hf_remote`/`trust_remote_code` and explain the associated security risks. [[1]](diffhunk://#diff-11d14636083c4529597f09601b8f66e5df0094978debab425bfe6dd850cfcb50L199-R214) [[2]](diffhunk://#diff-8a33668cd8981709ba426dab1b3d3145bd0756d1ebf1203657ba8b8aae860d45L89-R103) **User interface and argument handling:** * Added a `--trust_remote_code` command-line argument to `awq-quantized-model.py`, and ensured this option is only forwarded to model/tokenizer loading if the user has explicitly set it. [[1]](diffhunk://#diff-a2b2e6bb32d7bd2dbfd980b04d4de97851bf0f12108a1be09a0c880cb68567efR49-R59) [[2]](diffhunk://#diff-a2b2e6bb32d7bd2dbfd980b04d4de97851bf0f12108a1be09a0c880cb68567efL58-R71) [[3]](diffhunk://#diff-a2b2e6bb32d7bd2dbfd980b04d4de97851bf0f12108a1be09a0c880cb68567efR153) * Updated the help text for `hf_remote` in argument parsing to clarify the new default and the security implications. **Documentation updates:** * Updated the documentation in `README.md` to accurately describe the new default (`hf_remote=false`) and the risks of enabling remote code execution.
1 parent 7480c21 commit b58789f

4 files changed

Lines changed: 34 additions & 7 deletions

File tree

examples/python/awq-quantized-model.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,17 @@ def parse_args():
4646
help="Use the QDQ decomposition for quantized MatMul instead of the MatMulNBits operator",
4747
)
4848

49+
parser.add_argument(
50+
"--trust_remote_code",
51+
action="store_true",
52+
help=(
53+
"Allow loading custom Python code shipped inside the Hugging Face repository "
54+
"during tokenizer load (and forward `hf_remote=true` to the ONNX model "
55+
"builder). This is equivalent to running arbitrary code from that repository "
56+
"as the current user and should only be enabled for repositories you fully trust."
57+
),
58+
)
59+
4960
args = parser.parse_args()
5061
return args
5162

@@ -55,7 +66,9 @@ def quantize_model(args):
5566

5667
# Load model
5768
model = AutoAWQForCausalLM.from_pretrained(args.model_path, low_cpu_mem_usage=True, use_cache=False)
58-
tokenizer = AutoTokenizer.from_pretrained(args.model_path, trust_remote_code=True)
69+
# `trust_remote_code` is opt-in: forwarding True without explicit user consent would
70+
# cause arbitrary Python shipped inside the repository to execute during tokenizer load.
71+
tokenizer = AutoTokenizer.from_pretrained(args.model_path, trust_remote_code=args.trust_remote_code)
5972

6073
# Quantize model
6174
model.quantize(tokenizer, quant_config=quant_config)
@@ -137,6 +150,7 @@ def main():
137150

138151
extra_options = {
139152
"use_qdq": args.use_qdq,
153+
"hf_remote": args.trust_remote_code,
140154
}
141155

142156
create_model(model_name, input_folder, output_folder, precision, execution_provider, cache_dir, **extra_options)

src/python/py/models/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,14 +207,14 @@ python builder.py -m model_name -o path_to_output_folder -p precision -e executi
207207

208208
#### Hugging Face Remote Code
209209

210-
This scenario is for when you need to disable trusting remote code from a Hugging Face repo.
210+
This scenario is for when you need to enable trusting remote code from a Hugging Face repo. The default is `hf_remote=false`, which means `trust_remote_code=False` is used for `transformers.*.from_pretrained()` calls and any Python code shipped inside the repository (referenced by its `auto_map` field) will **not** be executed. Set `hf_remote=true` only for repositories you fully trust, because doing so is equivalent to running arbitrary code from that repository as the current user.
211211

212212
```bash
213213
# From wheel:
214-
python -m onnxruntime_genai.models.builder -m model_name -o path_to_output_folder -p precision -e execution_provider -c cache_dir_for_hf_files --extra_options hf_remote=false
214+
python -m onnxruntime_genai.models.builder -m model_name -o path_to_output_folder -p precision -e execution_provider -c cache_dir_for_hf_files --extra_options hf_remote=true
215215

216216
# From source:
217-
python builder.py -m model_name -o path_to_output_folder -p precision -e execution_provider -c cache_dir_for_hf_files --extra_options hf_remote=false
217+
python builder.py -m model_name -o path_to_output_folder -p precision -e execution_provider -c cache_dir_for_hf_files --extra_options hf_remote=true
218218
```
219219

220220
#### Exclude Embedding Layer

src/python/py/models/builder.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,11 @@ def create_model(
196196
extra_kwargs = {} if os.path.isdir(input_path) else {"cache_dir": cache_dir}
197197
hf_name = input_path if os.path.isdir(input_path) else model_name
198198
hf_token = extra_options.get("hf_token", True)
199-
hf_remote = extra_options.get("hf_remote", True)
199+
# Default to False so we never execute arbitrary code shipped inside a
200+
# Hugging Face repository unless the user has explicitly opted in. This
201+
# matches the safe default that `transformers` itself uses for
202+
# `trust_remote_code`.
203+
hf_remote = extra_options.get("hf_remote", False)
200204

201205
config = AutoConfig.from_pretrained(hf_name, token=hf_token, trust_remote_code=hf_remote, **extra_kwargs)
202206
if "adapter_path" in extra_options:
@@ -449,7 +453,12 @@ def get_args():
449453
If token, you can provide a custom authentication token that differs from the one stored in your environment.
450454
If you have already authenticated via `huggingface-cli login`, you do not need to use this flag because Hugging Face has already stored your authentication token for you.
451455
hf_remote = Use this to manage trusting remote code in Hugging Face repos.
452-
Default behavior is set to true. If false, remote code stored in Hugging Face repos will not be used.
456+
Default behavior is set to false. When false, transformers `from_pretrained()`
457+
calls will refuse to import or execute custom Python code shipped inside
458+
a Hugging Face repository (`trust_remote_code=False`).
459+
Set to true to opt in to executing repository-supplied code; only do this
460+
for repositories you fully trust because it is equivalent to running
461+
arbitrary code from that repository as the current user.
453462
exclude_embeds = Remove embedding layer from your ONNX model.
454463
Use this option when you want to remove the embedding layer from within your ONNX model.
455464
Instead of `input_ids`, you will have `inputs_embeds` as the input to your ONNX model.

src/python/py/models/builders/base.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,11 @@ def __init__(self, config, io_dtype, onnx_dtype, ep, cache_dir, extra_options):
8686
self.cache_dir = cache_dir
8787
self.filename = extra_options.get("filename", "model.onnx")
8888
self.hf_token = extra_options.get("hf_token", True)
89-
self.hf_remote = extra_options.get("hf_remote", True)
89+
# Default to False so transformers `from_pretrained()` calls do not
90+
# execute arbitrary Python from a Hugging Face repository unless the
91+
# caller has explicitly opted in via `hf_remote=true` in
92+
# `--extra_options`. See the security note in builder.py.
93+
self.hf_remote = extra_options.get("hf_remote", False)
9094
self.extra_options = extra_options
9195

9296
# States for building the model

0 commit comments

Comments
 (0)