Triton TRT-LLM Multimodal guide outdated
Page
Source: Popular_Models_Guide/Llava1.5/llava_trtllm_guide.md in
triton-inference-server/tutorials.
The LLaVA-1.5 guide is using TRTLLM engine backend, which is deprecated. Thus, updating the guide to LLM API, with a currently supported vision model such as Qwen2.5-VL.
While attempting that update, we found there is no way to pass an image through the
Triton llmapi backend to TRTLLM. The PyTorch/LLM API path on Triton is triton_backend/all_models/llmapi/tensorrt_llm/
(config.pbtxt + 1/model.py). It is text-only.
I think the gap is entirely in config.pbtxt and model.py, thus opening this PR: https://github.com/NVIDIA/TensorRT-LLM/pull/18381
- Can someone help check if editing these 2 files in TRTLLM is the right direction?
- Is there a supported way today to serve a multimodal model on Triton with the TensorRT-LLM PyTorch backend?
Tested on TensorRT-LLM v1.2.1 (376f7e1bd8) and
nvcr.io/nvidia/tritonserver:26.07-trtllm-python-py3 (Triton 2.71.0 / TRT-LLM 1.2.1 /
CUDA 13.1).
Details
- No media input tensor.
config.pbtxtdeclarestext_input,streaming,stop, 11sampling_param_*and 3return_*inputs. None can carry an image. - The prompt is passed as a bare
str._convert_request(1/model.py:482-511) reads onlytext_inputand returns a decoded string, which_execute_single_requestpasses togenerate_async(prompt, SamplingParams(...), streaming)(1/model.py:415). The LLM API only enters its multimodal branch wheninputsis a dict carryingmulti_modal_data(tensorrt_llm/llmapi/llm.py:480), so a string can never reach it. - No processor or HF config is loaded at startup.
initializestarts the engine only; theAutoProcessorandPretrainedConfigneeded for chat-template rendering and placeholder fusion are absent.
What we verified about the path that does work
trtllm-serve already serves images on v1/chat/completions, using only public helpers in
tensorrt_llm/. Nothing in the library is missing; the Triton backend simply never calls any
of it. For reference, the sequence in OpenAIServer.openai_chat
(tensorrt_llm/serve/openai_server.py:547-570) is:
parse_chat_messages_coroutines(messages, model_config, multimodal_server_config)(tensorrt_llm/serve/chat_utils.py:268) parses OpenAI content parts (text/image_url/video_url/audio_url/image_embeds) and returns the conversation, a set of lazily-awaited media coroutines, and per-model placeholder counts.async_load_image(tensorrt_llm/inputs/utils.py:150) does the fetch — http(s) viaaiohttp,data:base64, or a local path — returning RGB,format="pt"by default.MultimodalDataTracker+add_multimodal_placeholders(tensorrt_llm/inputs/utils.py:451,:518) inject the model-specific placeholder tokens fromMULTIMODAL_PLACEHOLDER_REGISTRYat the registered position.apply_chat_template(tensorrt_llm/inputs/utils.py:601) renders the prompt, preferringprocessor.chat_template.awaiting the coroutines yieldsprompt["multi_modal_data"], which flows intogenerate_async→create_input_processor_with_hash(tensorrt_llm/inputs/registry.py:647) → the model's input processor.
The init-time state this needs — tokenizer, AutoProcessor.from_pretrained, and
load_pretrained_config — is built once in OpenAIServer.__init__
(tensorrt_llm/serve/openai_server.py:81-120).
A few things we learned that would matter to anyone implementing this:
_execute_single_requestalready runs on the engine event loop, viaasyncio.run_coroutine_threadsafe(coro, self._event_loop)(1/model.py:378), so awaiting the media coroutines requires no new threading —_convert_requestjust becomesasync.parse_chat_message_content_partswallows media-load failures intoNone(tensorrt_llm/serve/chat_utils.py:129-133), so a bad URL silently degrades to a text-only request. A backend should compare the returnedmulti_modal_dataagainst the number of media items supplied and raise rather than inherit that behavior.self.model_configin1/model.py:145is already the Triton model config fromjson.loads(args["model_config"]); the HFPretrainedConfigneeds a different attribute name.default_multimodal_input_loader(tensorrt_llm/inputs/utils.py:656) looks like a shortcut, but it callsAutoProcessor.from_pretrainedandModelLoader.load_hf_tokenizeron every invocation, so it is not viable for a per-request serving path.
Questions
- Is there a supported way today to serve a multimodal model on Triton with the
TensorRT-LLM PyTorch backend? If we are missing an existing mechanism for getting an
image through the
llmapibackend, we would rather use it than add one.
Source: triton-inference-server/server