add explicit trust_remote_code controls to resolve the security issue#4511
add explicit trust_remote_code controls to resolve the security issue#4511lvhan028 wants to merge 1 commit intoInternLM:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces an explicit trust_remote_code flag (default False) and threads it through LMDeploy’s pipeline/serving/engine and VL model-loading paths to address a security concern around implicitly trusting Hugging Face remote code.
Changes:
- Add
trust_remote_codeparameters across the public entrypoints (API, pipeline, OpenAI server, engines) and propagate to HF loaders (AutoConfig,AutoTokenizer,AutoProcessor,AutoModel*,GenerationConfig). - Update VL model implementations to use
self.trust_remote_codeinstead of hardcodingtrust_remote_code=True. - Expose a CLI switch
--trust-remote-codeforlmdeploy serve api_server.
Reviewed changes
Copilot reviewed 29 out of 29 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| lmdeploy/vl/model/xcomposer2.py | Add trust_remote_code plumbing; stop hardcoding remote-code trust in HF model construction. |
| lmdeploy/vl/model/qwen3.py | Use self.trust_remote_code for AutoProcessor loading. |
| lmdeploy/vl/model/qwen.py | Use self.trust_remote_code for AutoModelForCausalLM.from_config. |
| lmdeploy/vl/model/phi3_vision.py | Use self.trust_remote_code for processor/model loading. |
| lmdeploy/vl/model/molmo.py | Use self.trust_remote_code for processor/model loading. |
| lmdeploy/vl/model/minicpmv.py | Add trust_remote_code to ctor and propagate to HF loaders. |
| lmdeploy/vl/model/llava.py | Use self.trust_remote_code for HF model construction. |
| lmdeploy/vl/model/llava_hf.py | Use self.trust_remote_code for AutoProcessor loading. |
| lmdeploy/vl/model/internvl3_hf.py | Add trust_remote_code to ctor; propagate into HF processors/models. |
| lmdeploy/vl/model/internvl.py | Add trust_remote_code to ctor; propagate into tokenizer/model loading. |
| lmdeploy/vl/model/internvl_llava.py | Use self.trust_remote_code for HF model construction. |
| lmdeploy/vl/model/glm4_v.py | Use self.trust_remote_code for HF model loading. |
| lmdeploy/vl/model/cogvlm.py | Use self.trust_remote_code for HF model loading. |
| lmdeploy/vl/model/builder.py | Add trust_remote_code to load_vl_model and pass through to arch detection and model ctor. |
| lmdeploy/vl/model/base.py | Store trust_remote_code on the base vision model; use it for config/tokenizer loading. |
| lmdeploy/vl/engine.py | Thread trust_remote_code into ImageEncoder and VL model loading. |
| lmdeploy/utils.py | Add trust_remote_code to HF GenerationConfig loading. |
| lmdeploy/tokenizer.py | Add trust_remote_code to tokenizer construction and config checks. |
| lmdeploy/serve/openai/api_server.py | Add trust_remote_code option and pass it into task selection/engine init. |
| lmdeploy/serve/core/vl_async_engine.py | Thread trust_remote_code into ImageEncoder and base async engine. |
| lmdeploy/serve/core/async_engine.py | Thread trust_remote_code through tokenizer/config loading and engine builders. |
| lmdeploy/pytorch/engine/executor/init.py | Pass trust_remote_code into ModelConfig.from_pretrained. |
| lmdeploy/pytorch/engine/engine.py | Default trust_remote_code to False and propagate into executor/specdecode config. |
| lmdeploy/pytorch/engine/config_builder.py | Thread trust_remote_code into speculative decode config creation. |
| lmdeploy/pytorch/config.py | Default trust_remote_code to False for model config loading; propagate for draft/spec configs. |
| lmdeploy/pipeline.py | Add user-facing trust_remote_code parameter and propagate into engine selection/construction. |
| lmdeploy/cli/serve.py | Add --trust-remote-code CLI flag and pass through to server startup. |
| lmdeploy/archs.py | Add trust_remote_code option to get_task/get_model_arch and propagate into AutoConfig. |
| lmdeploy/api.py | Expose trust_remote_code in the public pipeline() API wrapper. |
Comments suppressed due to low confidence (1)
lmdeploy/vl/model/builder.py:76
load_vl_modelnow passestrust_remote_codeinto every vision model constructor (model = module(**kwargs)), but at least one registered model (e.g.Gemma3VisionModelinlmdeploy/vl/model/gemma3_vl.py) still defines__init__(..., backend: str='')and will raiseTypeError: __init__() got an unexpected keyword argument 'trust_remote_code'.
To avoid runtime failures, either update all VisionModel subclasses with custom __init__ to accept/forward trust_remote_code (or **kwargs), or make load_vl_model only pass trust_remote_code when the target class accepts it (similar to _accepts_arg used elsewhere).
_, hf_config = get_model_arch(model_path, trust_remote_code=trust_remote_code)
kwargs = dict(model_path=model_path,
with_llm=with_llm,
max_memory=max_memory,
hf_config=hf_config,
backend=backend,
trust_remote_code=trust_remote_code)
for name, module in VISION_MODELS.module_dict.items():
try:
if module.match(hf_config):
logger.info(f'matching vision model: {name}')
model = module(**kwargs)
model.build_preprocessor()
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| def __init__(self, | ||
| model_path: str, | ||
| backend_config: TurbomindEngineConfig | PytorchEngineConfig | None = None, | ||
| chat_template_config: ChatTemplateConfig | None = None, | ||
| log_level: str = 'WARNING', | ||
| max_log_len: int | None = None, | ||
| trust_remote_code: bool = False, | ||
| speculative_config: SpeculativeConfig | None = None, | ||
| **kwargs): | ||
| """Initialize Pipeline. | ||
|
|
||
| Args: | ||
| model_path: Path to the model. | ||
| backend_config: Backend configuration. | ||
| chat_template_config: Chat template configuration. | ||
| log_level: Log level. | ||
| max_log_len: Max number of prompt characters or prompt tokens being printed in log. | ||
| trust_remote_code: whether to trust remote code from model repositories. | ||
| speculative_config: Speculative decoding configuration. | ||
| **kwargs: Additional keyword arguments. | ||
| """ | ||
|
|
||
| os.environ.setdefault('TM_LOG_LEVEL', log_level) | ||
| logger.setLevel(log_level) | ||
|
|
||
| # Download model if the path does not exist locally | ||
| if not os.path.exists(model_path): | ||
| download_dir = backend_config.download_dir if backend_config else None | ||
| revision = backend_config.revision if backend_config else None | ||
| model_path = get_model(model_path, download_dir, revision) | ||
|
|
||
| # Download speculative model if the path does not exist locally | ||
| if speculative_config and speculative_config.model and not os.path.exists(speculative_config.model): | ||
| download_dir = backend_config.download_dir if backend_config else None | ||
| speculative_config.model = get_model(speculative_config.model, download_dir) | ||
|
|
||
| # Create inference engine | ||
| backend, backend_config = autoget_backend_config(model_path, backend_config) | ||
| _, pipeline_class = get_task(backend, model_path) | ||
| _, pipeline_class = get_task(backend, model_path, trust_remote_code=trust_remote_code) | ||
| self.async_engine = pipeline_class(model_path, | ||
| backend=backend, | ||
| backend_config=backend_config, | ||
| chat_template_config=chat_template_config, | ||
| max_log_len=max_log_len, | ||
| trust_remote_code=trust_remote_code, | ||
| speculative_config=speculative_config, | ||
| **kwargs) |
There was a problem hiding this comment.
trust_remote_code is now a user-facing switch that changes how configs/tokenizers/models are loaded (defaulting to False). There are existing integration tests for pipeline() behavior (e.g. tests/test_lmdeploy/test_pipeline.py), but the new parameter and its default are not exercised here.
Please add/adjust tests to cover both: (1) default trust_remote_code=False behavior, and (2) successful loading when trust_remote_code=True is explicitly set for models that require remote code. This helps prevent regressions and ensures the security control remains effective.
No description provided.