From e07fff4f78ea9d5dae6e9bbaa2ca20be91174c33 Mon Sep 17 00:00:00 2001 From: liji-nv <59594262+liji-nv@users.noreply.github.com> Date: Fri, 25 Jul 2025 14:49:45 +0800 Subject: [PATCH 01/29] =?UTF-8?q?[https://nvbugs/5340941]=20-=20fix:=20Cor?= =?UTF-8?q?rect=20custom=20ops=20used=20by=20Qwen3=20Moe=20=E2=80=A6=20(#6?= =?UTF-8?q?285)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jin Li <59594262+liji-nv@users.noreply.github.com> --- cpp/tensorrt_llm/thop/fusedQKNormRopeOp.cpp | 5 ++--- cpp/tensorrt_llm/thop/renormMoeRoutingOp.cpp | 2 +- tensorrt_llm/_torch/compilation/utils.py | 3 +++ tensorrt_llm/_torch/custom_ops/cpp_custom_ops.py | 8 ++++++++ 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/cpp/tensorrt_llm/thop/fusedQKNormRopeOp.cpp b/cpp/tensorrt_llm/thop/fusedQKNormRopeOp.cpp index 0692ee57a7a..56ba59e1ee2 100644 --- a/cpp/tensorrt_llm/thop/fusedQKNormRopeOp.cpp +++ b/cpp/tensorrt_llm/thop/fusedQKNormRopeOp.cpp @@ -75,9 +75,8 @@ void fused_qk_norm_rope( TORCH_LIBRARY_FRAGMENT(trtllm, m) { m.def( - "fused_qk_norm_rope(Tensor qkv, int num_heads_q, int num_heads_k, int num_heads_v, int head_dim, float eps, " - "Tensor q_weight, Tensor k_weight, float base, bool is_neox, Tensor position_ids) -> ()", - &fused_qk_norm_rope); + "fused_qk_norm_rope(Tensor(a!) qkv, int num_heads_q, int num_heads_k, int num_heads_v, int head_dim, float " + "eps, Tensor q_weight, Tensor k_weight, float base, bool is_neox, Tensor position_ids) -> ()"); } // Register the CUDA implementation diff --git a/cpp/tensorrt_llm/thop/renormMoeRoutingOp.cpp b/cpp/tensorrt_llm/thop/renormMoeRoutingOp.cpp index e2e4ad492d7..616cf3bb7ec 100644 --- a/cpp/tensorrt_llm/thop/renormMoeRoutingOp.cpp +++ b/cpp/tensorrt_llm/thop/renormMoeRoutingOp.cpp @@ -74,7 +74,7 @@ std::tuple renorm_moe_routing_op(th::Tensor const& route TORCH_LIBRARY_FRAGMENT(trtllm, m) { m.def( - "renorm_moe_routing_op(Tensor router_logits, int topk" + "renorm_moe_routing_op(Tensor router_logits, SymInt topk" ") -> (Tensor, Tensor)"); } diff --git a/tensorrt_llm/_torch/compilation/utils.py b/tensorrt_llm/_torch/compilation/utils.py index f00d689458a..d99b34fe854 100644 --- a/tensorrt_llm/_torch/compilation/utils.py +++ b/tensorrt_llm/_torch/compilation/utils.py @@ -55,6 +55,9 @@ def inplace_info(): }, torch.ops.trtllm.mla_custom_op_inplace.default: { 1: "output" + }, + torch.ops.trtllm.fused_qk_norm_rope.default: { + 1: "qkv" } } return inplace_map diff --git a/tensorrt_llm/_torch/custom_ops/cpp_custom_ops.py b/tensorrt_llm/_torch/custom_ops/cpp_custom_ops.py index 31fa33d3084..5e001d9a48c 100644 --- a/tensorrt_llm/_torch/custom_ops/cpp_custom_ops.py +++ b/tensorrt_llm/_torch/custom_ops/cpp_custom_ops.py @@ -523,3 +523,11 @@ def _(input, residual, norm_weight, expanded_idx_to_permuted_idx, torch.empty_like(residual), torch.empty_like(residual), ] + + @torch.library.register_fake("trtllm::renorm_moe_routing_op") + def _(router_logits, topk): + num_tokens = router_logits.shape[0] + sz = (num_tokens, topk) + return router_logits.new_empty( + sz, dtype=torch.int32), router_logits.new_empty(sz, + dtype=torch.float32) From 470544cf178e1b19758bc689649c9ed22e0fa317 Mon Sep 17 00:00:00 2001 From: xinhe-nv <200704525+xinhe-nv@users.noreply.github.com> Date: Fri, 25 Jul 2025 00:18:06 -0700 Subject: [PATCH 02/29] test: [CI] Add failed cases into waives.txt (#6333) Signed-off-by: Xin He (SW-GPU) <200704525+xinhe-nv@users.noreply.github.com> --- tests/integration/defs/accuracy/test_cli_flow.py | 6 ++++-- tests/integration/defs/accuracy/test_llm_api_pytorch.py | 4 ++++ tests/integration/defs/test_e2e.py | 8 ++++++-- tests/integration/test_lists/qa/llm_sanity_test.txt | 2 ++ tests/integration/test_lists/waives.txt | 2 ++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/tests/integration/defs/accuracy/test_cli_flow.py b/tests/integration/defs/accuracy/test_cli_flow.py index a5ab844dfbc..1553838b95a 100644 --- a/tests/integration/defs/accuracy/test_cli_flow.py +++ b/tests/integration/defs/accuracy/test_cli_flow.py @@ -211,6 +211,7 @@ class TestLlama3_3NemotronSuper49Bv1(CliFlowAccuracyTestHarness): def test_auto_dtype_tp2(self): self.run(tasks=[MMLU(self.MODEL_NAME)], tp_size=2, dtype='auto') + @skip_pre_hopper @pytest.mark.skip( reason="nemotron-nas scripts have to accommodate fp8 flags") @pytest.mark.skip_less_device(2) @@ -811,14 +812,14 @@ class TestLlama3_1_8BInstruct(CliFlowAccuracyTestHarness): def test_auto_dtype(self): self.run(dtype='auto') - @skip_pre_ada + @skip_pre_hopper def test_fp8_prequantized(self, mocker): mocker.patch.object( self.__class__, "MODEL_PATH", f"{llm_models_root()}/llama-3.1-model/Llama-3.1-8B-Instruct-FP8") self.run(quant_algo=QuantAlgo.FP8, kv_cache_quant_algo=QuantAlgo.FP8) - @skip_pre_ada + @skip_pre_hopper @skip_post_blackwell def test_medusa_fp8_prequantized(self, mocker): # nvidia/Llama-3.1-8B-Medusa-FP8 @@ -958,6 +959,7 @@ class TestLlama3_3_70BInstruct(CliFlowAccuracyTestHarness): def test_auto_dtype_tp8(self): self.run(tasks=[MMLU(self.MODEL_NAME)], tp_size=8, dtype='auto') + @skip_pre_hopper @pytest.mark.skip_less_device(4) @pytest.mark.skip_device_not_contain(["H100", "H200", "B200"]) def test_fp8_prequantized_tp4(self, mocker): diff --git a/tests/integration/defs/accuracy/test_llm_api_pytorch.py b/tests/integration/defs/accuracy/test_llm_api_pytorch.py index 4af27e1d587..6fd9ed09677 100644 --- a/tests/integration/defs/accuracy/test_llm_api_pytorch.py +++ b/tests/integration/defs/accuracy/test_llm_api_pytorch.py @@ -307,6 +307,7 @@ def test_auto_dtype(self): task = CnnDailymail(self.MODEL_NAME) task.evaluate(llm) + @skip_pre_hopper def test_fp8_prequantized(self): model_path = f"{llm_models_root()}/llama-3.2-models/Llama-3.2-1B-FP8" with LLM(model_path) as llm: @@ -1478,6 +1479,7 @@ def test_auto_dtype_tp2(self): task.evaluate(llm, extra_evaluator_kwargs=dict(apply_chat_template=True)) + @skip_pre_hopper @pytest.mark.skip_less_device(2) @pytest.mark.skip_device_not_contain(["H100", "B200"]) def test_fp8_prequantized_tp2(self): @@ -1507,6 +1509,7 @@ def test_auto_dtype(self): task.evaluate(llm, extra_evaluator_kwargs=dict(apply_chat_template=True)) + @skip_pre_hopper @pytest.mark.skip_device_not_contain(["H100", "B200"]) def test_fp8_prequantized(self): model_path = f"{llm_models_root()}/Llama-3.1-Nemotron-Nano-8B-v1-FP8" @@ -1547,6 +1550,7 @@ def test_auto_dtype(self, cuda_graph, tp_size, pp_size, ep_size): # task.evaluate(llm, # extra_evaluator_kwargs=dict(apply_chat_template=True)) + @skip_pre_hopper @pytest.mark.skip_less_device(8) @pytest.mark.skip_device_not_contain(["H100", "B200"]) @parametrize_with_ids("cuda_graph", [False, True]) diff --git a/tests/integration/defs/test_e2e.py b/tests/integration/defs/test_e2e.py index 9cfd2eed341..03e5dd7f5ef 100644 --- a/tests/integration/defs/test_e2e.py +++ b/tests/integration/defs/test_e2e.py @@ -1938,8 +1938,12 @@ def test_ptp_quickstart_advanced_mixed_precision(llm_root, llm_venv): ("llava-v1.6-mistral-7b", "llava-v1.6-mistral-7b-hf"), ("qwen2-vl-7b-instruct", "Qwen2-VL-7B-Instruct"), ("qwen2.5-vl-7b-instruct", "Qwen2.5-VL-7B-Instruct"), - ("mistral-small-3.1-24b-instruct", "Mistral-Small-3.1-24B-Instruct-2503"), - ("gemma-3-27b-it", "gemma/gemma-3-27b-it"), + pytest.param("mistral-small-3.1-24b-instruct", + "Mistral-Small-3.1-24B-Instruct-2503", + marks=pytest.mark.skip_less_device_memory(80000)), + pytest.param("gemma-3-27b-it", + "gemma/gemma-3-27b-it", + marks=pytest.mark.skip_less_device_memory(80000)), ]) def test_ptp_quickstart_multimodal(llm_root, llm_venv, model_name, model_path, modality, use_cuda_graph): diff --git a/tests/integration/test_lists/qa/llm_sanity_test.txt b/tests/integration/test_lists/qa/llm_sanity_test.txt index 64c3396cf3d..5d5ce43be88 100644 --- a/tests/integration/test_lists/qa/llm_sanity_test.txt +++ b/tests/integration/test_lists/qa/llm_sanity_test.txt @@ -109,6 +109,8 @@ test_e2e.py::test_ptp_quickstart_multimodal[qwen2.5-vl-7b-instruct-Qwen2.5-VL-7B test_e2e.py::test_ptp_quickstart_multimodal[qwen2.5-vl-7b-instruct-Qwen2.5-VL-7B-Instruct-image-True] test_e2e.py::test_ptp_quickstart_multimodal[qwen2.5-vl-7b-instruct-Qwen2.5-VL-7B-Instruct-video-False] test_e2e.py::test_ptp_quickstart_multimodal[qwen2.5-vl-7b-instruct-Qwen2.5-VL-7B-Instruct-video-True] +test_e2e.py::test_ptp_quickstart_multimodal[gemma-3-27b-it-gemma/gemma-3-27b-it-image-False] +test_e2e.py::test_ptp_quickstart_multimodal[gemma-3-27b-it-gemma/gemma-3-27b-it-image-True] test_e2e.py::test_ptp_scaffolding[DeepSeek-R1-Distill-Qwen-7B-DeepSeek-R1/DeepSeek-R1-Distill-Qwen-7B] test_e2e.py::test_ptp_star_attention_example[Llama3.1-8B-BF16-llama-3.1-model/Meta-Llama-3.1-8B] test_e2e.py::test_qwen_e2e_cpprunner_large_new_tokens[DeepSeek-R1-Distill-Qwen-1.5B-DeepSeek-R1-Distill-Qwen-1.5B] diff --git a/tests/integration/test_lists/waives.txt b/tests/integration/test_lists/waives.txt index ad7d147ae13..f6a876ad01f 100644 --- a/tests/integration/test_lists/waives.txt +++ b/tests/integration/test_lists/waives.txt @@ -421,6 +421,7 @@ triton_server/test_triton_llm.py::test_llava_onevision[test_video-False-1---Fals triton_server/test_triton.py::test_cpp_unit_tests[cpp-unit-tests] SKIP (https://nvbugs/5401088) accuracy/test_llm_api_pytorch.py::TestGemma3_27BInstruct::test_auto_dtype SKIP (https://nvbugs/5401114) test_e2e.py::test_ptp_quickstart_multimodal[gemma-3-27b-it-gemma/gemma-3-27b-it-image-True] SKIP (https://nvbugs/5401114) +test_e2e.py::test_ptp_quickstart_multimodal[gemma-3-27b-it-gemma/gemma-3-27b-it-image-False] SKIP (https://nvbgus/5401114) examples/test_recurrentgemma.py::test_llm_recurrentgemma_1gpu[use_cpp_session-recurrentgemma-2b-use_paged_cache-int4_awq-float16-enable_attn_plugin-enable_gemm_plugin] SKIP (https://nvbugs/5401233) examples/test_recurrentgemma.py::test_llm_recurrentgemma_2gpu[recurrentgemma-2b] SKIP (https://nvbugs/5401233) examples/test_multimodal.py::test_llm_multimodal_general[VILA1.5-3b-pp:1-tp:1-float16-bs:1-cpp_e2e:False-nb:1] SKIP (https://nvbugs/5401156) @@ -440,3 +441,4 @@ unittest/trt/attention/test_gpt_attention.py -k "partition0" SKIP (https://nvbug unittest/trt/attention/test_gpt_attention.py -k "partition1" SKIP (https://nvbugs/5412456) unittest/trt/attention/test_gpt_attention.py -k "partition2" SKIP (https://nvbugs/5412456) unittest/trt/attention/test_gpt_attention.py -k "partition3" SKIP (https://nvbugs/5412456) +test_e2e.py::test_ptp_quickstart_multimodal[qwen2-vl-7b-instruct-Qwen2-VL-7B-Instruct-image-False] SKIP (https://nvbugs/5414909) From a0aecf04761d0e90a593392a00a514c7cf1043b2 Mon Sep 17 00:00:00 2001 From: xiaoqi Date: Fri, 25 Jul 2025 17:37:41 +0800 Subject: [PATCH 03/29] [feat]: support logit_bias (#5354) Signed-off-by: xq25478 Signed-off-by: Venky Ganesh <23023424+venkywonka@users.noreply.github.com> Signed-off-by: hexiao.xq Co-authored-by: Venky Ganesh <23023424+venkywonka@users.noreply.github.com> Co-authored-by: hexiao.xq Co-authored-by: Pengyun Lin <81065165+LinPoly@users.noreply.github.com> --- tensorrt_llm/sampling_params.py | 51 ++++++++++++++++++- tensorrt_llm/serve/openai_protocol.py | 17 ++++--- .../integration/test_lists/test-db/l0_a10.yml | 2 +- .../unittest/llmapi/apps/_test_openai_chat.py | 38 ++++++++++++++ .../llmapi/apps/_test_openai_completions.py | 33 ++++++++++++ 5 files changed, 132 insertions(+), 9 deletions(-) diff --git a/tensorrt_llm/sampling_params.py b/tensorrt_llm/sampling_params.py index c2ac3b881d2..d6da05d01bd 100644 --- a/tensorrt_llm/sampling_params.py +++ b/tensorrt_llm/sampling_params.py @@ -2,7 +2,7 @@ import os from abc import ABC, abstractmethod from dataclasses import dataclass, field, fields -from typing import List, NamedTuple, Optional, Tuple, Union +from typing import Dict, List, NamedTuple, Optional, Tuple, Union import torch from pydantic import BaseModel @@ -108,6 +108,55 @@ def __call__( pass # noqa +class LogitBiasLogitsProcessor(LogitsProcessor): + def __init__(self, logit_bias: Dict[str, float]) -> None: + super().__init__() + self.logit_bias = logit_bias + self.tokens_to_adjust = self.process_logit_bias(logit_bias) + if not self.tokens_to_adjust: + raise ValueError("Empty logit_bias provided - no tokens to adjust") + + def process_logit_bias(self, logit_bias: Dict[str, float]) -> Dict[int, float]: + valid = {} + invalid = {} + + for k, v in logit_bias.items(): + try: + token_id = int(k) + valid[token_id] = v + except (ValueError, TypeError): + invalid[k] = v + + if invalid: + raise ValueError( + f"Invalid token_ids in logit_bias: {list(invalid.keys())}. " + f"All keys must be integers." + ) + return valid + + def __call__( + self, + req_id: int, + logits: torch.Tensor, + token_ids: List[List[int]], + stream_ptr: Optional[int], + client_id: Optional[int], + ) -> None: + vocab_size = logits.size(-1) + token_ids_list = list(self.tokens_to_adjust.keys()) + bias_values = torch.tensor(list(self.tokens_to_adjust.values()), device=logits.device) + + invalid_token_ids = [tid for tid in token_ids_list if tid >= vocab_size] + if invalid_token_ids: + raise ValueError( + f"Token ID(s) {invalid_token_ids} exceed vocabulary size (vocab_size={vocab_size})" + ) + + stream = None if stream_ptr is None else torch.cuda.ExternalStream(stream_ptr) + with torch.cuda.stream(stream): + logits[:, :, token_ids_list] += bias_values + + @dataclass(slots=True, kw_only=True) class AdditionalModelOutput: """An additional output to gather from the model. diff --git a/tensorrt_llm/serve/openai_protocol.py b/tensorrt_llm/serve/openai_protocol.py index 4a6545beef9..cdd725db5e2 100644 --- a/tensorrt_llm/serve/openai_protocol.py +++ b/tensorrt_llm/serve/openai_protocol.py @@ -16,6 +16,8 @@ from tensorrt_llm.llmapi import DisaggregatedParams as LlmDisaggregatedParams from tensorrt_llm.llmapi import GuidedDecodingParams, SamplingParams +from ..sampling_params import LogitBiasLogitsProcessor + class OpenAIBaseModel(BaseModel): # OpenAI API does not allow extra fields & allow to initialize by both alias and field name @@ -248,6 +250,10 @@ def to_sampling_params(self) -> SamplingParams: self.response_format), detokenize=self.detokenize, + # logits_bias + logits_processor=None if not self.logit_bias else + LogitBiasLogitsProcessor(self.logit_bias), + # completion-extra-params add_special_tokens=self.add_special_tokens, @@ -539,6 +545,10 @@ def to_sampling_params(self) -> SamplingParams: guided_decoding=_response_format_to_guided_decoding_params( self.response_format), + # logits_bias + logits_processor=None if not self.logit_bias else + LogitBiasLogitsProcessor(self.logit_bias), + # chat-completion-extra-params add_special_tokens=self.add_special_tokens, @@ -574,13 +584,6 @@ def check_logprobs(cls, data): raise ValueError("top_logprobs is not supported") return data - @model_validator(mode="before") - @classmethod - def verify_logit_processor(cls, data): - if data.get("logit_bias"): - raise ValueError("logit bias is not supported") - return data - @model_validator(mode="before") @classmethod def check_suffix(cls, data): diff --git a/tests/integration/test_lists/test-db/l0_a10.yml b/tests/integration/test_lists/test-db/l0_a10.yml index 5799ea27945..a7cad599cdc 100644 --- a/tests/integration/test_lists/test-db/l0_a10.yml +++ b/tests/integration/test_lists/test-db/l0_a10.yml @@ -29,7 +29,7 @@ l0_a10: - test_e2e.py::test_openai_misc_example[pytorch] - test_e2e.py::test_openai_reasoning[pytorch] - test_e2e.py::test_openai_completions_example[pytorch] - - test_e2e.py::test_openai_chat_example[pytorch] + - test_e2e.py::test_openai_chat_example[pytorch] TIMEOUT (90) - test_e2e.py::test_trtllm_bench_request_rate_and_concurrency[enable_concurrency-] - condition: ranges: diff --git a/tests/unittest/llmapi/apps/_test_openai_chat.py b/tests/unittest/llmapi/apps/_test_openai_chat.py index 2306afe9456..fd00c380ac4 100644 --- a/tests/unittest/llmapi/apps/_test_openai_chat.py +++ b/tests/unittest/llmapi/apps/_test_openai_chat.py @@ -521,3 +521,41 @@ def test_stop_reason(client: openai.OpenAI, model_name: str, backend: str): ) assert resp.choices[0].finish_reason == "stop" assert resp.choices[0].stop_reason == "two" + + +@pytest.mark.asyncio +async def test_chat_completion_with_logit_bias(async_client: openai.AsyncOpenAI, + model_name: str): + """Test logit_bias in chat completions""" + logit_bias = { + "1000": 2.0, + "2000": -2.0, + } + + chat_completion = await async_client.chat.completions.create( + model=model_name, + messages=[{ + "role": "user", + "content": "Tell me a fact about Paris" + }], + max_tokens=20, + logit_bias=logit_bias, + temperature=0.0, + ) + assert chat_completion.choices[0].message.content + + +@pytest.mark.asyncio +async def test_chat_completion_with_invalid_logit_bias( + async_client: openai.AsyncOpenAI, model_name: str): + """Test with invalid token IDs (non-integer keys)""" + with pytest.raises(openai.BadRequestError): + await async_client.chat.completions.create( + model=model_name, + messages=[{ + "role": "user", + "content": "Tell me a fact about Paris" + }], + logit_bias={"invalid_token": 1.0}, # Non-integer key + max_tokens=5, + ) diff --git a/tests/unittest/llmapi/apps/_test_openai_completions.py b/tests/unittest/llmapi/apps/_test_openai_completions.py index 7beeff0179b..b7b20c1e036 100644 --- a/tests/unittest/llmapi/apps/_test_openai_completions.py +++ b/tests/unittest/llmapi/apps/_test_openai_completions.py @@ -368,3 +368,36 @@ async def test_completion_streaming(async_client: openai.AsyncOpenAI, tokens.extend(chunk.choices[0].token_ids) assert tokens == single_output + + +@pytest.mark.asyncio +async def test_completion_with_logit_bias(async_client: openai.AsyncOpenAI, + model_name: str): + """Test logit_bias with valid token IDs""" + logit_bias = { + "1000": 80, + "2000": -80, + } + + completion = await async_client.completions.create( + model=model_name, + prompt="The capital of France is", + max_tokens=10, + logit_bias=logit_bias, + temperature=0.0, + ) + + assert completion.choices[0].text + + +@pytest.mark.asyncio +async def test_completion_with_invalid_logit_bias( + async_client: openai.AsyncOpenAI, model_name: str): + """Test with invalid token IDs (non-integer keys)""" + with pytest.raises(openai.BadRequestError): + await async_client.completions.create( + model=model_name, + prompt="Hello world", + logit_bias={"invalid_token": 1.0}, # Non-integer key + max_tokens=5, + ) From 3805976e9034f197413e53302f5a917b418ec8b9 Mon Sep 17 00:00:00 2001 From: pcastonguay <55748270+pcastonguay@users.noreply.github.com> Date: Fri, 25 Jul 2025 08:55:44 -0400 Subject: [PATCH 04/29] fix: Fixing kv_cache_events unit tests [nvbug 5362412] (#6265) Signed-off-by: Patrice Castonguay <55748270+pcastonguay@users.noreply.github.com> --- tests/unittest/llmapi/test_llm_kv_cache_events.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/tests/unittest/llmapi/test_llm_kv_cache_events.py b/tests/unittest/llmapi/test_llm_kv_cache_events.py index 718cd531dda..f5efbe2bcf8 100644 --- a/tests/unittest/llmapi/test_llm_kv_cache_events.py +++ b/tests/unittest/llmapi/test_llm_kv_cache_events.py @@ -1,10 +1,8 @@ import asyncio import time -import pytest - import tensorrt_llm -from tensorrt_llm._tensorrt_engine import LLM +from tensorrt_llm import LLM from tensorrt_llm._torch.pyexecutor.llm_request import LlmRequest from tensorrt_llm._torch.pyexecutor.resource_manager import KVCacheManager from tensorrt_llm._utils import KVCacheEventSerializer @@ -16,7 +14,6 @@ default_model_name = "llama-models-v2/TinyLlama-1.1B-Chat-v1.0" llama_model_path = get_model_path(default_model_name) - global_kvcache_config = KvCacheConfig(free_gpu_memory_fraction=0.4, event_buffer_max_size=1024, enable_block_reuse=True, @@ -50,8 +47,7 @@ def create_llm(tensor_parallel_size=1): return LLM(model=llama_model_path, tensor_parallel_size=tensor_parallel_size, kv_cache_config=global_kvcache_config, - enable_autotuner=False, - backend="pytorch") + enable_autotuner=False) def create_llm_request(id, input_tokens, new_tokens=1): @@ -103,7 +99,6 @@ def test_kv_cache_event_data_serialization(): serialized_event = KVCacheEventSerializer.serialize(events) -@pytest.mark.skip(reason="https://nvbugs/5362412") def test_expected_kv_cache_events(): llm = create_llm() sampling_params = SamplingParams(max_tokens=6, temperature=0.01) @@ -122,7 +117,6 @@ def test_expected_kv_cache_events(): assert event["data"]["type"] == "stored" -@pytest.mark.skip(reason="https://nvbugs/5362412") def test_kv_cache_event_async_api(): llm = create_llm() sampling_params = SamplingParams(max_tokens=6, temperature=0.01) @@ -150,7 +144,6 @@ async def main(): asyncio.run(main()) -@pytest.mark.skip(reason="https://nvbugs/5362412") def test_llm_kv_events_api(): llm = create_llm() sampling_params = SamplingParams(max_tokens=6, temperature=0.01) From b8d4cb8bebfa7c96c914a4310a5290d8fa1163ee Mon Sep 17 00:00:00 2001 From: nv-guomingz <137257613+nv-guomingz@users.noreply.github.com> Date: Sat, 26 Jul 2025 00:55:56 +0800 Subject: [PATCH 05/29] feat: Support JSON Schema in OpenAI-Compatible API (#6321) Signed-off-by: noiji <52301388+noiji@users.noreply.github.com> --- tensorrt_llm/serve/openai_protocol.py | 13 +- tests/integration/defs/test_e2e.py | 8 + .../integration/test_lists/test-db/l0_a10.yml | 1 + .../llmapi/apps/_test_openai_chat_json.py | 145 ++++++++++++++++++ 4 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 tests/unittest/llmapi/apps/_test_openai_chat_json.py diff --git a/tensorrt_llm/serve/openai_protocol.py b/tensorrt_llm/serve/openai_protocol.py index cdd725db5e2..4c90b1af43a 100644 --- a/tensorrt_llm/serve/openai_protocol.py +++ b/tensorrt_llm/serve/openai_protocol.py @@ -54,8 +54,9 @@ class StructuralTag(OpenAIBaseModel): class ResponseFormat(OpenAIBaseModel): - # type must be "json_object" or "text" or "structural_tag" - type: Literal["text", "json_object", "structural_tag"] + # type must be one of "text", "json", "json_object", or "structural_tag" + type: Literal["text", "json", "json_object", "structural_tag"] + schema: Optional[dict] = None structures: Optional[List[StructuralTag]] = None triggers: Optional[List[str]] = None @@ -144,6 +145,12 @@ def _response_format_to_guided_decoding_params( return None elif response_format.type == "text": return None + elif response_format.type == "json": + if response_format.schema is None: + raise ValueError( + "The 'schema' field is required when response_format.type is 'json'." + ) + return GuidedDecodingParams(json=response_format.schema) elif response_format.type == "json_object": return GuidedDecodingParams(json_object=True) elif response_format.type == "structural_tag": @@ -207,7 +214,7 @@ class CompletionRequest(OpenAIBaseModel): default=None, description= ("Similar to chat completion, this parameter specifies the format of " - "output. {'type': 'json_object'}, {'type': 'text' }, {'type': 'structural_tag'} are " + "output. {'type': 'json_object'}, {'type': 'text' }, {'type': 'structural_tag'}, {'type': 'json'} are " "supported."), ) diff --git a/tests/integration/defs/test_e2e.py b/tests/integration/defs/test_e2e.py index 03e5dd7f5ef..dfb0a1a0d1f 100644 --- a/tests/integration/defs/test_e2e.py +++ b/tests/integration/defs/test_e2e.py @@ -1443,6 +1443,14 @@ def test_openai_chat_structural_tag_example(llm_venv): ]) +def test_openai_chat_json_example(llm_venv): + test_root = unittest_path() / "llmapi" / "apps" + + llm_venv.run_cmd( + ["-m", "pytest", + str(test_root / "_test_openai_chat_json.py")]) + + @pytest.mark.skip_less_device(2) @pytest.mark.skip_less_device_memory(40000) def test_openai_multi_chat_example(llm_root, llm_venv): diff --git a/tests/integration/test_lists/test-db/l0_a10.yml b/tests/integration/test_lists/test-db/l0_a10.yml index a7cad599cdc..048597bbb4c 100644 --- a/tests/integration/test_lists/test-db/l0_a10.yml +++ b/tests/integration/test_lists/test-db/l0_a10.yml @@ -22,6 +22,7 @@ l0_a10: - disaggregated/test_disaggregated.py::test_disaggregated_mixed[TinyLlama-1.1B-Chat-v1.0] - disaggregated/test_disaggregated.py::test_disaggregated_overlap[TinyLlama-1.1B-Chat-v1.0] - test_e2e.py::test_openai_chat_structural_tag_example + - test_e2e.py::test_openai_chat_json_example - test_e2e.py::test_openai_chat_multimodal_example - test_e2e.py::test_openai_lora - test_e2e.py::test_trtllm_serve_multimodal_example diff --git a/tests/unittest/llmapi/apps/_test_openai_chat_json.py b/tests/unittest/llmapi/apps/_test_openai_chat_json.py new file mode 100644 index 00000000000..5518afdba77 --- /dev/null +++ b/tests/unittest/llmapi/apps/_test_openai_chat_json.py @@ -0,0 +1,145 @@ +# Adapted from +# https://github.com/vllm-project/vllm/blob/aae6927be06dedbda39c6b0c30f6aa3242b84388/tests/entrypoints/openai/test_chat.py +import json +import os +import tempfile +from typing import Any + +import jsonschema +import openai +import pytest +import yaml + +from ..test_llm import get_model_path +from .openai_server import RemoteOpenAIServer + +pytestmark = pytest.mark.threadleak(enabled=False) + + +@pytest.fixture(scope="module", ids=["TinyLlama-1.1B-Chat"]) +def model_name(): + return "llama-models-v2/TinyLlama-1.1B-Chat-v1.0" + + +@pytest.fixture(scope="module") +def temp_extra_llm_api_options_file(request): + temp_dir = tempfile.gettempdir() + temp_file_path = os.path.join(temp_dir, "extra_llm_api_options.yaml") + try: + extra_llm_api_options_dict = { + "guided_decoding_backend": "xgrammar", + "disable_overlap_scheduler": + True, # Guided decoding is not supported with overlap scheduler + } + + with open(temp_file_path, "w") as f: + yaml.dump(extra_llm_api_options_dict, f) + + yield temp_file_path + finally: + if os.path.exists(temp_file_path): + os.remove(temp_file_path) + + +@pytest.fixture(scope="module") +def server(model_name: str, temp_extra_llm_api_options_file: str): + model_path = get_model_path(model_name) + args = [ + "--backend", "pytorch", "--extra_llm_api_options", + temp_extra_llm_api_options_file + ] + with RemoteOpenAIServer(model_path, args) as remote_server: + yield remote_server + + +@pytest.fixture(scope="module") +def client(server: RemoteOpenAIServer): + return server.get_client() + + +@pytest.fixture(scope="module") +def async_client(server: RemoteOpenAIServer): + return server.get_async_client() + + +@pytest.fixture(scope="module") +def user_profile_schema(): + """Provides a sample JSON schema for a user profile.""" + return { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The full name of the user." + }, + "age": { + "type": "integer", + "description": "The age of the user, in years." + }, + }, + "required": ["name", "age"], + } + + +def test_chat_json_schema(client: openai.OpenAI, model_name: str, + user_profile_schema): + """ + Tests the `json` response format in a multi-turn synchronous conversation. + Adapted from https://github.com/vllm-project/vllm/blob/aae6927be06dedbda39c6b0c30f6aa3242b84388/tests/entrypoints/openai/test_chat.py#L413 + """ + + def _create_and_validate_response( + messages: list[dict[str, Any]]) -> dict[str, Any]: + chat_completion = client.chat.completions.create( + model=model_name, + messages=messages, + max_tokens=1000, + temperature=0.0, + response_format={ + "type": "json", + "schema": user_profile_schema + }, + ) + message = chat_completion.choices[0].message + assert message.content is not None + try: + message_json = json.loads(message.content) + except json.JSONDecodeError: + pytest.fail( + f"The output was not a valid JSON string. Output: {message.content}" + ) + + jsonschema.validate(instance=message_json, schema=user_profile_schema) + return message_json, message.content + + messages = [ + { + "role": "system", + "content": "you are a helpful assistant" + }, + { + "role": + "user", + "content": + f"Give an example JSON for an employee profile that fits this schema: {user_profile_schema}", + }, + ] + first_json, first_content = _create_and_validate_response(messages) + messages.extend([ + { + "role": "assistant", + "content": first_content, + }, + { + "role": "user", + "content": "Give me another one with a different name and age.", + }, + ]) + second_json, second_content = _create_and_validate_response(messages) + + assert ( + first_json["name"] != second_json["name"] + ), "The model should have generated a different name in the second turn." + assert ( + first_json["age"] != second_json["age"] + ), "The model should have generated a different age in the second turn." From 7bff3415536d6a2ee8aff6f3f97d79c455d6013d Mon Sep 17 00:00:00 2001 From: Simeng Liu <109828133+SimengLiu-nv@users.noreply.github.com> Date: Fri, 25 Jul 2025 10:26:33 -0700 Subject: [PATCH 06/29] [doc] Add NGram tech blog (#6311) Signed-off-by: Simeng Liu --- .../tech_blog7_accepted_length_case2.png | Bin 0 -> 105146 bytes .../tech_blog7_al_over_iteration_magpie.png | Bin 0 -> 154044 bytes .../media/tech_blog7_init_sequence_scan.png | Bin 0 -> 10748 bytes ...g7_magpie_accepted_length_distribution.png | Bin 0 -> 55411 bytes .../media/tech_blog7_per_token_update.png | Bin 0 -> 24899 bytes .../media/tech_blog7_speed_up_first_turn.png | Bin 0 -> 84129 bytes .../media/tech_blog7_speed_up_second_turn.png | Bin 0 -> 83353 bytes ...erformance_Analysis_And_Auto_Enablement.md | 186 ++++++++++++++++++ examples/llm-api/README.md | 2 +- 9 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 docs/source/blogs/media/tech_blog7_accepted_length_case2.png create mode 100644 docs/source/blogs/media/tech_blog7_al_over_iteration_magpie.png create mode 100644 docs/source/blogs/media/tech_blog7_init_sequence_scan.png create mode 100644 docs/source/blogs/media/tech_blog7_magpie_accepted_length_distribution.png create mode 100644 docs/source/blogs/media/tech_blog7_per_token_update.png create mode 100644 docs/source/blogs/media/tech_blog7_speed_up_first_turn.png create mode 100644 docs/source/blogs/media/tech_blog7_speed_up_second_turn.png create mode 100644 docs/source/blogs/tech_blog/blog_7_NGram_performance_Analysis_And_Auto_Enablement.md diff --git a/docs/source/blogs/media/tech_blog7_accepted_length_case2.png b/docs/source/blogs/media/tech_blog7_accepted_length_case2.png new file mode 100644 index 0000000000000000000000000000000000000000..e033b387e1feb989a5117a62eefe6370d88144d2 GIT binary patch literal 105146 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µnr(wiuS5FfkSKFDM+i9BZx77q}|h)a0v$Rj8H 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